Skip to content

Commit 095bd9f

Browse files
committed
Support multiple invites from same doctor + robustness fixes
- CollectorClient.keyFromInfo uses accessId instead of accessName, so each invite from the same doctor gets a unique key - handleIncomingRequest no longer throws on different eventId/endpoint, allowing patients to accept multiple data set invites from one doctor - createAppStreams ignores item-already-exists for stream name collisions - streamData.children guard (from Plan 29)
1 parent d6feab0 commit 095bd9f

3 files changed

Lines changed: 18 additions & 17 deletions

File tree

ts/appTemplates/AppClientAccount.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,13 @@ export class AppClientAccount extends Application {
4040
if (this.cache.collectorClientsMap[collectorClientKey]) {
4141
const collectorClient = this.cache.collectorClientsMap[collectorClientKey];
4242
logger.debug('AppClient:handleIncomingRequest found existing', { collectorClient });
43-
if (collectorClient.requesterApiEndpoint !== apiEndpoint) {
44-
// console.log('⚠️⚠️⚠️⚠️ RESET! Found existing collectorClient with a different apiEndpoint', { actual: collectorClient.requesterApiEndpoint, incoming: apiEndpoint });
45-
throw new HDSLibError('Found existing collectorClient with a different apiEndpoint', { actual: collectorClient.requesterApiEndpoint, incoming: apiEndpoint });
46-
// we might consider reseting() in the future;
47-
// return await collectorClient.reset(apiEndpoint, incomingEventId, accessInfo);
43+
// Same access, same endpoint — idempotent, return existing
44+
if (collectorClient.requesterApiEndpoint === apiEndpoint) {
45+
return collectorClient;
4846
}
49-
if (incomingEventId && collectorClient.requesterEventId !== incomingEventId) {
50-
throw new HDSLibError('Found existing collectorClient with a different eventId', { actual: collectorClient.requesterEventId, incoming: incomingEventId });
51-
// console.log('⚠️⚠️⚠️⚠️ RESET! Found existing collectorClient with a different eventId', { actual: collectorClient.requesterEventId, incoming: incomingEventId });
52-
// we might consider reseting() in the future;
53-
// return await collectorClient.reset(apiEndpoint, incomingEventId, accessInfo);
54-
// return null;
55-
}
56-
return collectorClient;
47+
// Different apiEndpoint or eventId for same key — this shouldn't happen with id-based keys
48+
// but handle gracefully by logging and creating new (will get a different key from its own accessInfo)
49+
logger.info('AppClient:handleIncomingRequest existing key collision, creating new client');
5750
}
5851
// check if comming form hdsCollector
5952
if (!accessInfo?.clientData?.hdsCollector || (accessInfo.clientData?.hdsCollector as any)?.version !== 0) {

ts/appTemplates/Application.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,15 @@ async function createAppStreams (app: Application): Promise<void> {
221221
{ method: 'streams.create', params: { id: app.baseStreamId, name: app.appName, parentId: APPS_ROOT_STREAM } }
222222
];
223223
const streamCreateResult = await app.connection.api(apiCalls);
224-
if (streamCreateResult[1].error) throw new Error('Failed creating app streams ' + JSON.stringify(streamCreateResult[1].error));
225-
const stream = (streamCreateResult[1] as any).stream;
226-
app.cache.streamData = stream;
224+
const appStreamResult = streamCreateResult[1] as any;
225+
if (appStreamResult.error && appStreamResult.error.id !== 'item-already-exists') {
226+
throw new Error('Failed creating app streams ' + JSON.stringify(appStreamResult.error));
227+
}
228+
if (appStreamResult.stream) {
229+
app.cache.streamData = appStreamResult.stream;
230+
} else {
231+
// Stream already existed — load it
232+
await app.loadStreamData();
233+
}
227234
}
228235
}

ts/appTemplates/CollectorClient.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ export class CollectorClient {
356356
* @param {PryvAccessInfo} accessInfo
357357
*/
358358
static keyFromInfo (info) {
359-
return info.user.username + ':' + info.name;
359+
// Use access id when available (unique per invite), fall back to name for backwards compat
360+
return info.user.username + ':' + (info.id || info.name);
360361
}
361362

362363
// -------------------- access update requests ------------- //

0 commit comments

Comments
 (0)