@friggframework/core 2.0.0-next.41 → 2.0.0-next.43

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.
Files changed (197) hide show
  1. package/CLAUDE.md +693 -0
  2. package/README.md +931 -50
  3. package/application/commands/README.md +421 -0
  4. package/application/commands/credential-commands.js +224 -0
  5. package/application/commands/entity-commands.js +315 -0
  6. package/application/commands/integration-commands.js +160 -0
  7. package/application/commands/integration-commands.test.js +123 -0
  8. package/application/commands/user-commands.js +213 -0
  9. package/application/index.js +69 -0
  10. package/core/CLAUDE.md +690 -0
  11. package/core/create-handler.js +0 -6
  12. package/credential/repositories/credential-repository-factory.js +47 -0
  13. package/credential/repositories/credential-repository-interface.js +98 -0
  14. package/credential/repositories/credential-repository-mongo.js +301 -0
  15. package/credential/repositories/credential-repository-postgres.js +307 -0
  16. package/credential/repositories/credential-repository.js +307 -0
  17. package/credential/use-cases/get-credential-for-user.js +21 -0
  18. package/credential/use-cases/update-authentication-status.js +15 -0
  19. package/database/config.js +117 -0
  20. package/database/encryption/README.md +683 -0
  21. package/database/encryption/encryption-integration.test.js +553 -0
  22. package/database/encryption/encryption-schema-registry.js +141 -0
  23. package/database/encryption/encryption-schema-registry.test.js +392 -0
  24. package/database/encryption/field-encryption-service.js +226 -0
  25. package/database/encryption/field-encryption-service.test.js +525 -0
  26. package/database/encryption/logger.js +79 -0
  27. package/database/encryption/mongo-decryption-fix-verification.test.js +348 -0
  28. package/database/encryption/postgres-decryption-fix-verification.test.js +371 -0
  29. package/database/encryption/postgres-relation-decryption.test.js +245 -0
  30. package/database/encryption/prisma-encryption-extension.js +222 -0
  31. package/database/encryption/prisma-encryption-extension.test.js +439 -0
  32. package/database/index.js +25 -12
  33. package/database/models/readme.md +1 -0
  34. package/database/prisma.js +162 -0
  35. package/database/repositories/health-check-repository-factory.js +38 -0
  36. package/database/repositories/health-check-repository-interface.js +86 -0
  37. package/database/repositories/health-check-repository-mongodb.js +72 -0
  38. package/database/repositories/health-check-repository-postgres.js +75 -0
  39. package/database/repositories/health-check-repository.js +108 -0
  40. package/database/use-cases/check-database-health-use-case.js +34 -0
  41. package/database/use-cases/check-encryption-health-use-case.js +82 -0
  42. package/database/use-cases/test-encryption-use-case.js +252 -0
  43. package/encrypt/Cryptor.js +20 -152
  44. package/encrypt/index.js +1 -2
  45. package/encrypt/test-encrypt.js +0 -2
  46. package/handlers/app-definition-loader.js +38 -0
  47. package/handlers/app-handler-helpers.js +0 -3
  48. package/handlers/auth-flow.integration.test.js +147 -0
  49. package/handlers/backend-utils.js +25 -45
  50. package/handlers/integration-event-dispatcher.js +54 -0
  51. package/handlers/integration-event-dispatcher.test.js +141 -0
  52. package/handlers/routers/HEALTHCHECK.md +103 -1
  53. package/handlers/routers/auth.js +3 -14
  54. package/handlers/routers/health.js +63 -424
  55. package/handlers/routers/health.test.js +7 -0
  56. package/handlers/routers/integration-defined-routers.js +8 -5
  57. package/handlers/routers/user.js +27 -5
  58. package/handlers/routers/websocket.js +5 -3
  59. package/handlers/use-cases/check-external-apis-health-use-case.js +81 -0
  60. package/handlers/use-cases/check-integrations-health-use-case.js +32 -0
  61. package/handlers/workers/integration-defined-workers.js +6 -3
  62. package/index.js +45 -22
  63. package/integrations/index.js +12 -10
  64. package/integrations/integration-base.js +224 -53
  65. package/integrations/integration-router.js +386 -178
  66. package/integrations/options.js +1 -1
  67. package/integrations/repositories/integration-mapping-repository-factory.js +50 -0
  68. package/integrations/repositories/integration-mapping-repository-interface.js +106 -0
  69. package/integrations/repositories/integration-mapping-repository-mongo.js +161 -0
  70. package/integrations/repositories/integration-mapping-repository-postgres.js +227 -0
  71. package/integrations/repositories/integration-mapping-repository.js +156 -0
  72. package/integrations/repositories/integration-repository-factory.js +44 -0
  73. package/integrations/repositories/integration-repository-interface.js +115 -0
  74. package/integrations/repositories/integration-repository-mongo.js +271 -0
  75. package/integrations/repositories/integration-repository-postgres.js +319 -0
  76. package/integrations/tests/doubles/dummy-integration-class.js +90 -0
  77. package/integrations/tests/doubles/test-integration-repository.js +99 -0
  78. package/integrations/tests/use-cases/create-integration.test.js +131 -0
  79. package/integrations/tests/use-cases/delete-integration-for-user.test.js +150 -0
  80. package/integrations/tests/use-cases/find-integration-context-by-external-entity-id.test.js +92 -0
  81. package/integrations/tests/use-cases/get-integration-for-user.test.js +150 -0
  82. package/integrations/tests/use-cases/get-integration-instance.test.js +176 -0
  83. package/integrations/tests/use-cases/get-integrations-for-user.test.js +176 -0
  84. package/integrations/tests/use-cases/get-possible-integrations.test.js +188 -0
  85. package/integrations/tests/use-cases/update-integration-messages.test.js +142 -0
  86. package/integrations/tests/use-cases/update-integration-status.test.js +103 -0
  87. package/integrations/tests/use-cases/update-integration.test.js +141 -0
  88. package/integrations/use-cases/create-integration.js +83 -0
  89. package/integrations/use-cases/delete-integration-for-user.js +73 -0
  90. package/integrations/use-cases/find-integration-context-by-external-entity-id.js +72 -0
  91. package/integrations/use-cases/get-integration-for-user.js +78 -0
  92. package/integrations/use-cases/get-integration-instance-by-definition.js +67 -0
  93. package/integrations/use-cases/get-integration-instance.js +83 -0
  94. package/integrations/use-cases/get-integrations-for-user.js +87 -0
  95. package/integrations/use-cases/get-possible-integrations.js +27 -0
  96. package/integrations/use-cases/index.js +11 -0
  97. package/integrations/use-cases/load-integration-context-full.test.js +329 -0
  98. package/integrations/use-cases/load-integration-context.js +71 -0
  99. package/integrations/use-cases/load-integration-context.test.js +114 -0
  100. package/integrations/use-cases/update-integration-messages.js +44 -0
  101. package/integrations/use-cases/update-integration-status.js +32 -0
  102. package/integrations/use-cases/update-integration.js +93 -0
  103. package/integrations/utils/map-integration-dto.js +36 -0
  104. package/jest-global-setup-noop.js +3 -0
  105. package/jest-global-teardown-noop.js +3 -0
  106. package/{module-plugin → modules}/entity.js +1 -0
  107. package/{module-plugin → modules}/index.js +0 -8
  108. package/modules/module-factory.js +56 -0
  109. package/modules/module-hydration.test.js +205 -0
  110. package/modules/module.js +221 -0
  111. package/modules/repositories/module-repository-factory.js +33 -0
  112. package/modules/repositories/module-repository-interface.js +129 -0
  113. package/modules/repositories/module-repository-mongo.js +386 -0
  114. package/modules/repositories/module-repository-postgres.js +437 -0
  115. package/modules/repositories/module-repository.js +327 -0
  116. package/{module-plugin → modules}/test/mock-api/api.js +8 -3
  117. package/{module-plugin → modules}/test/mock-api/definition.js +12 -8
  118. package/modules/tests/doubles/test-module-factory.js +16 -0
  119. package/modules/tests/doubles/test-module-repository.js +39 -0
  120. package/modules/use-cases/get-entities-for-user.js +32 -0
  121. package/modules/use-cases/get-entity-options-by-id.js +59 -0
  122. package/modules/use-cases/get-entity-options-by-type.js +34 -0
  123. package/modules/use-cases/get-module-instance-from-type.js +31 -0
  124. package/modules/use-cases/get-module.js +56 -0
  125. package/modules/use-cases/process-authorization-callback.js +122 -0
  126. package/modules/use-cases/refresh-entity-options.js +59 -0
  127. package/modules/use-cases/test-module-auth.js +55 -0
  128. package/modules/utils/map-module-dto.js +18 -0
  129. package/package.json +14 -6
  130. package/prisma-mongodb/schema.prisma +318 -0
  131. package/prisma-postgresql/migrations/20250930193005_init/migration.sql +315 -0
  132. package/prisma-postgresql/migrations/20251006135218_init/migration.sql +9 -0
  133. package/prisma-postgresql/migrations/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
  134. package/prisma-postgresql/migrations/migration_lock.toml +3 -0
  135. package/prisma-postgresql/schema.prisma +300 -0
  136. package/syncs/manager.js +468 -443
  137. package/syncs/repositories/sync-repository-factory.js +38 -0
  138. package/syncs/repositories/sync-repository-interface.js +109 -0
  139. package/syncs/repositories/sync-repository-mongo.js +239 -0
  140. package/syncs/repositories/sync-repository-postgres.js +319 -0
  141. package/syncs/sync.js +0 -1
  142. package/token/repositories/token-repository-factory.js +33 -0
  143. package/token/repositories/token-repository-interface.js +131 -0
  144. package/token/repositories/token-repository-mongo.js +212 -0
  145. package/token/repositories/token-repository-postgres.js +257 -0
  146. package/token/repositories/token-repository.js +219 -0
  147. package/types/integrations/index.d.ts +2 -6
  148. package/types/module-plugin/index.d.ts +5 -57
  149. package/types/syncs/index.d.ts +0 -2
  150. package/user/repositories/user-repository-factory.js +46 -0
  151. package/user/repositories/user-repository-interface.js +198 -0
  152. package/user/repositories/user-repository-mongo.js +250 -0
  153. package/user/repositories/user-repository-postgres.js +311 -0
  154. package/user/tests/doubles/test-user-repository.js +72 -0
  155. package/user/tests/use-cases/create-individual-user.test.js +24 -0
  156. package/user/tests/use-cases/create-organization-user.test.js +28 -0
  157. package/user/tests/use-cases/create-token-for-user-id.test.js +19 -0
  158. package/user/tests/use-cases/get-user-from-bearer-token.test.js +64 -0
  159. package/user/tests/use-cases/login-user.test.js +140 -0
  160. package/user/use-cases/create-individual-user.js +61 -0
  161. package/user/use-cases/create-organization-user.js +47 -0
  162. package/user/use-cases/create-token-for-user-id.js +30 -0
  163. package/user/use-cases/get-user-from-bearer-token.js +77 -0
  164. package/user/use-cases/login-user.js +122 -0
  165. package/user/user.js +77 -0
  166. package/websocket/repositories/websocket-connection-repository-factory.js +37 -0
  167. package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
  168. package/websocket/repositories/websocket-connection-repository-mongo.js +155 -0
  169. package/websocket/repositories/websocket-connection-repository-postgres.js +195 -0
  170. package/websocket/repositories/websocket-connection-repository.js +160 -0
  171. package/database/models/State.js +0 -9
  172. package/database/models/Token.js +0 -70
  173. package/database/mongo.js +0 -171
  174. package/encrypt/Cryptor.test.js +0 -32
  175. package/encrypt/encrypt.js +0 -104
  176. package/encrypt/encrypt.test.js +0 -1069
  177. package/handlers/routers/middleware/loadUser.js +0 -15
  178. package/handlers/routers/middleware/requireLoggedInUser.js +0 -12
  179. package/integrations/create-frigg-backend.js +0 -31
  180. package/integrations/integration-factory.js +0 -251
  181. package/integrations/integration-mapping.js +0 -43
  182. package/integrations/integration-model.js +0 -46
  183. package/integrations/integration-user.js +0 -144
  184. package/integrations/test/integration-base.test.js +0 -144
  185. package/module-plugin/auther.js +0 -393
  186. package/module-plugin/credential.js +0 -22
  187. package/module-plugin/entity-manager.js +0 -70
  188. package/module-plugin/manager.js +0 -169
  189. package/module-plugin/module-factory.js +0 -61
  190. package/module-plugin/test/auther.test.js +0 -97
  191. /package/{module-plugin → modules}/ModuleConstants.js +0 -0
  192. /package/{module-plugin → modules}/requester/api-key.js +0 -0
  193. /package/{module-plugin → modules}/requester/basic.js +0 -0
  194. /package/{module-plugin → modules}/requester/oauth-2.js +0 -0
  195. /package/{module-plugin → modules}/requester/requester.js +0 -0
  196. /package/{module-plugin → modules}/requester/requester.test.js +0 -0
  197. /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,693 @@
