Skip to content

Commit c40ca22

Browse files
committed
generate TeamMemberDiscoveryAgent
1 parent 4770240 commit c40ca22

5 files changed

Lines changed: 84 additions & 10 deletions

File tree

WireDomain/Sources/WireDomain/Components/ClientSessionComponent.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ public final class ClientSessionComponent {
398398
mlsService: mlsService
399399
)
400400

401+
private lazy var teamMemberDiscoveryAgent = TeamMemberDiscoveryAgent()
402+
401403
public private(set) lazy var incrementalSync = IncrementalSync(
402404
selfClientID: selfClientID,
403405
pushChannelAPI: pushChannelAPI,
@@ -411,8 +413,8 @@ public final class ClientSessionComponent {
411413
liveBrokenGroupSubject: liveBrokenGroupSubject,
412414
journal: journal,
413415
mlsGroupRepairAgent: mlsGroupRepairAgent,
414-
earService: earService
415-
// TODO: pass team-member discovery use case
416+
earService: earService,
417+
teamMemberDiscoveryAgent: teamMemberDiscoveryAgent
416418
)
417419

418420
public lazy var incrementalSyncV2: IncrementalSyncV2 = if let sharedContainerURL {
@@ -431,7 +433,7 @@ public final class ClientSessionComponent {
431433
journal: journal,
432434
mlsGroupRepairAgent: mlsGroupRepairAgent,
433435
earService: earService,
434-
// TODO: pass team-member discovery use case
436+
teamMemberDiscoveryAgent: teamMemberDiscoveryAgent,
435437
createPushChannelState: { [selfClientID] in
436438
PushChannelState(sharedContainerURL: sharedContainerURL, clientID: selfClientID)
437439
}

WireDomain/Sources/WireDomain/Synchronization/IncrementalSync.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public struct IncrementalSync: IncrementalSyncProtocol {
4545
private let journal: Journal
4646
private let mlsGroupRepairAgent: MLSGroupRepairAgentProtocol
4747
private let earService: EARServiceInterface
48-
// TODO: add team-member discovery use case stored property
48+
private let teamMemberDiscoveryAgent: any TeamMemberDiscoveryAgentProtocol
4949

5050
public init(
5151
selfClientID: String,
@@ -60,8 +60,8 @@ public struct IncrementalSync: IncrementalSyncProtocol {
6060
liveBrokenGroupSubject: PassthroughSubject<Set<String>, Never>,
6161
journal: Journal,
6262
mlsGroupRepairAgent: MLSGroupRepairAgentProtocol,
63-
earService: EARServiceInterface
64-
// TODO: add team-member discovery use case init parameter
63+
earService: EARServiceInterface,
64+
teamMemberDiscoveryAgent: any TeamMemberDiscoveryAgentProtocol
6565
) {
6666
self.selfClientID = selfClientID
6767
self.pushChannelAPI = pushChannelAPI
@@ -76,6 +76,7 @@ public struct IncrementalSync: IncrementalSyncProtocol {
7676
self.journal = journal
7777
self.mlsGroupRepairAgent = mlsGroupRepairAgent
7878
self.earService = earService
79+
self.teamMemberDiscoveryAgent = teamMemberDiscoveryAgent
7980
}
8081

8182
public func perform() async throws -> Token {
@@ -163,7 +164,9 @@ public struct IncrementalSync: IncrementalSyncProtocol {
163164

164165
await mlsGroupRepairAgent.repairConversations()
165166

166-
// TODO: invoke team-member discovery use case here (skip when backgroundAccessibleOnly)
167+
if !backgroundAccessibleOnly {
168+
await teamMemberDiscoveryAgent.discoverMembers()
169+
}
167170

168171
let liveEventTask = Task { @Sendable [self] in
169172
logger.info("handling live event stream", attributes: .incrementalSyncV2, .safePublic)

WireDomain/Sources/WireDomain/Synchronization/IncrementalSyncV2.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public struct IncrementalSyncV2: LiveSyncProtocol {
5252
private let createPushChannelState: CreatePushChannelStateClosure
5353
private let mlsGroupRepairAgent: MLSGroupRepairAgentProtocol
5454
private let earService: EARServiceInterface
55-
// TODO: add team-member discovery use case stored property
55+
private let teamMemberDiscoveryAgent: any TeamMemberDiscoveryAgentProtocol
5656

5757
weak var delegate: (any LiveSyncDelegate)?
5858

@@ -71,7 +71,7 @@ public struct IncrementalSyncV2: LiveSyncProtocol {
7171
journal: Journal,
7272
mlsGroupRepairAgent: MLSGroupRepairAgentProtocol,
7373
earService: EARServiceInterface,
74-
// TODO: add team-member discovery use case init parameter
74+
teamMemberDiscoveryAgent: any TeamMemberDiscoveryAgentProtocol,
7575
createPushChannelState: @escaping CreatePushChannelStateClosure,
7676
syncMarkerGenerator: @escaping SyncMarkerGenerator = { UUID().uuidString }
7777
) {
@@ -89,6 +89,7 @@ public struct IncrementalSyncV2: LiveSyncProtocol {
8989
self.journal = journal
9090
self.mlsGroupRepairAgent = mlsGroupRepairAgent
9191
self.earService = earService
92+
self.teamMemberDiscoveryAgent = teamMemberDiscoveryAgent
9293
self.syncMarkerGenerator = syncMarkerGenerator
9394
self.createPushChannelState = createPushChannelState
9495
}
@@ -154,7 +155,7 @@ public struct IncrementalSyncV2: LiveSyncProtocol {
154155

155156
await mlsGroupRepairAgent.repairConversations()
156157

157-
// TODO: invoke team-member discovery use case here
158+
await teamMemberDiscoveryAgent.discoverMembers()
158159

159160
let task = Task { @Sendable [self] in
160161
logger.debug("handling live event stream", attributes: logAttributes)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// Wire
3+
// Copyright (C) 2026 Wire Swiss GmbH
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see http://www.gnu.org/licenses/.
17+
//
18+
19+
import Foundation
20+
21+
// sourcery: AutoMockable
22+
/// Discovers self-team members by replaying recent team notifications,
23+
/// working around the 2000-member cap on the legacy bulk team-members endpoint.
24+
public protocol TeamMemberDiscoveryAgentProtocol {
25+
26+
/// Fetch recent team notifications and apply any discovered
27+
/// `team.member-join` events to local storage.
28+
func discoverMembers() async
29+
30+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// Wire
3+
// Copyright (C) 2026 Wire Swiss GmbH
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see http://www.gnu.org/licenses/.
17+
//
18+
19+
import Foundation
20+
import WireLogging
21+
22+
final class TeamMemberDiscoveryAgent: TeamMemberDiscoveryAgentProtocol {
23+
24+
// MARK: - Life cycle
25+
26+
public init() {}
27+
28+
// MARK: - TeamMemberDiscoveryAgentProtocol
29+
30+
public func discoverMembers() async {
31+
// TODO: WPB-24947 — use teamsAPI.getNotifications(sinceNotificationID:)
32+
// to fetch recent team notifications, then extract & apply
33+
// `team.member-join` events to discover all team members
34+
// (works around the 2000-member cap on the legacy bulk endpoint).
35+
WireLogger.sync.debug("team member discovery: not implemented yet")
36+
}
37+
38+
}

0 commit comments

Comments
 (0)