@tailor-platform/erp-kit 0.1.2 → 0.2.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 +12 -0
- package/README.md +80 -12
- package/dist/cli.js +1070 -450
- package/package.json +11 -8
- package/schemas/app-compose/business-flow.yml +3 -0
- package/schemas/app-compose/story.yml +1 -1
- package/schemas/module/model.yml +5 -0
- package/skills/{app-compose-1-requirement-analysis → erp-kit-app-1-requirements}/SKILL.md +8 -14
- package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/SKILL.md +6 -13
- package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/SKILL.md +2 -6
- package/skills/{app-compose-6-implementation-spec → erp-kit-app-4-impl-spec}/SKILL.md +11 -22
- package/skills/erp-kit-app-5-implementation/SKILL.md +149 -0
- package/skills/erp-kit-app-5-implementation/references/backend.md +232 -0
- package/skills/erp-kit-app-5-implementation/references/frontend.md +242 -0
- package/skills/{mock-scenario → erp-kit-mock-scenario}/SKILL.md +1 -1
- package/skills/{1-module-docs → erp-kit-module-1-docs}/SKILL.md +2 -2
- package/skills/{2-module-feature-breakdown → erp-kit-module-2-feature-breakdown}/SKILL.md +13 -9
- package/skills/erp-kit-module-2-feature-breakdown/references/naming.md +59 -0
- package/skills/{3-module-doc-review → erp-kit-module-3-doc-review}/SKILL.md +83 -25
- package/skills/erp-kit-module-4-tdd/SKILL.md +94 -0
- package/skills/erp-kit-module-4-tdd/references/cross-module-dependency.md +133 -0
- package/skills/{4-module-tdd-implementation → erp-kit-module-4-tdd}/references/db-relations.md +5 -1
- package/skills/{4-module-tdd-implementation → erp-kit-module-4-tdd}/references/exports.md +1 -1
- package/skills/erp-kit-module-4-tdd/references/generated-code.md +32 -0
- package/skills/{5-module-implementation-review → erp-kit-module-5-impl-review}/SKILL.md +46 -44
- package/skills/erp-kit-module-5-impl-review/references/commands.md +62 -0
- package/skills/erp-kit-module-5-impl-review/references/errors.md +10 -0
- package/skills/{5-module-implementation-review → erp-kit-module-5-impl-review}/references/testing.md +1 -1
- package/skills/erp-kit-module-shared/SKILL.md +16 -0
- package/skills/erp-kit-module-shared/references/commands.md +203 -0
- package/skills/erp-kit-module-shared/references/errors.md +35 -0
- package/skills/erp-kit-module-shared/references/queries.md +168 -0
- package/skills/erp-kit-module-shared/references/structure.md +36 -0
- package/skills/{3-module-doc-review → erp-kit-module-shared}/references/testing.md +4 -3
- package/skills/erp-kit-update/SKILL.md +64 -0
- package/src/cli.doc.test.ts +65 -0
- package/src/cli.ts +3 -35
- package/src/commands/app/index.ts +3 -3
- package/src/commands/check.test.ts +1 -1
- package/src/commands/check.ts +2 -2
- package/src/commands/index.ts +73 -0
- package/src/commands/init.test.ts +22 -5
- package/src/commands/init.ts +25 -16
- package/src/commands/license.ts +193 -0
- package/src/commands/mock/index.ts +2 -2
- package/src/commands/mock/start.ts +1 -1
- package/src/commands/mock/validate.test.ts +1 -1
- package/src/commands/module/generate.ts +35 -0
- package/src/commands/module/index.ts +6 -4
- package/src/commands/module/list.test.ts +7 -12
- package/src/commands/module/list.ts +1 -1
- package/src/commands/scaffold-templates.ts +65 -0
- package/src/commands/scaffold.test.ts +92 -2
- package/src/commands/scaffold.ts +22 -2
- package/src/commands/sync-check.test.ts +60 -1
- package/src/commands/sync-check.ts +35 -2
- package/src/generator/generate-code.test.ts +200 -0
- package/src/generator/generate-code.ts +260 -0
- package/src/generator/parse-command-doc.test.ts +159 -0
- package/src/generator/parse-command-doc.ts +116 -0
- package/src/integration.test.ts +2 -2
- package/src/module.ts +44 -6
- package/src/modules/item-management/README.md +38 -0
- package/src/modules/item-management/command/activateItem.generated.ts +6 -0
- package/src/modules/item-management/command/activateItem.test.ts +76 -0
- package/src/modules/item-management/command/activateItem.ts +42 -0
- package/src/modules/item-management/command/assignItemToTaxonomy.generated.ts +6 -0
- package/src/modules/item-management/command/assignItemToTaxonomy.test.ts +88 -0
- package/src/modules/item-management/command/assignItemToTaxonomy.ts +63 -0
- package/src/modules/item-management/command/createItem.generated.ts +6 -0
- package/src/modules/item-management/command/createItem.test.ts +152 -0
- package/src/modules/item-management/command/createItem.ts +72 -0
- package/src/modules/item-management/command/createTaxonomyNode.generated.ts +6 -0
- package/src/modules/item-management/command/createTaxonomyNode.test.ts +126 -0
- package/src/modules/item-management/command/createTaxonomyNode.ts +70 -0
- package/src/modules/item-management/command/deactivateItem.generated.ts +6 -0
- package/src/modules/item-management/command/deactivateItem.test.ts +76 -0
- package/src/modules/item-management/command/deactivateItem.ts +42 -0
- package/src/modules/item-management/command/deleteItem.generated.ts +6 -0
- package/src/modules/item-management/command/deleteItem.test.ts +61 -0
- package/src/modules/item-management/command/deleteItem.ts +38 -0
- package/src/modules/item-management/command/deleteTaxonomyNode.generated.ts +6 -0
- package/src/modules/item-management/command/deleteTaxonomyNode.test.ts +73 -0
- package/src/modules/item-management/command/deleteTaxonomyNode.ts +50 -0
- package/src/modules/item-management/command/moveTaxonomyNode.generated.ts +6 -0
- package/src/modules/item-management/command/moveTaxonomyNode.test.ts +136 -0
- package/src/modules/item-management/command/moveTaxonomyNode.ts +85 -0
- package/src/modules/item-management/command/reactivateItem.generated.ts +6 -0
- package/src/modules/item-management/command/reactivateItem.test.ts +76 -0
- package/src/modules/item-management/command/reactivateItem.ts +42 -0
- package/src/modules/item-management/command/removeItemFromTaxonomy.generated.ts +6 -0
- package/src/modules/item-management/command/removeItemFromTaxonomy.test.ts +43 -0
- package/src/modules/item-management/command/removeItemFromTaxonomy.ts +30 -0
- package/src/modules/item-management/command/updateItem.generated.ts +6 -0
- package/src/modules/item-management/command/updateItem.test.ts +178 -0
- package/src/modules/item-management/command/updateItem.ts +103 -0
- package/src/modules/item-management/command/updateTaxonomyNode.generated.ts +6 -0
- package/src/modules/item-management/command/updateTaxonomyNode.test.ts +88 -0
- package/src/modules/item-management/command/updateTaxonomyNode.ts +62 -0
- package/src/modules/item-management/db/item.ts +47 -0
- package/src/modules/item-management/db/itemTaxonomyAssignment.ts +49 -0
- package/src/modules/item-management/db/taxonomyNode.ts +34 -0
- package/src/modules/item-management/docs/commands/ActivateItem.md +32 -0
- package/src/modules/item-management/docs/commands/AssignItemToTaxonomy.md +38 -0
- package/src/modules/item-management/docs/commands/CreateItem.md +44 -0
- package/src/modules/item-management/docs/commands/CreateTaxonomyNode.md +44 -0
- package/src/modules/item-management/docs/commands/DeactivateItem.md +34 -0
- package/src/modules/item-management/docs/commands/DeleteItem.md +35 -0
- package/src/modules/item-management/docs/commands/DeleteTaxonomyNode.md +39 -0
- package/src/modules/item-management/docs/commands/MoveTaxonomyNode.md +45 -0
- package/src/modules/item-management/docs/commands/ReactivateItem.md +34 -0
- package/src/modules/item-management/docs/commands/RemoveItemFromTaxonomy.md +30 -0
- package/src/modules/item-management/docs/commands/UpdateItem.md +55 -0
- package/src/modules/item-management/docs/commands/UpdateTaxonomyNode.md +36 -0
- package/src/modules/item-management/docs/features/item-lifecycle.md +60 -0
- package/src/modules/item-management/docs/features/item-taxonomy.md +65 -0
- package/src/modules/item-management/docs/models/ItemTaxonomyAssignment.md +36 -0
- package/src/modules/item-management/docs/models/TaxonomyNode.md +47 -0
- package/src/modules/item-management/docs/models/item.md +59 -0
- package/src/modules/item-management/docs/queries/CalculateNodeDepth.md +36 -0
- package/src/modules/item-management/docs/queries/CalculateSubtreeDepth.md +40 -0
- package/src/modules/item-management/docs/queries/DetectCircularReference.md +41 -0
- package/src/modules/item-management/docs/queries/GetItem.md +38 -0
- package/src/modules/item-management/docs/queries/GetItemTaxonomyAssignment.md +29 -0
- package/src/modules/item-management/docs/queries/GetTaxonomyNode.md +35 -0
- package/src/modules/item-management/docs/queries/GetTaxonomyNodeAssignments.md +29 -0
- package/src/modules/item-management/docs/queries/GetTaxonomyNodeChildren.md +29 -0
- package/src/modules/item-management/generated/enums.ts +9 -0
- package/src/modules/item-management/generated/kysely-tailordb.ts +62 -0
- package/src/modules/item-management/index.ts +53 -0
- package/src/modules/item-management/lib/_db_deps.ts +13 -0
- package/src/modules/item-management/lib/errors.generated.ts +117 -0
- package/src/modules/item-management/lib/permissions.generated.ts +17 -0
- package/src/modules/item-management/lib/types.ts +19 -0
- package/src/modules/item-management/module.ts +97 -0
- package/src/modules/item-management/query/calculateNodeDepth.generated.ts +5 -0
- package/src/modules/item-management/query/calculateNodeDepth.test.ts +56 -0
- package/src/modules/item-management/query/calculateNodeDepth.ts +28 -0
- package/src/modules/item-management/query/calculateSubtreeDepth.generated.ts +5 -0
- package/src/modules/item-management/query/calculateSubtreeDepth.test.ts +75 -0
- package/src/modules/item-management/query/calculateSubtreeDepth.ts +29 -0
- package/src/modules/item-management/query/detectCircularReference.generated.ts +5 -0
- package/src/modules/item-management/query/detectCircularReference.test.ts +61 -0
- package/src/modules/item-management/query/detectCircularReference.ts +32 -0
- package/src/modules/item-management/query/getItem.generated.ts +5 -0
- package/src/modules/item-management/query/getItem.test.ts +67 -0
- package/src/modules/item-management/query/getItem.ts +20 -0
- package/src/modules/item-management/query/getItemTaxonomyAssignment.generated.ts +5 -0
- package/src/modules/item-management/query/getItemTaxonomyAssignment.test.ts +25 -0
- package/src/modules/item-management/query/getItemTaxonomyAssignment.ts +18 -0
- package/src/modules/item-management/query/getTaxonomyNode.generated.ts +5 -0
- package/src/modules/item-management/query/getTaxonomyNode.test.ts +47 -0
- package/src/modules/item-management/query/getTaxonomyNode.ts +18 -0
- package/src/modules/item-management/query/getTaxonomyNodeAssignments.generated.ts +5 -0
- package/src/modules/item-management/query/getTaxonomyNodeAssignments.test.ts +25 -0
- package/src/modules/item-management/query/getTaxonomyNodeAssignments.ts +16 -0
- package/src/modules/item-management/query/getTaxonomyNodeChildren.generated.ts +5 -0
- package/src/modules/item-management/query/getTaxonomyNodeChildren.test.ts +34 -0
- package/src/modules/item-management/query/getTaxonomyNodeChildren.ts +16 -0
- package/src/modules/item-management/tailor.config.ts +11 -0
- package/src/modules/item-management/testing/fixtures.ts +81 -0
- package/src/modules/primitives/command/activateCategory.generated.ts +6 -0
- package/src/modules/primitives/command/activateCategory.test.ts +11 -29
- package/src/modules/primitives/command/activateCategory.ts +27 -34
- package/src/modules/primitives/command/activateCurrency.generated.ts +6 -0
- package/src/modules/primitives/command/activateCurrency.test.ts +11 -29
- package/src/modules/primitives/command/activateCurrency.ts +27 -34
- package/src/modules/primitives/command/activateUnit.generated.ts +6 -0
- package/src/modules/primitives/command/activateUnit.test.ts +11 -15
- package/src/modules/primitives/command/activateUnit.ts +27 -34
- package/src/modules/primitives/command/createCategory.generated.ts +6 -0
- package/src/modules/primitives/command/createCategory.test.ts +27 -39
- package/src/modules/primitives/command/createCategory.ts +53 -62
- package/src/modules/primitives/command/createCurrency.generated.ts +6 -0
- package/src/modules/primitives/command/createCurrency.test.ts +78 -71
- package/src/modules/primitives/command/createCurrency.ts +43 -48
- package/src/modules/primitives/command/createExchangeRate.generated.ts +6 -0
- package/src/modules/primitives/command/createExchangeRate.test.ts +101 -100
- package/src/modules/primitives/command/createExchangeRate.ts +50 -59
- package/src/modules/primitives/command/createUnit.generated.ts +6 -0
- package/src/modules/primitives/command/createUnit.test.ts +92 -95
- package/src/modules/primitives/command/createUnit.ts +54 -57
- package/src/modules/primitives/command/deactivateCategory.generated.ts +6 -0
- package/src/modules/primitives/command/deactivateCategory.test.ts +27 -28
- package/src/modules/primitives/command/deactivateCategory.ts +43 -50
- package/src/modules/primitives/command/deactivateCurrency.generated.ts +6 -0
- package/src/modules/primitives/command/deactivateCurrency.test.ts +23 -38
- package/src/modules/primitives/command/deactivateCurrency.ts +31 -38
- package/src/modules/primitives/command/deactivateUnit.generated.ts +6 -0
- package/src/modules/primitives/command/deactivateUnit.test.ts +27 -23
- package/src/modules/primitives/command/deactivateUnit.ts +39 -49
- package/src/modules/primitives/command/setBaseCurrency.generated.ts +6 -0
- package/src/modules/primitives/command/setBaseCurrency.test.ts +40 -33
- package/src/modules/primitives/command/setBaseCurrency.ts +43 -50
- package/src/modules/primitives/command/setReferenceUnit.generated.ts +6 -0
- package/src/modules/primitives/command/setReferenceUnit.test.ts +39 -35
- package/src/modules/primitives/command/setReferenceUnit.ts +46 -59
- package/src/modules/primitives/db/unit.ts +13 -3
- package/src/modules/primitives/docs/commands/ActivateCategory.md +1 -2
- package/src/modules/primitives/docs/commands/ActivateCurrency.md +1 -2
- package/src/modules/primitives/docs/commands/ActivateUnit.md +1 -2
- package/src/modules/primitives/docs/commands/CreateCategory.md +1 -4
- package/src/modules/primitives/docs/commands/CreateCurrency.md +3 -4
- package/src/modules/primitives/docs/commands/CreateExchangeRate.md +4 -5
- package/src/modules/primitives/docs/commands/CreateUnit.md +5 -5
- package/src/modules/primitives/docs/commands/DeactivateCategory.md +2 -3
- package/src/modules/primitives/docs/commands/DeactivateCurrency.md +2 -3
- package/src/modules/primitives/docs/commands/DeactivateUnit.md +2 -3
- package/src/modules/primitives/docs/commands/SetBaseCurrency.md +2 -3
- package/src/modules/primitives/docs/commands/SetReferenceUnit.md +2 -3
- package/src/modules/primitives/docs/queries/ConvertAmount.md +3 -5
- package/src/modules/primitives/docs/queries/ConvertQuantity.md +3 -5
- package/src/modules/primitives/docs/queries/GetBaseCurrency.md +32 -0
- package/src/modules/primitives/docs/queries/GetCurrency.md +36 -0
- package/src/modules/primitives/docs/queries/GetUnit.md +36 -0
- package/src/modules/primitives/docs/queries/GetUoMCategory.md +36 -0
- package/src/modules/primitives/docs/queries/ListUnitsByCategory.md +26 -0
- package/src/modules/primitives/generated/kysely-tailordb.ts +24 -45
- package/src/modules/primitives/index.ts +15 -4
- package/src/modules/primitives/lib/errors.generated.ts +112 -0
- package/src/modules/primitives/{permissions.ts → lib/permissions.generated.ts} +9 -8
- package/src/modules/primitives/module.ts +37 -27
- package/src/modules/primitives/query/convertAmount.generated.ts +5 -0
- package/src/modules/primitives/query/convertAmount.test.ts +2 -2
- package/src/modules/primitives/query/convertAmount.ts +27 -28
- package/src/modules/primitives/query/convertQuantity.generated.ts +5 -0
- package/src/modules/primitives/query/convertQuantity.test.ts +6 -2
- package/src/modules/primitives/query/convertQuantity.ts +49 -57
- package/src/modules/primitives/query/getBaseCurrency.generated.ts +5 -0
- package/src/modules/primitives/query/getBaseCurrency.test.ts +28 -0
- package/src/modules/primitives/query/getBaseCurrency.ts +16 -0
- package/src/modules/primitives/query/getCurrency.generated.ts +5 -0
- package/src/modules/primitives/query/getCurrency.test.ts +47 -0
- package/src/modules/primitives/query/getCurrency.ts +18 -0
- package/src/modules/primitives/query/getUnit.generated.ts +5 -0
- package/src/modules/primitives/query/getUnit.test.ts +47 -0
- package/src/modules/primitives/query/getUnit.ts +18 -0
- package/src/modules/primitives/query/getUoMCategory.generated.ts +5 -0
- package/src/modules/primitives/query/getUoMCategory.test.ts +47 -0
- package/src/modules/primitives/query/getUoMCategory.ts +18 -0
- package/src/modules/primitives/query/listUnitsByCategory.generated.ts +5 -0
- package/src/modules/primitives/query/listUnitsByCategory.ts +16 -0
- package/src/modules/primitives/tailor.config.ts +3 -3
- package/src/modules/shared/defineCommand.test.ts +23 -10
- package/src/modules/shared/defineCommand.ts +23 -10
- package/src/modules/shared/internal.ts +1 -0
- package/src/modules/shared/requirePermission.test.ts +22 -21
- package/src/modules/shared/requirePermission.ts +8 -2
- package/src/modules/shared/result.ts +12 -0
- package/src/modules/testing/index.ts +36 -11
- package/src/modules/user-management/command/activateUser.generated.ts +6 -0
- package/src/modules/user-management/command/activateUser.test.ts +27 -27
- package/src/modules/user-management/command/activateUser.ts +40 -48
- package/src/modules/user-management/command/assignPermissionToRole.generated.ts +6 -0
- package/src/modules/user-management/command/assignPermissionToRole.test.ts +42 -43
- package/src/modules/user-management/command/assignPermissionToRole.ts +59 -62
- package/src/modules/user-management/command/assignRoleToUser.generated.ts +6 -0
- package/src/modules/user-management/command/assignRoleToUser.test.ts +70 -63
- package/src/modules/user-management/command/assignRoleToUser.ts +63 -66
- package/src/modules/user-management/command/createPermission.generated.ts +6 -0
- package/src/modules/user-management/command/createPermission.test.ts +45 -38
- package/src/modules/user-management/command/createPermission.ts +42 -46
- package/src/modules/user-management/command/createRole.generated.ts +6 -0
- package/src/modules/user-management/command/createRole.test.ts +30 -29
- package/src/modules/user-management/command/createRole.ts +33 -33
- package/src/modules/user-management/command/createUser.generated.ts +6 -0
- package/src/modules/user-management/command/createUser.test.ts +64 -42
- package/src/modules/user-management/command/createUser.ts +54 -56
- package/src/modules/user-management/command/deactivateUser.generated.ts +6 -0
- package/src/modules/user-management/command/deactivateUser.test.ts +27 -27
- package/src/modules/user-management/command/deactivateUser.ts +40 -48
- package/src/modules/user-management/command/logAuditEvent.generated.ts +6 -0
- package/src/modules/user-management/command/logAuditEvent.test.ts +50 -42
- package/src/modules/user-management/command/logAuditEvent.ts +25 -28
- package/src/modules/user-management/command/reactivateUser.generated.ts +6 -0
- package/src/modules/user-management/command/reactivateUser.test.ts +31 -27
- package/src/modules/user-management/command/reactivateUser.ts +40 -48
- package/src/modules/user-management/command/revokePermissionFromRole.generated.ts +6 -0
- package/src/modules/user-management/command/revokePermissionFromRole.test.ts +52 -51
- package/src/modules/user-management/command/revokePermissionFromRole.ts +60 -57
- package/src/modules/user-management/command/revokeRoleFromUser.generated.ts +6 -0
- package/src/modules/user-management/command/revokeRoleFromUser.test.ts +53 -48
- package/src/modules/user-management/command/revokeRoleFromUser.ts +58 -57
- package/src/modules/user-management/docs/commands/CreatePermission.md +2 -2
- package/src/modules/user-management/docs/commands/CreateRole.md +1 -1
- package/src/modules/user-management/generated/enums.ts +11 -11
- package/src/modules/user-management/generated/kysely-tailordb.ts +27 -56
- package/src/modules/user-management/index.ts +2 -2
- package/src/modules/user-management/lib/errors.generated.ts +67 -0
- package/src/modules/user-management/{permissions.ts → lib/permissions.generated.ts} +8 -7
- package/src/modules/user-management/module.ts +22 -22
- package/src/modules/user-management/tailor.config.ts +3 -3
- package/src/schemas.ts +1 -1
- package/skills/1-module-docs/references/structure.md +0 -22
- package/skills/2-module-feature-breakdown/references/commands.md +0 -48
- package/skills/2-module-feature-breakdown/references/structure.md +0 -22
- package/skills/3-module-doc-review/references/commands.md +0 -54
- package/skills/3-module-doc-review/references/models.md +0 -29
- package/skills/4-module-tdd-implementation/SKILL.md +0 -74
- package/skills/4-module-tdd-implementation/references/commands.md +0 -45
- package/skills/4-module-tdd-implementation/references/errors.md +0 -7
- package/skills/4-module-tdd-implementation/references/models.md +0 -30
- package/skills/4-module-tdd-implementation/references/structure.md +0 -22
- package/skills/4-module-tdd-implementation/references/testing.md +0 -37
- package/skills/5-module-implementation-review/references/commands.md +0 -45
- package/skills/5-module-implementation-review/references/errors.md +0 -7
- package/skills/5-module-implementation-review/references/exports.md +0 -8
- package/skills/5-module-implementation-review/references/models.md +0 -30
- package/skills/app-compose-1-requirement-analysis/references/structure.md +0 -27
- package/skills/app-compose-2-requirements-breakdown/references/screen-detailview.md +0 -106
- package/skills/app-compose-2-requirements-breakdown/references/screen-form.md +0 -139
- package/skills/app-compose-2-requirements-breakdown/references/screen-listview.md +0 -153
- package/skills/app-compose-2-requirements-breakdown/references/structure.md +0 -27
- package/skills/app-compose-3-doc-review/references/structure.md +0 -27
- package/skills/app-compose-4-design-mock/SKILL.md +0 -256
- package/skills/app-compose-4-design-mock/references/component.md +0 -50
- package/skills/app-compose-4-design-mock/references/screen-detailview.md +0 -106
- package/skills/app-compose-4-design-mock/references/screen-form.md +0 -139
- package/skills/app-compose-4-design-mock/references/screen-listview.md +0 -153
- package/skills/app-compose-4-design-mock/references/structure.md +0 -27
- package/skills/app-compose-5-design-mock-review/SKILL.md +0 -290
- package/skills/app-compose-5-design-mock-review/references/component.md +0 -50
- package/skills/app-compose-5-design-mock-review/references/screen-detailview.md +0 -106
- package/skills/app-compose-5-design-mock-review/references/screen-form.md +0 -139
- package/skills/app-compose-5-design-mock-review/references/screen-listview.md +0 -153
- package/skills/app-compose-6-implementation-spec/references/auth.md +0 -72
- package/skills/app-compose-6-implementation-spec/references/structure.md +0 -27
- package/src/modules/primitives/lib/errors.ts +0 -138
- package/src/modules/user-management/lib/errors.ts +0 -81
- /package/skills/{2-module-feature-breakdown → erp-kit-module-4-tdd}/references/models.md +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/erp-kit",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Opinionated ERP toolkit for building business applications on Tailor Platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -26,15 +26,18 @@
|
|
|
26
26
|
"@mockoon/commons-server": "^9.0.0",
|
|
27
27
|
"chalk": "^5.4.1",
|
|
28
28
|
"fast-glob": "^3.3.3",
|
|
29
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
30
|
+
"mdast-util-to-string": "^4.0.0",
|
|
29
31
|
"politty": "^0.4.0",
|
|
30
32
|
"zod": "4.3.6"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
35
|
"@tailor-platform/function-kysely-tailordb": "0.1.3",
|
|
34
|
-
"@tailor-platform/function-types": "0.8.
|
|
36
|
+
"@tailor-platform/function-types": "0.8.2",
|
|
35
37
|
"@tailor-platform/sdk": "1.17.1",
|
|
38
|
+
"@types/mdast": "^4.0.4",
|
|
36
39
|
"@types/node": "^25.1.0",
|
|
37
|
-
"eslint": "9.39.
|
|
40
|
+
"eslint": "9.39.4",
|
|
38
41
|
"kysely": "0.28.10",
|
|
39
42
|
"tsup": "^8.0.0",
|
|
40
43
|
"typescript": "^5.7.3",
|
|
@@ -43,7 +46,7 @@
|
|
|
43
46
|
},
|
|
44
47
|
"peerDependencies": {
|
|
45
48
|
"@tailor-platform/function-kysely-tailordb": "0.1.3",
|
|
46
|
-
"@tailor-platform/function-types": "0.8.
|
|
49
|
+
"@tailor-platform/function-types": "0.8.2",
|
|
47
50
|
"@tailor-platform/sdk": "1.17.1",
|
|
48
51
|
"kysely": "0.28.10"
|
|
49
52
|
},
|
|
@@ -52,9 +55,7 @@
|
|
|
52
55
|
},
|
|
53
56
|
"scripts": {
|
|
54
57
|
"build": "tsup",
|
|
55
|
-
"generate": "
|
|
56
|
-
"generate:primitives": "cd src/modules/primitives && tailor-sdk generate",
|
|
57
|
-
"generate:user-management": "cd src/modules/user-management && tailor-sdk generate",
|
|
58
|
+
"generate": "for dir in src/modules/*/; do [ -f \"$dir/tailor.config.ts\" ] && (cd \"$dir\" && echo \"Generating $dir...\" && tailor-sdk generate); done",
|
|
58
59
|
"lint": "eslint --cache .",
|
|
59
60
|
"lint:fix": "eslint --cache --fix .",
|
|
60
61
|
"typecheck": "tsc --noEmit",
|
|
@@ -64,6 +65,8 @@
|
|
|
64
65
|
"test:user-management": "vitest run src/modules/user-management/",
|
|
65
66
|
"test:shared": "vitest run src/modules/shared/",
|
|
66
67
|
"mock:start": "node dist/cli.js mock start",
|
|
67
|
-
"mock:validate": "node dist/cli.js mock validate"
|
|
68
|
+
"mock:validate": "node dist/cli.js mock validate",
|
|
69
|
+
"doc:gen": "POLITTY_DOCS_UPDATE=true vitest run src/cli.doc.test.ts",
|
|
70
|
+
"doc:check": "vitest run src/cli.doc.test.ts"
|
|
68
71
|
}
|
|
69
72
|
}
|
|
@@ -24,6 +24,9 @@ structure:
|
|
|
24
24
|
|
|
25
25
|
# Diagram representing this flow - REQUIRED
|
|
26
26
|
- heading: "## Flow Diagram"
|
|
27
|
+
description: |
|
|
28
|
+
Mermaid sequence diagram showing actor interactions across the flow.
|
|
29
|
+
Use actors from "Actors Involved" as participants.
|
|
27
30
|
code_blocks:
|
|
28
31
|
- min: 1
|
|
29
32
|
lang: mermaid
|
|
@@ -24,7 +24,7 @@ structure:
|
|
|
24
24
|
# Diagram representing this story - REQUIRED
|
|
25
25
|
- heading: "## Story Diagram"
|
|
26
26
|
description: |
|
|
27
|
-
Mermaid
|
|
27
|
+
Mermaid flowchart showing user interactions with screens.
|
|
28
28
|
Focus on actors, UI screens, and business outcomes.
|
|
29
29
|
Avoid technical details (APIs, databases, endpoints).
|
|
30
30
|
code_blocks:
|
package/schemas/module/model.yml
CHANGED
|
@@ -41,6 +41,11 @@ structure:
|
|
|
41
41
|
description: |
|
|
42
42
|
Definitions of queries this domain model supports.
|
|
43
43
|
Should match with the queries defined in modules/**/docs/queries/*.md and link to them.
|
|
44
|
+
For Stateful models or models with isActive, follow the status-aware naming convention:
|
|
45
|
+
- get{Entity}: single lookup, returns any status
|
|
46
|
+
- list{Status}{Entities}: business use case with status baked into the name (e.g., listActiveItems)
|
|
47
|
+
- list{Entities}: unfiltered, returns all statuses
|
|
48
|
+
- search{Entities}: admin/exploratory with parametric status filter
|
|
44
49
|
lists:
|
|
45
50
|
- min: 0
|
|
46
51
|
type: unordered
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: app-
|
|
2
|
+
name: erp-kit-app-1-requirements
|
|
3
3
|
description: Create Tier 1-2 documentation (requirements, actors, business-flow) for examples/. Use when starting a new application or documenting high-level requirements and workflows.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -44,13 +44,13 @@ Generate documentation using `erp-kit` CLI:
|
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
# Tier 1: Requirements
|
|
47
|
-
erp-kit
|
|
47
|
+
erp-kit app scaffold requirements <app-name> --root examples
|
|
48
48
|
|
|
49
49
|
# Tier 2: Actors
|
|
50
|
-
erp-kit
|
|
50
|
+
erp-kit app scaffold actors <app-name> <actor-name> --root examples
|
|
51
51
|
|
|
52
52
|
# Tier 2: Business Flows
|
|
53
|
-
erp-kit
|
|
53
|
+
erp-kit app scaffold business-flow <app-name> <flow-name> --root examples
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
**Naming conventions:**
|
|
@@ -58,13 +58,11 @@ erp-kit scaffold --app-root examples business-flow <app-name> <flow-name>
|
|
|
58
58
|
- Files: kebab-case (e.g., `sales-representative.md`)
|
|
59
59
|
- H1 heading slug must match filename slug
|
|
60
60
|
|
|
61
|
-
**
|
|
61
|
+
**Business flow diagram:** Use `sequenceDiagram` with actors from "Actors Involved" as participants. Show who initiates each step and the system responses.
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
- [Flow Name](../business-flow/<flow>/README.md) — role
|
|
65
|
-
```
|
|
63
|
+
**Business flow `## Stories` section:**
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
At Tier 2, story files do not exist yet. Use `- TBD` as a placeholder to avoid broken link violations. Replace with actual story links in `/erp-kit-app-2-breakdown`.
|
|
68
66
|
|
|
69
67
|
### Phase 4: Validate
|
|
70
68
|
|
|
@@ -82,8 +80,4 @@ pnpm run app:doc:check
|
|
|
82
80
|
|
|
83
81
|
## Next Step
|
|
84
82
|
|
|
85
|
-
After completing Tier 1-2, use `/app-
|
|
86
|
-
|
|
87
|
-
## References
|
|
88
|
-
|
|
89
|
-
- [Application structure](references/structure.md)
|
|
83
|
+
After completing Tier 1-2, use `/erp-kit-app-2-breakdown` to create Tier 3 documentation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: app-
|
|
3
|
-
description: Create Tier 3 documentation (stories, screens) by breaking down business flows. Use after completing Tier 1-2 documentation with app-
|
|
2
|
+
name: erp-kit-app-2-breakdown
|
|
3
|
+
description: Create Tier 3 documentation (stories, screens) by breaking down business flows. Use after completing Tier 1-2 documentation with erp-kit-app-1-requirements.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Requirements Breakdown Workflow
|
|
@@ -46,10 +46,10 @@ Generate documentation using `erp-kit` CLI:
|
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
# Tier 3: Stories
|
|
49
|
-
erp-kit
|
|
49
|
+
erp-kit app scaffold story <app> <flow>/<actor>--<story> --root examples
|
|
50
50
|
|
|
51
51
|
# Tier 3: Screens
|
|
52
|
-
erp-kit
|
|
52
|
+
erp-kit app scaffold screen <app> <screen-name> --root examples
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
**Naming conventions:**
|
|
@@ -58,7 +58,7 @@ erp-kit scaffold --app-root examples screen <app> <screen-name>
|
|
|
58
58
|
- Story heading: Title Case of story name (after `--`)
|
|
59
59
|
- Screen filename: kebab-case, noun-focused (e.g., `supplier-list.md`)
|
|
60
60
|
|
|
61
|
-
**After creating stories**,
|
|
61
|
+
**After creating stories**, replace `- TBD` placeholders in the `## Stories` section of each business flow README with actual links:
|
|
62
62
|
|
|
63
63
|
```markdown
|
|
64
64
|
- [Story Title](./story/<actor>--<story-name>.md)
|
|
@@ -85,11 +85,4 @@ pnpm run app:doc:check
|
|
|
85
85
|
|
|
86
86
|
## Next Step
|
|
87
87
|
|
|
88
|
-
After completing Tier 3, use `/app-
|
|
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)
|
|
88
|
+
After completing Tier 3, use `/erp-kit-app-3-doc-review` to validate documentation parity.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: app-
|
|
2
|
+
name: erp-kit-app-3-doc-review
|
|
3
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
4
|
---
|
|
5
5
|
|
|
@@ -109,8 +109,4 @@ examples/<app-name>/docs/actors/*.md # Actors
|
|
|
109
109
|
|
|
110
110
|
## Next Step
|
|
111
111
|
|
|
112
|
-
After fixing all issues, use `/app-
|
|
113
|
-
|
|
114
|
-
## References
|
|
115
|
-
|
|
116
|
-
- [Application structure](references/structure.md)
|
|
112
|
+
After fixing all issues, use `/erp-kit-app-4-impl-spec` to create implementation specifications from screen and story documentation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: app-
|
|
3
|
-
description: Create Tier 4 documentation (resolvers) for GraphQL operations. Use after completing
|
|
2
|
+
name: erp-kit-app-4-impl-spec
|
|
3
|
+
description: Create Tier 4 documentation (resolvers) for GraphQL operations. Use after completing documentation review with erp-kit-app-3-doc-review.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Implementation Spec Workflow
|
|
@@ -9,14 +9,13 @@ Create Tier 4 documentation: GraphQL Resolvers (mutations and queries).
|
|
|
9
9
|
|
|
10
10
|
## Prerequisites
|
|
11
11
|
|
|
12
|
-
Tier 1-3 documentation
|
|
12
|
+
Tier 1-3 documentation must exist:
|
|
13
13
|
|
|
14
14
|
- `README.md` (requirements)
|
|
15
15
|
- `docs/actors/*.md` (actors)
|
|
16
16
|
- `docs/business-flow/*/README.md` (flows)
|
|
17
17
|
- `docs/business-flow/*/story/*.md` (stories)
|
|
18
18
|
- `docs/screen/*.md` (screens)
|
|
19
|
-
- `docs/design.pen` (UI mockups)
|
|
20
19
|
|
|
21
20
|
## Workflow Phases
|
|
22
21
|
|
|
@@ -42,7 +41,7 @@ Map stories to resolvers:
|
|
|
42
41
|
| View/List/Search | Query |
|
|
43
42
|
| Real-time updates | Subscription |
|
|
44
43
|
|
|
45
|
-
**Naming:** Use action-verb names: `create
|
|
44
|
+
**Naming:** Use camelCase action-verb names: `create`, `update`, `delete`, `submit`, `approve`
|
|
46
45
|
|
|
47
46
|
### Phase 3: Check Module Dependencies
|
|
48
47
|
|
|
@@ -51,13 +50,13 @@ Resolvers reference module commands. Before creating resolver docs, verify requi
|
|
|
51
50
|
**Check existing modules:**
|
|
52
51
|
|
|
53
52
|
```bash
|
|
54
|
-
ls modules/
|
|
53
|
+
ls packages/erp-kit/src/modules/
|
|
55
54
|
```
|
|
56
55
|
|
|
57
56
|
**Check module commands:**
|
|
58
57
|
|
|
59
58
|
```bash
|
|
60
|
-
ls modules/<module-name>/docs/commands/
|
|
59
|
+
ls packages/erp-kit/src/modules/<module-name>/docs/commands/
|
|
61
60
|
```
|
|
62
61
|
|
|
63
62
|
**Map resolvers to modules:**
|
|
@@ -72,7 +71,7 @@ ls modules/<module-name>/docs/commands/
|
|
|
72
71
|
**If modules don't exist:**
|
|
73
72
|
|
|
74
73
|
1. **Identify needed modules** - Group resolver operations by domain
|
|
75
|
-
2. **Create module docs first** - Use `
|
|
74
|
+
2. **Create module docs first** - Use `erp-kit-module-1-docs` skill
|
|
76
75
|
3. **Return to Tier 4** - After modules have documented commands
|
|
77
76
|
|
|
78
77
|
```
|
|
@@ -91,8 +90,8 @@ erp-kit scaffold --app-root examples resolver <app> <resolver-name>
|
|
|
91
90
|
|
|
92
91
|
**Naming conventions:**
|
|
93
92
|
|
|
94
|
-
- Filename must match H1 heading exactly (
|
|
95
|
-
- Action-focused names: `
|
|
93
|
+
- Filename must match H1 heading exactly (camelCase)
|
|
94
|
+
- Action-focused names: `createSupplierInvitation.md`
|
|
96
95
|
|
|
97
96
|
### Phase 5: Validate
|
|
98
97
|
|
|
@@ -112,16 +111,6 @@ pnpm run app:doc:check
|
|
|
112
111
|
- Group related operations logically
|
|
113
112
|
- Document all error scenarios
|
|
114
113
|
|
|
115
|
-
##
|
|
114
|
+
## Next Step
|
|
116
115
|
|
|
117
|
-
After Tier 4,
|
|
118
|
-
|
|
119
|
-
- **Tier 1**: Application overview
|
|
120
|
-
- **Tier 2**: Actors and business workflows
|
|
121
|
-
- **Tier 3**: User stories and screens
|
|
122
|
-
- **Tier 4**: Implementation specifications
|
|
123
|
-
|
|
124
|
-
## References
|
|
125
|
-
|
|
126
|
-
- [Application structure](references/structure.md)
|
|
127
|
-
- [Backend auth](references/auth.md)
|
|
116
|
+
After completing Tier 4, use `/erp-kit-app-5-implementation` to implement backend resolvers and frontend pages.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: erp-kit-app-5-implementation
|
|
3
|
+
description: Implement backend and frontend code for app-compose applications using erp-kit modules. Use after completing Tier 4 documentation (resolver specs) with erp-kit-app-4-impl-spec. Triggers when implementing resolvers, wiring modules, creating frontend pages, or building a full-stack application from documentation specs. Also use when the user mentions implementing an app, writing backend resolvers, creating frontend pages, or connecting erp-kit modules to an application.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# App-Compose Implementation
|
|
7
|
+
|
|
8
|
+
Implement backend resolvers and frontend pages for an app-compose application, driven by Tier 1-4 documentation (actors, business flows, stories, screens, resolver specs).
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Implementing backend resolvers from resolver spec docs
|
|
13
|
+
- Creating frontend pages from screen spec docs
|
|
14
|
+
- Wiring erp-kit modules into an application
|
|
15
|
+
- Building full-stack code for an app-compose application
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
All four tiers of documentation must exist:
|
|
20
|
+
|
|
21
|
+
- `README.md` — Application overview
|
|
22
|
+
- `docs/actors/*.md` — Actor definitions
|
|
23
|
+
- `docs/business-flow/*/README.md` + `story/*.md` — Business flows and user stories
|
|
24
|
+
- `docs/screen/*.md` — Screen specifications (ListView, Form, DetailView)
|
|
25
|
+
- `docs/resolver/*.md` — Resolver specifications (mutations, queries)
|
|
26
|
+
|
|
27
|
+
## Workflow
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
ANALYZE DOCS → BACKEND SCAFFOLD → MODULE WIRING → CONFIG → RESOLVERS → GENERATED FILES → DEPLOY → FRONTEND SCAFFOLD → PAGES → VERIFY
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Phase 1: Analyze Documentation
|
|
34
|
+
|
|
35
|
+
Read all resolver and screen specs to build a complete picture:
|
|
36
|
+
|
|
37
|
+
1. **Resolver docs** (`docs/resolver/*.md`) — Identify which module commands each resolver calls, what inputs/outputs it needs, and what errors it handles
|
|
38
|
+
2. **Screen docs** (`docs/screen/*.md`) — Identify screen types (ListView, Form, DetailView) and their fields/columns/actions
|
|
39
|
+
3. **Command source types** — For each module command the resolver calls, read the input type at `node_modules/@tailor-platform/erp-kit/src/modules/<module>/command/<commandName>.ts`. Do not invent fields that don't exist in the command, and preserve the required/optional distinction.
|
|
40
|
+
|
|
41
|
+
Classify resolvers into two categories:
|
|
42
|
+
|
|
43
|
+
| Category | Description | Implementation |
|
|
44
|
+
| -------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
45
|
+
| **Custom resolvers** | Mutations that call module commands (create, update, activate, deactivate, assign) | Write `createResolver()` files |
|
|
46
|
+
| **Built-in queries** | List and get operations for reading data | Handled automatically by `gqlOperations: "query"` in config — no code needed |
|
|
47
|
+
|
|
48
|
+
Prefer built-in queries over custom resolvers for list/get operations where possible.
|
|
49
|
+
|
|
50
|
+
### Phase 2: Backend Scaffold
|
|
51
|
+
|
|
52
|
+
Set up the backend project structure and config files.
|
|
53
|
+
|
|
54
|
+
**Read [backend reference](references/backend.md) § "Backend Scaffold" for the directory structure and boilerplate.**
|
|
55
|
+
|
|
56
|
+
Key files: `package.json` (dependencies, scripts), `tsconfig.json` (path alias, types), `eslint.config.js`.
|
|
57
|
+
|
|
58
|
+
### Phase 3: Wire Modules (`src/modules.ts`)
|
|
59
|
+
|
|
60
|
+
Create the module wiring file that composes all required erp-kit modules.
|
|
61
|
+
|
|
62
|
+
**Read [backend reference](references/backend.md) § "Module Wiring" for the composition pattern.**
|
|
63
|
+
|
|
64
|
+
Key points:
|
|
65
|
+
|
|
66
|
+
- Use `defineXxxModule()` functions from `@tailor-platform/erp-kit/module`
|
|
67
|
+
- Pass inter-module dependencies explicitly (e.g., item-management needs primitives' unit type and query)
|
|
68
|
+
- Export `db`, `commands`, and `executors` for use in resolvers
|
|
69
|
+
|
|
70
|
+
### Phase 4: Configure Application (`tailor.config.ts`)
|
|
71
|
+
|
|
72
|
+
**Read [backend reference](references/backend.md) § "Application Config" for the config pattern.**
|
|
73
|
+
|
|
74
|
+
Key points:
|
|
75
|
+
|
|
76
|
+
- Single DB namespace (`"main-db"`) with `gqlOperations: "query"` for automatic list/get queries
|
|
77
|
+
- Resolver/executor discovery via glob patterns
|
|
78
|
+
- Auth with OAuth2, DPoP, and user profile mapping
|
|
79
|
+
- Generators for Kysely types and seed data
|
|
80
|
+
|
|
81
|
+
### Phase 5: Implement Backend Resolvers and Executors
|
|
82
|
+
|
|
83
|
+
Write one file per resolver under `src/modules/<module-name>/resolvers/`, one per executor under `executors/`.
|
|
84
|
+
|
|
85
|
+
**Read [backend reference](references/backend.md) § "Resolver Patterns" and "Executor Patterns".**
|
|
86
|
+
|
|
87
|
+
Do not directly mutate module-owned tables via Kysely — always use module commands.
|
|
88
|
+
|
|
89
|
+
### Phase 6: Generated Files
|
|
90
|
+
|
|
91
|
+
- **Kysely types** (`src/generated/kysely-tailordb.ts`) — Auto-generated by `pnpm generate` after deployment. Before deployment, create a minimal placeholder so the codebase typechecks.
|
|
92
|
+
- **Seed data** (`seed/`) — `exec.mjs` runner + `data/*.jsonl` (records) and `data/*.schema.ts` (validation). Create seed records for initial data (permissions, roles, test users, etc.). Seeded users must have concrete permission keys required by the wired modules.
|
|
93
|
+
|
|
94
|
+
### Phase 7: Deploy Backend
|
|
95
|
+
|
|
96
|
+
Frontend implementation requires a deployed backend (for GraphQL schema generation). Prompt the user to:
|
|
97
|
+
|
|
98
|
+
1. Create a workspace and configure `.env` (including `TAILOR_PLATFORM_WORKSPACE_ID`)
|
|
99
|
+
2. Run `pnpm deploy` and `pnpm generate`
|
|
100
|
+
3. Run `pnpm seed` if seed data was created
|
|
101
|
+
4. Retrieve OAuth2 client ID via `tailor-sdk oauth2client get default --json` for frontend `.env`
|
|
102
|
+
|
|
103
|
+
Wait for the user to confirm deployment is complete before proceeding.
|
|
104
|
+
|
|
105
|
+
### Phase 8: Frontend Scaffold
|
|
106
|
+
|
|
107
|
+
Set up the frontend project structure, config files, and generate GraphQL schema.
|
|
108
|
+
|
|
109
|
+
**Read [frontend reference](references/frontend.md) § "Frontend Scaffold" for the directory structure, boilerplate, and schema generation.**
|
|
110
|
+
|
|
111
|
+
Key files: `package.json`, `tsconfig.json`, `vite.config.ts`, `eslint.config.js`, UI components, `scripts/generate-graphql.mjs`. After scaffolding, run `pnpm generate` to fetch the GraphQL schema from the deployed backend.
|
|
112
|
+
|
|
113
|
+
### Phase 9: Implement Frontend Pages
|
|
114
|
+
|
|
115
|
+
Create pages driven by screen spec docs. Each screen type has a standard implementation pattern.
|
|
116
|
+
|
|
117
|
+
**Read [frontend reference](references/frontend.md) § "Frontend Pages" for the full pattern catalog.**
|
|
118
|
+
|
|
119
|
+
Page types and their file structure:
|
|
120
|
+
|
|
121
|
+
| Screen Type | Files |
|
|
122
|
+
| ------------- | ------------------------------------------------------------------------------------------------ |
|
|
123
|
+
| ListView | `page.tsx` + `components/<entity>-table.tsx` |
|
|
124
|
+
| Form (create) | `create/page.tsx` + `create/components/create-<entity>-form.tsx` |
|
|
125
|
+
| Form (edit) | `[id]/edit/page.tsx` + `[id]/edit/components/edit-<entity>-form.tsx` |
|
|
126
|
+
| DetailView | `[id]/page.tsx` + `[id]/components/<entity>-detail.tsx` + `[id]/components/<entity>-actions.tsx` |
|
|
127
|
+
|
|
128
|
+
Key frontend patterns:
|
|
129
|
+
|
|
130
|
+
- **GraphQL fragments** — Each table/form/detail component exports its own fragment; page-level queries compose fragments
|
|
131
|
+
- **gql.tada** — Type-safe GraphQL via `graphql()` from `@/graphql`
|
|
132
|
+
- **React Hook Form + Zod** — Form validation with `zodResolver`
|
|
133
|
+
- **urql** — `useQuery` for reads, `useMutation` for writes
|
|
134
|
+
- **app-shell routing** — `Layout`, `Link`, `useParams`, `useNavigate` from `@tailor-platform/app-shell`
|
|
135
|
+
|
|
136
|
+
### Phase 10: Verify
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Backend
|
|
140
|
+
cd <app-root>/backend
|
|
141
|
+
pnpm lint
|
|
142
|
+
pnpm typecheck
|
|
143
|
+
|
|
144
|
+
# Frontend
|
|
145
|
+
cd <app-root>/frontend
|
|
146
|
+
pnpm lint
|
|
147
|
+
pnpm typecheck
|
|
148
|
+
pnpm build
|
|
149
|
+
```
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Backend Implementation Patterns
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Backend Scaffold](#backend-scaffold)
|
|
6
|
+
- [Module Wiring](#module-wiring)
|
|
7
|
+
- [Application Config](#application-config)
|
|
8
|
+
- [Resolver Patterns](#resolver-patterns)
|
|
9
|
+
- [Executor Patterns](#executor-pattern)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Backend Scaffold
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
backend/
|
|
17
|
+
├── src/
|
|
18
|
+
│ ├── modules.ts # Module wiring
|
|
19
|
+
│ ├── generated/kysely-tailordb.ts # Auto-generated (placeholder until deploy)
|
|
20
|
+
│ └── modules/<module-name>/
|
|
21
|
+
│ ├── resolvers/<name>.ts
|
|
22
|
+
│ └── executors/<name>.ts
|
|
23
|
+
├── seed/ # Seed data scripts
|
|
24
|
+
├── package.json
|
|
25
|
+
├── tsconfig.json
|
|
26
|
+
├── eslint.config.js
|
|
27
|
+
└── tailor.config.ts
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`package.json` key dependencies and scripts:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"type": "module",
|
|
35
|
+
"scripts": {
|
|
36
|
+
"generate": "tailor-sdk generate",
|
|
37
|
+
"deploy": "tailor-sdk apply --env-file-if-exists .env",
|
|
38
|
+
"lint": "eslint --cache .",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"seed": "node --env-file-if-exists=.env seed/exec.mjs"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@tailor-platform/erp-kit": "...",
|
|
44
|
+
"@tailor-platform/function-kysely-tailordb": "...",
|
|
45
|
+
"kysely": "..."
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@tailor-platform/sdk": "...",
|
|
49
|
+
"@tailor-platform/function-types": "...",
|
|
50
|
+
"typescript": "..."
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`tsconfig.json` — requires `@/*` path alias and `@tailor-platform/function-types` in types:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"compilerOptions": {
|
|
60
|
+
"target": "ES2022",
|
|
61
|
+
"module": "ESNext",
|
|
62
|
+
"moduleResolution": "bundler",
|
|
63
|
+
"strict": true,
|
|
64
|
+
"noEmit": true,
|
|
65
|
+
"skipLibCheck": true,
|
|
66
|
+
"types": ["node", "@tailor-platform/function-types"],
|
|
67
|
+
"paths": { "@/*": ["./src/*"] }
|
|
68
|
+
},
|
|
69
|
+
"include": ["**/*.ts"]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Module Wiring
|
|
76
|
+
|
|
77
|
+
`src/modules.ts` composes erp-kit modules and exports their parts for resolver use.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { db as field } from "@tailor-platform/sdk";
|
|
81
|
+
import {
|
|
82
|
+
definePrimitivesModule,
|
|
83
|
+
defineUserManagementModule,
|
|
84
|
+
defineItemManagementModule,
|
|
85
|
+
} from "@tailor-platform/erp-kit/module";
|
|
86
|
+
|
|
87
|
+
const primitivesModules = definePrimitivesModule({});
|
|
88
|
+
|
|
89
|
+
const umModules = defineUserManagementModule({
|
|
90
|
+
dbNamespace: "main-db",
|
|
91
|
+
user: {
|
|
92
|
+
fields: {
|
|
93
|
+
/* custom fields */
|
|
94
|
+
},
|
|
95
|
+
additionalStatuses: ["SUSPENDED"],
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Pass inter-module dependencies explicitly
|
|
100
|
+
const imModules = defineItemManagementModule({
|
|
101
|
+
primitives: {
|
|
102
|
+
db: { unit: primitivesModules.db.unit },
|
|
103
|
+
queries: { getUnit: primitivesModules.queries.getUnit },
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Destructure db into individual table exports (required for DB scanner)
|
|
108
|
+
export const { db: primitivesDb, commands: primitivesCommands } = primitivesModules;
|
|
109
|
+
export const { uomCategory, unit, currency, exchangeRate } = primitivesDb;
|
|
110
|
+
|
|
111
|
+
export const { db: umDb, executors: umExecutors, commands: umCommands } = umModules;
|
|
112
|
+
export const { user, permission, role, userRole, rolePermission, auditEvent } = umDb;
|
|
113
|
+
|
|
114
|
+
export const { db: imDb, commands: imCommands } = imModules;
|
|
115
|
+
export const { item, taxonomyNode, itemTaxonomyAssignment } = imDb;
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Key conventions:
|
|
119
|
+
|
|
120
|
+
- Prefix exports to avoid collisions (`umCommands`, `imCommands`, `primitivesCommands`)
|
|
121
|
+
- Every module's `db` must be destructured into individual table exports — the DB scanner only picks up named exports
|
|
122
|
+
- Extract individual executors for re-export in executor files
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Application Config
|
|
127
|
+
|
|
128
|
+
`tailor.config.ts` defines the Tailor application configuration. Key structure:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
export default defineConfig({
|
|
132
|
+
name: "<app-name>",
|
|
133
|
+
cors: ["http://localhost:5173", website.url],
|
|
134
|
+
db: {
|
|
135
|
+
"main-db": {
|
|
136
|
+
files: [`./src/modules.ts`],
|
|
137
|
+
gqlOperations: "query",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
resolver: {
|
|
141
|
+
"main-resolver": { files: [`./src/modules/**/resolvers/**/*.ts`] },
|
|
142
|
+
},
|
|
143
|
+
executor: { files: [`./src/modules/**/executors/**/*.ts`] },
|
|
144
|
+
auth: auth,
|
|
145
|
+
idp: [idp],
|
|
146
|
+
staticWebsites: [website],
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Key points:
|
|
151
|
+
|
|
152
|
+
- `gqlOperations: "query"` — Auto-generates list/get GraphQL queries for all DB types
|
|
153
|
+
- Glob patterns for resolver/executor discovery
|
|
154
|
+
- See [SDK configuration docs](https://raw.githubusercontent.com/tailor-platform/sdk/refs/heads/main/packages/sdk/docs/configuration.md) for full config options
|
|
155
|
+
|
|
156
|
+
### Auth configuration
|
|
157
|
+
|
|
158
|
+
- Define IdP (`defineIdp`), Auth (`defineAuth`), and static website (`defineStaticWebSite`) using Tailor SDK
|
|
159
|
+
- Prefer stable default naming: auth `default`, IdP `default`, OAuth2 client `default`
|
|
160
|
+
- `userProfile.type` must reference the `user` DB type from `modules.ts`
|
|
161
|
+
- `userProfile.usernameField`: stable unique field (e.g., `email`)
|
|
162
|
+
- Include static website URL and localhost in CORS: `cors: ["http://localhost:5173", website.url]`
|
|
163
|
+
- Frontend `VITE_TAILOR_CLIENT_ID` must come from `tailor-sdk oauth2client get default --json` — do not hardcode
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Resolver Patterns
|
|
168
|
+
|
|
169
|
+
All resolvers export a default `createResolver()` from `@tailor-platform/sdk`.
|
|
170
|
+
|
|
171
|
+
### Verify command input types
|
|
172
|
+
|
|
173
|
+
Before implementing a resolver, read the command's type definition:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
node_modules/@tailor-platform/erp-kit/src/modules/<module>/command/<commandName>.ts
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The command source is the ground truth. Do not invent fields that don't exist, and preserve the required/optional distinction.
|
|
180
|
+
|
|
181
|
+
### SDK type system
|
|
182
|
+
|
|
183
|
+
See [Resolver docs](https://raw.githubusercontent.com/tailor-platform/sdk/refs/heads/main/packages/sdk/docs/services/resolver.md) for the `t` namespace.
|
|
184
|
+
|
|
185
|
+
`t.array()` and `t.boolean()` do **not exist**. Never attempt to use them.
|
|
186
|
+
|
|
187
|
+
### Command-based mutation
|
|
188
|
+
|
|
189
|
+
The most common pattern. Key points:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { createContext } from "@tailor-platform/erp-kit/app";
|
|
193
|
+
|
|
194
|
+
body: async (context) => {
|
|
195
|
+
const db = getDB("main-db");
|
|
196
|
+
const result = await imCommands.createItem(db, { ...context.input }, createContext(context));
|
|
197
|
+
if (!result.ok) throw result.error;
|
|
198
|
+
return { id: result.value.item.id, ... };
|
|
199
|
+
},
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
- `context.input.optionalField ?? undefined` — Convert null to undefined for command inputs
|
|
203
|
+
- `result.value.entity.nullableField ?? ""` — Handle nullable return values
|
|
204
|
+
- `createContext(context)` wraps the resolver context for erp-kit commands
|
|
205
|
+
- `getDB("main-db")` — Namespace must match `tailor.config.ts`
|
|
206
|
+
|
|
207
|
+
### Error handling
|
|
208
|
+
|
|
209
|
+
When the resolver spec documents specific error codes, use `result.error.code` to switch:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
if (!result.ok) {
|
|
213
|
+
switch (result.error.code) {
|
|
214
|
+
case "USER_NOT_FOUND":
|
|
215
|
+
throw new Error(`User ${context.input.userId} not found`);
|
|
216
|
+
// ...
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Do not directly mutate module-owned tables via Kysely — always use module commands.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Executor Patterns
|
|
226
|
+
|
|
227
|
+
Executors re-export module-provided event handlers. One file per executor, no custom logic:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import { rolePermissionCreated } from "@/modules";
|
|
231
|
+
export default rolePermissionCreated;
|
|
232
|
+
```
|