@dainamite/cpq 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 +70 -0
- package/LICENSE +21 -0
- package/MIGRATION.md +236 -0
- package/README.md +108 -0
- package/dist/modules/cpq/acl.js +30 -0
- package/dist/modules/cpq/acl.js.map +7 -0
- package/dist/modules/cpq/api/_helpers/handleArcError.js +37 -0
- package/dist/modules/cpq/api/_helpers/handleArcError.js.map +7 -0
- package/dist/modules/cpq/api/attribute-options/route.js +47 -0
- package/dist/modules/cpq/api/attribute-options/route.js.map +7 -0
- package/dist/modules/cpq/api/bundle-slots/route.js +101 -0
- package/dist/modules/cpq/api/bundle-slots/route.js.map +7 -0
- package/dist/modules/cpq/api/bundle-tree/route.js +28 -0
- package/dist/modules/cpq/api/bundle-tree/route.js.map +7 -0
- package/dist/modules/cpq/api/context.js +29 -0
- package/dist/modules/cpq/api/context.js.map +7 -0
- package/dist/modules/cpq/api/inventory/assets/route.js +113 -0
- package/dist/modules/cpq/api/inventory/assets/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/assets/status/route.js +35 -0
- package/dist/modules/cpq/api/inventory/assets/status/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/customer/[customerId]/parent-items/route.js +30 -0
- package/dist/modules/cpq/api/inventory/customer/[customerId]/parent-items/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/customer/[customerId]/route.js +31 -0
- package/dist/modules/cpq/api/inventory/customer/[customerId]/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/subscription-items/route.js +99 -0
- package/dist/modules/cpq/api/inventory/subscription-items/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/subscriptions/[subscriptionId]/change-log/route.js +57 -0
- package/dist/modules/cpq/api/inventory/subscriptions/[subscriptionId]/change-log/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/subscriptions/expiring/route.js +62 -0
- package/dist/modules/cpq/api/inventory/subscriptions/expiring/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/subscriptions/route.js +116 -0
- package/dist/modules/cpq/api/inventory/subscriptions/route.js.map +7 -0
- package/dist/modules/cpq/api/inventory/subscriptions/status/route.js +35 -0
- package/dist/modules/cpq/api/inventory/subscriptions/status/route.js.map +7 -0
- package/dist/modules/cpq/api/offering-components/route.js +91 -0
- package/dist/modules/cpq/api/offering-components/route.js.map +7 -0
- package/dist/modules/cpq/api/orders/[orderId]/activate/route.js +39 -0
- package/dist/modules/cpq/api/orders/[orderId]/activate/route.js.map +7 -0
- package/dist/modules/cpq/api/orders/[orderId]/route.js +28 -0
- package/dist/modules/cpq/api/orders/[orderId]/route.js.map +7 -0
- package/dist/modules/cpq/api/orders/[orderId]/status/route.js +38 -0
- package/dist/modules/cpq/api/orders/[orderId]/status/route.js.map +7 -0
- package/dist/modules/cpq/api/orders/route.js +71 -0
- package/dist/modules/cpq/api/orders/route.js.map +7 -0
- package/dist/modules/cpq/api/price-rules/route.js +180 -0
- package/dist/modules/cpq/api/price-rules/route.js.map +7 -0
- package/dist/modules/cpq/api/pricing-table-entries/route.js +142 -0
- package/dist/modules/cpq/api/pricing-table-entries/route.js.map +7 -0
- package/dist/modules/cpq/api/pricing-tables/route.js +179 -0
- package/dist/modules/cpq/api/pricing-tables/route.js.map +7 -0
- package/dist/modules/cpq/api/product-attributes/route.js +160 -0
- package/dist/modules/cpq/api/product-attributes/route.js.map +7 -0
- package/dist/modules/cpq/api/product-charges/route.js +166 -0
- package/dist/modules/cpq/api/product-charges/route.js.map +7 -0
- package/dist/modules/cpq/api/product-offerings/route.js +294 -0
- package/dist/modules/cpq/api/product-offerings/route.js.map +7 -0
- package/dist/modules/cpq/api/product-relationships/route.js +144 -0
- package/dist/modules/cpq/api/product-relationships/route.js.map +7 -0
- package/dist/modules/cpq/api/product-specifications/route.js +292 -0
- package/dist/modules/cpq/api/product-specifications/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/cancel-meta/route.js +71 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/cancel-meta/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/clone/route.js +29 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/clone/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/items/[lineId]/route.js +54 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/items/[lineId]/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/items/route.js +27 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/items/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/merge-meta/route.js +72 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/merge-meta/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/recalculate/route.js +35 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/recalculate/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/route.js +102 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/status/route.js +27 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/status/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/target-subscriptions/[targetId]/route.js +79 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/target-subscriptions/[targetId]/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/target-subscriptions/route.js +95 -0
- package/dist/modules/cpq/api/quotes/[quoteId]/target-subscriptions/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/attributes/route.js +52 -0
- package/dist/modules/cpq/api/quotes/attributes/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/from-subscription/route.js +72 -0
- package/dist/modules/cpq/api/quotes/from-subscription/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/price/route.js +69 -0
- package/dist/modules/cpq/api/quotes/price/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/route.js +97 -0
- package/dist/modules/cpq/api/quotes/route.js.map +7 -0
- package/dist/modules/cpq/api/quotes/validate-relationships/route.js +86 -0
- package/dist/modules/cpq/api/quotes/validate-relationships/route.js.map +7 -0
- package/dist/modules/cpq/api/resolveQuotingService.js +7 -0
- package/dist/modules/cpq/api/resolveQuotingService.js.map +7 -0
- package/dist/modules/cpq/api/wizards/resolve/route.js +38 -0
- package/dist/modules/cpq/api/wizards/resolve/route.js.map +7 -0
- package/dist/modules/cpq/api/wizards/route.js +111 -0
- package/dist/modules/cpq/api/wizards/route.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js +136 -0
- package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js +185 -0
- package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js +343 -0
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js +13 -0
- package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/page.js +35 -0
- package/dist/modules/cpq/backend/cpq/inventory/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/inventory/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/shared.js +20 -0
- package/dist/modules/cpq/backend/cpq/inventory/shared.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js +794 -0
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js +13 -0
- package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js +917 -0
- package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/offerings/page.js +405 -0
- package/dist/modules/cpq/backend/cpq/offerings/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/offerings/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/offerings/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/orders/[id]/page.js +677 -0
- package/dist/modules/cpq/backend/cpq/orders/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/orders/page.js +134 -0
- package/dist/modules/cpq/backend/cpq/orders/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/orders/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/orders/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js +272 -0
- package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js +407 -0
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js +13 -0
- package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/price-rules/page.js +211 -0
- package/dist/modules/cpq/backend/cpq/price-rules/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/price-rules/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/price-rules/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js +275 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js +112 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js +492 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxExport.js +50 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxExport.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js +249 -0
- package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/page.js +87 -0
- package/dist/modules/cpq/backend/cpq/pricing/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/pricing/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/pricing/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js +652 -0
- package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js +1289 -0
- package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/quotes/page.js +283 -0
- package/dist/modules/cpq/backend/cpq/quotes/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/quotes/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/quotes/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js +214 -0
- package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js +1399 -0
- package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/specifications/page.js +148 -0
- package/dist/modules/cpq/backend/cpq/specifications/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/specifications/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/specifications/page.meta.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js +204 -0
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js +191 -0
- package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/wizards/page.js +119 -0
- package/dist/modules/cpq/backend/cpq/wizards/page.js.map +7 -0
- package/dist/modules/cpq/backend/cpq/wizards/page.meta.js +18 -0
- package/dist/modules/cpq/backend/cpq/wizards/page.meta.js.map +7 -0
- package/dist/modules/cpq/ce.js +151 -0
- package/dist/modules/cpq/ce.js.map +7 -0
- package/dist/modules/cpq/cli.js +11 -0
- package/dist/modules/cpq/cli.js.map +7 -0
- package/dist/modules/cpq/components/CpqListView.js +265 -0
- package/dist/modules/cpq/components/CpqListView.js.map +7 -0
- package/dist/modules/cpq/components/NumberInput.js +95 -0
- package/dist/modules/cpq/components/NumberInput.js.map +7 -0
- package/dist/modules/cpq/components/StatusPath.js +60 -0
- package/dist/modules/cpq/components/StatusPath.js.map +7 -0
- package/dist/modules/cpq/components/statusMaps.js +66 -0
- package/dist/modules/cpq/components/statusMaps.js.map +7 -0
- package/dist/modules/cpq/components/useCpqRowActions.js +125 -0
- package/dist/modules/cpq/components/useCpqRowActions.js.map +7 -0
- package/dist/modules/cpq/data/entities.js +1556 -0
- package/dist/modules/cpq/data/entities.js.map +7 -0
- package/dist/modules/cpq/data/validators.js +575 -0
- package/dist/modules/cpq/data/validators.js.map +7 -0
- package/dist/modules/cpq/di.js +57 -0
- package/dist/modules/cpq/di.js.map +7 -0
- package/dist/modules/cpq/events.js +50 -0
- package/dist/modules/cpq/events.js.map +7 -0
- package/dist/modules/cpq/index.js +16 -0
- package/dist/modules/cpq/index.js.map +7 -0
- package/dist/modules/cpq/lib/seeds/api.js +32 -0
- package/dist/modules/cpq/lib/seeds/api.js.map +7 -0
- package/dist/modules/cpq/lib/seeds/tenant-provisioning.js +158 -0
- package/dist/modules/cpq/lib/seeds/tenant-provisioning.js.map +7 -0
- package/dist/modules/cpq/lib/seeds.js +6 -0
- package/dist/modules/cpq/lib/seeds.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260220220000_cpq.js +40 -0
- package/dist/modules/cpq/migrations/Migration20260220220000_cpq.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260330000000_cpq_product_domain.js +54 -0
- package/dist/modules/cpq/migrations/Migration20260330000000_cpq_product_domain.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260331000000_cpq_charge_unique_per_offering.js +15 -0
- package/dist/modules/cpq/migrations/Migration20260331000000_cpq_charge_unique_per_offering.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260401000000_cpq_quoting_v2.js +62 -0
- package/dist/modules/cpq/migrations/Migration20260401000000_cpq_quoting_v2.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260402000000_cpq_workflows.js +56 -0
- package/dist/modules/cpq/migrations/Migration20260402000000_cpq_workflows.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260407000000_cpq_pricing_tables_v2.js +26 -0
- package/dist/modules/cpq/migrations/Migration20260407000000_cpq_pricing_tables_v2.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260407100000_cpq_price_rules.js +37 -0
- package/dist/modules/cpq/migrations/Migration20260407100000_cpq_price_rules.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260408000000_cpq_price_rules.js +35 -0
- package/dist/modules/cpq/migrations/Migration20260408000000_cpq_price_rules.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260410000000_cpq_drop_datacentres_inventory.js +21 -0
- package/dist/modules/cpq/migrations/Migration20260410000000_cpq_drop_datacentres_inventory.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260410000000_cpq_wizard_rename.js +46 -0
- package/dist/modules/cpq/migrations/Migration20260410000000_cpq_wizard_rename.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260410100000_cpq_inventory.js +118 -0
- package/dist/modules/cpq/migrations/Migration20260410100000_cpq_inventory.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260411000000_cpq_orders.js +63 -0
- package/dist/modules/cpq/migrations/Migration20260411000000_cpq_orders.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260412000000_cpq_bundled_offerings.js +28 -0
- package/dist/modules/cpq/migrations/Migration20260412000000_cpq_bundled_offerings.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260504064621_cpq_arc.js +36 -0
- package/dist/modules/cpq/migrations/Migration20260504064621_cpq_arc.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260514000000_cpq_spec_merge_retired_deprecated.js +14 -0
- package/dist/modules/cpq/migrations/Migration20260514000000_cpq_spec_merge_retired_deprecated.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260514100000_cpq_offering_merge_retired_deprecated.js +14 -0
- package/dist/modules/cpq/migrations/Migration20260514100000_cpq_offering_merge_retired_deprecated.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260514110000_cpq_list_search_indexes.js +58 -0
- package/dist/modules/cpq/migrations/Migration20260514110000_cpq_list_search_indexes.js.map +7 -0
- package/dist/modules/cpq/migrations/Migration20260515000000_cpq_inventory_subscriptions_search_indexes.js +29 -0
- package/dist/modules/cpq/migrations/Migration20260515000000_cpq_inventory_subscriptions_search_indexes.js.map +7 -0
- package/dist/modules/cpq/services/cpqBundleService.js +447 -0
- package/dist/modules/cpq/services/cpqBundleService.js.map +7 -0
- package/dist/modules/cpq/services/cpqInventoryService.js +1371 -0
- package/dist/modules/cpq/services/cpqInventoryService.js.map +7 -0
- package/dist/modules/cpq/services/cpqOrderService.js +901 -0
- package/dist/modules/cpq/services/cpqOrderService.js.map +7 -0
- package/dist/modules/cpq/services/cpqPricingService.js +289 -0
- package/dist/modules/cpq/services/cpqPricingService.js.map +7 -0
- package/dist/modules/cpq/services/cpqProductService.js +204 -0
- package/dist/modules/cpq/services/cpqProductService.js.map +7 -0
- package/dist/modules/cpq/services/cpqQuotingService.js +1867 -0
- package/dist/modules/cpq/services/cpqQuotingService.js.map +7 -0
- package/dist/modules/cpq/services/cpqValidationService.js +234 -0
- package/dist/modules/cpq/services/cpqValidationService.js.map +7 -0
- package/dist/modules/cpq/services/cpqWizardService.js +137 -0
- package/dist/modules/cpq/services/cpqWizardService.js.map +7 -0
- package/dist/modules/cpq/services/types.js +114 -0
- package/dist/modules/cpq/services/types.js.map +7 -0
- package/dist/modules/cpq/setup.js +49 -0
- package/dist/modules/cpq/setup.js.map +7 -0
- package/dist/modules/cpq/subscribers/subscription-amended-log.js +18 -0
- package/dist/modules/cpq/subscribers/subscription-amended-log.js.map +7 -0
- package/dist/modules/cpq/subscribers/subscription-cancelled-log.js +19 -0
- package/dist/modules/cpq/subscribers/subscription-cancelled-log.js.map +7 -0
- package/dist/modules/cpq/subscribers/subscription-merged-log.js +20 -0
- package/dist/modules/cpq/subscribers/subscription-merged-log.js.map +7 -0
- package/dist/modules/cpq/subscribers/subscription-renewed-log.js +18 -0
- package/dist/modules/cpq/subscribers/subscription-renewed-log.js.map +7 -0
- package/dist/modules/cpq/subscribers/subscription-superseded-log.js +18 -0
- package/dist/modules/cpq/subscribers/subscription-superseded-log.js.map +7 -0
- package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js +192 -0
- package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js.map +7 -0
- package/dist/modules/cpq/widgets/injection/customer-inventory/widget.js +17 -0
- package/dist/modules/cpq/widgets/injection/customer-inventory/widget.js.map +7 -0
- package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js +79 -0
- package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js.map +7 -0
- package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.js +17 -0
- package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.js.map +7 -0
- package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js +181 -0
- package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js.map +7 -0
- package/dist/modules/cpq/widgets/injection/quote-configurator/widget.js +17 -0
- package/dist/modules/cpq/widgets/injection/quote-configurator/widget.js.map +7 -0
- package/dist/modules/cpq/widgets/injection-table.js +44 -0
- package/dist/modules/cpq/widgets/injection-table.js.map +7 -0
- package/dist/modules/cpq/workflows/WizardRunner.js +113 -0
- package/dist/modules/cpq/workflows/WizardRunner.js.map +7 -0
- package/dist/modules/cpq/workflows/WizardTrigger.js +116 -0
- package/dist/modules/cpq/workflows/WizardTrigger.js.map +7 -0
- package/dist/modules/cpq/workflows/engine.js +188 -0
- package/dist/modules/cpq/workflows/engine.js.map +7 -0
- package/dist/modules/cpq/workflows/registry.js +16 -0
- package/dist/modules/cpq/workflows/registry.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js +119 -0
- package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/InventorySelectStep.js +24 -0
- package/dist/modules/cpq/workflows/steps/InventorySelectStep.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/ItemListStep.js +115 -0
- package/dist/modules/cpq/workflows/steps/ItemListStep.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js +327 -0
- package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js +231 -0
- package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/ReviewStep.js +152 -0
- package/dist/modules/cpq/workflows/steps/ReviewStep.js.map +7 -0
- package/dist/modules/cpq/workflows/steps/index.js +49 -0
- package/dist/modules/cpq/workflows/steps/index.js.map +7 -0
- package/dist/modules/cpq/workflows/types.js +1 -0
- package/dist/modules/cpq/workflows/types.js.map +7 -0
- package/package.json +150 -0
- package/src/modules/cpq/__integration__/TC-CPQ-001.spec.ts +177 -0
- package/src/modules/cpq/__integration__/TC-CPQ-002.spec.ts +123 -0
- package/src/modules/cpq/__integration__/TC-CPQ-003.spec.ts +115 -0
- package/src/modules/cpq/__integration__/TC-CPQ-004.spec.ts +184 -0
- package/src/modules/cpq/__integration__/TC-CPQ-005.spec.ts +43 -0
- package/src/modules/cpq/__integration__/TC-CPQ-006.spec.ts +87 -0
- package/src/modules/cpq/__integration__/TC-CPQ-007.spec.ts +79 -0
- package/src/modules/cpq/__integration__/TC-CPQ-008.spec.ts +55 -0
- package/src/modules/cpq/__integration__/TC-CPQ-009.spec.ts +45 -0
- package/src/modules/cpq/__integration__/TC-CPQ-010.spec.ts +54 -0
- package/src/modules/cpq/__integration__/TC-CPQ-011.spec.ts +24 -0
- package/src/modules/cpq/__integration__/TC-CPQ-012.spec.ts +62 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-001.spec.ts +52 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-002.spec.ts +65 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-003.spec.ts +107 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-004.spec.ts +74 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-005.spec.ts +86 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-006.spec.ts +79 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-007.spec.ts +63 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-008.spec.ts +62 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-009.spec.ts +62 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-010.spec.ts +59 -0
- package/src/modules/cpq/__integration__/TC-CPQ-ARC-011.spec.ts +128 -0
- package/src/modules/cpq/__integration__/_helpers/cpqArcFixtures.ts +208 -0
- package/src/modules/cpq/__tests__/package-isolation.test.ts +232 -0
- package/src/modules/cpq/acl.ts +26 -0
- package/src/modules/cpq/api/_helpers/__tests__/handleArcError.test.ts +117 -0
- package/src/modules/cpq/api/_helpers/handleArcError.ts +81 -0
- package/src/modules/cpq/api/attribute-options/route.ts +55 -0
- package/src/modules/cpq/api/bundle-slots/route.ts +112 -0
- package/src/modules/cpq/api/bundle-tree/route.ts +31 -0
- package/src/modules/cpq/api/context.ts +39 -0
- package/src/modules/cpq/api/inventory/assets/route.ts +123 -0
- package/src/modules/cpq/api/inventory/assets/status/route.ts +34 -0
- package/src/modules/cpq/api/inventory/customer/[customerId]/parent-items/route.ts +30 -0
- package/src/modules/cpq/api/inventory/customer/[customerId]/route.ts +31 -0
- package/src/modules/cpq/api/inventory/subscription-items/route.ts +107 -0
- package/src/modules/cpq/api/inventory/subscriptions/[subscriptionId]/change-log/route.ts +64 -0
- package/src/modules/cpq/api/inventory/subscriptions/expiring/route.ts +66 -0
- package/src/modules/cpq/api/inventory/subscriptions/route.ts +126 -0
- package/src/modules/cpq/api/inventory/subscriptions/status/route.ts +34 -0
- package/src/modules/cpq/api/offering-components/route.ts +103 -0
- package/src/modules/cpq/api/orders/[orderId]/activate/route.ts +48 -0
- package/src/modules/cpq/api/orders/[orderId]/route.ts +28 -0
- package/src/modules/cpq/api/orders/[orderId]/status/route.ts +38 -0
- package/src/modules/cpq/api/orders/route.ts +77 -0
- package/src/modules/cpq/api/price-rules/route.ts +210 -0
- package/src/modules/cpq/api/pricing-table-entries/route.ts +159 -0
- package/src/modules/cpq/api/pricing-tables/route.ts +202 -0
- package/src/modules/cpq/api/product-attributes/route.ts +175 -0
- package/src/modules/cpq/api/product-charges/route.ts +181 -0
- package/src/modules/cpq/api/product-offerings/route.ts +329 -0
- package/src/modules/cpq/api/product-relationships/route.ts +156 -0
- package/src/modules/cpq/api/product-specifications/route.ts +325 -0
- package/src/modules/cpq/api/quotes/[quoteId]/cancel-meta/route.ts +77 -0
- package/src/modules/cpq/api/quotes/[quoteId]/clone/route.ts +28 -0
- package/src/modules/cpq/api/quotes/[quoteId]/items/[lineId]/route.ts +55 -0
- package/src/modules/cpq/api/quotes/[quoteId]/items/route.ts +26 -0
- package/src/modules/cpq/api/quotes/[quoteId]/merge-meta/route.ts +78 -0
- package/src/modules/cpq/api/quotes/[quoteId]/recalculate/route.ts +34 -0
- package/src/modules/cpq/api/quotes/[quoteId]/route.ts +109 -0
- package/src/modules/cpq/api/quotes/[quoteId]/status/route.ts +26 -0
- package/src/modules/cpq/api/quotes/[quoteId]/target-subscriptions/[targetId]/route.ts +91 -0
- package/src/modules/cpq/api/quotes/[quoteId]/target-subscriptions/route.ts +107 -0
- package/src/modules/cpq/api/quotes/attributes/route.ts +61 -0
- package/src/modules/cpq/api/quotes/from-subscription/route.ts +85 -0
- package/src/modules/cpq/api/quotes/price/route.ts +81 -0
- package/src/modules/cpq/api/quotes/route.ts +114 -0
- package/src/modules/cpq/api/quotes/validate-relationships/route.ts +100 -0
- package/src/modules/cpq/api/resolveQuotingService.ts +11 -0
- package/src/modules/cpq/api/wizards/resolve/route.ts +39 -0
- package/src/modules/cpq/api/wizards/route.ts +127 -0
- package/src/modules/cpq/backend/cpq/inventory/AssetsTable.tsx +166 -0
- package/src/modules/cpq/backend/cpq/inventory/SubscriptionsTable.tsx +251 -0
- package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.ts +9 -0
- package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.tsx +440 -0
- package/src/modules/cpq/backend/cpq/inventory/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/inventory/page.tsx +49 -0
- package/src/modules/cpq/backend/cpq/inventory/shared.tsx +32 -0
- package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.ts +9 -0
- package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.tsx +1085 -0
- package/src/modules/cpq/backend/cpq/offerings/[id]/page.tsx +1165 -0
- package/src/modules/cpq/backend/cpq/offerings/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/offerings/page.tsx +468 -0
- package/src/modules/cpq/backend/cpq/orders/[id]/page.tsx +921 -0
- package/src/modules/cpq/backend/cpq/orders/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/orders/page.tsx +182 -0
- package/src/modules/cpq/backend/cpq/price-rules/PriceRuleForm.tsx +310 -0
- package/src/modules/cpq/backend/cpq/price-rules/[id]/page.meta.ts +9 -0
- package/src/modules/cpq/backend/cpq/price-rules/[id]/page.tsx +472 -0
- package/src/modules/cpq/backend/cpq/price-rules/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/price-rules/page.tsx +253 -0
- package/src/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.tsx +431 -0
- package/src/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.tsx +122 -0
- package/src/modules/cpq/backend/cpq/pricing/[id]/page.tsx +588 -0
- package/src/modules/cpq/backend/cpq/pricing/[id]/xlsxExport.ts +90 -0
- package/src/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.ts +338 -0
- package/src/modules/cpq/backend/cpq/pricing/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/pricing/page.tsx +111 -0
- package/src/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.tsx +737 -0
- package/src/modules/cpq/backend/cpq/quotes/[id]/page.tsx +1721 -0
- package/src/modules/cpq/backend/cpq/quotes/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/quotes/page.tsx +370 -0
- package/src/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.tsx +300 -0
- package/src/modules/cpq/backend/cpq/specifications/[id]/page.tsx +1722 -0
- package/src/modules/cpq/backend/cpq/specifications/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/specifications/page.tsx +191 -0
- package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.tsx +319 -0
- package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/page.tsx +234 -0
- package/src/modules/cpq/backend/cpq/wizards/page.meta.ts +16 -0
- package/src/modules/cpq/backend/cpq/wizards/page.tsx +141 -0
- package/src/modules/cpq/ce.ts +150 -0
- package/src/modules/cpq/cli.ts +10 -0
- package/src/modules/cpq/components/CpqListView.tsx +431 -0
- package/src/modules/cpq/components/NumberInput.tsx +166 -0
- package/src/modules/cpq/components/StatusPath.tsx +116 -0
- package/src/modules/cpq/components/statusMaps.ts +148 -0
- package/src/modules/cpq/components/useCpqRowActions.tsx +183 -0
- package/src/modules/cpq/data/__tests__/validators.arc.test.ts +271 -0
- package/src/modules/cpq/data/__tests__/validators.test.ts +782 -0
- package/src/modules/cpq/data/entities.ts +1467 -0
- package/src/modules/cpq/data/validators.ts +663 -0
- package/src/modules/cpq/di.ts +70 -0
- package/src/modules/cpq/events.ts +62 -0
- package/src/modules/cpq/index.ts +15 -0
- package/src/modules/cpq/lib/seeds/__tests__/api.test.ts +86 -0
- package/src/modules/cpq/lib/seeds/__tests__/tenant-provisioning.test.ts +349 -0
- package/src/modules/cpq/lib/seeds/api.ts +119 -0
- package/src/modules/cpq/lib/seeds/tenant-provisioning.ts +239 -0
- package/src/modules/cpq/lib/seeds.ts +18 -0
- package/src/modules/cpq/migrations/.snapshot-open-mercato.json +7473 -0
- package/src/modules/cpq/migrations/Migration20260220220000_cpq.ts +51 -0
- package/src/modules/cpq/migrations/Migration20260330000000_cpq_product_domain.ts +70 -0
- package/src/modules/cpq/migrations/Migration20260331000000_cpq_charge_unique_per_offering.ts +15 -0
- package/src/modules/cpq/migrations/Migration20260401000000_cpq_quoting_v2.ts +73 -0
- package/src/modules/cpq/migrations/Migration20260402000000_cpq_workflows.ts +59 -0
- package/src/modules/cpq/migrations/Migration20260407000000_cpq_pricing_tables_v2.ts +30 -0
- package/src/modules/cpq/migrations/Migration20260407100000_cpq_price_rules.ts +36 -0
- package/src/modules/cpq/migrations/Migration20260408000000_cpq_price_rules.ts +33 -0
- package/src/modules/cpq/migrations/Migration20260410000000_cpq_drop_datacentres_inventory.ts +22 -0
- package/src/modules/cpq/migrations/Migration20260410000000_cpq_wizard_rename.ts +56 -0
- package/src/modules/cpq/migrations/Migration20260410100000_cpq_inventory.ts +118 -0
- package/src/modules/cpq/migrations/Migration20260411000000_cpq_orders.ts +62 -0
- package/src/modules/cpq/migrations/Migration20260412000000_cpq_bundled_offerings.ts +33 -0
- package/src/modules/cpq/migrations/Migration20260504064621_cpq_arc.ts +68 -0
- package/src/modules/cpq/migrations/Migration20260514000000_cpq_spec_merge_retired_deprecated.ts +30 -0
- package/src/modules/cpq/migrations/Migration20260514100000_cpq_offering_merge_retired_deprecated.ts +27 -0
- package/src/modules/cpq/migrations/Migration20260514110000_cpq_list_search_indexes.ts +82 -0
- package/src/modules/cpq/migrations/Migration20260515000000_cpq_inventory_subscriptions_search_indexes.ts +52 -0
- package/src/modules/cpq/services/__tests__/_helpers/mockEm.ts +59 -0
- package/src/modules/cpq/services/__tests__/cpqBundleService.test.ts +661 -0
- package/src/modules/cpq/services/__tests__/cpqInventoryService.arc.test.ts +357 -0
- package/src/modules/cpq/services/__tests__/cpqInventoryService.test.ts +718 -0
- package/src/modules/cpq/services/__tests__/cpqOrderService.test.ts +603 -0
- package/src/modules/cpq/services/__tests__/cpqPricingService.test.ts +1012 -0
- package/src/modules/cpq/services/__tests__/cpqProductService.test.ts +603 -0
- package/src/modules/cpq/services/__tests__/cpqQuotingService.arc.test.ts +143 -0
- package/src/modules/cpq/services/__tests__/cpqQuotingService.test.ts +658 -0
- package/src/modules/cpq/services/__tests__/cpqValidationService.test.ts +811 -0
- package/src/modules/cpq/services/__tests__/cpqWizardService.test.ts +389 -0
- package/src/modules/cpq/services/__tests__/types.test.ts +359 -0
- package/src/modules/cpq/services/cpqBundleService.ts +671 -0
- package/src/modules/cpq/services/cpqInventoryService.ts +1929 -0
- package/src/modules/cpq/services/cpqOrderService.ts +1230 -0
- package/src/modules/cpq/services/cpqPricingService.ts +412 -0
- package/src/modules/cpq/services/cpqProductService.ts +311 -0
- package/src/modules/cpq/services/cpqQuotingService.ts +2638 -0
- package/src/modules/cpq/services/cpqValidationService.ts +323 -0
- package/src/modules/cpq/services/cpqWizardService.ts +204 -0
- package/src/modules/cpq/services/types.ts +303 -0
- package/src/modules/cpq/setup.ts +63 -0
- package/src/modules/cpq/subscribers/subscription-amended-log.ts +20 -0
- package/src/modules/cpq/subscribers/subscription-cancelled-log.ts +19 -0
- package/src/modules/cpq/subscribers/subscription-merged-log.ts +22 -0
- package/src/modules/cpq/subscribers/subscription-renewed-log.ts +18 -0
- package/src/modules/cpq/subscribers/subscription-superseded-log.ts +19 -0
- package/src/modules/cpq/widgets/injection/customer-inventory/widget.client.tsx +339 -0
- package/src/modules/cpq/widgets/injection/customer-inventory/widget.ts +16 -0
- package/src/modules/cpq/widgets/injection/order-cpq-tab/widget.client.tsx +96 -0
- package/src/modules/cpq/widgets/injection/order-cpq-tab/widget.ts +16 -0
- package/src/modules/cpq/widgets/injection/quote-configurator/widget.client.tsx +265 -0
- package/src/modules/cpq/widgets/injection/quote-configurator/widget.ts +16 -0
- package/src/modules/cpq/widgets/injection-table.ts +42 -0
- package/src/modules/cpq/workflows/WizardRunner.tsx +158 -0
- package/src/modules/cpq/workflows/WizardTrigger.tsx +142 -0
- package/src/modules/cpq/workflows/engine.tsx +278 -0
- package/src/modules/cpq/workflows/registry.ts +15 -0
- package/src/modules/cpq/workflows/steps/CustomerSelectStep.tsx +136 -0
- package/src/modules/cpq/workflows/steps/InventorySelectStep.tsx +34 -0
- package/src/modules/cpq/workflows/steps/ItemListStep.tsx +146 -0
- package/src/modules/cpq/workflows/steps/OfferingSelectStep.tsx +438 -0
- package/src/modules/cpq/workflows/steps/ProductConfigureStep.tsx +287 -0
- package/src/modules/cpq/workflows/steps/ReviewStep.tsx +219 -0
- package/src/modules/cpq/workflows/steps/index.ts +51 -0
- package/src/modules/cpq/workflows/types.ts +102 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
+
import type { AwilixContainer } from 'awilix'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Public API for the CPQ multi-tenant use-case seeding system (XD-276).
|
|
6
|
+
*
|
|
7
|
+
* A use case is a self-contained, idempotent unit that knows how to seed one
|
|
8
|
+
* tenant's worth of CPQ data (products, pricing tables, charges, attributes,
|
|
9
|
+
* price rules, bundles, wizards, optional demo customers/quotes).
|
|
10
|
+
*
|
|
11
|
+
* Use cases live OUTSIDE the cpq module (in `src/modules/@app/demo_<x>/`) so
|
|
12
|
+
* the cpq module remains free of customer-specific demo data when it is
|
|
13
|
+
* extracted to `@dainamite/cpq` per SPEC-001.
|
|
14
|
+
*
|
|
15
|
+
* Registration is process-local module state — populated when each demo
|
|
16
|
+
* module is imported by the framework's module bootstrap. The orchestrator
|
|
17
|
+
* (`@app/demo_tenants`) walks this registry at init time.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export type CpqUseCaseAdditionalUserSpec = {
|
|
21
|
+
/** Email address for the additional user, e.g. `employee@gix.com`. */
|
|
22
|
+
email: string
|
|
23
|
+
/** Initial password (dev-only — overridable via env). */
|
|
24
|
+
password: string
|
|
25
|
+
/** Optional display name. */
|
|
26
|
+
displayName?: string
|
|
27
|
+
/** Roles assigned to this user. Default `['employee']`. */
|
|
28
|
+
roles?: string[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type CpqUseCaseTenantSpec = {
|
|
32
|
+
/** Stable slug used as a key in env overrides, e.g. `gix`, `puffin`. */
|
|
33
|
+
slug: string
|
|
34
|
+
/** Tenant display name, e.g. `GIX Network Services Tenant`. */
|
|
35
|
+
tenantName: string
|
|
36
|
+
/** Organization display name, e.g. `GIX`. Defaults to `tenantName` if omitted. */
|
|
37
|
+
organizationName?: string
|
|
38
|
+
/** Primary admin email. e.g. `admin@gix.com`. */
|
|
39
|
+
adminEmail: string
|
|
40
|
+
/** Initial admin password (dev-only — overridable via env). */
|
|
41
|
+
adminPassword: string
|
|
42
|
+
/** Optional display name for the admin user. */
|
|
43
|
+
adminDisplayName?: string
|
|
44
|
+
/** Roles to ensure on the tenant; default `['admin', 'employee']` (no superadmin). */
|
|
45
|
+
roleNames?: string[]
|
|
46
|
+
/** Roles assigned to the primary admin user. Default `['admin']`. */
|
|
47
|
+
primaryUserRoles?: string[]
|
|
48
|
+
/** Whether to also create the derived `employee@<domain>` user. Default `false`. */
|
|
49
|
+
includeDerivedUsers?: boolean
|
|
50
|
+
/**
|
|
51
|
+
* Additional users to provision in this tenant alongside the admin.
|
|
52
|
+
* Each entry is created idempotently with the specified roles. Use this
|
|
53
|
+
* to seed e.g. `employee@gix.com` so a non-admin login is available.
|
|
54
|
+
*/
|
|
55
|
+
additionalUsers?: CpqUseCaseAdditionalUserSpec[]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type CpqUseCaseSeedContext = {
|
|
59
|
+
em: EntityManager
|
|
60
|
+
container: AwilixContainer
|
|
61
|
+
tenantId: string
|
|
62
|
+
organizationId: string
|
|
63
|
+
/**
|
|
64
|
+
* False when invoked under `mercato init --no-examples` — seeders MUST skip
|
|
65
|
+
* any demo customer/quote/order creation. seedDefaults still runs.
|
|
66
|
+
*/
|
|
67
|
+
withExamples: boolean
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type CpqUseCase = {
|
|
71
|
+
/** Stable id used by CLI flags and env vars; e.g. `gix`, `puffin`. */
|
|
72
|
+
id: string
|
|
73
|
+
/** Tenant provisioning spec — passed to `ensureDemoTenant`. */
|
|
74
|
+
tenant: CpqUseCaseTenantSpec
|
|
75
|
+
/** Idempotent. Seeds the catalog: specs, offerings, attributes, charges, pricing tables, rules, bundles, wizards. */
|
|
76
|
+
seedDefaults(ctx: CpqUseCaseSeedContext): Promise<void>
|
|
77
|
+
/** Optional. Seeds demo customers, quotes, orders. Skipped when --no-examples or CPQ_DEMO_SKIP_EXAMPLES. */
|
|
78
|
+
seedExamples?(ctx: CpqUseCaseSeedContext): Promise<void>
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const registry = new Map<string, CpqUseCase>()
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Register a use case. Called from the demo module's `setup.ts` on import.
|
|
85
|
+
*
|
|
86
|
+
* Re-registration with the same id overwrites and emits a warning. This keeps
|
|
87
|
+
* dev-server HMR working without throwing on every reload, while still
|
|
88
|
+
* surfacing accidental duplicate ids in logs.
|
|
89
|
+
*/
|
|
90
|
+
export function registerCpqUseCase(useCase: CpqUseCase): void {
|
|
91
|
+
if (!useCase || typeof useCase.id !== 'string' || useCase.id.length === 0) {
|
|
92
|
+
throw new Error('registerCpqUseCase: useCase.id is required')
|
|
93
|
+
}
|
|
94
|
+
if (!useCase.tenant || typeof useCase.tenant.adminEmail !== 'string') {
|
|
95
|
+
throw new Error(`registerCpqUseCase[${useCase.id}]: tenant.adminEmail is required`)
|
|
96
|
+
}
|
|
97
|
+
if (typeof useCase.seedDefaults !== 'function') {
|
|
98
|
+
throw new Error(`registerCpqUseCase[${useCase.id}]: seedDefaults must be a function`)
|
|
99
|
+
}
|
|
100
|
+
if (registry.has(useCase.id)) {
|
|
101
|
+
console.warn(`[cpq:seeds] Use case "${useCase.id}" re-registered — replacing prior registration.`)
|
|
102
|
+
}
|
|
103
|
+
registry.set(useCase.id, useCase)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Returns all registered use cases in registration order. */
|
|
107
|
+
export function listCpqUseCases(): CpqUseCase[] {
|
|
108
|
+
return Array.from(registry.values())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Returns the use case with the given id, or undefined. */
|
|
112
|
+
export function getCpqUseCase(id: string): CpqUseCase | undefined {
|
|
113
|
+
return registry.get(id)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Test-only helper to reset the registry between unit tests. */
|
|
117
|
+
export function clearCpqUseCases(): void {
|
|
118
|
+
registry.clear()
|
|
119
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { hash } from 'bcryptjs'
|
|
2
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
3
|
+
import type { AwilixContainer } from 'awilix'
|
|
4
|
+
import { setupInitialTenant } from '@open-mercato/core/modules/auth/lib/setup-app'
|
|
5
|
+
import { computeEmailHash } from '@open-mercato/core/modules/auth/lib/emailHash'
|
|
6
|
+
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
7
|
+
import { Role, User, UserRole } from '@open-mercato/core/modules/auth/data/entities'
|
|
8
|
+
import { isTenantDataEncryptionEnabled } from '@open-mercato/shared/lib/encryption/toggles'
|
|
9
|
+
import { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'
|
|
10
|
+
import { createKmsService } from '@open-mercato/shared/lib/encryption/kms'
|
|
11
|
+
import type { Module } from '@open-mercato/shared/modules/registry'
|
|
12
|
+
import type { CpqUseCaseAdditionalUserSpec, CpqUseCaseTenantSpec } from './api'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Outcome of `ensureDemoTenant`. `created` is true iff this call provisioned
|
|
16
|
+
* a new tenant; false if an existing tenant was reused (idempotent re-runs).
|
|
17
|
+
*/
|
|
18
|
+
export type EnsuredTenant = {
|
|
19
|
+
tenantId: string
|
|
20
|
+
organizationId: string
|
|
21
|
+
adminUserId: string
|
|
22
|
+
created: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type EnsureDemoTenantOptions = {
|
|
26
|
+
/**
|
|
27
|
+
* The full module list, used by `setupInitialTenant` to merge each module's
|
|
28
|
+
* `defaultRoleFeatures` into the tenant's role ACLs. MUST be passed when
|
|
29
|
+
* called from CLI bootstrap — otherwise the framework falls back to the
|
|
30
|
+
* runtime registry which may be empty in CLI context, leaving the new
|
|
31
|
+
* admin role with zero features (e.g. missing `dashboards.view`).
|
|
32
|
+
*/
|
|
33
|
+
modules?: Module[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Idempotent tenant provisioning for demo/use-case seeds (XD-276).
|
|
38
|
+
*
|
|
39
|
+
* Wraps `setupInitialTenant` from `@open-mercato/core/auth` so each demo
|
|
40
|
+
* tenant is bootstrapped through the same code path the framework uses for
|
|
41
|
+
* the primary tenant.
|
|
42
|
+
*
|
|
43
|
+
* Behavior:
|
|
44
|
+
* - If a user with `spec.adminEmail` already exists, return that tenant —
|
|
45
|
+
* no-op idempotent path. Re-running `yarn initialize` is safe.
|
|
46
|
+
* - Otherwise create Tenant, Organization, default Roles, primary admin
|
|
47
|
+
* user (and optionally a derived employee user), assign roles, and
|
|
48
|
+
* run all module `onTenantCreated` hooks.
|
|
49
|
+
* - After the admin tenant exists, every entry in `spec.additionalUsers`
|
|
50
|
+
* is provisioned idempotently in the new tenant scope.
|
|
51
|
+
*
|
|
52
|
+
* Demo tenants intentionally do NOT include the `superadmin` role — the
|
|
53
|
+
* only superadmin in the system is the one created by `mercato init` for
|
|
54
|
+
* the primary (ACME) tenant. Cross-tenant visibility for the primary
|
|
55
|
+
* superadmin is the framework default and is preserved.
|
|
56
|
+
*
|
|
57
|
+
* Password policy is bypassed implicitly: this helper calls
|
|
58
|
+
* `setupInitialTenant` directly (not via the `mercato auth setup` CLI
|
|
59
|
+
* command), and the policy check lives only in the CLI wrapper.
|
|
60
|
+
*/
|
|
61
|
+
export async function ensureDemoTenant(
|
|
62
|
+
em: EntityManager,
|
|
63
|
+
_container: AwilixContainer,
|
|
64
|
+
spec: CpqUseCaseTenantSpec,
|
|
65
|
+
options: EnsureDemoTenantOptions = {},
|
|
66
|
+
): Promise<EnsuredTenant> {
|
|
67
|
+
const orgName = spec.organizationName ?? spec.tenantName
|
|
68
|
+
const roleNames = spec.roleNames ?? ['admin', 'employee']
|
|
69
|
+
const primaryUserRoles = spec.primaryUserRoles ?? ['admin']
|
|
70
|
+
const includeDerivedUsers = spec.includeDerivedUsers ?? false
|
|
71
|
+
|
|
72
|
+
const result = await setupInitialTenant(em, {
|
|
73
|
+
orgName,
|
|
74
|
+
roleNames,
|
|
75
|
+
primaryUser: {
|
|
76
|
+
email: spec.adminEmail,
|
|
77
|
+
password: spec.adminPassword,
|
|
78
|
+
displayName: spec.adminDisplayName,
|
|
79
|
+
confirm: true,
|
|
80
|
+
},
|
|
81
|
+
primaryUserRoles,
|
|
82
|
+
includeSuperadminRole: false,
|
|
83
|
+
includeDerivedUsers,
|
|
84
|
+
failIfUserExists: false,
|
|
85
|
+
modules: options.modules,
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const primarySnapshot = result.users.find(
|
|
89
|
+
(entry) => entry.user.email?.toLowerCase() === spec.adminEmail.toLowerCase(),
|
|
90
|
+
)
|
|
91
|
+
let adminUserId = primarySnapshot?.user.id ? String(primarySnapshot.user.id) : null
|
|
92
|
+
|
|
93
|
+
if (!adminUserId) {
|
|
94
|
+
const fallback = await findOneWithDecryption(
|
|
95
|
+
em,
|
|
96
|
+
User,
|
|
97
|
+
{ email: spec.adminEmail },
|
|
98
|
+
{},
|
|
99
|
+
{ tenantId: result.tenantId, organizationId: result.organizationId },
|
|
100
|
+
)
|
|
101
|
+
adminUserId = fallback ? String(fallback.id) : null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!adminUserId) {
|
|
105
|
+
throw new Error(`ensureDemoTenant: failed to resolve admin user id for ${spec.adminEmail}`)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (spec.additionalUsers && spec.additionalUsers.length > 0) {
|
|
109
|
+
for (const userSpec of spec.additionalUsers) {
|
|
110
|
+
await ensureAdditionalUser(em, {
|
|
111
|
+
tenantId: result.tenantId,
|
|
112
|
+
organizationId: result.organizationId,
|
|
113
|
+
spec: userSpec,
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
tenantId: result.tenantId,
|
|
120
|
+
organizationId: result.organizationId,
|
|
121
|
+
adminUserId,
|
|
122
|
+
created: !result.reusedExistingUser,
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Look up a previously-provisioned demo tenant by admin email without
|
|
128
|
+
* creating anything. Returns null if not found.
|
|
129
|
+
*
|
|
130
|
+
* Useful for CLI commands that operate on existing tenants (e.g. `seed
|
|
131
|
+
* --use-case puffin` re-running on an already-initialized DB).
|
|
132
|
+
*/
|
|
133
|
+
export async function findDemoTenant(
|
|
134
|
+
em: EntityManager,
|
|
135
|
+
spec: CpqUseCaseTenantSpec,
|
|
136
|
+
): Promise<EnsuredTenant | null> {
|
|
137
|
+
const user = await findOneWithDecryption(
|
|
138
|
+
em,
|
|
139
|
+
User,
|
|
140
|
+
{ email: spec.adminEmail },
|
|
141
|
+
{},
|
|
142
|
+
{ tenantId: null, organizationId: null },
|
|
143
|
+
)
|
|
144
|
+
if (!user || !user.tenantId || !user.organizationId) return null
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
tenantId: String(user.tenantId),
|
|
148
|
+
organizationId: String(user.organizationId),
|
|
149
|
+
adminUserId: String(user.id),
|
|
150
|
+
created: false,
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function ensureAdditionalUser(
|
|
155
|
+
em: EntityManager,
|
|
156
|
+
args: {
|
|
157
|
+
tenantId: string
|
|
158
|
+
organizationId: string
|
|
159
|
+
spec: CpqUseCaseAdditionalUserSpec
|
|
160
|
+
},
|
|
161
|
+
): Promise<void> {
|
|
162
|
+
const { tenantId, organizationId, spec } = args
|
|
163
|
+
const roles = spec.roles && spec.roles.length > 0 ? spec.roles : ['employee']
|
|
164
|
+
|
|
165
|
+
const existing = await findOneWithDecryption(
|
|
166
|
+
em,
|
|
167
|
+
User,
|
|
168
|
+
{ email: spec.email },
|
|
169
|
+
{},
|
|
170
|
+
{ tenantId: null, organizationId: null },
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
let user: User
|
|
174
|
+
if (existing) {
|
|
175
|
+
user = existing
|
|
176
|
+
if (!user.tenantId) user.tenantId = tenantId
|
|
177
|
+
if (!user.organizationId) user.organizationId = organizationId
|
|
178
|
+
if (user.isConfirmed === false) user.isConfirmed = true
|
|
179
|
+
em.persist(user)
|
|
180
|
+
await em.flush()
|
|
181
|
+
} else {
|
|
182
|
+
const passwordHash = await hash(spec.password, 10)
|
|
183
|
+
let emailValue: string = spec.email
|
|
184
|
+
let emailHashValue: string = computeEmailHash(spec.email)
|
|
185
|
+
if (isTenantDataEncryptionEnabled()) {
|
|
186
|
+
try {
|
|
187
|
+
const encryptionService = new TenantDataEncryptionService(em as any, { kms: createKmsService() })
|
|
188
|
+
await encryptionService.invalidateMap('auth:user', tenantId, organizationId)
|
|
189
|
+
const encrypted = await encryptionService.encryptEntityPayload(
|
|
190
|
+
'auth:user',
|
|
191
|
+
{ email: spec.email },
|
|
192
|
+
tenantId,
|
|
193
|
+
organizationId,
|
|
194
|
+
)
|
|
195
|
+
emailValue = (encrypted as any).email ?? spec.email
|
|
196
|
+
emailHashValue = (encrypted as any).emailHash ?? computeEmailHash(spec.email)
|
|
197
|
+
} catch (err) {
|
|
198
|
+
console.warn(`[cpq:tenant-provisioning] Failed to encrypt additional user payload, falling back to plaintext (${(err as Error).message})`)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
user = em.create(User, {
|
|
202
|
+
email: emailValue,
|
|
203
|
+
emailHash: emailHashValue,
|
|
204
|
+
passwordHash,
|
|
205
|
+
organizationId,
|
|
206
|
+
tenantId,
|
|
207
|
+
name: spec.displayName ?? undefined,
|
|
208
|
+
isConfirmed: true,
|
|
209
|
+
createdAt: new Date(),
|
|
210
|
+
})
|
|
211
|
+
em.persist(user)
|
|
212
|
+
await em.flush()
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
for (const roleName of roles) {
|
|
216
|
+
const role = await findOneWithDecryption(
|
|
217
|
+
em,
|
|
218
|
+
Role,
|
|
219
|
+
{ name: roleName, tenantId },
|
|
220
|
+
{},
|
|
221
|
+
{ tenantId, organizationId: null },
|
|
222
|
+
)
|
|
223
|
+
if (!role) {
|
|
224
|
+
console.warn(`[cpq:tenant-provisioning] Role "${roleName}" not found for tenant ${tenantId}; skipping link for ${spec.email}`)
|
|
225
|
+
continue
|
|
226
|
+
}
|
|
227
|
+
const link = await findOneWithDecryption(
|
|
228
|
+
em,
|
|
229
|
+
UserRole,
|
|
230
|
+
{ user, role },
|
|
231
|
+
{},
|
|
232
|
+
{ tenantId, organizationId: null },
|
|
233
|
+
)
|
|
234
|
+
if (!link) {
|
|
235
|
+
em.persist(em.create(UserRole, { user, role, createdAt: new Date() }))
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
await em.flush()
|
|
239
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
+
|
|
3
|
+
export type CpqSeedScope = { tenantId: string; organizationId: string }
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generic CPQ defaults seed.
|
|
7
|
+
*
|
|
8
|
+
* After XD-276 the cpq module ships with no built-in wizard or product
|
|
9
|
+
* defaults — vertical-specific seeds live in app-level `demo_<x>` modules
|
|
10
|
+
* that register CPQ use cases via `cpq/lib/seeds/api.ts`.
|
|
11
|
+
*
|
|
12
|
+
* The export is kept as a no-op so existing call sites and any external
|
|
13
|
+
* tooling that imported it before the refactor still resolve. New code
|
|
14
|
+
* should not call this — register a use case instead.
|
|
15
|
+
*/
|
|
16
|
+
export async function seedCpqDefaults(_em: EntityManager, _scope: CpqSeedScope): Promise<void> {
|
|
17
|
+
// Intentionally empty: see XD-276 for the migration rationale.
|
|
18
|
+
}
|