@tailor-platform/erp-kit 0.1.1 → 0.2.0
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 +158 -62
- package/dist/cli.js +1010 -270
- package/package.json +11 -8
- package/schemas/module/command.yml +1 -0
- package/schemas/module/model.yml +14 -0
- package/schemas/module/query.yml +53 -0
- package/skills/{app-compose-1-requirement-analysis → erp-kit-app-1-requirements}/SKILL.md +2 -2
- package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/SKILL.md +3 -3
- package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/SKILL.md +2 -2
- package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/SKILL.md +3 -3
- package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/SKILL.md +4 -4
- package/skills/{app-compose-6-implementation-spec → erp-kit-app-6-impl-spec}/SKILL.md +3 -3
- 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 -117
- package/src/commands/app/index.ts +74 -0
- package/src/commands/check.test.ts +3 -2
- package/src/commands/check.ts +3 -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 +87 -0
- package/src/commands/module/list.test.ts +57 -0
- package/src/commands/module/list.ts +64 -0
- package/src/commands/scaffold-templates.ts +65 -0
- package/src/commands/scaffold.test.ts +97 -2
- package/src/commands/scaffold.ts +24 -3
- package/src/commands/sync-check.test.ts +88 -1
- package/src/commands/sync-check.ts +41 -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 +6 -8
- package/src/module.ts +10 -9
- 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/models/Currency.md +4 -0
- package/src/modules/primitives/docs/models/ExchangeRate.md +4 -1
- package/src/modules/primitives/docs/models/Unit.md +4 -1
- package/src/modules/primitives/docs/models/UoMCategory.md +2 -0
- package/src/modules/primitives/docs/{commands → queries}/ConvertAmount.md +3 -5
- package/src/modules/primitives/docs/{commands → 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 +17 -6
- package/src/modules/primitives/lib/errors.generated.ts +112 -0
- package/src/modules/primitives/{permissions.ts → lib/permissions.generated.ts} +9 -10
- package/src/modules/primitives/module.ts +39 -27
- package/src/modules/primitives/query/convertAmount.generated.ts +5 -0
- package/src/modules/primitives/{command → query}/convertAmount.test.ts +4 -21
- package/src/modules/primitives/query/convertAmount.ts +121 -0
- package/src/modules/primitives/query/convertQuantity.generated.ts +5 -0
- package/src/modules/primitives/{command → query}/convertQuantity.test.ts +8 -15
- package/src/modules/primitives/query/convertQuantity.ts +63 -0
- 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/defineQuery.test.ts +28 -0
- package/src/modules/shared/defineQuery.ts +16 -0
- package/src/modules/shared/internal.ts +3 -1
- 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/shared/types.ts +8 -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/docs/models/AuditEvent.md +2 -0
- package/src/modules/user-management/docs/models/Permission.md +2 -0
- package/src/modules/user-management/docs/models/Role.md +2 -0
- package/src/modules/user-management/docs/models/RolePermission.md +2 -0
- package/src/modules/user-management/docs/models/User.md +2 -0
- package/src/modules/user-management/docs/models/UserRole.md +2 -0
- 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 +2 -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/src/modules/primitives/command/convertAmount.ts +0 -126
- package/src/modules/primitives/command/convertQuantity.ts +0 -73
- package/src/modules/primitives/lib/errors.ts +0 -138
- package/src/modules/user-management/lib/errors.ts +0 -81
- /package/skills/{app-compose-1-requirement-analysis → erp-kit-app-1-requirements}/references/structure.md +0 -0
- /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/screen-detailview.md +0 -0
- /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/screen-form.md +0 -0
- /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/screen-listview.md +0 -0
- /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/structure.md +0 -0
- /package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/references/structure.md +0 -0
- /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/component.md +0 -0
- /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-detailview.md +0 -0
- /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-form.md +0 -0
- /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-listview.md +0 -0
- /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/structure.md +0 -0
- /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/component.md +0 -0
- /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/screen-detailview.md +0 -0
- /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/screen-form.md +0 -0
- /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/screen-listview.md +0 -0
- /package/skills/{app-compose-6-implementation-spec → erp-kit-app-6-impl-spec}/references/auth.md +0 -0
- /package/skills/{app-compose-6-implementation-spec → erp-kit-app-6-impl-spec}/references/structure.md +0 -0
- /package/skills/{2-module-feature-breakdown → erp-kit-module-4-tdd}/references/models.md +0 -0
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Command Implementation
|
|
2
|
-
|
|
3
|
-
## Dual Function Pattern
|
|
4
|
-
|
|
5
|
-
Two functions per operation: internal `_fn` and public `fn`.
|
|
6
|
-
|
|
7
|
-
**Internal function (`_myFunction`):**
|
|
8
|
-
|
|
9
|
-
- Takes concrete `DB` type from `generated/kysely-tailordb`
|
|
10
|
-
- Return type uses `Schema` from `lib/types`: `Promise<{ entity: Entity<Schema> }>`
|
|
11
|
-
- Contains actual implementation
|
|
12
|
-
|
|
13
|
-
**Public function (`myFunction`):**
|
|
14
|
-
|
|
15
|
-
- Generic signature: `<T extends { Entity: object }>(db: Kysely<T>, ...)`
|
|
16
|
-
- Return type uses generic `T`: `Promise<{ entity: Entity<T> }>`
|
|
17
|
-
- Delegates to internal with type casting: `_fn(db as unknown as DB, ...) as unknown as Result`
|
|
18
|
-
|
|
19
|
-
## Implementation Considerations
|
|
20
|
-
|
|
21
|
-
- **Validation**: Check referenced entities exist before operating
|
|
22
|
-
- **Idempotency**: For assign/revoke, return existing instead of throwing
|
|
23
|
-
- **Return format**: Wrap in object `{ entity }` not just `entity`
|
|
24
|
-
|
|
25
|
-
## Conventions
|
|
26
|
-
|
|
27
|
-
- Input types: exported interfaces (`export interface MyFunctionInput`)
|
|
28
|
-
- Use `.executeTakeFirst()` for single results
|
|
29
|
-
- Include JSDoc: `/** Function: name \n Description */`
|
|
30
|
-
|
|
31
|
-
## State Transitions
|
|
32
|
-
|
|
33
|
-
For commands that transition between statuses, accept `from?: string[]` with a default:
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
from?: string[]; // Default: ["ACTIVE"]
|
|
37
|
-
|
|
38
|
-
const validFromStatuses = input.from ?? ["ACTIVE"];
|
|
39
|
-
if (!validFromStatuses.includes(user.status)) {
|
|
40
|
-
throw new InvalidStatusTransitionError(user.status, targetStatus);
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
- Default `from` contains the base valid source status
|
|
45
|
-
- Parent modules can override to allow transitions from additional statuses
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# Database Models
|
|
2
|
-
|
|
3
|
-
## Factory Function Pattern
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
export function createEntityType(params: {
|
|
7
|
-
fields?: Record<string, unknown>;
|
|
8
|
-
additionalStatuses?: string[];
|
|
9
|
-
});
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
- Include `...db.fields.timestamps()`
|
|
13
|
-
- Use `.description()` for field docs
|
|
14
|
-
- Apply permissions at model level
|
|
15
|
-
|
|
16
|
-
## Stateful Model Enums
|
|
17
|
-
|
|
18
|
-
Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
// Good: extension only
|
|
22
|
-
const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
|
|
23
|
-
const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
|
|
24
|
-
|
|
25
|
-
// Bad: allows replacement
|
|
26
|
-
const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
- Name parameter `additionalX` to signal extension-only
|
|
30
|
-
- Parent modules handle their additional status transitions
|
|
@@ -1,22 +0,0 @@
|
|
|
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
|
|
@@ -1,37 +0,0 @@
|
|
|
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
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Command Implementation
|
|
2
|
-
|
|
3
|
-
## Dual Function Pattern
|
|
4
|
-
|
|
5
|
-
Two functions per operation: internal `_fn` and public `fn`.
|
|
6
|
-
|
|
7
|
-
**Internal function (`_myFunction`):**
|
|
8
|
-
|
|
9
|
-
- Takes concrete `DB` type from `generated/kysely-tailordb`
|
|
10
|
-
- Return type uses `Schema` from `lib/types`: `Promise<{ entity: Entity<Schema> }>`
|
|
11
|
-
- Contains actual implementation
|
|
12
|
-
|
|
13
|
-
**Public function (`myFunction`):**
|
|
14
|
-
|
|
15
|
-
- Generic signature: `<T extends { Entity: object }>(db: Kysely<T>, ...)`
|
|
16
|
-
- Return type uses generic `T`: `Promise<{ entity: Entity<T> }>`
|
|
17
|
-
- Delegates to internal with type casting: `_fn(db as unknown as DB, ...) as unknown as Result`
|
|
18
|
-
|
|
19
|
-
## Implementation Considerations
|
|
20
|
-
|
|
21
|
-
- **Validation**: Check referenced entities exist before operating
|
|
22
|
-
- **Idempotency**: For assign/revoke, return existing instead of throwing
|
|
23
|
-
- **Return format**: Wrap in object `{ entity }` not just `entity`
|
|
24
|
-
|
|
25
|
-
## Conventions
|
|
26
|
-
|
|
27
|
-
- Input types: exported interfaces (`export interface MyFunctionInput`)
|
|
28
|
-
- Use `.executeTakeFirst()` for single results
|
|
29
|
-
- Include JSDoc: `/** Function: name \n Description */`
|
|
30
|
-
|
|
31
|
-
## State Transitions
|
|
32
|
-
|
|
33
|
-
For commands that transition between statuses, accept `from?: string[]` with a default:
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
from?: string[]; // Default: ["ACTIVE"]
|
|
37
|
-
|
|
38
|
-
const validFromStatuses = input.from ?? ["ACTIVE"];
|
|
39
|
-
if (!validFromStatuses.includes(user.status)) {
|
|
40
|
-
throw new InvalidStatusTransitionError(user.status, targetStatus);
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
- Default `from` contains the base valid source status
|
|
45
|
-
- Parent modules can override to allow transitions from additional statuses
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# Database Models
|
|
2
|
-
|
|
3
|
-
## Factory Function Pattern
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
export function createEntityType(params: {
|
|
7
|
-
fields?: Record<string, unknown>;
|
|
8
|
-
additionalStatuses?: string[];
|
|
9
|
-
});
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
- Include `...db.fields.timestamps()`
|
|
13
|
-
- Use `.description()` for field docs
|
|
14
|
-
- Apply permissions at model level
|
|
15
|
-
|
|
16
|
-
## Stateful Model Enums
|
|
17
|
-
|
|
18
|
-
Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
// Good: extension only
|
|
22
|
-
const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
|
|
23
|
-
const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
|
|
24
|
-
|
|
25
|
-
// Bad: allows replacement
|
|
26
|
-
const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
- Name parameter `additionalX` to signal extension-only
|
|
30
|
-
- Parent modules handle their additional status transitions
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "../../shared/internal";
|
|
2
|
-
import { DB } from "../generated/kysely-tailordb";
|
|
3
|
-
import {
|
|
4
|
-
CurrencyNotFoundError,
|
|
5
|
-
ExchangeRateNotFoundError,
|
|
6
|
-
InactiveCurrencyError,
|
|
7
|
-
} from "../lib/errors";
|
|
8
|
-
import { permissions } from "../permissions";
|
|
9
|
-
|
|
10
|
-
export interface ConvertAmountInput {
|
|
11
|
-
amount: number;
|
|
12
|
-
sourceCurrencyCode: string;
|
|
13
|
-
targetCurrencyCode: string;
|
|
14
|
-
conversionDate: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Function: convertAmount
|
|
19
|
-
*
|
|
20
|
-
* Converts a monetary amount from one currency to another using the applicable
|
|
21
|
-
* exchange rate for a given date. Currencies are identified by their ISO 4217
|
|
22
|
-
* code (e.g., "USD", "EUR", "JPY"). The function looks up the most recent exchange
|
|
23
|
-
* rate on or before the specified date. If no direct rate exists, it calculates
|
|
24
|
-
* the inverse rate. Result is rounded to the target currency's decimal precision.
|
|
25
|
-
*/
|
|
26
|
-
export const convertAmount = defineCommand(
|
|
27
|
-
permissions.convertAmount,
|
|
28
|
-
async (db: DB, input: ConvertAmountInput) => {
|
|
29
|
-
// 1. Validate source currency exists
|
|
30
|
-
const sourceCurrency = await db
|
|
31
|
-
.selectFrom("Currency")
|
|
32
|
-
.selectAll()
|
|
33
|
-
.where("code", "=", input.sourceCurrencyCode)
|
|
34
|
-
.executeTakeFirst();
|
|
35
|
-
|
|
36
|
-
if (!sourceCurrency) {
|
|
37
|
-
throw new CurrencyNotFoundError(input.sourceCurrencyCode);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// 2. Validate target currency exists
|
|
41
|
-
const targetCurrency = await db
|
|
42
|
-
.selectFrom("Currency")
|
|
43
|
-
.selectAll()
|
|
44
|
-
.where("code", "=", input.targetCurrencyCode)
|
|
45
|
-
.executeTakeFirst();
|
|
46
|
-
|
|
47
|
-
if (!targetCurrency) {
|
|
48
|
-
throw new CurrencyNotFoundError(input.targetCurrencyCode);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// 3. Validate both currencies are active
|
|
52
|
-
if (!sourceCurrency.isActive) {
|
|
53
|
-
throw new InactiveCurrencyError(input.sourceCurrencyCode);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (!targetCurrency.isActive) {
|
|
57
|
-
throw new InactiveCurrencyError(input.targetCurrencyCode);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 4. Same currency - return original amount
|
|
61
|
-
if (sourceCurrency.id === targetCurrency.id) {
|
|
62
|
-
return {
|
|
63
|
-
convertedAmount: input.amount,
|
|
64
|
-
exchangeRate: 1,
|
|
65
|
-
sourceCurrency,
|
|
66
|
-
targetCurrency,
|
|
67
|
-
exchangeRateRecord: null,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// 5. Find direct exchange rate (most recent on or before conversion date)
|
|
72
|
-
const conversionDate = new Date(input.conversionDate);
|
|
73
|
-
const directRate = await db
|
|
74
|
-
.selectFrom("ExchangeRate")
|
|
75
|
-
.selectAll()
|
|
76
|
-
.where("sourceCurrencyId", "=", sourceCurrency.id)
|
|
77
|
-
.where("targetCurrencyId", "=", targetCurrency.id)
|
|
78
|
-
.where("effectiveDate", "<=", conversionDate)
|
|
79
|
-
.orderBy("effectiveDate", "desc")
|
|
80
|
-
.executeTakeFirst();
|
|
81
|
-
|
|
82
|
-
let exchangeRate: number;
|
|
83
|
-
let exchangeRateRecord = null;
|
|
84
|
-
|
|
85
|
-
if (directRate) {
|
|
86
|
-
exchangeRate = directRate.rate;
|
|
87
|
-
exchangeRateRecord = directRate;
|
|
88
|
-
} else {
|
|
89
|
-
// 6. Try inverse rate
|
|
90
|
-
const inverseRate = await db
|
|
91
|
-
.selectFrom("ExchangeRate")
|
|
92
|
-
.selectAll()
|
|
93
|
-
.where("sourceCurrencyId", "=", targetCurrency.id)
|
|
94
|
-
.where("targetCurrencyId", "=", sourceCurrency.id)
|
|
95
|
-
.where("effectiveDate", "<=", conversionDate)
|
|
96
|
-
.orderBy("effectiveDate", "desc")
|
|
97
|
-
.executeTakeFirst();
|
|
98
|
-
|
|
99
|
-
if (!inverseRate) {
|
|
100
|
-
throw new ExchangeRateNotFoundError(
|
|
101
|
-
input.sourceCurrencyCode,
|
|
102
|
-
input.targetCurrencyCode,
|
|
103
|
-
input.conversionDate,
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
exchangeRate = 1 / inverseRate.rate;
|
|
108
|
-
exchangeRateRecord = inverseRate;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// 7. Calculate converted amount
|
|
112
|
-
const rawResult = input.amount * exchangeRate;
|
|
113
|
-
|
|
114
|
-
// 8. Round to target currency's decimal places
|
|
115
|
-
const roundingFactor = Math.pow(10, targetCurrency.decimalPlaces);
|
|
116
|
-
const convertedAmount = Math.round(rawResult * roundingFactor) / roundingFactor;
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
convertedAmount,
|
|
120
|
-
exchangeRate,
|
|
121
|
-
sourceCurrency,
|
|
122
|
-
targetCurrency,
|
|
123
|
-
exchangeRateRecord,
|
|
124
|
-
};
|
|
125
|
-
},
|
|
126
|
-
);
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "../../shared/internal";
|
|
2
|
-
import { DB } from "../generated/kysely-tailordb";
|
|
3
|
-
import { InactiveUnitError, IncompatibleUnitsError, UnitNotFoundError } from "../lib/errors";
|
|
4
|
-
import { permissions } from "../permissions";
|
|
5
|
-
|
|
6
|
-
export interface ConvertQuantityInput {
|
|
7
|
-
quantity: number;
|
|
8
|
-
sourceUnitSymbol: string;
|
|
9
|
-
targetUnitSymbol: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Function: convertQuantity
|
|
14
|
-
*
|
|
15
|
-
* Converts a quantity from one unit of measure to another within the same category.
|
|
16
|
-
* Units are identified by their symbol (e.g., "kg", "lb", "g").
|
|
17
|
-
* The conversion uses each unit's conversion factor relative to the category's reference unit.
|
|
18
|
-
* Result is rounded to the target unit's precision setting.
|
|
19
|
-
*/
|
|
20
|
-
export const convertQuantity = defineCommand(
|
|
21
|
-
permissions.convertQuantity,
|
|
22
|
-
async (db: DB, input: ConvertQuantityInput) => {
|
|
23
|
-
// 1. Validate source unit exists
|
|
24
|
-
const sourceUnit = await db
|
|
25
|
-
.selectFrom("Unit")
|
|
26
|
-
.selectAll()
|
|
27
|
-
.where("symbol", "=", input.sourceUnitSymbol)
|
|
28
|
-
.executeTakeFirst();
|
|
29
|
-
|
|
30
|
-
if (!sourceUnit) {
|
|
31
|
-
throw new UnitNotFoundError(input.sourceUnitSymbol);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 2. Validate target unit exists
|
|
35
|
-
const targetUnit = await db
|
|
36
|
-
.selectFrom("Unit")
|
|
37
|
-
.selectAll()
|
|
38
|
-
.where("symbol", "=", input.targetUnitSymbol)
|
|
39
|
-
.executeTakeFirst();
|
|
40
|
-
|
|
41
|
-
if (!targetUnit) {
|
|
42
|
-
throw new UnitNotFoundError(input.targetUnitSymbol);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 3. Validate both units are active
|
|
46
|
-
if (!sourceUnit.isActive) {
|
|
47
|
-
throw new InactiveUnitError(input.sourceUnitSymbol);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!targetUnit.isActive) {
|
|
51
|
-
throw new InactiveUnitError(input.targetUnitSymbol);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// 4. Validate units belong to the same category
|
|
55
|
-
if (sourceUnit.categoryId !== targetUnit.categoryId) {
|
|
56
|
-
throw new IncompatibleUnitsError(input.sourceUnitSymbol, input.targetUnitSymbol);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// 5. Perform conversion
|
|
60
|
-
// Formula: result = quantity * sourceConversionFactor / targetConversionFactor
|
|
61
|
-
const rawResult = (input.quantity * sourceUnit.conversionFactor) / targetUnit.conversionFactor;
|
|
62
|
-
|
|
63
|
-
// 6. Apply rounding to target unit's precision
|
|
64
|
-
const roundingFactor = Math.pow(10, targetUnit.roundingPrecision);
|
|
65
|
-
const convertedQuantity = Math.round(rawResult * roundingFactor) / roundingFactor;
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
convertedQuantity,
|
|
69
|
-
sourceUnit,
|
|
70
|
-
targetUnit,
|
|
71
|
-
};
|
|
72
|
-
},
|
|
73
|
-
);
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { createDomainError } from "../../shared/internal";
|
|
2
|
-
|
|
3
|
-
export const UoMCategoryNotFoundError = createDomainError(
|
|
4
|
-
"UoMCategoryNotFoundError",
|
|
5
|
-
"UOM_CATEGORY_NOT_FOUND",
|
|
6
|
-
(identifier: string) => `UoM category not found: ${identifier}`,
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export const UnitNotFoundError = createDomainError(
|
|
10
|
-
"UnitNotFoundError",
|
|
11
|
-
"UNIT_NOT_FOUND",
|
|
12
|
-
(symbol: string) => `Unit not found: ${symbol}`,
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
export const IncompatibleUnitsError = createDomainError(
|
|
16
|
-
"IncompatibleUnitsError",
|
|
17
|
-
"INCOMPATIBLE_UNITS",
|
|
18
|
-
(sourceSymbol: string, targetSymbol: string) =>
|
|
19
|
-
`Cannot convert between incompatible units: ${sourceSymbol} and ${targetSymbol} belong to different categories`,
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
export const InactiveUnitError = createDomainError(
|
|
23
|
-
"InactiveUnitError",
|
|
24
|
-
"INACTIVE_UNIT",
|
|
25
|
-
(symbol: string) => `Unit is inactive: ${symbol}`,
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
export const CurrencyNotFoundError = createDomainError(
|
|
29
|
-
"CurrencyNotFoundError",
|
|
30
|
-
"CURRENCY_NOT_FOUND",
|
|
31
|
-
(code: string) => `Currency not found: ${code}`,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
export const InactiveCurrencyError = createDomainError(
|
|
35
|
-
"InactiveCurrencyError",
|
|
36
|
-
"INACTIVE_CURRENCY",
|
|
37
|
-
(code: string) => `Currency is inactive: ${code}`,
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
export const ExchangeRateNotFoundError = createDomainError(
|
|
41
|
-
"ExchangeRateNotFoundError",
|
|
42
|
-
"EXCHANGE_RATE_NOT_FOUND",
|
|
43
|
-
(sourceCode: string, targetCode: string, date: string) =>
|
|
44
|
-
`No exchange rate found for ${sourceCode} to ${targetCode} on or before ${date}`,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
export const CannotDeactivateReferenceUnitError = createDomainError(
|
|
48
|
-
"CannotDeactivateReferenceUnitError",
|
|
49
|
-
"CANNOT_DEACTIVATE_REFERENCE_UNIT",
|
|
50
|
-
(unitId: string) => `Cannot deactivate reference unit: ${unitId}. Change reference unit first.`,
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
export const CategoryNotActiveError = createDomainError(
|
|
54
|
-
"CategoryNotActiveError",
|
|
55
|
-
"CATEGORY_NOT_ACTIVE",
|
|
56
|
-
(categoryId: string) => `Category is not active: ${categoryId}`,
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
export const DuplicateUnitSymbolError = createDomainError(
|
|
60
|
-
"DuplicateUnitSymbolError",
|
|
61
|
-
"DUPLICATE_UNIT_SYMBOL",
|
|
62
|
-
(symbol: string, categoryId: string) =>
|
|
63
|
-
`Unit with symbol "${symbol}" already exists in category ${categoryId}`,
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
export const InvalidConversionFactorError = createDomainError(
|
|
67
|
-
"InvalidConversionFactorError",
|
|
68
|
-
"INVALID_CONVERSION_FACTOR",
|
|
69
|
-
(factor: number) => `Conversion factor must be positive: ${factor}`,
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
export const InvalidRoundingPrecisionError = createDomainError(
|
|
73
|
-
"InvalidRoundingPrecisionError",
|
|
74
|
-
"INVALID_ROUNDING_PRECISION",
|
|
75
|
-
(precision: number) => `Rounding precision must be non-negative: ${precision}`,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
export const DuplicateCategoryNameError = createDomainError(
|
|
79
|
-
"DuplicateCategoryNameError",
|
|
80
|
-
"DUPLICATE_CATEGORY_NAME",
|
|
81
|
-
(name: string) => `Category with name "${name}" already exists`,
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
export const CategoryHasActiveUnitsError = createDomainError(
|
|
85
|
-
"CategoryHasActiveUnitsError",
|
|
86
|
-
"CATEGORY_HAS_ACTIVE_UNITS",
|
|
87
|
-
(categoryId: string) => `Cannot deactivate category ${categoryId}: has active units`,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
export const UnitNotInCategoryError = createDomainError(
|
|
91
|
-
"UnitNotInCategoryError",
|
|
92
|
-
"UNIT_NOT_IN_CATEGORY",
|
|
93
|
-
(unitId: string, categoryId: string) =>
|
|
94
|
-
`Unit ${unitId} does not belong to category ${categoryId}`,
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
export const InvalidISOCodeError = createDomainError(
|
|
98
|
-
"InvalidISOCodeError",
|
|
99
|
-
"INVALID_ISO_CODE",
|
|
100
|
-
(code: string) => `Invalid ISO 4217 code: "${code}". Must be exactly 3 uppercase letters.`,
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
export const DuplicateCurrencyCodeError = createDomainError(
|
|
104
|
-
"DuplicateCurrencyCodeError",
|
|
105
|
-
"DUPLICATE_CURRENCY_CODE",
|
|
106
|
-
(code: string) => `Currency with code "${code}" already exists`,
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
export const InvalidDecimalPlacesError = createDomainError(
|
|
110
|
-
"InvalidDecimalPlacesError",
|
|
111
|
-
"INVALID_DECIMAL_PLACES",
|
|
112
|
-
(decimalPlaces: number) => `Decimal places must be between 0 and 4: ${decimalPlaces}`,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
export const CannotDeactivateBaseCurrencyError = createDomainError(
|
|
116
|
-
"CannotDeactivateBaseCurrencyError",
|
|
117
|
-
"CANNOT_DEACTIVATE_BASE_CURRENCY",
|
|
118
|
-
(currencyId: string) =>
|
|
119
|
-
`Cannot deactivate base currency: ${currencyId}. Change base currency first.`,
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
export const CannotSetInactiveAsBaseCurrencyError = createDomainError(
|
|
123
|
-
"CannotSetInactiveAsBaseCurrencyError",
|
|
124
|
-
"CANNOT_SET_INACTIVE_AS_BASE_CURRENCY",
|
|
125
|
-
(currencyId: string) => `Cannot set inactive currency as base: ${currencyId}. Activate it first.`,
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
export const SameCurrencyPairError = createDomainError(
|
|
129
|
-
"SameCurrencyPairError",
|
|
130
|
-
"SAME_CURRENCY_PAIR",
|
|
131
|
-
(currencyId: string) => `Source and target currency cannot be the same: ${currencyId}`,
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
export const InvalidExchangeRateError = createDomainError(
|
|
135
|
-
"InvalidExchangeRateError",
|
|
136
|
-
"INVALID_EXCHANGE_RATE",
|
|
137
|
-
(rate: number) => `Exchange rate must be positive: ${rate}`,
|
|
138
|
-
);
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { createDomainError } from "../../shared/internal";
|
|
2
|
-
|
|
3
|
-
export const UserNotFoundError = createDomainError(
|
|
4
|
-
"UserNotFoundError",
|
|
5
|
-
"USER_NOT_FOUND",
|
|
6
|
-
(userId: string) => `User not found: ${userId}`,
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export const UserAlreadyExistsError = createDomainError(
|
|
10
|
-
"UserAlreadyExistsError",
|
|
11
|
-
"USER_ALREADY_EXISTS",
|
|
12
|
-
(email: string) => `User with email "${email}" already exists`,
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
export const UserNotActiveError = createDomainError(
|
|
16
|
-
"UserNotActiveError",
|
|
17
|
-
"USER_NOT_ACTIVE",
|
|
18
|
-
(userId: string, status: string) => `User ${userId} is not active (current status: ${status})`,
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export const InvalidEmailError = createDomainError(
|
|
22
|
-
"InvalidEmailError",
|
|
23
|
-
"INVALID_EMAIL",
|
|
24
|
-
(email: string) => `Invalid email format: ${email}`,
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
export const MissingRequiredFieldError = createDomainError(
|
|
28
|
-
"MissingRequiredFieldError",
|
|
29
|
-
"MISSING_REQUIRED_FIELD",
|
|
30
|
-
(field: string) => `Missing required field: ${field}`,
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
export const InvalidStatusTransitionError = createDomainError(
|
|
34
|
-
"InvalidStatusTransitionError",
|
|
35
|
-
"INVALID_STATUS_TRANSITION",
|
|
36
|
-
(currentStatus: string, targetStatus: string) =>
|
|
37
|
-
`Invalid status transition from ${currentStatus} to ${targetStatus}`,
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
export const PermissionNotFoundError = createDomainError(
|
|
41
|
-
"PermissionNotFoundError",
|
|
42
|
-
"PERMISSION_NOT_FOUND",
|
|
43
|
-
(permissionId: string) => `Permission not found: ${permissionId}`,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
export const DuplicatePermissionKeyError = createDomainError(
|
|
47
|
-
"DuplicatePermissionKeyError",
|
|
48
|
-
"DUPLICATE_PERMISSION_KEY",
|
|
49
|
-
(key: string) => `Permission with key "${key}" already exists`,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
export const InvalidPermissionKeyFormatError = createDomainError(
|
|
53
|
-
"InvalidPermissionKeyFormatError",
|
|
54
|
-
"INVALID_PERMISSION_KEY_FORMAT",
|
|
55
|
-
(key: string) => `Invalid permission key format: "${key}". Expected format: resource:action`,
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
export const RoleNotFoundError = createDomainError(
|
|
59
|
-
"RoleNotFoundError",
|
|
60
|
-
"ROLE_NOT_FOUND",
|
|
61
|
-
(roleId: string) => `Role not found: ${roleId}`,
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
export const DuplicateRoleNameError = createDomainError(
|
|
65
|
-
"DuplicateRoleNameError",
|
|
66
|
-
"DUPLICATE_ROLE_NAME",
|
|
67
|
-
(name: string) => `Role with name "${name}" already exists`,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
export const AssignmentNotFoundError = createDomainError(
|
|
71
|
-
"AssignmentNotFoundError",
|
|
72
|
-
"ASSIGNMENT_NOT_FOUND",
|
|
73
|
-
(sourceType: string, sourceId: string, targetType: string, targetId: string) =>
|
|
74
|
-
`Assignment not found: ${sourceType} ${sourceId} -> ${targetType} ${targetId}`,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
export const InvalidEventTypeError = createDomainError(
|
|
78
|
-
"InvalidEventTypeError",
|
|
79
|
-
"INVALID_EVENT_TYPE",
|
|
80
|
-
(eventType: string) => `Invalid event type: ${eventType}`,
|
|
81
|
-
);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/references/structure.md
RENAMED
|
File without changes
|
|
File without changes
|
/package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-detailview.md
RENAMED
|
File without changes
|
/package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-form.md
RENAMED
|
File without changes
|