@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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +196 -28
- package/dist/cli.js +914 -0
- package/package.json +67 -8
- package/schemas/app-compose/actors.yml +34 -0
- package/schemas/app-compose/business-flow.yml +50 -0
- package/schemas/app-compose/requirements.yml +33 -0
- package/schemas/app-compose/resolver.yml +47 -0
- package/schemas/app-compose/screen.yml +81 -0
- package/schemas/app-compose/story.yml +67 -0
- package/schemas/module/command.yml +52 -0
- package/schemas/module/feature.yml +58 -0
- package/schemas/module/model.yml +70 -0
- package/schemas/module/module.yml +50 -0
- package/skills/1-module-docs/SKILL.md +111 -0
- package/skills/1-module-docs/references/structure.md +22 -0
- package/skills/2-module-feature-breakdown/SKILL.md +72 -0
- package/skills/2-module-feature-breakdown/references/commands.md +48 -0
- package/skills/2-module-feature-breakdown/references/models.md +29 -0
- package/skills/2-module-feature-breakdown/references/structure.md +22 -0
- package/skills/3-module-doc-review/SKILL.md +236 -0
- package/skills/3-module-doc-review/references/commands.md +54 -0
- package/skills/3-module-doc-review/references/models.md +29 -0
- package/skills/3-module-doc-review/references/testing.md +37 -0
- package/skills/4-module-tdd-implementation/SKILL.md +74 -0
- package/skills/4-module-tdd-implementation/references/commands.md +45 -0
- package/skills/4-module-tdd-implementation/references/db-relations.md +69 -0
- package/skills/4-module-tdd-implementation/references/errors.md +7 -0
- package/skills/4-module-tdd-implementation/references/exports.md +8 -0
- package/skills/4-module-tdd-implementation/references/models.md +30 -0
- package/skills/4-module-tdd-implementation/references/structure.md +22 -0
- package/skills/4-module-tdd-implementation/references/testing.md +37 -0
- package/skills/5-module-implementation-review/SKILL.md +408 -0
- package/skills/5-module-implementation-review/references/commands.md +45 -0
- package/skills/5-module-implementation-review/references/errors.md +7 -0
- package/skills/5-module-implementation-review/references/exports.md +8 -0
- package/skills/5-module-implementation-review/references/models.md +30 -0
- package/skills/5-module-implementation-review/references/testing.md +29 -0
- package/skills/app-compose-1-requirement-analysis/SKILL.md +89 -0
- package/skills/app-compose-1-requirement-analysis/references/structure.md +27 -0
- package/skills/app-compose-2-requirements-breakdown/SKILL.md +95 -0
- package/skills/app-compose-2-requirements-breakdown/references/screen-detailview.md +106 -0
- package/skills/app-compose-2-requirements-breakdown/references/screen-form.md +139 -0
- package/skills/app-compose-2-requirements-breakdown/references/screen-listview.md +153 -0
- package/skills/app-compose-2-requirements-breakdown/references/structure.md +27 -0
- package/skills/app-compose-3-doc-review/SKILL.md +116 -0
- package/skills/app-compose-3-doc-review/references/structure.md +27 -0
- package/skills/app-compose-4-design-mock/SKILL.md +256 -0
- package/skills/app-compose-4-design-mock/references/component.md +50 -0
- package/skills/app-compose-4-design-mock/references/screen-detailview.md +106 -0
- package/skills/app-compose-4-design-mock/references/screen-form.md +139 -0
- package/skills/app-compose-4-design-mock/references/screen-listview.md +153 -0
- package/skills/app-compose-4-design-mock/references/structure.md +27 -0
- package/skills/app-compose-5-design-mock-review/SKILL.md +290 -0
- package/skills/app-compose-5-design-mock-review/references/component.md +50 -0
- package/skills/app-compose-5-design-mock-review/references/screen-detailview.md +106 -0
- package/skills/app-compose-5-design-mock-review/references/screen-form.md +139 -0
- package/skills/app-compose-5-design-mock-review/references/screen-listview.md +153 -0
- package/skills/app-compose-6-implementation-spec/SKILL.md +127 -0
- package/skills/app-compose-6-implementation-spec/references/auth.md +72 -0
- package/skills/app-compose-6-implementation-spec/references/structure.md +27 -0
- package/skills/mock-scenario/SKILL.md +118 -0
- package/src/app.ts +1 -0
- package/src/cli.ts +120 -0
- package/src/commands/check.test.ts +30 -0
- package/src/commands/check.ts +66 -0
- package/src/commands/init.test.ts +88 -0
- package/src/commands/init.ts +120 -0
- package/src/commands/mock/index.ts +53 -0
- package/src/commands/mock/start.ts +179 -0
- package/src/commands/mock/validate.test.ts +185 -0
- package/src/commands/mock/validate.ts +198 -0
- package/src/commands/scaffold.test.ts +76 -0
- package/src/commands/scaffold.ts +119 -0
- package/src/commands/sync-check.test.ts +125 -0
- package/src/commands/sync-check.ts +182 -0
- package/src/integration.test.ts +63 -0
- package/src/mdschema.ts +48 -0
- package/src/mockServer.ts +55 -0
- package/src/module.ts +86 -0
- package/src/modules/accounting/.gitkeep +0 -0
- package/src/modules/coa-management/.gitkeep +0 -0
- package/src/modules/inventory/.gitkeep +0 -0
- package/src/modules/manufacturing/.gitkeep +0 -0
- package/src/modules/primitives/README.md +39 -0
- package/src/modules/primitives/command/activateCategory.test.ts +75 -0
- package/src/modules/primitives/command/activateCategory.ts +50 -0
- package/src/modules/primitives/command/activateCurrency.test.ts +70 -0
- package/src/modules/primitives/command/activateCurrency.ts +50 -0
- package/src/modules/primitives/command/activateUnit.test.ts +53 -0
- package/src/modules/primitives/command/activateUnit.ts +50 -0
- package/src/modules/primitives/command/convertAmount.test.ts +275 -0
- package/src/modules/primitives/command/convertAmount.ts +126 -0
- package/src/modules/primitives/command/convertQuantity.test.ts +219 -0
- package/src/modules/primitives/command/convertQuantity.ts +73 -0
- package/src/modules/primitives/command/createCategory.test.ts +126 -0
- package/src/modules/primitives/command/createCategory.ts +89 -0
- package/src/modules/primitives/command/createCurrency.test.ts +191 -0
- package/src/modules/primitives/command/createCurrency.ts +77 -0
- package/src/modules/primitives/command/createExchangeRate.test.ts +216 -0
- package/src/modules/primitives/command/createExchangeRate.ts +91 -0
- package/src/modules/primitives/command/createUnit.test.ts +214 -0
- package/src/modules/primitives/command/createUnit.ts +88 -0
- package/src/modules/primitives/command/deactivateCategory.test.ts +97 -0
- package/src/modules/primitives/command/deactivateCategory.ts +62 -0
- package/src/modules/primitives/command/deactivateCurrency.test.ts +85 -0
- package/src/modules/primitives/command/deactivateCurrency.ts +55 -0
- package/src/modules/primitives/command/deactivateUnit.test.ts +78 -0
- package/src/modules/primitives/command/deactivateUnit.ts +62 -0
- package/src/modules/primitives/command/setBaseCurrency.test.ts +98 -0
- package/src/modules/primitives/command/setBaseCurrency.ts +74 -0
- package/src/modules/primitives/command/setReferenceUnit.test.ts +108 -0
- package/src/modules/primitives/command/setReferenceUnit.ts +84 -0
- package/src/modules/primitives/db/currency.ts +30 -0
- package/src/modules/primitives/db/exchangeRate.ts +28 -0
- package/src/modules/primitives/db/unit.ts +32 -0
- package/src/modules/primitives/db/uomCategory.ts +32 -0
- package/src/modules/primitives/docs/commands/ActivateCategory.md +34 -0
- package/src/modules/primitives/docs/commands/ActivateCurrency.md +33 -0
- package/src/modules/primitives/docs/commands/ActivateUnit.md +34 -0
- package/src/modules/primitives/docs/commands/ConvertAmount.md +50 -0
- package/src/modules/primitives/docs/commands/ConvertQuantity.md +43 -0
- package/src/modules/primitives/docs/commands/CreateCategory.md +44 -0
- package/src/modules/primitives/docs/commands/CreateCurrency.md +47 -0
- package/src/modules/primitives/docs/commands/CreateExchangeRate.md +48 -0
- package/src/modules/primitives/docs/commands/CreateUnit.md +48 -0
- package/src/modules/primitives/docs/commands/DeactivateCategory.md +38 -0
- package/src/modules/primitives/docs/commands/DeactivateCurrency.md +38 -0
- package/src/modules/primitives/docs/commands/DeactivateUnit.md +38 -0
- package/src/modules/primitives/docs/commands/SetBaseCurrency.md +39 -0
- package/src/modules/primitives/docs/commands/SetReferenceUnit.md +43 -0
- package/src/modules/primitives/docs/features/currency-definitions.md +55 -0
- package/src/modules/primitives/docs/features/exchange-rates.md +61 -0
- package/src/modules/primitives/docs/features/unit-conversion.md +66 -0
- package/src/modules/primitives/docs/features/uom-categories.md +52 -0
- package/src/modules/primitives/docs/models/Currency.md +45 -0
- package/src/modules/primitives/docs/models/ExchangeRate.md +33 -0
- package/src/modules/primitives/docs/models/Unit.md +46 -0
- package/src/modules/primitives/docs/models/UoMCategory.md +44 -0
- package/src/modules/primitives/generated/kysely-tailordb.ts +95 -0
- package/src/modules/primitives/index.ts +40 -0
- package/src/modules/primitives/lib/errors.ts +138 -0
- package/src/modules/primitives/lib/types.ts +20 -0
- package/src/modules/primitives/module.ts +66 -0
- package/src/modules/primitives/permissions.ts +18 -0
- package/src/modules/primitives/tailor.config.ts +11 -0
- package/src/modules/primitives/testing/fixtures.ts +161 -0
- package/src/modules/product-management/.gitkeep +0 -0
- package/src/modules/purchase/.gitkeep +0 -0
- package/src/modules/sales/.gitkeep +0 -0
- package/src/modules/shared/createContext.test.ts +39 -0
- package/src/modules/shared/createContext.ts +15 -0
- package/src/modules/shared/defineCommand.test.ts +42 -0
- package/src/modules/shared/defineCommand.ts +19 -0
- package/src/modules/shared/definePermissions.test.ts +146 -0
- package/src/modules/shared/definePermissions.ts +94 -0
- package/src/modules/shared/entityTypes.ts +15 -0
- package/src/modules/shared/errors.ts +22 -0
- package/src/modules/shared/index.ts +1 -0
- package/src/modules/shared/internal.ts +13 -0
- package/src/modules/shared/requirePermission.test.ts +47 -0
- package/src/modules/shared/requirePermission.ts +8 -0
- package/src/modules/shared/types.ts +4 -0
- package/src/modules/supplier-management/.gitkeep +0 -0
- package/src/modules/supplier-portal/.gitkeep +0 -0
- package/src/modules/testing/index.ts +120 -0
- package/src/modules/user-management/README.md +38 -0
- package/src/modules/user-management/command/activateUser.test.ts +112 -0
- package/src/modules/user-management/command/activateUser.ts +67 -0
- package/src/modules/user-management/command/assignPermissionToRole.test.ts +119 -0
- package/src/modules/user-management/command/assignPermissionToRole.ts +87 -0
- package/src/modules/user-management/command/assignRoleToUser.test.ts +162 -0
- package/src/modules/user-management/command/assignRoleToUser.ts +93 -0
- package/src/modules/user-management/command/createPermission.test.ts +143 -0
- package/src/modules/user-management/command/createPermission.ts +66 -0
- package/src/modules/user-management/command/createRole.test.ts +115 -0
- package/src/modules/user-management/command/createRole.ts +52 -0
- package/src/modules/user-management/command/createUser.test.ts +198 -0
- package/src/modules/user-management/command/createUser.ts +85 -0
- package/src/modules/user-management/command/deactivateUser.test.ts +112 -0
- package/src/modules/user-management/command/deactivateUser.ts +67 -0
- package/src/modules/user-management/command/logAuditEvent.test.ts +179 -0
- package/src/modules/user-management/command/logAuditEvent.ts +59 -0
- package/src/modules/user-management/command/reactivateUser.test.ts +115 -0
- package/src/modules/user-management/command/reactivateUser.ts +67 -0
- package/src/modules/user-management/command/revokePermissionFromRole.test.ts +112 -0
- package/src/modules/user-management/command/revokePermissionFromRole.ts +81 -0
- package/src/modules/user-management/command/revokeRoleFromUser.test.ts +112 -0
- package/src/modules/user-management/command/revokeRoleFromUser.ts +81 -0
- package/src/modules/user-management/db/auditEvent.ts +47 -0
- package/src/modules/user-management/db/permission.ts +31 -0
- package/src/modules/user-management/db/role.ts +28 -0
- package/src/modules/user-management/db/rolePermission.ts +44 -0
- package/src/modules/user-management/db/user.ts +38 -0
- package/src/modules/user-management/db/userRole.ts +44 -0
- package/src/modules/user-management/docs/commands/ActivateUser.md +36 -0
- package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +39 -0
- package/src/modules/user-management/docs/commands/AssignRoleToUser.md +43 -0
- package/src/modules/user-management/docs/commands/CreatePermission.md +35 -0
- package/src/modules/user-management/docs/commands/CreateRole.md +35 -0
- package/src/modules/user-management/docs/commands/CreateUser.md +41 -0
- package/src/modules/user-management/docs/commands/DeactivateUser.md +38 -0
- package/src/modules/user-management/docs/commands/LogAuditEvent.md +37 -0
- package/src/modules/user-management/docs/commands/ReactivateUser.md +37 -0
- package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +40 -0
- package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +40 -0
- package/src/modules/user-management/docs/features/audit-trail.md +80 -0
- package/src/modules/user-management/docs/features/role-based-access-control.md +76 -0
- package/src/modules/user-management/docs/features/user-account-management.md +64 -0
- package/src/modules/user-management/docs/models/AuditEvent.md +34 -0
- package/src/modules/user-management/docs/models/Permission.md +31 -0
- package/src/modules/user-management/docs/models/Role.md +31 -0
- package/src/modules/user-management/docs/models/RolePermission.md +33 -0
- package/src/modules/user-management/docs/models/User.md +47 -0
- package/src/modules/user-management/docs/models/UserRole.md +34 -0
- package/src/modules/user-management/docs/plans/2026-01-30-flattened-permissions-design.md +52 -0
- package/src/modules/user-management/executor/recomputeOnRolePermissionChange.ts +61 -0
- package/src/modules/user-management/generated/enums.ts +24 -0
- package/src/modules/user-management/generated/kysely-tailordb.ts +112 -0
- package/src/modules/user-management/index.ts +32 -0
- package/src/modules/user-management/lib/errors.ts +81 -0
- package/src/modules/user-management/lib/recomputeUserPermissions.ts +53 -0
- package/src/modules/user-management/lib/types.ts +31 -0
- package/src/modules/user-management/module.ts +77 -0
- package/src/modules/user-management/permissions.ts +15 -0
- package/src/modules/user-management/tailor.config.ts +11 -0
- package/src/modules/user-management/testing/fixtures.ts +98 -0
- package/src/schemas.ts +25 -0
- package/src/testing.ts +10 -0
- package/src/util.ts +3 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 1-module-docs
|
|
3
|
+
description: Create ERP module documentation following framework schemas. Use when starting a new module, documenting an existing module, or when user asks to create module docs, feature docs, or design module features. Guides collaborative research, scoping, and iterative feature breakdown.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Module Documentation Workflow
|
|
7
|
+
|
|
8
|
+
Collaborative workflow for creating ERP module documentation. Human and AI work together through research, scoping, design validation, and iterative refinement.
|
|
9
|
+
|
|
10
|
+
## Workflow Phases
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
RESEARCH → SCOPE → DESIGN → CREATE → REVIEW
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Phase 1: Research
|
|
17
|
+
|
|
18
|
+
Study established ERP solutions for the module domain:
|
|
19
|
+
|
|
20
|
+
1. **Web search** Odoo, Oracle ERP Cloud, SAP for the domain (e.g., "Odoo inventory management features")
|
|
21
|
+
2. **Fetch documentation** from official sources when available
|
|
22
|
+
3. **Identify** common features, models, workflows, compliance requirements
|
|
23
|
+
4. **Summarize** findings before proceeding
|
|
24
|
+
|
|
25
|
+
Key ERP references:
|
|
26
|
+
|
|
27
|
+
- Odoo: https://www.odoo.com/documentation/19.0/applications.html
|
|
28
|
+
- Oracle: https://docs.oracle.com/en/cloud/saas/index.html
|
|
29
|
+
- SAP: Search SAP Docs
|
|
30
|
+
|
|
31
|
+
### Phase 2: Scope
|
|
32
|
+
|
|
33
|
+
Present scope options to user. Use AskUserQuestion:
|
|
34
|
+
|
|
35
|
+
| Option | Description |
|
|
36
|
+
| ---------------------- | ----------------------------------------------------------------------- |
|
|
37
|
+
| **Minimal** | Core entities only, basic CRUD, no workflows |
|
|
38
|
+
| **Core (Recommended)** | Essential features for production use, foundational for other modules |
|
|
39
|
+
| **Comprehensive** | Full feature set including advanced workflows, compliance, integrations |
|
|
40
|
+
|
|
41
|
+
Wait for user selection before proceeding.
|
|
42
|
+
|
|
43
|
+
### Phase 3: Design
|
|
44
|
+
|
|
45
|
+
Present features incrementally for validation:
|
|
46
|
+
|
|
47
|
+
1. **List proposed features** as a table (feature name, purpose)
|
|
48
|
+
2. **Wait for user approval** of feature list
|
|
49
|
+
3. For each feature, briefly describe:
|
|
50
|
+
- What it does
|
|
51
|
+
- Key scenarios
|
|
52
|
+
4. **Ask**: "Does this feature breakdown look right?"
|
|
53
|
+
|
|
54
|
+
Keep descriptions concise (~100-200 words per section). Do not present all details at once.
|
|
55
|
+
|
|
56
|
+
### Phase 4: Create
|
|
57
|
+
|
|
58
|
+
Generate documentation following framework schemas.
|
|
59
|
+
|
|
60
|
+
**File structure:**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
modules/<module-name>/
|
|
64
|
+
├── README.md # module.yml schema
|
|
65
|
+
└── docs/
|
|
66
|
+
└── features/
|
|
67
|
+
└── <feature-name>.md # feature.yml schema
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Naming conventions:**
|
|
71
|
+
|
|
72
|
+
- Feature files: kebab-case (e.g., `role-based-access-control.md`)
|
|
73
|
+
- Headings: Title Case
|
|
74
|
+
|
|
75
|
+
Create with `erp-kit` CLI:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
erp-kit scaffold --modules-root modules module <module-name>
|
|
79
|
+
erp-kit scaffold --modules-root modules feature <module-name> <feature-name>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Phase 5: Review
|
|
83
|
+
|
|
84
|
+
After creating docs, user reviews and may request changes:
|
|
85
|
+
|
|
86
|
+
**Split detection**: If a feature covers multiple distinct workflows, split into separate feature files.
|
|
87
|
+
|
|
88
|
+
**Iteration pattern:**
|
|
89
|
+
|
|
90
|
+
1. User identifies issue (e.g., "X is too broad, split it")
|
|
91
|
+
2. Create new feature file for split-out content
|
|
92
|
+
3. Remove split content from original file
|
|
93
|
+
4. Update README.md feature list if needed
|
|
94
|
+
|
|
95
|
+
Continue iterating until user approves.
|
|
96
|
+
|
|
97
|
+
# Framework Schemas Reference
|
|
98
|
+
|
|
99
|
+
Schemas are bundled in `@tailor-platform/erp-kit`.
|
|
100
|
+
|
|
101
|
+
## Validation
|
|
102
|
+
|
|
103
|
+
Always run before completing:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pnpm run module:doc:check
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## References
|
|
110
|
+
|
|
111
|
+
- [Module structure](references/structure.md)
|
|
@@ -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,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 2-module-feature-breakdown
|
|
3
|
+
description: Use when breaking down a feature spec into model and command documentation. Triggers on feature implementation planning, creating model docs, creating command docs, or when user references model.yml/command.yml schemas.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Feature Breakdown to Model/Command Docs
|
|
7
|
+
|
|
8
|
+
Convert feature specifications into structured model and command documentation following framework schemas.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- User has a feature spec (e.g., `docs/features/*.md`) and wants implementation docs
|
|
13
|
+
- User asks to create model or command documentation
|
|
14
|
+
- User references `model.yml` or `command.yml` schemas
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
ANALYZE → SCAFFOLD → POPULATE → VALIDATE
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 1. Analyze
|
|
23
|
+
|
|
24
|
+
Read the feature spec and identify:
|
|
25
|
+
|
|
26
|
+
- **Models**: Entities with state, fields, relationships
|
|
27
|
+
- **Commands**: Operations that change state (look for verbs in state diagrams)
|
|
28
|
+
|
|
29
|
+
### 2. Scaffold
|
|
30
|
+
|
|
31
|
+
For each model and command, scaffold the documentation files using `erp-kit` CLI:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
erp-kit scaffold --modules-root modules model <module-name> <model-name>
|
|
35
|
+
erp-kit scaffold --modules-root modules command <module-name> <command-name>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 3. Populate
|
|
39
|
+
|
|
40
|
+
Fill in the scaffolded docs with details analyzed from Step 1.
|
|
41
|
+
|
|
42
|
+
### 4. Validate
|
|
43
|
+
|
|
44
|
+
Run `pnpm run module:doc:check` and fix any violations.
|
|
45
|
+
|
|
46
|
+
## Schema Quick Reference
|
|
47
|
+
|
|
48
|
+
Schemas are bundled in `@tailor-platform/erp-kit` (model.yml, command.yml).
|
|
49
|
+
|
|
50
|
+
## Common Patterns
|
|
51
|
+
|
|
52
|
+
| Feature Element | Documentation Type |
|
|
53
|
+
| --------------------- | -------------------------------- |
|
|
54
|
+
| Entity with fields | Model doc |
|
|
55
|
+
| State machine | Model doc with State Transitions |
|
|
56
|
+
| Verb in state diagram | Command doc |
|
|
57
|
+
| CRUD operation | Command doc |
|
|
58
|
+
| Validation logic | Command doc Business Rules |
|
|
59
|
+
|
|
60
|
+
## Validation
|
|
61
|
+
|
|
62
|
+
Always run before completing:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pnpm run module:doc:check
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## References
|
|
69
|
+
|
|
70
|
+
- [Module structure](references/structure.md)
|
|
71
|
+
- [Model patterns](references/models.md)
|
|
72
|
+
- [Command patterns](references/commands.md)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Command Implementation
|
|
2
|
+
|
|
3
|
+
## defineCommand Pattern
|
|
4
|
+
|
|
5
|
+
Commands that don't need custom fields use `defineCommand` directly:
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
export const myCommand = defineCommand(permissions.myCommand, async (db: DB, input: Input) => { ... });
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Factory Function Pattern (custom fields)
|
|
12
|
+
|
|
13
|
+
Commands that insert into a table with user-extensible fields use a `makeCreateX<CF>()` factory:
|
|
14
|
+
|
|
15
|
+
- Export only `makeCreateX` — no default instance
|
|
16
|
+
- Generic `CF extends Record<string, unknown>` for custom fields
|
|
17
|
+
- Input type: `CreateXInput & CF`
|
|
18
|
+
- Destructure known fields, rest-spread custom fields into `.values()` before known fields
|
|
19
|
+
- Cast custom fields: `...(customFields as Record<string, unknown>)`
|
|
20
|
+
- `module.ts` wires with `makeCreateX<FieldsToInsertable<F>>()`
|
|
21
|
+
|
|
22
|
+
## Implementation Considerations
|
|
23
|
+
|
|
24
|
+
- **Validation**: Check referenced entities exist before operating
|
|
25
|
+
- **Idempotency**: For assign/revoke, return existing instead of throwing
|
|
26
|
+
- **Return format**: Wrap in object `{ entity }` not just `entity`
|
|
27
|
+
|
|
28
|
+
## Conventions
|
|
29
|
+
|
|
30
|
+
- Input types: exported interfaces (`export interface MyFunctionInput`)
|
|
31
|
+
- Use `.executeTakeFirst()` for single results
|
|
32
|
+
- Include JSDoc: `/** Function: name \n Description */`
|
|
33
|
+
|
|
34
|
+
## State Transitions
|
|
35
|
+
|
|
36
|
+
For commands that transition between statuses, accept `from?: string[]` with a default:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
from?: string[]; // Default: ["ACTIVE"]
|
|
40
|
+
|
|
41
|
+
const validFromStatuses = input.from ?? ["ACTIVE"];
|
|
42
|
+
if (!validFromStatuses.includes(user.status)) {
|
|
43
|
+
throw new InvalidStatusTransitionError(user.status, targetStatus);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Default `from` contains the base valid source status
|
|
48
|
+
- Parent modules can override to allow transitions from additional statuses
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Database Models
|
|
2
|
+
|
|
3
|
+
## Factory Function Pattern
|
|
4
|
+
|
|
5
|
+
Each model is a `createXType<const F>(params)` factory:
|
|
6
|
+
|
|
7
|
+
- Params interface generic: `F extends Record<string, TailorAnyDBField>`
|
|
8
|
+
- `fields?: F` — optional custom fields from parent modules
|
|
9
|
+
- Spread as `...(params.fields ?? {}) as F` to preserve type information
|
|
10
|
+
- Include `...db.fields.timestamps()`
|
|
11
|
+
- Use `.description()` for field docs
|
|
12
|
+
- Apply permissions at model level
|
|
13
|
+
- Export a default instance: `export const x = createXType({})`
|
|
14
|
+
|
|
15
|
+
## Stateful Model Enums
|
|
16
|
+
|
|
17
|
+
Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// Good: extension only
|
|
21
|
+
const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
|
|
22
|
+
const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
|
|
23
|
+
|
|
24
|
+
// Bad: allows replacement
|
|
25
|
+
const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Name parameter `additionalX` to signal extension-only
|
|
29
|
+
- 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,236 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 3-module-review
|
|
3
|
+
description: Review feature parity between feature documentation and command/model documentation. Use when validating that all feature scenarios are covered by command docs, and that all required models exist.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Feature Parity Review Workflow
|
|
7
|
+
|
|
8
|
+
Review **documentation consistency** between feature specs and command/model docs.
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
Verify that feature documentation (high-level business requirements) is properly covered by command documentation (command specifications) and model documentation (data structures).
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Feature Docs (What) → Command Docs (How) → Model Docs (With What)
|
|
16
|
+
↓ ↓ ↓
|
|
17
|
+
Scenarios Business Rules Data Structures
|
|
18
|
+
Process Flows Error Scenarios Relationships
|
|
19
|
+
Test Cases Process Flows Constraints
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## When to Use
|
|
23
|
+
|
|
24
|
+
- After writing feature documentation, check for gaps in command/model documentation
|
|
25
|
+
- After writing command/model documentation, verify consistency with features
|
|
26
|
+
- Quality check during documentation review
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
FEATURE DOCS → COMMAND DOCS → MODEL DOCS → COMPARE → REPORT
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Step-by-Step
|
|
35
|
+
|
|
36
|
+
### 1. Read Feature Documentation
|
|
37
|
+
|
|
38
|
+
Read ALL feature docs:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
modules/<module-name>/docs/features/*.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Read Command Documentation
|
|
45
|
+
|
|
46
|
+
Read ALL command docs:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
modules/<module-name>/docs/commands/*.md
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. Read Model Documentation
|
|
53
|
+
|
|
54
|
+
Read ALL model docs:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
modules/<module-name>/docs/models/*.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 4. Feature → Command Parity Check
|
|
61
|
+
|
|
62
|
+
For each feature's scenarios and test cases:
|
|
63
|
+
|
|
64
|
+
| Check Item | Question |
|
|
65
|
+
| ---------------------- | -------------------------------------------------------------------------- |
|
|
66
|
+
| Command existence | Does a command doc exist to implement the scenario? |
|
|
67
|
+
| Business rule coverage | Are feature test cases covered by command business rules? |
|
|
68
|
+
| Error handling | Are expected error cases from feature included in command error scenarios? |
|
|
69
|
+
| Process flow alignment | Does feature process flow match command process flow? |
|
|
70
|
+
|
|
71
|
+
#### How to Check
|
|
72
|
+
|
|
73
|
+
1. List all scenario patterns from feature
|
|
74
|
+
2. Identify required operations (verbs) for each scenario: "Add", "Update", "Delete", "Set default", etc.
|
|
75
|
+
3. Verify corresponding command doc exists
|
|
76
|
+
4. Map feature test cases to command business rules / error scenarios
|
|
77
|
+
|
|
78
|
+
### 5. Feature → Model Parity Check
|
|
79
|
+
|
|
80
|
+
For each entity mentioned in feature:
|
|
81
|
+
|
|
82
|
+
| Check Item | Question |
|
|
83
|
+
| ---------------- | ------------------------------------------------------------------ |
|
|
84
|
+
| Model existence | Does a model doc exist for entities mentioned in feature? |
|
|
85
|
+
| State management | Do feature state transitions match model state transitions? |
|
|
86
|
+
| Relationships | Are relationships shown in feature defined in model relationships? |
|
|
87
|
+
|
|
88
|
+
### 6. Command → Model Consistency Check
|
|
89
|
+
|
|
90
|
+
For each command doc:
|
|
91
|
+
|
|
92
|
+
| Check Item | Question |
|
|
93
|
+
| -------------------------- | -------------------------------------------------------------- |
|
|
94
|
+
| Target model | Does a model doc exist for the model that command operates on? |
|
|
95
|
+
| State transition alignment | Do state changes by command match model state transitions? |
|
|
96
|
+
|
|
97
|
+
### 7. Report Findings
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
## Feature Parity Review Report
|
|
101
|
+
|
|
102
|
+
**Module:** <module-name>
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### 1. Feature → Command Coverage
|
|
107
|
+
|
|
108
|
+
| Feature | Scenarios | Required Commands | Documented Commands | Gap |
|
|
109
|
+
| ----------- | ----------- | ---------------------------------- | ------------------------- | ------------------ |
|
|
110
|
+
| <feature-1> | N scenarios | <cmd-a>, <cmd-b>, <cmd-c>, <cmd-d> | <cmd-a>, <cmd-b>, <cmd-c> | ❌ <cmd-d> missing |
|
|
111
|
+
| <feature-2> | N scenarios | <cmd-e>, <cmd-f>, <cmd-g> | - | ❌ No command docs |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### 2. Feature → Model Coverage
|
|
116
|
+
|
|
117
|
+
| Feature | Required Models | Documented Models | Gap |
|
|
118
|
+
| ----------- | -------------------- | -------------------- | --- |
|
|
119
|
+
| <feature-1> | <Model-A> | <Model-A> | ✅ |
|
|
120
|
+
| <feature-2> | <Model-B>, <Model-A> | <Model-B>, <Model-A> | ✅ |
|
|
121
|
+
| <feature-3> | <Model-C>, <Model-A> | <Model-C>, <Model-A> | ✅ |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### 3. Test Case → Business Rule Mapping
|
|
126
|
+
|
|
127
|
+
| Feature | Test Case | Covered by Command | Status |
|
|
128
|
+
| ----------- | ------------------------------------------ | ----------------------- | ----------------- |
|
|
129
|
+
| <feature-1> | "<test case description from feature doc>" | <cmd-a> (business rule) | ✅ |
|
|
130
|
+
| <feature-1> | "<test case description from feature doc>" | <cmd-c> (business rule) | ✅ |
|
|
131
|
+
| <feature-2> | "<test case description from feature doc>" | - | ❌ No command doc |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### 4. Missing Documentation
|
|
136
|
+
|
|
137
|
+
#### Missing Command Docs
|
|
138
|
+
|
|
139
|
+
| Feature | Expected Command | Purpose |
|
|
140
|
+
| ----------- | ---------------- | --------------------- |
|
|
141
|
+
| <feature-2> | <cmd-e> | <purpose description> |
|
|
142
|
+
| <feature-2> | <cmd-f> | <purpose description> |
|
|
143
|
+
| <feature-2> | <cmd-g> | <purpose description> |
|
|
144
|
+
|
|
145
|
+
#### Missing Model Docs
|
|
146
|
+
|
|
147
|
+
(none found)
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### 5. Inconsistencies
|
|
152
|
+
|
|
153
|
+
| Type | Location | Issue |
|
|
154
|
+
| ------------------------- | -------------------------------------- | ----------------------------------------------------------------- |
|
|
155
|
+
| State transition mismatch | <feature-1> feature vs <Model-A> model | Feature shows "<cmd-x>" but no command doc exists |
|
|
156
|
+
| Missing error scenario | <feature-2> feature | "<error case from test cases>" has no corresponding command error |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### 6. Summary
|
|
161
|
+
|
|
162
|
+
| Aspect | Status | Details |
|
|
163
|
+
| -------------------------- | ------ | ------------------------------------------- |
|
|
164
|
+
| Feature → Command Coverage | ⚠️ | X/Y features have complete command coverage |
|
|
165
|
+
| Feature → Model Coverage | ✅ | All required models documented |
|
|
166
|
+
| Test Case Coverage | ⚠️ | X/Y test cases mapped to business rules |
|
|
167
|
+
| Documentation Consistency | ⚠️ | N inconsistencies found |
|
|
168
|
+
|
|
169
|
+
### 7. Recommendations
|
|
170
|
+
|
|
171
|
+
1. **Create missing command docs:**
|
|
172
|
+
- List all missing commands grouped by feature
|
|
173
|
+
|
|
174
|
+
2. **Add missing business rules to existing command docs:**
|
|
175
|
+
- Feature test cases not yet mapped to command business rules
|
|
176
|
+
3. **Resolve inconsistencies:**
|
|
177
|
+
- Align state transitions between feature and model docs
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Common Gaps
|
|
181
|
+
|
|
182
|
+
### Feature → Command
|
|
183
|
+
|
|
184
|
+
- **Orphaned scenarios**: Feature describes operation but no command doc exists
|
|
185
|
+
- **Missing CRUD**: Feature implies create/update/delete but only some are documented
|
|
186
|
+
- **Implicit commands**: Feature scenario requires helper command not documented
|
|
187
|
+
- **Default handling**: Feature mentions "default" selection but no setDefault command
|
|
188
|
+
|
|
189
|
+
### Feature → Model
|
|
190
|
+
|
|
191
|
+
- **Missing models**: Feature references entity with no model doc
|
|
192
|
+
- **State mismatch**: Feature shows states not in model's state diagram
|
|
193
|
+
- **Relationship gaps**: Feature implies relationship not in model doc
|
|
194
|
+
|
|
195
|
+
### Test Case → Business Rule
|
|
196
|
+
|
|
197
|
+
- **Uncovered test cases**: Feature test case has no corresponding business rule
|
|
198
|
+
- **Missing error scenarios**: Feature error case not in command's error scenarios
|
|
199
|
+
- **Validation gaps**: Feature constraint not enforced by any command
|
|
200
|
+
|
|
201
|
+
## Quick Reference: Extraction Patterns
|
|
202
|
+
|
|
203
|
+
### From Feature Docs
|
|
204
|
+
|
|
205
|
+
```markdown
|
|
206
|
+
## Scenario Patterns
|
|
207
|
+
|
|
208
|
+
- **Add <entity>**: ... → Command: add<Entity> / create<Entity>
|
|
209
|
+
- **Change default <entity>**: ... → Command: setDefault<Entity>
|
|
210
|
+
|
|
211
|
+
## Test Cases
|
|
212
|
+
|
|
213
|
+
- Adding a <entity> with valid data creates it in active status
|
|
214
|
+
→ Business rule in add<Entity>
|
|
215
|
+
- Only one <entity> can be default per <parent> at a time
|
|
216
|
+
→ Business rule in setDefault<Entity>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Expected Command Docs for Feature
|
|
220
|
+
|
|
221
|
+
| Feature Operation | Expected Command Doc |
|
|
222
|
+
| ----------------- | -------------------- |
|
|
223
|
+
| "Add X" | addX / createX |
|
|
224
|
+
| "Update X" | updateX |
|
|
225
|
+
| "Delete X" | deleteX |
|
|
226
|
+
| "Set default X" | setDefaultX |
|
|
227
|
+
| "Activate X" | activateX |
|
|
228
|
+
| "Deactivate X" | deactivateX |
|
|
229
|
+
| "Assign X to Y" | assignXToY |
|
|
230
|
+
| "Remove X from Y" | removeXFromY |
|
|
231
|
+
|
|
232
|
+
## References
|
|
233
|
+
|
|
234
|
+
- [Model patterns](references/models.md)
|
|
235
|
+
- [Command patterns](references/commands.md)
|
|
236
|
+
- [Testing patterns](references/testing.md)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "packages/erp-kit/src/modules/*/command/*.ts"
|
|
4
|
+
- "!packages/erp-kit/src/modules/*/command/*.test.ts"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Command Implementation
|
|
8
|
+
|
|
9
|
+
## defineCommand Pattern
|
|
10
|
+
|
|
11
|
+
Commands that don't need custom fields use `defineCommand` directly:
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
export const myCommand = defineCommand(permissions.myCommand, async (db: DB, input: Input) => { ... });
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Factory Function Pattern (custom fields)
|
|
18
|
+
|
|
19
|
+
Commands that insert into a table with user-extensible fields use a `makeCreateX<CF>()` factory:
|
|
20
|
+
|
|
21
|
+
- Export only `makeCreateX` — no default instance
|
|
22
|
+
- Generic `CF extends Record<string, unknown>` for custom fields
|
|
23
|
+
- Input type: `CreateXInput & CF`
|
|
24
|
+
- Destructure known fields, rest-spread custom fields into `.values()` before known fields
|
|
25
|
+
- Cast custom fields: `...(customFields as Record<string, unknown>)`
|
|
26
|
+
- `module.ts` wires with `makeCreateX<FieldsToInsertable<F>>()`
|
|
27
|
+
|
|
28
|
+
## Implementation Considerations
|
|
29
|
+
|
|
30
|
+
- **Validation**: Check referenced entities exist before operating
|
|
31
|
+
- **Idempotency**: For assign/revoke, return existing instead of throwing
|
|
32
|
+
- **Return format**: Wrap in object `{ entity }` not just `entity`
|
|
33
|
+
|
|
34
|
+
## Conventions
|
|
35
|
+
|
|
36
|
+
- Input types: exported interfaces (`export interface MyFunctionInput`)
|
|
37
|
+
- Use `.executeTakeFirst()` for single results
|
|
38
|
+
- Include JSDoc: `/** Function: name \n Description */`
|
|
39
|
+
|
|
40
|
+
## State Transitions
|
|
41
|
+
|
|
42
|
+
For commands that transition between statuses, accept `from?: string[]` with a default:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
from?: string[]; // Default: ["ACTIVE"]
|
|
46
|
+
|
|
47
|
+
const validFromStatuses = input.from ?? ["ACTIVE"];
|
|
48
|
+
if (!validFromStatuses.includes(user.status)) {
|
|
49
|
+
throw new InvalidStatusTransitionError(user.status, targetStatus);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- Default `from` contains the base valid source status
|
|
54
|
+
- Parent modules can override to allow transitions from additional statuses
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Database Models
|
|
2
|
+
|
|
3
|
+
## Factory Function Pattern
|
|
4
|
+
|
|
5
|
+
Each model is a `createXType<const F>(params)` factory:
|
|
6
|
+
|
|
7
|
+
- Params interface generic: `F extends Record<string, TailorAnyDBField>`
|
|
8
|
+
- `fields?: F` — optional custom fields from parent modules
|
|
9
|
+
- Spread as `...(params.fields ?? {}) as F` to preserve type information
|
|
10
|
+
- Include `...db.fields.timestamps()`
|
|
11
|
+
- Use `.description()` for field docs
|
|
12
|
+
- Apply permissions at model level
|
|
13
|
+
- Export a default instance: `export const x = createXType({})`
|
|
14
|
+
|
|
15
|
+
## Stateful Model Enums
|
|
16
|
+
|
|
17
|
+
Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// Good: extension only
|
|
21
|
+
const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
|
|
22
|
+
const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
|
|
23
|
+
|
|
24
|
+
// Bad: allows replacement
|
|
25
|
+
const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Name parameter `additionalX` to signal extension-only
|
|
29
|
+
- Parent modules handle their additional status transitions
|
|
@@ -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
|