Skip to content

Commit 62a1329

Browse files
authored
fix: idempotency in dreamsync adapter (#376)
1 parent 3bf6916 commit 62a1329

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

platforms/dreamsync-api/src/services/ConsentService.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Group } from "../database/entities/Group";
55
import { Message } from "../database/entities/Message";
66
import { UserService } from "./UserService";
77
import { GroupService } from "./GroupService";
8+
import { withOperationContext } from "../context/OperationContext";
89

910
export class ConsentService {
1011
private userService: UserService;
@@ -20,7 +21,11 @@ export class ConsentService {
2021
* Process a consent response to a match notification (by Match ID)
2122
*/
2223
async processConsentResponse(messageText: string, senderId: string, groupId: string): Promise<void> {
23-
try {
24+
// Generate unique operation ID for this consent processing
25+
const operationId = `consent-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
26+
27+
return withOperationContext('ConsentService', operationId, async () => {
28+
try {
2429
// Check if the message text itself is a UUID (Match ID)
2530
const uuidRegex = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
2631
const isDirectMatchId = uuidRegex.test(messageText.trim());
@@ -150,9 +155,10 @@ export class ConsentService {
150155
}
151156
}
152157

153-
} catch (error) {
154-
console.error("Error processing consent response:", error);
155-
}
158+
} catch (error) {
159+
console.error("Error processing consent response:", error);
160+
}
161+
});
156162
}
157163

158164
/**

platforms/dreamsync-api/src/web3adapter/watchers/subscriber.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Web3Adapter } from "web3-adapter";
1010
import path from "path";
1111
import dotenv from "dotenv";
1212
import { AppDataSource } from "../../database/data-source";
13+
import { shouldProcessWebhook } from "../../context/OperationContext";
1314

1415
dotenv.config({ path: path.resolve(__dirname, "../../../../../.env") });
1516
export const adapter = new Web3Adapter({
@@ -253,6 +254,12 @@ export class PostgresSubscriber implements EntitySubscriberInterface {
253254
private async handleChange(entity: any, tableName: string): Promise<void> {
254255
console.log(`🔍 handleChange called for: ${tableName}, entityId: ${entity?.id}`);
255256

257+
// Check if this operation should be processed (only ConsentService operations for groups/messages)
258+
if (!shouldProcessWebhook(entity?.id, tableName)) {
259+
console.log(`⏭️ Skipping webhook for ${tableName}:${entity?.id} - not from ConsentService (protected entity)`);
260+
return;
261+
}
262+
256263
// Handle junction table changes - DON'T IGNORE group_participants!
257264
// @ts-ignore
258265
const junctionInfo = JUNCTION_TABLE_MAP[tableName];
@@ -344,6 +351,12 @@ export class PostgresSubscriber implements EntitySubscriberInterface {
344351
return;
345352
}
346353

354+
// Check if this junction table change should be processed (only ConsentService operations for groups)
355+
if (!shouldProcessWebhook(parentId, junctionInfo.entity)) {
356+
console.log(`⏭️ Skipping junction table webhook for ${junctionInfo.entity}:${parentId} - not from ConsentService (protected entity)`);
357+
return;
358+
}
359+
347360
const repository = AppDataSource.getRepository(junctionInfo.entity);
348361
const parentEntity = await repository.findOne({
349362
where: { id: parentId },
@@ -408,6 +421,12 @@ export class PostgresSubscriber implements EntitySubscriberInterface {
408421
*/
409422
private async sendGroupWebhook(data: any): Promise<void> {
410423
try {
424+
// Check if this group webhook should be processed (only ConsentService operations for groups)
425+
if (!shouldProcessWebhook(data.id, "groups")) {
426+
console.log(`⏭️ Skipping group webhook for ${data.id} - not from ConsentService (protected entity)`);
427+
return;
428+
}
429+
411430
// Skip groups with Match ID in description (already processed)
412431
if (data.description && typeof data.description === 'string' && data.description.startsWith('Match ID:')) {
413432
console.log(`🔍 Skipping group webhook - has Match ID in description: ${data.description}`);

0 commit comments

Comments
 (0)