@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,95 @@
1
+ ---
2
+ name: app-compose-2-requirements-breakdown
3
+ description: Create Tier 3 documentation (stories, screens) by breaking down business flows. Use after completing Tier 1-2 documentation with app-compose-1-requirement-analysis.
4
+ ---
5
+
6
+ # Requirements Breakdown Workflow
7
+
8
+ Break down Tier 2 business flows into Tier 3 documentation: User Stories and Screens.
9
+
10
+ ## Prerequisites
11
+
12
+ Tier 1-2 documentation must exist:
13
+
14
+ - `README.md` (requirements)
15
+ - `docs/actors/*.md` (actor definitions)
16
+ - `docs/business-flow/*/README.md` (business workflows)
17
+
18
+ ## Workflow Phases
19
+
20
+ ```
21
+ ANALYZE → BREAKDOWN → CREATE → VALIDATE
22
+ ```
23
+
24
+ ### Phase 1: Analyze
25
+
26
+ Review existing Tier 2 documentation:
27
+
28
+ 1. **Read** all business flow files in `docs/business-flow/`
29
+ 2. **Identify** flow steps that represent user actions
30
+ 3. **Map** each step to the responsible actor
31
+ 4. **Note** data inputs/outputs for each step
32
+
33
+ ### Phase 2: Breakdown
34
+
35
+ For each business flow, decompose into stories and screens:
36
+
37
+ | Flow Element | Maps To |
38
+ | ---------------- | ----------- |
39
+ | User action step | Story |
40
+ | UI requirement | Screen |
41
+ | Actor in flow | Story actor |
42
+
43
+ ### Phase 3: Create
44
+
45
+ Generate documentation using `erp-kit` CLI:
46
+
47
+ ```bash
48
+ # Tier 3: Stories
49
+ erp-kit scaffold --app-root examples story <app> <flow>/<actor>--<story>
50
+
51
+ # Tier 3: Screens
52
+ erp-kit scaffold --app-root examples screen <app> <screen-name>
53
+ ```
54
+
55
+ **Naming conventions:**
56
+
57
+ - Story filename: `<actor>--<story-name>.md` (double-dash separator)
58
+ - Story heading: Title Case of story name (after `--`)
59
+ - Screen filename: kebab-case, noun-focused (e.g., `supplier-list.md`)
60
+
61
+ **After creating stories**, update `## Stories` section in business flow README:
62
+
63
+ ```markdown
64
+ - [Story Title](./story/<actor>--<story-name>.md)
65
+ ```
66
+
67
+ ### Phase 4: Validate
68
+
69
+ ```bash
70
+ pnpm run app:doc:check
71
+ ```
72
+
73
+ ## Schema Reference
74
+
75
+ | Schema | Tier | Output Path |
76
+ | ------------ | ---- | ---------------------------------------------------- |
77
+ | `story.yml` | 3 | `docs/business-flow/<flow>/story/<actor>--<name>.md` |
78
+ | `screen.yml` | 3 | `docs/screen/<name>.md` |
79
+
80
+ ## Tips
81
+
82
+ - One business flow typically produces 3-8 stories
83
+ - Stories should be completable in a single user session
84
+ - Screens can be shared across multiple stories
85
+
86
+ ## Next Step
87
+
88
+ After completing Tier 3, use `/app-compose-3-doc-review` to validate documentation parity.
89
+
90
+ ## References
91
+
92
+ - [Application structure](references/structure.md)
93
+ - [ListView screen](references/screen-listview.md)
94
+ - [Form screen](references/screen-form.md)
95
+ - [DetailView screen](references/screen-detailview.md)
@@ -0,0 +1,106 @@
1
+ # DetailView Screen Implementation
2
+
3
+ Implementation pattern for screens with `Screen Type: DetailView`.
4
+ Assumes `page.md` and `component.md` rules.
5
+
6
+ ## File Structure
7
+
8
+ ```
9
+ {screen-path}/[id]/
10
+ ├── components/
11
+ │ ├── {screen-name}-detail.tsx # Main content (left column)
12
+ │ └── {screen-name}-actions.tsx # Action sidebar (right column)
13
+ ├── edit/
14
+ │ ├── components/
15
+ │ │ └── edit-{screen-name}-form.tsx
16
+ │ └── page.tsx
17
+ └── page.tsx
18
+ ```
19
+
20
+ ## Layout
21
+
22
+ - Two-column layout: main content on the left, actions on the right.
23
+
24
+ ```tsx
25
+ const ResourcePage = () => {
26
+ const { id } = useParams();
27
+ const [{ data, error, fetching }, reexecuteQuery] = useQuery({
28
+ query: ResourceQuery,
29
+ variables: { id: id! },
30
+ });
31
+
32
+ if (fetching) return <Loading />;
33
+ if (error || !data?.resource) return <ErrorFallback ... />;
34
+
35
+ return (
36
+ <Layout columns={2} title="Resource Detail">
37
+ <Layout.Column>
38
+ <ResourceDetail resource={data.resource} />
39
+ </Layout.Column>
40
+ <Layout.Column>
41
+ <ResourceActions resource={data.resource} />
42
+ </Layout.Column>
43
+ </Layout>
44
+ );
45
+ };
46
+ ```
47
+
48
+ ## Left Column: Detail Component
49
+
50
+ Stack `DescriptionCard` and related tables vertically with `space-y-6`.
51
+
52
+ - `DescriptionCard` (`@tailor-platform/app-shell`): renders key-value fields declaratively.
53
+ - Complex content (tables, timelines): wrap in `<div className="rounded-lg border bg-card p-6">`.
54
+
55
+ ### DescriptionCard
56
+
57
+ ```tsx
58
+ <DescriptionCard
59
+ data={resource}
60
+ title="Overview"
61
+ columns={3}
62
+ fields={[
63
+ { key: "name", label: "Name", meta: { copyable: true } },
64
+ {
65
+ key: "status",
66
+ label: "Status",
67
+ type: "badge",
68
+ meta: { badgeVariantMap: { ACTIVE: "success", PENDING: "warning" } },
69
+ },
70
+ { type: "divider" },
71
+ {
72
+ key: "createdAt",
73
+ label: "Created At",
74
+ type: "date",
75
+ meta: { dateFormat: "medium" },
76
+ },
77
+ ]}
78
+ />
79
+ ```
80
+
81
+ Field types: `"text"` (default), `"badge"`, `"money"`, `"date"`, `"link"`, `"address"`, `"reference"`, `"divider"`
82
+
83
+ ## Right Column: Actions Component
84
+
85
+ Wrap in a `Card` component. Use `Button variant="ghost"` for each action item.
86
+
87
+ ```tsx
88
+ <Card>
89
+ <CardHeader>
90
+ <CardTitle>Actions</CardTitle>
91
+ </CardHeader>
92
+ <CardContent className="space-y-2">
93
+ <Button variant="ghost" className="w-full justify-start gap-2" asChild>
94
+ <Link to="edit">✎ Edit</Link>
95
+ </Button>
96
+ <Button variant="ghost" className="w-full justify-start gap-2" onClick={handler}>
97
+ ✓ Approve
98
+ </Button>
99
+ </CardContent>
100
+ </Card>
101
+ ```
102
+
103
+ - Navigation: `<Button variant="ghost" asChild><Link to="...">`
104
+ - Mutation: `<Button variant="ghost" onClick={handler}>` with custom resolvers (see `backend/resolvers.md`)
105
+ - Conditional: show/hide based on status
106
+ - Multiple cards: stack with `<div className="space-y-6">`
@@ -0,0 +1,139 @@
1
+ # Form Screen Implementation
2
+
3
+ Implementation pattern for screens with `Screen Type: Form`.
4
+ Assumes `page.md` and `component.md` rules.
5
+
6
+ ## File Structure
7
+
8
+ ```
9
+ {screen-path}/
10
+ ├── components/
11
+ │ └── {screen-name}-form.tsx # Form component with validation
12
+ └── page.tsx
13
+ ```
14
+
15
+ ## Page Component (page.tsx)
16
+
17
+ Form pages delegate mutation logic to the form component.
18
+
19
+ ```tsx
20
+ const ScreenNamePage = () => (
21
+ <Layout columns={1} title="Screen Title">
22
+ <Layout.Column>
23
+ <ScreenNameForm />
24
+ </Layout.Column>
25
+ </Layout>
26
+ );
27
+ ```
28
+
29
+ For edit forms that need existing data, co-locate data fetching in the page component:
30
+
31
+ ```tsx
32
+ const EditPage = () => {
33
+ const { id } = useParams();
34
+ const [{ data, error, fetching }] = useQuery({
35
+ query: ResourceQuery,
36
+ variables: { id: id! },
37
+ });
38
+
39
+ if (fetching) return <Loading />;
40
+ if (error || !data?.resource) return <ErrorFallback ... />;
41
+
42
+ return (
43
+ <Layout columns={1} title="Edit Resource">
44
+ <Layout.Column>
45
+ <EditResourceForm resource={data.resource} />
46
+ </Layout.Column>
47
+ </Layout>
48
+ );
49
+ };
50
+ ```
51
+
52
+ ## Form Component (components/{screen-name}-form.tsx)
53
+
54
+ ### Technology Stack
55
+
56
+ - `react-hook-form` — form state management
57
+ - `zod` + `@hookform/resolvers/zod` — validation
58
+ - `useMutation` (urql) — GraphQL mutation
59
+ - `useNavigate` (@tailor-platform/app-shell) — post-submit navigation
60
+
61
+ ### Pattern
62
+
63
+ ```tsx
64
+ const formSchema = z.object({
65
+ title: z.string().min(1, "Title is required"),
66
+ description: z.string().optional(),
67
+ });
68
+
69
+ type FormValues = z.infer<typeof formSchema>;
70
+
71
+ export const ScreenNameForm = () => {
72
+ const navigate = useNavigate();
73
+ const [, createResource] = useMutation(CreateMutation);
74
+
75
+ const form = useForm<FormValues>({
76
+ resolver: zodResolver(formSchema),
77
+ defaultValues: { title: "", description: "" },
78
+ });
79
+
80
+ const onSubmit = (values: FormValues) => {
81
+ void createResource({ input: values }).then((result) => {
82
+ if (!result.error) {
83
+ void navigate("..");
84
+ }
85
+ });
86
+ };
87
+
88
+ return (
89
+ <Form {...form}>
90
+ <form onSubmit={(e) => void form.handleSubmit(onSubmit)(e)} className="max-w-md space-y-4">
91
+ <FormField
92
+ control={form.control}
93
+ name="title"
94
+ render={({ field }) => (
95
+ <FormItem>
96
+ <FormLabel>Title</FormLabel>
97
+ <FormControl>
98
+ <Input placeholder="Enter title" {...field} />
99
+ </FormControl>
100
+ <FormMessage />
101
+ </FormItem>
102
+ )}
103
+ />
104
+ <div className="flex gap-2">
105
+ <Button type="submit">Create</Button>
106
+ <Button type="button" variant="outline" onClick={() => void navigate("..")}>
107
+ Cancel
108
+ </Button>
109
+ </div>
110
+ </form>
111
+ </Form>
112
+ );
113
+ };
114
+ ```
115
+
116
+ ## Field Type Mapping
117
+
118
+ | Field Type | Component | Zod Schema |
119
+ | ---------- | ------------------------------ | ------------------------------- |
120
+ | Text | `<Input />` | `z.string()` |
121
+ | Textarea | `<textarea className="..." />` | `z.string()` |
122
+ | Dropdown | `<Select />` | `z.string()` or `z.enum([...])` |
123
+ | Date | `<Input type="date" />` | `z.string()` (ISO format) |
124
+ | Number | `<Input type="number" />` | `z.coerce.number()` |
125
+ | Email | `<Input type="email" />` | `z.string().email()` |
126
+ | Checkbox | `<Checkbox />` | `z.boolean()` |
127
+ | Radio | `<RadioGroup />` | `z.enum([...])` |
128
+
129
+ ## Validation Mapping
130
+
131
+ - **Required: Yes** → `.min(1, "Field is required")` (string) / `.positive()` (number)
132
+ - **Required: No** → `.optional()`
133
+
134
+ ## Key Points
135
+
136
+ - Set `defaultValues` for all fields (empty string, false, etc.)
137
+ - Navigate to `".."` after successful mutation
138
+ - Cancel button must use `type="button"` to prevent form submit
139
+ - For edit forms, accept fragment data as props and pre-fill `defaultValues`
@@ -0,0 +1,153 @@
1
+ # ListView Screen Implementation
2
+
3
+ Implementation pattern for screens with `Screen Type: ListView`.
4
+ Assumes `page.md` and `component.md` rules.
5
+
6
+ ## File Structure
7
+
8
+ ```
9
+ {screen-path}/
10
+ ├── components/
11
+ │ └── {screen-name}-table.tsx # Table component with fragments
12
+ └── page.tsx
13
+ ```
14
+
15
+ ## Page Component (page.tsx)
16
+
17
+ Data fetching and `Layout` must be co-located in the same page component.
18
+ Do NOT split into an inner Content component — `Layout` requires `Layout.Column` as direct children.
19
+
20
+ ```tsx
21
+ const ResourcesQuery = graphql(
22
+ `
23
+ query Resources {
24
+ resources {
25
+ ...ResourceTable
26
+ }
27
+ }
28
+ `,
29
+ [ResourceTableFragment],
30
+ );
31
+
32
+ const ResourcesPage = () => {
33
+ const [{ data, error, fetching }, reexecuteQuery] = useQuery({
34
+ query: ResourcesQuery,
35
+ });
36
+
37
+ if (fetching) return <Loading />;
38
+
39
+ if (error || !data) {
40
+ return (
41
+ <ErrorFallback
42
+ title="Failed to load resources"
43
+ message="An error occurred while fetching the list."
44
+ onReset={() => reexecuteQuery({ requestPolicy: "network-only" })}
45
+ />
46
+ );
47
+ }
48
+
49
+ return (
50
+ <Layout
51
+ columns={1}
52
+ title="Resources"
53
+ actions={[
54
+ <Button key="create" asChild>
55
+ <Link to="create">Create</Link>
56
+ </Button>,
57
+ ]}
58
+ >
59
+ <Layout.Column>
60
+ <ResourceTable data={data.resources} />
61
+ </Layout.Column>
62
+ </Layout>
63
+ );
64
+ };
65
+ ```
66
+
67
+ ## Table Component (components/{screen-name}-table.tsx)
68
+
69
+ ### Fragment Collocation
70
+
71
+ Define a row fragment and a table fragment wrapping the Connection type.
72
+
73
+ ```tsx
74
+ const ResourceRowFragment = graphql(`
75
+ fragment ResourceRow on Resource {
76
+ id
77
+ title
78
+ status
79
+ createdAt
80
+ }
81
+ `);
82
+
83
+ export const ResourceTableFragment = graphql(
84
+ `
85
+ fragment ResourceTable on ResourceConnection {
86
+ edges {
87
+ node {
88
+ ...ResourceRow
89
+ }
90
+ }
91
+ }
92
+ `,
93
+ [ResourceRowFragment],
94
+ );
95
+ ```
96
+
97
+ ### Row Component
98
+
99
+ ```tsx
100
+ const ResourceRow = ({ resource: resourceFragment }: ResourceRowProps) => {
101
+ const resource = readFragment(ResourceRowFragment, resourceFragment);
102
+ return (
103
+ <TableRow>
104
+ <TableCell>{resource.title}</TableCell>
105
+ <TableCell>
106
+ <Badge variant={resource.status === "ACTIVE" ? "default" : "secondary"}>
107
+ {resource.status}
108
+ </Badge>
109
+ </TableCell>
110
+ <TableCell>
111
+ <Button variant="ghost" size="sm" asChild>
112
+ <Link to={resource.id}>View</Link>
113
+ </Button>
114
+ </TableCell>
115
+ </TableRow>
116
+ );
117
+ };
118
+ ```
119
+
120
+ ### Empty State
121
+
122
+ ```tsx
123
+ if (connection.edges.length === 0) {
124
+ return (
125
+ <EmptyState
126
+ title="No resources"
127
+ message="Get started by creating a new resource."
128
+ action={
129
+ <Button asChild>
130
+ <Link to="create">Create</Link>
131
+ </Button>
132
+ }
133
+ />
134
+ );
135
+ }
136
+ ```
137
+
138
+ ## Column Property Mapping
139
+
140
+ | Property | Implementation |
141
+ | --------------- | ----------------------------------------------------------- |
142
+ | Hideable: Yes | Column visibility state to toggle show/hide |
143
+ | Sortable: Yes | Sort icon on `<TableHead>` + onClick to toggle query vars |
144
+ | Filterable: Yes | Filter UI above table (`<Select />`) |
145
+ | Searchable: Yes | Search input above table (`<Input placeholder="Search" />`) |
146
+
147
+ ## Key Points
148
+
149
+ - Use `<Badge />` for status columns
150
+ - Format dates with `toLocaleDateString()`
151
+ - Use `<EmptyState />` with Create action for empty lists
152
+ - Add a View button per row to navigate to the detail page
153
+ - Iterate data using Connection type `edges.node` pattern
@@ -0,0 +1,27 @@
1
+ # Application Directory Structure
2
+
3
+ ```
4
+ {app_name}/
5
+ ├── backend/
6
+ │ ├── src/
7
+ │ │ ├── modules.ts # Declaring module usage
8
+ │ │ ├── modules/
9
+ │ │ │ └── {module-name}/ # Module-specific directory
10
+ │ │ │ ├── resolvers/ # API Definition to expose graphql apis
11
+ │ │ │ └── executors/ # PubSub Automation (one file per declaration)
12
+ │ │ └── generated/ # Auto-generated code (do not edit)
13
+ │ └── tailor.config.ts # tailor application config
14
+
15
+ └── frontend/
16
+ └── src/
17
+ ├── pages/ # File-based routing (auto-discovered by Vite plugin)
18
+ │ └── {page-path}/
19
+ │ ├── page.tsx
20
+ │ └── {page-path}/
21
+ │ ├── components/
22
+ │ └── page.tsx
23
+ ├── components/
24
+ │ └── ui/ # Generic UI components
25
+ ├── graphql/ # gql.tada settings
26
+ └── providers/ # react providers
27
+ ```
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: app-compose-3-doc-review
3
+ description: Review documentation parity between Tier 2 (business flows, actors) and Tier 3 (stories, screens). Use when validating that all business flow steps have corresponding stories, and that screens are properly linked.
4
+ ---
5
+
6
+ # Documentation Parity Review Workflow
7
+
8
+ Review **documentation consistency** between Tier 2 and Tier 3 documentation.
9
+
10
+ ## Purpose
11
+
12
+ ```
13
+ Business Flow (Tier 2) → Stories (Tier 3) → Screens (Tier 3)
14
+ ↓ ↓ ↓
15
+ Flow Steps User Actions UI Components
16
+ Actors Involved Scenario Patterns Screen Types
17
+ ```
18
+
19
+ ## When to Use
20
+
21
+ - After writing Tier 3 documentation, check for gaps
22
+ - Before proceeding to Tier 4 (implementation spec)
23
+ - Quality check during documentation review
24
+
25
+ ## Workflow
26
+
27
+ ```
28
+ READ DOCS → PARITY CHECKS → REPORT
29
+ ```
30
+
31
+ ### Step 1: Read All Documentation
32
+
33
+ ```
34
+ examples/<app-name>/docs/business-flow/*/README.md # Flows
35
+ examples/<app-name>/docs/business-flow/*/story/*.md # Stories
36
+ examples/<app-name>/docs/screen/*.md # Screens
37
+ examples/<app-name>/docs/actors/*.md # Actors
38
+ ```
39
+
40
+ ### Step 2: Parity Checks
41
+
42
+ #### Business Flow → Story
43
+
44
+ | Check | Question |
45
+ | --------------- | ----------------------------------------------- |
46
+ | Story existence | Does each flow step have a corresponding story? |
47
+ | Actor coverage | Are all actors in flow represented in stories? |
48
+ | Link validity | Do story links in flow README resolve? |
49
+
50
+ #### Actor → Business Flow
51
+
52
+ | Check | Question |
53
+ | -------------- | ----------------------------------------- |
54
+ | Flow existence | Do all flows in "Authorized Flows" exist? |
55
+ | Link validity | Do flow links resolve correctly? |
56
+
57
+ #### Story → Screen
58
+
59
+ | Check | Question |
60
+ | ---------------- | ---------------------------------- |
61
+ | Screen existence | Do all screens in story exist? |
62
+ | Link validity | Do screen links resolve correctly? |
63
+
64
+ #### Orphan Detection
65
+
66
+ | Check | Question |
67
+ | -------------- | ------------------------------------------ |
68
+ | Orphan stories | Stories not linked from any business flow? |
69
+ | Orphan screens | Screens not referenced by any story? |
70
+ | Orphan actors | Actors not participating in any flow? |
71
+
72
+ ### Step 3: Report
73
+
74
+ ```markdown
75
+ ## Documentation Parity Review Report
76
+
77
+ **Application:** <app-name>
78
+
79
+ ### Summary
80
+
81
+ | Aspect | Status | Details |
82
+ | --------------------- | -------- | ----------------- |
83
+ | Business Flow → Story | ✅/⚠️/❌ | X/Y flows covered |
84
+ | Actor → Flow | ✅/⚠️/❌ | All links valid |
85
+ | Story → Screen | ✅/⚠️/❌ | X missing screens |
86
+ | Orphan Detection | ✅/⚠️/❌ | N orphans found |
87
+
88
+ ### Gaps Found
89
+
90
+ - [ ] Missing: <item>
91
+ - [ ] Broken link: <source> → <target>
92
+ - [ ] Orphan: <file>
93
+
94
+ ### Recommendations
95
+
96
+ 1. Create missing: ...
97
+ 2. Fix broken links: ...
98
+ 3. Remove or link orphans: ...
99
+ ```
100
+
101
+ ## Link Format Reference
102
+
103
+ | From | To | Format |
104
+ | ------------- | ------------- | ----------------------------------- |
105
+ | Business Flow | Story | `./story/<actor>--<name>.md` |
106
+ | Business Flow | Actor | `../../actors/<actor>.md` |
107
+ | Actor | Business Flow | `../business-flow/<flow>/README.md` |
108
+ | Story | Screen | `../../../screen/<screen>.md` |
109
+
110
+ ## Next Step
111
+
112
+ After fixing all issues, use `/app-compose-4-design-mock` to create visual UI mockups from screen specifications.
113
+
114
+ ## References
115
+
116
+ - [Application structure](references/structure.md)
@@ -0,0 +1,27 @@
1
+ # Application Directory Structure
2
+
3
+ ```
4
+ {app_name}/
5
+ ├── backend/
6
+ │ ├── src/
7
+ │ │ ├── modules.ts # Declaring module usage
8
+ │ │ ├── modules/
9
+ │ │ │ └── {module-name}/ # Module-specific directory
10
+ │ │ │ ├── resolvers/ # API Definition to expose graphql apis
11
+ │ │ │ └── executors/ # PubSub Automation (one file per declaration)
12
+ │ │ └── generated/ # Auto-generated code (do not edit)
13
+ │ └── tailor.config.ts # tailor application config
14
+
15
+ └── frontend/
16
+ └── src/
17
+ ├── pages/ # File-based routing (auto-discovered by Vite plugin)
18
+ │ └── {page-path}/
19
+ │ ├── page.tsx
20
+ │ └── {page-path}/
21
+ │ ├── components/
22
+ │ └── page.tsx
23
+ ├── components/
24
+ │ └── ui/ # Generic UI components
25
+ ├── graphql/ # gql.tada settings
26
+ └── providers/ # react providers
27
+ ```