1
+ # CLAUDE.md - Frigg Framework Core Package
2
+
3
+ This file provides guidance to Claude Code when working with the Frigg Framework's core package (`@friggframework/core`).
4
+
5
+ ## Critical Context (Read First)
6
+
7
+ - **Package Purpose**: Core framework functionality for building enterprise serverless integrations
8
+ - **Main Architecture**: Hexagonal/DDD architecture with clear separation of adapters, use cases, and repositories
9
+ - **Key Technologies**: Node.js, Express, AWS Lambda, MongoDB/PostgreSQL (Prisma), AWS KMS encryption
10
+ - **Core Value**: Provides building blocks for integration developers - they extend IntegrationBase and use framework services
11
+ - **Security Model**: Field-level encryption, OAuth2 flows, signature validation, VPC deployment
12
+ - **DO NOT**: Bypass architectural layers, skip encryption for sensitive data, expose internal errors to users
13
+
14
+ ## Table of Contents
15
+
16
+ 1. [Package Overview](#package-overview)
17
+ 2. [Architecture Principles](#architecture-principles)
18
+ 3. [Essential Commands](#essential-commands)
19
+ 4. [Directory Structure](#directory-structure)
20
+ 5. [Core Components](#core-components)
21
+ 6. [Development Workflow](#development-workflow)
22
+ 7. [Testing Strategy](#testing-strategy)
23
+ 8. [Anti-Patterns](#anti-patterns)
24
+
25
+ ## Package Overview
26
+
27
+ `@friggframework/core` is the foundational package of the Frigg Framework, providing:
28
+
29
+ - **IntegrationBase**: Base class all integrations extend
30
+ - **Database Layer**: Multi-database support (MongoDB, PostgreSQL) with Prisma ORM
31
+ - **Encryption**: Transparent field-level encryption with AWS KMS or AES
32
+ - **User Management**: Individual and organizational user support
33
+ - **Module System**: API module loading and credential management
34
+ - **Lambda Runtime**: Handler factory, worker base class, timeout management
35
+ - **Error Handling**: Standardized error types with proper HTTP status codes
36
+ - **Event System**: Integration lifecycle events and user actions
37
+
38
+ ## Architecture Principles
39
+
40
+ ### Hexagonal Architecture (Ports and Adapters)
41
+
42
+ The core package strictly follows hexagonal architecture:
43
+
44
+ ```
45
+ ┌─────────────────────────────────────────────────────────┐
46
+ │ Adapters (Inbound) │
47
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
48
+ │ │ HTTP/REST │ │ Lambda │ │ SQS Workers │ │
49
+ │ │ (handlers/) │ │ (core/) │ │ (queues/) │ │
50
+ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
51
+ └─────────┼─────────────────┼─────────────────┼───────────┘
52
+ │ │ │
53
+ ┌─────────▼─────────────────▼─────────────────▼───────────┐
54
+ │ Application Layer (Use Cases) │
55
+ │ ┌────────────────────────────────────────────────┐ │
56
+ │ │ CreateIntegration, UpdateIntegration, │ │
57
+ │ │ LoginUser, ProcessAttachmentJob, etc. │ │
58
+ │ └────────────────────┬───────────────────────────┘ │
59
+ └───────────────────────┼─────────────────────────────────┘
60
+ │ calls
61
+ ┌───────────────────────▼─────────────────────────────────┐
62
+ │ Domain Layer (Entities) │
63
+ │ ┌────────────────────────────────────────────────┐ │
64
+ │ │ IntegrationBase, User, Credential, Entity │ │
65
+ │ └────────────────────┬───────────────────────────┘ │
66
+ └───────────────────────┼─────────────────────────────────┘
67
+ │ persisted by
68
+ ┌───────────────────────▼─────────────────────────────────┐
69
+ │ Infrastructure Layer (Repositories) │
70
+ │ ┌────────────────────────────────────────────────┐ │
71
+ │ │ IntegrationRepository, UserRepository, │ │
72
+ │ │ CredentialRepository, ModuleRepository │ │
73
+ │ └────────────────────┬───────────────────────────┘ │
74
+ └───────────────────────┼─────────────────────────────────┘
75
+ │ accesses
76
+ ┌───────────────────────▼─────────────────────────────────┐
77
+ │ External Systems │
78
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
79
+ │ │ MongoDB │ │ Postgres │ │ AWS KMS │ │
80
+ │ └──────────┘ └──────────┘ └──────────┘ │
81
+ └─────────────────────────────────────────────────────────┘
82
+ ```
83
+
84
+ ### Golden Rules
85
+
86
+ 1. **Handlers NEVER call repositories directly** - Always go through use cases
87
+ 2. **Use cases contain business logic** - Not repositories or handlers
88
+ 3. **Repositories are pure data access** - No business logic or orchestration
89
+ 4. **Domain entities have behavior** - Not just data bags
90
+ 5. **Encryption is transparent** - Application code works with plain data
91
+
92
+ ## Essential Commands
93
+
94
+ ### Development
95
+
96
+ ```bash
97
+ # Install dependencies
98
+ npm install
99
+
100
+ # Generate Prisma clients (both MongoDB and PostgreSQL)
101
+ npm run prisma:generate
102
+
103
+ # Format and lint code
104
+ npm run lint:fix
105
+
106
+ # Run tests
107
+ npm test
108
+
109
+ # Run specific test file
110
+ npm test -- path/to/test.test.js
111
+
112
+ # Run tests for specific pattern
113
+ npm test -- --testPathPattern="encryption"
114
+ ```
115
+
116
+ ### Prisma Database Operations
117
+
118
+ ```bash
119
+ # Generate clients
120
+ npm run prisma:generate:mongo # MongoDB only
121
+ npm run prisma:generate:postgres # PostgreSQL only
122
+ npm run prisma:generate # Both databases
123
+
124
+ # Database migrations
125
+ npm run prisma:push:mongo # Push MongoDB schema
126
+ npm run prisma:migrate:postgres # Run PostgreSQL migrations
127
+ ```
128
+
129
+ ### Testing
130
+
131
+ ```bash
132
+ # All tests
133
+ npm test
134
+
135
+ # Specific test categories
136
+ npm test -- database/encryption/ # Encryption tests
137
+ npm test -- integrations/ # Integration tests
138
+ npm test -- handlers/ # Handler tests
139
+ ```
140
+
141
+ ## Directory Structure
142
+
143
+ ```
144
+ packages/core/
145
+ ├── application/ # Application-level commands and initialization
146
+ │ └── commands/ # Command pattern implementations
147
+ ├── assertions/ # Validation and assertion utilities
148
+ ├── associations/ # Entity association management
149
+ ├── core/ # Runtime system (Lambda, Workers, Delegates)
150
+ │ └── CLAUDE.md # Detailed core runtime documentation
151
+ ├── credential/ # Credential management
152
+ │ ├── repositories/ # Credential data access
153
+ │ └── use-cases/ # Credential business logic
154
+ ├── database/ # Database layer and encryption
155
+ │ ├── encryption/ # Field-level encryption system
156
+ │ │ └── README.md # Comprehensive encryption documentation
157
+ │ ├── models/ # Mongoose models
158
+ │ ├── repositories/ # Database repositories
159
+ │ └── use-cases/ # Database health and management
160
+ ├── encrypt/ # Cryptor adapter for AWS KMS and AES
161
+ ├── errors/ # Error type definitions
162
+ ├── handlers/ # HTTP/Lambda request handlers
163
+ │ └── routers/ # Express routers
164
+ ├── integrations/ # Integration domain and lifecycle
165
+ │ ├── integration-base.js # Base class for all integrations
166
+ │ ├── repositories/ # Integration data access
167
+ │ ├── tests/ # Integration tests
168
+ │ └── use-cases/ # Integration business logic
169
+ ├── lambda/ # AWS Lambda utilities
170
+ ├── logs/ # Logging system
171
+ ├── modules/ # API module system
172
+ │ ├── requester/ # HTTP client implementations
173
+ │ └── repositories/ # Module data access
174
+ ├── prisma-mongodb/ # MongoDB Prisma schema
175
+ ├── prisma-postgresql/ # PostgreSQL Prisma schema
176
+ ├── queues/ # SQS job queue management
177
+ ├── syncs/ # Data synchronization
178
+ ├── token/ # Token management
179
+ │ └── repositories/ # Token data access
180
+ ├── types/ # TypeScript type definitions
181
+ ├── user/ # User management
182
+ │ ├── repositories/ # User data access
183
+ │ └── use-cases/ # User business logic
184
+ ├── utils/ # Utility functions
185
+ ├── websocket/ # WebSocket connection management
186
+ │ └── repositories/ # WebSocket data access
187
+ ├── index.js # Main export file
188
+ ├── package.json # Package configuration
189
+ └── README.md # Package documentation
190
+ ```
191
+
192
+ ## Core Components
193
+
194
+ ### 1. Integration System (`/integrations`)
195
+
196
+ **Purpose**: Foundation for building integrations between external systems.
197
+
198
+ **Key Files**:
199
+ - `integration-base.js` - Base class all integrations extend
200
+ - `integration.js` - Integration domain aggregate using Proxy pattern
201
+ - `options.js` - Integration configuration and options
202
+
203
+ **Use Cases**:
204
+ - `create-integration.js` - Create new integration instance
205
+ - `update-integration.js` - Update integration configuration
206
+ - `delete-integration-for-user.js` - Remove integration
207
+ - `get-integration-instance.js` - Load integration with modules
208
+ - `load-integration-context.js` - Full integration context loading
209
+
210
+ **Repositories**:
211
+ - `integration-repository-factory.js` - Creates database-specific repositories
212
+ - `integration-repository-mongo.js` - MongoDB implementation
213
+ - `integration-repository-postgres.js` - PostgreSQL implementation
214
+ - `integration-mapping-repository-*.js` - Mapping data persistence
215
+
216
+ **Integration developers extend IntegrationBase**:
217
+
218
+ ```javascript
219
+ const { IntegrationBase } = require('@friggframework/core');
220
+
221
+ class MyIntegration extends IntegrationBase {
222
+ static Definition = {
223
+ name: 'my-integration',
224
+ version: '1.0.0',
225
+ modules: {
226
+ serviceA: 'service-a',
227
+ serviceB: 'service-b'
228
+ }
229
+ };
230
+
231
+ async onCreate({ integrationId }) {
232
+ // Setup logic
233
+ await super.onCreate({ integrationId });
234
+ }
235
+ }
236
+ ```
237
+
238
+ ### 2. Database Layer (`/database`)
239
+
240
+ **Purpose**: Multi-database support with transparent encryption.
241
+
242
+ **Key Components**:
243
+ - `prisma.js` - Prisma client initialization with encryption extension
244
+ - `mongo.js` - Mongoose connection management (legacy)
245
+ - `models/` - Mongoose model definitions
246
+
247
+ **Encryption System** (`/database/encryption`):
248
+ - **Transparent encryption**: Application code never sees encrypted data
249
+ - **Database-agnostic**: Works with MongoDB and PostgreSQL
250
+ - **AWS KMS or AES**: Production KMS, development AES
251
+ - **Configurable**: Via environment variables and app definition
252
+
253
+ **See**: `database/encryption/README.md` for comprehensive documentation
254
+
255
+ **Repositories**:
256
+ - `health-check-repository.js` - Database health monitoring
257
+ - `token-repository.js` - Authentication tokens
258
+ - `websocket-connection-repository.js` - WebSocket connections
259
+
260
+ **Use Cases**:
261
+ - `check-database-health-use-case.js` - Database health checks
262
+ - `test-encryption-use-case.js` - Encryption verification
263
+
264
+ ### 3. User Management (`/user`)
265
+
266
+ **Purpose**: Individual and organizational user authentication.
267
+
268
+ **User Types**:
269
+ - **Individual Users**: Personal accounts with email/password
270
+ - **Organization Users**: Business accounts with organization-level access
271
+ - **Hybrid**: Support both simultaneously
272
+
273
+ **Authentication Methods**:
274
+ - Password-based (bcrypt hashed)
275
+ - Token-based (Bearer tokens)
276
+ - App-based (external app user IDs)
277
+
278
+ **Use Cases**:
279
+ - `login-user.js` - User authentication
280
+ - `create-individual-user.js` - Create personal account
281
+ - `create-organization-user.js` - Create business account
282
+ - `get-user-from-bearer-token.js` - Token authentication
283
+
284
+ **Repositories**:
285
+ - `user-repository-factory.js` - Creates database-specific repositories
286
+ - `user-repository-mongo.js` - MongoDB implementation
287
+ - `user-repository-postgres.js` - PostgreSQL implementation
288
+
289
+ **Configuration** (in app definition):
290
+
291
+ ```javascript
292
+ {
293
+ user: {
294
+ usePassword: true, // Enable password auth
295
+ primary: 'individual', // Primary user type
296
+ individualUserRequired: true, // Require individual user
297
+ organizationUserRequired: false // Optional org user
298
+ }
299
+ }
300
+ ```
301
+
302
+ ### 4. Module System (`/modules`)
303
+
304
+ **Purpose**: API module loading, credential management, and HTTP clients.
305
+
306
+ **Key Classes**:
307
+ - `Credential` - API credentials domain entity
308
+ - `Entity` - External service entity (account, workspace, etc.)
309
+ - `Requester` - Base HTTP client class
310
+ - `OAuth2Requester` - OAuth 2.0 flow implementation
311
+ - `ApiKeyRequester` - API key authentication
312
+ - `BasicAuthRequester` - Basic authentication
313
+
314
+ **Module Factory**:
315
+ - `ModuleFactory` - Creates and configures API module instances
316
+ - Handles credential injection
317
+ - Manages module lifecycle
318
+
319
+ **Repositories**:
320
+ - `module-repository.js` - Module data access
321
+ - `credential-repository.js` - Credential persistence (encrypted)
322
+
323
+ ### 5. Core Runtime System (`/core`)
324
+
325
+ **Purpose**: Lambda-optimized runtime with handlers, workers, and delegates.
326
+
327
+ **See**: `core/CLAUDE.md` for comprehensive documentation
328
+
329
+ **Key Components**:
330
+ - `create-handler.js` - Lambda handler factory
331
+ - `Worker.js` - SQS job processing base class
332
+ - `Delegate.js` - Observer/delegation pattern
333
+ - `load-installed-modules.js` - Dynamic module loading
334
+
335
+ **Handler Pattern**:
336
+
337
+ ```javascript
338
+ const { createHandler } = require('@friggframework/core');
339
+
340
+ const handler = createHandler({
341
+ eventName: 'MyIntegration',
342
+ isUserFacingResponse: true, // Sanitize errors
343
+ shouldUseDatabase: true, // Connect to DB
344
+ method: async (event, context) => {
345
+ // Your logic here
346
+ return { statusCode: 200, body: 'Success' };
347
+ }
348
+ });
349
+ ```
350
+
351
+ **Worker Pattern**:
352
+
353
+ ```javascript
354
+ const { Worker } = require('@friggframework/core');
355
+
356
+ class MyWorker extends Worker {
357
+ _validateParams(params) {
358
+ this._verifyParamExists(params, 'requiredField');
359
+ }
360
+
361
+ async _run(params, context) {
362
+ // Process SQS message
363
+ }
364
+ }
365
+ ```
366
+
367
+ ### 6. Encryption System (`/encrypt`)
368
+
369
+ **Purpose**: Cryptor adapter for AWS KMS and AES encryption.
370
+
371
+ **Key Class**: `Cryptor.js`
372
+ - Envelope encryption pattern
373
+ - AWS KMS integration
374
+ - AES-256-GCM fallback
375
+ - Key rotation support
376
+
377
+ **Usage**:
378
+
379
+ ```javascript
380
+ const { Cryptor } = require('@friggframework/core');
381
+
382
+ const cryptor = new Cryptor({
383
+ shouldUseAws: process.env.KMS_KEY_ARN ? true : false
384
+ });
385
+
386
+ const encrypted = await cryptor.encrypt('sensitive-data');
387
+ const decrypted = await cryptor.decrypt(encrypted);
388
+ ```
389
+
390
+ ### 7. Handlers & Routers (`/handlers`)
391
+
392
+ **Purpose**: HTTP/Lambda request handling and routing.
393
+
394
+ **Key Routers**:
395
+ - `integration-router.js` - Integration CRUD operations
396
+ - `auth.js` - Authentication endpoints
397
+ - `health.js` - Health check endpoints with encryption verification
398
+
399
+ **Handler Types**:
400
+ - **User-facing**: Sanitize errors, friendly responses
401
+ - **Server-to-server**: Full error details for debugging
402
+ - **Background workers**: SQS message processing
403
+
404
+ **Event Dispatcher**:
405
+ - `integration-event-dispatcher.js` - Routes events to integration handlers
406
+ - Supports lifecycle events and user actions
407
+
408
+ ### 8. Error Handling (`/errors`)
409
+
410
+ **Purpose**: Standardized error types with proper HTTP semantics.
411
+
412
+ **Error Types**:
413
+ - `BaseError` - Base error class
414
+ - `FetchError` - HTTP request failures
415
+ - `HaltError` - Stop processing without retry
416
+ - `RequiredPropertyError` - Missing required parameters
417
+ - `ParameterTypeError` - Invalid parameter type
418
+
419
+ **Usage**:
420
+
421
+ ```javascript
422
+ const { RequiredPropertyError } = require('@friggframework/core');
423
+
424
+ if (!userId) {
425
+ throw new RequiredPropertyError('userId is required');
426
+ }
427
+ ```
428
+
429
+ ### 9. Logging System (`/logs`)
430
+
431
+ **Purpose**: Structured logging with debug capabilities.
432
+
433
+ **Functions**:
434
+ - `debug(message, data)` - Debug logging
435
+ - `initDebugLog(eventName, event)` - Initialize debug context
436
+ - `flushDebugLog(error)` - Flush logs on error
437
+
438
+ **Usage**:
439
+
440
+ ```javascript
441
+ const { debug, initDebugLog, flushDebugLog } = require('@friggframework/core');
442
+
443
+ initDebugLog('MyIntegration', event);
444
+ debug('Processing request', { userId, action });
445
+ // ... your code ...
446
+ flushDebugLog(); // On error
447
+ ```
448
+
449
+ ### 10. Lambda Utilities (`/lambda`)
450
+
451
+ **Purpose**: AWS Lambda-specific utilities.
452
+
453
+ **Key Classes**:
454
+ - `TimeoutCatcher` - Detect approaching Lambda timeout
455
+ - Graceful shutdown handling
456
+
457
+ **Usage**:
458
+
459
+ ```javascript
460
+ const { TimeoutCatcher } = require('@friggframework/core');
461
+
462
+ exports.handler = async (event, context) => {
463
+ const timeoutCatcher = new TimeoutCatcher(context);
464
+
465
+ if (timeoutCatcher.isNearTimeout()) {
466
+ // Save state and exit gracefully
467
+ }
468
+ };
469
+ ```
470
+
471
+ ## Development Workflow
472
+
473
+ ### Adding a New Use Case
474
+
475
+ 1. **Create use case file** in appropriate `use-cases/` directory:
476
+
477
+ ```javascript
478
+ // integrations/use-cases/my-new-use-case.js
479
+ class MyNewUseCase {
480
+ constructor({ integrationRepository, userRepository }) {
481
+ this.integrationRepo = integrationRepository;
482
+ this.userRepo = userRepository;
483
+ }
484
+
485
+ async execute(userId, integrationId) {
486
+ // Business logic here
487
+ const user = await this.userRepo.findById(userId);
488
+ const integration = await this.integrationRepo.findById(integrationId);
489
+
490
+ // Validate, orchestrate, coordinate
491
+ // Return result
492
+ }
493
+ }
494
+
495
+ module.exports = { MyNewUseCase };
496
+ ```
497
+
498
+ 2. **Add tests** in corresponding `tests/` directory
499
+ 3. **Export** from parent index.js if needed
500
+ 4. **Use in handler** - handlers call use cases, not repositories
501
+
502
+ ### Adding Encrypted Fields
503
+
504
+ **For custom models** (integration developers):
505
+
506
+ In `backend/index.js`:
507
+
508
+ ```javascript
509
+ const appDefinition = {
510
+ encryption: {
511
+ schema: {
512
+ MyCustomModel: {
513
+ fields: ['secretData', 'data.apiKey']
514
+ }
515
+ }
516
+ }
517
+ };
518
+ ```
519
+
520
+ **For core models** (framework developers):
521
+
522
+ Edit `database/encryption/encryption-schema-registry.js`:
523
+
524
+ ```javascript
525
+ const ENCRYPTION_SCHEMA = {
526
+ MyModel: {
527
+ fields: ['sensitiveField']
528
+ }
529
+ };
530
+ ```
531
+
532
+ ### Database Migrations
533
+
534
+ **MongoDB** (Prisma push):
535
+
536
+ ```bash
537
+ npm run prisma:push:mongo
538
+ ```
539
+
540
+ **PostgreSQL** (Prisma migrate):
541
+
542
+ ```bash
543
+ npm run prisma:migrate:postgres
544
+ ```
545
+
546
+ ### Integration Development
547
+
548
+ 1. **Extend IntegrationBase** in your app
549
+ 2. **Define static Definition** with name, version, modules
550
+ 3. **Implement lifecycle methods**: `onCreate`, `onUpdate`, `onDelete`
551
+ 4. **Add event handlers** for webhooks and user actions
552
+ 5. **Use framework services**: repositories, encryption, logging
553
+
554
+ ## Testing Strategy
555
+
556
+ ### Test Categories
557
+
558
+ 1. **Unit Tests**: Use cases with mocked repositories
559
+ 2. **Integration Tests**: Full flow with real dependencies
560
+ 3. **Repository Tests**: Database operations
561
+ 4. **Handler Tests**: HTTP/Lambda response testing
562
+
563
+ ### Test Structure
564
+
565
+ ```javascript
566
+ describe('MyUseCase', () => {
567
+ let useCase;
568
+ let mockRepository;
569
+
570
+ beforeEach(() => {
571
+ mockRepository = {
572
+ findById: jest.fn(),
573
+ save: jest.fn()
574
+ };
575
+ useCase = new MyUseCase({ repository: mockRepository });
576
+ });
577
+
578
+ it('executes successfully', async () => {
579
+ mockRepository.findById.mockResolvedValue({ id: '123' });
580
+
581
+ const result = await useCase.execute('123');
582
+
583
+ expect(result).toBeDefined();
584
+ expect(mockRepository.findById).toHaveBeenCalledWith('123');
585
+ });
586
+ });
587
+ ```
588
+
589
+ ### Running Tests
590
+
591
+ ```bash
592
+ # All tests
593
+ npm test
594
+
595
+ # Specific file
596
+ npm test -- path/to/test.test.js
597
+
598
+ # Pattern matching
599
+ npm test -- --testPathPattern="encryption"
600
+
601
+ # With coverage
602
+ npm test -- --coverage
603
+ ```
604
+
605
+ ### Test Doubles
606
+
607
+ Use test doubles from `@friggframework/test` package for consistent mocking.
608
+
609
+ ## Anti-Patterns
610
+
611
+ ### Architecture Anti-Patterns
612
+
613
+ ❌ **Don't call repositories from handlers** - Always use use cases
614
+ ❌ **Don't put business logic in repositories** - Repositories are pure data access
615
+ ❌ **Don't put HTTP concerns in use cases** - Use cases are protocol-agnostic
616
+ ❌ **Don't bypass encryption** - Sensitive data must be encrypted
617
+ ❌ **Don't expose internal errors to users** - Use `isUserFacingResponse: true`
618
+ ❌ **Don't skip connection pooling** - Set `callbackWaitsForEmptyEventLoop = false`
619
+
620
+ ### Development Anti-Patterns
621
+
622
+ ❌ **Don't modify node_modules** - Extend through proper patterns
623
+ ❌ **Don't hardcode credentials** - Use environment variables
624
+ ❌ **Don't skip tests** - Maintain test coverage
625
+ ❌ **Don't commit secrets** - Use .gitignore and AWS Secrets Manager
626
+ ❌ **Don't ignore linting errors** - Run `npm run lint:fix`
627
+
628
+ ### Integration Development Anti-Patterns
629
+
630
+ ❌ **Don't bypass IntegrationBase** - Always extend the base class
631
+ ❌ **Don't ignore lifecycle methods** - Implement onCreate, onUpdate, onDelete
632
+ ❌ **Don't skip signature validation** - Validate all webhooks
633
+ ❌ **Don't sync operations in handlers** - Use background workers for long tasks
634
+ ❌ **Don't ignore errors** - Proper error handling and logging
635
+
636
+ ## Environment Variables
637
+
638
+ ### Required
639
+
640
+ - `AWS_REGION` - AWS region for services
641
+ - `DATABASE_URL` - Database connection string (auto-set)
642
+ - `DB_TYPE` - Database type: 'mongodb' or 'postgresql'
643
+
644
+ ### Encryption
645
+
646
+ - `KMS_KEY_ARN` - AWS KMS key ARN (production)
647
+ - `AES_KEY_ID` - AES key ID (development)
648
+ - `AES_KEY` - AES encryption key (development)
649
+ - `STAGE` - Environment stage (dev, test, local bypass encryption)
650
+
651
+ ### Optional
652
+
653
+ - `SECRET_ARN` - AWS Secrets Manager ARN for auto-injection
654
+ - `DEBUG` - Debug logging pattern
655
+ - `LOG_LEVEL` - Logging level (debug, info, warn, error)
656
+
657
+ ## Version Information
658
+
659
+ - **Current Version**: 2.0.0-next.0 (pre-release)
660
+ - **Node.js**: >=18 required
661
+ - **Dependencies**: See package.json for full list
662
+
663
+ ## Support and Documentation
664
+
665
+ - **Main Framework CLAUDE.md**: See root Frigg CLAUDE.md for framework-wide guidance
666
+ - **Core Runtime**: See `core/CLAUDE.md` for Lambda/Worker patterns
667
+ - **Encryption**: See `database/encryption/README.md` for encryption details
668
+ - **Package README**: See `README.md` for API reference
669
+
670
+ ## Recent Important Changes
671
+
672
+ ### Field-Level Encryption JSON Object Support
673
+
674
+ **Date**: 2025-01-06
675
+
676
+ **Problem**: The `FieldEncryptionService` was converting objects to the string `"[object Object]"` before encrypting, corrupting JSON fields like `IntegrationMapping.mapping`.
677
+
678
+ **Solution**: Added `_serializeForEncryption()` and `_deserializeAfterDecryption()` methods:
679
+ - Objects are now JSON.stringify'd before encryption
680
+ - Decrypted strings are JSON.parse'd back to objects
681
+ - Plain strings work as before
682
+
683
+ **Files Changed**:
684
+ - `database/encryption/field-encryption-service.js`
685
+ - `database/encryption/field-encryption-service.test.js`
686
+
687
+ **Test Coverage**: All 40 tests pass, including new object encryption test.
688
+
689
+ **Impact**: `IntegrationMapping.mapping` and other JSON fields now correctly round-trip through encryption.
690
+
691
+ ---
692
+
693
+ **Built with ❤️ by the Frigg Framework team**