@tailor-platform/erp-kit 0.2.1 → 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 +6 -0
- package/README.md +1 -23
- package/dist/cli.mjs +1613 -0
- package/package.json +14 -13
- package/schemas/app-compose/story.yml +12 -0
- 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 +4 -4
- 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-implementation → erp-kit-app-5-impl-backend}/SKILL.md +24 -68
- 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-5-implementation/references/frontend.md → erp-kit-app-6-impl-frontend/references/pages.md} +8 -90
- 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 +14 -97
- 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-2-breakdown/SKILL.md +0 -88
- package/skills/erp-kit-app-3-doc-review/SKILL.md +0 -112
- package/skills/erp-kit-app-4-impl-spec/SKILL.md +0 -116
- package/skills/erp-kit-app-5-implementation/references/backend.md +0 -232
- 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,46 @@
|
|
|
1
|
+
# UpdateProductCategory
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
updateProductCategory modifies the display name of an existing product category. In extensible module configurations, consumer-defined custom fields may also be updated through this command. Category code and parent reference are immutable through this command — use moveProductCategory to change the parent.
|
|
6
|
+
|
|
7
|
+
## Business Rules
|
|
8
|
+
|
|
9
|
+
- Target category must exist
|
|
10
|
+
- Category code is immutable — cannot be changed
|
|
11
|
+
- At least one updatable field must be provided
|
|
12
|
+
- Name must remain non-empty when provided
|
|
13
|
+
- Consumer-defined custom fields may be updated
|
|
14
|
+
- Updating name does not affect product assignments or child categories
|
|
15
|
+
|
|
16
|
+
## Process Flow
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
flowchart TD
|
|
20
|
+
A[Receive update request] --> B{Category exists?}
|
|
21
|
+
B -->|No| C[Return error: CATEGORY_NOT_FOUND]
|
|
22
|
+
B -->|Yes| D{Code change attempted?}
|
|
23
|
+
D -->|Yes| E[Return error: CODE_IMMUTABLE]
|
|
24
|
+
D -->|No| F{Any updatable fields provided?}
|
|
25
|
+
F -->|No| G[Return error: MISSING_REQUIRED_FIELD]
|
|
26
|
+
F -->|Yes| H[Apply name and/or custom field updates]
|
|
27
|
+
H --> I[Return updated category]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## External Dependencies
|
|
31
|
+
|
|
32
|
+
- None
|
|
33
|
+
|
|
34
|
+
## Error Scenarios
|
|
35
|
+
|
|
36
|
+
- **CATEGORY_NOT_FOUND**: Specified category ID does not exist
|
|
37
|
+
- **CODE_IMMUTABLE**: Attempt to change the category code
|
|
38
|
+
- **MISSING_REQUIRED_FIELD**: No updatable fields were provided, or name is empty when provided without any custom field updates
|
|
39
|
+
|
|
40
|
+
## Test Cases
|
|
41
|
+
|
|
42
|
+
- should return CategoryNotFoundError when category does not exist
|
|
43
|
+
- should return CodeImmutableError when code is provided
|
|
44
|
+
- should return MissingRequiredFieldError when no fields are provided
|
|
45
|
+
- should pass custom fields through to update
|
|
46
|
+
- should update category name successfully
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Attribute Management
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Attributes define the variant axes of products. Each attribute is identified by a unique code and has a display name. Attributes hold a set of predefined values (e.g., "Red", "Blue" for a Color attribute). Products generate variants from the cartesian product of their assigned attribute values.
|
|
6
|
+
|
|
7
|
+
## Business Purpose
|
|
8
|
+
|
|
9
|
+
A flexible attribute system is essential for variant generation:
|
|
10
|
+
|
|
11
|
+
- **Variant axes** (e.g., Color, Size) determine the combinations that generate product variants. Each axis value maps to a distinct variant
|
|
12
|
+
- Attributes are always variant axes — there are no "descriptive-only" attributes in this module. Descriptive product information is handled via product fields or other modules
|
|
13
|
+
|
|
14
|
+
## Process Flow
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart TD
|
|
18
|
+
A[Create Attribute] --> B[Add Attribute Values]
|
|
19
|
+
B --> C[Assign to Product]
|
|
20
|
+
C --> D[Generate Variants]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Scenario Patterns
|
|
24
|
+
|
|
25
|
+
- **Color Attribute**: A "Color" attribute is created with values Red, Blue, Green. When assigned to a product, these values drive variant generation
|
|
26
|
+
- **Size Attribute**: A "Size" attribute is created with values S, M, L. Combined with Color, it produces the cartesian product (e.g., Red/S, Red/M, ..., Green/L)
|
|
27
|
+
- **Numeric Values as Select**: Values like "10mm", "12mm", "14mm" are modeled as select values, not as numeric types — they are discrete options for variant generation
|
|
28
|
+
- **Attribute Value Addition**: New values (e.g., "Yellow") are added to an existing attribute. Products using this attribute can then include the new value in variant generation
|
|
29
|
+
- **Attribute Name Update**: An attribute's display name can be updated at any time (e.g., renaming "Colour" to "Color"). The attribute's code remains unchanged
|
|
30
|
+
- **Attribute Value Label Update**: A value's display label can be updated at any time (e.g., fixing a typo, changing language). The value's identity (ID) is preserved, so existing variant references and generated SKUs are unaffected
|
|
31
|
+
- **Axis Structure Locked**: Once a product is ACTIVE, the set of attributes assigned to it is locked. New attributes cannot be assigned — only new values can be added to existing attributes. This prevents structure changes that would invalidate existing variants
|
|
32
|
+
- **Attribute Value Removal**: A value is removed from an attribute only if no ACTIVE product uses it as a variant value
|
|
33
|
+
- **Attribute Deletion**: An attribute can only be deleted if it is not assigned to any product
|
|
34
|
+
|
|
35
|
+
## Test Cases
|
|
36
|
+
|
|
37
|
+
- Attributes require a unique code and a display name
|
|
38
|
+
- Attribute code is immutable after creation
|
|
39
|
+
- Attribute value labels can be updated at any time without affecting variant structure or SKUs
|
|
40
|
+
- Attributes must have at least one value before being used for variant generation
|
|
41
|
+
- Attribute values must be unique within the attribute
|
|
42
|
+
- Attribute deletion is blocked if the attribute is assigned to any product
|
|
43
|
+
- Attribute value removal is blocked if the value is in use on any ACTIVE product
|
|
44
|
+
|
|
45
|
+
## Reference Links
|
|
46
|
+
|
|
47
|
+
- [Odoo Product Attributes](https://www.odoo.com/documentation/19.0/applications/sales/sales/products_prices/products/variants.html)
|
|
48
|
+
- [Akeneo Attribute Types](https://help.akeneo.com/pim/serenity/articles/what-about-products-variants.html)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Product Category
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Product categories provide a hierarchical tree structure for classifying products. Each category is identified by a unique code and has a display name. Categories organize the commercial/marketing view of products (e.g., Apparel > Men's > T-Shirts). Products can belong to multiple categories (many-to-many), enabling multi-dimensional classification. This is distinct from item-management's taxonomy, which classifies Items at the SKU level.
|
|
6
|
+
|
|
7
|
+
## Business Purpose
|
|
8
|
+
|
|
9
|
+
Product categories serve the commercial organization of product lines:
|
|
10
|
+
|
|
11
|
+
- Marketing teams organize products into browsable hierarchies for catalogs, e-commerce navigation, and reporting
|
|
12
|
+
- Multiple category trees can coexist (e.g., one by product type, another by season or collection)
|
|
13
|
+
- Categories at the product level group related products (and their variants) together, while item-management's taxonomy classifies individual SKUs for operational purposes
|
|
14
|
+
|
|
15
|
+
The separation from item taxonomy ensures:
|
|
16
|
+
|
|
17
|
+
- Product teams can reorganize commercial categories without affecting operational item classification
|
|
18
|
+
- A product (e.g., "Classic T-Shirt") belongs to a marketing category, while its individual Items (SKUs) may have separate taxonomy assignments for warehouse or procurement purposes
|
|
19
|
+
|
|
20
|
+
## Process Flow
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
flowchart TD
|
|
24
|
+
A[Create Root Category] --> B[Create Child Categories]
|
|
25
|
+
B --> C[Build category tree]
|
|
26
|
+
C --> D[Assign products to categories]
|
|
27
|
+
D --> E{Product in multiple categories?}
|
|
28
|
+
E -->|Yes| F[Create additional assignments]
|
|
29
|
+
E -->|No| G[Single assignment]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Example category tree structure:
|
|
33
|
+
|
|
34
|
+
```mermaid
|
|
35
|
+
flowchart TD
|
|
36
|
+
R[Root: All Products] --> A[Apparel]
|
|
37
|
+
R --> B[Accessories]
|
|
38
|
+
A --> C[Men's]
|
|
39
|
+
A --> D[Women's]
|
|
40
|
+
C --> E[T-Shirts]
|
|
41
|
+
C --> F[Pants]
|
|
42
|
+
D --> G[Dresses]
|
|
43
|
+
B --> H[Bags]
|
|
44
|
+
B --> I[Jewelry]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Scenario Patterns
|
|
48
|
+
|
|
49
|
+
- **Category Tree Setup**: A root category "All Products" is created, then child categories are added hierarchically (Apparel > Men's > T-Shirts)
|
|
50
|
+
- **Multi-Category Assignment**: A "Unisex T-Shirt" product is assigned to both "Men's > T-Shirts" and "Women's > T-Shirts" categories
|
|
51
|
+
- **Category Reorganization**: A category is moved from one parent to another (e.g., "Accessories" moved under "Apparel")
|
|
52
|
+
- **Category Deletion**: A leaf category with no product assignments is deleted. Categories with assignments or children cannot be deleted
|
|
53
|
+
- **Depth Limit**: Category tree depth is configurable (default max depth enforced to prevent excessively deep hierarchies)
|
|
54
|
+
|
|
55
|
+
## Test Cases
|
|
56
|
+
|
|
57
|
+
- Categories require a unique code (globally unique) and a display name
|
|
58
|
+
- Category code is immutable after creation
|
|
59
|
+
- Root categories have no parent
|
|
60
|
+
- Child categories reference a valid parent category
|
|
61
|
+
- Category tree respects a configurable maximum depth
|
|
62
|
+
- Circular references are prevented (a category cannot be its own ancestor)
|
|
63
|
+
- Products can be assigned to multiple categories (many-to-many)
|
|
64
|
+
- Category deletion is blocked if the category has child categories or product assignments
|
|
65
|
+
- Moving a category updates all descendant paths
|
|
66
|
+
- Category names can be updated without affecting product assignments
|
|
67
|
+
|
|
68
|
+
## Reference Links
|
|
69
|
+
|
|
70
|
+
- [Odoo Product Categories](https://www.odoo.com/documentation/19.0/applications/inventory_and_mrp/inventory/product_management.html)
|
|
71
|
+
- [Akeneo Category Trees](https://help.akeneo.com/pim/serenity/articles/what-about-products-variants.html)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Product Lifecycle
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Products are the central entity in the Product Management module. A product represents a commercial product — identified by a unique code, along with its name, description, and attribute assignments. Products serve as the parent entity from which variants are generated. Each product has a lifecycle state machine (DRAFT → ACTIVE ↔ ARCHIVED) that controls when variant generation and downstream operations are permitted.
|
|
6
|
+
|
|
7
|
+
## Business Purpose
|
|
8
|
+
|
|
9
|
+
Products provide the commercial/marketing view of a product, separate from the operational SKU-level Item in item-management. This separation enables:
|
|
10
|
+
|
|
11
|
+
- Marketing and product teams to define product structure and descriptions before SKUs exist
|
|
12
|
+
- Attribute assignment and configuration before generating actual Items
|
|
13
|
+
- Archival of discontinued product lines while preserving generated Items for historical transactions
|
|
14
|
+
The lifecycle ensures:
|
|
15
|
+
|
|
16
|
+
- Products are reviewed before variant generation is allowed (DRAFT → ACTIVE)
|
|
17
|
+
- Archived products stop generating new variants but existing Items remain unaffected
|
|
18
|
+
- Only DRAFT products can be permanently deleted; ACTIVE/ARCHIVED products are preserved
|
|
19
|
+
|
|
20
|
+
## Process Flow
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
stateDiagram-v2
|
|
24
|
+
[*] --> Draft: createProduct
|
|
25
|
+
Draft --> Active: activateProduct
|
|
26
|
+
Active --> Archived: deactivateProduct
|
|
27
|
+
Archived --> Active: reactivateProduct
|
|
28
|
+
Draft --> [*]: deleteProduct
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The product creation and setup flow follows this pattern:
|
|
32
|
+
|
|
33
|
+
```mermaid
|
|
34
|
+
flowchart TD
|
|
35
|
+
A[Create Product] --> B[Assign Attributes]
|
|
36
|
+
B --> C{Ready for variants?}
|
|
37
|
+
C -->|Yes| D[Activate Product]
|
|
38
|
+
C -->|No| E[Continue editing]
|
|
39
|
+
E --> B
|
|
40
|
+
D --> F[Generate Variants]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Scenario Patterns
|
|
44
|
+
|
|
45
|
+
- **New Product Setup**: A product is created in DRAFT, attributes are assigned (Color, Size), then the product is activated
|
|
46
|
+
- **Product Line Archival**: An entire product line is archived. The product moves to ARCHIVED status, preventing new variant generation, but all existing Items remain ACTIVE in item-management
|
|
47
|
+
- **Product Relaunch**: A previously archived product is reactivated for a new season, allowing new variant generation with updated attribute values
|
|
48
|
+
- **Draft Cleanup**: Unfinished products in DRAFT are deleted before activation
|
|
49
|
+
- **Product Update**: An ACTIVE product's name and description can be updated. New attribute values can be added to existing attributes (to support incremental variant generation), but existing values cannot be modified or removed to preserve variant consistency
|
|
50
|
+
|
|
51
|
+
## Test Cases
|
|
52
|
+
|
|
53
|
+
- Product lifecycle follows DRAFT → ACTIVE ↔ ARCHIVED state machine
|
|
54
|
+
- Products can only be created in DRAFT status
|
|
55
|
+
- Only DRAFT products can be deleted; ACTIVE and ARCHIVED products cannot
|
|
56
|
+
- Product code is required, unique, and immutable after creation
|
|
57
|
+
- Product name is required and must be non-empty
|
|
58
|
+
- On ACTIVE products, new attribute values can be added but existing values cannot be modified or removed
|
|
59
|
+
- On DRAFT products, all attribute operations (add, modify, remove) are allowed
|
|
60
|
+
- Archiving a product does not affect existing Items generated from its variants
|
|
61
|
+
- Reactivating an ARCHIVED product returns it to ACTIVE status
|
|
62
|
+
|
|
63
|
+
## Reference Links
|
|
64
|
+
|
|
65
|
+
- [Odoo Product Variants](https://www.odoo.com/documentation/19.0/applications/sales/sales/products_prices/products/variants.html)
|
|
66
|
+
- [Akeneo Product Model](https://help.akeneo.com/pim/serenity/articles/what-about-products-variants.html)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Variant Generation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Variant generation creates product variants from the combination of attribute values on an ACTIVE product. Each variant represents a unique attribute combination (e.g., Red/S, Red/M, Blue/S, Blue/M). Upon generation, each variant creates a corresponding Item in the item-management module with a SKU produced by an injectable SKU generation strategy, inheriting the product's UoM configuration.
|
|
6
|
+
|
|
7
|
+
## Business Purpose
|
|
8
|
+
|
|
9
|
+
Variant generation is the bridge between the commercial product view (product-management) and the operational SKU view (item-management):
|
|
10
|
+
|
|
11
|
+
- Product teams define the product structure (product + attributes) in product-management
|
|
12
|
+
- Variant generation materializes this structure into concrete, tradeable Items
|
|
13
|
+
- Each Item receives a unique SKU produced by the injectable SKU generation strategy (default: sequential numbering based on product code, e.g., `CLASSIC-TSHIRT-001`)
|
|
14
|
+
- Generated Items can then participate in inventory, sales, and purchasing workflows independently
|
|
15
|
+
|
|
16
|
+
This separation ensures:
|
|
17
|
+
|
|
18
|
+
- Product structure changes (adding a new color) can be planned before creating SKUs
|
|
19
|
+
- Only ACTIVE products can generate variants, preventing premature Item creation
|
|
20
|
+
- The relationship between a product and its generated Items is tracked for traceability
|
|
21
|
+
|
|
22
|
+
## Process Flow
|
|
23
|
+
|
|
24
|
+
```mermaid
|
|
25
|
+
flowchart TD
|
|
26
|
+
A[Product - ACTIVE] --> B[Collect attribute assignments]
|
|
27
|
+
B --> C[Compute attribute value combinations]
|
|
28
|
+
C --> D{For each combination}
|
|
29
|
+
D --> E[Check if variant already exists]
|
|
30
|
+
E -->|Exists| F[Skip]
|
|
31
|
+
E -->|New| G[Create ProductVariant record]
|
|
32
|
+
G --> H[Call item-management createItem]
|
|
33
|
+
H --> I[Link Item to ProductVariant]
|
|
34
|
+
I --> D
|
|
35
|
+
D -->|All done| J[Generation complete]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
SKU generation logic is **injectable**. Consumers can provide a custom SKU generation strategy when configuring the module; a sensible default is shipped out of the box. The generator receives the product code, axis values, and the current variant count as input and returns a SKU string. The default strategy produces sequential numbering based on the product code, avoiding coupling to attribute value labels:
|
|
39
|
+
|
|
40
|
+
```mermaid
|
|
41
|
+
flowchart LR
|
|
42
|
+
A["Product code: 'CLASSIC-TSHIRT'"] --> B["Variant count: 0"]
|
|
43
|
+
B --> C["SKU: CLASSIC-TSHIRT-001"]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Custom strategy examples include attribute-value slug (`CLASSIC-TSHIRT-RED-M`), prefix by brand (`ACME-CTSHIRT-001`), or hash-based (`CT-a3f8b2`).
|
|
47
|
+
|
|
48
|
+
## Scenario Patterns
|
|
49
|
+
|
|
50
|
+
- **Full Generation**: A product with Color (Red, Blue) × Size (S, M, L) generates 6 variants. Each variant creates an Item in item-management with a SKU produced by the configured SKU generation strategy (default: `CLASSIC-TSHIRT-001` through `CLASSIC-TSHIRT-006`)
|
|
51
|
+
- **Incremental Generation**: A new color (Green) is added to a product. Re-running generation creates only the 3 new variants (Green/S, Green/M, Green/L), skipping existing ones
|
|
52
|
+
- **Single Axis**: A product with only one attribute (e.g., Size: S, M, L) generates 3 variants
|
|
53
|
+
- **Generation Blocked**: Attempting to generate variants from a DRAFT or ARCHIVED product is rejected
|
|
54
|
+
- **Axis Structure Locked**: Once a product is ACTIVE, the set of assigned attributes is locked. New attributes cannot be assigned; only new values can be added to existing attributes
|
|
55
|
+
- **Generated Item Independence**: After generation, the Item's lifecycle is independent — deactivating an Item in item-management does not affect the product or other variants
|
|
56
|
+
- **Variant Traceability**: Each ProductVariant record links the product, the specific axis values, and the generated Item ID for full traceability
|
|
57
|
+
|
|
58
|
+
## Test Cases
|
|
59
|
+
|
|
60
|
+
- Variants can only be generated from ACTIVE products
|
|
61
|
+
- Each variant represents a unique combination of attribute values
|
|
62
|
+
- Duplicate combinations are skipped during generation (idempotent)
|
|
63
|
+
- Each generated variant creates exactly one Item in item-management
|
|
64
|
+
- Generated Item SKU is produced by the injectable SKU generation strategy (defaults to sequential numbering based on product code)
|
|
65
|
+
- A custom SKU generation strategy can be provided at module configuration time
|
|
66
|
+
- The strategy receives product code, axis values, and current variant count, and must return a unique string
|
|
67
|
+
- The default strategy avoids coupling SKUs to attribute value labels, ensuring label updates do not create inconsistencies
|
|
68
|
+
- Generated Item inherits the product's configured UoM
|
|
69
|
+
- Generated Items are created in DRAFT status (requiring explicit activation in item-management)
|
|
70
|
+
- ProductVariant records store the product ID, axis value combination, and generated Item ID
|
|
71
|
+
- Variant generation fails atomically if any Item creation fails (no partial generation)
|
|
72
|
+
- The set of assigned attributes is locked on non-DRAFT products — new attributes cannot be assigned after activation
|
|
73
|
+
|
|
74
|
+
## Reference Links
|
|
75
|
+
|
|
76
|
+
- [Odoo Variant Creation Modes](https://www.odoo.com/documentation/19.0/applications/sales/sales/products_prices/products/variants.html)
|
|
77
|
+
- [Akeneo Family Variant Levels](https://help.akeneo.com/pim/serenity/articles/what-about-products-variants.html)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Product
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
Product is the central entity in the Product Management module. A product represents a commercial product -- identified by a unique code, along with its name, description, and unit of measure. Products serve as the parent entity from which variants are generated via attribute combinations. Each product has a lifecycle state machine (DRAFT -> ACTIVE <-> ARCHIVED) that controls when variant generation and downstream operations are permitted.
|
|
6
|
+
|
|
7
|
+
Products provide the commercial/marketing view of a product, separate from the operational SKU-level Item in item-management. Only ACTIVE products can generate variants. Only DRAFT products can be permanently deleted.
|
|
8
|
+
|
|
9
|
+
## Domain Model Definitions
|
|
10
|
+
|
|
11
|
+
### Model type
|
|
12
|
+
|
|
13
|
+
Stateful
|
|
14
|
+
|
|
15
|
+
#### State Transitions
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
stateDiagram-v2
|
|
19
|
+
[*] --> Draft: createProduct
|
|
20
|
+
Draft --> Active: activateProduct
|
|
21
|
+
Active --> Archived: deactivateProduct
|
|
22
|
+
Archived --> Active: reactivateProduct
|
|
23
|
+
Draft --> [*]: deleteProduct
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Command Definitions
|
|
27
|
+
|
|
28
|
+
- [createProduct](../commands/CreateProduct.md) - Create a new product in DRAFT status
|
|
29
|
+
- [updateProduct](../commands/UpdateProduct.md) - Update mutable fields of an existing product
|
|
30
|
+
- [activateProduct](../commands/ActivateProduct.md) - Transition product from DRAFT to ACTIVE
|
|
31
|
+
- [deactivateProduct](../commands/DeactivateProduct.md) - Transition product from ACTIVE to ARCHIVED
|
|
32
|
+
- [reactivateProduct](../commands/ReactivateProduct.md) - Transition product from ARCHIVED to ACTIVE
|
|
33
|
+
- [deleteProduct](../commands/DeleteProduct.md) - Permanently delete a DRAFT product
|
|
34
|
+
|
|
35
|
+
### Query Definitions
|
|
36
|
+
|
|
37
|
+
- GetProduct - Retrieve a product by id or code
|
|
38
|
+
|
|
39
|
+
### Models
|
|
40
|
+
|
|
41
|
+
- Product
|
|
42
|
+
|
|
43
|
+
### Invariants
|
|
44
|
+
|
|
45
|
+
- Product code is required, globally unique, and immutable after creation
|
|
46
|
+
- Product name is required and must be non-empty
|
|
47
|
+
- Products are always created in DRAFT status
|
|
48
|
+
- Only DRAFT products can be deleted; ACTIVE and ARCHIVED products are preserved
|
|
49
|
+
- Assigned attributes are freely modifiable in DRAFT status; on ACTIVE products only additive changes are allowed (new values for existing attributes); on ARCHIVED products all attribute changes are blocked
|
|
50
|
+
- Archiving a product does not affect existing Items generated from its variants
|
|
51
|
+
- UoM must reference an existing active Unit from the primitives module
|
|
52
|
+
|
|
53
|
+
### Relationships
|
|
54
|
+
|
|
55
|
+
- **References Unit**: Each product references a Unit from the primitives module as its unit of measure
|
|
56
|
+
- **Has Many ProductAttributeAssignments**: Product attribute assignments link attributes and their values to this product
|
|
57
|
+
- **Has Many ProductVariants**: Variants are generated from this product's attribute combinations
|
|
58
|
+
- **Has Many ProductCategoryAssignments**: Products are linked to ProductCategories via many-to-many assignments
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# ProductAttribute
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
ProductAttribute defines a variant axis that can be assigned to products. Each attribute is identified by a unique code and has a display name. Attributes hold predefined values (e.g., "Red", "Blue", "Green" for a Color attribute) that drive variant generation. All attributes are variant axes — there are no descriptive-only attributes in this module.
|
|
6
|
+
|
|
7
|
+
## Domain Model Definitions
|
|
8
|
+
|
|
9
|
+
### Model type
|
|
10
|
+
|
|
11
|
+
Standard
|
|
12
|
+
|
|
13
|
+
### Command Definitions
|
|
14
|
+
|
|
15
|
+
- [createProductAttribute](../commands/CreateProductAttribute.md) - Create a new attribute
|
|
16
|
+
- [updateProductAttribute](../commands/UpdateProductAttribute.md) - Update the display name of an existing attribute
|
|
17
|
+
- [deleteProductAttribute](../commands/DeleteProductAttribute.md) - Delete an attribute that is not assigned to any product
|
|
18
|
+
|
|
19
|
+
### Query Definitions
|
|
20
|
+
|
|
21
|
+
- GetProductAttribute - Retrieve an attribute by id or code
|
|
22
|
+
|
|
23
|
+
### Models
|
|
24
|
+
|
|
25
|
+
- ProductAttribute
|
|
26
|
+
|
|
27
|
+
### Invariants
|
|
28
|
+
|
|
29
|
+
- Attribute code is required, globally unique, and immutable after creation
|
|
30
|
+
- Attribute name is required and must be non-empty
|
|
31
|
+
- Attributes must have at least one ProductAttributeValue before being used for variant generation
|
|
32
|
+
- Attribute deletion is blocked if the attribute is assigned to any product
|
|
33
|
+
|
|
34
|
+
### Relationships
|
|
35
|
+
|
|
36
|
+
- **Has Many ProductAttributeValues**: Attributes have a set of predefined values
|
|
37
|
+
- **Referenced By ProductAttributeAssignments**: Attributes are assigned to products via attribute assignment records
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ProductAttributeAssignment
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
ProductAttributeAssignment records the assignment of a single attribute value to a specific product. A product can have multiple assignments for the same attribute, each carrying a different value (e.g., Color=Red, Color=Blue, Color=Green). All assignments participate in variant generation — the set of values per attribute defines the variant axes.
|
|
6
|
+
|
|
7
|
+
This model is the junction between Product and ProductAttribute, carrying the actual attribute values for each product.
|
|
8
|
+
|
|
9
|
+
## Domain Model Definitions
|
|
10
|
+
|
|
11
|
+
### Model type
|
|
12
|
+
|
|
13
|
+
Standard
|
|
14
|
+
|
|
15
|
+
### Command Definitions
|
|
16
|
+
|
|
17
|
+
- [setProductAttributeAssignment](../commands/SetProductAttributeAssignment.md) - Set or update an attribute value on a product
|
|
18
|
+
|
|
19
|
+
### Query Definitions
|
|
20
|
+
|
|
21
|
+
- GetProductAttributeAssignment - Retrieve a specific assignment by productId and attributeId
|
|
22
|
+
- ListProductAttributeAssignments - Retrieve all attribute assignments for a given product
|
|
23
|
+
|
|
24
|
+
### Models
|
|
25
|
+
|
|
26
|
+
- ProductAttributeAssignment
|
|
27
|
+
|
|
28
|
+
### Invariants
|
|
29
|
+
|
|
30
|
+
- Each record references a valid Product and a valid ProductAttribute
|
|
31
|
+
- The combination of (productId, attributeId, valueId) must be unique — multiple values per attribute are allowed
|
|
32
|
+
- The value must reference a valid ProductAttributeValue belonging to the attribute
|
|
33
|
+
- On DRAFT products: assignments can be freely created and removed
|
|
34
|
+
- On ACTIVE products: adding new values to an already-assigned attribute is allowed (additive-only); removing existing values or assigning a new attribute is blocked
|
|
35
|
+
- On ARCHIVED products: all assignment changes are blocked
|
|
36
|
+
|
|
37
|
+
### Relationships
|
|
38
|
+
|
|
39
|
+
- **Belongs To Product**: Each record is associated with exactly one product
|
|
40
|
+
- **Belongs To ProductAttribute**: Each record references exactly one attribute definition
|
|
41
|
+
- **References ProductAttributeValue**: The value references a predefined option
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ProductAttributeValue
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
ProductAttributeValue represents a predefined option for a ProductAttribute. Each value belongs to exactly one attribute and has a unique label within that attribute. Values define the available options for attributes (e.g., "Red", "Blue", "Green" for a Color attribute) and serve as the axis values for variant generation.
|
|
6
|
+
|
|
7
|
+
## Domain Model Definitions
|
|
8
|
+
|
|
9
|
+
### Model type
|
|
10
|
+
|
|
11
|
+
Standard
|
|
12
|
+
|
|
13
|
+
### Command Definitions
|
|
14
|
+
|
|
15
|
+
- [createProductAttributeValue](../commands/CreateProductAttributeValue.md) - Create a new value for an attribute
|
|
16
|
+
- [updateProductAttributeValue](../commands/UpdateProductAttributeValue.md) - Update the display label of an existing value
|
|
17
|
+
- [deleteProductAttributeValue](../commands/DeleteProductAttributeValue.md) - Delete a value from an attribute
|
|
18
|
+
|
|
19
|
+
### Query Definitions
|
|
20
|
+
|
|
21
|
+
- GetProductAttributeValue - Retrieve a single value by id or by attributeId + label
|
|
22
|
+
- ListProductAttributeValues - Retrieve all values for a given attribute
|
|
23
|
+
|
|
24
|
+
### Models
|
|
25
|
+
|
|
26
|
+
- ProductAttributeValue
|
|
27
|
+
|
|
28
|
+
### Invariants
|
|
29
|
+
|
|
30
|
+
- Each value must belong to exactly one ProductAttribute
|
|
31
|
+
- Value label must be unique within the parent attribute
|
|
32
|
+
- Value label can be updated at any time (display-only change; identity is preserved)
|
|
33
|
+
- Value removal is blocked if the value is in use on any ACTIVE product
|
|
34
|
+
- Adding values is always allowed for any attribute
|
|
35
|
+
|
|
36
|
+
### Relationships
|
|
37
|
+
|
|
38
|
+
- **Belongs To ProductAttribute**: Each value belongs to exactly one attribute
|
|
39
|
+
- **Referenced By ProductAttributeAssignments**: Values are referenced when assigning attribute values to products
|
|
40
|
+
- **Referenced By ProductVariants**: Variant axis values reference these records for traceability
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# ProductCategory
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
ProductCategory represents a single node in a hierarchical tree structure used to classify products for commercial and marketing purposes. Each category is identified by a globally unique code and has a display name. Root categories have no parent. Categories can be reorganized by moving them to a different parent, and children follow their parent.
|
|
6
|
+
|
|
7
|
+
This is distinct from item-management's taxonomy, which classifies Items at the SKU level. Product categories organize the commercial view of products (e.g., Apparel > Men's > T-Shirts).
|
|
8
|
+
|
|
9
|
+
## Domain Model Definitions
|
|
10
|
+
|
|
11
|
+
### Model type
|
|
12
|
+
|
|
13
|
+
Standard
|
|
14
|
+
|
|
15
|
+
### Command Definitions
|
|
16
|
+
|
|
17
|
+
- [createProductCategory](../commands/CreateProductCategory.md) - Create a new root or child category
|
|
18
|
+
- [updateProductCategory](../commands/UpdateProductCategory.md) - Update the display name of an existing category
|
|
19
|
+
- [moveProductCategory](../commands/MoveProductCategory.md) - Reparent a category within the tree
|
|
20
|
+
- [deleteProductCategory](../commands/DeleteProductCategory.md) - Delete a leaf category with no product assignments
|
|
21
|
+
|
|
22
|
+
### Query Definitions
|
|
23
|
+
|
|
24
|
+
- GetProductCategory - Retrieve a category by id or code
|
|
25
|
+
- ListProductCategoryChildren - Retrieve direct child categories of a given category
|
|
26
|
+
|
|
27
|
+
### Models
|
|
28
|
+
|
|
29
|
+
- ProductCategory
|
|
30
|
+
|
|
31
|
+
### Invariants
|
|
32
|
+
|
|
33
|
+
- Category code is required, globally unique, and immutable after creation
|
|
34
|
+
- Category name is required and must be non-empty
|
|
35
|
+
- Root categories have a null parent reference
|
|
36
|
+
- Child categories must reference a valid existing parent category
|
|
37
|
+
- Category tree respects a configurable maximum depth (prevents excessively deep hierarchies)
|
|
38
|
+
- Circular references are prevented -- a category cannot be its own ancestor
|
|
39
|
+
- Category deletion is blocked if the category has child categories
|
|
40
|
+
- Category deletion is blocked if the category has product assignments
|
|
41
|
+
- Moving a category updates the category's parent reference while preserving its descendants
|
|
42
|
+
|
|
43
|
+
### Relationships
|
|
44
|
+
|
|
45
|
+
- **Self-Referential Parent-Child**: Each category optionally references another ProductCategory as its parent, forming a tree
|
|
46
|
+
- **Referenced By ProductCategoryAssignments**: Categories are linked to products via many-to-many assignments
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# ProductCategoryAssignment
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
ProductCategoryAssignment is the junction entity that links products to product categories in a many-to-many relationship. A product can belong to multiple categories (e.g., a "Unisex T-Shirt" in both "Men's > T-Shirts" and "Women's > T-Shirts"), and a category can contain multiple products.
|
|
6
|
+
|
|
7
|
+
## Domain Model Definitions
|
|
8
|
+
|
|
9
|
+
### Model type
|
|
10
|
+
|
|
11
|
+
Standard
|
|
12
|
+
|
|
13
|
+
### Command Definitions
|
|
14
|
+
|
|
15
|
+
- [assignProductToCategory](../commands/AssignProductToCategory.md) - Assign a product to a category
|
|
16
|
+
- [removeProductFromCategory](../commands/RemoveProductFromCategory.md) - Remove a product from a category
|
|
17
|
+
|
|
18
|
+
### Query Definitions
|
|
19
|
+
|
|
20
|
+
- GetProductCategoryAssignment - Retrieve a specific assignment by productId and categoryId
|
|
21
|
+
- ListProductCategoryAssignments - Retrieve all product assignments for a given category
|
|
22
|
+
- ListCategoryAssignmentsByProduct - Retrieve all category assignments for a given product
|
|
23
|
+
|
|
24
|
+
### Models
|
|
25
|
+
|
|
26
|
+
- ProductCategoryAssignment
|
|
27
|
+
|
|
28
|
+
### Invariants
|
|
29
|
+
|
|
30
|
+
- Each assignment references a valid Product and a valid ProductCategory
|
|
31
|
+
- The combination of (productId, categoryId) must be unique (no duplicate assignments)
|
|
32
|
+
- Assignment is idempotent -- assigning an already-assigned product returns the existing record
|
|
33
|
+
|
|
34
|
+
### Relationships
|
|
35
|
+
|
|
36
|
+
- **Belongs To Product**: Each assignment links to exactly one product
|
|
37
|
+
- **Belongs To ProductCategory**: Each assignment links to exactly one category
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ProductVariant
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
ProductVariant represents a unique combination of attribute values generated from an ACTIVE product. Each variant links the product, the specific value combination, and the generated Item ID in item-management. Variants are created during the variant generation process and provide full traceability between the commercial product structure and operational SKUs.
|
|
6
|
+
|
|
7
|
+
Variant generation is idempotent -- existing combinations are skipped, and only new combinations create new variant records and corresponding Items.
|
|
8
|
+
|
|
9
|
+
## Domain Model Definitions
|
|
10
|
+
|
|
11
|
+
### Model type
|
|
12
|
+
|
|
13
|
+
Standard
|
|
14
|
+
|
|
15
|
+
### Command Definitions
|
|
16
|
+
|
|
17
|
+
- [generateVariants](../commands/GenerateVariants.md) - Generate variants from attribute value combinations on an ACTIVE product
|
|
18
|
+
|
|
19
|
+
### Query Definitions
|
|
20
|
+
|
|
21
|
+
- GetProductVariant - Retrieve a single variant by id or by productId + axisValueKey
|
|
22
|
+
- ListProductVariants - Retrieve all variants for a given product
|
|
23
|
+
|
|
24
|
+
### Models
|
|
25
|
+
|
|
26
|
+
- ProductVariant
|
|
27
|
+
|
|
28
|
+
### Invariants
|
|
29
|
+
|
|
30
|
+
- Each variant represents a unique combination of attribute values within a product
|
|
31
|
+
- Each variant is associated with exactly one generated Item in item-management
|
|
32
|
+
- The value combination (`productId` + `axisValueKey`) must be unique
|
|
33
|
+
- `axisValueKey` is a canonical string key derived from sorted value IDs (e.g., `"value-1|value-3"`)
|
|
34
|
+
- Variants can only be created from ACTIVE products
|
|
35
|
+
- Once created, variant records are immutable (the link between product, values, and Item is permanent)
|
|
36
|
+
|
|
37
|
+
### Relationships
|
|
38
|
+
|
|
39
|
+
- **Belongs To Product**: Each variant is generated from exactly one product (`productId`)
|
|
40
|
+
- **References ProductAttributeValues**: Each variant stores the specific value combination via `axisValueKey`
|
|
41
|
+
- **References item-management::Item**: Each variant links to the Item created during generation (`itemId`)
|