@friggframework/core 2.0.0--canary.545.ccb5010.0 → 2.0.0--canary.549.b074651.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -66
- package/CLAUDE.md +124 -148
- package/README.md +130 -165
- package/assertions/jest.config.ts +7 -0
- package/core/CLAUDE.md +156 -222
- package/database/MONGODB_TRANSACTION_FIX.md +52 -72
- package/database/encryption/README.md +36 -53
- package/database/jest.config.ts +7 -0
- package/database/models/WorkflowExecutionModel.ts +315 -0
- package/database/models/WorkflowModel.ts +129 -0
- package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +80 -135
- package/generated/prisma-mongodb/edge.js +5 -60
- package/generated/prisma-mongodb/index-browser.js +1 -49
- package/generated/prisma-mongodb/index.d.ts +57 -4019
- package/generated/prisma-mongodb/index.js +11 -66
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/{libquery_engine-debian-openssl-3.0.x.so.node → query-engine-debian-openssl-3.0.x} +0 -0
- package/generated/prisma-mongodb/{libquery_engine-rhel-openssl-3.0.x.so.node → query-engine-rhel-openssl-3.0.x} +0 -0
- package/generated/prisma-mongodb/runtime/binary.d.ts +1 -0
- package/generated/prisma-mongodb/runtime/binary.js +289 -0
- package/generated/prisma-mongodb/schema.prisma +2 -89
- package/generated/prisma-mongodb/wasm.js +5 -60
- package/generated/prisma-postgresql/edge.js +5 -59
- package/generated/prisma-postgresql/index-browser.js +1 -48
- package/generated/prisma-postgresql/index.d.ts +44 -4732
- package/generated/prisma-postgresql/index.js +11 -65
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/{libquery_engine-debian-openssl-3.0.x.so.node → query-engine-debian-openssl-3.0.x} +0 -0
- package/generated/prisma-postgresql/{libquery_engine-rhel-openssl-3.0.x.so.node → query-engine-rhel-openssl-3.0.x} +0 -0
- package/generated/prisma-postgresql/runtime/binary.d.ts +1 -0
- package/generated/prisma-postgresql/runtime/binary.js +289 -0
- package/generated/prisma-postgresql/schema.prisma +2 -87
- package/generated/prisma-postgresql/wasm.js +5 -59
- package/handlers/WEBHOOKS.md +81 -104
- package/handlers/routers/HEALTHCHECK.md +135 -170
- package/integrations/WEBHOOK-QUICKSTART.md +14 -21
- package/jest-global-setup-noop.ts +3 -0
- package/jest-global-teardown-noop.ts +3 -0
- package/jest-resolver.ts +36 -0
- package/jest-setup.ts +1 -0
- package/jest-teardown.ts +1 -0
- package/jest.config.ts +20 -0
- package/package.json +32 -8
- package/prisma-mongodb/schema.prisma +2 -89
- package/prisma-postgresql/schema.prisma +2 -87
- package/src/application/commands/command-utils.ts +17 -0
- package/src/application/commands/credential-commands.ts +214 -0
- package/src/application/commands/entity-commands.ts +253 -0
- package/src/application/commands/integration-commands.test.ts +158 -0
- package/src/application/commands/integration-commands.ts +205 -0
- package/{application/commands/scheduler-commands.js → src/application/commands/scheduler-commands.ts} +82 -104
- package/{application/commands/user-commands.js → src/application/commands/user-commands.ts} +73 -97
- package/src/application/index.ts +82 -0
- package/src/assertions/get.ts +196 -0
- package/src/assertions/index.ts +9 -0
- package/src/associations/association.ts +103 -0
- package/src/associations/index.ts +3 -0
- package/src/core/Delegate.ts +41 -0
- package/src/core/Worker.test.ts +158 -0
- package/src/core/Worker.ts +86 -0
- package/{core/create-handler.js → src/core/create-handler.ts} +42 -15
- package/src/core/index.ts +15 -0
- package/src/core/load-installed-modules.ts +31 -0
- package/{core/secrets-to-env.js → src/core/secrets-to-env.ts} +14 -14
- package/src/credential/index.ts +9 -0
- package/src/credential/repositories/credential-repository-documentdb.ts +185 -0
- package/src/credential/repositories/credential-repository-factory.ts +26 -0
- package/src/credential/repositories/credential-repository-interface.ts +62 -0
- package/src/credential/repositories/credential-repository-mongo.ts +163 -0
- package/src/credential/repositories/credential-repository-postgres.ts +169 -0
- package/src/credential/repositories/credential-repository.ts +162 -0
- package/src/credential/use-cases/get-credential-for-user.ts +27 -0
- package/src/credential/use-cases/update-authentication-status.ts +17 -0
- package/src/database/adapters/index.ts +1 -0
- package/src/database/adapters/lambda-invoker.test.ts +104 -0
- package/src/database/adapters/lambda-invoker.ts +61 -0
- package/src/database/config.ts +142 -0
- package/src/database/documentdb-encryption-service.ts +191 -0
- package/src/database/documentdb-utils.ts +160 -0
- package/src/database/encryption/encryption-schema-registry.test.ts +397 -0
- package/src/database/encryption/encryption-schema-registry.ts +243 -0
- package/src/database/encryption/field-encryption-service.test.ts +511 -0
- package/{database/encryption/field-encryption-service.js → src/database/encryption/field-encryption-service.ts} +46 -67
- package/src/database/encryption/index.ts +24 -0
- package/{database/encryption/logger.js → src/database/encryption/logger.ts} +19 -21
- package/src/database/encryption/mongo-decryption-fix-verification.test.ts +337 -0
- package/src/database/encryption/postgres-decryption-fix-verification.test.ts +335 -0
- package/src/database/encryption/postgres-relation-decryption.test.ts +205 -0
- package/src/database/encryption/prisma-encryption-extension.test.ts +433 -0
- package/{database/encryption/prisma-encryption-extension.js → src/database/encryption/prisma-encryption-extension.ts} +58 -77
- package/src/database/index.ts +126 -0
- package/src/database/prisma.test.ts +65 -0
- package/src/database/prisma.ts +166 -0
- package/{database/repositories/health-check-repository-documentdb.js → src/database/repositories/health-check-repository-documentdb.ts} +34 -45
- package/src/database/repositories/health-check-repository-factory.ts +38 -0
- package/src/database/repositories/health-check-repository-interface.ts +20 -0
- package/src/database/repositories/health-check-repository-mongodb.test.ts +178 -0
- package/src/database/repositories/health-check-repository-mongodb.ts +79 -0
- package/src/database/repositories/health-check-repository-postgres.test.ts +94 -0
- package/src/database/repositories/health-check-repository-postgres.ts +70 -0
- package/src/database/repositories/index.ts +10 -0
- package/src/database/repositories/migration-status-repository-s3.test.ts +150 -0
- package/src/database/repositories/migration-status-repository-s3.ts +127 -0
- package/src/database/use-cases/check-database-health-use-case.test.ts +131 -0
- package/src/database/use-cases/check-database-health-use-case.ts +30 -0
- package/src/database/use-cases/check-database-state-use-case.test.ts +131 -0
- package/src/database/use-cases/check-database-state-use-case.ts +66 -0
- package/src/database/use-cases/check-encryption-health-use-case.test.ts +183 -0
- package/{database/use-cases/check-encryption-health-use-case.js → src/database/use-cases/check-encryption-health-use-case.ts} +38 -15
- package/src/database/use-cases/get-database-state-via-worker-use-case.test.ts +126 -0
- package/src/database/use-cases/get-database-state-via-worker-use-case.ts +31 -0
- package/src/database/use-cases/get-migration-status-use-case.test.ts +160 -0
- package/src/database/use-cases/get-migration-status-use-case.ts +57 -0
- package/src/database/use-cases/index.ts +14 -0
- package/src/database/use-cases/run-database-migration-use-case.test.ts +350 -0
- package/src/database/use-cases/run-database-migration-use-case.ts +113 -0
- package/src/database/use-cases/test-encryption-use-case.ts +197 -0
- package/src/database/use-cases/trigger-database-migration-use-case.test.ts +256 -0
- package/src/database/use-cases/trigger-database-migration-use-case.ts +131 -0
- package/src/database/utils/index.ts +26 -0
- package/src/database/utils/mongodb-collection-utils.test.ts +133 -0
- package/src/database/utils/mongodb-collection-utils.ts +45 -0
- package/src/database/utils/mongodb-schema-init.test.ts +152 -0
- package/src/database/utils/mongodb-schema-init.ts +51 -0
- package/src/database/utils/prisma-runner.test.ts +513 -0
- package/src/database/utils/prisma-runner.ts +336 -0
- package/src/database/utils/prisma-schema-parser.test.ts +283 -0
- package/src/database/utils/prisma-schema-parser.ts +90 -0
- package/src/declarations.d.ts +141 -0
- package/src/encrypt/Cryptor.test.ts +137 -0
- package/src/encrypt/Cryptor.ts +92 -0
- package/{encrypt/aes.js → src/encrypt/aes.ts} +4 -9
- package/src/encrypt/index.ts +2 -0
- package/src/errors/base-error.test.ts +32 -0
- package/src/errors/base-error.ts +15 -0
- package/src/errors/client-safe-error.ts +12 -0
- package/src/errors/fetch-error.test.ts +105 -0
- package/{errors/fetch-error.js → src/errors/fetch-error.ts} +36 -17
- package/src/errors/halt-error.test.ts +11 -0
- package/src/errors/halt-error.ts +10 -0
- package/src/errors/index.ts +9 -0
- package/src/errors/validation-errors.test.ts +122 -0
- package/src/errors/validation-errors.ts +33 -0
- package/src/handlers/app-definition-loader.ts +52 -0
- package/src/handlers/app-handler-helpers.ts +62 -0
- package/src/handlers/auth-flow.integration.test.ts +149 -0
- package/{handlers/backend-utils.js → src/handlers/backend-utils.ts} +55 -52
- package/src/handlers/database-migration-handler.ts +172 -0
- package/src/handlers/index.ts +22 -0
- package/src/handlers/integration-event-dispatcher.test.ts +211 -0
- package/{handlers/integration-event-dispatcher.js → src/handlers/integration-event-dispatcher.ts} +33 -9
- package/src/handlers/routers/auth.ts +20 -0
- package/src/handlers/routers/db-migration.handler.ts +28 -0
- package/src/handlers/routers/db-migration.test.ts +69 -0
- package/src/handlers/routers/db-migration.ts +173 -0
- package/src/handlers/routers/health.test.ts +251 -0
- package/src/handlers/routers/health.ts +390 -0
- package/src/handlers/routers/index.ts +8 -0
- package/src/handlers/routers/integration-defined-routers.ts +50 -0
- package/src/handlers/routers/integration-webhook-routers.test.ts +116 -0
- package/src/handlers/routers/integration-webhook-routers.ts +72 -0
- package/src/handlers/routers/user.ts +63 -0
- package/{handlers/routers/websocket.js → src/handlers/routers/websocket.ts} +25 -28
- package/{handlers/use-cases/check-external-apis-health-use-case.js → src/handlers/use-cases/check-external-apis-health-use-case.ts} +31 -12
- package/src/handlers/use-cases/check-integrations-health-use-case.test.ts +124 -0
- package/src/handlers/use-cases/check-integrations-health-use-case.ts +69 -0
- package/src/handlers/use-cases/index.ts +9 -0
- package/src/handlers/webhook-flow.integration.test.ts +318 -0
- package/src/handlers/workers/db-migration.test.ts +168 -0
- package/src/handlers/workers/db-migration.ts +173 -0
- package/src/handlers/workers/index.ts +3 -0
- package/src/handlers/workers/integration-defined-workers.test.ts +254 -0
- package/src/handlers/workers/integration-defined-workers.ts +35 -0
- package/src/index.ts +400 -0
- package/src/infrastructure/index.ts +14 -0
- package/src/infrastructure/scheduler/eventbridge-scheduler-adapter.ts +148 -0
- package/src/infrastructure/scheduler/index.ts +19 -0
- package/{infrastructure/scheduler/mock-scheduler-adapter.js → src/infrastructure/scheduler/mock-scheduler-adapter.ts} +25 -59
- package/src/infrastructure/scheduler/scheduler-service-factory.ts +50 -0
- package/src/infrastructure/scheduler/scheduler-service-interface.ts +31 -0
- package/src/integrations/index.ts +79 -0
- package/src/integrations/integration-base.module-keys.test.ts +204 -0
- package/{integrations/integration-base.js → src/integrations/integration-base.ts} +161 -169
- package/src/integrations/integration-router.ts +645 -0
- package/src/integrations/options.ts +57 -0
- package/{integrations/repositories/integration-mapping-repository-documentdb.js → src/integrations/repositories/integration-mapping-repository-documentdb.ts} +54 -134
- package/src/integrations/repositories/integration-mapping-repository-factory.ts +27 -0
- package/src/integrations/repositories/integration-mapping-repository-interface.ts +56 -0
- package/src/integrations/repositories/integration-mapping-repository-mongo.ts +89 -0
- package/src/integrations/repositories/integration-mapping-repository-postgres.ts +129 -0
- package/src/integrations/repositories/integration-mapping-repository.ts +71 -0
- package/{integrations/repositories/integration-repository-documentdb.js → src/integrations/repositories/integration-repository-documentdb.ts} +51 -89
- package/src/integrations/repositories/integration-repository-factory.ts +27 -0
- package/src/integrations/repositories/integration-repository-interface.ts +52 -0
- package/src/integrations/repositories/integration-repository-mongo.ts +186 -0
- package/src/integrations/repositories/integration-repository-postgres.ts +227 -0
- package/{integrations/repositories/process-repository-documentdb.js → src/integrations/repositories/process-repository-documentdb.ts} +57 -124
- package/src/integrations/repositories/process-repository-factory.ts +27 -0
- package/src/integrations/repositories/process-repository-interface.ts +34 -0
- package/src/integrations/repositories/process-repository-mongo.ts +102 -0
- package/src/integrations/repositories/process-repository-postgres.ts +123 -0
- package/{integrations/tests/doubles/config-capturing-integration.js → src/integrations/tests/doubles/config-capturing-integration.ts} +21 -22
- package/src/integrations/tests/doubles/dummy-integration-class.ts +109 -0
- package/src/integrations/tests/doubles/test-integration-repository.ts +100 -0
- package/src/integrations/tests/integration-router-multi-auth.test.ts +531 -0
- package/src/integrations/tests/use-cases/create-integration.test.ts +131 -0
- package/src/integrations/tests/use-cases/delete-integration-for-user.test.ts +150 -0
- package/src/integrations/tests/use-cases/find-integration-context-by-external-entity-id.test.ts +92 -0
- package/src/integrations/tests/use-cases/get-integration-for-user.test.ts +150 -0
- package/src/integrations/tests/use-cases/get-integration-instance.test.ts +176 -0
- package/src/integrations/tests/use-cases/get-integrations-for-user.test.ts +176 -0
- package/src/integrations/tests/use-cases/get-possible-integrations.test.ts +188 -0
- package/src/integrations/tests/use-cases/update-integration-messages.test.ts +142 -0
- package/src/integrations/tests/use-cases/update-integration-status.test.ts +103 -0
- package/src/integrations/tests/use-cases/update-integration.test.ts +208 -0
- package/src/integrations/types.ts +195 -0
- package/src/integrations/use-cases/create-integration.ts +70 -0
- package/src/integrations/use-cases/create-process.test.ts +172 -0
- package/src/integrations/use-cases/create-process.ts +77 -0
- package/src/integrations/use-cases/delete-integration-for-user.ts +87 -0
- package/src/integrations/use-cases/find-integration-context-by-external-entity-id.ts +92 -0
- package/src/integrations/use-cases/get-integration-for-user.ts +74 -0
- package/src/integrations/use-cases/get-integration-instance-by-definition.ts +69 -0
- package/{integrations/use-cases/get-integration-instance.js → src/integrations/use-cases/get-integration-instance.ts} +20 -31
- package/src/integrations/use-cases/get-integrations-for-user.ts +75 -0
- package/src/integrations/use-cases/get-possible-integrations.ts +15 -0
- package/src/integrations/use-cases/get-process.test.ts +181 -0
- package/src/integrations/use-cases/get-process.ts +49 -0
- package/src/integrations/use-cases/index.ts +16 -0
- package/src/integrations/use-cases/load-integration-context-full.test.ts +316 -0
- package/src/integrations/use-cases/load-integration-context.test.ts +115 -0
- package/{integrations/use-cases/load-integration-context.js → src/integrations/use-cases/load-integration-context.ts} +34 -14
- package/src/integrations/use-cases/update-integration-messages.ts +26 -0
- package/src/integrations/use-cases/update-integration-status.ts +17 -0
- package/src/integrations/use-cases/update-integration.ts +76 -0
- package/src/integrations/use-cases/update-process-metrics.test.ts +278 -0
- package/src/integrations/use-cases/update-process-metrics.ts +128 -0
- package/src/integrations/use-cases/update-process-state.test.ts +249 -0
- package/src/integrations/use-cases/update-process-state.ts +73 -0
- package/src/integrations/utils/map-integration-dto.ts +55 -0
- package/src/lambda/TimeoutCatcher.test.ts +69 -0
- package/src/lambda/TimeoutCatcher.ts +57 -0
- package/src/lambda/index.ts +2 -0
- package/src/logs/index.ts +2 -0
- package/src/logs/logger.test.ts +76 -0
- package/{logs/logger.js → src/logs/logger.ts} +15 -10
- package/src/modules/ModuleConstants.ts +11 -0
- package/src/modules/index.ts +38 -0
- package/{modules/module-factory.js → src/modules/module-factory.ts} +16 -20
- package/src/modules/module-hydration.test.ts +203 -0
- package/src/modules/module.ts +283 -0
- package/src/modules/repositories/module-repository-documentdb.ts +303 -0
- package/src/modules/repositories/module-repository-factory.ts +29 -0
- package/src/modules/repositories/module-repository-interface.ts +73 -0
- package/src/modules/repositories/module-repository-mongo.ts +260 -0
- package/src/modules/repositories/module-repository-postgres.ts +293 -0
- package/src/modules/repositories/module-repository.ts +210 -0
- package/src/modules/requester/api-key.ts +58 -0
- package/src/modules/requester/basic.ts +49 -0
- package/src/modules/requester/oauth-2.test.ts +425 -0
- package/src/modules/requester/oauth-2.ts +298 -0
- package/src/modules/requester/requester.test.ts +28 -0
- package/src/modules/requester/requester.ts +212 -0
- package/{modules/test/mock-api/api.js → src/modules/test/mock-api/api.ts} +6 -8
- package/{modules/test/mock-api/definition.js → src/modules/test/mock-api/definition.ts} +15 -21
- package/src/modules/test/mock-api/mocks/hubspot.ts +41 -0
- package/src/modules/tests/doubles/test-module-factory.ts +11 -0
- package/{modules/tests/doubles/test-module-repository.js → src/modules/tests/doubles/test-module-repository.ts} +7 -7
- package/src/modules/tests/module-on-token-update.test.ts +125 -0
- package/src/modules/use-cases/get-entities-for-user.ts +36 -0
- package/src/modules/use-cases/get-entity-options-by-id.ts +64 -0
- package/src/modules/use-cases/get-entity-options-by-type.ts +25 -0
- package/src/modules/use-cases/get-module-instance-from-type.ts +23 -0
- package/src/modules/use-cases/get-module.ts +70 -0
- package/{modules/use-cases/process-authorization-callback.js → src/modules/use-cases/process-authorization-callback.ts} +50 -49
- package/src/modules/use-cases/refresh-entity-options.ts +65 -0
- package/src/modules/use-cases/test-module-auth.ts +64 -0
- package/src/modules/utils/map-module-dto.ts +23 -0
- package/src/queues/index.ts +1 -0
- package/src/queues/queuer-util.test.ts +131 -0
- package/src/queues/queuer-util.ts +59 -0
- package/src/syncs/index.ts +14 -0
- package/{syncs/manager.js → src/syncs/manager.ts} +140 -142
- package/{syncs/repositories/sync-repository-documentdb.js → src/syncs/repositories/sync-repository-documentdb.ts} +46 -67
- package/src/syncs/repositories/sync-repository-factory.ts +30 -0
- package/src/syncs/repositories/sync-repository-interface.ts +68 -0
- package/src/syncs/repositories/sync-repository-mongo.ts +149 -0
- package/src/syncs/repositories/sync-repository-postgres.ts +221 -0
- package/src/syncs/sync.ts +119 -0
- package/src/token/index.ts +7 -0
- package/src/token/repositories/token-repository-documentdb.ts +110 -0
- package/src/token/repositories/token-repository-factory.ts +26 -0
- package/src/token/repositories/token-repository-interface.ts +57 -0
- package/src/token/repositories/token-repository-mongo.ts +81 -0
- package/src/token/repositories/token-repository-postgres.ts +105 -0
- package/src/token/repositories/token-repository.ts +125 -0
- package/src/user/index.ts +17 -0
- package/src/user/repositories/user-repository-documentdb.ts +286 -0
- package/src/user/repositories/user-repository-factory.ts +26 -0
- package/src/user/repositories/user-repository-interface.ts +109 -0
- package/src/user/repositories/user-repository-mongo.ts +130 -0
- package/src/user/repositories/user-repository-postgres.ts +175 -0
- package/{user/tests/doubles/test-user-repository.js → src/user/tests/doubles/test-user-repository.ts} +16 -19
- package/src/user/tests/use-cases/create-individual-user.test.ts +24 -0
- package/src/user/tests/use-cases/create-organization-user.test.ts +28 -0
- package/src/user/tests/use-cases/create-token-for-user-id.test.ts +18 -0
- package/src/user/tests/use-cases/get-user-from-adopter-jwt.test.ts +113 -0
- package/src/user/tests/use-cases/get-user-from-bearer-token.test.ts +64 -0
- package/src/user/tests/use-cases/get-user-from-x-frigg-headers.test.ts +440 -0
- package/src/user/tests/use-cases/login-user.test.ts +220 -0
- package/src/user/use-cases/authenticate-user.ts +98 -0
- package/src/user/use-cases/authenticate-with-shared-secret.test.ts +127 -0
- package/src/user/use-cases/authenticate-with-shared-secret.ts +19 -0
- package/src/user/use-cases/create-individual-user.ts +59 -0
- package/src/user/use-cases/create-organization-user.ts +44 -0
- package/src/user/use-cases/create-token-for-user-id.ts +19 -0
- package/src/user/use-cases/get-user-from-adopter-jwt.ts +40 -0
- package/{user/use-cases/get-user-from-bearer-token.js → src/user/use-cases/get-user-from-bearer-token.ts} +23 -30
- package/src/user/use-cases/get-user-from-x-frigg-headers.ts +119 -0
- package/src/user/use-cases/login-user.ts +110 -0
- package/src/user/user.ts +125 -0
- package/{utils/backend-path.js → src/utils/backend-path.ts} +5 -8
- package/src/utils/index.ts +2 -0
- package/src/websocket/index.ts +7 -0
- package/src/websocket/repositories/websocket-connection-repository-documentdb.ts +93 -0
- package/src/websocket/repositories/websocket-connection-repository-factory.ts +26 -0
- package/src/websocket/repositories/websocket-connection-repository-interface.ts +47 -0
- package/src/websocket/repositories/websocket-connection-repository-mongo.ts +77 -0
- package/src/websocket/repositories/websocket-connection-repository-postgres.ts +94 -0
- package/src/websocket/repositories/websocket-connection-repository.test.ts +220 -0
- package/src/websocket/repositories/websocket-connection-repository.ts +101 -0
- package/tsconfig.json +17 -0
- package/tsconfig.test.json +10 -0
- package/workflows/frigg-workflow.ts +322 -0
- package/workflows/index.ts +205 -0
- package/workflows/steps/fan-out-step.ts +275 -0
- package/workflows/steps/function-step.ts +174 -0
- package/workflows/steps/index.ts +30 -0
- package/workflows/steps/workflow-step.ts +115 -0
- package/workflows/use-cases/create-workflow.ts +332 -0
- package/workflows/use-cases/execute-workflow-step.ts +465 -0
- package/workflows/use-cases/execute-workflow.ts +403 -0
- package/workflows/workflow-execution-repository.ts +415 -0
- package/workflows/workflow-execution.ts +209 -0
- package/workflows/workflow-queue-service.ts +379 -0
- package/workflows/workflow-repository.ts +295 -0
- package/workflows/workflow.ts +117 -0
- package/admin-scripts/index.js +0 -52
- package/admin-scripts/repositories/admin-api-key-repository-documentdb.js +0 -21
- package/admin-scripts/repositories/admin-api-key-repository-factory.js +0 -51
- package/admin-scripts/repositories/admin-api-key-repository-interface.js +0 -121
- package/admin-scripts/repositories/admin-api-key-repository-mongo.js +0 -155
- package/admin-scripts/repositories/admin-api-key-repository-postgres.js +0 -189
- package/admin-scripts/repositories/admin-process-repository-documentdb.js +0 -21
- package/admin-scripts/repositories/admin-process-repository-factory.js +0 -49
- package/admin-scripts/repositories/admin-process-repository-interface.js +0 -150
- package/admin-scripts/repositories/admin-process-repository-mongo.js +0 -213
- package/admin-scripts/repositories/admin-process-repository-postgres.js +0 -251
- package/admin-scripts/repositories/script-execution-repository-documentdb.js +0 -21
- package/admin-scripts/repositories/script-execution-repository-factory.js +0 -51
- package/admin-scripts/repositories/script-execution-repository-interface.js +0 -193
- package/admin-scripts/repositories/script-execution-repository-mongo.js +0 -278
- package/admin-scripts/repositories/script-execution-repository-postgres.js +0 -320
- package/admin-scripts/repositories/script-schedule-repository-documentdb.js +0 -21
- package/admin-scripts/repositories/script-schedule-repository-factory.js +0 -49
- package/admin-scripts/repositories/script-schedule-repository-interface.js +0 -108
- package/admin-scripts/repositories/script-schedule-repository-mongo.js +0 -179
- package/admin-scripts/repositories/script-schedule-repository-postgres.js +0 -210
- package/application/commands/admin-script-commands.js +0 -348
- package/application/commands/credential-commands.js +0 -245
- package/application/commands/entity-commands.js +0 -336
- package/application/commands/integration-commands.js +0 -216
- package/application/index.js +0 -75
- package/assertions/get.js +0 -149
- package/assertions/index.js +0 -16
- package/assertions/jest.config.js +0 -5
- package/associations/association.js +0 -80
- package/core/Delegate.js +0 -29
- package/core/Worker.js +0 -93
- package/core/index.js +0 -6
- package/core/load-installed-modules.js +0 -28
- package/credential/credential-router.js +0 -262
- package/credential/repositories/credential-repository-documentdb.js +0 -374
- package/credential/repositories/credential-repository-factory.js +0 -52
- package/credential/repositories/credential-repository-interface.js +0 -104
- package/credential/repositories/credential-repository-mongo.js +0 -310
- package/credential/repositories/credential-repository-postgres.js +0 -328
- package/credential/repositories/credential-repository.js +0 -302
- package/credential/use-cases/delete-credential-for-user.js +0 -50
- package/credential/use-cases/get-credential-for-user.js +0 -43
- package/credential/use-cases/list-credentials-for-user.js +0 -31
- package/credential/use-cases/reauthorize-credential.js +0 -103
- package/credential/use-cases/update-authentication-status.js +0 -18
- package/database/config.js +0 -108
- package/database/documentdb-encryption-service.js +0 -346
- package/database/documentdb-utils.js +0 -145
- package/database/encryption/encryption-schema-registry.js +0 -314
- package/database/index.js +0 -25
- package/database/jest.config.js +0 -5
- package/database/prisma.js +0 -193
- package/database/repositories/health-check-repository-factory.js +0 -50
- package/database/repositories/health-check-repository-interface.js +0 -92
- package/database/repositories/health-check-repository-mongodb.js +0 -89
- package/database/repositories/health-check-repository-postgres.js +0 -82
- package/database/use-cases/check-database-health-use-case.js +0 -30
- package/database/use-cases/check-database-state-use-case.js +0 -82
- package/database/use-cases/get-database-state-via-worker-use-case.js +0 -64
- package/database/use-cases/get-migration-status-use-case.js +0 -95
- package/database/use-cases/run-database-migration-use-case.js +0 -171
- package/database/use-cases/test-encryption-use-case.js +0 -252
- package/database/use-cases/trigger-database-migration-use-case.js +0 -158
- package/database/utils/mongodb-collection-utils.js +0 -102
- package/database/utils/mongodb-schema-init.js +0 -114
- package/database/utils/prisma-runner.js +0 -547
- package/database/utils/prisma-schema-parser.js +0 -182
- package/encrypt/Cryptor.js +0 -107
- package/encrypt/aes-encryption-key-provider.js +0 -82
- package/encrypt/encryption-key-provider-interface.js +0 -50
- package/encrypt/index.js +0 -3
- package/errors/base-error.js +0 -23
- package/errors/client-safe-error.js +0 -26
- package/errors/halt-error.js +0 -10
- package/errors/index.js +0 -17
- package/errors/validation-errors.js +0 -23
- package/extensions/bootstrap-runner.js +0 -43
- package/extensions/extension-loader.js +0 -167
- package/extensions/index.js +0 -37
- package/extensions/initialize-app.js +0 -123
- package/extensions/route-mounter.js +0 -59
- package/extensions/schema-composer.js +0 -188
- package/generated/prisma-mongodb/runtime/library.js +0 -146
- package/generated/prisma-postgresql/runtime/library.js +0 -146
- package/handlers/app-definition-loader.js +0 -81
- package/handlers/app-handler-helpers.js +0 -68
- package/handlers/database-migration-handler.js +0 -246
- package/handlers/middleware/admin-auth.js +0 -53
- package/handlers/routers/admin.js +0 -474
- package/handlers/routers/auth.js +0 -57
- package/handlers/routers/db-migration.handler.js +0 -28
- package/handlers/routers/db-migration.js +0 -362
- package/handlers/routers/docs.js +0 -180
- package/handlers/routers/health.js +0 -317
- package/handlers/routers/integration-defined-routers.js +0 -56
- package/handlers/routers/integration-webhook-routers.js +0 -88
- package/handlers/routers/middleware/loadUser.js +0 -39
- package/handlers/routers/middleware/requireAdmin.js +0 -43
- package/handlers/routers/middleware/requireLoggedInUser.js +0 -19
- package/handlers/routers/user.js +0 -79
- package/handlers/use-cases/check-integrations-health-use-case.js +0 -51
- package/handlers/workers/db-migration.js +0 -391
- package/handlers/workers/integration-defined-workers.js +0 -38
- package/index.js +0 -220
- package/infrastructure/scheduler/index.js +0 -37
- package/infrastructure/scheduler/netlify-scheduler-adapter.js +0 -185
- package/infrastructure/scheduler/scheduler-service-factory.js +0 -80
- package/infrastructure/scheduler/scheduler-service-interface.js +0 -47
- package/integrations/index.js +0 -25
- package/integrations/integration-router.js +0 -2354
- package/integrations/options.js +0 -80
- package/integrations/repositories/integration-mapping-repository-factory.js +0 -53
- package/integrations/repositories/integration-mapping-repository-interface.js +0 -106
- package/integrations/repositories/integration-mapping-repository-mongo.js +0 -161
- package/integrations/repositories/integration-mapping-repository-postgres.js +0 -227
- package/integrations/repositories/integration-mapping-repository.js +0 -156
- package/integrations/repositories/integration-repository-factory.js +0 -51
- package/integrations/repositories/integration-repository-interface.js +0 -145
- package/integrations/repositories/integration-repository-mongo.js +0 -303
- package/integrations/repositories/integration-repository-postgres.js +0 -352
- package/integrations/repositories/process-repository-factory.js +0 -50
- package/integrations/repositories/process-repository-interface.js +0 -94
- package/integrations/repositories/process-repository-mongo.js +0 -194
- package/integrations/repositories/process-repository-postgres.js +0 -217
- package/integrations/tests/doubles/dummy-integration-class.js +0 -178
- package/integrations/tests/doubles/test-integration-repository.js +0 -139
- package/integrations/use-cases/create-integration.js +0 -87
- package/integrations/use-cases/create-process.js +0 -139
- package/integrations/use-cases/delete-integration-for-user.js +0 -102
- package/integrations/use-cases/execute-proxy-request.js +0 -564
- package/integrations/use-cases/find-integration-context-by-external-entity-id.js +0 -72
- package/integrations/use-cases/get-integration-for-user.js +0 -93
- package/integrations/use-cases/get-integration-instance-by-definition.js +0 -73
- package/integrations/use-cases/get-integrations-for-user.js +0 -91
- package/integrations/use-cases/get-possible-integrations.js +0 -27
- package/integrations/use-cases/get-process.js +0 -86
- package/integrations/use-cases/index.js +0 -21
- package/integrations/use-cases/update-integration-messages.js +0 -44
- package/integrations/use-cases/update-integration-status.js +0 -32
- package/integrations/use-cases/update-integration.js +0 -92
- package/integrations/use-cases/update-process-metrics.js +0 -201
- package/integrations/use-cases/update-process-state.js +0 -121
- package/integrations/utils/map-integration-dto.js +0 -43
- package/jest-global-setup-noop.js +0 -3
- package/jest-global-teardown-noop.js +0 -3
- package/jest-setup.js +0 -2
- package/jest-teardown.js +0 -2
- package/jest.config.js +0 -21
- package/lambda/TimeoutCatcher.js +0 -45
- package/lambda/index.js +0 -3
- package/logs/index.js +0 -7
- package/modules/ModuleConstants.js +0 -10
- package/modules/domain/entities/AuthorizationSession.js +0 -131
- package/modules/domain/entities/index.js +0 -10
- package/modules/index.js +0 -15
- package/modules/module.js +0 -261
- package/modules/repositories/authorization-session-repository-factory.js +0 -53
- package/modules/repositories/authorization-session-repository-interface.js +0 -75
- package/modules/repositories/authorization-session-repository-mongo.js +0 -169
- package/modules/repositories/authorization-session-repository-postgres.js +0 -170
- package/modules/repositories/module-repository-documentdb.js +0 -383
- package/modules/repositories/module-repository-factory.js +0 -38
- package/modules/repositories/module-repository-interface.js +0 -142
- package/modules/repositories/module-repository-mongo.js +0 -443
- package/modules/repositories/module-repository-postgres.js +0 -490
- package/modules/repositories/module-repository.js +0 -373
- package/modules/requester/api-key.js +0 -50
- package/modules/requester/basic.js +0 -42
- package/modules/requester/oauth-2.js +0 -385
- package/modules/requester/requester.js +0 -167
- package/modules/test/mock-api/mocks/hubspot.js +0 -43
- package/modules/tests/doubles/test-module-factory.js +0 -22
- package/modules/use-cases/delete-module-entity.js +0 -23
- package/modules/use-cases/get-authorization-requirements.js +0 -110
- package/modules/use-cases/get-entities-for-user.js +0 -32
- package/modules/use-cases/get-entity-options-by-id.js +0 -73
- package/modules/use-cases/get-entity-options-by-type.js +0 -34
- package/modules/use-cases/get-module-entity-by-id.js +0 -16
- package/modules/use-cases/get-module-instance-from-type.js +0 -31
- package/modules/use-cases/get-module.js +0 -77
- package/modules/use-cases/process-authorization-step.js +0 -160
- package/modules/use-cases/refresh-entity-options.js +0 -74
- package/modules/use-cases/start-authorization-session.js +0 -86
- package/modules/use-cases/test-module-auth.js +0 -74
- package/modules/use-cases/update-module-entity.js +0 -27
- package/modules/utils/map-module-dto.js +0 -18
- package/openapi/openapi-spec-generator.js +0 -370
- package/openapi/openapi-v1.yaml +0 -1360
- package/openapi/openapi-v2.yaml +0 -1535
- package/prisma-postgresql/migrations/20260222000000_add_admin_process_and_script_schedule/migration.sql +0 -55
- package/providers/index.js +0 -13
- package/providers/resolve-provider.js +0 -93
- package/queues/index.js +0 -23
- package/queues/providers/index.js +0 -7
- package/queues/providers/netlify-background-provider.js +0 -76
- package/queues/providers/qstash-queue-provider.js +0 -122
- package/queues/queue-client-interface.js +0 -55
- package/queues/queue-provider-factory.js +0 -93
- package/queues/queue-provider.js +0 -46
- package/queues/queuer-util.js +0 -74
- package/syncs/repositories/sync-repository-factory.js +0 -43
- package/syncs/repositories/sync-repository-interface.js +0 -113
- package/syncs/repositories/sync-repository-mongo.js +0 -239
- package/syncs/repositories/sync-repository-postgres.js +0 -325
- package/syncs/sync.js +0 -117
- package/token/repositories/token-repository-documentdb.js +0 -137
- package/token/repositories/token-repository-factory.js +0 -38
- package/token/repositories/token-repository-interface.js +0 -131
- package/token/repositories/token-repository-mongo.js +0 -219
- package/token/repositories/token-repository-postgres.js +0 -264
- package/token/repositories/token-repository.js +0 -219
- package/types/assertions/index.d.ts +0 -83
- package/types/associations/index.d.ts +0 -57
- package/types/core/index.d.ts +0 -99
- package/types/database/index.d.ts +0 -11
- package/types/encrypt/index.d.ts +0 -7
- package/types/errors/index.d.ts +0 -73
- package/types/eslint-config/index.d.ts +0 -41
- package/types/index.d.ts +0 -14
- package/types/integrations/index.d.ts +0 -186
- package/types/lambda/index.d.ts +0 -31
- package/types/logs/index.d.ts +0 -5
- package/types/module-plugin/index.d.ts +0 -241
- package/types/prettier-config/index.d.ts +0 -6
- package/types/syncs/index.d.ts +0 -111
- package/types/test-environment/index.d.ts +0 -17
- package/types/tsconfig.json +0 -105
- package/user/repositories/user-repository-documentdb.js +0 -441
- package/user/repositories/user-repository-factory.js +0 -52
- package/user/repositories/user-repository-interface.js +0 -201
- package/user/repositories/user-repository-mongo.js +0 -308
- package/user/repositories/user-repository-postgres.js +0 -360
- package/user/use-cases/authenticate-user.js +0 -125
- package/user/use-cases/authenticate-with-shared-secret.js +0 -48
- package/user/use-cases/create-individual-user.js +0 -62
- package/user/use-cases/create-organization-user.js +0 -47
- package/user/use-cases/create-token-for-user-id.js +0 -30
- package/user/use-cases/delete-user.js +0 -47
- package/user/use-cases/get-user-from-adopter-jwt.js +0 -147
- package/user/use-cases/get-user-from-x-frigg-headers.js +0 -135
- package/user/use-cases/login-user.js +0 -122
- package/user/user.js +0 -139
- package/utils/index.js +0 -9
- package/websocket/repositories/websocket-connection-repository-documentdb.js +0 -144
- package/websocket/repositories/websocket-connection-repository-factory.js +0 -40
- package/websocket/repositories/websocket-connection-repository-interface.js +0 -106
- package/websocket/repositories/websocket-connection-repository-mongo.js +0 -166
- package/websocket/repositories/websocket-connection-repository-postgres.js +0 -207
- package/websocket/repositories/websocket-connection-repository.js +0 -167
- package/websocket/websocket-message-sender-interface.js +0 -38
package/core/CLAUDE.md
CHANGED
|
@@ -4,12 +4,12 @@ This file provides guidance to Claude Code when working with the Frigg Framework
|
|
|
4
4
|
|
|
5
5
|
## Critical Context (Read First)
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
7
|
+
- **Package Purpose**: Core runtime system and foundational classes for Frigg Lambda execution
|
|
8
|
+
- **Main Components**: Handler factory, Worker base class, Delegate pattern, Module loading
|
|
9
|
+
- **Core Architecture**: Lambda-optimized runtime with connection pooling, error handling, secrets management
|
|
10
|
+
- **Key Integration**: AWS Lambda, SQS job processing, MongoDB connections, AWS Secrets Manager
|
|
11
|
+
- **Security Model**: Automatic secrets injection, database connection management, user-facing error sanitization
|
|
12
|
+
- **DO NOT**: Expose internal errors to users, bypass connection pooling, skip database initialization
|
|
13
13
|
|
|
14
14
|
## Core Components Architecture
|
|
15
15
|
|
|
@@ -18,50 +18,45 @@ This file provides guidance to Claude Code when working with the Frigg Framework
|
|
|
18
18
|
**Purpose**: Factory for creating Lambda handlers with consistent infrastructure setup
|
|
19
19
|
|
|
20
20
|
**Key Features**:
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- **Connection Optimization**: `context.callbackWaitsForEmptyEventLoop = false` for reuse
|
|
21
|
+
- **Database Connection Management**: Automatic MongoDB connection with pooling
|
|
22
|
+
- **Secrets Management**: AWS Secrets Manager integration via `SECRET_ARN` env var
|
|
23
|
+
- **Error Sanitization**: Prevents internal details from leaking to end users
|
|
24
|
+
- **Debug Logging**: Request/response logging with structured debug info
|
|
25
|
+
- **Connection Optimization**: `context.callbackWaitsForEmptyEventLoop = false` for reuse
|
|
27
26
|
|
|
28
27
|
**Handler Configuration Options**:
|
|
29
|
-
|
|
30
28
|
```javascript
|
|
31
29
|
const handler = createHandler({
|
|
32
|
-
eventName: 'MyIntegration',
|
|
33
|
-
isUserFacingResponse: true,
|
|
30
|
+
eventName: 'MyIntegration', // For logging/debugging
|
|
31
|
+
isUserFacingResponse: true, // true = sanitize errors, false = pass through
|
|
34
32
|
method: async (event, context) => {}, // Your Lambda function logic
|
|
35
|
-
shouldUseDatabase: true
|
|
33
|
+
shouldUseDatabase: true // false = skip MongoDB connection
|
|
36
34
|
});
|
|
37
35
|
```
|
|
38
36
|
|
|
39
37
|
**Error Handling Patterns**:
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
- **Halt Errors**: `error.isHaltError = true` logs but returns success (no retry)
|
|
38
|
+
- **User-Facing**: Returns 500 with generic "Internal Error Occurred" message
|
|
39
|
+
- **Server-to-Server**: Re-throws errors for AWS to handle
|
|
40
|
+
- **Halt Errors**: `error.isHaltError = true` logs but returns success (no retry)
|
|
44
41
|
|
|
45
42
|
### Worker Base Class (`Worker.js:9-83`)
|
|
46
43
|
|
|
47
44
|
**Purpose**: Base class for SQS job processing with standardized patterns
|
|
48
45
|
|
|
49
46
|
**Core Responsibilities**:
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
- **Error Handling**: Structured error handling for async job processing
|
|
47
|
+
- **Queue Management**: Get SQS queue URLs and send messages
|
|
48
|
+
- **Batch Processing**: Process multiple SQS records in sequence
|
|
49
|
+
- **Message Validation**: Extensible parameter validation system
|
|
50
|
+
- **Error Handling**: Structured error handling for async job processing
|
|
55
51
|
|
|
56
52
|
**Usage Pattern**:
|
|
57
|
-
|
|
58
53
|
```javascript
|
|
59
54
|
class MyWorker extends Worker {
|
|
60
55
|
async _run(params, context = {}) {
|
|
61
56
|
// Your job processing logic here
|
|
62
57
|
// params are already JSON.parsed from SQS message body
|
|
63
58
|
}
|
|
64
|
-
|
|
59
|
+
|
|
65
60
|
_validateParams(params) {
|
|
66
61
|
// Validate required parameters
|
|
67
62
|
this._verifyParamExists(params, 'requiredField');
|
|
@@ -74,17 +69,13 @@ await worker.run(event, context); // Process SQS Records
|
|
|
74
69
|
```
|
|
75
70
|
|
|
76
71
|
**Message Sending**:
|
|
77
|
-
|
|
78
72
|
```javascript
|
|
79
|
-
await worker.send(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
},
|
|
86
|
-
delaySeconds
|
|
87
|
-
);
|
|
73
|
+
await worker.send({
|
|
74
|
+
QueueUrl: 'https://sqs.region.amazonaws.com/account/queue',
|
|
75
|
+
jobType: 'processAttachment',
|
|
76
|
+
integrationId: 'abc123',
|
|
77
|
+
// ... other job parameters
|
|
78
|
+
}, delaySeconds);
|
|
88
79
|
```
|
|
89
80
|
|
|
90
81
|
### Delegate Pattern System (`Delegate.js:3-27`)
|
|
@@ -92,35 +83,29 @@ await worker.send(
|
|
|
92
83
|
**Purpose**: Observer/delegation pattern for decoupled component communication
|
|
93
84
|
|
|
94
85
|
**Core Concepts**:
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
- **Null Safety**: Gracefully handles missing delegates
|
|
86
|
+
- **Notification System**: Components notify delegates of events/state changes
|
|
87
|
+
- **Type Safety**: `delegateTypes` array defines valid notification strings
|
|
88
|
+
- **Bidirectional**: Supports both sending and receiving notifications
|
|
89
|
+
- **Null Safety**: Gracefully handles missing delegates
|
|
100
90
|
|
|
101
91
|
**Implementation Pattern**:
|
|
102
|
-
|
|
103
92
|
```javascript
|
|
104
93
|
class MyIntegration extends Delegate {
|
|
105
94
|
constructor(params) {
|
|
106
95
|
super(params);
|
|
107
|
-
this.delegateTypes = [
|
|
108
|
-
'processComplete',
|
|
109
|
-
'errorOccurred',
|
|
110
|
-
'statusUpdate',
|
|
111
|
-
];
|
|
96
|
+
this.delegateTypes = ['processComplete', 'errorOccurred', 'statusUpdate'];
|
|
112
97
|
}
|
|
113
|
-
|
|
98
|
+
|
|
114
99
|
async processData(data) {
|
|
115
100
|
// Do work
|
|
116
101
|
await this.notify('statusUpdate', { progress: 50 });
|
|
117
102
|
// More work
|
|
118
103
|
await this.notify('processComplete', { result: data });
|
|
119
104
|
}
|
|
120
|
-
|
|
105
|
+
|
|
121
106
|
async receiveNotification(notifier, delegateString, object) {
|
|
122
107
|
// Handle notifications from other components
|
|
123
|
-
switch
|
|
108
|
+
switch(delegateString) {
|
|
124
109
|
case 'dataReady':
|
|
125
110
|
await this.processData(object);
|
|
126
111
|
break;
|
|
@@ -134,63 +119,55 @@ class MyIntegration extends Delegate {
|
|
|
134
119
|
**Purpose**: Dynamic loading and registration of integration modules
|
|
135
120
|
|
|
136
121
|
**Key Features**:
|
|
137
|
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
- **Dependency Resolution**: Manage inter-module dependencies
|
|
122
|
+
- **Package Discovery**: Automatically find `@friggframework/api-module-*` packages
|
|
123
|
+
- **Module Registration**: Load and register integration classes
|
|
124
|
+
- **Configuration Management**: Handle module-specific configuration
|
|
125
|
+
- **Dependency Resolution**: Manage inter-module dependencies
|
|
142
126
|
|
|
143
127
|
## Runtime Lifecycle & Patterns
|
|
144
128
|
|
|
145
129
|
### Lambda Handler Lifecycle
|
|
146
|
-
|
|
147
130
|
1. **Pre-Execution Setup**:
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
```
|
|
131
|
+
```javascript
|
|
132
|
+
initDebugLog(eventName, event); // Debug logging setup
|
|
133
|
+
await secretsToEnv(); // Secrets Manager injection
|
|
134
|
+
context.callbackWaitsForEmptyEventLoop = false; // Connection pooling
|
|
135
|
+
```
|
|
154
136
|
|
|
155
137
|
2. **Database Connection**:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
```
|
|
138
|
+
```javascript
|
|
139
|
+
if (shouldUseDatabase) {
|
|
140
|
+
await connectToDatabase(); // MongoDB connection with pooling
|
|
141
|
+
}
|
|
142
|
+
```
|
|
162
143
|
|
|
163
144
|
3. **Method Execution**:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
```
|
|
145
|
+
```javascript
|
|
146
|
+
return await method(event, context); // Your integration logic
|
|
147
|
+
```
|
|
168
148
|
|
|
169
149
|
4. **Error Handling & Cleanup**:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
150
|
+
```javascript
|
|
151
|
+
flushDebugLog(error); // Debug info flush on error
|
|
152
|
+
// Sanitized error response for user-facing endpoints
|
|
153
|
+
```
|
|
174
154
|
|
|
175
155
|
### SQS Job Processing Lifecycle
|
|
176
|
-
|
|
177
156
|
1. **Batch Processing**: Process all records in `event.Records` sequentially
|
|
178
|
-
2. **Message Parsing**: JSON.parse message body for parameters
|
|
157
|
+
2. **Message Parsing**: JSON.parse message body for parameters
|
|
179
158
|
3. **Validation**: Run custom validation on parsed parameters
|
|
180
159
|
4. **Execution**: Call `_run()` method with validated parameters
|
|
181
160
|
5. **Error Propagation**: Let AWS handle retries/DLQ for failed jobs
|
|
182
161
|
|
|
183
162
|
### Secrets Management Integration
|
|
184
|
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
- **Caching**: Secrets cached for Lambda container lifetime
|
|
163
|
+
- **Automatic Injection**: If `SECRET_ARN` environment variable is set
|
|
164
|
+
- **Environment Variables**: Secrets automatically set as `process.env` variables
|
|
165
|
+
- **Security**: No secrets logging or exposure in error messages
|
|
166
|
+
- **Caching**: Secrets cached for Lambda container lifetime
|
|
189
167
|
|
|
190
168
|
## Database Connection Patterns
|
|
191
169
|
|
|
192
170
|
### Connection Pooling Strategy
|
|
193
|
-
|
|
194
171
|
```javascript
|
|
195
172
|
// Mongoose connection reuse across Lambda invocations
|
|
196
173
|
context.callbackWaitsForEmptyEventLoop = false;
|
|
@@ -198,51 +175,45 @@ await connectToDatabase(); // Reuses existing connection if available
|
|
|
198
175
|
```
|
|
199
176
|
|
|
200
177
|
### Database Usage Patterns
|
|
201
|
-
|
|
202
178
|
```javascript
|
|
203
179
|
// Conditional database connection
|
|
204
180
|
const handler = createHandler({
|
|
205
|
-
shouldUseDatabase: false,
|
|
181
|
+
shouldUseDatabase: false, // Skip for database-free operations
|
|
206
182
|
method: async (event) => {
|
|
207
183
|
// No DB operations needed
|
|
208
184
|
return { statusCode: 200, body: 'OK' };
|
|
209
|
-
}
|
|
185
|
+
}
|
|
210
186
|
});
|
|
211
187
|
```
|
|
212
188
|
|
|
213
189
|
## Error Handling Architecture
|
|
214
190
|
|
|
215
191
|
### Error Classification
|
|
216
|
-
|
|
217
192
|
1. **User-Facing Errors**: `isUserFacingResponse: true`
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
- Logs full error details internally
|
|
193
|
+
- Returns generic 500 error message
|
|
194
|
+
- Prevents information disclosure
|
|
195
|
+
- Logs full error details internally
|
|
222
196
|
|
|
223
197
|
2. **Server-to-Server Errors**: `isUserFacingResponse: false`
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
- Enables proper retry mechanisms
|
|
198
|
+
- Re-throws original error for AWS handling
|
|
199
|
+
- Used for SQS, SNS, and internal API calls
|
|
200
|
+
- Enables proper retry mechanisms
|
|
228
201
|
|
|
229
202
|
3. **Halt Errors**: `error.isHaltError = true`
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
203
|
+
- Logs error but returns success
|
|
204
|
+
- Prevents infinite retries for known issues
|
|
205
|
+
- Used for graceful degradation scenarios
|
|
233
206
|
|
|
234
207
|
### Debug Logging Strategy
|
|
235
|
-
|
|
236
208
|
```javascript
|
|
237
|
-
initDebugLog(eventName, event);
|
|
209
|
+
initDebugLog(eventName, event); // Start logging context
|
|
238
210
|
// ... your code ...
|
|
239
|
-
flushDebugLog(error);
|
|
211
|
+
flushDebugLog(error); // Flush on error (includes full context)
|
|
240
212
|
```
|
|
241
213
|
|
|
242
214
|
## Integration Development Patterns
|
|
243
215
|
|
|
244
216
|
### Extending Worker for Job Processing
|
|
245
|
-
|
|
246
217
|
```javascript
|
|
247
218
|
class AttachmentWorker extends Worker {
|
|
248
219
|
_validateParams(params) {
|
|
@@ -250,7 +221,7 @@ class AttachmentWorker extends Worker {
|
|
|
250
221
|
this._verifyParamExists(params, 'attachmentUrl');
|
|
251
222
|
this._verifyParamExists(params, 'destination');
|
|
252
223
|
}
|
|
253
|
-
|
|
224
|
+
|
|
254
225
|
async _run(params, context) {
|
|
255
226
|
const { integrationId, attachmentUrl, destination } = params;
|
|
256
227
|
// Process attachment upload/download
|
|
@@ -261,39 +232,37 @@ class AttachmentWorker extends Worker {
|
|
|
261
232
|
```
|
|
262
233
|
|
|
263
234
|
### Creating Custom Handlers
|
|
264
|
-
|
|
265
235
|
```javascript
|
|
266
236
|
const myIntegrationHandler = createHandler({
|
|
267
237
|
eventName: 'MyIntegration',
|
|
268
|
-
isUserFacingResponse: true,
|
|
269
|
-
shouldUseDatabase: true,
|
|
238
|
+
isUserFacingResponse: true, // Sanitize errors for users
|
|
239
|
+
shouldUseDatabase: true, // Need database access
|
|
270
240
|
method: async (event, context) => {
|
|
271
241
|
// Your integration logic here
|
|
272
242
|
// Database is already connected
|
|
273
243
|
// Secrets are in process.env
|
|
274
|
-
|
|
244
|
+
|
|
275
245
|
return {
|
|
276
246
|
statusCode: 200,
|
|
277
|
-
body: JSON.stringify({ success: true })
|
|
247
|
+
body: JSON.stringify({ success: true })
|
|
278
248
|
};
|
|
279
|
-
}
|
|
249
|
+
}
|
|
280
250
|
});
|
|
281
251
|
```
|
|
282
252
|
|
|
283
253
|
### Delegate Pattern for Integration Communication
|
|
284
|
-
|
|
285
254
|
```javascript
|
|
286
255
|
class IntegrationManager extends Delegate {
|
|
287
256
|
constructor() {
|
|
288
257
|
super();
|
|
289
258
|
this.delegateTypes = [
|
|
290
259
|
'authenticationComplete',
|
|
291
|
-
'syncStarted',
|
|
260
|
+
'syncStarted',
|
|
292
261
|
'syncComplete',
|
|
293
|
-
'errorOccurred'
|
|
262
|
+
'errorOccurred'
|
|
294
263
|
];
|
|
295
264
|
}
|
|
296
|
-
|
|
265
|
+
|
|
297
266
|
async startSync(integrationId) {
|
|
298
267
|
await this.notify('syncStarted', { integrationId });
|
|
299
268
|
// ... sync logic ...
|
|
@@ -305,24 +274,21 @@ class IntegrationManager extends Delegate {
|
|
|
305
274
|
## Performance Optimization Patterns
|
|
306
275
|
|
|
307
276
|
### Connection Reuse
|
|
308
|
-
|
|
309
277
|
```javascript
|
|
310
278
|
// ALWAYS set this in handlers for performance
|
|
311
279
|
context.callbackWaitsForEmptyEventLoop = false;
|
|
312
280
|
```
|
|
313
281
|
|
|
314
282
|
### Conditional Database Usage
|
|
315
|
-
|
|
316
283
|
```javascript
|
|
317
284
|
// Skip database for lightweight operations
|
|
318
285
|
const handler = createHandler({
|
|
319
|
-
shouldUseDatabase: false,
|
|
320
|
-
method: healthCheckMethod
|
|
286
|
+
shouldUseDatabase: false, // Faster cold starts
|
|
287
|
+
method: healthCheckMethod
|
|
321
288
|
});
|
|
322
289
|
```
|
|
323
290
|
|
|
324
291
|
### SQS Batch Processing Optimization
|
|
325
|
-
|
|
326
292
|
```javascript
|
|
327
293
|
// Process records sequentially (not parallel) for resource control
|
|
328
294
|
for (const record of records) {
|
|
@@ -339,7 +305,6 @@ The Frigg Framework follows DDD/Hexagonal Architecture with clear separation bet
|
|
|
339
305
|
**Purpose**: Abstract database and external system access into dedicated repository classes.
|
|
340
306
|
|
|
341
307
|
**Structure**:
|
|
342
|
-
|
|
343
308
|
```javascript
|
|
344
309
|
// Example: packages/core/database/websocket-connection-repository.js
|
|
345
310
|
class WebsocketConnectionRepository {
|
|
@@ -370,28 +335,25 @@ class WebsocketConnectionRepository {
|
|
|
370
335
|
```
|
|
371
336
|
|
|
372
337
|
**Repository Responsibilities**:
|
|
373
|
-
|
|
374
|
-
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
-
|
|
379
|
-
- ❌ **NO orchestration** - Don't coordinate multiple operations
|
|
338
|
+
- ✅ **CRUD operations** - Create, Read, Update, Delete database records
|
|
339
|
+
- ✅ **Query execution** - Run database queries and return results
|
|
340
|
+
- ✅ **Data access only** - No interpretation or decision-making
|
|
341
|
+
- ✅ **Atomic operations** - Each method performs one database operation
|
|
342
|
+
- ❌ **NO business logic** - Don't decide what data means or what to do with it
|
|
343
|
+
- ❌ **NO orchestration** - Don't coordinate multiple operations
|
|
380
344
|
|
|
381
345
|
**Real Repository Examples**:
|
|
382
|
-
|
|
383
|
-
-
|
|
384
|
-
-
|
|
385
|
-
-
|
|
386
|
-
-
|
|
387
|
-
- `HealthCheckRepository` - Health check data access (packages/core/database/health-check-repository.js)
|
|
346
|
+
- `WebsocketConnectionRepository` - WebSocket persistence (packages/core/database/websocket-connection-repository.js)
|
|
347
|
+
- `SyncRepository` - Sync object management (packages/core/syncs/sync-repository.js)
|
|
348
|
+
- `IntegrationMappingRepository` - Integration mappings (packages/core/integrations/integration-mapping-repository.js)
|
|
349
|
+
- `TokenRepository` - Token operations (packages/core/database/token-repository.js)
|
|
350
|
+
- `HealthCheckRepository` - Health check data access (packages/core/database/health-check-repository.js)
|
|
388
351
|
|
|
389
352
|
### Use Case Pattern in Core
|
|
390
353
|
|
|
391
354
|
**Purpose**: Contain business logic, orchestration, and workflow coordination.
|
|
392
355
|
|
|
393
356
|
**Structure**:
|
|
394
|
-
|
|
395
357
|
```javascript
|
|
396
358
|
// Example: packages/core/database/use-cases/check-database-health-use-case.js
|
|
397
359
|
class CheckDatabaseHealthUseCase {
|
|
@@ -402,8 +364,7 @@ class CheckDatabaseHealthUseCase {
|
|
|
402
364
|
|
|
403
365
|
async execute() {
|
|
404
366
|
// 1. Get raw data from repository
|
|
405
|
-
const { stateName, isConnected } =
|
|
406
|
-
this.repository.getDatabaseConnectionState();
|
|
367
|
+
const { stateName, isConnected } = this.repository.getDatabaseConnectionState();
|
|
407
368
|
|
|
408
369
|
// 2. Apply business logic - determine health status
|
|
409
370
|
const result = {
|
|
@@ -422,43 +383,38 @@ class CheckDatabaseHealthUseCase {
|
|
|
422
383
|
```
|
|
423
384
|
|
|
424
385
|
**Use Case Responsibilities**:
|
|
425
|
-
|
|
426
|
-
-
|
|
427
|
-
-
|
|
428
|
-
-
|
|
429
|
-
-
|
|
430
|
-
-
|
|
431
|
-
-
|
|
432
|
-
- ❌ **NO HTTP concerns** - Don't know about status codes or headers
|
|
386
|
+
- ✅ **Business logic** - Make decisions based on data
|
|
387
|
+
- ✅ **Orchestration** - Coordinate multiple repository calls
|
|
388
|
+
- ✅ **Validation** - Enforce business rules
|
|
389
|
+
- ✅ **Workflow** - Determine what happens next
|
|
390
|
+
- ✅ **Error handling** - Handle domain-specific errors
|
|
391
|
+
- ❌ **NO direct database access** - Always use repositories
|
|
392
|
+
- ❌ **NO HTTP concerns** - Don't know about status codes or headers
|
|
433
393
|
|
|
434
394
|
**Real Use Case Examples**:
|
|
435
|
-
|
|
436
|
-
-
|
|
437
|
-
- `TestEncryptionUseCase` - Encryption testing workflow (packages/core/database/use-cases/test-encryption-use-case.js)
|
|
395
|
+
- `CheckDatabaseHealthUseCase` - Database health business logic (packages/core/database/use-cases/check-database-health-use-case.js)
|
|
396
|
+
- `TestEncryptionUseCase` - Encryption testing workflow (packages/core/database/use-cases/test-encryption-use-case.js)
|
|
438
397
|
|
|
439
398
|
### Handler Pattern in Core
|
|
440
399
|
|
|
441
400
|
**Purpose**: Translate Lambda/HTTP/SQS events into use case calls.
|
|
442
401
|
|
|
443
402
|
**Handler Should ONLY**:
|
|
444
|
-
|
|
445
|
-
-
|
|
446
|
-
-
|
|
447
|
-
-
|
|
448
|
-
- Handle protocol-specific concerns (status codes, headers)
|
|
403
|
+
- Define routes and event handlers
|
|
404
|
+
- Call use cases (NOT repositories)
|
|
405
|
+
- Map use case results to HTTP/Lambda responses
|
|
406
|
+
- Handle protocol-specific concerns (status codes, headers)
|
|
449
407
|
|
|
450
408
|
**❌ WRONG - Handler contains business logic**:
|
|
451
|
-
|
|
452
409
|
```javascript
|
|
453
410
|
// BAD: Business logic in handler
|
|
454
411
|
router.get('/health', async (req, res) => {
|
|
455
412
|
const state = mongoose.connection.readyState;
|
|
456
|
-
const isHealthy = state === 1;
|
|
413
|
+
const isHealthy = state === 1; // ❌ Business logic in handler
|
|
457
414
|
|
|
458
|
-
if (isHealthy) {
|
|
459
|
-
// ❌ Orchestration in handler
|
|
415
|
+
if (isHealthy) { // ❌ Orchestration in handler
|
|
460
416
|
const pingStart = Date.now();
|
|
461
|
-
await mongoose.connection.db.admin().ping();
|
|
417
|
+
await mongoose.connection.db.admin().ping(); // ❌ Direct DB access
|
|
462
418
|
const responseTime = Date.now() - pingStart;
|
|
463
419
|
res.json({ status: 'healthy', responseTime });
|
|
464
420
|
}
|
|
@@ -466,12 +422,11 @@ router.get('/health', async (req, res) => {
|
|
|
466
422
|
```
|
|
467
423
|
|
|
468
424
|
**✅ CORRECT - Handler delegates to use case**:
|
|
469
|
-
|
|
470
425
|
```javascript
|
|
471
426
|
// GOOD: Handler calls use case
|
|
472
427
|
const healthCheckRepository = new HealthCheckRepository();
|
|
473
428
|
const checkDatabaseHealthUseCase = new CheckDatabaseHealthUseCase({
|
|
474
|
-
healthCheckRepository
|
|
429
|
+
healthCheckRepository
|
|
475
430
|
});
|
|
476
431
|
|
|
477
432
|
router.get('/health', async (req, res) => {
|
|
@@ -487,11 +442,9 @@ router.get('/health', async (req, res) => {
|
|
|
487
442
|
### Dependency Direction
|
|
488
443
|
|
|
489
444
|
**The Golden Rule**:
|
|
490
|
-
|
|
491
445
|
> "Handlers ONLY call Use Cases, NEVER Repositories or Business Logic directly"
|
|
492
446
|
|
|
493
447
|
**Correct Flow**:
|
|
494
|
-
|
|
495
448
|
```
|
|
496
449
|
Handler/Router (createHandler)
|
|
497
450
|
↓ calls
|
|
@@ -503,32 +456,28 @@ Database/External System
|
|
|
503
456
|
```
|
|
504
457
|
|
|
505
458
|
**Why This Matters**:
|
|
506
|
-
|
|
507
|
-
-
|
|
508
|
-
-
|
|
509
|
-
-
|
|
510
|
-
- **Flexibility**: Swap repository implementations without changing use cases
|
|
459
|
+
- **Testability**: Use cases can be tested with mocked repositories
|
|
460
|
+
- **Reusability**: Use cases can be called from handlers, CLI, background jobs
|
|
461
|
+
- **Maintainability**: Business logic is centralized, not scattered across handlers
|
|
462
|
+
- **Flexibility**: Swap repository implementations without changing use cases
|
|
511
463
|
|
|
512
464
|
### Migration from Old Patterns
|
|
513
465
|
|
|
514
466
|
**Old Pattern (Mongoose models everywhere)**:
|
|
515
|
-
|
|
516
467
|
```javascript
|
|
517
468
|
// BAD: Direct model access in handlers
|
|
518
469
|
const handler = createHandler({
|
|
519
470
|
method: async (event) => {
|
|
520
|
-
const user = await User.findById(event.userId);
|
|
521
|
-
if (!user.isActive) {
|
|
522
|
-
// ❌ Business logic in handler
|
|
471
|
+
const user = await User.findById(event.userId); // ❌ Direct model access
|
|
472
|
+
if (!user.isActive) { // ❌ Business logic in handler
|
|
523
473
|
throw new Error('User not active');
|
|
524
474
|
}
|
|
525
|
-
await Sync.create({ userId: user.id });
|
|
526
|
-
}
|
|
475
|
+
await Sync.create({ userId: user.id }); // ❌ Direct model access
|
|
476
|
+
}
|
|
527
477
|
});
|
|
528
478
|
```
|
|
529
479
|
|
|
530
480
|
**New Pattern (Repository + Use Case)**:
|
|
531
|
-
|
|
532
481
|
```javascript
|
|
533
482
|
// GOOD: Repository abstracts data access
|
|
534
483
|
class UserRepository {
|
|
@@ -553,8 +502,7 @@ class ActivateUserSyncUseCase {
|
|
|
553
502
|
async execute(userId) {
|
|
554
503
|
const user = await this.userRepo.findById(userId);
|
|
555
504
|
|
|
556
|
-
if (!user.isActive) {
|
|
557
|
-
// ✅ Business logic in use case
|
|
505
|
+
if (!user.isActive) { // ✅ Business logic in use case
|
|
558
506
|
throw new Error('User not active');
|
|
559
507
|
}
|
|
560
508
|
|
|
@@ -567,10 +515,10 @@ const handler = createHandler({
|
|
|
567
515
|
method: async (event) => {
|
|
568
516
|
const useCase = new ActivateUserSyncUseCase({
|
|
569
517
|
userRepository: new UserRepository(),
|
|
570
|
-
syncRepository: new SyncRepository()
|
|
518
|
+
syncRepository: new SyncRepository()
|
|
571
519
|
});
|
|
572
520
|
return await useCase.execute(event.userId);
|
|
573
|
-
}
|
|
521
|
+
}
|
|
574
522
|
});
|
|
575
523
|
```
|
|
576
524
|
|
|
@@ -585,7 +533,7 @@ class ProcessAttachmentWorker extends Worker {
|
|
|
585
533
|
// Inject repositories into use case
|
|
586
534
|
this.useCase = new ProcessAttachmentUseCase({
|
|
587
535
|
asanaRepository: new AsanaRepository(),
|
|
588
|
-
frontifyRepository: new FrontifyRepository()
|
|
536
|
+
frontifyRepository: new FrontifyRepository()
|
|
589
537
|
});
|
|
590
538
|
}
|
|
591
539
|
|
|
@@ -603,23 +551,20 @@ class ProcessAttachmentWorker extends Worker {
|
|
|
603
551
|
### When to Extract to Repository/Use Case
|
|
604
552
|
|
|
605
553
|
**Extract to Repository when you see**:
|
|
606
|
-
|
|
607
|
-
-
|
|
608
|
-
-
|
|
609
|
-
-
|
|
610
|
-
- File system or AWS SDK operations in handlers
|
|
554
|
+
- Direct Mongoose model calls (`User.findById()`, `Sync.create()`)
|
|
555
|
+
- Database queries in handlers or business logic
|
|
556
|
+
- External API calls scattered across codebase
|
|
557
|
+
- File system or AWS SDK operations in handlers
|
|
611
558
|
|
|
612
559
|
**Extract to Use Case when you see**:
|
|
613
|
-
|
|
614
|
-
-
|
|
615
|
-
-
|
|
616
|
-
-
|
|
617
|
-
- Workflow coordination
|
|
560
|
+
- Business logic in handlers (if/else based on data)
|
|
561
|
+
- Orchestration of multiple operations
|
|
562
|
+
- Validation and error handling logic
|
|
563
|
+
- Workflow coordination
|
|
618
564
|
|
|
619
565
|
### Testing with Repository/Use Case Pattern
|
|
620
566
|
|
|
621
567
|
**Repository Tests** (Integration tests with real DB):
|
|
622
|
-
|
|
623
568
|
```javascript
|
|
624
569
|
describe('WebsocketConnectionRepository', () => {
|
|
625
570
|
it('creates connection record', async () => {
|
|
@@ -631,18 +576,17 @@ describe('WebsocketConnectionRepository', () => {
|
|
|
631
576
|
```
|
|
632
577
|
|
|
633
578
|
**Use Case Tests** (Unit tests with mocked repositories):
|
|
634
|
-
|
|
635
579
|
```javascript
|
|
636
580
|
describe('CheckDatabaseHealthUseCase', () => {
|
|
637
581
|
it('returns unhealthy when disconnected', async () => {
|
|
638
582
|
const mockRepo = {
|
|
639
583
|
getDatabaseConnectionState: () => ({
|
|
640
584
|
stateName: 'disconnected',
|
|
641
|
-
isConnected: false
|
|
642
|
-
})
|
|
585
|
+
isConnected: false
|
|
586
|
+
})
|
|
643
587
|
};
|
|
644
588
|
const useCase = new CheckDatabaseHealthUseCase({
|
|
645
|
-
healthCheckRepository: mockRepo
|
|
589
|
+
healthCheckRepository: mockRepo
|
|
646
590
|
});
|
|
647
591
|
const result = await useCase.execute();
|
|
648
592
|
expect(result.status).toBe('unhealthy');
|
|
@@ -651,13 +595,12 @@ describe('CheckDatabaseHealthUseCase', () => {
|
|
|
651
595
|
```
|
|
652
596
|
|
|
653
597
|
**Handler Tests** (HTTP/Lambda response tests):
|
|
654
|
-
|
|
655
598
|
```javascript
|
|
656
599
|
describe('Health Handler', () => {
|
|
657
600
|
it('returns 503 when unhealthy', async () => {
|
|
658
601
|
// Mock use case
|
|
659
602
|
const mockUseCase = {
|
|
660
|
-
execute: async () => ({ status: 'unhealthy' })
|
|
603
|
+
execute: async () => ({ status: 'unhealthy' })
|
|
661
604
|
};
|
|
662
605
|
// Test HTTP response
|
|
663
606
|
const response = await handler(mockEvent, mockContext);
|
|
@@ -669,7 +612,6 @@ describe('Health Handler', () => {
|
|
|
669
612
|
## Anti-Patterns to Avoid
|
|
670
613
|
|
|
671
614
|
### Core Runtime Anti-Patterns
|
|
672
|
-
|
|
673
615
|
❌ **Don't expose internal errors** to user-facing endpoints - use `isUserFacingResponse: true`
|
|
674
616
|
❌ **Don't skip connection optimization** - always set `callbackWaitsForEmptyEventLoop = false`
|
|
675
617
|
❌ **Don't parallel process SQS records** - sequential processing prevents resource exhaustion
|
|
@@ -679,7 +621,6 @@ describe('Health Handler', () => {
|
|
|
679
621
|
❌ **Don't ignore delegate types** - define valid `delegateTypes` array for type safety
|
|
680
622
|
|
|
681
623
|
### DDD/Hexagonal Architecture Anti-Patterns
|
|
682
|
-
|
|
683
624
|
❌ **Don't access models directly in handlers** - create repositories to abstract data access
|
|
684
625
|
❌ **Don't put business logic in handlers** - extract to use cases
|
|
685
626
|
❌ **Don't call repositories from handlers** - always go through use cases
|
|
@@ -691,14 +632,13 @@ describe('Health Handler', () => {
|
|
|
691
632
|
## Testing Patterns
|
|
692
633
|
|
|
693
634
|
### Handler Testing
|
|
694
|
-
|
|
695
635
|
```javascript
|
|
696
636
|
const { createHandler } = require('@friggframework/core/core');
|
|
697
637
|
|
|
698
638
|
const testHandler = createHandler({
|
|
699
639
|
isUserFacingResponse: false, // Get full errors in tests
|
|
700
|
-
shouldUseDatabase: false,
|
|
701
|
-
method: yourTestMethod
|
|
640
|
+
shouldUseDatabase: false, // Mock/skip DB in tests
|
|
641
|
+
method: yourTestMethod
|
|
702
642
|
});
|
|
703
643
|
|
|
704
644
|
// Test with mock event/context
|
|
@@ -706,13 +646,12 @@ const result = await testHandler(mockEvent, mockContext);
|
|
|
706
646
|
```
|
|
707
647
|
|
|
708
648
|
### Worker Testing
|
|
709
|
-
|
|
710
649
|
```javascript
|
|
711
650
|
class TestWorker extends Worker {
|
|
712
651
|
_validateParams(params) {
|
|
713
652
|
this._verifyParamExists(params, 'testField');
|
|
714
653
|
}
|
|
715
|
-
|
|
654
|
+
|
|
716
655
|
async _run(params, context) {
|
|
717
656
|
// Your test logic
|
|
718
657
|
return { processed: true };
|
|
@@ -722,35 +661,30 @@ class TestWorker extends Worker {
|
|
|
722
661
|
// Test SQS record processing
|
|
723
662
|
const worker = new TestWorker();
|
|
724
663
|
await worker.run({
|
|
725
|
-
Records: [
|
|
726
|
-
{
|
|
727
|
-
|
|
728
|
-
},
|
|
729
|
-
],
|
|
664
|
+
Records: [{
|
|
665
|
+
body: JSON.stringify({ testField: 'value' })
|
|
666
|
+
}]
|
|
730
667
|
});
|
|
731
668
|
```
|
|
732
669
|
|
|
733
670
|
## Environment Variables
|
|
734
671
|
|
|
735
672
|
### Required Variables
|
|
736
|
-
|
|
737
|
-
-
|
|
738
|
-
- `SECRET_ARN`: (Optional) AWS Secrets Manager secret ARN for automatic injection
|
|
673
|
+
- `AWS_REGION`: AWS region for SQS operations
|
|
674
|
+
- `SECRET_ARN`: (Optional) AWS Secrets Manager secret ARN for automatic injection
|
|
739
675
|
|
|
740
676
|
### Database Variables
|
|
741
|
-
|
|
742
|
-
-
|
|
743
|
-
- See database module documentation for complete list
|
|
677
|
+
- MongoDB connection variables (handled by `../database/mongo`)
|
|
678
|
+
- See database module documentation for complete list
|
|
744
679
|
|
|
745
680
|
### Queue Variables
|
|
746
|
-
|
|
747
|
-
-
|
|
748
|
-
- Use Worker's `getQueueURL()` method for dynamic queue discovery
|
|
681
|
+
- Queue URLs typically passed as parameters, not environment variables
|
|
682
|
+
- Use Worker's `getQueueURL()` method for dynamic queue discovery
|
|
749
683
|
|
|
750
684
|
## Security Considerations
|
|
751
685
|
|
|
752
|
-
-
|
|
753
|
-
-
|
|
754
|
-
-
|
|
755
|
-
-
|
|
756
|
-
-
|
|
686
|
+
- **Secrets**: Never log or expose secrets in error messages
|
|
687
|
+
- **Error Messages**: Always sanitize errors for user-facing responses
|
|
688
|
+
- **Database**: Connection pooling reuses connections securely
|
|
689
|
+
- **SQS**: Message validation prevents injection attacks
|
|
690
|
+
- **Logging**: Debug logs include sensitive data - handle carefully in production
|