@tailor-platform/erp-kit 0.0.1 → 0.1.1

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 (231) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +196 -28
  4. package/dist/cli.js +914 -0
  5. package/package.json +67 -8
  6. package/schemas/app-compose/actors.yml +34 -0
  7. package/schemas/app-compose/business-flow.yml +50 -0
  8. package/schemas/app-compose/requirements.yml +33 -0
  9. package/schemas/app-compose/resolver.yml +47 -0
  10. package/schemas/app-compose/screen.yml +81 -0
  11. package/schemas/app-compose/story.yml +67 -0
  12. package/schemas/module/command.yml +52 -0
  13. package/schemas/module/feature.yml +58 -0
  14. package/schemas/module/model.yml +70 -0
  15. package/schemas/module/module.yml +50 -0
  16. package/skills/1-module-docs/SKILL.md +111 -0
  17. package/skills/1-module-docs/references/structure.md +22 -0
  18. package/skills/2-module-feature-breakdown/SKILL.md +72 -0
  19. package/skills/2-module-feature-breakdown/references/commands.md +48 -0
  20. package/skills/2-module-feature-breakdown/references/models.md +29 -0
  21. package/skills/2-module-feature-breakdown/references/structure.md +22 -0
  22. package/skills/3-module-doc-review/SKILL.md +236 -0
  23. package/skills/3-module-doc-review/references/commands.md +54 -0
  24. package/skills/3-module-doc-review/references/models.md +29 -0
  25. package/skills/3-module-doc-review/references/testing.md +37 -0
  26. package/skills/4-module-tdd-implementation/SKILL.md +74 -0
  27. package/skills/4-module-tdd-implementation/references/commands.md +45 -0
  28. package/skills/4-module-tdd-implementation/references/db-relations.md +69 -0
  29. package/skills/4-module-tdd-implementation/references/errors.md +7 -0
  30. package/skills/4-module-tdd-implementation/references/exports.md +8 -0
  31. package/skills/4-module-tdd-implementation/references/models.md +30 -0
  32. package/skills/4-module-tdd-implementation/references/structure.md +22 -0
  33. package/skills/4-module-tdd-implementation/references/testing.md +37 -0
  34. package/skills/5-module-implementation-review/SKILL.md +408 -0
  35. package/skills/5-module-implementation-review/references/commands.md +45 -0
  36. package/skills/5-module-implementation-review/references/errors.md +7 -0
  37. package/skills/5-module-implementation-review/references/exports.md +8 -0
  38. package/skills/5-module-implementation-review/references/models.md +30 -0
  39. package/skills/5-module-implementation-review/references/testing.md +29 -0
  40. package/skills/app-compose-1-requirement-analysis/SKILL.md +89 -0
  41. package/skills/app-compose-1-requirement-analysis/references/structure.md +27 -0
  42. package/skills/app-compose-2-requirements-breakdown/SKILL.md +95 -0
  43. package/skills/app-compose-2-requirements-breakdown/references/screen-detailview.md +106 -0
  44. package/skills/app-compose-2-requirements-breakdown/references/screen-form.md +139 -0
  45. package/skills/app-compose-2-requirements-breakdown/references/screen-listview.md +153 -0
  46. package/skills/app-compose-2-requirements-breakdown/references/structure.md +27 -0
  47. package/skills/app-compose-3-doc-review/SKILL.md +116 -0
  48. package/skills/app-compose-3-doc-review/references/structure.md +27 -0
  49. package/skills/app-compose-4-design-mock/SKILL.md +256 -0
  50. package/skills/app-compose-4-design-mock/references/component.md +50 -0
  51. package/skills/app-compose-4-design-mock/references/screen-detailview.md +106 -0
  52. package/skills/app-compose-4-design-mock/references/screen-form.md +139 -0
  53. package/skills/app-compose-4-design-mock/references/screen-listview.md +153 -0
  54. package/skills/app-compose-4-design-mock/references/structure.md +27 -0
  55. package/skills/app-compose-5-design-mock-review/SKILL.md +290 -0
  56. package/skills/app-compose-5-design-mock-review/references/component.md +50 -0
  57. package/skills/app-compose-5-design-mock-review/references/screen-detailview.md +106 -0
  58. package/skills/app-compose-5-design-mock-review/references/screen-form.md +139 -0
  59. package/skills/app-compose-5-design-mock-review/references/screen-listview.md +153 -0
  60. package/skills/app-compose-6-implementation-spec/SKILL.md +127 -0
  61. package/skills/app-compose-6-implementation-spec/references/auth.md +72 -0
  62. package/skills/app-compose-6-implementation-spec/references/structure.md +27 -0
  63. package/skills/mock-scenario/SKILL.md +118 -0
  64. package/src/app.ts +1 -0
  65. package/src/cli.ts +120 -0
  66. package/src/commands/check.test.ts +30 -0
  67. package/src/commands/check.ts +66 -0
  68. package/src/commands/init.test.ts +88 -0
  69. package/src/commands/init.ts +120 -0
  70. package/src/commands/mock/index.ts +53 -0
  71. package/src/commands/mock/start.ts +179 -0
  72. package/src/commands/mock/validate.test.ts +185 -0
  73. package/src/commands/mock/validate.ts +198 -0
  74. package/src/commands/scaffold.test.ts +76 -0
  75. package/src/commands/scaffold.ts +119 -0
  76. package/src/commands/sync-check.test.ts +125 -0
  77. package/src/commands/sync-check.ts +182 -0
  78. package/src/integration.test.ts +63 -0
  79. package/src/mdschema.ts +48 -0
  80. package/src/mockServer.ts +55 -0
  81. package/src/module.ts +86 -0
  82. package/src/modules/accounting/.gitkeep +0 -0
  83. package/src/modules/coa-management/.gitkeep +0 -0
  84. package/src/modules/inventory/.gitkeep +0 -0
  85. package/src/modules/manufacturing/.gitkeep +0 -0
  86. package/src/modules/primitives/README.md +39 -0
  87. package/src/modules/primitives/command/activateCategory.test.ts +75 -0
  88. package/src/modules/primitives/command/activateCategory.ts +50 -0
  89. package/src/modules/primitives/command/activateCurrency.test.ts +70 -0
  90. package/src/modules/primitives/command/activateCurrency.ts +50 -0
  91. package/src/modules/primitives/command/activateUnit.test.ts +53 -0
  92. package/src/modules/primitives/command/activateUnit.ts +50 -0
  93. package/src/modules/primitives/command/convertAmount.test.ts +275 -0
  94. package/src/modules/primitives/command/convertAmount.ts +126 -0
  95. package/src/modules/primitives/command/convertQuantity.test.ts +219 -0
  96. package/src/modules/primitives/command/convertQuantity.ts +73 -0
  97. package/src/modules/primitives/command/createCategory.test.ts +126 -0
  98. package/src/modules/primitives/command/createCategory.ts +89 -0
  99. package/src/modules/primitives/command/createCurrency.test.ts +191 -0
  100. package/src/modules/primitives/command/createCurrency.ts +77 -0
  101. package/src/modules/primitives/command/createExchangeRate.test.ts +216 -0
  102. package/src/modules/primitives/command/createExchangeRate.ts +91 -0
  103. package/src/modules/primitives/command/createUnit.test.ts +214 -0
  104. package/src/modules/primitives/command/createUnit.ts +88 -0
  105. package/src/modules/primitives/command/deactivateCategory.test.ts +97 -0
  106. package/src/modules/primitives/command/deactivateCategory.ts +62 -0
  107. package/src/modules/primitives/command/deactivateCurrency.test.ts +85 -0
  108. package/src/modules/primitives/command/deactivateCurrency.ts +55 -0
  109. package/src/modules/primitives/command/deactivateUnit.test.ts +78 -0
  110. package/src/modules/primitives/command/deactivateUnit.ts +62 -0
  111. package/src/modules/primitives/command/setBaseCurrency.test.ts +98 -0
  112. package/src/modules/primitives/command/setBaseCurrency.ts +74 -0
  113. package/src/modules/primitives/command/setReferenceUnit.test.ts +108 -0
  114. package/src/modules/primitives/command/setReferenceUnit.ts +84 -0
  115. package/src/modules/primitives/db/currency.ts +30 -0
  116. package/src/modules/primitives/db/exchangeRate.ts +28 -0
  117. package/src/modules/primitives/db/unit.ts +32 -0
  118. package/src/modules/primitives/db/uomCategory.ts +32 -0
  119. package/src/modules/primitives/docs/commands/ActivateCategory.md +34 -0
  120. package/src/modules/primitives/docs/commands/ActivateCurrency.md +33 -0
  121. package/src/modules/primitives/docs/commands/ActivateUnit.md +34 -0
  122. package/src/modules/primitives/docs/commands/ConvertAmount.md +50 -0
  123. package/src/modules/primitives/docs/commands/ConvertQuantity.md +43 -0
  124. package/src/modules/primitives/docs/commands/CreateCategory.md +44 -0
  125. package/src/modules/primitives/docs/commands/CreateCurrency.md +47 -0
  126. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +48 -0
  127. package/src/modules/primitives/docs/commands/CreateUnit.md +48 -0
  128. package/src/modules/primitives/docs/commands/DeactivateCategory.md +38 -0
  129. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +38 -0
  130. package/src/modules/primitives/docs/commands/DeactivateUnit.md +38 -0
  131. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +39 -0
  132. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +43 -0
  133. package/src/modules/primitives/docs/features/currency-definitions.md +55 -0
  134. package/src/modules/primitives/docs/features/exchange-rates.md +61 -0
  135. package/src/modules/primitives/docs/features/unit-conversion.md +66 -0
  136. package/src/modules/primitives/docs/features/uom-categories.md +52 -0
  137. package/src/modules/primitives/docs/models/Currency.md +45 -0
  138. package/src/modules/primitives/docs/models/ExchangeRate.md +33 -0
  139. package/src/modules/primitives/docs/models/Unit.md +46 -0
  140. package/src/modules/primitives/docs/models/UoMCategory.md +44 -0
  141. package/src/modules/primitives/generated/kysely-tailordb.ts +95 -0
  142. package/src/modules/primitives/index.ts +40 -0
  143. package/src/modules/primitives/lib/errors.ts +138 -0
  144. package/src/modules/primitives/lib/types.ts +20 -0
  145. package/src/modules/primitives/module.ts +66 -0
  146. package/src/modules/primitives/permissions.ts +18 -0
  147. package/src/modules/primitives/tailor.config.ts +11 -0
  148. package/src/modules/primitives/testing/fixtures.ts +161 -0
  149. package/src/modules/product-management/.gitkeep +0 -0
  150. package/src/modules/purchase/.gitkeep +0 -0
  151. package/src/modules/sales/.gitkeep +0 -0
  152. package/src/modules/shared/createContext.test.ts +39 -0
  153. package/src/modules/shared/createContext.ts +15 -0
  154. package/src/modules/shared/defineCommand.test.ts +42 -0
  155. package/src/modules/shared/defineCommand.ts +19 -0
  156. package/src/modules/shared/definePermissions.test.ts +146 -0
  157. package/src/modules/shared/definePermissions.ts +94 -0
  158. package/src/modules/shared/entityTypes.ts +15 -0
  159. package/src/modules/shared/errors.ts +22 -0
  160. package/src/modules/shared/index.ts +1 -0
  161. package/src/modules/shared/internal.ts +13 -0
  162. package/src/modules/shared/requirePermission.test.ts +47 -0
  163. package/src/modules/shared/requirePermission.ts +8 -0
  164. package/src/modules/shared/types.ts +4 -0
  165. package/src/modules/supplier-management/.gitkeep +0 -0
  166. package/src/modules/supplier-portal/.gitkeep +0 -0
  167. package/src/modules/testing/index.ts +120 -0
  168. package/src/modules/user-management/README.md +38 -0
  169. package/src/modules/user-management/command/activateUser.test.ts +112 -0
  170. package/src/modules/user-management/command/activateUser.ts +67 -0
  171. package/src/modules/user-management/command/assignPermissionToRole.test.ts +119 -0
  172. package/src/modules/user-management/command/assignPermissionToRole.ts +87 -0
  173. package/src/modules/user-management/command/assignRoleToUser.test.ts +162 -0
  174. package/src/modules/user-management/command/assignRoleToUser.ts +93 -0
  175. package/src/modules/user-management/command/createPermission.test.ts +143 -0
  176. package/src/modules/user-management/command/createPermission.ts +66 -0
  177. package/src/modules/user-management/command/createRole.test.ts +115 -0
  178. package/src/modules/user-management/command/createRole.ts +52 -0
  179. package/src/modules/user-management/command/createUser.test.ts +198 -0
  180. package/src/modules/user-management/command/createUser.ts +85 -0
  181. package/src/modules/user-management/command/deactivateUser.test.ts +112 -0
  182. package/src/modules/user-management/command/deactivateUser.ts +67 -0
  183. package/src/modules/user-management/command/logAuditEvent.test.ts +179 -0
  184. package/src/modules/user-management/command/logAuditEvent.ts +59 -0
  185. package/src/modules/user-management/command/reactivateUser.test.ts +115 -0
  186. package/src/modules/user-management/command/reactivateUser.ts +67 -0
  187. package/src/modules/user-management/command/revokePermissionFromRole.test.ts +112 -0
  188. package/src/modules/user-management/command/revokePermissionFromRole.ts +81 -0
  189. package/src/modules/user-management/command/revokeRoleFromUser.test.ts +112 -0
  190. package/src/modules/user-management/command/revokeRoleFromUser.ts +81 -0
  191. package/src/modules/user-management/db/auditEvent.ts +47 -0
  192. package/src/modules/user-management/db/permission.ts +31 -0
  193. package/src/modules/user-management/db/role.ts +28 -0
  194. package/src/modules/user-management/db/rolePermission.ts +44 -0
  195. package/src/modules/user-management/db/user.ts +38 -0
  196. package/src/modules/user-management/db/userRole.ts +44 -0
  197. package/src/modules/user-management/docs/commands/ActivateUser.md +36 -0
  198. package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +39 -0
  199. package/src/modules/user-management/docs/commands/AssignRoleToUser.md +43 -0
  200. package/src/modules/user-management/docs/commands/CreatePermission.md +35 -0
  201. package/src/modules/user-management/docs/commands/CreateRole.md +35 -0
  202. package/src/modules/user-management/docs/commands/CreateUser.md +41 -0
  203. package/src/modules/user-management/docs/commands/DeactivateUser.md +38 -0
  204. package/src/modules/user-management/docs/commands/LogAuditEvent.md +37 -0
  205. package/src/modules/user-management/docs/commands/ReactivateUser.md +37 -0
  206. package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +40 -0
  207. package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +40 -0
  208. package/src/modules/user-management/docs/features/audit-trail.md +80 -0
  209. package/src/modules/user-management/docs/features/role-based-access-control.md +76 -0
  210. package/src/modules/user-management/docs/features/user-account-management.md +64 -0
  211. package/src/modules/user-management/docs/models/AuditEvent.md +34 -0
  212. package/src/modules/user-management/docs/models/Permission.md +31 -0
  213. package/src/modules/user-management/docs/models/Role.md +31 -0
  214. package/src/modules/user-management/docs/models/RolePermission.md +33 -0
  215. package/src/modules/user-management/docs/models/User.md +47 -0
  216. package/src/modules/user-management/docs/models/UserRole.md +34 -0
  217. package/src/modules/user-management/docs/plans/2026-01-30-flattened-permissions-design.md +52 -0
  218. package/src/modules/user-management/executor/recomputeOnRolePermissionChange.ts +61 -0
  219. package/src/modules/user-management/generated/enums.ts +24 -0
  220. package/src/modules/user-management/generated/kysely-tailordb.ts +112 -0
  221. package/src/modules/user-management/index.ts +32 -0
  222. package/src/modules/user-management/lib/errors.ts +81 -0
  223. package/src/modules/user-management/lib/recomputeUserPermissions.ts +53 -0
  224. package/src/modules/user-management/lib/types.ts +31 -0
  225. package/src/modules/user-management/module.ts +77 -0
  226. package/src/modules/user-management/permissions.ts +15 -0
  227. package/src/modules/user-management/tailor.config.ts +11 -0
  228. package/src/modules/user-management/testing/fixtures.ts +98 -0
  229. package/src/schemas.ts +25 -0
  230. package/src/testing.ts +10 -0
  231. package/src/util.ts +3 -0
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: 4-module-tdd-implementation
3
+ description: Use when implementing features in any module under modules/. Triggers on TDD workflow, domain command implementation, adding new database models, creating test fixtures, or implementing business logic commands.
4
+ ---
5
+
6
+ # TDD Implementation for Module Development
7
+
8
+ Guide for implementing features in modules using Test-Driven Development.
9
+
10
+ ## When to Use
11
+
12
+ - Implementing new domain commands in any module
13
+ - Adding database models with `@tailor-platform/sdk`
14
+ - Creating tests with `@tailor-platform/erp-kit` testing utilities
15
+ - Implementing business logic (CRUD, state transitions, relationships)
16
+
17
+ ## Workflow
18
+
19
+ ```
20
+ MODELS → ERRORS → FIXTURES → TESTS → IMPLEMENT → EXPORT → VERIFY
21
+ ```
22
+
23
+ ## Step-by-Step
24
+
25
+ ### 1. Database Models (`src/db/`)
26
+
27
+ **Read [models rules](references/models.md) and [db-relations rules](references/db-relations.md) before writing any model.**
28
+
29
+ Key patterns: factory function, `db.fields.timestamps()`, `.description()` on fields, `.relation()` for foreign keys.
30
+
31
+ ### 2. Error Classes (`src/lib/errors.ts`)
32
+
33
+ **Read [errors rules](references/errors.md) before defining errors.**
34
+
35
+ Key patterns: `name` as const = class name, `code` as const = SCREAMING_SNAKE_CASE.
36
+
37
+ ### 3. Test Fixtures (`src/testing/fixtures.ts`)
38
+
39
+ **Read [testing rules](references/testing.md) before writing fixtures or tests.**
40
+
41
+ ### 4. Write Tests First (`src/command/*.test.ts`)
42
+
43
+ Same reference: [testing rules](references/testing.md).
44
+
45
+ Key patterns: `createMockDb<DB>()`, fixed IDs `"entity-1"`, cover all doc branches.
46
+
47
+ ### 5. Implement Commands (`src/command/*.ts`)
48
+
49
+ **Read [commands rules](references/commands.md) before implementing.**
50
+
51
+ Key patterns: dual function (`_fn` internal + `fn<T>` public), validate → query → mutate.
52
+
53
+ ### 6. Export (`src/index.ts`)
54
+
55
+ **Read [exports rules](references/exports.md) for export order.**
56
+
57
+ ### 7. Verify
58
+
59
+ ```bash
60
+ pnpm generate # Regenerate types if models changed
61
+ pnpm lint # Check code style
62
+ pnpm typecheck # Verify TypeScript types
63
+ pnpm test # Run all tests
64
+ ```
65
+
66
+ ## References
67
+
68
+ - [Module structure](references/structure.md)
69
+ - [Model patterns](references/models.md)
70
+ - [Database relations](references/db-relations.md)
71
+ - [Command patterns](references/commands.md)
72
+ - [Error patterns](references/errors.md)
73
+ - [Testing patterns](references/testing.md)
74
+ - [Export order](references/exports.md)
@@ -0,0 +1,45 @@
1
+ # Command Implementation
2
+
3
+ ## Dual Function Pattern
4
+
5
+ Two functions per operation: internal `_fn` and public `fn`.
6
+
7
+ **Internal function (`_myFunction`):**
8
+
9
+ - Takes concrete `DB` type from `generated/kysely-tailordb`
10
+ - Return type uses `Schema` from `lib/types`: `Promise<{ entity: Entity<Schema> }>`
11
+ - Contains actual implementation
12
+
13
+ **Public function (`myFunction`):**
14
+
15
+ - Generic signature: `<T extends { Entity: object }>(db: Kysely<T>, ...)`
16
+ - Return type uses generic `T`: `Promise<{ entity: Entity<T> }>`
17
+ - Delegates to internal with type casting: `_fn(db as unknown as DB, ...) as unknown as Result`
18
+
19
+ ## Implementation Considerations
20
+
21
+ - **Validation**: Check referenced entities exist before operating
22
+ - **Idempotency**: For assign/revoke, return existing instead of throwing
23
+ - **Return format**: Wrap in object `{ entity }` not just `entity`
24
+
25
+ ## Conventions
26
+
27
+ - Input types: exported interfaces (`export interface MyFunctionInput`)
28
+ - Use `.executeTakeFirst()` for single results
29
+ - Include JSDoc: `/** Function: name \n Description */`
30
+
31
+ ## State Transitions
32
+
33
+ For commands that transition between statuses, accept `from?: string[]` with a default:
34
+
35
+ ```typescript
36
+ from?: string[]; // Default: ["ACTIVE"]
37
+
38
+ const validFromStatuses = input.from ?? ["ACTIVE"];
39
+ if (!validFromStatuses.includes(user.status)) {
40
+ throw new InvalidStatusTransitionError(user.status, targetStatus);
41
+ }
42
+ ```
43
+
44
+ - Default `from` contains the base valid source status
45
+ - Parent modules can override to allow transitions from additional statuses
@@ -0,0 +1,69 @@
1
+ # Database Relations
2
+
3
+ ## Relation Pattern
4
+
5
+ Use `.relation()` for foreign keys instead of plain `db.uuid()`:
6
+
7
+ ```typescript
8
+ userId: db.uuid().relation({
9
+ type: "n-1",
10
+ toward: { type: user },
11
+ backward: "userRoles",
12
+ }).description("Foreign key to User"),
13
+ ```
14
+
15
+ ### Parameters
16
+
17
+ - `type`: `"n-1"` (many-to-one), `"1-1"` (one-to-one), or `"keyOnly"` (FK only, no navigation)
18
+ - `toward.type`: The related type definition (import it)
19
+ - `backward`: Field name for reverse navigation from the related type
20
+
21
+ ### Benefits over plain `db.uuid()`
22
+
23
+ - Foreign key constraints (referential integrity)
24
+ - Forward navigation: `UserRole.user`
25
+ - Backward navigation: `User.userRoles`
26
+ - GraphQL relational queries
27
+
28
+ ## Junction Tables (Many-to-Many)
29
+
30
+ Junction tables need relations on both foreign keys plus a composite unique index:
31
+
32
+ ```typescript
33
+ import { user } from "./user";
34
+ import { role } from "./role";
35
+
36
+ db.type("UserRole", {
37
+ userId: db.uuid().relation({
38
+ type: "n-1",
39
+ toward: { type: user },
40
+ backward: "userRoles",
41
+ }),
42
+ roleId: db.uuid().relation({
43
+ type: "n-1",
44
+ toward: { type: role },
45
+ backward: "userRoles",
46
+ }),
47
+ }).indexes({
48
+ fields: ["userId", "roleId"],
49
+ unique: true,
50
+ name: "user_role_unique_idx",
51
+ });
52
+ ```
53
+
54
+ ### Naming Conventions
55
+
56
+ - `backward` field: Use plural of the junction table name (e.g., `"userRoles"`, `"rolePermissions"`)
57
+ - Index name: `{table}_unique_idx` pattern
58
+
59
+ ## Composite Indexes
60
+
61
+ Use `.indexes()` (not `.uniqueIndex()`) for multi-column constraints:
62
+
63
+ ```typescript
64
+ .indexes({
65
+ fields: ["fieldA", "fieldB"],
66
+ unique: true,
67
+ name: "descriptive_idx_name",
68
+ })
69
+ ```
@@ -0,0 +1,7 @@
1
+ # Error Classes
2
+
3
+ Naming convention:
4
+
5
+ - `name`: Class name exactly, `as const`
6
+ - `code`: SCREAMING_SNAKE_CASE, `as const`
7
+ - Constructor includes context (IDs, values)
@@ -0,0 +1,8 @@
1
+ # Module Exports
2
+
3
+ Export order:
4
+
5
+ 1. `defineModule` from module.ts
6
+ 2. Generated types (enum values + types separately)
7
+ 3. Error classes (for typed catch blocks)
8
+ 4. Domain functions with input types
@@ -0,0 +1,30 @@
1
+ # Database Models
2
+
3
+ ## Factory Function Pattern
4
+
5
+ ```typescript
6
+ export function createEntityType(params: {
7
+ fields?: Record<string, unknown>;
8
+ additionalStatuses?: string[];
9
+ });
10
+ ```
11
+
12
+ - Include `...db.fields.timestamps()`
13
+ - Use `.description()` for field docs
14
+ - Apply permissions at model level
15
+
16
+ ## Stateful Model Enums
17
+
18
+ Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
19
+
20
+ ```typescript
21
+ // Good: extension only
22
+ const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
23
+ const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
24
+
25
+ // Bad: allows replacement
26
+ const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
27
+ ```
28
+
29
+ - Name parameter `additionalX` to signal extension-only
30
+ - Parent modules handle their additional status transitions
@@ -0,0 +1,22 @@
1
+ # Module Directory Structure
2
+
3
+ ```
4
+ src/
5
+ ├── db/ # Database models (one file per model)
6
+ ├── executor/ # Async executors (record triggers, job functions)
7
+ ├── command/ # Domain commands + tests (*.test.ts co-located)
8
+ ├── lib/ # Internal shared code (errors.ts, types.ts)
9
+ ├── testing/ # Test fixtures and helpers
10
+ ├── generated/ # Auto-generated code (do not edit)
11
+ ├── index.ts # Public exports
12
+ └── module.ts # Module definition
13
+ ```
14
+
15
+ ## Rules
16
+
17
+ - `db/`: Only documentable model definitions, no helpers
18
+ - `executor/`: Async executors as factory functions (see executors.md)
19
+ - `command/`: Domain commands + co-located tests, no utilities
20
+ - `lib/`: Internal errors and types (not documented)
21
+ - `testing/`: Fixtures for tests only
22
+ - Run `pnpm generate` after modifying `db/` models
@@ -0,0 +1,37 @@
1
+ # Testing Patterns
2
+
3
+ ## Test Coverage Goal
4
+
5
+ Tests should cover all paths in the corresponding `docs/commands/*.md`:
6
+
7
+ - **Process Flow**: Each branch in the mermaid flowchart = one test case
8
+ - **Error Scenarios**: Each error code listed = one test case
9
+ - **Idempotent paths**: If flowchart shows "Already exists? → Return existing"
10
+
11
+ ## Mock Database
12
+
13
+ ```typescript
14
+ const { db, spies } = createMockDb<DB>();
15
+
16
+ // Single return
17
+ spies.select.mockReturnValue(entity);
18
+
19
+ // Sequential returns (in query execution order)
20
+ spies.select.mockReturnValueOnce(first).mockReturnValueOnce(second);
21
+ ```
22
+
23
+ ## Custom Fields Passthrough
24
+
25
+ For `makeCreateX` factory commands, add one test verifying custom fields reach `.values()`:
26
+
27
+ - Instantiate with concrete type: `makeCreateX<{ myField: string }>()`
28
+ - Assert with `spies.values`: `expect(spies.values).toHaveBeenNthCalledWith(1, expect.objectContaining({ myField: "value" }))`
29
+ - Use `toHaveBeenNthCalledWith(n, ...)` when multiple inserts occur (e.g., audit events)
30
+
31
+ ## Fixtures (`src/testing/fixtures.ts`)
32
+
33
+ - Import `Schema` from `lib/types` (not `Namespace` from generated code)
34
+ - Pattern: `export const baseEntity = { ... } as const satisfies Entity<Schema>`
35
+ - Fixed IDs for traceability: `"entity-1"`
36
+ - Consistent timestamp: `new Date("2024-01-01T00:00:00.000Z")`
37
+ - `updatedAt: null` for base fixtures