Conversation
CreateIntegration previously called integrationRepository.createIntegration unconditionally, so every re-auth POST /api/integrations created a fresh Integration row for the same user + type + entity set. Entities are already deduped in ProcessAuthorizationCallback by (userId, moduleName, externalId), so re-auth returns the same entity.id — the integration record is where the duplicate leaks in. Now CreateIntegration looks up an existing integration keyed by (userId, config.type, entityIds). If found, it loads the integration instance and runs testAuth() so stale credentials surface via the normal status/messages pipeline instead of silently succeeding; no ON_CREATE is re-sent and config is not overwritten. Entity comparison is order-insensitive since entityIds is a set. Adds findIntegrationByUserIdTypeAndEntities to the repository interface and implementations for Mongo, Postgres, and DocumentDB, plus the in-memory test double. Extends create-integration.test.js with cases covering reuse, testAuth invocation, order-insensitive matching, and the discriminators (type, entity set, userId) that should still produce fresh records.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd85498e4a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| await instance.testAuth(); | ||
| return mapIntegrationClassToIntegrationDTO(instance); |
There was a problem hiding this comment.
Return refreshed state after re-auth testAuth
When an existing integration is reused, instance.testAuth() persists status/message changes through repository use-cases, but those writes do not mutate the in-memory instance object; immediately mapping instance to DTO can therefore return stale status/messages even when auth just failed. This affects re-authorize requests that depend on the response payload to reflect credential validity, so the flow should reload the integration (or update the instance fields) before returning.
Useful? React with 👍 / 👎.
Code reviewFound 1 issue:
frigg/packages/core/integrations/use-cases/create-integration.js Lines 49 to 57 in dd85498 Fix options: re-read the record from the repository after 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |




Summary
CreateIntegrationnow looks up an existing integration by(userId, config.type, entityIds)before creating a new one. If found, the existing record is reused andtestAuth()runs so stale credentials surface via the usual status/messages pipeline — noON_CREATEre-send, no config overwrite.ProcessAuthorizationCallback.findOrCreateEntitydedupes entities by(userId, moduleName, externalId). Re-auth returns the sameentity.id, so the integration record was the only place duplicates still leaked in.Files changed
integrations/use-cases/create-integration.js— dedup logic +_buildInstanceextraction.integrations/repositories/integration-repository-interface.js— new abstractfindIntegrationByUserIdTypeAndEntities.integrations/repositories/integration-repository-{mongo,postgres,documentdb}.js— implementations. Filter byuserId+config.typeat the DB layer, then order-insensitive set equality on entity IDs in JS.integrations/tests/doubles/test-integration-repository.js— in-memory version.integrations/tests/doubles/dummy-integration-class.js— adds atestAuth()spy (no other tests reference it).integrations/tests/use-cases/create-integration.test.js— 6 new cases.Test plan
npm test -- --testPathPattern="create-integration"— 13/13 pass (6 new).npm test -- --testPathPattern="integrations/tests"— 129/129 pass.Notes
testAuth()on reuse writes tomessages.errorsand flipsstatustoERRORon failure viaUpdateIntegrationStatus/UpdateIntegrationMessages, so the API response naturally reflects credential validity.