@tailor-platform/erp-kit 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +193 -69
- package/dist/cli.mjs +1038 -398
- package/package.json +7 -5
- package/skills/erp-kit-app-1-requirements/SKILL.md +27 -17
- package/skills/erp-kit-app-2-requirements-review/SKILL.md +5 -4
- package/skills/erp-kit-app-2-requirements-review/references/best-practices-check.md +10 -1
- package/skills/erp-kit-app-2-requirements-review/references/boundary-consistency-check.md +10 -1
- package/skills/erp-kit-app-3-plan/SKILL.md +31 -34
- package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +22 -36
- package/skills/erp-kit-app-3-plan/references/screen-extraction.md +15 -1
- package/skills/erp-kit-app-3-plan/references/story-extraction.md +8 -2
- package/skills/erp-kit-app-4-plan-review/SKILL.md +1 -10
- package/skills/erp-kit-app-5-impl-backend/SKILL.md +10 -19
- package/skills/erp-kit-app-5-impl-backend/references/app-config.md +1 -22
- package/skills/erp-kit-app-5-impl-backend/references/module-wiring.md +0 -1
- package/skills/erp-kit-app-5-impl-backend/references/resolver-patterns.md +13 -4
- package/skills/erp-kit-app-6-impl-frontend/SKILL.md +5 -0
- package/skills/erp-kit-app-6-impl-frontend/references/pages.md +16 -46
- package/skills/erp-kit-app-7-impl-review/SKILL.md +13 -11
- package/skills/erp-kit-app-7-impl-review/references/resolver-doc-code-parity.md +16 -17
- package/skills/erp-kit-app-shared/SKILL.md +15 -0
- package/skills/erp-kit-app-shared/references/link-format-reference.md +13 -0
- package/skills/erp-kit-app-shared/references/naming-conventions.md +21 -0
- package/skills/erp-kit-app-shared/references/resolver-classification.md +23 -0
- package/skills/erp-kit-app-shared/references/schema-constraints.md +25 -0
- package/skills/erp-kit-module-1-requirements/SKILL.md +7 -13
- package/skills/erp-kit-module-1-requirements/references/feature-doc.md +1 -1
- package/skills/erp-kit-module-2-requirements-review/SKILL.md +21 -5
- package/skills/erp-kit-module-2-requirements-review/references/requirements-report-format.md +19 -0
- package/skills/erp-kit-module-3-plan/SKILL.md +6 -8
- package/skills/erp-kit-module-3-plan/references/naming.md +15 -1
- package/skills/erp-kit-module-4-plan-review/SKILL.md +21 -5
- package/skills/erp-kit-module-4-plan-review/references/parity-report-format.md +15 -0
- package/skills/erp-kit-module-5-impl/SKILL.md +12 -10
- package/skills/erp-kit-module-5-impl/references/generated-code.md +2 -2
- package/skills/erp-kit-module-6-impl-review/SKILL.md +21 -7
- package/skills/erp-kit-module-6-impl-review/references/error-implementation-parity.md +1 -1
- package/skills/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 +15 -0
- package/skills/erp-kit-module-shared/SKILL.md +4 -0
- package/skills/erp-kit-module-shared/references/errors.md +1 -1
- package/skills/erp-kit-module-shared/references/queries.md +1 -1
- package/skills/erp-kit-module-shared/references/structure.md +1 -1
- package/skills/erp-kit-update/SKILL.md +2 -2
- package/src/commands/app/index.ts +75 -31
- package/src/commands/check.test.ts +1 -1
- package/src/commands/check.ts +2 -35
- package/src/commands/doc/index.ts +83 -0
- package/src/commands/doc/module.test.ts +119 -0
- package/src/commands/doc/module.ts +114 -0
- package/src/commands/doc/modules.test.ts +103 -0
- package/src/commands/doc/modules.ts +98 -0
- package/src/commands/doc/search.test.ts +94 -0
- package/src/commands/doc/search.ts +111 -0
- package/src/commands/generate-doc.test.ts +63 -0
- package/src/commands/generate-doc.ts +105 -0
- package/src/commands/index.ts +20 -8
- package/src/commands/init-module.test.ts +43 -0
- package/src/commands/init-module.ts +74 -0
- package/src/commands/lib/command-result.ts +30 -0
- package/src/commands/lib/discovery.test.ts +74 -0
- package/src/commands/lib/discovery.ts +106 -0
- package/src/commands/lib/paths.ts +22 -0
- package/src/commands/lib/sync-check-source.test.ts +197 -0
- package/src/commands/lib/sync-check-source.ts +100 -0
- package/src/commands/lib/sync-check-tests.test.ts +178 -0
- package/src/commands/lib/sync-check-tests.ts +69 -0
- package/src/commands/mock/index.ts +11 -6
- package/src/commands/module/generate.ts +39 -14
- package/src/commands/module/index.ts +31 -45
- package/src/commands/parse-doc-test-cases.ts +13 -2
- package/src/commands/sync-check.test.ts +6 -364
- package/src/commands/sync-check.ts +7 -251
- package/src/generator/generate-app-code.test.ts +121 -0
- package/src/generator/generate-app-code.ts +51 -0
- package/src/{commands/scaffold.test.ts → generator/generate-code-boilerplate.test.ts} +19 -89
- package/src/generator/generate-code.test.ts +57 -6
- package/src/generator/generate-code.ts +40 -157
- package/src/generator/generate-errors.ts +34 -0
- package/src/generator/generate-permissions.ts +12 -0
- package/src/generator/generate-shells.ts +28 -0
- package/src/generator/generate-stubs.ts +31 -0
- package/src/generator/parse-resolver-doc.test.ts +89 -0
- package/src/generator/parse-resolver-doc.ts +125 -0
- package/src/generator/scaffold.ts +57 -0
- package/src/generator/stub-templates.test.ts +55 -0
- package/src/generator/stub-templates.ts +145 -0
- package/src/integration.test.ts +2 -2
- package/src/modules/audit/README.md +46 -0
- package/src/modules/audit/command/activateAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/activateAuditPolicy.test.ts +186 -0
- package/src/modules/audit/command/activateAuditPolicy.ts +97 -0
- package/src/modules/audit/command/createAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/createAuditPolicy.test.ts +395 -0
- package/src/modules/audit/command/createAuditPolicy.ts +131 -0
- package/src/modules/audit/command/deactivateAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/deactivateAuditPolicy.test.ts +138 -0
- package/src/modules/audit/command/deactivateAuditPolicy.ts +58 -0
- package/src/modules/audit/command/deleteAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/deleteAuditPolicy.test.ts +121 -0
- package/src/modules/audit/command/deleteAuditPolicy.ts +52 -0
- package/src/modules/audit/command/logAuditEvent.generated.ts +6 -0
- package/src/modules/audit/command/logAuditEvent.test.ts +991 -0
- package/src/modules/audit/command/logAuditEvent.ts +357 -0
- package/src/modules/audit/command/reactivateAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/reactivateAuditPolicy.test.ts +143 -0
- package/src/modules/audit/command/reactivateAuditPolicy.ts +79 -0
- package/src/modules/audit/command/registerAuditableEntity.generated.ts +6 -0
- package/src/modules/audit/command/registerAuditableEntity.test.ts +268 -0
- package/src/modules/audit/command/registerAuditableEntity.ts +94 -0
- package/src/modules/audit/command/replaceAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/replaceAuditPolicy.test.ts +242 -0
- package/src/modules/audit/command/replaceAuditPolicy.ts +91 -0
- package/src/modules/audit/command/updateAuditPolicy.generated.ts +6 -0
- package/src/modules/audit/command/updateAuditPolicy.test.ts +284 -0
- package/src/modules/audit/command/updateAuditPolicy.ts +151 -0
- package/src/modules/audit/db/auditEntry.ts +47 -0
- package/src/modules/audit/db/auditPolicy.ts +33 -0
- package/src/modules/audit/db/auditableEntity.ts +22 -0
- package/src/modules/audit/db/changeDetail.ts +28 -0
- package/src/modules/audit/db/policyFieldRule.ts +23 -0
- package/src/modules/audit/docs/commands/ActivateAuditPolicy.md +69 -0
- package/src/modules/audit/docs/commands/CreateAuditPolicy.md +79 -0
- package/src/modules/audit/docs/commands/DeactivateAuditPolicy.md +55 -0
- package/src/modules/audit/docs/commands/DeleteAuditPolicy.md +55 -0
- package/src/modules/audit/docs/commands/LogAuditEvent.md +137 -0
- package/src/modules/audit/docs/commands/ReactivateAuditPolicy.md +58 -0
- package/src/modules/audit/docs/commands/RegisterAuditableEntity.md +62 -0
- package/src/modules/audit/docs/commands/ReplaceAuditPolicy.md +72 -0
- package/src/modules/audit/docs/commands/UpdateAuditPolicy.md +77 -0
- package/src/modules/audit/docs/features/audit-event-logging.md +126 -0
- package/src/modules/audit/docs/features/audit-policy-configuration.md +135 -0
- package/src/modules/audit/docs/features/field-level-change-tracking.md +95 -0
- package/src/modules/audit/docs/models/AuditEntry.md +55 -0
- package/src/modules/audit/docs/models/AuditPolicy.md +79 -0
- package/src/modules/audit/docs/models/AuditableEntity.md +38 -0
- package/src/modules/audit/docs/models/ChangeDetail.md +55 -0
- package/src/modules/audit/docs/models/PolicyFieldRule.md +45 -0
- package/src/modules/audit/docs/queries/GetAuditEntry.md +49 -0
- package/src/modules/audit/docs/queries/GetAuditPolicy.md +54 -0
- package/src/modules/audit/docs/queries/GetAuditSummary.md +84 -0
- package/src/modules/audit/docs/queries/GetChangeDetails.md +56 -0
- package/src/modules/audit/docs/queries/ListAuditPolicies.md +58 -0
- package/src/modules/audit/docs/queries/SearchAuditEntries.md +91 -0
- package/src/modules/audit/generated/kysely-tailordb.ts +92 -0
- package/src/modules/audit/index.ts +2 -0
- package/src/modules/audit/lib/_db_deps.ts +13 -0
- package/src/modules/audit/lib/errors.generated.ts +120 -0
- package/src/modules/audit/lib/permissions.generated.ts +14 -0
- package/src/modules/audit/lib/types.ts +28 -0
- package/src/modules/audit/module.ts +57 -0
- package/src/modules/audit/permissions.ts +39 -0
- package/src/modules/audit/query/getAuditEntry.generated.ts +5 -0
- package/src/modules/audit/query/getAuditEntry.test.ts +123 -0
- package/src/modules/audit/query/getAuditEntry.ts +36 -0
- package/src/modules/audit/query/getAuditPolicy.generated.ts +5 -0
- package/src/modules/audit/query/getAuditPolicy.test.ts +169 -0
- package/src/modules/audit/query/getAuditPolicy.ts +42 -0
- package/src/modules/audit/query/getAuditSummary.generated.ts +5 -0
- package/src/modules/audit/query/getAuditSummary.test.ts +632 -0
- package/src/modules/audit/query/getAuditSummary.ts +164 -0
- package/src/modules/audit/query/getChangeDetails.generated.ts +5 -0
- package/src/modules/audit/query/getChangeDetails.test.ts +195 -0
- package/src/modules/audit/query/getChangeDetails.ts +42 -0
- package/src/modules/audit/query/listAuditPolicies.generated.ts +5 -0
- package/src/modules/audit/query/listAuditPolicies.test.ts +239 -0
- package/src/modules/audit/query/listAuditPolicies.ts +100 -0
- package/src/modules/audit/query/searchAuditEntries.generated.ts +5 -0
- package/src/modules/audit/query/searchAuditEntries.test.ts +424 -0
- package/src/modules/audit/query/searchAuditEntries.ts +121 -0
- package/src/modules/audit/tailor.config.ts +13 -0
- package/src/modules/audit/tailor.d.ts +13 -0
- package/src/modules/audit/testing/fixtures.ts +215 -0
- package/src/modules/business-partner/README.md +60 -0
- package/src/modules/business-partner/command/.gitkeep +0 -0
- package/src/modules/business-partner/command/activatePartner.generated.ts +6 -0
- package/src/modules/business-partner/command/activatePartner.test.ts +59 -0
- package/src/modules/business-partner/command/activatePartner.ts +45 -0
- package/src/modules/business-partner/command/assignRoleToPartner.generated.ts +6 -0
- package/src/modules/business-partner/command/assignRoleToPartner.test.ts +113 -0
- package/src/modules/business-partner/command/assignRoleToPartner.ts +72 -0
- package/src/modules/business-partner/command/createContactPerson.generated.ts +6 -0
- package/src/modules/business-partner/command/createContactPerson.test.ts +193 -0
- package/src/modules/business-partner/command/createContactPerson.ts +98 -0
- package/src/modules/business-partner/command/createPartner.generated.ts +6 -0
- package/src/modules/business-partner/command/createPartner.test.ts +179 -0
- package/src/modules/business-partner/command/createPartner.ts +83 -0
- package/src/modules/business-partner/command/createPartnerAddress.generated.ts +6 -0
- package/src/modules/business-partner/command/createPartnerAddress.test.ts +195 -0
- package/src/modules/business-partner/command/createPartnerAddress.ts +119 -0
- package/src/modules/business-partner/command/createPartnerBankAccount.generated.ts +6 -0
- package/src/modules/business-partner/command/createPartnerBankAccount.test.ts +297 -0
- package/src/modules/business-partner/command/createPartnerBankAccount.ts +114 -0
- package/src/modules/business-partner/command/createPartnerIdentification.generated.ts +6 -0
- package/src/modules/business-partner/command/createPartnerIdentification.test.ts +255 -0
- package/src/modules/business-partner/command/createPartnerIdentification.ts +97 -0
- package/src/modules/business-partner/command/deactivateContactPerson.generated.ts +6 -0
- package/src/modules/business-partner/command/deactivateContactPerson.test.ts +70 -0
- package/src/modules/business-partner/command/deactivateContactPerson.ts +54 -0
- package/src/modules/business-partner/command/deactivatePartner.generated.ts +6 -0
- package/src/modules/business-partner/command/deactivatePartner.test.ts +59 -0
- package/src/modules/business-partner/command/deactivatePartner.ts +46 -0
- package/src/modules/business-partner/command/deleteContactPerson.generated.ts +6 -0
- package/src/modules/business-partner/command/deleteContactPerson.test.ts +61 -0
- package/src/modules/business-partner/command/deleteContactPerson.ts +48 -0
- package/src/modules/business-partner/command/deletePartner.generated.ts +6 -0
- package/src/modules/business-partner/command/deletePartner.test.ts +58 -0
- package/src/modules/business-partner/command/deletePartner.ts +46 -0
- package/src/modules/business-partner/command/deletePartnerAddress.generated.ts +6 -0
- package/src/modules/business-partner/command/deletePartnerAddress.test.ts +74 -0
- package/src/modules/business-partner/command/deletePartnerAddress.ts +52 -0
- package/src/modules/business-partner/command/deletePartnerBankAccount.generated.ts +6 -0
- package/src/modules/business-partner/command/deletePartnerBankAccount.test.ts +55 -0
- package/src/modules/business-partner/command/deletePartnerBankAccount.ts +36 -0
- package/src/modules/business-partner/command/deletePartnerIdentification.generated.ts +6 -0
- package/src/modules/business-partner/command/deletePartnerIdentification.test.ts +47 -0
- package/src/modules/business-partner/command/deletePartnerIdentification.ts +37 -0
- package/src/modules/business-partner/command/reactivateContactPerson.generated.ts +6 -0
- package/src/modules/business-partner/command/reactivateContactPerson.test.ts +48 -0
- package/src/modules/business-partner/command/reactivateContactPerson.ts +48 -0
- package/src/modules/business-partner/command/reactivatePartner.generated.ts +6 -0
- package/src/modules/business-partner/command/reactivatePartner.test.ts +59 -0
- package/src/modules/business-partner/command/reactivatePartner.ts +46 -0
- package/src/modules/business-partner/command/removeRoleFromPartner.generated.ts +6 -0
- package/src/modules/business-partner/command/removeRoleFromPartner.test.ts +82 -0
- package/src/modules/business-partner/command/removeRoleFromPartner.ts +73 -0
- package/src/modules/business-partner/command/setDefaultPartnerAddress.generated.ts +6 -0
- package/src/modules/business-partner/command/setDefaultPartnerAddress.test.ts +60 -0
- package/src/modules/business-partner/command/setDefaultPartnerAddress.ts +48 -0
- package/src/modules/business-partner/command/setDefaultPartnerBankAccount.generated.ts +6 -0
- package/src/modules/business-partner/command/setDefaultPartnerBankAccount.test.ts +56 -0
- package/src/modules/business-partner/command/setDefaultPartnerBankAccount.ts +51 -0
- package/src/modules/business-partner/command/setPrimaryContactPerson.generated.ts +6 -0
- package/src/modules/business-partner/command/setPrimaryContactPerson.test.ts +63 -0
- package/src/modules/business-partner/command/setPrimaryContactPerson.ts +55 -0
- package/src/modules/business-partner/command/updateContactPerson.generated.ts +6 -0
- package/src/modules/business-partner/command/updateContactPerson.test.ts +193 -0
- package/src/modules/business-partner/command/updateContactPerson.ts +92 -0
- package/src/modules/business-partner/command/updatePartner.generated.ts +6 -0
- package/src/modules/business-partner/command/updatePartner.test.ts +101 -0
- package/src/modules/business-partner/command/updatePartner.ts +76 -0
- package/src/modules/business-partner/command/updatePartnerAddress.generated.ts +6 -0
- package/src/modules/business-partner/command/updatePartnerAddress.test.ts +148 -0
- package/src/modules/business-partner/command/updatePartnerAddress.ts +64 -0
- package/src/modules/business-partner/command/updatePartnerBankAccount.generated.ts +6 -0
- package/src/modules/business-partner/command/updatePartnerBankAccount.test.ts +249 -0
- package/src/modules/business-partner/command/updatePartnerBankAccount.ts +109 -0
- package/src/modules/business-partner/command/updatePartnerIdentification.generated.ts +6 -0
- package/src/modules/business-partner/command/updatePartnerIdentification.test.ts +162 -0
- package/src/modules/business-partner/command/updatePartnerIdentification.ts +105 -0
- package/src/modules/business-partner/db/.gitkeep +0 -0
- package/src/modules/business-partner/db/businessPartner.ts +59 -0
- package/src/modules/business-partner/db/contactPerson.ts +49 -0
- package/src/modules/business-partner/db/partnerAddress.ts +45 -0
- package/src/modules/business-partner/db/partnerBankAccount.ts +53 -0
- package/src/modules/business-partner/db/partnerIdentification.ts +53 -0
- package/src/modules/business-partner/db/partnerRole.ts +43 -0
- package/src/modules/business-partner/docs/commands/ActivatePartner.md +39 -0
- package/src/modules/business-partner/docs/commands/AssignRoleToPartner.md +49 -0
- package/src/modules/business-partner/docs/commands/CreateContactPerson.md +59 -0
- package/src/modules/business-partner/docs/commands/CreatePartner.md +54 -0
- package/src/modules/business-partner/docs/commands/CreatePartnerAddress.md +60 -0
- package/src/modules/business-partner/docs/commands/CreatePartnerBankAccount.md +68 -0
- package/src/modules/business-partner/docs/commands/CreatePartnerIdentification.md +59 -0
- package/src/modules/business-partner/docs/commands/DeactivateContactPerson.md +42 -0
- package/src/modules/business-partner/docs/commands/DeactivatePartner.md +39 -0
- package/src/modules/business-partner/docs/commands/DeleteContactPerson.md +43 -0
- package/src/modules/business-partner/docs/commands/DeletePartner.md +40 -0
- package/src/modules/business-partner/docs/commands/DeletePartnerAddress.md +40 -0
- package/src/modules/business-partner/docs/commands/DeletePartnerBankAccount.md +35 -0
- package/src/modules/business-partner/docs/commands/DeletePartnerIdentification.md +33 -0
- package/src/modules/business-partner/docs/commands/ReactivateContactPerson.md +38 -0
- package/src/modules/business-partner/docs/commands/ReactivatePartner.md +39 -0
- package/src/modules/business-partner/docs/commands/RemoveRoleFromPartner.md +46 -0
- package/src/modules/business-partner/docs/commands/SetDefaultPartnerAddress.md +38 -0
- package/src/modules/business-partner/docs/commands/SetDefaultPartnerBankAccount.md +38 -0
- package/src/modules/business-partner/docs/commands/SetPrimaryContactPerson.md +43 -0
- package/src/modules/business-partner/docs/commands/UpdateContactPerson.md +66 -0
- package/src/modules/business-partner/docs/commands/UpdatePartner.md +48 -0
- package/src/modules/business-partner/docs/commands/UpdatePartnerAddress.md +46 -0
- package/src/modules/business-partner/docs/commands/UpdatePartnerBankAccount.md +64 -0
- package/src/modules/business-partner/docs/commands/UpdatePartnerIdentification.md +52 -0
- package/src/modules/business-partner/docs/features/contact-person-management.md +70 -0
- package/src/modules/business-partner/docs/features/partner-address-management.md +96 -0
- package/src/modules/business-partner/docs/features/partner-bank-account.md +70 -0
- package/src/modules/business-partner/docs/features/partner-identification.md +76 -0
- package/src/modules/business-partner/docs/features/partner-lifecycle.md +59 -0
- package/src/modules/business-partner/docs/features/partner-role-classification.md +73 -0
- package/src/modules/business-partner/docs/models/BusinessPartner.md +64 -0
- package/src/modules/business-partner/docs/models/ContactPerson.md +62 -0
- package/src/modules/business-partner/docs/models/PartnerAddress.md +52 -0
- package/src/modules/business-partner/docs/models/PartnerBankAccount.md +50 -0
- package/src/modules/business-partner/docs/models/PartnerIdentification.md +46 -0
- package/src/modules/business-partner/docs/models/PartnerRole.md +42 -0
- package/src/modules/business-partner/docs/queries/GetContactPerson.md +34 -0
- package/src/modules/business-partner/docs/queries/GetDefaultPartnerAddress.md +40 -0
- package/src/modules/business-partner/docs/queries/GetDefaultPartnerBankAccount.md +36 -0
- package/src/modules/business-partner/docs/queries/GetPartner.md +35 -0
- package/src/modules/business-partner/docs/queries/GetPartnerAddress.md +34 -0
- package/src/modules/business-partner/docs/queries/GetPartnerBankAccount.md +34 -0
- package/src/modules/business-partner/docs/queries/GetPartnerIdentification.md +34 -0
- package/src/modules/business-partner/docs/queries/GetPartnerRole.md +34 -0
- package/src/modules/business-partner/docs/queries/GetPrimaryContactPerson.md +36 -0
- package/src/modules/business-partner/docs/queries/ListContactPersonsByPartner.md +39 -0
- package/src/modules/business-partner/docs/queries/ListPartnerAddressesByPartner.md +41 -0
- package/src/modules/business-partner/docs/queries/ListPartnerBankAccountsByPartner.md +39 -0
- package/src/modules/business-partner/docs/queries/ListPartnerIdentificationsByPartner.md +41 -0
- package/src/modules/business-partner/docs/queries/ListPartnersByRole.md +47 -0
- package/src/modules/business-partner/executor/.gitkeep +0 -0
- package/src/modules/business-partner/generated/.gitkeep +0 -0
- package/src/modules/business-partner/generated/enums.ts +60 -0
- package/src/modules/business-partner/generated/kysely-tailordb.ts +114 -0
- package/src/modules/business-partner/index.ts +2 -0
- package/src/modules/business-partner/lib/_db_deps.ts +17 -0
- package/src/modules/business-partner/lib/errors.generated.ts +172 -0
- package/src/modules/business-partner/lib/errors.ts +2 -0
- package/src/modules/business-partner/lib/permissions.generated.ts +30 -0
- package/src/modules/business-partner/lib/types.ts +53 -0
- package/src/modules/business-partner/module.ts +181 -0
- package/src/modules/business-partner/permissions.ts +3 -0
- package/src/modules/business-partner/query/.gitkeep +0 -0
- package/src/modules/business-partner/query/getContactPerson.generated.ts +5 -0
- package/src/modules/business-partner/query/getContactPerson.test.ts +31 -0
- package/src/modules/business-partner/query/getContactPerson.ts +16 -0
- package/src/modules/business-partner/query/getDefaultPartnerAddress.generated.ts +5 -0
- package/src/modules/business-partner/query/getDefaultPartnerAddress.test.ts +45 -0
- package/src/modules/business-partner/query/getDefaultPartnerAddress.ts +30 -0
- package/src/modules/business-partner/query/getDefaultPartnerBankAccount.generated.ts +5 -0
- package/src/modules/business-partner/query/getDefaultPartnerBankAccount.test.ts +43 -0
- package/src/modules/business-partner/query/getDefaultPartnerBankAccount.ts +17 -0
- package/src/modules/business-partner/query/getPartner.generated.ts +5 -0
- package/src/modules/business-partner/query/getPartner.test.ts +31 -0
- package/src/modules/business-partner/query/getPartner.ts +16 -0
- package/src/modules/business-partner/query/getPartnerAddress.generated.ts +5 -0
- package/src/modules/business-partner/query/getPartnerAddress.test.ts +31 -0
- package/src/modules/business-partner/query/getPartnerAddress.ts +16 -0
- package/src/modules/business-partner/query/getPartnerBankAccount.generated.ts +5 -0
- package/src/modules/business-partner/query/getPartnerBankAccount.test.ts +31 -0
- package/src/modules/business-partner/query/getPartnerBankAccount.ts +16 -0
- package/src/modules/business-partner/query/getPartnerIdentification.generated.ts +5 -0
- package/src/modules/business-partner/query/getPartnerIdentification.test.ts +31 -0
- package/src/modules/business-partner/query/getPartnerIdentification.ts +16 -0
- package/src/modules/business-partner/query/getPartnerRole.generated.ts +5 -0
- package/src/modules/business-partner/query/getPartnerRole.test.ts +31 -0
- package/src/modules/business-partner/query/getPartnerRole.ts +19 -0
- package/src/modules/business-partner/query/getPrimaryContactPerson.generated.ts +5 -0
- package/src/modules/business-partner/query/getPrimaryContactPerson.test.ts +43 -0
- package/src/modules/business-partner/query/getPrimaryContactPerson.ts +17 -0
- package/src/modules/business-partner/query/listContactPersonsByPartner.generated.ts +5 -0
- package/src/modules/business-partner/query/listContactPersonsByPartner.test.ts +77 -0
- package/src/modules/business-partner/query/listContactPersonsByPartner.ts +32 -0
- package/src/modules/business-partner/query/listPartnerAddressesByPartner.generated.ts +5 -0
- package/src/modules/business-partner/query/listPartnerAddressesByPartner.test.ts +71 -0
- package/src/modules/business-partner/query/listPartnerAddressesByPartner.ts +37 -0
- package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.generated.ts +5 -0
- package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.test.ts +59 -0
- package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.ts +32 -0
- package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.generated.ts +5 -0
- package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.test.ts +72 -0
- package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.ts +40 -0
- package/src/modules/business-partner/query/listPartnersByRole.generated.ts +5 -0
- package/src/modules/business-partner/query/listPartnersByRole.test.ts +103 -0
- package/src/modules/business-partner/query/listPartnersByRole.ts +47 -0
- package/src/modules/business-partner/tailor.config.ts +13 -0
- package/src/modules/business-partner/tailor.d.ts +13 -0
- package/src/modules/business-partner/testing/fixtures.ts +204 -0
- package/src/modules/coa-management/README.md +61 -0
- package/src/modules/coa-management/command/.gitkeep +0 -0
- package/src/modules/coa-management/command/activateAccount.generated.ts +6 -0
- package/src/modules/coa-management/command/activateAccount.test.ts +125 -0
- package/src/modules/coa-management/command/activateAccount.ts +105 -0
- package/src/modules/coa-management/command/activateChartOfAccounts.generated.ts +6 -0
- package/src/modules/coa-management/command/activateChartOfAccounts.test.ts +113 -0
- package/src/modules/coa-management/command/activateChartOfAccounts.ts +104 -0
- package/src/modules/coa-management/command/createAccount.generated.ts +6 -0
- package/src/modules/coa-management/command/createAccount.test.ts +767 -0
- package/src/modules/coa-management/command/createAccount.ts +247 -0
- package/src/modules/coa-management/command/createAccountGroup.generated.ts +6 -0
- package/src/modules/coa-management/command/createAccountGroup.test.ts +494 -0
- package/src/modules/coa-management/command/createAccountGroup.ts +207 -0
- package/src/modules/coa-management/command/createChartOfAccounts.generated.ts +6 -0
- package/src/modules/coa-management/command/createChartOfAccounts.test.ts +502 -0
- package/src/modules/coa-management/command/createChartOfAccounts.ts +267 -0
- package/src/modules/coa-management/command/deactivateAccount.generated.ts +6 -0
- package/src/modules/coa-management/command/deactivateAccount.test.ts +199 -0
- package/src/modules/coa-management/command/deactivateAccount.ts +142 -0
- package/src/modules/coa-management/command/deactivateChartOfAccounts.generated.ts +6 -0
- package/src/modules/coa-management/command/deactivateChartOfAccounts.test.ts +91 -0
- package/src/modules/coa-management/command/deactivateChartOfAccounts.ts +88 -0
- package/src/modules/coa-management/command/deleteAccount.generated.ts +6 -0
- package/src/modules/coa-management/command/deleteAccount.test.ts +122 -0
- package/src/modules/coa-management/command/deleteAccount.ts +103 -0
- package/src/modules/coa-management/command/deleteAccountGroup.generated.ts +6 -0
- package/src/modules/coa-management/command/deleteAccountGroup.test.ts +120 -0
- package/src/modules/coa-management/command/deleteAccountGroup.ts +113 -0
- package/src/modules/coa-management/command/deleteChartOfAccounts.generated.ts +6 -0
- package/src/modules/coa-management/command/deleteChartOfAccounts.test.ts +154 -0
- package/src/modules/coa-management/command/deleteChartOfAccounts.ts +133 -0
- package/src/modules/coa-management/command/moveAccountGroup.generated.ts +6 -0
- package/src/modules/coa-management/command/moveAccountGroup.test.ts +199 -0
- package/src/modules/coa-management/command/moveAccountGroup.ts +145 -0
- package/src/modules/coa-management/command/reactivateAccount.generated.ts +6 -0
- package/src/modules/coa-management/command/reactivateAccount.test.ts +126 -0
- package/src/modules/coa-management/command/reactivateAccount.ts +123 -0
- package/src/modules/coa-management/command/updateAccount.generated.ts +6 -0
- package/src/modules/coa-management/command/updateAccount.test.ts +669 -0
- package/src/modules/coa-management/command/updateAccount.ts +370 -0
- package/src/modules/coa-management/command/updateAccountGroup.generated.ts +6 -0
- package/src/modules/coa-management/command/updateAccountGroup.test.ts +253 -0
- package/src/modules/coa-management/command/updateAccountGroup.ts +191 -0
- package/src/modules/coa-management/command/updateChartOfAccounts.generated.ts +6 -0
- package/src/modules/coa-management/command/updateChartOfAccounts.test.ts +153 -0
- package/src/modules/coa-management/command/updateChartOfAccounts.ts +133 -0
- package/src/modules/coa-management/db/.gitkeep +0 -0
- package/src/modules/coa-management/db/account.ts +119 -0
- package/src/modules/coa-management/db/accountGroup.ts +57 -0
- package/src/modules/coa-management/db/chartOfAccounts.ts +55 -0
- package/src/modules/coa-management/docs/commands/ActivateAccount.md +49 -0
- package/src/modules/coa-management/docs/commands/ActivateChartOfAccounts.md +47 -0
- package/src/modules/coa-management/docs/commands/CreateAccount.md +94 -0
- package/src/modules/coa-management/docs/commands/CreateAccountGroup.md +70 -0
- package/src/modules/coa-management/docs/commands/CreateChartOfAccounts.md +72 -0
- package/src/modules/coa-management/docs/commands/DeactivateAccount.md +65 -0
- package/src/modules/coa-management/docs/commands/DeactivateChartOfAccounts.md +44 -0
- package/src/modules/coa-management/docs/commands/DeleteAccount.md +52 -0
- package/src/modules/coa-management/docs/commands/DeleteAccountGroup.md +50 -0
- package/src/modules/coa-management/docs/commands/DeleteChartOfAccounts.md +48 -0
- package/src/modules/coa-management/docs/commands/MoveAccountGroup.md +57 -0
- package/src/modules/coa-management/docs/commands/ReactivateAccount.md +50 -0
- package/src/modules/coa-management/docs/commands/UpdateAccount.md +102 -0
- package/src/modules/coa-management/docs/commands/UpdateAccountGroup.md +62 -0
- package/src/modules/coa-management/docs/commands/UpdateChartOfAccounts.md +49 -0
- package/src/modules/coa-management/docs/features/account-group-hierarchy.md +81 -0
- package/src/modules/coa-management/docs/features/account-lifecycle.md +80 -0
- package/src/modules/coa-management/docs/features/account-management.md +114 -0
- package/src/modules/coa-management/docs/features/chart-of-accounts-setup.md +86 -0
- package/src/modules/coa-management/docs/models/Account.md +84 -0
- package/src/modules/coa-management/docs/models/AccountGroup.md +55 -0
- package/src/modules/coa-management/docs/models/ChartOfAccounts.md +65 -0
- package/src/modules/coa-management/docs/queries/DetectCircularReference.md +52 -0
- package/src/modules/coa-management/docs/queries/GetAccount.md +42 -0
- package/src/modules/coa-management/docs/queries/GetAccountGroup.md +42 -0
- package/src/modules/coa-management/docs/queries/GetChartOfAccounts.md +48 -0
- package/src/modules/coa-management/docs/queries/ListAccountGroups.md +42 -0
- package/src/modules/coa-management/docs/queries/ListAccounts.md +54 -0
- package/src/modules/coa-management/docs/queries/ListUnassignedAccounts.md +40 -0
- package/src/modules/coa-management/executor/.gitkeep +0 -0
- package/src/modules/coa-management/generated/.gitkeep +0 -0
- package/src/modules/coa-management/generated/enums.ts +45 -0
- package/src/modules/coa-management/generated/kysely-tailordb.ts +81 -0
- package/src/modules/coa-management/index.ts +2 -0
- package/src/modules/coa-management/lib/_db_deps.ts +17 -0
- package/src/modules/coa-management/lib/errors.generated.ts +162 -0
- package/src/modules/coa-management/lib/errors.ts +0 -0
- package/src/modules/coa-management/lib/permissions.generated.ts +20 -0
- package/src/modules/coa-management/lib/types.ts +22 -0
- package/src/modules/coa-management/module.ts +136 -0
- package/src/modules/coa-management/permissions.ts +3 -0
- package/src/modules/coa-management/query/.gitkeep +0 -0
- package/src/modules/coa-management/query/detectCircularReference.generated.ts +5 -0
- package/src/modules/coa-management/query/detectCircularReference.test.ts +88 -0
- package/src/modules/coa-management/query/detectCircularReference.ts +46 -0
- package/src/modules/coa-management/query/getAccount.generated.ts +5 -0
- package/src/modules/coa-management/query/getAccount.test.ts +55 -0
- package/src/modules/coa-management/query/getAccount.ts +25 -0
- package/src/modules/coa-management/query/getAccountGroup.generated.ts +5 -0
- package/src/modules/coa-management/query/getAccountGroup.test.ts +55 -0
- package/src/modules/coa-management/query/getAccountGroup.ts +25 -0
- package/src/modules/coa-management/query/getChartOfAccounts.generated.ts +5 -0
- package/src/modules/coa-management/query/getChartOfAccounts.test.ts +79 -0
- package/src/modules/coa-management/query/getChartOfAccounts.ts +28 -0
- package/src/modules/coa-management/query/listAccountGroups.generated.ts +5 -0
- package/src/modules/coa-management/query/listAccountGroups.test.ts +72 -0
- package/src/modules/coa-management/query/listAccountGroups.ts +49 -0
- package/src/modules/coa-management/query/listAccounts.generated.ts +5 -0
- package/src/modules/coa-management/query/listAccounts.test.ts +136 -0
- package/src/modules/coa-management/query/listAccounts.ts +82 -0
- package/src/modules/coa-management/query/listUnassignedAccounts.generated.ts +5 -0
- package/src/modules/coa-management/query/listUnassignedAccounts.test.ts +96 -0
- package/src/modules/coa-management/query/listUnassignedAccounts.ts +39 -0
- package/src/modules/coa-management/tailor.config.ts +13 -0
- package/src/modules/coa-management/tailor.d.ts +13 -0
- package/src/modules/coa-management/testing/fixtures.ts +201 -0
- package/src/modules/item-management/README.md +1 -1
- package/src/modules/organization/README.md +57 -0
- package/src/modules/organization/command/.gitkeep +0 -0
- package/src/modules/organization/command/activateCompany.generated.ts +6 -0
- package/src/modules/organization/command/activateCompany.test.ts +184 -0
- package/src/modules/organization/command/activateCompany.ts +92 -0
- package/src/modules/organization/command/createCompany.generated.ts +6 -0
- package/src/modules/organization/command/createCompany.test.ts +156 -0
- package/src/modules/organization/command/createCompany.ts +80 -0
- package/src/modules/organization/command/createDepartment.generated.ts +6 -0
- package/src/modules/organization/command/createDepartment.test.ts +239 -0
- package/src/modules/organization/command/createDepartment.ts +98 -0
- package/src/modules/organization/command/createSite.generated.ts +6 -0
- package/src/modules/organization/command/createSite.test.ts +262 -0
- package/src/modules/organization/command/createSite.ts +155 -0
- package/src/modules/organization/command/deactivateCompany.generated.ts +6 -0
- package/src/modules/organization/command/deactivateCompany.test.ts +58 -0
- package/src/modules/organization/command/deactivateCompany.ts +47 -0
- package/src/modules/organization/command/deactivateDepartment.generated.ts +6 -0
- package/src/modules/organization/command/deactivateDepartment.test.ts +115 -0
- package/src/modules/organization/command/deactivateDepartment.ts +63 -0
- package/src/modules/organization/command/deactivateSite.generated.ts +6 -0
- package/src/modules/organization/command/deactivateSite.test.ts +53 -0
- package/src/modules/organization/command/deactivateSite.ts +47 -0
- package/src/modules/organization/command/deleteCompany.generated.ts +6 -0
- package/src/modules/organization/command/deleteCompany.test.ts +99 -0
- package/src/modules/organization/command/deleteCompany.ts +66 -0
- package/src/modules/organization/command/reactivateCompany.generated.ts +6 -0
- package/src/modules/organization/command/reactivateCompany.test.ts +58 -0
- package/src/modules/organization/command/reactivateCompany.ts +47 -0
- package/src/modules/organization/command/reactivateDepartment.generated.ts +6 -0
- package/src/modules/organization/command/reactivateDepartment.test.ts +59 -0
- package/src/modules/organization/command/reactivateDepartment.ts +47 -0
- package/src/modules/organization/command/reactivateSite.generated.ts +6 -0
- package/src/modules/organization/command/reactivateSite.test.ts +53 -0
- package/src/modules/organization/command/reactivateSite.ts +47 -0
- package/src/modules/organization/command/updateCompany.generated.ts +6 -0
- package/src/modules/organization/command/updateCompany.test.ts +239 -0
- package/src/modules/organization/command/updateCompany.ts +127 -0
- package/src/modules/organization/command/updateDepartment.generated.ts +6 -0
- package/src/modules/organization/command/updateDepartment.test.ts +232 -0
- package/src/modules/organization/command/updateDepartment.ts +120 -0
- package/src/modules/organization/command/updateSite.generated.ts +6 -0
- package/src/modules/organization/command/updateSite.test.ts +274 -0
- package/src/modules/organization/command/updateSite.ts +176 -0
- package/src/modules/organization/db/.gitkeep +0 -0
- package/src/modules/organization/db/company.ts +44 -0
- package/src/modules/organization/db/department.ts +46 -0
- package/src/modules/organization/db/site.ts +44 -0
- package/src/modules/organization/docs/commands/ActivateCompany.md +62 -0
- package/src/modules/organization/docs/commands/CreateCompany.md +49 -0
- package/src/modules/organization/docs/commands/CreateDepartment.md +62 -0
- package/src/modules/organization/docs/commands/CreateSite.md +74 -0
- package/src/modules/organization/docs/commands/DeactivateCompany.md +40 -0
- package/src/modules/organization/docs/commands/DeactivateDepartment.md +44 -0
- package/src/modules/organization/docs/commands/DeactivateSite.md +38 -0
- package/src/modules/organization/docs/commands/DeleteCompany.md +50 -0
- package/src/modules/organization/docs/commands/ReactivateCompany.md +39 -0
- package/src/modules/organization/docs/commands/ReactivateDepartment.md +37 -0
- package/src/modules/organization/docs/commands/ReactivateSite.md +37 -0
- package/src/modules/organization/docs/commands/UpdateCompany.md +58 -0
- package/src/modules/organization/docs/commands/UpdateDepartment.md +64 -0
- package/src/modules/organization/docs/commands/UpdateSite.md +80 -0
- package/src/modules/organization/docs/features/company-lifecycle.md +76 -0
- package/src/modules/organization/docs/features/department-management.md +66 -0
- package/src/modules/organization/docs/features/site-management.md +86 -0
- package/src/modules/organization/docs/models/Company.md +60 -0
- package/src/modules/organization/docs/models/Department.md +57 -0
- package/src/modules/organization/docs/models/Site.md +57 -0
- package/src/modules/organization/docs/queries/DetectDepartmentCircularReference.md +50 -0
- package/src/modules/organization/docs/queries/GetCompany.md +40 -0
- package/src/modules/organization/docs/queries/GetDepartment.md +44 -0
- package/src/modules/organization/docs/queries/GetDepartmentChildren.md +40 -0
- package/src/modules/organization/docs/queries/GetSite.md +37 -0
- package/src/modules/organization/docs/queries/ListDepartmentsByCompany.md +54 -0
- package/src/modules/organization/docs/queries/ListSitesByCompany.md +54 -0
- package/src/modules/organization/executor/.gitkeep +0 -0
- package/src/modules/organization/generated/.gitkeep +0 -0
- package/src/modules/organization/generated/kysely-tailordb.ts +77 -0
- package/src/modules/organization/index.ts +2 -0
- package/src/modules/organization/lib/_db_deps.ts +10 -0
- package/src/modules/organization/lib/errors.generated.ts +117 -0
- package/src/modules/organization/lib/errors.ts +1 -0
- package/src/modules/organization/lib/permissions.generated.ts +19 -0
- package/src/modules/organization/lib/types.ts +16 -0
- package/src/modules/organization/module.ts +89 -0
- package/src/modules/organization/permissions.ts +3 -0
- package/src/modules/organization/query/.gitkeep +0 -0
- package/src/modules/organization/query/detectDepartmentCircularReference.generated.ts +5 -0
- package/src/modules/organization/query/detectDepartmentCircularReference.test.ts +102 -0
- package/src/modules/organization/query/detectDepartmentCircularReference.ts +27 -0
- package/src/modules/organization/query/getCompany.generated.ts +5 -0
- package/src/modules/organization/query/getCompany.test.ts +70 -0
- package/src/modules/organization/query/getCompany.ts +16 -0
- package/src/modules/organization/query/getDepartment.generated.ts +5 -0
- package/src/modules/organization/query/getDepartment.test.ts +85 -0
- package/src/modules/organization/query/getDepartment.ts +17 -0
- package/src/modules/organization/query/getDepartmentChildren.generated.ts +5 -0
- package/src/modules/organization/query/getDepartmentChildren.test.ts +75 -0
- package/src/modules/organization/query/getDepartmentChildren.ts +21 -0
- package/src/modules/organization/query/getSite.generated.ts +5 -0
- package/src/modules/organization/query/getSite.test.ts +55 -0
- package/src/modules/organization/query/getSite.ts +16 -0
- package/src/modules/organization/query/listDepartmentsByCompany.generated.ts +5 -0
- package/src/modules/organization/query/listDepartmentsByCompany.test.ts +124 -0
- package/src/modules/organization/query/listDepartmentsByCompany.ts +43 -0
- package/src/modules/organization/query/listSitesByCompany.generated.ts +5 -0
- package/src/modules/organization/query/listSitesByCompany.test.ts +126 -0
- package/src/modules/organization/query/listSitesByCompany.ts +41 -0
- package/src/modules/organization/tailor.config.ts +13 -0
- package/src/modules/organization/tailor.d.ts +13 -0
- package/src/modules/organization/testing/fixtures.ts +155 -0
- package/src/modules/primitives/README.md +1 -1
- package/src/modules/primitives/command/setBaseCurrency.test.ts +8 -64
- package/src/modules/primitives/command/setBaseCurrency.ts +6 -64
- package/src/modules/primitives/docs/commands/ActivateCategory.md +1 -1
- package/src/modules/primitives/docs/commands/ActivateCurrency.md +1 -1
- package/src/modules/primitives/docs/commands/ActivateUnit.md +1 -1
- package/src/modules/primitives/docs/commands/CreateExchangeRate.md +2 -2
- package/src/modules/primitives/docs/commands/CreateUnit.md +1 -1
- package/src/modules/primitives/docs/commands/DeactivateCategory.md +1 -1
- package/src/modules/primitives/docs/commands/DeactivateCurrency.md +1 -1
- package/src/modules/primitives/docs/commands/DeactivateUnit.md +1 -1
- package/src/modules/primitives/docs/commands/SetBaseCurrency.md +13 -23
- package/src/modules/primitives/docs/commands/SetReferenceUnit.md +1 -1
- package/src/modules/primitives/docs/features/currency-definitions.md +13 -14
- package/src/modules/primitives/docs/models/Currency.md +3 -4
- package/src/modules/primitives/docs/queries/ConvertAmount.md +2 -2
- package/src/modules/primitives/docs/queries/ConvertQuantity.md +2 -2
- package/src/modules/primitives/lib/errors.generated.ts +5 -0
- package/src/modules/product-management/README.md +1 -1
- package/src/modules/user-management/docs/commands/CreatePermission.md +3 -3
- package/src/modules/user-management/docs/commands/CreateRole.md +1 -1
- package/src/modules/user-management/docs/queries/ListRolePermissionsByRole.md +39 -0
- package/src/modules/user-management/docs/queries/ListUserRolesByUser.md +39 -0
- package/src/modules/user-management/generated/enums.ts +0 -15
- package/src/modules/user-management/generated/kysely-tailordb.ts +0 -11
- package/src/shared/createContext.ts +2 -1
- package/src/shared/defineQuery.ts +36 -1
- package/src/shared/requirePermission.ts +3 -3
- package/src/shared/types.ts +3 -0
- package/templates/scaffold/app/backend/package.json +8 -7
- package/templates/scaffold/app/frontend/eslint.config.js +12 -0
- package/templates/scaffold/app/frontend/package.json +19 -16
- package/templates/scaffold/app/frontend/src/hooks/use-toast.ts +30 -0
- package/templates/scaffold/app/frontend/src/pages/user-management/user/create/components/create-user-form.tsx +3 -2
- package/templates/scaffold/app/frontend/vite.config.ts +5 -5
- package/templates/workflows/erp-kit-check.yml +2 -2
- package/src/commands/module/list.test.ts +0 -57
- package/src/commands/module/list.ts +0 -64
- package/src/commands/scaffold.ts +0 -176
- /package/src/modules/{accounting → audit/db}/.gitkeep +0 -0
- /package/src/modules/audit/{.gitkeep → executor/.gitkeep} +0 -0
- /package/src/modules/{coa-management/.gitkeep → audit/lib/errors.ts} +0 -0
- /package/src/modules/{supplier-management → business-partner}/.gitkeep +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AuditableEntity,
|
|
3
|
+
AuditPolicy,
|
|
4
|
+
PolicyFieldRule,
|
|
5
|
+
AuditEntry,
|
|
6
|
+
ChangeDetail,
|
|
7
|
+
Schema,
|
|
8
|
+
} from "../lib/types";
|
|
9
|
+
|
|
10
|
+
// AuditableEntity fixtures
|
|
11
|
+
export const companyBoundEntity = {
|
|
12
|
+
id: "entity-1",
|
|
13
|
+
entityName: "SalesOrder",
|
|
14
|
+
entityScope: "COMPANY_BOUND",
|
|
15
|
+
auditableFields: JSON.stringify([
|
|
16
|
+
{ fieldName: "amount", fieldType: "scalar" },
|
|
17
|
+
{ fieldName: "status", fieldType: "scalar" },
|
|
18
|
+
{ fieldName: "customerId", fieldType: "relation" },
|
|
19
|
+
]),
|
|
20
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
21
|
+
updatedAt: null,
|
|
22
|
+
} as const satisfies AuditableEntity<Schema>;
|
|
23
|
+
|
|
24
|
+
export const globalEntity = {
|
|
25
|
+
id: "entity-2",
|
|
26
|
+
entityName: "User",
|
|
27
|
+
entityScope: "GLOBAL",
|
|
28
|
+
auditableFields: JSON.stringify([
|
|
29
|
+
{ fieldName: "email", fieldType: "scalar" },
|
|
30
|
+
{ fieldName: "role", fieldType: "scalar" },
|
|
31
|
+
{ fieldName: "isActive", fieldType: "scalar" },
|
|
32
|
+
]),
|
|
33
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
34
|
+
updatedAt: null,
|
|
35
|
+
} as const satisfies AuditableEntity<Schema>;
|
|
36
|
+
|
|
37
|
+
// AuditPolicy fixtures
|
|
38
|
+
export const draftPolicy = {
|
|
39
|
+
id: "policy-1",
|
|
40
|
+
entityName: "SalesOrder",
|
|
41
|
+
companyId: "company-1",
|
|
42
|
+
operationType: "UPDATE",
|
|
43
|
+
status: "DRAFT",
|
|
44
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
45
|
+
updatedAt: null,
|
|
46
|
+
} as const satisfies AuditPolicy<Schema>;
|
|
47
|
+
|
|
48
|
+
export const activePolicy = {
|
|
49
|
+
id: "policy-2",
|
|
50
|
+
entityName: "SalesOrder",
|
|
51
|
+
companyId: "company-1",
|
|
52
|
+
operationType: "UPDATE",
|
|
53
|
+
status: "ACTIVE",
|
|
54
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
55
|
+
updatedAt: null,
|
|
56
|
+
} as const satisfies AuditPolicy<Schema>;
|
|
57
|
+
|
|
58
|
+
export const inactivePolicy = {
|
|
59
|
+
id: "policy-3",
|
|
60
|
+
entityName: "SalesOrder",
|
|
61
|
+
companyId: "company-1",
|
|
62
|
+
operationType: "UPDATE",
|
|
63
|
+
status: "INACTIVE",
|
|
64
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
65
|
+
updatedAt: null,
|
|
66
|
+
} as const satisfies AuditPolicy<Schema>;
|
|
67
|
+
|
|
68
|
+
export const globalDraftPolicy = {
|
|
69
|
+
id: "policy-4",
|
|
70
|
+
entityName: "User",
|
|
71
|
+
companyId: null,
|
|
72
|
+
operationType: "CREATE",
|
|
73
|
+
status: "DRAFT",
|
|
74
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
75
|
+
updatedAt: null,
|
|
76
|
+
} as const satisfies AuditPolicy<Schema>;
|
|
77
|
+
|
|
78
|
+
export const globalActivePolicy = {
|
|
79
|
+
id: "policy-5",
|
|
80
|
+
entityName: "User",
|
|
81
|
+
companyId: null,
|
|
82
|
+
operationType: "CREATE",
|
|
83
|
+
status: "ACTIVE",
|
|
84
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
85
|
+
updatedAt: null,
|
|
86
|
+
} as const satisfies AuditPolicy<Schema>;
|
|
87
|
+
|
|
88
|
+
export const draftReplacementPolicy = {
|
|
89
|
+
id: "policy-6",
|
|
90
|
+
entityName: "SalesOrder",
|
|
91
|
+
companyId: "company-1",
|
|
92
|
+
operationType: "UPDATE",
|
|
93
|
+
status: "DRAFT",
|
|
94
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
95
|
+
updatedAt: null,
|
|
96
|
+
} as const satisfies AuditPolicy<Schema>;
|
|
97
|
+
|
|
98
|
+
// PolicyFieldRule fixtures
|
|
99
|
+
export const captureFieldRule = {
|
|
100
|
+
id: "rule-1",
|
|
101
|
+
auditPolicyId: "policy-2",
|
|
102
|
+
fieldName: "amount",
|
|
103
|
+
sensitivityMode: "CAPTURE",
|
|
104
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
105
|
+
updatedAt: null,
|
|
106
|
+
} as const satisfies PolicyFieldRule<Schema>;
|
|
107
|
+
|
|
108
|
+
export const maskFieldRule = {
|
|
109
|
+
id: "rule-2",
|
|
110
|
+
auditPolicyId: "policy-2",
|
|
111
|
+
fieldName: "customerId",
|
|
112
|
+
sensitivityMode: "MASK",
|
|
113
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
114
|
+
updatedAt: null,
|
|
115
|
+
} as const satisfies PolicyFieldRule<Schema>;
|
|
116
|
+
|
|
117
|
+
export const hashFieldRule = {
|
|
118
|
+
id: "rule-3",
|
|
119
|
+
auditPolicyId: "policy-2",
|
|
120
|
+
fieldName: "status",
|
|
121
|
+
sensitivityMode: "HASH",
|
|
122
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
123
|
+
updatedAt: null,
|
|
124
|
+
} as const satisfies PolicyFieldRule<Schema>;
|
|
125
|
+
|
|
126
|
+
export const excludeFieldRule = {
|
|
127
|
+
id: "rule-4",
|
|
128
|
+
auditPolicyId: "policy-2",
|
|
129
|
+
fieldName: "amount",
|
|
130
|
+
sensitivityMode: "EXCLUDE",
|
|
131
|
+
createdAt: new Date("2024-01-01T00:00:00.000Z"),
|
|
132
|
+
updatedAt: null,
|
|
133
|
+
} as const satisfies PolicyFieldRule<Schema>;
|
|
134
|
+
|
|
135
|
+
// AuditEntry fixtures
|
|
136
|
+
export const baseAuditEntry = {
|
|
137
|
+
id: "entry-1",
|
|
138
|
+
eventId: "event-uuid-1",
|
|
139
|
+
actorType: "USER",
|
|
140
|
+
actorId: "user-1",
|
|
141
|
+
entityType: "SalesOrder",
|
|
142
|
+
entityId: "so-1",
|
|
143
|
+
operationType: "UPDATE",
|
|
144
|
+
companyId: "company-1",
|
|
145
|
+
correlationId: null,
|
|
146
|
+
ipAddress: null,
|
|
147
|
+
userAgent: null,
|
|
148
|
+
sessionId: null,
|
|
149
|
+
requestId: null,
|
|
150
|
+
onBehalfOf: null,
|
|
151
|
+
timestamp: new Date("2024-01-15T10:30:00.000Z"),
|
|
152
|
+
createdAt: new Date("2024-01-15T10:30:00.000Z"),
|
|
153
|
+
updatedAt: null,
|
|
154
|
+
} as const satisfies AuditEntry<Schema>;
|
|
155
|
+
|
|
156
|
+
export const globalAuditEntry = {
|
|
157
|
+
id: "entry-2",
|
|
158
|
+
eventId: "event-uuid-2",
|
|
159
|
+
actorType: "SYSTEM",
|
|
160
|
+
actorId: "system-job-1",
|
|
161
|
+
entityType: "User",
|
|
162
|
+
entityId: "user-2",
|
|
163
|
+
operationType: "CREATE",
|
|
164
|
+
companyId: null,
|
|
165
|
+
correlationId: "corr-uuid-1",
|
|
166
|
+
ipAddress: "192.168.1.1",
|
|
167
|
+
userAgent: "AuditBot/1.0",
|
|
168
|
+
sessionId: "session-1",
|
|
169
|
+
requestId: "req-1",
|
|
170
|
+
onBehalfOf: "user-3",
|
|
171
|
+
timestamp: new Date("2024-01-16T12:00:00.000Z"),
|
|
172
|
+
createdAt: new Date("2024-01-16T12:00:00.000Z"),
|
|
173
|
+
updatedAt: null,
|
|
174
|
+
} as const satisfies AuditEntry<Schema>;
|
|
175
|
+
|
|
176
|
+
// ChangeDetail fixtures
|
|
177
|
+
export const baseChangeDetail = {
|
|
178
|
+
id: "detail-1",
|
|
179
|
+
auditEntryId: "entry-1",
|
|
180
|
+
fieldName: "amount",
|
|
181
|
+
oldValue: "100.00",
|
|
182
|
+
newValue: "95.00",
|
|
183
|
+
createdAt: new Date("2024-01-15T10:30:00.000Z"),
|
|
184
|
+
updatedAt: null,
|
|
185
|
+
} as const satisfies ChangeDetail<Schema>;
|
|
186
|
+
|
|
187
|
+
export const maskedChangeDetail = {
|
|
188
|
+
id: "detail-2",
|
|
189
|
+
auditEntryId: "entry-1",
|
|
190
|
+
fieldName: "customerId",
|
|
191
|
+
oldValue: "***",
|
|
192
|
+
newValue: "***",
|
|
193
|
+
createdAt: new Date("2024-01-15T10:30:00.000Z"),
|
|
194
|
+
updatedAt: null,
|
|
195
|
+
} as const satisfies ChangeDetail<Schema>;
|
|
196
|
+
|
|
197
|
+
export const excludedChangeDetail = {
|
|
198
|
+
id: "detail-3",
|
|
199
|
+
auditEntryId: "entry-1",
|
|
200
|
+
fieldName: "amount",
|
|
201
|
+
oldValue: null,
|
|
202
|
+
newValue: null,
|
|
203
|
+
createdAt: new Date("2024-01-15T10:30:00.000Z"),
|
|
204
|
+
updatedAt: null,
|
|
205
|
+
} as const satisfies ChangeDetail<Schema>;
|
|
206
|
+
|
|
207
|
+
export const createChangeDetail = {
|
|
208
|
+
id: "detail-4",
|
|
209
|
+
auditEntryId: "entry-2",
|
|
210
|
+
fieldName: "email",
|
|
211
|
+
oldValue: null,
|
|
212
|
+
newValue: "user@example.com",
|
|
213
|
+
createdAt: new Date("2024-01-16T12:00:00.000Z"),
|
|
214
|
+
updatedAt: null,
|
|
215
|
+
} as const satisfies ChangeDetail<Schema>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# README
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Business Partner module manages the master data for all external parties the organization transacts with — suppliers, customers, or both. It provides a unified business partner entity following SAP's Business Partner model, where a single record can hold multiple roles (CUSTOMER, SUPPLIER) without duplication. Each partner is classified by type (ORGANIZATION or INDIVIDUAL), carries its own lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE), and is scoped to a company.
|
|
6
|
+
|
|
7
|
+
Partners serve as the authoritative counterparty reference for all downstream transactional modules. Sales orders reference a partner as the customer; purchase orders reference a partner as the supplier; accounting entries reference partners for accounts payable and receivable. The module also manages partner-owned sub-entities: addresses (billing, shipping, registered), contact persons (individuals at an organization), bank accounts (for AP/AR payments), and identification documents (tax IDs, VAT numbers, DUNS).
|
|
8
|
+
|
|
9
|
+
## Key Features
|
|
10
|
+
|
|
11
|
+
- **[Partner Lifecycle](docs/features/partner-lifecycle.md)**: Unified business partner entity with type distinction (ORGANIZATION/INDIVIDUAL), lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE), and core master data. The central entity that all downstream modules reference as the counterparty
|
|
12
|
+
- **[Partner Address Management](docs/features/partner-address-management.md)**: Multiple addresses per partner with type classification (BILLING, SHIPPING, REGISTERED, OTHER). Structured address format consistent with organization's Site addresses but separately owned for external parties
|
|
13
|
+
- **[Contact Person Management](docs/features/contact-person-management.md)**: Link individual contacts to their parent organization with name, email, phone, job title, and primary contact designation. Contact persons are sub-entities of ORGANIZATION-type partners, distinct from user-management login accounts
|
|
14
|
+
- **[Partner Role Classification](docs/features/partner-role-classification.md)**: Assign roles (CUSTOMER, SUPPLIER) to a partner additively. A single partner can serve multiple roles without record duplication, following SAP's unified BP model
|
|
15
|
+
- **[Partner Bank Account](docs/features/partner-bank-account.md)**: Store partner banking details (bank name, account number, routing, IBAN/SWIFT) for AP/AR payments. Multiple accounts per partner with default designation and currency reference
|
|
16
|
+
- **[Partner Identification](docs/features/partner-identification.md)**: Store tax IDs, VAT numbers, DUNS, company registry numbers, and other identification documents per partner. Supports multiple identification types with optional validity periods
|
|
17
|
+
|
|
18
|
+
## Module Scope
|
|
19
|
+
|
|
20
|
+
### In Scope
|
|
21
|
+
|
|
22
|
+
- Business partner master data management (create, update, delete, status transitions)
|
|
23
|
+
- Partner type distinction (ORGANIZATION and INDIVIDUAL)
|
|
24
|
+
- Partner lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE)
|
|
25
|
+
- Company-scoped partner records (each partner belongs to a company)
|
|
26
|
+
- Multiple addresses per partner with type classification and default designation
|
|
27
|
+
- Contact person management for ORGANIZATION-type partners
|
|
28
|
+
- Role classification (CUSTOMER, SUPPLIER) with additive assignment
|
|
29
|
+
- Bank account storage with default designation and currency reference
|
|
30
|
+
- Identification document storage (tax IDs, VAT, DUNS, etc.) with uniqueness enforcement
|
|
31
|
+
|
|
32
|
+
### Out of Scope
|
|
33
|
+
|
|
34
|
+
- Customer relationship management and sales pipeline (CRM module)
|
|
35
|
+
- Lead/prospect qualification and conversion workflows (CRM module)
|
|
36
|
+
- Supplier onboarding workflows with approval gates (`purchase` module)
|
|
37
|
+
- Supplier qualification, certification, and performance scoring (`purchase` module)
|
|
38
|
+
- Supplier catalog — linking suppliers to items they supply (`purchase` module)
|
|
39
|
+
- Payment terms and pricing rules (`payment-terms` module)
|
|
40
|
+
- Duplicate detection and automated merge (future enhancement)
|
|
41
|
+
- Partner portal and self-service capabilities (future enhancement)
|
|
42
|
+
- Activity logging — calls, emails, meetings, notes (CRM module)
|
|
43
|
+
- Know Your Customer (KYC) and sanctions screening workflows (compliance module)
|
|
44
|
+
|
|
45
|
+
### Scope Decision Rationale
|
|
46
|
+
|
|
47
|
+
Business-partner is scoped to **external party master data** — the "who we transact with" foundation. It owns the identity, classification, and contact details of every customer, supplier, or dual-role partner the organization deals with. This is separated from internal organizational structure (organization module) because external parties have fundamentally different lifecycles, data requirements, and access patterns than internal entities like companies, departments, and sites.
|
|
48
|
+
|
|
49
|
+
The unified partner model (one entity with role classification rather than separate Customer and Supplier entities) follows the SAP Business Partner pattern. This prevents duplicate records when the same company is both a customer and a supplier, simplifies address and contact management, and provides a single reference point for downstream modules.
|
|
50
|
+
|
|
51
|
+
Addresses are included here rather than in the organization module because partner addresses belong to external parties (billing/shipping for customers and suppliers), while organization's Site addresses belong to company-owned facilities. The address structure is consistent across both modules, but ownership and semantics differ.
|
|
52
|
+
|
|
53
|
+
Contact persons are included because knowing who to communicate with at a partner organization is core master data, not a CRM concern. However, activity tracking (logging calls, meetings, emails) is excluded as CRM functionality.
|
|
54
|
+
|
|
55
|
+
Supplier catalog (which suppliers provide which items), payment terms, and pricing are excluded because they involve transactional business rules that change at different rates than partner master data. A supplier catalog naturally fits in a purchasing module where it integrates with PO workflows. Payment terms belong in pricing/accounting where they interact with discount rules and installment plans.
|
|
56
|
+
|
|
57
|
+
## Module Dependencies
|
|
58
|
+
|
|
59
|
+
- [organization](../organization/README.md) — Company reference for partner scoping (each partner belongs to a company)
|
|
60
|
+
- [primitives](../primitives/README.md) — Currency definitions for bank account currency assignment
|
|
File without changes
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createMockDb } from "../../../testing/index";
|
|
3
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
4
|
+
import { InvalidStateTransitionError, PartnerNotFoundError } from "../lib/errors.generated";
|
|
5
|
+
import { baseActivePartner, baseDraftPartner, baseInactivePartner } from "../testing/fixtures";
|
|
6
|
+
import { run } from "./activatePartner";
|
|
7
|
+
|
|
8
|
+
describe("activatePartner", () => {
|
|
9
|
+
it("activates a DRAFT partner", async () => {
|
|
10
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
11
|
+
const activatedPartner = { ...baseDraftPartner, status: "ACTIVE" };
|
|
12
|
+
spies.select.mockReturnValueOnce(baseDraftPartner);
|
|
13
|
+
spies.update.mockReturnValue(activatedPartner);
|
|
14
|
+
|
|
15
|
+
const result = await run(db, { id: baseDraftPartner.id });
|
|
16
|
+
|
|
17
|
+
expect(result.ok).toBe(true);
|
|
18
|
+
if (result.ok) {
|
|
19
|
+
expect(result.value.partner.status).toBe("ACTIVE");
|
|
20
|
+
}
|
|
21
|
+
expect(spies.update).toHaveBeenCalled();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("returns error when partner not found", async () => {
|
|
25
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
26
|
+
spies.select.mockReturnValue(undefined);
|
|
27
|
+
|
|
28
|
+
const result = await run(db, { id: "nonexistent" });
|
|
29
|
+
|
|
30
|
+
expect(result.ok).toBe(false);
|
|
31
|
+
if (!result.ok) {
|
|
32
|
+
expect(result.error).toBeInstanceOf(PartnerNotFoundError);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("returns error when partner is ACTIVE", async () => {
|
|
37
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
38
|
+
spies.select.mockReturnValueOnce(baseActivePartner);
|
|
39
|
+
|
|
40
|
+
const result = await run(db, { id: baseActivePartner.id });
|
|
41
|
+
|
|
42
|
+
expect(result.ok).toBe(false);
|
|
43
|
+
if (!result.ok) {
|
|
44
|
+
expect(result.error).toBeInstanceOf(InvalidStateTransitionError);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("returns error when partner is INACTIVE", async () => {
|
|
49
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
50
|
+
spies.select.mockReturnValueOnce(baseInactivePartner);
|
|
51
|
+
|
|
52
|
+
const result = await run(db, { id: baseInactivePartner.id });
|
|
53
|
+
|
|
54
|
+
expect(result.ok).toBe(false);
|
|
55
|
+
if (!result.ok) {
|
|
56
|
+
expect(result.error).toBeInstanceOf(InvalidStateTransitionError);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ok, err } from "../../../shared";
|
|
2
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
3
|
+
import { InvalidStateTransitionError, PartnerNotFoundError } from "../lib/errors.generated";
|
|
4
|
+
|
|
5
|
+
export interface ActivatePartnerInput {
|
|
6
|
+
id: string;
|
|
7
|
+
from?: string[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Function: activatePartner
|
|
12
|
+
*
|
|
13
|
+
* Transitions a business partner from DRAFT to ACTIVE status.
|
|
14
|
+
*/
|
|
15
|
+
export async function run(db: Transaction, input: ActivatePartnerInput) {
|
|
16
|
+
const { id, from } = input;
|
|
17
|
+
|
|
18
|
+
// 1. Check partner exists
|
|
19
|
+
const partner = await db
|
|
20
|
+
.selectFrom("BusinessPartner")
|
|
21
|
+
.selectAll()
|
|
22
|
+
.where("id", "=", id)
|
|
23
|
+
.forUpdate()
|
|
24
|
+
.executeTakeFirst();
|
|
25
|
+
|
|
26
|
+
if (!partner) {
|
|
27
|
+
return err(new PartnerNotFoundError(id));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 2. Check status is valid for activation
|
|
31
|
+
const validFromStatuses = from ?? ["DRAFT"];
|
|
32
|
+
if (!validFromStatuses.includes(partner.status)) {
|
|
33
|
+
return err(new InvalidStateTransitionError(`${partner.status} to ACTIVE`));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 3. Update status to ACTIVE
|
|
37
|
+
const activatedPartner = await db
|
|
38
|
+
.updateTable("BusinessPartner")
|
|
39
|
+
.set({ status: "ACTIVE", updatedAt: new Date() })
|
|
40
|
+
.where("id", "=", id)
|
|
41
|
+
.returningAll()
|
|
42
|
+
.executeTakeFirstOrThrow();
|
|
43
|
+
|
|
44
|
+
return ok({ partner: activatedPartner });
|
|
45
|
+
}
|
|
@@ -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 "./assignRoleToPartner";
|
|
5
|
+
|
|
6
|
+
export const assignRoleToPartner = defineCommand(permissions.assignRoleToPartner, run);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createMockDb } from "../../../testing/index";
|
|
3
|
+
import type { CommandContext } from "../../../shared";
|
|
4
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
5
|
+
import {
|
|
6
|
+
PartnerNotFoundError,
|
|
7
|
+
PartnerNotActiveError,
|
|
8
|
+
InvalidRoleError,
|
|
9
|
+
} from "../lib/errors.generated";
|
|
10
|
+
import {
|
|
11
|
+
baseActivePartner,
|
|
12
|
+
baseDraftPartner,
|
|
13
|
+
baseInactivePartner,
|
|
14
|
+
baseCustomerRole,
|
|
15
|
+
baseSupplierRole,
|
|
16
|
+
} from "../testing/fixtures";
|
|
17
|
+
import { run } from "./assignRoleToPartner";
|
|
18
|
+
|
|
19
|
+
const ctx: CommandContext = {
|
|
20
|
+
actorId: "test-actor",
|
|
21
|
+
permissions: ["business-partner:assignRoleToPartner"],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe("assignRoleToPartner", () => {
|
|
25
|
+
it("assigns CUSTOMER to partner with no roles", async () => {
|
|
26
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
27
|
+
spies.select.mockReturnValueOnce(baseActivePartner); // partner lookup
|
|
28
|
+
spies.select.mockReturnValueOnce(undefined); // no existing role
|
|
29
|
+
spies.insert.mockReturnValue({ ...baseCustomerRole, id: "role-new" });
|
|
30
|
+
|
|
31
|
+
const result = await run(db, { partnerId: "partner-2", role: "CUSTOMER" }, ctx);
|
|
32
|
+
|
|
33
|
+
expect(result.ok).toBe(true);
|
|
34
|
+
if (result.ok) {
|
|
35
|
+
expect(result.value.partnerRole).toBeDefined();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("assigns SUPPLIER to partner that already holds CUSTOMER", async () => {
|
|
40
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
41
|
+
spies.select.mockReturnValueOnce(baseActivePartner); // partner lookup
|
|
42
|
+
spies.select.mockReturnValueOnce(undefined); // no existing SUPPLIER role
|
|
43
|
+
spies.insert.mockReturnValue({ ...baseSupplierRole, id: "role-new" });
|
|
44
|
+
|
|
45
|
+
const result = await run(db, { partnerId: "partner-2", role: "SUPPLIER" }, ctx);
|
|
46
|
+
|
|
47
|
+
expect(result.ok).toBe(true);
|
|
48
|
+
if (result.ok) {
|
|
49
|
+
expect(result.value.partnerRole).toBeDefined();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("idempotent when role already assigned", async () => {
|
|
54
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
55
|
+
spies.select.mockReturnValueOnce(baseActivePartner); // partner lookup
|
|
56
|
+
spies.select.mockReturnValueOnce(baseCustomerRole); // existing role found
|
|
57
|
+
|
|
58
|
+
const result = await run(db, { partnerId: "partner-2", role: "CUSTOMER" }, ctx);
|
|
59
|
+
|
|
60
|
+
expect(result.ok).toBe(true);
|
|
61
|
+
if (result.ok) {
|
|
62
|
+
expect(result.value.partnerRole).toEqual(baseCustomerRole);
|
|
63
|
+
}
|
|
64
|
+
expect(spies.insert).not.toHaveBeenCalled();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("returns error when partner not found", async () => {
|
|
68
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
69
|
+
spies.select.mockReturnValueOnce(undefined); // partner not found
|
|
70
|
+
|
|
71
|
+
const result = await run(db, { partnerId: "nonexistent", role: "CUSTOMER" }, ctx);
|
|
72
|
+
|
|
73
|
+
expect(result.ok).toBe(false);
|
|
74
|
+
if (!result.ok) {
|
|
75
|
+
expect(result.error).toBeInstanceOf(PartnerNotFoundError);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("returns error when partner is INACTIVE", async () => {
|
|
80
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
81
|
+
spies.select.mockReturnValueOnce(baseInactivePartner); // partner in INACTIVE
|
|
82
|
+
|
|
83
|
+
const result = await run(db, { partnerId: "partner-3", role: "CUSTOMER" }, ctx);
|
|
84
|
+
|
|
85
|
+
expect(result.ok).toBe(false);
|
|
86
|
+
if (!result.ok) {
|
|
87
|
+
expect(result.error).toBeInstanceOf(PartnerNotActiveError);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("returns error when partner is DRAFT", async () => {
|
|
92
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
93
|
+
spies.select.mockReturnValueOnce(baseDraftPartner); // partner in DRAFT
|
|
94
|
+
|
|
95
|
+
const result = await run(db, { partnerId: "partner-1", role: "CUSTOMER" }, ctx);
|
|
96
|
+
|
|
97
|
+
expect(result.ok).toBe(false);
|
|
98
|
+
if (!result.ok) {
|
|
99
|
+
expect(result.error).toBeInstanceOf(PartnerNotActiveError);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("returns error when role is invalid", async () => {
|
|
104
|
+
const { db } = createMockDb<Transaction>();
|
|
105
|
+
|
|
106
|
+
const result = await run(db, { partnerId: "partner-2", role: "INVALID_ROLE" }, ctx);
|
|
107
|
+
|
|
108
|
+
expect(result.ok).toBe(false);
|
|
109
|
+
if (!result.ok) {
|
|
110
|
+
expect(result.error).toBeInstanceOf(InvalidRoleError);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ok, err, type CommandContext } from "../../../shared";
|
|
2
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
3
|
+
import {
|
|
4
|
+
PartnerNotFoundError,
|
|
5
|
+
PartnerNotActiveError,
|
|
6
|
+
InvalidRoleError,
|
|
7
|
+
} from "../lib/errors.generated";
|
|
8
|
+
|
|
9
|
+
type ValidRole = "CUSTOMER" | "SUPPLIER";
|
|
10
|
+
const VALID_ROLES: readonly ValidRole[] = ["CUSTOMER", "SUPPLIER"] as const;
|
|
11
|
+
|
|
12
|
+
export interface AssignRoleToPartnerInput {
|
|
13
|
+
partnerId: string;
|
|
14
|
+
role: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Function: assignRoleToPartner
|
|
19
|
+
*
|
|
20
|
+
* Assigns a CUSTOMER or SUPPLIER role to an ACTIVE partner. Idempotent —
|
|
21
|
+
* returns the existing role if already assigned.
|
|
22
|
+
*/
|
|
23
|
+
export async function run(db: Transaction, input: AssignRoleToPartnerInput, _ctx: CommandContext) {
|
|
24
|
+
const { partnerId, role } = input;
|
|
25
|
+
|
|
26
|
+
// 1. Validate role
|
|
27
|
+
if (!VALID_ROLES.includes(role as ValidRole)) {
|
|
28
|
+
return err(new InvalidRoleError(role ?? ""));
|
|
29
|
+
}
|
|
30
|
+
const validRole = role as ValidRole;
|
|
31
|
+
|
|
32
|
+
// 2. Check partner exists and is ACTIVE
|
|
33
|
+
const partner = await db
|
|
34
|
+
.selectFrom("BusinessPartner")
|
|
35
|
+
.selectAll()
|
|
36
|
+
.where("id", "=", partnerId)
|
|
37
|
+
.forUpdate()
|
|
38
|
+
.executeTakeFirst();
|
|
39
|
+
|
|
40
|
+
if (!partner) {
|
|
41
|
+
return err(new PartnerNotFoundError(partnerId));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (partner.status !== "ACTIVE") {
|
|
45
|
+
return err(new PartnerNotActiveError(partnerId));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 3. Check if role already assigned (idempotent)
|
|
49
|
+
const existingRole = await db
|
|
50
|
+
.selectFrom("PartnerRole")
|
|
51
|
+
.selectAll()
|
|
52
|
+
.where("partnerId", "=", partnerId)
|
|
53
|
+
.where("role", "=", validRole)
|
|
54
|
+
.executeTakeFirst();
|
|
55
|
+
|
|
56
|
+
if (existingRole) {
|
|
57
|
+
return ok({ partnerRole: existingRole });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 4. Create new role
|
|
61
|
+
const partnerRole = await db
|
|
62
|
+
.insertInto("PartnerRole")
|
|
63
|
+
.values({
|
|
64
|
+
partnerId,
|
|
65
|
+
role: validRole,
|
|
66
|
+
updatedAt: null,
|
|
67
|
+
})
|
|
68
|
+
.returningAll()
|
|
69
|
+
.executeTakeFirst();
|
|
70
|
+
|
|
71
|
+
return ok({ partnerRole: partnerRole! });
|
|
72
|
+
}
|
|
@@ -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 "./createContactPerson";
|
|
5
|
+
|
|
6
|
+
export const createContactPerson = defineCommand(permissions.createContactPerson, run);
|