@tailor-platform/erp-kit 0.2.0 → 0.2.2
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 +3 -26
- package/dist/cli.mjs +1613 -0
- package/package.json +14 -13
- package/schemas/app-compose/business-flow.yml +3 -0
- package/schemas/app-compose/story.yml +13 -1
- package/schemas/module/command.yml +9 -0
- package/schemas/module/module.yml +4 -0
- package/schemas/module/query.yml +9 -0
- package/skills/erp-kit-app-1-requirements/SKILL.md +8 -14
- package/skills/erp-kit-app-2-requirements-review/SKILL.md +102 -0
- package/skills/erp-kit-app-2-requirements-review/references/best-practices-check.md +66 -0
- package/skills/erp-kit-app-2-requirements-review/references/boundary-consistency-check.md +69 -0
- package/skills/erp-kit-app-2-requirements-review/references/requirements-report-format.md +25 -0
- package/skills/erp-kit-app-3-plan/SKILL.md +157 -0
- package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +107 -0
- package/skills/erp-kit-app-3-plan/references/screen-extraction.md +74 -0
- package/skills/erp-kit-app-3-plan/references/story-extraction.md +86 -0
- package/skills/erp-kit-app-4-plan-review/SKILL.md +177 -0
- package/skills/erp-kit-app-4-plan-review/references/actor-flow-parity.md +73 -0
- package/skills/erp-kit-app-4-plan-review/references/business-flow-story-parity.md +86 -0
- package/skills/erp-kit-app-4-plan-review/references/orphan-detection.md +69 -0
- package/skills/erp-kit-app-4-plan-review/references/parity-report-format.md +52 -0
- package/skills/erp-kit-app-4-plan-review/references/story-resolver-parity.md +83 -0
- package/skills/erp-kit-app-4-plan-review/references/story-screen-parity.md +73 -0
- package/skills/erp-kit-app-5-impl-backend/SKILL.md +105 -0
- package/skills/erp-kit-app-5-impl-backend/references/app-config.md +38 -0
- package/skills/erp-kit-app-5-impl-backend/references/module-wiring.md +48 -0
- package/skills/erp-kit-app-5-impl-backend/references/resolver-patterns.md +68 -0
- package/skills/erp-kit-app-6-impl-frontend/SKILL.md +74 -0
- package/skills/erp-kit-app-6-impl-frontend/references/pages.md +160 -0
- package/skills/erp-kit-app-7-impl-review/SKILL.md +176 -0
- package/skills/erp-kit-app-7-impl-review/references/impl-parity-report-format.md +52 -0
- package/skills/erp-kit-app-7-impl-review/references/module-wiring-parity.md +84 -0
- package/skills/erp-kit-app-7-impl-review/references/resolver-doc-code-parity.md +86 -0
- package/skills/erp-kit-app-7-impl-review/references/screen-doc-code-parity.md +86 -0
- package/skills/erp-kit-module-1-requirements/SKILL.md +126 -0
- package/skills/erp-kit-module-1-requirements/references/boundary-analysis.md +51 -0
- package/skills/erp-kit-module-1-requirements/references/erp-research.md +57 -0
- package/skills/erp-kit-module-1-requirements/references/feature-doc.md +61 -0
- package/skills/erp-kit-module-2-requirements-review/SKILL.md +112 -0
- package/skills/erp-kit-module-2-requirements-review/references/best-practices-check.md +79 -0
- package/skills/erp-kit-module-2-requirements-review/references/boundary-consistency-check.md +70 -0
- package/skills/erp-kit-module-2-requirements-review/references/requirements-report-format.md +25 -0
- package/skills/erp-kit-module-3-plan/SKILL.md +107 -0
- package/skills/erp-kit-module-3-plan/references/command-extraction.md +87 -0
- package/skills/erp-kit-module-3-plan/references/model-extraction.md +72 -0
- package/skills/erp-kit-module-3-plan/references/query-extraction.md +59 -0
- package/skills/erp-kit-module-4-plan-review/SKILL.md +158 -0
- package/skills/erp-kit-module-4-plan-review/references/command-model-consistency.md +46 -0
- package/skills/erp-kit-module-4-plan-review/references/feature-command-parity.md +97 -0
- package/skills/erp-kit-module-4-plan-review/references/feature-model-parity.md +47 -0
- package/skills/erp-kit-module-4-plan-review/references/feature-query-parity.md +70 -0
- package/skills/erp-kit-module-4-plan-review/references/parity-report-format.md +52 -0
- package/skills/erp-kit-module-5-impl/SKILL.md +118 -0
- package/skills/erp-kit-module-5-impl/references/command-impl.md +68 -0
- package/skills/erp-kit-module-5-impl/references/exports.md +10 -0
- package/skills/erp-kit-module-5-impl/references/model-impl.md +45 -0
- package/skills/erp-kit-module-5-impl/references/query-impl.md +53 -0
- package/skills/erp-kit-module-6-impl-review/SKILL.md +187 -0
- package/skills/erp-kit-module-6-impl-review/references/command-doc-code-parity.md +92 -0
- package/skills/erp-kit-module-6-impl-review/references/command-doc-test-parity.md +93 -0
- package/skills/erp-kit-module-6-impl-review/references/error-implementation-parity.md +95 -0
- package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/errors.md +1 -1
- package/skills/erp-kit-module-6-impl-review/references/impl-parity-report-format.md +52 -0
- package/skills/erp-kit-module-6-impl-review/references/model-doc-code-parity.md +80 -0
- package/skills/erp-kit-module-shared/SKILL.md +1 -1
- package/skills/erp-kit-module-shared/references/commands.md +1 -1
- package/skills/erp-kit-module-shared/references/errors.md +12 -9
- package/skills/erp-kit-module-shared/references/queries.md +109 -36
- package/skills/erp-kit-module-shared/references/testing.md +10 -0
- package/skills/erp-kit-update/SKILL.md +2 -2
- package/src/app.ts +1 -1
- package/src/commands/check.ts +1 -1
- package/src/commands/index.ts +16 -5
- package/src/commands/init.test.ts +22 -69
- package/src/commands/init.ts +28 -115
- package/src/commands/lib/distribute.test.ts +126 -0
- package/src/commands/lib/distribute.ts +129 -0
- package/src/commands/parse-doc-test-cases.ts +55 -0
- package/src/commands/scaffold.test.ts +74 -33
- package/src/commands/scaffold.ts +54 -18
- package/src/commands/sync-check.test.ts +173 -0
- package/src/commands/sync-check.ts +103 -2
- package/src/commands/update.test.ts +87 -0
- package/src/commands/update.ts +41 -0
- package/src/generator/generate-code.test.ts +23 -12
- package/src/generator/generate-code.ts +22 -16
- package/src/integration.test.ts +1 -1
- package/src/module.ts +20 -65
- package/src/modules/item-management/README.md +8 -0
- package/src/modules/item-management/command/activateItem.generated.ts +1 -1
- package/src/modules/item-management/command/activateItem.test.ts +12 -18
- package/src/modules/item-management/command/activateItem.ts +9 -5
- package/src/modules/item-management/command/assignItemToTaxonomy.generated.ts +1 -1
- package/src/modules/item-management/command/assignItemToTaxonomy.test.ts +10 -24
- package/src/modules/item-management/command/assignItemToTaxonomy.ts +19 -16
- package/src/modules/item-management/command/createItem.generated.ts +1 -1
- package/src/modules/item-management/command/createItem.test.ts +11 -11
- package/src/modules/item-management/command/createItem.ts +16 -7
- package/src/modules/item-management/command/createTaxonomyNode.generated.ts +1 -1
- package/src/modules/item-management/command/createTaxonomyNode.test.ts +9 -9
- package/src/modules/item-management/command/createTaxonomyNode.ts +33 -14
- package/src/modules/item-management/command/deactivateItem.generated.ts +1 -1
- package/src/modules/item-management/command/deactivateItem.test.ts +12 -18
- package/src/modules/item-management/command/deactivateItem.ts +9 -5
- package/src/modules/item-management/command/deleteItem.generated.ts +1 -1
- package/src/modules/item-management/command/deleteItem.test.ts +10 -16
- package/src/modules/item-management/command/deleteItem.ts +9 -5
- package/src/modules/item-management/command/deleteTaxonomyNode.generated.ts +1 -1
- package/src/modules/item-management/command/deleteTaxonomyNode.test.ts +10 -16
- package/src/modules/item-management/command/deleteTaxonomyNode.ts +22 -12
- package/src/modules/item-management/command/moveTaxonomyNode.generated.ts +1 -1
- package/src/modules/item-management/command/moveTaxonomyNode.test.ts +10 -10
- package/src/modules/item-management/command/moveTaxonomyNode.ts +63 -19
- package/src/modules/item-management/command/reactivateItem.generated.ts +1 -1
- package/src/modules/item-management/command/reactivateItem.test.ts +12 -18
- package/src/modules/item-management/command/reactivateItem.ts +9 -5
- package/src/modules/item-management/command/removeItemFromTaxonomy.generated.ts +1 -1
- package/src/modules/item-management/command/removeItemFromTaxonomy.test.ts +9 -16
- package/src/modules/item-management/command/removeItemFromTaxonomy.ts +11 -6
- package/src/modules/item-management/command/updateItem.generated.ts +1 -1
- package/src/modules/item-management/command/updateItem.test.ts +16 -16
- package/src/modules/item-management/command/updateItem.ts +11 -6
- package/src/modules/item-management/command/updateTaxonomyNode.generated.ts +1 -1
- package/src/modules/item-management/command/updateTaxonomyNode.test.ts +14 -20
- package/src/modules/item-management/command/updateTaxonomyNode.ts +9 -6
- package/src/modules/item-management/docs/commands/ActivateItem.md +8 -0
- package/src/modules/item-management/docs/commands/AssignItemToTaxonomy.md +7 -0
- package/src/modules/item-management/docs/commands/CreateItem.md +10 -0
- package/src/modules/item-management/docs/commands/CreateTaxonomyNode.md +9 -0
- package/src/modules/item-management/docs/commands/DeactivateItem.md +8 -0
- package/src/modules/item-management/docs/commands/DeleteItem.md +7 -0
- package/src/modules/item-management/docs/commands/DeleteTaxonomyNode.md +7 -0
- package/src/modules/item-management/docs/commands/MoveTaxonomyNode.md +10 -0
- package/src/modules/item-management/docs/commands/ReactivateItem.md +8 -0
- package/src/modules/item-management/docs/commands/RemoveItemFromTaxonomy.md +5 -0
- package/src/modules/item-management/docs/commands/UpdateItem.md +15 -0
- package/src/modules/item-management/docs/commands/UpdateTaxonomyNode.md +9 -0
- package/src/modules/item-management/docs/queries/CalculateNodeDepth.md +8 -0
- package/src/modules/item-management/docs/queries/CalculateSubtreeDepth.md +7 -0
- package/src/modules/item-management/docs/queries/DetectCircularReference.md +9 -0
- package/src/modules/item-management/docs/queries/GetItem.md +9 -0
- package/src/modules/item-management/docs/queries/GetItemTaxonomyAssignment.md +5 -0
- package/src/modules/item-management/docs/queries/GetTaxonomyNode.md +7 -0
- package/src/modules/item-management/docs/queries/GetTaxonomyNodeAssignments.md +5 -0
- package/src/modules/item-management/docs/queries/GetTaxonomyNodeChildren.md +6 -0
- package/src/modules/item-management/index.ts +0 -51
- package/src/modules/item-management/lib/errors.generated.ts +24 -24
- package/src/modules/item-management/lib/permissions.generated.ts +1 -1
- package/src/modules/item-management/lib/types.ts +1 -1
- package/src/modules/item-management/module.ts +1 -1
- package/src/modules/item-management/query/calculateNodeDepth.generated.ts +1 -1
- package/src/modules/item-management/query/calculateNodeDepth.test.ts +21 -6
- package/src/modules/item-management/query/calculateNodeDepth.ts +2 -2
- package/src/modules/item-management/query/calculateSubtreeDepth.generated.ts +1 -1
- package/src/modules/item-management/query/calculateSubtreeDepth.test.ts +17 -5
- package/src/modules/item-management/query/calculateSubtreeDepth.ts +2 -2
- package/src/modules/item-management/query/detectCircularReference.generated.ts +1 -1
- package/src/modules/item-management/query/detectCircularReference.test.ts +25 -7
- package/src/modules/item-management/query/detectCircularReference.ts +4 -4
- package/src/modules/item-management/query/getItem.generated.ts +1 -1
- package/src/modules/item-management/query/getItem.test.ts +25 -7
- package/src/modules/item-management/query/getItem.ts +2 -2
- package/src/modules/item-management/query/getItemTaxonomyAssignment.generated.ts +1 -1
- package/src/modules/item-management/query/getItemTaxonomyAssignment.test.ts +9 -3
- package/src/modules/item-management/query/getItemTaxonomyAssignment.ts +2 -2
- package/src/modules/item-management/query/getTaxonomyNode.generated.ts +1 -1
- package/src/modules/item-management/query/getTaxonomyNode.test.ts +17 -5
- package/src/modules/item-management/query/getTaxonomyNode.ts +2 -2
- package/src/modules/item-management/query/getTaxonomyNodeAssignments.generated.ts +1 -1
- package/src/modules/item-management/query/getTaxonomyNodeAssignments.test.ts +9 -3
- package/src/modules/item-management/query/getTaxonomyNodeAssignments.ts +2 -2
- package/src/modules/item-management/query/getTaxonomyNodeChildren.generated.ts +1 -1
- package/src/modules/item-management/query/getTaxonomyNodeChildren.test.ts +13 -4
- package/src/modules/item-management/query/getTaxonomyNodeChildren.ts +2 -2
- package/src/modules/item-management/tailor.config.ts +6 -4
- package/src/modules/item-management/tailor.d.ts +13 -0
- package/src/modules/primitives/README.md +8 -0
- package/src/modules/primitives/command/activateCategory.generated.ts +1 -1
- package/src/modules/primitives/command/activateCategory.test.ts +8 -18
- package/src/modules/primitives/command/activateCategory.ts +9 -5
- package/src/modules/primitives/command/activateCurrency.generated.ts +1 -1
- package/src/modules/primitives/command/activateCurrency.test.ts +8 -18
- package/src/modules/primitives/command/activateCurrency.ts +9 -5
- package/src/modules/primitives/command/activateUnit.generated.ts +1 -1
- package/src/modules/primitives/command/activateUnit.test.ts +8 -15
- package/src/modules/primitives/command/activateUnit.ts +9 -5
- package/src/modules/primitives/command/createCategory.generated.ts +1 -1
- package/src/modules/primitives/command/createCategory.test.ts +29 -44
- package/src/modules/primitives/command/createCategory.ts +9 -5
- package/src/modules/primitives/command/createCurrency.generated.ts +1 -1
- package/src/modules/primitives/command/createCurrency.test.ts +53 -78
- package/src/modules/primitives/command/createCurrency.ts +9 -6
- package/src/modules/primitives/command/createExchangeRate.generated.ts +1 -1
- package/src/modules/primitives/command/createExchangeRate.test.ts +59 -97
- package/src/modules/primitives/command/createExchangeRate.ts +13 -7
- package/src/modules/primitives/command/createUnit.generated.ts +1 -1
- package/src/modules/primitives/command/createUnit.test.ts +59 -90
- package/src/modules/primitives/command/createUnit.ts +9 -6
- package/src/modules/primitives/command/deactivateCategory.generated.ts +1 -1
- package/src/modules/primitives/command/deactivateCategory.test.ts +15 -33
- package/src/modules/primitives/command/deactivateCategory.ts +9 -5
- package/src/modules/primitives/command/deactivateCurrency.generated.ts +1 -1
- package/src/modules/primitives/command/deactivateCurrency.test.ts +12 -26
- package/src/modules/primitives/command/deactivateCurrency.ts +9 -5
- package/src/modules/primitives/command/deactivateUnit.generated.ts +1 -1
- package/src/modules/primitives/command/deactivateUnit.test.ts +15 -30
- package/src/modules/primitives/command/deactivateUnit.ts +14 -7
- package/src/modules/primitives/command/setBaseCurrency.generated.ts +1 -1
- package/src/modules/primitives/command/setBaseCurrency.test.ts +18 -40
- package/src/modules/primitives/command/setBaseCurrency.ts +15 -7
- package/src/modules/primitives/command/setReferenceUnit.generated.ts +1 -1
- package/src/modules/primitives/command/setReferenceUnit.test.ts +22 -44
- package/src/modules/primitives/command/setReferenceUnit.ts +21 -9
- package/src/modules/primitives/docs/commands/ActivateCategory.md +6 -0
- package/src/modules/primitives/docs/commands/ActivateCurrency.md +6 -0
- package/src/modules/primitives/docs/commands/ActivateUnit.md +6 -0
- package/src/modules/primitives/docs/commands/CreateCategory.md +6 -0
- package/src/modules/primitives/docs/commands/CreateCurrency.md +10 -0
- package/src/modules/primitives/docs/commands/CreateExchangeRate.md +11 -0
- package/src/modules/primitives/docs/commands/CreateUnit.md +10 -0
- package/src/modules/primitives/docs/commands/DeactivateCategory.md +7 -0
- package/src/modules/primitives/docs/commands/DeactivateCurrency.md +7 -0
- package/src/modules/primitives/docs/commands/DeactivateUnit.md +7 -0
- package/src/modules/primitives/docs/commands/SetBaseCurrency.md +7 -0
- package/src/modules/primitives/docs/commands/SetReferenceUnit.md +7 -0
- package/src/modules/primitives/docs/queries/ConvertAmount.md +14 -0
- package/src/modules/primitives/docs/queries/ConvertQuantity.md +13 -0
- package/src/modules/primitives/docs/queries/GetBaseCurrency.md +5 -0
- package/src/modules/primitives/docs/queries/GetCurrency.md +7 -0
- package/src/modules/primitives/docs/queries/GetUnit.md +7 -0
- package/src/modules/primitives/docs/queries/GetUoMCategory.md +7 -0
- package/src/modules/primitives/docs/queries/ListUnitsByCategory.md +15 -5
- package/src/modules/primitives/index.ts +0 -49
- package/src/modules/primitives/lib/errors.generated.ts +23 -23
- package/src/modules/primitives/lib/permissions.generated.ts +1 -1
- package/src/modules/primitives/lib/types.ts +1 -1
- package/src/modules/primitives/module.ts +1 -1
- package/src/modules/primitives/query/convertAmount.generated.ts +1 -1
- package/src/modules/primitives/query/convertAmount.test.ts +110 -77
- package/src/modules/primitives/query/convertAmount.ts +61 -47
- package/src/modules/primitives/query/convertQuantity.generated.ts +1 -1
- package/src/modules/primitives/query/convertQuantity.test.ts +99 -69
- package/src/modules/primitives/query/convertQuantity.ts +12 -10
- package/src/modules/primitives/query/getBaseCurrency.generated.ts +1 -1
- package/src/modules/primitives/query/getBaseCurrency.test.ts +10 -4
- package/src/modules/primitives/query/getBaseCurrency.ts +2 -2
- package/src/modules/primitives/query/getCurrency.generated.ts +1 -1
- package/src/modules/primitives/query/getCurrency.test.ts +17 -5
- package/src/modules/primitives/query/getCurrency.ts +2 -2
- package/src/modules/primitives/query/getUnit.generated.ts +1 -1
- package/src/modules/primitives/query/getUnit.test.ts +17 -5
- package/src/modules/primitives/query/getUnit.ts +2 -2
- package/src/modules/primitives/query/getUoMCategory.generated.ts +1 -1
- package/src/modules/primitives/query/getUoMCategory.test.ts +17 -5
- package/src/modules/primitives/query/getUoMCategory.ts +2 -2
- package/src/modules/primitives/query/listUnitsByCategory.generated.ts +1 -1
- package/src/modules/primitives/query/listUnitsByCategory.test.ts +80 -0
- package/src/modules/primitives/query/listUnitsByCategory.ts +19 -3
- package/src/modules/primitives/tailor.config.ts +6 -4
- package/src/modules/primitives/tailor.d.ts +13 -0
- package/src/modules/product-management/README.md +52 -0
- package/src/modules/product-management/command/activateProduct.generated.ts +6 -0
- package/src/modules/product-management/command/activateProduct.test.ts +40 -0
- package/src/modules/product-management/command/activateProduct.ts +42 -0
- package/src/modules/product-management/command/assignProductToCategory.generated.ts +6 -0
- package/src/modules/product-management/command/assignProductToCategory.test.ts +90 -0
- package/src/modules/product-management/command/assignProductToCategory.ts +62 -0
- package/src/modules/product-management/command/createProduct.generated.ts +6 -0
- package/src/modules/product-management/command/createProduct.test.ts +149 -0
- package/src/modules/product-management/command/createProduct.ts +73 -0
- package/src/modules/product-management/command/createProductAttribute.generated.ts +6 -0
- package/src/modules/product-management/command/createProductAttribute.test.ts +70 -0
- package/src/modules/product-management/command/createProductAttribute.ts +53 -0
- package/src/modules/product-management/command/createProductAttributeValue.generated.ts +6 -0
- package/src/modules/product-management/command/createProductAttributeValue.test.ts +68 -0
- package/src/modules/product-management/command/createProductAttributeValue.ts +63 -0
- package/src/modules/product-management/command/createProductCategory.generated.ts +6 -0
- package/src/modules/product-management/command/createProductCategory.test.ts +135 -0
- package/src/modules/product-management/command/createProductCategory.ts +82 -0
- package/src/modules/product-management/command/deactivateProduct.generated.ts +6 -0
- package/src/modules/product-management/command/deactivateProduct.test.ts +40 -0
- package/src/modules/product-management/command/deactivateProduct.ts +42 -0
- package/src/modules/product-management/command/deleteProduct.generated.ts +6 -0
- package/src/modules/product-management/command/deleteProduct.test.ts +42 -0
- package/src/modules/product-management/command/deleteProduct.ts +42 -0
- package/src/modules/product-management/command/deleteProductAttribute.generated.ts +6 -0
- package/src/modules/product-management/command/deleteProductAttribute.test.ts +49 -0
- package/src/modules/product-management/command/deleteProductAttribute.ts +45 -0
- package/src/modules/product-management/command/deleteProductAttributeValue.generated.ts +6 -0
- package/src/modules/product-management/command/deleteProductAttributeValue.test.ts +71 -0
- package/src/modules/product-management/command/deleteProductAttributeValue.ts +68 -0
- package/src/modules/product-management/command/deleteProductCategory.generated.ts +6 -0
- package/src/modules/product-management/command/deleteProductCategory.test.ts +74 -0
- package/src/modules/product-management/command/deleteProductCategory.ts +53 -0
- package/src/modules/product-management/command/generateVariants.generated.ts +6 -0
- package/src/modules/product-management/command/generateVariants.test.ts +365 -0
- package/src/modules/product-management/command/generateVariants.ts +168 -0
- package/src/modules/product-management/command/moveProductCategory.generated.ts +6 -0
- package/src/modules/product-management/command/moveProductCategory.test.ts +170 -0
- package/src/modules/product-management/command/moveProductCategory.ts +124 -0
- package/src/modules/product-management/command/reactivateProduct.generated.ts +6 -0
- package/src/modules/product-management/command/reactivateProduct.test.ts +40 -0
- package/src/modules/product-management/command/reactivateProduct.ts +42 -0
- package/src/modules/product-management/command/removeProductFromCategory.generated.ts +6 -0
- package/src/modules/product-management/command/removeProductFromCategory.test.ts +42 -0
- package/src/modules/product-management/command/removeProductFromCategory.ts +32 -0
- package/src/modules/product-management/command/setProductAttributeAssignment.generated.ts +6 -0
- package/src/modules/product-management/command/setProductAttributeAssignment.test.ts +206 -0
- package/src/modules/product-management/command/setProductAttributeAssignment.ts +102 -0
- package/src/modules/product-management/command/updateProduct.generated.ts +6 -0
- package/src/modules/product-management/command/updateProduct.test.ts +168 -0
- package/src/modules/product-management/command/updateProduct.ts +95 -0
- package/src/modules/product-management/command/updateProductAttribute.generated.ts +6 -0
- package/src/modules/product-management/command/updateProductAttribute.test.ts +101 -0
- package/src/modules/product-management/command/updateProductAttribute.ts +68 -0
- package/src/modules/product-management/command/updateProductAttributeValue.generated.ts +6 -0
- package/src/modules/product-management/command/updateProductAttributeValue.test.ts +80 -0
- package/src/modules/product-management/command/updateProductAttributeValue.ts +58 -0
- package/src/modules/product-management/command/updateProductCategory.generated.ts +6 -0
- package/src/modules/product-management/command/updateProductCategory.test.ts +80 -0
- package/src/modules/product-management/command/updateProductCategory.ts +66 -0
- package/src/modules/product-management/db/product.ts +47 -0
- package/src/modules/product-management/db/productAttribute.ts +26 -0
- package/src/modules/product-management/db/productAttributeAssignment.ts +58 -0
- package/src/modules/product-management/db/productAttributeValue.ts +39 -0
- package/src/modules/product-management/db/productCategory.ts +34 -0
- package/src/modules/product-management/db/productCategoryAssignment.ts +49 -0
- package/src/modules/product-management/db/productVariant.ts +52 -0
- package/src/modules/product-management/docs/commands/ActivateProduct.md +39 -0
- package/src/modules/product-management/docs/commands/AssignProductToCategory.md +43 -0
- package/src/modules/product-management/docs/commands/CreateProduct.md +48 -0
- package/src/modules/product-management/docs/commands/CreateProductAttribute.md +39 -0
- package/src/modules/product-management/docs/commands/CreateProductAttributeValue.md +42 -0
- package/src/modules/product-management/docs/commands/CreateProductCategory.md +54 -0
- package/src/modules/product-management/docs/commands/DeactivateProduct.md +39 -0
- package/src/modules/product-management/docs/commands/DeleteProduct.md +42 -0
- package/src/modules/product-management/docs/commands/DeleteProductAttribute.md +39 -0
- package/src/modules/product-management/docs/commands/DeleteProductAttributeValue.md +42 -0
- package/src/modules/product-management/docs/commands/DeleteProductCategory.md +43 -0
- package/src/modules/product-management/docs/commands/GenerateVariants.md +68 -0
- package/src/modules/product-management/docs/commands/MoveProductCategory.md +54 -0
- package/src/modules/product-management/docs/commands/ReactivateProduct.md +38 -0
- package/src/modules/product-management/docs/commands/RemoveProductFromCategory.md +34 -0
- package/src/modules/product-management/docs/commands/SetProductAttributeAssignment.md +62 -0
- package/src/modules/product-management/docs/commands/UpdateProduct.md +61 -0
- package/src/modules/product-management/docs/commands/UpdateProductAttribute.md +46 -0
- package/src/modules/product-management/docs/commands/UpdateProductAttributeValue.md +47 -0
- package/src/modules/product-management/docs/commands/UpdateProductCategory.md +46 -0
- package/src/modules/product-management/docs/features/attribute-management.md +48 -0
- package/src/modules/product-management/docs/features/product-category.md +71 -0
- package/src/modules/product-management/docs/features/product-lifecycle.md +66 -0
- package/src/modules/product-management/docs/features/variant-generation.md +77 -0
- package/src/modules/product-management/docs/models/Product.md +58 -0
- package/src/modules/product-management/docs/models/ProductAttribute.md +37 -0
- package/src/modules/product-management/docs/models/ProductAttributeAssignment.md +41 -0
- package/src/modules/product-management/docs/models/ProductAttributeValue.md +40 -0
- package/src/modules/product-management/docs/models/ProductCategory.md +46 -0
- package/src/modules/product-management/docs/models/ProductCategoryAssignment.md +37 -0
- package/src/modules/product-management/docs/models/ProductVariant.md +41 -0
- package/src/modules/product-management/docs/queries/CalculateCategoryDepth.md +47 -0
- package/src/modules/product-management/docs/queries/DetectCategoryCircularReference.md +51 -0
- package/src/modules/product-management/docs/queries/GetProduct.md +42 -0
- package/src/modules/product-management/docs/queries/GetProductAttribute.md +42 -0
- package/src/modules/product-management/docs/queries/GetProductAttributeAssignment.md +34 -0
- package/src/modules/product-management/docs/queries/GetProductAttributeValue.md +40 -0
- package/src/modules/product-management/docs/queries/GetProductCategory.md +42 -0
- package/src/modules/product-management/docs/queries/GetProductCategoryAssignment.md +34 -0
- package/src/modules/product-management/docs/queries/GetProductVariant.md +41 -0
- package/src/modules/product-management/docs/queries/ListAttributeAssignmentsByAttribute.md +34 -0
- package/src/modules/product-management/docs/queries/ListCategoryAssignmentsByProduct.md +35 -0
- package/src/modules/product-management/docs/queries/ListProductAttributeAssignments.md +34 -0
- package/src/modules/product-management/docs/queries/ListProductAttributeValues.md +36 -0
- package/src/modules/product-management/docs/queries/ListProductCategoryAssignments.md +34 -0
- package/src/modules/product-management/docs/queries/ListProductCategoryChildren.md +34 -0
- package/src/modules/product-management/docs/queries/ListProductVariants.md +34 -0
- package/src/modules/product-management/generated/enums.ts +9 -0
- package/src/modules/product-management/generated/kysely-tailordb.ts +100 -0
- package/src/modules/product-management/index.ts +2 -0
- package/src/modules/product-management/lib/_db_deps.ts +17 -0
- package/src/modules/product-management/lib/errors.generated.ts +152 -0
- package/src/modules/product-management/lib/permissions.generated.ts +25 -0
- package/src/modules/product-management/lib/types.ts +51 -0
- package/src/modules/product-management/module.ts +201 -0
- package/src/modules/product-management/query/calculateCategoryDepth.generated.ts +5 -0
- package/src/modules/product-management/query/calculateCategoryDepth.test.ts +72 -0
- package/src/modules/product-management/query/calculateCategoryDepth.ts +37 -0
- package/src/modules/product-management/query/detectCategoryCircularReference.generated.ts +5 -0
- package/src/modules/product-management/query/detectCategoryCircularReference.test.ts +72 -0
- package/src/modules/product-management/query/detectCategoryCircularReference.ts +44 -0
- package/src/modules/product-management/query/getProduct.generated.ts +5 -0
- package/src/modules/product-management/query/getProduct.test.ts +59 -0
- package/src/modules/product-management/query/getProduct.ts +18 -0
- package/src/modules/product-management/query/getProductAttribute.generated.ts +5 -0
- package/src/modules/product-management/query/getProductAttribute.test.ts +59 -0
- package/src/modules/product-management/query/getProductAttribute.ts +18 -0
- package/src/modules/product-management/query/getProductAttributeAssignment.generated.ts +5 -0
- package/src/modules/product-management/query/getProductAttributeAssignment.test.ts +37 -0
- package/src/modules/product-management/query/getProductAttributeAssignment.ts +18 -0
- package/src/modules/product-management/query/getProductAttributeValue.generated.ts +5 -0
- package/src/modules/product-management/query/getProductAttributeValue.test.ts +31 -0
- package/src/modules/product-management/query/getProductAttributeValue.ts +16 -0
- package/src/modules/product-management/query/getProductCategory.generated.ts +5 -0
- package/src/modules/product-management/query/getProductCategory.test.ts +59 -0
- package/src/modules/product-management/query/getProductCategory.ts +18 -0
- package/src/modules/product-management/query/getProductCategoryAssignment.generated.ts +5 -0
- package/src/modules/product-management/query/getProductCategoryAssignment.test.ts +37 -0
- package/src/modules/product-management/query/getProductCategoryAssignment.ts +18 -0
- package/src/modules/product-management/query/getProductVariant.generated.ts +5 -0
- package/src/modules/product-management/query/getProductVariant.test.ts +43 -0
- package/src/modules/product-management/query/getProductVariant.ts +20 -0
- package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.generated.ts +5 -0
- package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.test.ts +31 -0
- package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.ts +16 -0
- package/src/modules/product-management/query/listCategoryAssignmentsByProduct.generated.ts +5 -0
- package/src/modules/product-management/query/listCategoryAssignmentsByProduct.test.ts +31 -0
- package/src/modules/product-management/query/listCategoryAssignmentsByProduct.ts +16 -0
- package/src/modules/product-management/query/listProductAttributeAssignments.generated.ts +5 -0
- package/src/modules/product-management/query/listProductAttributeAssignments.test.ts +31 -0
- package/src/modules/product-management/query/listProductAttributeAssignments.ts +16 -0
- package/src/modules/product-management/query/listProductAttributeValues.generated.ts +5 -0
- package/src/modules/product-management/query/listProductAttributeValues.test.ts +31 -0
- package/src/modules/product-management/query/listProductAttributeValues.ts +17 -0
- package/src/modules/product-management/query/listProductCategoryAssignments.generated.ts +5 -0
- package/src/modules/product-management/query/listProductCategoryAssignments.test.ts +31 -0
- package/src/modules/product-management/query/listProductCategoryAssignments.ts +16 -0
- package/src/modules/product-management/query/listProductCategoryChildren.generated.ts +5 -0
- package/src/modules/product-management/query/listProductCategoryChildren.test.ts +31 -0
- package/src/modules/product-management/query/listProductCategoryChildren.ts +16 -0
- package/src/modules/product-management/query/listProductVariants.generated.ts +5 -0
- package/src/modules/product-management/query/listProductVariants.test.ts +31 -0
- package/src/modules/product-management/query/listProductVariants.ts +16 -0
- package/src/modules/product-management/tailor.config.ts +13 -0
- package/src/modules/product-management/tailor.d.ts +13 -0
- package/src/modules/product-management/testing/fixtures.ts +151 -0
- package/src/modules/user-management/README.md +9 -3
- package/src/modules/user-management/command/activateUser.generated.ts +1 -1
- package/src/modules/user-management/command/activateUser.test.ts +12 -65
- package/src/modules/user-management/command/activateUser.ts +5 -20
- package/src/modules/user-management/command/assignPermissionToRole.generated.ts +1 -1
- package/src/modules/user-management/command/assignPermissionToRole.test.ts +25 -60
- package/src/modules/user-management/command/assignPermissionToRole.ts +5 -24
- package/src/modules/user-management/command/assignRoleToUser.generated.ts +1 -1
- package/src/modules/user-management/command/assignRoleToUser.test.ts +35 -87
- package/src/modules/user-management/command/assignRoleToUser.ts +5 -24
- package/src/modules/user-management/command/createPermission.generated.ts +1 -1
- package/src/modules/user-management/command/createPermission.test.ts +23 -33
- package/src/modules/user-management/command/createPermission.ts +4 -5
- package/src/modules/user-management/command/createRole.generated.ts +1 -1
- package/src/modules/user-management/command/createRole.test.ts +17 -27
- package/src/modules/user-management/command/createRole.ts +4 -5
- package/src/modules/user-management/command/createUser.generated.ts +1 -1
- package/src/modules/user-management/command/createUser.test.ts +31 -118
- package/src/modules/user-management/command/createUser.ts +7 -25
- package/src/modules/user-management/command/deactivateUser.generated.ts +1 -1
- package/src/modules/user-management/command/deactivateUser.test.ts +12 -65
- package/src/modules/user-management/command/deactivateUser.ts +6 -21
- package/src/modules/user-management/command/reactivateUser.generated.ts +1 -1
- package/src/modules/user-management/command/reactivateUser.test.ts +13 -66
- package/src/modules/user-management/command/reactivateUser.ts +5 -20
- package/src/modules/user-management/command/revokePermissionFromRole.generated.ts +1 -1
- package/src/modules/user-management/command/revokePermissionFromRole.test.ts +24 -62
- package/src/modules/user-management/command/revokePermissionFromRole.ts +5 -24
- package/src/modules/user-management/command/revokeRoleFromUser.generated.ts +1 -1
- package/src/modules/user-management/command/revokeRoleFromUser.test.ts +24 -60
- package/src/modules/user-management/command/revokeRoleFromUser.ts +5 -24
- package/src/modules/user-management/docs/commands/ActivateUser.md +7 -0
- package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +7 -0
- package/src/modules/user-management/docs/commands/AssignRoleToUser.md +9 -0
- package/src/modules/user-management/docs/commands/CreatePermission.md +12 -0
- package/src/modules/user-management/docs/commands/CreateRole.md +9 -0
- package/src/modules/user-management/docs/commands/CreateUser.md +11 -0
- package/src/modules/user-management/docs/commands/DeactivateUser.md +7 -0
- package/src/modules/user-management/docs/commands/ReactivateUser.md +7 -0
- package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +7 -0
- package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +7 -0
- package/src/modules/user-management/index.ts +0 -30
- package/src/modules/user-management/lib/errors.generated.ts +14 -14
- package/src/modules/user-management/lib/permissions.generated.ts +1 -2
- package/src/modules/user-management/lib/recomputeUserPermissions.ts +4 -3
- package/src/modules/user-management/lib/types.ts +1 -1
- package/src/modules/user-management/module.ts +2 -7
- package/src/modules/user-management/tailor.config.ts +6 -4
- package/src/modules/user-management/tailor.d.ts +13 -0
- package/src/modules/user-management/testing/fixtures.ts +1 -20
- package/src/schemas.ts +1 -1
- package/src/{modules/shared → shared}/defineCommand.test.ts +23 -7
- package/src/{modules/shared → shared}/defineCommand.ts +19 -10
- package/src/{modules/shared/internal.ts → shared/index.ts} +9 -1
- package/src/shared/pagination.test.ts +43 -0
- package/src/shared/pagination.ts +22 -0
- package/src/{modules/shared → shared}/types.ts +13 -0
- package/src/{modules/testing → testing}/index.ts +14 -7
- package/src/testing.ts +1 -1
- package/src/util.ts +8 -0
- package/templates/config/license.config.json +4 -0
- package/templates/scaffold/app/backend/.env.example +1 -0
- package/templates/scaffold/app/backend/__dot__gitignore +4 -0
- package/templates/scaffold/app/backend/eslint.config.js +32 -0
- package/templates/scaffold/app/backend/package.json +31 -0
- package/templates/scaffold/app/backend/seed/data/AuditEvent.jsonl +0 -0
- package/templates/scaffold/app/backend/seed/data/Permission.jsonl +0 -0
- package/templates/scaffold/app/backend/seed/data/Permission.schema.ts +20 -0
- package/templates/scaffold/app/backend/seed/data/Role.jsonl +0 -0
- package/templates/scaffold/app/backend/seed/data/Role.schema.ts +20 -0
- package/templates/scaffold/app/backend/seed/data/RolePermission.jsonl +0 -0
- package/templates/scaffold/app/backend/seed/data/RolePermission.schema.ts +24 -0
- package/templates/scaffold/app/backend/seed/data/User.jsonl +1 -0
- package/templates/scaffold/app/backend/seed/data/User.schema.ts +20 -0
- package/templates/scaffold/app/backend/seed/data/UserRole.jsonl +0 -0
- package/templates/scaffold/app/backend/seed/data/UserRole.schema.ts +24 -0
- package/templates/scaffold/app/backend/seed/data/_User.jsonl +1 -0
- package/templates/scaffold/app/backend/seed/data/_User.schema.ts +30 -0
- package/templates/scaffold/app/backend/seed/exec.mjs +659 -0
- package/templates/scaffold/app/backend/src/executors/permissionCreated.ts +3 -0
- package/templates/scaffold/app/backend/src/executors/permissionDeleted.ts +3 -0
- package/templates/scaffold/app/backend/src/generated/kysely-tailordb.ts +83 -0
- package/templates/scaffold/app/backend/src/modules.ts +9 -0
- package/templates/scaffold/app/backend/src/resolvers/createUser.ts +46 -0
- package/templates/scaffold/app/backend/tailor.config.ts +68 -0
- package/templates/scaffold/app/backend/tailor.d.ts +15 -0
- package/templates/scaffold/app/backend/tsconfig.json +19 -0
- package/templates/scaffold/app/docs/actors/.gitkeep +0 -0
- package/templates/scaffold/app/docs/business-flow/.gitkeep +0 -0
- package/templates/scaffold/app/docs/resolver/.gitkeep +0 -0
- package/templates/scaffold/app/docs/screen/.gitkeep +0 -0
- package/templates/scaffold/app/frontend/.env.example +2 -0
- package/templates/scaffold/app/frontend/__dot__gitignore +3 -0
- package/templates/scaffold/app/frontend/components.json +23 -0
- package/templates/scaffold/app/frontend/eslint.config.js +48 -0
- package/templates/scaffold/app/frontend/index.html +13 -0
- package/templates/scaffold/app/frontend/package.json +53 -0
- package/templates/scaffold/app/frontend/scripts/generate-graphql.mjs +6 -0
- package/templates/scaffold/app/frontend/src/App.tsx +58 -0
- package/templates/scaffold/app/frontend/src/components/composed/empty-state.tsx +26 -0
- package/templates/scaffold/app/frontend/src/components/composed/error-fallback.tsx +28 -0
- package/templates/scaffold/app/frontend/src/components/composed/loading.tsx +13 -0
- package/templates/scaffold/app/frontend/src/components/ui/badge.tsx +39 -0
- package/templates/scaffold/app/frontend/src/components/ui/button.tsx +60 -0
- package/templates/scaffold/app/frontend/src/components/ui/card.tsx +75 -0
- package/templates/scaffold/app/frontend/src/components/ui/form.tsx +152 -0
- package/templates/scaffold/app/frontend/src/components/ui/input.tsx +21 -0
- package/templates/scaffold/app/frontend/src/components/ui/label.tsx +21 -0
- package/templates/scaffold/app/frontend/src/components/ui/spinner.tsx +16 -0
- package/templates/scaffold/app/frontend/src/components/ui/table.tsx +90 -0
- package/templates/scaffold/app/frontend/src/graphql/generated/graphql-env.d.ts +103 -0
- package/templates/scaffold/app/frontend/src/graphql/generated/schema.graphql +1235 -0
- package/templates/scaffold/app/frontend/src/graphql/index.ts +15 -0
- package/templates/scaffold/app/frontend/src/index.css +5 -0
- package/templates/scaffold/app/frontend/src/lib/auth-client.ts +17 -0
- package/templates/scaffold/app/frontend/src/lib/utils.ts +6 -0
- package/templates/scaffold/app/frontend/src/main.tsx +10 -0
- package/templates/scaffold/app/frontend/src/pages/page.tsx +20 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/page.tsx +19 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/profile/page.tsx +97 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/[id]/components/user-detail.tsx +58 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/[id]/page.tsx +51 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/components/users-table.tsx +101 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/create/components/create-user-form.tsx +99 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/create/page.tsx +19 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/page.tsx +61 -0
- package/templates/scaffold/app/frontend/src/providers/graphql-provider.tsx +21 -0
- package/templates/scaffold/app/frontend/tsconfig.app.json +35 -0
- package/templates/scaffold/app/frontend/tsconfig.json +16 -0
- package/templates/scaffold/app/frontend/tsconfig.node.json +23 -0
- package/templates/scaffold/app/frontend/vite.config.ts +23 -0
- package/templates/scaffold/module/command/.gitkeep +0 -0
- package/templates/scaffold/module/db/.gitkeep +0 -0
- package/templates/scaffold/module/executor/.gitkeep +0 -0
- package/templates/scaffold/module/generated/.gitkeep +0 -0
- package/templates/scaffold/module/index.ts +2 -0
- package/templates/scaffold/module/lib/errors.ts +1 -0
- package/templates/scaffold/module/lib/types.ts +4 -0
- package/templates/scaffold/module/module.ts +7 -0
- package/templates/scaffold/module/permissions.ts +3 -0
- package/templates/scaffold/module/query/.gitkeep +0 -0
- package/templates/scaffold/module/tailor.config.ts +13 -0
- package/templates/scaffold/module/testing/fixtures.ts +1 -0
- package/templates/workflows/erp-kit-check.yml +37 -0
- package/dist/cli.js +0 -1654
- package/skills/erp-kit-app-1-requirements/references/structure.md +0 -27
- package/skills/erp-kit-app-2-breakdown/SKILL.md +0 -95
- package/skills/erp-kit-app-2-breakdown/references/screen-detailview.md +0 -106
- package/skills/erp-kit-app-2-breakdown/references/screen-form.md +0 -139
- package/skills/erp-kit-app-2-breakdown/references/screen-listview.md +0 -153
- package/skills/erp-kit-app-2-breakdown/references/structure.md +0 -27
- package/skills/erp-kit-app-3-doc-review/SKILL.md +0 -116
- package/skills/erp-kit-app-3-doc-review/references/structure.md +0 -27
- package/skills/erp-kit-app-4-design/SKILL.md +0 -256
- package/skills/erp-kit-app-4-design/references/component.md +0 -50
- package/skills/erp-kit-app-4-design/references/screen-detailview.md +0 -106
- package/skills/erp-kit-app-4-design/references/screen-form.md +0 -139
- package/skills/erp-kit-app-4-design/references/screen-listview.md +0 -153
- package/skills/erp-kit-app-4-design/references/structure.md +0 -27
- package/skills/erp-kit-app-5-design-review/SKILL.md +0 -290
- package/skills/erp-kit-app-5-design-review/references/component.md +0 -50
- package/skills/erp-kit-app-5-design-review/references/screen-detailview.md +0 -106
- package/skills/erp-kit-app-5-design-review/references/screen-form.md +0 -139
- package/skills/erp-kit-app-5-design-review/references/screen-listview.md +0 -153
- package/skills/erp-kit-app-6-impl-spec/SKILL.md +0 -127
- package/skills/erp-kit-app-6-impl-spec/references/auth.md +0 -72
- package/skills/erp-kit-app-6-impl-spec/references/structure.md +0 -27
- package/skills/erp-kit-module-1-docs/SKILL.md +0 -111
- package/skills/erp-kit-module-2-feature-breakdown/SKILL.md +0 -76
- package/skills/erp-kit-module-3-doc-review/SKILL.md +0 -294
- package/skills/erp-kit-module-4-tdd/SKILL.md +0 -94
- package/skills/erp-kit-module-4-tdd/references/exports.md +0 -8
- package/skills/erp-kit-module-5-impl-review/SKILL.md +0 -410
- package/src/commands/scaffold-templates.ts +0 -65
- package/src/modules/shared/index.ts +0 -1
- package/src/modules/user-management/command/logAuditEvent.generated.ts +0 -6
- package/src/modules/user-management/command/logAuditEvent.test.ts +0 -187
- package/src/modules/user-management/command/logAuditEvent.ts +0 -56
- package/src/modules/user-management/db/auditEvent.ts +0 -47
- package/src/modules/user-management/docs/commands/LogAuditEvent.md +0 -37
- package/src/modules/user-management/docs/features/audit-trail.md +0 -80
- package/src/modules/user-management/docs/models/AuditEvent.md +0 -36
- /package/skills/{erp-kit-module-2-feature-breakdown → erp-kit-module-3-plan}/references/naming.md +0 -0
- /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/cross-module-dependency.md +0 -0
- /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/db-relations.md +0 -0
- /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/generated-code.md +0 -0
- /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/models.md +0 -0
- /package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/commands.md +0 -0
- /package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/testing.md +0 -0
- /package/src/modules/{product-management → audit}/.gitkeep +0 -0
- /package/src/{modules/shared → shared}/createContext.test.ts +0 -0
- /package/src/{modules/shared → shared}/createContext.ts +0 -0
- /package/src/{modules/shared → shared}/definePermissions.test.ts +0 -0
- /package/src/{modules/shared → shared}/definePermissions.ts +0 -0
- /package/src/{modules/shared → shared}/defineQuery.test.ts +0 -0
- /package/src/{modules/shared → shared}/defineQuery.ts +0 -0
- /package/src/{modules/shared → shared}/entityTypes.ts +0 -0
- /package/src/{modules/shared → shared}/errors.ts +0 -0
- /package/src/{modules/shared → shared}/requirePermission.test.ts +0 -0
- /package/src/{modules/shared → shared}/requirePermission.ts +0 -0
- /package/src/{modules/shared → shared}/result.ts +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @generated — do not edit
|
|
2
|
+
import { defineCommand } from "../../../shared";
|
|
3
|
+
import { permissions } from "../lib/permissions.generated";
|
|
4
|
+
import { run } from "./updateProductCategory";
|
|
5
|
+
|
|
6
|
+
export const updateProductCategory = defineCommand(permissions.updateProductCategory, run);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createMockDb } from "../../../testing/index";
|
|
3
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
4
|
+
import { baseRootCategory } from "../testing/fixtures";
|
|
5
|
+
import {
|
|
6
|
+
CategoryNotFoundError,
|
|
7
|
+
CodeImmutableError,
|
|
8
|
+
MissingRequiredFieldError,
|
|
9
|
+
} from "../lib/errors.generated";
|
|
10
|
+
import { run } from "./updateProductCategory";
|
|
11
|
+
|
|
12
|
+
describe("updateProductCategory", () => {
|
|
13
|
+
it("should return CategoryNotFoundError when category does not exist", async () => {
|
|
14
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
15
|
+
spies.select.mockReturnValueOnce(undefined);
|
|
16
|
+
const input = { id: "non-existent", name: "New Name" };
|
|
17
|
+
const result = await run(db, input);
|
|
18
|
+
expect(result.ok).toBe(false);
|
|
19
|
+
if (!result.ok) {
|
|
20
|
+
expect(result.error).toBeInstanceOf(CategoryNotFoundError);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should return CodeImmutableError when code is provided", async () => {
|
|
25
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
26
|
+
spies.select.mockReturnValueOnce(baseRootCategory);
|
|
27
|
+
const input = {
|
|
28
|
+
id: baseRootCategory.id,
|
|
29
|
+
code: "NEW-CODE",
|
|
30
|
+
};
|
|
31
|
+
const result = await run(db, input);
|
|
32
|
+
expect(result.ok).toBe(false);
|
|
33
|
+
if (!result.ok) {
|
|
34
|
+
expect(result.error).toBeInstanceOf(CodeImmutableError);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should return MissingRequiredFieldError when no fields are provided", async () => {
|
|
39
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
40
|
+
spies.select.mockReturnValueOnce(baseRootCategory);
|
|
41
|
+
const input = { id: baseRootCategory.id };
|
|
42
|
+
const result = await run(db, input);
|
|
43
|
+
expect(result.ok).toBe(false);
|
|
44
|
+
if (!result.ok) {
|
|
45
|
+
expect(result.error).toBeInstanceOf(MissingRequiredFieldError);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should pass custom fields through to update", async () => {
|
|
50
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
51
|
+
spies.select.mockReturnValueOnce(baseRootCategory);
|
|
52
|
+
const updatedCategory = { ...baseRootCategory, priority: 1, updatedAt: new Date() };
|
|
53
|
+
spies.update.mockReturnValueOnce(updatedCategory);
|
|
54
|
+
|
|
55
|
+
const result = await run(db, { id: baseRootCategory.id, priority: 1 });
|
|
56
|
+
expect(result.ok).toBe(true);
|
|
57
|
+
expect(spies.set).toHaveBeenCalledWith(
|
|
58
|
+
expect.objectContaining({
|
|
59
|
+
priority: 1,
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should update category name successfully", async () => {
|
|
65
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
66
|
+
spies.select.mockReturnValueOnce(baseRootCategory);
|
|
67
|
+
const updatedCategory = { ...baseRootCategory, name: "Apparel", updatedAt: new Date() };
|
|
68
|
+
spies.update.mockReturnValueOnce(updatedCategory);
|
|
69
|
+
|
|
70
|
+
const input = {
|
|
71
|
+
id: baseRootCategory.id,
|
|
72
|
+
name: "Apparel",
|
|
73
|
+
};
|
|
74
|
+
const result = await run(db, input);
|
|
75
|
+
expect(result.ok).toBe(true);
|
|
76
|
+
if (result.ok) {
|
|
77
|
+
expect(result.value.category.name).toBe("Apparel");
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ok, err } from "../../../shared";
|
|
2
|
+
import { Transaction } from "../generated/kysely-tailordb";
|
|
3
|
+
import {
|
|
4
|
+
CategoryNotFoundError,
|
|
5
|
+
CodeImmutableError,
|
|
6
|
+
MissingRequiredFieldError,
|
|
7
|
+
} from "../lib/errors.generated";
|
|
8
|
+
|
|
9
|
+
export interface UpdateProductCategoryInput {
|
|
10
|
+
id: string;
|
|
11
|
+
code?: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Function: updateProductCategory
|
|
17
|
+
*
|
|
18
|
+
* Updates the display name of an existing category.
|
|
19
|
+
*/
|
|
20
|
+
export async function run<CF extends Record<string, unknown>>(
|
|
21
|
+
db: Transaction,
|
|
22
|
+
input: UpdateProductCategoryInput & CF,
|
|
23
|
+
) {
|
|
24
|
+
const { id, code, name, ...customFields } = input;
|
|
25
|
+
|
|
26
|
+
const category = await db
|
|
27
|
+
.selectFrom("ProductCategory")
|
|
28
|
+
.selectAll()
|
|
29
|
+
.where("id", "=", id)
|
|
30
|
+
.forUpdate()
|
|
31
|
+
.executeTakeFirst();
|
|
32
|
+
|
|
33
|
+
if (!category) {
|
|
34
|
+
return err(new CategoryNotFoundError(id));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (code !== undefined) {
|
|
38
|
+
return err(new CodeImmutableError(id));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const hasNameUpdate = name !== undefined;
|
|
42
|
+
const hasCustomFields = Object.keys(customFields).length > 0;
|
|
43
|
+
|
|
44
|
+
if (!hasNameUpdate && !hasCustomFields) {
|
|
45
|
+
return err(new MissingRequiredFieldError(id));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (hasNameUpdate && !name?.trim()) {
|
|
49
|
+
return err(new MissingRequiredFieldError("name"));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const updates: Record<string, unknown> = {
|
|
53
|
+
...(customFields as Record<string, unknown>),
|
|
54
|
+
updatedAt: new Date(),
|
|
55
|
+
};
|
|
56
|
+
if (hasNameUpdate) updates.name = name;
|
|
57
|
+
|
|
58
|
+
const updated = await db
|
|
59
|
+
.updateTable("ProductCategory")
|
|
60
|
+
.set(updates)
|
|
61
|
+
.where("id", "=", id)
|
|
62
|
+
.returningAll()
|
|
63
|
+
.executeTakeFirst();
|
|
64
|
+
|
|
65
|
+
return ok({ category: updated! });
|
|
66
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
type TailorAnyDBType,
|
|
5
|
+
unsafeAllowAllGqlPermission,
|
|
6
|
+
unsafeAllowAllTypePermission,
|
|
7
|
+
} from "@tailor-platform/sdk";
|
|
8
|
+
import { unit as unitStub } from "../lib/_db_deps";
|
|
9
|
+
|
|
10
|
+
export const BASE_PRODUCT_STATUSES = ["DRAFT", "ACTIVE", "ARCHIVED"] as const;
|
|
11
|
+
|
|
12
|
+
export interface CreateProductTypeParams<F extends Record<string, TailorAnyDBField>> {
|
|
13
|
+
fields?: F;
|
|
14
|
+
additionalStatuses?: string[];
|
|
15
|
+
unitType: TailorAnyDBType;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createProductType<const F extends Record<string, TailorAnyDBField>>(
|
|
19
|
+
params: CreateProductTypeParams<F>,
|
|
20
|
+
) {
|
|
21
|
+
const statuses = [...BASE_PRODUCT_STATUSES, ...(params.additionalStatuses ?? [])] as [
|
|
22
|
+
string,
|
|
23
|
+
...string[],
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
return db
|
|
27
|
+
.type("Product", {
|
|
28
|
+
code: db.string().unique().description("Globally unique, immutable product code"),
|
|
29
|
+
name: db.string().description("Product display name"),
|
|
30
|
+
description: db.string({ optional: true }).description("Optional product description"),
|
|
31
|
+
unitId: db
|
|
32
|
+
.uuid()
|
|
33
|
+
.relation({
|
|
34
|
+
type: "n-1",
|
|
35
|
+
toward: { type: params.unitType },
|
|
36
|
+
backward: "products",
|
|
37
|
+
})
|
|
38
|
+
.description("Foreign key to Unit"),
|
|
39
|
+
status: db.enum(statuses).description("Lifecycle status: DRAFT, ACTIVE, ARCHIVED"),
|
|
40
|
+
...((params.fields ?? {}) as F),
|
|
41
|
+
...db.fields.timestamps(),
|
|
42
|
+
})
|
|
43
|
+
.permission(unsafeAllowAllTypePermission)
|
|
44
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const product = createProductType({ unitType: unitStub });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
unsafeAllowAllGqlPermission,
|
|
5
|
+
unsafeAllowAllTypePermission,
|
|
6
|
+
} from "@tailor-platform/sdk";
|
|
7
|
+
|
|
8
|
+
export interface CreateProductAttributeTypeParams<F extends Record<string, TailorAnyDBField>> {
|
|
9
|
+
fields?: F;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createProductAttributeType<const F extends Record<string, TailorAnyDBField>>(
|
|
13
|
+
params: CreateProductAttributeTypeParams<F>,
|
|
14
|
+
) {
|
|
15
|
+
return db
|
|
16
|
+
.type("ProductAttribute", {
|
|
17
|
+
code: db.string().unique().description("Globally unique, immutable attribute code"),
|
|
18
|
+
name: db.string().description("Attribute display name"),
|
|
19
|
+
...((params.fields ?? {}) as F),
|
|
20
|
+
...db.fields.timestamps(),
|
|
21
|
+
})
|
|
22
|
+
.permission(unsafeAllowAllTypePermission)
|
|
23
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const productAttribute = createProductAttributeType({});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
unsafeAllowAllGqlPermission,
|
|
5
|
+
unsafeAllowAllTypePermission,
|
|
6
|
+
} from "@tailor-platform/sdk";
|
|
7
|
+
import { product } from "./product";
|
|
8
|
+
import { productAttribute } from "./productAttribute";
|
|
9
|
+
import { productAttributeValue } from "./productAttributeValue";
|
|
10
|
+
|
|
11
|
+
export interface CreateProductAttributeAssignmentTypeParams<
|
|
12
|
+
F extends Record<string, TailorAnyDBField>,
|
|
13
|
+
> {
|
|
14
|
+
fields?: F;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createProductAttributeAssignmentType<
|
|
18
|
+
const F extends Record<string, TailorAnyDBField>,
|
|
19
|
+
>(params: CreateProductAttributeAssignmentTypeParams<F>) {
|
|
20
|
+
return db
|
|
21
|
+
.type("ProductAttributeAssignment", {
|
|
22
|
+
productId: db
|
|
23
|
+
.uuid()
|
|
24
|
+
.relation({
|
|
25
|
+
type: "n-1",
|
|
26
|
+
toward: { type: product },
|
|
27
|
+
backward: "productAttributeAssignments",
|
|
28
|
+
})
|
|
29
|
+
.description("Foreign key to Product"),
|
|
30
|
+
attributeId: db
|
|
31
|
+
.uuid()
|
|
32
|
+
.relation({
|
|
33
|
+
type: "n-1",
|
|
34
|
+
toward: { type: productAttribute },
|
|
35
|
+
backward: "productAttributeAssignments",
|
|
36
|
+
})
|
|
37
|
+
.description("Foreign key to ProductAttribute"),
|
|
38
|
+
valueId: db
|
|
39
|
+
.uuid()
|
|
40
|
+
.relation({
|
|
41
|
+
type: "n-1",
|
|
42
|
+
toward: { type: productAttributeValue },
|
|
43
|
+
backward: "productAttributeAssignments",
|
|
44
|
+
})
|
|
45
|
+
.description("Foreign key to ProductAttributeValue"),
|
|
46
|
+
...((params.fields ?? {}) as F),
|
|
47
|
+
...db.fields.timestamps(),
|
|
48
|
+
})
|
|
49
|
+
.indexes({
|
|
50
|
+
fields: ["productId", "attributeId", "valueId"],
|
|
51
|
+
unique: true,
|
|
52
|
+
name: "product_attribute_assignment_unique_idx",
|
|
53
|
+
})
|
|
54
|
+
.permission(unsafeAllowAllTypePermission)
|
|
55
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const productAttributeAssignment = createProductAttributeAssignmentType({});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
unsafeAllowAllGqlPermission,
|
|
5
|
+
unsafeAllowAllTypePermission,
|
|
6
|
+
} from "@tailor-platform/sdk";
|
|
7
|
+
import { productAttribute } from "./productAttribute";
|
|
8
|
+
|
|
9
|
+
export interface CreateProductAttributeValueTypeParams<F extends Record<string, TailorAnyDBField>> {
|
|
10
|
+
fields?: F;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createProductAttributeValueType<const F extends Record<string, TailorAnyDBField>>(
|
|
14
|
+
params: CreateProductAttributeValueTypeParams<F>,
|
|
15
|
+
) {
|
|
16
|
+
return db
|
|
17
|
+
.type("ProductAttributeValue", {
|
|
18
|
+
attributeId: db
|
|
19
|
+
.uuid()
|
|
20
|
+
.relation({
|
|
21
|
+
type: "n-1",
|
|
22
|
+
toward: { type: productAttribute },
|
|
23
|
+
backward: "productAttributeValues",
|
|
24
|
+
})
|
|
25
|
+
.description("Foreign key to ProductAttribute"),
|
|
26
|
+
label: db.string().description("Display label for this value option"),
|
|
27
|
+
...((params.fields ?? {}) as F),
|
|
28
|
+
...db.fields.timestamps(),
|
|
29
|
+
})
|
|
30
|
+
.indexes({
|
|
31
|
+
fields: ["attributeId", "label"],
|
|
32
|
+
unique: true,
|
|
33
|
+
name: "product_attribute_value_unique_idx",
|
|
34
|
+
})
|
|
35
|
+
.permission(unsafeAllowAllTypePermission)
|
|
36
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const productAttributeValue = createProductAttributeValueType({});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
unsafeAllowAllGqlPermission,
|
|
5
|
+
unsafeAllowAllTypePermission,
|
|
6
|
+
} from "@tailor-platform/sdk";
|
|
7
|
+
|
|
8
|
+
export interface CreateProductCategoryTypeParams<F extends Record<string, TailorAnyDBField>> {
|
|
9
|
+
fields?: F;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createProductCategoryType<const F extends Record<string, TailorAnyDBField>>(
|
|
13
|
+
params: CreateProductCategoryTypeParams<F>,
|
|
14
|
+
) {
|
|
15
|
+
return db
|
|
16
|
+
.type("ProductCategory", {
|
|
17
|
+
code: db.string().unique().description("Globally unique, immutable category code"),
|
|
18
|
+
name: db.string().description("Category display name"),
|
|
19
|
+
parentId: db
|
|
20
|
+
.uuid({ optional: true })
|
|
21
|
+
.relation({
|
|
22
|
+
type: "n-1",
|
|
23
|
+
toward: { type: "self" },
|
|
24
|
+
backward: "children",
|
|
25
|
+
})
|
|
26
|
+
.description("Parent category ID (null for root categories)"),
|
|
27
|
+
...((params.fields ?? {}) as F),
|
|
28
|
+
...db.fields.timestamps(),
|
|
29
|
+
})
|
|
30
|
+
.permission(unsafeAllowAllTypePermission)
|
|
31
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const productCategory = createProductCategoryType({});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
unsafeAllowAllGqlPermission,
|
|
5
|
+
unsafeAllowAllTypePermission,
|
|
6
|
+
} from "@tailor-platform/sdk";
|
|
7
|
+
import { product } from "./product";
|
|
8
|
+
import { productCategory } from "./productCategory";
|
|
9
|
+
|
|
10
|
+
export interface CreateProductCategoryAssignmentTypeParams<
|
|
11
|
+
F extends Record<string, TailorAnyDBField>,
|
|
12
|
+
> {
|
|
13
|
+
fields?: F;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createProductCategoryAssignmentType<
|
|
17
|
+
const F extends Record<string, TailorAnyDBField>,
|
|
18
|
+
>(params: CreateProductCategoryAssignmentTypeParams<F>) {
|
|
19
|
+
return db
|
|
20
|
+
.type("ProductCategoryAssignment", {
|
|
21
|
+
productId: db
|
|
22
|
+
.uuid()
|
|
23
|
+
.relation({
|
|
24
|
+
type: "n-1",
|
|
25
|
+
toward: { type: product },
|
|
26
|
+
backward: "productCategoryAssignments",
|
|
27
|
+
})
|
|
28
|
+
.description("Foreign key to Product"),
|
|
29
|
+
categoryId: db
|
|
30
|
+
.uuid()
|
|
31
|
+
.relation({
|
|
32
|
+
type: "n-1",
|
|
33
|
+
toward: { type: productCategory },
|
|
34
|
+
backward: "productCategoryAssignments",
|
|
35
|
+
})
|
|
36
|
+
.description("Foreign key to ProductCategory"),
|
|
37
|
+
...((params.fields ?? {}) as F),
|
|
38
|
+
...db.fields.timestamps(),
|
|
39
|
+
})
|
|
40
|
+
.indexes({
|
|
41
|
+
fields: ["productId", "categoryId"],
|
|
42
|
+
unique: true,
|
|
43
|
+
name: "product_category_assignment_unique_idx",
|
|
44
|
+
})
|
|
45
|
+
.permission(unsafeAllowAllTypePermission)
|
|
46
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const productCategoryAssignment = createProductCategoryAssignmentType({});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
db,
|
|
3
|
+
type TailorAnyDBField,
|
|
4
|
+
type TailorAnyDBType,
|
|
5
|
+
unsafeAllowAllGqlPermission,
|
|
6
|
+
unsafeAllowAllTypePermission,
|
|
7
|
+
} from "@tailor-platform/sdk";
|
|
8
|
+
import { item as itemStub } from "../lib/_db_deps";
|
|
9
|
+
import { product } from "./product";
|
|
10
|
+
|
|
11
|
+
export interface CreateProductVariantTypeParams<F extends Record<string, TailorAnyDBField>> {
|
|
12
|
+
fields?: F;
|
|
13
|
+
itemType: TailorAnyDBType;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function createProductVariantType<const F extends Record<string, TailorAnyDBField>>(
|
|
17
|
+
params: CreateProductVariantTypeParams<F>,
|
|
18
|
+
) {
|
|
19
|
+
return db
|
|
20
|
+
.type("ProductVariant", {
|
|
21
|
+
productId: db
|
|
22
|
+
.uuid()
|
|
23
|
+
.relation({
|
|
24
|
+
type: "n-1",
|
|
25
|
+
toward: { type: product },
|
|
26
|
+
backward: "productVariants",
|
|
27
|
+
})
|
|
28
|
+
.description("Foreign key to Product"),
|
|
29
|
+
axisValueKey: db
|
|
30
|
+
.string()
|
|
31
|
+
.description("Canonical key derived from sorted axis value IDs (e.g., value-1|value-3)"),
|
|
32
|
+
itemId: db
|
|
33
|
+
.uuid()
|
|
34
|
+
.relation({
|
|
35
|
+
type: "n-1",
|
|
36
|
+
toward: { type: params.itemType },
|
|
37
|
+
backward: "productVariants",
|
|
38
|
+
})
|
|
39
|
+
.description("Foreign key to generated Item in item-management"),
|
|
40
|
+
...((params.fields ?? {}) as F),
|
|
41
|
+
...db.fields.timestamps(),
|
|
42
|
+
})
|
|
43
|
+
.indexes({
|
|
44
|
+
fields: ["productId", "axisValueKey"],
|
|
45
|
+
unique: true,
|
|
46
|
+
name: "product_variant_unique_idx",
|
|
47
|
+
})
|
|
48
|
+
.permission(unsafeAllowAllTypePermission)
|
|
49
|
+
.gqlPermission(unsafeAllowAllGqlPermission);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const productVariant = createProductVariantType({ itemType: itemStub });
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ActivateProduct
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
activateProduct transitions a product from DRAFT to ACTIVE status, enabling variant generation and downstream operations. Once active, the set of assigned attributes and their values become locked to preserve variant consistency.
|
|
6
|
+
|
|
7
|
+
## Business Rules
|
|
8
|
+
|
|
9
|
+
- Target product must exist
|
|
10
|
+
- Target product must be in DRAFT status
|
|
11
|
+
- After activation, the attribute structure is locked: assigned attributes cannot be added or removed, and existing attribute values cannot be modified or removed. New values can still be added to existing attributes to support incremental variant generation
|
|
12
|
+
- After activation, UoM is locked and cannot be changed
|
|
13
|
+
|
|
14
|
+
## Process Flow
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart TD
|
|
18
|
+
A[Receive activate request] --> B{Product exists?}
|
|
19
|
+
B -->|No| C[Return error: PRODUCT_NOT_FOUND]
|
|
20
|
+
B -->|Yes| D{Status is DRAFT?}
|
|
21
|
+
D -->|No| E[Return error: INVALID_STATE_TRANSITION]
|
|
22
|
+
D -->|Yes| F[Update status to ACTIVE]
|
|
23
|
+
F --> G[Return activated product]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## External Dependencies
|
|
27
|
+
|
|
28
|
+
- None
|
|
29
|
+
|
|
30
|
+
## Error Scenarios
|
|
31
|
+
|
|
32
|
+
- **PRODUCT_NOT_FOUND**: Specified product ID does not exist
|
|
33
|
+
- **INVALID_STATE_TRANSITION**: Product is not in DRAFT status
|
|
34
|
+
|
|
35
|
+
## Test Cases
|
|
36
|
+
|
|
37
|
+
- returns error when product not found
|
|
38
|
+
- returns error when not in DRAFT status
|
|
39
|
+
- activates DRAFT product to ACTIVE
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# AssignProductToCategory
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
assignProductToCategory creates a many-to-many link between a product and a product category. Products can be assigned to multiple categories for multi-dimensional classification. Assignment is idempotent — assigning an already-assigned product returns the existing record without error.
|
|
6
|
+
|
|
7
|
+
## Business Rules
|
|
8
|
+
|
|
9
|
+
- Target product must exist
|
|
10
|
+
- Target category must exist
|
|
11
|
+
- The (productId, categoryId) combination must be unique
|
|
12
|
+
- Assignment is idempotent — if the assignment already exists, return the existing record
|
|
13
|
+
- Products in any status (DRAFT, ACTIVE, ARCHIVED) can be assigned to categories
|
|
14
|
+
|
|
15
|
+
## Process Flow
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
flowchart TD
|
|
19
|
+
A[Receive assign request] --> B{Product exists?}
|
|
20
|
+
B -->|No| C[Return error: PRODUCT_NOT_FOUND]
|
|
21
|
+
B -->|Yes| D{Category exists?}
|
|
22
|
+
D -->|No| E[Return error: CATEGORY_NOT_FOUND]
|
|
23
|
+
D -->|Yes| F{Assignment already exists?}
|
|
24
|
+
F -->|Yes| G[Return existing assignment]
|
|
25
|
+
F -->|No| H[Create assignment record]
|
|
26
|
+
H --> I[Return created assignment]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## External Dependencies
|
|
30
|
+
|
|
31
|
+
- None
|
|
32
|
+
|
|
33
|
+
## Error Scenarios
|
|
34
|
+
|
|
35
|
+
- **PRODUCT_NOT_FOUND**: Specified product ID does not exist
|
|
36
|
+
- **CATEGORY_NOT_FOUND**: Specified category ID does not exist
|
|
37
|
+
|
|
38
|
+
## Test Cases
|
|
39
|
+
|
|
40
|
+
- should return ProductNotFoundError when product does not exist
|
|
41
|
+
- should return CategoryNotFoundError when category does not exist
|
|
42
|
+
- should create assignment successfully
|
|
43
|
+
- should return existing assignment when already assigned (idempotent)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# CreateProduct
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
createProduct establishes a new product in DRAFT status with a unique code, name, optional description, and unit of measure reference. Products are the commercial representation of a product and serve as the parent entity for variant generation. All products start in DRAFT to allow review and attribute configuration before activation.
|
|
6
|
+
|
|
7
|
+
## Business Rules
|
|
8
|
+
|
|
9
|
+
- Product code is required, must be globally unique across all products, and is immutable after creation
|
|
10
|
+
- Product name is required and must be non-empty
|
|
11
|
+
- UoM is required and must reference an existing active Unit from the primitives module
|
|
12
|
+
- Products are always created in DRAFT status (not configurable)
|
|
13
|
+
- Description is optional
|
|
14
|
+
|
|
15
|
+
## Process Flow
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
flowchart TD
|
|
19
|
+
A[Receive create request] --> B{Code provided?}
|
|
20
|
+
B -->|No| C[Return error: MISSING_REQUIRED_FIELD]
|
|
21
|
+
B -->|Yes| D{Code unique?}
|
|
22
|
+
D -->|No| E[Return error: DUPLICATE_CODE]
|
|
23
|
+
D -->|Yes| F{Name provided and non-empty?}
|
|
24
|
+
F -->|No| G[Return error: MISSING_REQUIRED_FIELD]
|
|
25
|
+
F -->|Yes| H{UoM valid and active?}
|
|
26
|
+
H -->|No| I[Return error: INVALID_UOM]
|
|
27
|
+
H -->|Yes| J[Create product in DRAFT status]
|
|
28
|
+
J --> K[Return created product]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## External Dependencies
|
|
32
|
+
|
|
33
|
+
- [primitives::Unit](../../../primitives/docs/models/Unit.md) - Validates that the referenced UoM exists and is active
|
|
34
|
+
|
|
35
|
+
## Error Scenarios
|
|
36
|
+
|
|
37
|
+
- **DUPLICATE_CODE**: A product with the same code already exists
|
|
38
|
+
- **MISSING_REQUIRED_FIELD**: Code, name, or UoM not provided
|
|
39
|
+
- **INVALID_UOM**: Referenced unit does not exist or is inactive
|
|
40
|
+
|
|
41
|
+
## Test Cases
|
|
42
|
+
|
|
43
|
+
- returns error when code is empty
|
|
44
|
+
- returns error when name is empty
|
|
45
|
+
- returns error when code already exists
|
|
46
|
+
- returns error when UoM is invalid
|
|
47
|
+
- creates product in DRAFT status
|
|
48
|
+
- passes custom fields through
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# CreateProductAttribute
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
createProductAttribute defines a new product attribute with a unique code and display name. All attributes are variant axes — they hold predefined values that drive variant generation. Values are created separately via createProductAttributeValue.
|
|
6
|
+
|
|
7
|
+
## Business Rules
|
|
8
|
+
|
|
9
|
+
- Attribute code is required, must be globally unique, and is immutable after creation
|
|
10
|
+
- Attribute name is required and must be non-empty
|
|
11
|
+
|
|
12
|
+
## Process Flow
|
|
13
|
+
|
|
14
|
+
```mermaid
|
|
15
|
+
flowchart TD
|
|
16
|
+
A[Receive create request] --> B{Code provided and unique?}
|
|
17
|
+
B -->|No| C[Return error: DUPLICATE_CODE or MISSING_REQUIRED_FIELD]
|
|
18
|
+
B -->|Yes| D{Name provided?}
|
|
19
|
+
D -->|No| E[Return error: MISSING_REQUIRED_FIELD]
|
|
20
|
+
D -->|Yes| F[Create attribute record]
|
|
21
|
+
F --> G[Return created attribute]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## External Dependencies
|
|
25
|
+
|
|
26
|
+
- None
|
|
27
|
+
|
|
28
|
+
## Error Scenarios
|
|
29
|
+
|
|
30
|
+
- **DUPLICATE_CODE**: An attribute with the same code already exists
|
|
31
|
+
- **MISSING_REQUIRED_FIELD**: Code or name not provided
|
|
32
|
+
|
|
33
|
+
## Test Cases
|
|
34
|
+
|
|
35
|
+
- returns error when code is empty
|
|
36
|
+
- returns error when name is empty
|
|
37
|
+
- returns error when code already exists
|
|
38
|
+
- creates attribute successfully
|
|
39
|
+
- passes custom fields through to insert
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# CreateProductAttributeValue
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
createProductAttributeValue creates a new predefined value for an existing attribute. Values define the available options for that attribute (e.g., adding "Yellow" to a Color attribute). Products using this attribute can then include the new value in variant generation.
|
|
6
|
+
|
|
7
|
+
## Business Rules
|
|
8
|
+
|
|
9
|
+
- Target attribute must exist
|
|
10
|
+
- Value label is required and must be unique within the parent attribute
|
|
11
|
+
- Values can be added at any time, regardless of whether the attribute is assigned to products
|
|
12
|
+
|
|
13
|
+
## Process Flow
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
flowchart TD
|
|
17
|
+
A[Receive create value request] --> B{Attribute exists?}
|
|
18
|
+
B -->|No| C[Return error: ATTRIBUTE_NOT_FOUND]
|
|
19
|
+
B -->|Yes| D{Label provided and non-empty?}
|
|
20
|
+
D -->|No| E[Return error: INVALID_LABEL]
|
|
21
|
+
D -->|Yes| F{Label unique within attribute?}
|
|
22
|
+
F -->|No| G[Return error: DUPLICATE_VALUE]
|
|
23
|
+
F -->|Yes| H[Create attribute value record]
|
|
24
|
+
H --> I[Return created value]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## External Dependencies
|
|
28
|
+
|
|
29
|
+
- None
|
|
30
|
+
|
|
31
|
+
## Error Scenarios
|
|
32
|
+
|
|
33
|
+
- **ATTRIBUTE_NOT_FOUND**: Specified attribute ID does not exist
|
|
34
|
+
- **INVALID_LABEL**: Label is empty or blank
|
|
35
|
+
- **DUPLICATE_VALUE**: A value with the same label already exists for this attribute
|
|
36
|
+
|
|
37
|
+
## Test Cases
|
|
38
|
+
|
|
39
|
+
- returns error when attribute not found
|
|
40
|
+
- returns error when label is empty
|
|
41
|
+
- returns error when label already exists
|
|
42
|
+
- creates value successfully
|