@open-mercato/core 0.4.2-canary-f821f89ef6 → 0.4.2-canary-3b5064ce72
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/dist/generated/entities/notification/index.js +57 -0
- package/dist/generated/entities/notification/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +5 -2
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -2
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/api_docs/frontend/docs/api/page.js +3 -2
- package/dist/modules/api_docs/frontend/docs/api/page.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +1 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js +4 -0
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +2 -0
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/auth/api/admin/nav.js +4 -3
- package/dist/modules/auth/api/admin/nav.js.map +2 -2
- package/dist/modules/auth/api/login.js +25 -6
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/api/profile/route.js +157 -0
- package/dist/modules/auth/api/profile/route.js.map +7 -0
- package/dist/modules/auth/api/reset/confirm.js +25 -2
- package/dist/modules/auth/api/reset/confirm.js.map +2 -2
- package/dist/modules/auth/api/reset.js +23 -0
- package/dist/modules/auth/api/reset.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +14 -9
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +4 -2
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/auth/profile/page.js +141 -0
- package/dist/modules/auth/backend/auth/profile/page.js.map +7 -0
- package/dist/modules/auth/backend/auth/profile/page.meta.js +13 -0
- package/dist/modules/auth/backend/auth/profile/page.meta.js.map +7 -0
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +4 -1
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +3 -3
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +18 -3
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +15 -2
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +3 -3
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/cli.js +25 -11
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/commands/users.js +59 -2
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/data/validators.js +6 -3
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/auth/frontend/login.js +112 -3
- package/dist/modules/auth/frontend/login.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +20 -10
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/setup-app.js +42 -8
- package/dist/modules/auth/lib/setup-app.js.map +2 -2
- package/dist/modules/auth/notifications.js +112 -0
- package/dist/modules/auth/notifications.js.map +7 -0
- package/dist/modules/auth/services/authService.js +24 -3
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/business_rules/api/execute/route.js +7 -1
- package/dist/modules/business_rules/api/execute/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +4 -0
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +3 -0
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/business_rules/cli.js +2 -1
- package/dist/modules/business_rules/cli.js.map +2 -2
- package/dist/modules/business_rules/data/validators.js +0 -34
- package/dist/modules/business_rules/data/validators.js.map +2 -2
- package/dist/modules/business_rules/index.js +1 -21
- package/dist/modules/business_rules/index.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-engine.js +34 -185
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/business_rules/notifications.js +28 -0
- package/dist/modules/business_rules/notifications.js.map +7 -0
- package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +37 -0
- package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +7 -0
- package/dist/modules/catalog/components/PriceKindSettings.js +2 -0
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +2 -0
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/notifications.js +28 -0
- package/dist/modules/catalog/notifications.js.map +7 -0
- package/dist/modules/catalog/subscribers/low-stock-notification.js +38 -0
- package/dist/modules/catalog/subscribers/low-stock-notification.js.map +7 -0
- package/dist/modules/configs/cli.js +6 -0
- package/dist/modules/configs/cli.js.map +2 -2
- package/dist/modules/configs/components/CachePanel.js +4 -4
- package/dist/modules/configs/components/CachePanel.js.map +2 -2
- package/dist/modules/configs/lib/system-status.js +48 -1
- package/dist/modules/configs/lib/system-status.js.map +2 -2
- package/dist/modules/configs/lib/upgrade-actions.js +18 -0
- package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +3 -0
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +2 -0
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +3 -0
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +3 -0
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +3 -0
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +31 -0
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/notifications.js +48 -0
- package/dist/modules/customers/notifications.js.map +7 -0
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js.map +2 -2
- package/dist/modules/dashboards/cli.js +44 -5
- package/dist/modules/dashboards/cli.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +16 -11
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +3 -3
- package/dist/modules/dashboards/lib/role-widgets.js +58 -0
- package/dist/modules/dashboards/lib/role-widgets.js.map +7 -0
- package/dist/modules/dashboards/services/widgetDataService.js +139 -3
- package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryTable.js +2 -0
- package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
- package/dist/modules/directory/api/get/tenants/lookup.js +70 -0
- package/dist/modules/directory/api/get/tenants/lookup.js.map +7 -0
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/SystemEntitiesTable.js +1 -1
- package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +3 -3
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/OverridesTable.js +1 -1
- package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
- package/dist/modules/notifications/acl.js +11 -0
- package/dist/modules/notifications/acl.js.map +7 -0
- package/dist/modules/notifications/api/[id]/action/route.js +74 -0
- package/dist/modules/notifications/api/[id]/action/route.js.map +7 -0
- package/dist/modules/notifications/api/[id]/dismiss/route.js +15 -0
- package/dist/modules/notifications/api/[id]/dismiss/route.js.map +7 -0
- package/dist/modules/notifications/api/[id]/read/route.js +15 -0
- package/dist/modules/notifications/api/[id]/read/route.js.map +7 -0
- package/dist/modules/notifications/api/[id]/restore/route.js +53 -0
- package/dist/modules/notifications/api/[id]/restore/route.js.map +7 -0
- package/dist/modules/notifications/api/batch/route.js +17 -0
- package/dist/modules/notifications/api/batch/route.js.map +7 -0
- package/dist/modules/notifications/api/feature/route.js +17 -0
- package/dist/modules/notifications/api/feature/route.js.map +7 -0
- package/dist/modules/notifications/api/mark-all-read/route.js +35 -0
- package/dist/modules/notifications/api/mark-all-read/route.js.map +7 -0
- package/dist/modules/notifications/api/openapi.js +76 -0
- package/dist/modules/notifications/api/openapi.js.map +7 -0
- package/dist/modules/notifications/api/role/route.js +17 -0
- package/dist/modules/notifications/api/role/route.js.map +7 -0
- package/dist/modules/notifications/api/route.js +85 -0
- package/dist/modules/notifications/api/route.js.map +7 -0
- package/dist/modules/notifications/api/settings/route.js +155 -0
- package/dist/modules/notifications/api/settings/route.js.map +7 -0
- package/dist/modules/notifications/api/unread-count/route.js +38 -0
- package/dist/modules/notifications/api/unread-count/route.js.map +7 -0
- package/dist/modules/notifications/backend/config/notifications/page.js +10 -0
- package/dist/modules/notifications/backend/config/notifications/page.js.map +7 -0
- package/dist/modules/notifications/backend/config/notifications/page.meta.js +24 -0
- package/dist/modules/notifications/backend/config/notifications/page.meta.js.map +7 -0
- package/dist/modules/notifications/cli.js +16 -0
- package/dist/modules/notifications/cli.js.map +7 -0
- package/dist/modules/notifications/data/entities.js +112 -0
- package/dist/modules/notifications/data/entities.js.map +7 -0
- package/dist/modules/notifications/data/validators.js +98 -0
- package/dist/modules/notifications/data/validators.js.map +7 -0
- package/dist/modules/notifications/di.js +13 -0
- package/dist/modules/notifications/di.js.map +7 -0
- package/dist/modules/notifications/emails/NotificationEmail.js +58 -0
- package/dist/modules/notifications/emails/NotificationEmail.js.map +7 -0
- package/dist/modules/notifications/frontend/NotificationInboxPageClient.js +44 -0
- package/dist/modules/notifications/frontend/NotificationInboxPageClient.js.map +7 -0
- package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js +220 -0
- package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js.map +7 -0
- package/dist/modules/notifications/index.js +14 -0
- package/dist/modules/notifications/index.js.map +7 -0
- package/dist/modules/notifications/lib/deliveryConfig.js +107 -0
- package/dist/modules/notifications/lib/deliveryConfig.js.map +7 -0
- package/dist/modules/notifications/lib/deliveryStrategies.js +14 -0
- package/dist/modules/notifications/lib/deliveryStrategies.js.map +7 -0
- package/dist/modules/notifications/lib/events.js +12 -0
- package/dist/modules/notifications/lib/events.js.map +7 -0
- package/dist/modules/notifications/lib/notificationBuilder.js +66 -0
- package/dist/modules/notifications/lib/notificationBuilder.js.map +7 -0
- package/dist/modules/notifications/lib/notificationFactory.js +54 -0
- package/dist/modules/notifications/lib/notificationFactory.js.map +7 -0
- package/dist/modules/notifications/lib/notificationMapper.js +34 -0
- package/dist/modules/notifications/lib/notificationMapper.js.map +7 -0
- package/dist/modules/notifications/lib/notificationRecipients.js +35 -0
- package/dist/modules/notifications/lib/notificationRecipients.js.map +7 -0
- package/dist/modules/notifications/lib/notificationService.js +279 -0
- package/dist/modules/notifications/lib/notificationService.js.map +7 -0
- package/dist/modules/notifications/lib/routeHelpers.js +101 -0
- package/dist/modules/notifications/lib/routeHelpers.js.map +7 -0
- package/dist/modules/notifications/lib/safeHref.js +24 -0
- package/dist/modules/notifications/lib/safeHref.js.map +7 -0
- package/dist/modules/notifications/migrations/Migration20260123000001.js +70 -0
- package/dist/modules/notifications/migrations/Migration20260123000001.js.map +7 -0
- package/dist/modules/notifications/migrations/Migration20260126150000.js +37 -0
- package/dist/modules/notifications/migrations/Migration20260126150000.js.map +7 -0
- package/dist/modules/notifications/migrations/Migration20260129082610.js +13 -0
- package/dist/modules/notifications/migrations/Migration20260129082610.js.map +7 -0
- package/dist/modules/notifications/subscribers/deliver-notification.js +165 -0
- package/dist/modules/notifications/subscribers/deliver-notification.js.map +7 -0
- package/dist/modules/notifications/workers/create-notification.worker.js +70 -0
- package/dist/modules/notifications/workers/create-notification.worker.js.map +7 -0
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/query_index/cli.js +63 -7
- package/dist/modules/query_index/cli.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +7 -1
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/sales/acl.js +0 -1
- package/dist/modules/sales/acl.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +2 -0
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +2 -0
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +0 -12
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +53 -62
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +26 -0
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +2 -0
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +2 -0
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +2 -1
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -0
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/lib/dictionaries.js +0 -3
- package/dist/modules/sales/lib/dictionaries.js.map +2 -2
- package/dist/modules/sales/notifications.client.js +51 -0
- package/dist/modules/sales/notifications.client.js.map +7 -0
- package/dist/modules/sales/notifications.js +88 -0
- package/dist/modules/sales/notifications.js.map +7 -0
- package/dist/modules/sales/subscribers/quote-expiring-notification.js +38 -0
- package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js +137 -0
- package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js +137 -0
- package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/index.js +7 -0
- package/dist/modules/sales/widgets/notifications/index.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js +60 -0
- package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js.map +7 -0
- package/dist/modules/staff/backend/staff/team-members/page.js +1 -1
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +79 -0
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/notifications.js +75 -0
- package/dist/modules/staff/notifications.js.map +7 -0
- package/dist/modules/workflows/acl.js +0 -2
- package/dist/modules/workflows/acl.js.map +2 -2
- package/dist/modules/workflows/api/instances/route.js +6 -18
- package/dist/modules/workflows/api/instances/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/route.js +1 -6
- package/dist/modules/workflows/api/tasks/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +1 -9
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.js +15 -24
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/create/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/page.js +5 -0
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +132 -150
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/visual-editor/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.js +1 -1
- package/dist/modules/workflows/backend/events/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.meta.js +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.meta.js +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +3 -0
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.js +1 -1
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.meta.js +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +9 -5
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/cli.js +15 -93
- package/dist/modules/workflows/cli.js.map +3 -3
- package/dist/modules/workflows/data/entities.js +1 -64
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/data/validators.js +0 -115
- package/dist/modules/workflows/data/validators.js.map +2 -2
- package/dist/modules/workflows/examples/checkout-demo-definition.json +5 -1
- package/dist/modules/workflows/lib/activity-executor.js +13 -75
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/graph-utils.js +2 -71
- package/dist/modules/workflows/lib/graph-utils.js.map +2 -2
- package/dist/modules/workflows/lib/seeds.js +5 -22
- package/dist/modules/workflows/lib/seeds.js.map +2 -2
- package/dist/modules/workflows/lib/start-validator.js +23 -33
- package/dist/modules/workflows/lib/start-validator.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +57 -161
- package/dist/modules/workflows/lib/transition-handler.js.map +3 -3
- package/dist/modules/workflows/notifications.js +28 -0
- package/dist/modules/workflows/notifications.js.map +7 -0
- package/dist/modules/workflows/subscribers/task-assigned-notification.js +38 -0
- package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +7 -0
- package/generated/entities/notification/index.ts +27 -0
- package/generated/entities.ids.generated.ts +5 -2
- package/generated/entity-fields-registry.ts +2 -2
- package/package.json +2 -2
- package/src/modules/api_docs/frontend/docs/api/page.tsx +3 -2
- package/src/modules/api_keys/backend/api-keys/page.tsx +1 -1
- package/src/modules/attachments/components/AttachmentLibrary.tsx +4 -0
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +2 -0
- package/src/modules/auth/README.md +1 -1
- package/src/modules/auth/__tests__/cli-setup-acl.test.ts +1 -1
- package/src/modules/auth/api/__tests__/login.test.ts +2 -0
- package/src/modules/auth/api/admin/nav.ts +10 -6
- package/src/modules/auth/api/login.ts +26 -7
- package/src/modules/auth/api/profile/route.ts +163 -0
- package/src/modules/auth/api/reset/confirm.ts +25 -2
- package/src/modules/auth/api/reset.ts +23 -0
- package/src/modules/auth/api/sidebar/preferences/route.ts +21 -12
- package/src/modules/auth/api/users/route.ts +5 -2
- package/src/modules/auth/backend/auth/profile/page.meta.ts +9 -0
- package/src/modules/auth/backend/auth/profile/page.tsx +174 -0
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +4 -1
- package/src/modules/auth/backend/roles/page.tsx +3 -3
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +22 -3
- package/src/modules/auth/backend/users/create/page.tsx +19 -2
- package/src/modules/auth/backend/users/page.tsx +3 -3
- package/src/modules/auth/cli.ts +38 -11
- package/src/modules/auth/commands/users.ts +73 -2
- package/src/modules/auth/data/validators.ts +6 -2
- package/src/modules/auth/frontend/login.tsx +134 -5
- package/src/modules/auth/frontend/reset/[token]/page.tsx +24 -11
- package/src/modules/auth/i18n/de.json +48 -1
- package/src/modules/auth/i18n/en.json +48 -1
- package/src/modules/auth/i18n/es.json +48 -1
- package/src/modules/auth/i18n/pl.json +48 -1
- package/src/modules/auth/lib/setup-app.ts +58 -9
- package/src/modules/auth/notifications.ts +109 -0
- package/src/modules/auth/services/authService.ts +27 -4
- package/src/modules/business_rules/api/execute/route.ts +8 -1
- package/src/modules/business_rules/backend/rules/page.tsx +4 -0
- package/src/modules/business_rules/backend/sets/page.tsx +3 -0
- package/src/modules/business_rules/cli.ts +2 -1
- package/src/modules/business_rules/data/validators.ts +0 -40
- package/src/modules/business_rules/i18n/en.json +3 -1
- package/src/modules/business_rules/index.ts +0 -25
- package/src/modules/business_rules/lib/__tests__/rule-engine.test.ts +51 -0
- package/src/modules/business_rules/lib/rule-engine.ts +51 -277
- package/src/modules/business_rules/notifications.ts +25 -0
- package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +50 -0
- package/src/modules/catalog/components/PriceKindSettings.tsx +2 -0
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -2
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +2 -0
- package/src/modules/catalog/i18n/en.json +3 -1
- package/src/modules/catalog/notifications.ts +25 -0
- package/src/modules/catalog/subscribers/low-stock-notification.ts +52 -0
- package/src/modules/configs/cli.ts +6 -0
- package/src/modules/configs/components/CachePanel.tsx +4 -4
- package/src/modules/configs/i18n/en.json +12 -2
- package/src/modules/configs/i18n/pl.json +12 -2
- package/src/modules/configs/lib/system-status.ts +48 -1
- package/src/modules/configs/lib/system-status.types.ts +1 -0
- package/src/modules/configs/lib/upgrade-actions.ts +18 -0
- package/src/modules/currencies/backend/currencies/page.tsx +3 -0
- package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -0
- package/src/modules/customers/backend/customers/companies/page.tsx +3 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +3 -0
- package/src/modules/customers/backend/customers/people/page.tsx +3 -0
- package/src/modules/customers/commands/deals.ts +39 -0
- package/src/modules/customers/components/CustomerTodosTable.tsx +1 -0
- package/src/modules/customers/i18n/en.json +5 -1
- package/src/modules/customers/notifications.ts +44 -0
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.ts +2 -2
- package/src/modules/customers/widgets/dashboard/new-customers/widget.ts +2 -2
- package/src/modules/customers/widgets/dashboard/new-deals/widget.ts +2 -2
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.ts +2 -2
- package/src/modules/dashboards/cli.ts +55 -5
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +22 -11
- package/src/modules/dashboards/lib/role-widgets.ts +80 -0
- package/src/modules/dashboards/services/widgetDataService.ts +164 -4
- package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.ts +2 -2
- package/src/modules/dictionaries/components/DictionaryTable.tsx +2 -0
- package/src/modules/directory/api/get/tenants/lookup.ts +75 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +2 -2
- package/src/modules/directory/backend/directory/tenants/page.tsx +2 -2
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +2 -2
- package/src/modules/entities/components/SystemEntitiesTable.tsx +1 -1
- package/src/modules/entities/components/UserEntitiesTable.tsx +2 -2
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +3 -4
- package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -1
- package/src/modules/notifications/__tests__/deliver-notification.test.ts +195 -0
- package/src/modules/notifications/__tests__/deliveryStrategies.test.ts +19 -0
- package/src/modules/notifications/__tests__/notificationService.test.ts +208 -0
- package/src/modules/notifications/acl.ts +7 -0
- package/src/modules/notifications/api/[id]/action/route.ts +75 -0
- package/src/modules/notifications/api/[id]/dismiss/route.ts +12 -0
- package/src/modules/notifications/api/[id]/read/route.ts +12 -0
- package/src/modules/notifications/api/[id]/restore/route.ts +53 -0
- package/src/modules/notifications/api/batch/route.ts +14 -0
- package/src/modules/notifications/api/feature/route.ts +14 -0
- package/src/modules/notifications/api/mark-all-read/route.ts +34 -0
- package/src/modules/notifications/api/openapi.ts +76 -0
- package/src/modules/notifications/api/role/route.ts +14 -0
- package/src/modules/notifications/api/route.ts +92 -0
- package/src/modules/notifications/api/settings/route.ts +157 -0
- package/src/modules/notifications/api/unread-count/route.ts +38 -0
- package/src/modules/notifications/backend/config/notifications/page.meta.ts +22 -0
- package/src/modules/notifications/backend/config/notifications/page.tsx +12 -0
- package/src/modules/notifications/cli.ts +18 -0
- package/src/modules/notifications/data/entities.ts +99 -0
- package/src/modules/notifications/data/validators.ts +115 -0
- package/src/modules/notifications/di.ts +11 -0
- package/src/modules/notifications/emails/NotificationEmail.tsx +98 -0
- package/src/modules/notifications/frontend/NotificationInboxPageClient.tsx +42 -0
- package/src/modules/notifications/frontend/NotificationSettingsPageClient.tsx +233 -0
- package/src/modules/notifications/i18n/de.json +50 -0
- package/src/modules/notifications/i18n/en.json +50 -0
- package/src/modules/notifications/i18n/es.json +50 -0
- package/src/modules/notifications/i18n/pl.json +50 -0
- package/src/modules/notifications/index.ts +12 -0
- package/src/modules/notifications/lib/deliveryConfig.ts +153 -0
- package/src/modules/notifications/lib/deliveryStrategies.ts +50 -0
- package/src/modules/notifications/lib/events.ts +48 -0
- package/src/modules/notifications/lib/notificationBuilder.ts +121 -0
- package/src/modules/notifications/lib/notificationFactory.ts +76 -0
- package/src/modules/notifications/lib/notificationMapper.ts +33 -0
- package/src/modules/notifications/lib/notificationRecipients.ts +83 -0
- package/src/modules/notifications/lib/notificationService.ts +414 -0
- package/src/modules/notifications/lib/routeHelpers.ts +151 -0
- package/src/modules/notifications/lib/safeHref.ts +29 -0
- package/src/modules/notifications/migrations/.snapshot-open-mercato.json +336 -0
- package/src/modules/notifications/migrations/Migration20260123000001.ts +73 -0
- package/src/modules/notifications/migrations/Migration20260126150000.ts +39 -0
- package/src/modules/notifications/migrations/Migration20260129082610.ts +13 -0
- package/src/modules/notifications/subscribers/deliver-notification.ts +204 -0
- package/src/modules/notifications/workers/create-notification.worker.ts +122 -0
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +2 -2
- package/src/modules/query_index/cli.ts +82 -13
- package/src/modules/query_index/components/QueryIndexesTable.tsx +8 -2
- package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -2
- package/src/modules/resources/backend/resources/resources/page.tsx +2 -2
- package/src/modules/sales/acl.ts +0 -1
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +2 -0
- package/src/modules/sales/backend/sales/channels/page.tsx +2 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +0 -16
- package/src/modules/sales/commands/documents.ts +62 -70
- package/src/modules/sales/commands/payments.ts +33 -0
- package/src/modules/sales/components/AdjustmentKindSettings.tsx +2 -2
- package/src/modules/sales/components/PaymentMethodsSettings.tsx +2 -2
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +2 -2
- package/src/modules/sales/components/TaxRatesSettings.tsx +2 -2
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +2 -0
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +2 -0
- package/src/modules/sales/components/documents/PaymentsSection.tsx +2 -1
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -0
- package/src/modules/sales/i18n/de.json +20 -0
- package/src/modules/sales/i18n/en.json +25 -1
- package/src/modules/sales/i18n/es.json +20 -0
- package/src/modules/sales/i18n/pl.json +20 -0
- package/src/modules/sales/lib/dictionaries.ts +0 -3
- package/src/modules/sales/notifications.client.ts +65 -0
- package/src/modules/sales/notifications.ts +82 -0
- package/src/modules/sales/subscribers/quote-expiring-notification.ts +53 -0
- package/src/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.tsx +156 -0
- package/src/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.tsx +156 -0
- package/src/modules/sales/widgets/notifications/index.ts +2 -0
- package/src/modules/sales/widgets/notifications/useSalesDocumentTotals.ts +81 -0
- package/src/modules/staff/backend/staff/team-members/page.tsx +1 -1
- package/src/modules/staff/backend/staff/team-roles/page.tsx +2 -2
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +2 -2
- package/src/modules/staff/backend/staff/teams/page.tsx +2 -2
- package/src/modules/staff/commands/leave-requests.ts +94 -0
- package/src/modules/staff/i18n/de.json +4 -0
- package/src/modules/staff/i18n/en.json +9 -1
- package/src/modules/staff/i18n/es.json +4 -0
- package/src/modules/staff/i18n/pl.json +4 -0
- package/src/modules/staff/notifications.ts +71 -0
- package/src/modules/workflows/acl.ts +0 -2
- package/src/modules/workflows/api/__tests__/instances.route.test.ts +2 -5
- package/src/modules/workflows/api/instances/route.ts +7 -21
- package/src/modules/workflows/api/tasks/route.ts +1 -7
- package/src/modules/workflows/backend/definitions/[id]/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +0 -9
- package/src/modules/workflows/backend/definitions/create/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/create/page.tsx +0 -9
- package/src/modules/workflows/backend/definitions/page.tsx +5 -0
- package/src/modules/workflows/backend/definitions/visual-editor/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +3 -21
- package/src/modules/workflows/backend/events/[id]/page.meta.ts +2 -2
- package/src/modules/workflows/backend/events/[id]/page.tsx +1 -1
- package/src/modules/workflows/backend/instances/[id]/page.meta.ts +2 -2
- package/src/modules/workflows/backend/instances/page.tsx +4 -1
- package/src/modules/workflows/backend/tasks/[id]/page.meta.ts +2 -2
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +1 -1
- package/src/modules/workflows/backend/tasks/page.tsx +10 -6
- package/src/modules/workflows/cli.ts +12 -123
- package/src/modules/workflows/data/entities.ts +0 -124
- package/src/modules/workflows/data/validators.ts +0 -138
- package/src/modules/workflows/examples/checkout-demo-definition.json +5 -1
- package/src/modules/workflows/i18n/en.json +3 -72
- package/src/modules/workflows/lib/__tests__/activity-executor.test.ts +36 -43
- package/src/modules/workflows/lib/__tests__/transition-handler.test.ts +90 -170
- package/src/modules/workflows/lib/activity-executor.ts +16 -129
- package/src/modules/workflows/lib/graph-utils.ts +2 -117
- package/src/modules/workflows/lib/seeds.ts +8 -34
- package/src/modules/workflows/lib/start-validator.ts +28 -38
- package/src/modules/workflows/lib/transition-handler.ts +71 -212
- package/src/modules/workflows/notifications.ts +25 -0
- package/src/modules/workflows/subscribers/task-assigned-notification.ts +53 -0
- package/dist/generated/entities/workflow_event_trigger/index.js +0 -33
- package/dist/generated/entities/workflow_event_trigger/index.js.map +0 -7
- package/dist/modules/auth/events.js +0 -30
- package/dist/modules/auth/events.js.map +0 -7
- package/dist/modules/business_rules/api/execute/[ruleId]/route.js +0 -145
- package/dist/modules/business_rules/api/execute/[ruleId]/route.js.map +0 -7
- package/dist/modules/catalog/events.js +0 -34
- package/dist/modules/catalog/events.js.map +0 -7
- package/dist/modules/customers/events.js +0 -49
- package/dist/modules/customers/events.js.map +0 -7
- package/dist/modules/directory/events.js +0 -23
- package/dist/modules/directory/events.js.map +0 -7
- package/dist/modules/sales/events.js +0 -63
- package/dist/modules/sales/events.js.map +0 -7
- package/dist/modules/sales/lib/frontend/documentDataEvents.js +0 -25
- package/dist/modules/sales/lib/frontend/documentDataEvents.js.map +0 -7
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +0 -481
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +0 -7
- package/dist/modules/workflows/components/EventTriggersEditor.js +0 -553
- package/dist/modules/workflows/components/EventTriggersEditor.js.map +0 -7
- package/dist/modules/workflows/events.js +0 -38
- package/dist/modules/workflows/events.js.map +0 -7
- package/dist/modules/workflows/examples/order-approval-definition.json +0 -257
- package/dist/modules/workflows/examples/order-approval-guard-rules.json +0 -32
- package/dist/modules/workflows/lib/event-trigger-service.js +0 -308
- package/dist/modules/workflows/lib/event-trigger-service.js.map +0 -7
- package/dist/modules/workflows/migrations/Migration20260123143500.js +0 -36
- package/dist/modules/workflows/migrations/Migration20260123143500.js.map +0 -7
- package/dist/modules/workflows/subscribers/event-trigger.js +0 -78
- package/dist/modules/workflows/subscribers/event-trigger.js.map +0 -7
- package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js +0 -323
- package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js.map +0 -7
- package/dist/modules/workflows/widgets/injection/order-approval/widget.js +0 -17
- package/dist/modules/workflows/widgets/injection/order-approval/widget.js.map +0 -7
- package/dist/modules/workflows/widgets/injection-table.js +0 -19
- package/dist/modules/workflows/widgets/injection-table.js.map +0 -7
- package/generated/entities/workflow_event_trigger/index.ts +0 -15
- package/src/modules/auth/events.ts +0 -39
- package/src/modules/business_rules/api/execute/[ruleId]/route.ts +0 -163
- package/src/modules/catalog/events.ts +0 -45
- package/src/modules/customers/events.ts +0 -63
- package/src/modules/directory/events.ts +0 -31
- package/src/modules/sales/events.ts +0 -82
- package/src/modules/sales/lib/frontend/documentDataEvents.ts +0 -28
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +0 -581
- package/src/modules/workflows/components/EventTriggersEditor.tsx +0 -664
- package/src/modules/workflows/events.ts +0 -49
- package/src/modules/workflows/examples/order-approval-definition.json +0 -257
- package/src/modules/workflows/examples/order-approval-guard-rules.json +0 -32
- package/src/modules/workflows/lib/event-trigger-service.ts +0 -557
- package/src/modules/workflows/migrations/Migration20260123143500.ts +0 -38
- package/src/modules/workflows/subscribers/event-trigger.ts +0 -109
- package/src/modules/workflows/widgets/injection/order-approval/widget.client.tsx +0 -446
- package/src/modules/workflows/widgets/injection/order-approval/widget.ts +0 -16
- package/src/modules/workflows/widgets/injection-table.ts +0 -21
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BusinessRule, RuleExecutionLog } from "../data/entities.js";
|
|
2
2
|
import * as ruleEvaluator from "./rule-evaluator.js";
|
|
3
3
|
import * as actionExecutor from "./action-executor.js";
|
|
4
|
-
import { ruleEngineContextSchema, ruleDiscoveryOptionsSchema
|
|
4
|
+
import { ruleEngineContextSchema, ruleDiscoveryOptionsSchema } from "../data/validators.js";
|
|
5
5
|
const DEFAULT_ENTITY_ID = "unknown";
|
|
6
6
|
const RULE_TYPE_GUARD = "GUARD";
|
|
7
7
|
const EXECUTION_RESULT_ERROR = "ERROR";
|
|
@@ -23,7 +23,7 @@ async function withTimeout(promise, timeoutMs, errorMessage) {
|
|
|
23
23
|
clearTimeout(timeoutId);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
async function executeRules(em, context) {
|
|
26
|
+
async function executeRules(em, context, options = {}) {
|
|
27
27
|
const validation = ruleEngineContextSchema.safeParse(context);
|
|
28
28
|
if (!validation.success) {
|
|
29
29
|
const validationErrors = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
@@ -59,7 +59,7 @@ async function executeRules(em, context) {
|
|
|
59
59
|
const executionPromise = (async () => {
|
|
60
60
|
for (const rule of rules) {
|
|
61
61
|
try {
|
|
62
|
-
const ruleResult = await executeSingleRule(em, rule, context);
|
|
62
|
+
const ruleResult = await executeSingleRule(em, rule, context, options);
|
|
63
63
|
executedRules.push(ruleResult);
|
|
64
64
|
if (ruleResult.logId) {
|
|
65
65
|
logIds.push(ruleResult.logId);
|
|
@@ -74,6 +74,16 @@ async function executeRules(em, context) {
|
|
|
74
74
|
errors.push(
|
|
75
75
|
`Unexpected error in rule execution [ruleId=${rule.ruleId}, type=${rule.ruleType}]: ${errorMessage}`
|
|
76
76
|
);
|
|
77
|
+
if (!context.dryRun) {
|
|
78
|
+
await emitRuleExecutionFailed(options.eventBus, {
|
|
79
|
+
ruleId: rule.ruleId,
|
|
80
|
+
ruleName: rule.ruleName,
|
|
81
|
+
entityType: context.entityType ?? null,
|
|
82
|
+
errorMessage,
|
|
83
|
+
tenantId: context.tenantId,
|
|
84
|
+
organizationId: context.organizationId ?? null
|
|
85
|
+
});
|
|
86
|
+
}
|
|
77
87
|
executedRules.push({
|
|
78
88
|
rule,
|
|
79
89
|
conditionResult: false,
|
|
@@ -115,7 +125,7 @@ Stack: ${stack}` : ""}`
|
|
|
115
125
|
};
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
|
-
async function executeSingleRule(em, rule, context) {
|
|
128
|
+
async function executeSingleRule(em, rule, context, options = {}) {
|
|
119
129
|
const startTime = Date.now();
|
|
120
130
|
try {
|
|
121
131
|
const executeWithTimeout = async () => {
|
|
@@ -140,6 +150,14 @@ async function executeSingleRule(em, rule, context) {
|
|
|
140
150
|
executionTime: executionTime2,
|
|
141
151
|
error: result.error
|
|
142
152
|
});
|
|
153
|
+
await emitRuleExecutionFailed(options.eventBus, {
|
|
154
|
+
ruleId: rule.ruleId,
|
|
155
|
+
ruleName: rule.ruleName,
|
|
156
|
+
entityType: context.entityType ?? null,
|
|
157
|
+
errorMessage: result.error ?? null,
|
|
158
|
+
tenantId: context.tenantId,
|
|
159
|
+
organizationId: context.organizationId ?? null
|
|
160
|
+
});
|
|
143
161
|
}
|
|
144
162
|
return {
|
|
145
163
|
rule,
|
|
@@ -199,6 +217,14 @@ async function executeSingleRule(em, rule, context) {
|
|
|
199
217
|
executionTime,
|
|
200
218
|
error: enhancedError
|
|
201
219
|
});
|
|
220
|
+
await emitRuleExecutionFailed(options.eventBus, {
|
|
221
|
+
ruleId: rule.ruleId,
|
|
222
|
+
ruleName: rule.ruleName,
|
|
223
|
+
entityType: context.entityType ?? null,
|
|
224
|
+
errorMessage: enhancedError,
|
|
225
|
+
tenantId: context.tenantId,
|
|
226
|
+
organizationId: context.organizationId ?? null
|
|
227
|
+
});
|
|
202
228
|
}
|
|
203
229
|
return {
|
|
204
230
|
rule,
|
|
@@ -240,185 +266,6 @@ async function findApplicableRules(em, options) {
|
|
|
240
266
|
return true;
|
|
241
267
|
});
|
|
242
268
|
}
|
|
243
|
-
async function executeRuleById(em, context) {
|
|
244
|
-
const startTime = Date.now();
|
|
245
|
-
const validation = directRuleExecutionContextSchema.safeParse(context);
|
|
246
|
-
if (!validation.success) {
|
|
247
|
-
const validationErrors = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
248
|
-
return {
|
|
249
|
-
success: false,
|
|
250
|
-
ruleId: context.ruleId,
|
|
251
|
-
ruleName: "Unknown",
|
|
252
|
-
conditionResult: false,
|
|
253
|
-
actionsExecuted: null,
|
|
254
|
-
executionTime: Date.now() - startTime,
|
|
255
|
-
error: `Validation failed: ${validationErrors.join(", ")}`
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
const rule = await em.findOne(BusinessRule, {
|
|
259
|
-
id: context.ruleId,
|
|
260
|
-
tenantId: context.tenantId,
|
|
261
|
-
organizationId: context.organizationId,
|
|
262
|
-
deletedAt: null
|
|
263
|
-
});
|
|
264
|
-
if (!rule) {
|
|
265
|
-
return {
|
|
266
|
-
success: false,
|
|
267
|
-
ruleId: context.ruleId,
|
|
268
|
-
ruleName: "Unknown",
|
|
269
|
-
conditionResult: false,
|
|
270
|
-
actionsExecuted: null,
|
|
271
|
-
executionTime: Date.now() - startTime,
|
|
272
|
-
error: "Rule not found"
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
if (!rule.enabled) {
|
|
276
|
-
return {
|
|
277
|
-
success: false,
|
|
278
|
-
ruleId: rule.ruleId,
|
|
279
|
-
ruleName: rule.ruleName,
|
|
280
|
-
conditionResult: false,
|
|
281
|
-
actionsExecuted: null,
|
|
282
|
-
executionTime: Date.now() - startTime,
|
|
283
|
-
error: "Rule is disabled"
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
const now = /* @__PURE__ */ new Date();
|
|
287
|
-
if (rule.effectiveFrom && rule.effectiveFrom > now) {
|
|
288
|
-
return {
|
|
289
|
-
success: false,
|
|
290
|
-
ruleId: rule.ruleId,
|
|
291
|
-
ruleName: rule.ruleName,
|
|
292
|
-
conditionResult: false,
|
|
293
|
-
actionsExecuted: null,
|
|
294
|
-
executionTime: Date.now() - startTime,
|
|
295
|
-
error: `Rule is not yet effective (starts ${rule.effectiveFrom.toISOString()})`
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
if (rule.effectiveTo && rule.effectiveTo < now) {
|
|
299
|
-
return {
|
|
300
|
-
success: false,
|
|
301
|
-
ruleId: rule.ruleId,
|
|
302
|
-
ruleName: rule.ruleName,
|
|
303
|
-
conditionResult: false,
|
|
304
|
-
actionsExecuted: null,
|
|
305
|
-
executionTime: Date.now() - startTime,
|
|
306
|
-
error: `Rule has expired (ended ${rule.effectiveTo.toISOString()})`
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
const engineContext = {
|
|
310
|
-
entityType: context.entityType || rule.entityType,
|
|
311
|
-
entityId: context.entityId,
|
|
312
|
-
eventType: context.eventType || rule.eventType || void 0,
|
|
313
|
-
data: context.data,
|
|
314
|
-
user: context.user,
|
|
315
|
-
tenantId: context.tenantId,
|
|
316
|
-
organizationId: context.organizationId,
|
|
317
|
-
executedBy: context.executedBy,
|
|
318
|
-
dryRun: context.dryRun
|
|
319
|
-
};
|
|
320
|
-
const result = await executeSingleRule(em, rule, engineContext);
|
|
321
|
-
return {
|
|
322
|
-
success: !result.error,
|
|
323
|
-
ruleId: rule.ruleId,
|
|
324
|
-
ruleName: rule.ruleName,
|
|
325
|
-
conditionResult: result.conditionResult,
|
|
326
|
-
actionsExecuted: result.actionsExecuted,
|
|
327
|
-
executionTime: result.executionTime,
|
|
328
|
-
error: result.error,
|
|
329
|
-
logId: result.logId
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
async function executeRuleByRuleId(em, context) {
|
|
333
|
-
const startTime = Date.now();
|
|
334
|
-
const validation = ruleIdExecutionContextSchema.safeParse(context);
|
|
335
|
-
if (!validation.success) {
|
|
336
|
-
const validationErrors = validation.error.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
|
|
337
|
-
return {
|
|
338
|
-
success: false,
|
|
339
|
-
ruleId: context.ruleId || "unknown",
|
|
340
|
-
ruleName: "Unknown",
|
|
341
|
-
conditionResult: false,
|
|
342
|
-
actionsExecuted: null,
|
|
343
|
-
executionTime: Date.now() - startTime,
|
|
344
|
-
error: `Validation failed: ${validationErrors.join(", ")}`
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
const rule = await em.findOne(BusinessRule, {
|
|
348
|
-
ruleId: context.ruleId,
|
|
349
|
-
// String identifier column
|
|
350
|
-
tenantId: context.tenantId,
|
|
351
|
-
organizationId: context.organizationId,
|
|
352
|
-
deletedAt: null
|
|
353
|
-
});
|
|
354
|
-
if (!rule) {
|
|
355
|
-
return {
|
|
356
|
-
success: false,
|
|
357
|
-
ruleId: context.ruleId,
|
|
358
|
-
ruleName: "Unknown",
|
|
359
|
-
conditionResult: false,
|
|
360
|
-
actionsExecuted: null,
|
|
361
|
-
executionTime: Date.now() - startTime,
|
|
362
|
-
error: "Rule not found"
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
if (!rule.enabled) {
|
|
366
|
-
return {
|
|
367
|
-
success: false,
|
|
368
|
-
ruleId: rule.ruleId,
|
|
369
|
-
ruleName: rule.ruleName,
|
|
370
|
-
conditionResult: false,
|
|
371
|
-
actionsExecuted: null,
|
|
372
|
-
executionTime: Date.now() - startTime,
|
|
373
|
-
error: "Rule is disabled"
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
const now = /* @__PURE__ */ new Date();
|
|
377
|
-
if (rule.effectiveFrom && rule.effectiveFrom > now) {
|
|
378
|
-
return {
|
|
379
|
-
success: false,
|
|
380
|
-
ruleId: rule.ruleId,
|
|
381
|
-
ruleName: rule.ruleName,
|
|
382
|
-
conditionResult: false,
|
|
383
|
-
actionsExecuted: null,
|
|
384
|
-
executionTime: Date.now() - startTime,
|
|
385
|
-
error: `Rule is not yet effective (starts ${rule.effectiveFrom.toISOString()})`
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
if (rule.effectiveTo && rule.effectiveTo < now) {
|
|
389
|
-
return {
|
|
390
|
-
success: false,
|
|
391
|
-
ruleId: rule.ruleId,
|
|
392
|
-
ruleName: rule.ruleName,
|
|
393
|
-
conditionResult: false,
|
|
394
|
-
actionsExecuted: null,
|
|
395
|
-
executionTime: Date.now() - startTime,
|
|
396
|
-
error: `Rule has expired (ended ${rule.effectiveTo.toISOString()})`
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
const engineContext = {
|
|
400
|
-
entityType: context.entityType || rule.entityType,
|
|
401
|
-
entityId: context.entityId,
|
|
402
|
-
eventType: context.eventType || rule.eventType || void 0,
|
|
403
|
-
data: context.data,
|
|
404
|
-
user: context.user,
|
|
405
|
-
tenantId: context.tenantId,
|
|
406
|
-
organizationId: context.organizationId,
|
|
407
|
-
executedBy: context.executedBy,
|
|
408
|
-
dryRun: context.dryRun
|
|
409
|
-
};
|
|
410
|
-
const result = await executeSingleRule(em, rule, engineContext);
|
|
411
|
-
return {
|
|
412
|
-
success: !result.error,
|
|
413
|
-
ruleId: rule.ruleId,
|
|
414
|
-
ruleName: rule.ruleName,
|
|
415
|
-
conditionResult: result.conditionResult,
|
|
416
|
-
actionsExecuted: result.actionsExecuted,
|
|
417
|
-
executionTime: result.executionTime,
|
|
418
|
-
error: result.error,
|
|
419
|
-
logId: result.logId
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
269
|
const SENSITIVE_FIELD_PATTERNS = [
|
|
423
270
|
/password/i,
|
|
424
271
|
/passwd/i,
|
|
@@ -503,9 +350,11 @@ async function logRuleExecution(em, options) {
|
|
|
503
350
|
await em.persistAndFlush(log);
|
|
504
351
|
return log.id;
|
|
505
352
|
}
|
|
353
|
+
async function emitRuleExecutionFailed(eventBus, payload) {
|
|
354
|
+
if (!eventBus?.emitEvent) return;
|
|
355
|
+
await eventBus.emitEvent("business_rules.rule.execution_failed", payload).catch(() => void 0);
|
|
356
|
+
}
|
|
506
357
|
export {
|
|
507
|
-
executeRuleById,
|
|
508
|
-
executeRuleByRuleId,
|
|
509
358
|
executeRules,
|
|
510
359
|
executeSingleRule,
|
|
511
360
|
findApplicableRules,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/business_rules/lib/rule-engine.ts"],
|
|
4
|
-
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/core'\nimport { BusinessRule, RuleExecutionLog, type RuleType } from '../data/entities'\nimport * as ruleEvaluator from './rule-evaluator'\nimport * as actionExecutor from './action-executor'\nimport type { RuleEvaluationContext } from './rule-evaluator'\nimport type { ActionContext, ActionExecutionOutcome } from './action-executor'\nimport { ruleEngineContextSchema, ruleDiscoveryOptionsSchema, directRuleExecutionContextSchema, ruleIdExecutionContextSchema } from '../data/validators'\n\n/**\n * Constants\n */\nconst DEFAULT_ENTITY_ID = 'unknown'\nconst RULE_TYPE_GUARD = 'GUARD'\nconst EXECUTION_RESULT_ERROR = 'ERROR'\nconst EXECUTION_RESULT_SUCCESS = 'SUCCESS'\nconst EXECUTION_RESULT_FAILURE = 'FAILURE'\n\n/**\n * Execution limits\n */\nconst MAX_RULES_PER_EXECUTION = 100\nconst MAX_SINGLE_RULE_TIMEOUT_MS = 30000 // 30 seconds\nconst MAX_TOTAL_EXECUTION_TIMEOUT_MS = 60000 // 60 seconds\n\n/**\n * Rule execution context\n */\nexport interface RuleEngineContext {\n entityType: string\n entityId?: string\n eventType?: string\n data: any\n user?: {\n id?: string\n email?: string\n role?: string\n [key: string]: any\n }\n tenant?: {\n id?: string\n [key: string]: any\n }\n organization?: {\n id?: string\n [key: string]: any\n }\n tenantId: string\n organizationId: string\n executedBy?: string\n dryRun?: boolean\n [key: string]: any\n}\n\n/**\n * Single rule execution result\n */\nexport interface RuleExecutionResult {\n rule: BusinessRule\n conditionResult: boolean\n actionsExecuted: ActionExecutionOutcome | null\n executionTime: number\n error?: string\n logId?: string // Database log ID (if logged)\n}\n\n/**\n * Overall rule engine result\n */\nexport interface RuleEngineResult {\n allowed: boolean\n executedRules: RuleExecutionResult[]\n totalExecutionTime: number\n errors?: string[]\n logIds?: string[]\n}\n\n/**\n * Rule discovery options\n */\nexport interface RuleDiscoveryOptions {\n entityType: string\n eventType?: string\n tenantId: string\n organizationId: string\n ruleType?: RuleType\n}\n\n/**\n * Direct rule execution context (for executing a specific rule by ID)\n */\nexport interface DirectRuleExecutionContext {\n ruleId: string // Database UUID of the rule\n data: any\n user?: {\n id?: string\n email?: string\n role?: string\n [key: string]: any\n }\n tenantId: string\n organizationId: string\n executedBy?: string\n dryRun?: boolean\n // Optional for logging (falls back to rule's entityType)\n entityType?: string\n entityId?: string\n eventType?: string\n}\n\n/**\n * Direct rule execution result\n */\nexport interface DirectRuleExecutionResult {\n success: boolean\n ruleId: string\n ruleName: string\n conditionResult: boolean\n actionsExecuted: ActionExecutionOutcome | null\n executionTime: number\n error?: string\n logId?: string\n}\n\n/**\n * Context for executing a rule by its string rule_id identifier\n * Unlike DirectRuleExecutionContext which uses database UUID,\n * this uses the string identifier (e.g., \"workflow_checkout_inventory_available\")\n */\nexport interface RuleIdExecutionContext {\n ruleId: string // String identifier (e.g., \"workflow_checkout_inventory_available\")\n data: any\n user?: {\n id?: string\n email?: string\n role?: string\n [key: string]: any\n }\n tenantId: string\n organizationId: string\n executedBy?: string\n dryRun?: boolean\n entityType?: string\n entityId?: string\n eventType?: string\n}\n\n/**\n * Execute a function with a timeout\n */\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(`${errorMessage} (timeout: ${timeoutMs}ms)`))\n }, timeoutMs)\n })\n\n try {\n return await Promise.race([promise, timeoutPromise])\n } finally {\n clearTimeout(timeoutId!)\n }\n}\n\n/**\n * Execute all applicable rules for the given context\n */\nexport async function executeRules(\n em: EntityManager,\n context: RuleEngineContext\n): Promise<RuleEngineResult> {\n // Validate input\n const validation = ruleEngineContextSchema.safeParse(context)\n if (!validation.success) {\n const validationErrors = validation.error.issues.map(e => `${e.path.join('.')}: ${e.message}`)\n return {\n allowed: false,\n executedRules: [],\n totalExecutionTime: 0,\n errors: validationErrors,\n }\n }\n\n const startTime = Date.now()\n const executedRules: RuleExecutionResult[] = []\n const errors: string[] = []\n const logIds: string[] = []\n\n try {\n // Discover applicable rules\n const rules = await findApplicableRules(em, {\n entityType: context.entityType,\n eventType: context.eventType,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n })\n\n // Check rule count limit\n if (rules.length > MAX_RULES_PER_EXECUTION) {\n errors.push(\n `Rule count limit exceeded: ${rules.length} rules found, maximum is ${MAX_RULES_PER_EXECUTION}`\n )\n return {\n allowed: false,\n executedRules: [],\n totalExecutionTime: Date.now() - startTime,\n errors,\n }\n }\n\n // Rules already sorted by database query (priority DESC, ruleId ASC)\n // Execute each rule with total timeout\n const executionPromise = (async () => {\n for (const rule of rules) {\n try {\n const ruleResult = await executeSingleRule(em, rule, context)\n executedRules.push(ruleResult)\n\n if (ruleResult.logId) {\n logIds.push(ruleResult.logId)\n }\n\n if (ruleResult.error) {\n errors.push(\n `Rule execution failed [ruleId=${rule.ruleId}, type=${rule.ruleType}, entityType=${context.entityType}]: ${ruleResult.error}`\n )\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n errors.push(\n `Unexpected error in rule execution [ruleId=${rule.ruleId}, type=${rule.ruleType}]: ${errorMessage}`\n )\n\n executedRules.push({\n rule,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: 0,\n error: errorMessage,\n })\n }\n }\n })()\n\n // Execute with timeout\n await withTimeout(\n executionPromise,\n MAX_TOTAL_EXECUTION_TIMEOUT_MS,\n `Total rule execution timeout [entityType=${context.entityType}]`\n )\n\n // Determine overall allowed status\n // For GUARD rules: all must pass for operation to be allowed\n const guardRules = executedRules.filter((r) => r.rule.ruleType === RULE_TYPE_GUARD)\n const allowed = guardRules.length === 0 || guardRules.every((r) => r.conditionResult)\n\n const totalExecutionTime = Date.now() - startTime\n\n return {\n allowed,\n executedRules,\n totalExecutionTime,\n errors: errors.length > 0 ? errors : undefined,\n logIds: logIds.length > 0 ? logIds : undefined,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n const stack = error instanceof Error ? error.stack : undefined\n errors.push(\n `Critical rule engine error [entityType=${context.entityType}, entityId=${context.entityId || 'unknown'}]: ${errorMessage}${stack ? `\\nStack: ${stack}` : ''}`\n )\n\n const totalExecutionTime = Date.now() - startTime\n\n return {\n allowed: false,\n executedRules,\n totalExecutionTime,\n errors,\n }\n }\n}\n\n/**\n * Execute a single rule\n */\nexport async function executeSingleRule(\n em: EntityManager,\n rule: BusinessRule,\n context: RuleEngineContext\n): Promise<RuleExecutionResult> {\n const startTime = Date.now()\n\n try {\n // Wrap execution in timeout\n const executeWithTimeout = async () => {\n // Build evaluation context\n const evalContext: RuleEvaluationContext = {\n entityType: context.entityType,\n entityId: context.entityId,\n eventType: context.eventType,\n user: context.user,\n tenant: context.tenant,\n organization: context.organization,\n }\n\n // Evaluate rule conditions\n const result = await ruleEvaluator.evaluateSingleRule(rule, context.data, evalContext)\n\n // Check if evaluation completed (not just if conditions passed)\n if (!result.evaluationCompleted) {\n const executionTime = Date.now() - startTime\n\n let logId: string | undefined\n\n // Log failure if not dry run\n if (!context.dryRun) {\n logId = await logRuleExecution(em, {\n rule,\n context,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: result.error,\n })\n }\n\n return {\n rule,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: result.error,\n logId,\n }\n }\n\n // Evaluation completed successfully - determine which actions to execute\n const actions = result.conditionsPassed ? rule.successActions : rule.failureActions\n\n let actionsExecuted: ActionExecutionOutcome | null = null\n\n if (actions && Array.isArray(actions) && actions.length > 0) {\n // Build action context\n const actionContext: ActionContext = {\n ...evalContext,\n data: context.data,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n }\n\n // Execute actions\n actionsExecuted = await actionExecutor.executeActions(actions, actionContext)\n }\n\n const executionTime = Date.now() - startTime\n\n let logId: string | undefined\n\n // Log execution if not dry run\n if (!context.dryRun) {\n logId = await logRuleExecution(em, {\n rule,\n context,\n conditionResult: result.conditionsPassed,\n actionsExecuted,\n executionTime,\n })\n }\n\n return {\n rule,\n conditionResult: result.conditionsPassed,\n actionsExecuted,\n executionTime,\n logId,\n }\n }\n\n // Execute with single rule timeout\n return await withTimeout(\n executeWithTimeout(),\n MAX_SINGLE_RULE_TIMEOUT_MS,\n `Single rule execution timeout [ruleId=${rule.ruleId}]`\n )\n } catch (error) {\n const executionTime = Date.now() - startTime\n const errorMessage = error instanceof Error ? error.message : String(error)\n const enhancedError = `Failed to execute rule [ruleId=${rule.ruleId}, entityType=${context.entityType}]: ${errorMessage}`\n\n let logId: string | undefined\n\n // Log error if not dry run\n if (!context.dryRun) {\n logId = await logRuleExecution(em, {\n rule,\n context,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: enhancedError,\n })\n }\n\n return {\n rule,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: enhancedError,\n logId,\n }\n }\n}\n\n/**\n * Find all applicable rules for the given criteria\n */\nexport async function findApplicableRules(\n em: EntityManager,\n options: RuleDiscoveryOptions\n): Promise<BusinessRule[]> {\n // Validate input\n ruleDiscoveryOptionsSchema.parse(options)\n\n const { entityType, eventType, tenantId, organizationId, ruleType } = options\n\n const where: Partial<BusinessRule> = {\n entityType,\n tenantId,\n organizationId,\n enabled: true,\n deletedAt: null,\n }\n\n if (eventType) {\n where.eventType = eventType\n }\n\n if (ruleType) {\n where.ruleType = ruleType\n }\n\n const rules = await em.find(BusinessRule, where, {\n orderBy: { priority: 'DESC', ruleId: 'ASC' },\n })\n\n // Filter by effective date range\n const now = new Date()\n return rules.filter((rule) => {\n if (rule.effectiveFrom && rule.effectiveFrom > now) {\n return false\n }\n if (rule.effectiveTo && rule.effectiveTo < now) {\n return false\n }\n return true\n })\n}\n\n/**\n * Execute a specific rule by its database UUID\n * This bypasses the entityType/eventType discovery mechanism and directly executes the rule\n */\nexport async function executeRuleById(\n em: EntityManager,\n context: DirectRuleExecutionContext\n): Promise<DirectRuleExecutionResult> {\n const startTime = Date.now()\n\n // Validate input\n const validation = directRuleExecutionContextSchema.safeParse(context)\n if (!validation.success) {\n const validationErrors = validation.error.issues.map(e => `${e.path.join('.')}: ${e.message}`)\n return {\n success: false,\n ruleId: context.ruleId,\n ruleName: 'Unknown',\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: `Validation failed: ${validationErrors.join(', ')}`,\n }\n }\n\n // Fetch rule by ID with tenant/org validation\n const rule = await em.findOne(BusinessRule, {\n id: context.ruleId,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n deletedAt: null,\n })\n\n if (!rule) {\n return {\n success: false,\n ruleId: context.ruleId,\n ruleName: 'Unknown',\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: 'Rule not found',\n }\n }\n\n if (!rule.enabled) {\n return {\n success: false,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: 'Rule is disabled',\n }\n }\n\n // Check effective date range\n const now = new Date()\n if (rule.effectiveFrom && rule.effectiveFrom > now) {\n return {\n success: false,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: `Rule is not yet effective (starts ${rule.effectiveFrom.toISOString()})`,\n }\n }\n if (rule.effectiveTo && rule.effectiveTo < now) {\n return {\n success: false,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: `Rule has expired (ended ${rule.effectiveTo.toISOString()})`,\n }\n }\n\n // Build RuleEngineContext (use provided entityType or fall back to rule's)\n const engineContext: RuleEngineContext = {\n entityType: context.entityType || rule.entityType,\n entityId: context.entityId,\n eventType: context.eventType || rule.eventType || undefined,\n data: context.data,\n user: context.user,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n executedBy: context.executedBy,\n dryRun: context.dryRun,\n }\n\n // Execute via existing executeSingleRule\n const result = await executeSingleRule(em, rule, engineContext)\n\n return {\n success: !result.error,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: result.conditionResult,\n actionsExecuted: result.actionsExecuted,\n executionTime: result.executionTime,\n error: result.error,\n logId: result.logId,\n }\n}\n\n/**\n * Execute a rule by its string rule_id identifier\n * Looks up rule by rule_id (string column) + tenant_id (unique constraint)\n * This is useful for workflow conditions that reference rules by their string identifiers\n */\nexport async function executeRuleByRuleId(\n em: EntityManager,\n context: RuleIdExecutionContext\n): Promise<DirectRuleExecutionResult> {\n const startTime = Date.now()\n\n // Validate input\n const validation = ruleIdExecutionContextSchema.safeParse(context)\n if (!validation.success) {\n const validationErrors = validation.error.issues.map(e => `${e.path.join('.')}: ${e.message}`)\n return {\n success: false,\n ruleId: context.ruleId || 'unknown',\n ruleName: 'Unknown',\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: `Validation failed: ${validationErrors.join(', ')}`,\n }\n }\n\n // Fetch rule by rule_id (string identifier) + tenant/org\n const rule = await em.findOne(BusinessRule, {\n ruleId: context.ruleId, // String identifier column\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n deletedAt: null,\n })\n\n if (!rule) {\n return {\n success: false,\n ruleId: context.ruleId,\n ruleName: 'Unknown',\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: 'Rule not found',\n }\n }\n\n if (!rule.enabled) {\n return {\n success: false,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: 'Rule is disabled',\n }\n }\n\n // Check effective date range\n const now = new Date()\n if (rule.effectiveFrom && rule.effectiveFrom > now) {\n return {\n success: false,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: `Rule is not yet effective (starts ${rule.effectiveFrom.toISOString()})`,\n }\n }\n if (rule.effectiveTo && rule.effectiveTo < now) {\n return {\n success: false,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: Date.now() - startTime,\n error: `Rule has expired (ended ${rule.effectiveTo.toISOString()})`,\n }\n }\n\n // Build RuleEngineContext (use provided entityType or fall back to rule's)\n const engineContext: RuleEngineContext = {\n entityType: context.entityType || rule.entityType,\n entityId: context.entityId,\n eventType: context.eventType || rule.eventType || undefined,\n data: context.data,\n user: context.user,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n executedBy: context.executedBy,\n dryRun: context.dryRun,\n }\n\n // Execute via existing executeSingleRule\n const result = await executeSingleRule(em, rule, engineContext)\n\n return {\n success: !result.error,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n conditionResult: result.conditionResult,\n actionsExecuted: result.actionsExecuted,\n executionTime: result.executionTime,\n error: result.error,\n logId: result.logId,\n }\n}\n\n/**\n * Sensitive field patterns to exclude from logs\n */\nconst SENSITIVE_FIELD_PATTERNS = [\n /password/i,\n /passwd/i,\n /pwd/i,\n /secret/i,\n /token/i,\n /api[_-]?key/i,\n /auth/i,\n /credit[_-]?card/i,\n /card[_-]?number/i,\n /cvv/i,\n /ssn/i,\n /social[_-]?security/i,\n /tax[_-]?id/i,\n /driver[_-]?license/i,\n /passport/i,\n]\n\n/**\n * Maximum depth for nested object sanitization\n */\nconst MAX_SANITIZATION_DEPTH = 5\n\n/**\n * Sanitize data for logging by removing sensitive fields\n */\nfunction sanitizeForLogging(data: any, depth: number = 0): any {\n // Prevent infinite recursion\n if (depth > MAX_SANITIZATION_DEPTH) {\n return '[Max depth exceeded]'\n }\n\n // Handle null/undefined\n if (data === null || data === undefined) {\n return data\n }\n\n // Handle primitives\n if (typeof data !== 'object') {\n return data\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map(item => sanitizeForLogging(item, depth + 1))\n }\n\n // Handle objects\n const sanitized: Record<string, any> = {}\n\n for (const [key, value] of Object.entries(data)) {\n // Check if field name matches sensitive patterns\n const isSensitive = SENSITIVE_FIELD_PATTERNS.some(pattern => pattern.test(key))\n\n if (isSensitive) {\n sanitized[key] = '[REDACTED]'\n } else if (typeof value === 'object' && value !== null) {\n sanitized[key] = sanitizeForLogging(value, depth + 1)\n } else {\n sanitized[key] = value\n }\n }\n\n return sanitized\n}\n\n/**\n * Sanitize user object for logging (keep only safe fields)\n */\nfunction sanitizeUser(user: any): any {\n if (!user) {\n return undefined\n }\n\n // Only log safe user fields\n return {\n id: user.id,\n role: user.role,\n // Don't log: email, name, phone, address, etc.\n }\n}\n\n/**\n * Log rule execution to database\n */\ninterface LogExecutionOptions {\n rule: BusinessRule\n context: RuleEngineContext\n conditionResult: boolean\n actionsExecuted: ActionExecutionOutcome | null\n executionTime: number\n error?: string\n}\n\nexport async function logRuleExecution(\n em: EntityManager,\n options: LogExecutionOptions\n): Promise<string> {\n const { rule, context, conditionResult, actionsExecuted, executionTime, error } = options\n\n const executionResult: 'SUCCESS' | 'FAILURE' | 'ERROR' = error\n ? EXECUTION_RESULT_ERROR\n : conditionResult\n ? EXECUTION_RESULT_SUCCESS\n : EXECUTION_RESULT_FAILURE\n\n const log = em.create(RuleExecutionLog, {\n rule,\n entityId: context.entityId || DEFAULT_ENTITY_ID,\n entityType: context.entityType,\n executionResult,\n inputContext: {\n data: sanitizeForLogging(context.data),\n eventType: context.eventType,\n user: sanitizeUser(context.user),\n },\n outputContext: actionsExecuted\n ? {\n conditionResult,\n actionsExecuted: actionsExecuted.results.map((r) => ({\n type: r.action.type,\n success: r.success,\n error: r.error,\n })),\n }\n : null,\n errorMessage: error || null,\n executionTimeMs: executionTime,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n executedBy: context.executedBy || null,\n })\n\n await em.persistAndFlush(log)\n\n return log.id\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/core'\nimport type { EventBus } from '@open-mercato/events'\nimport { BusinessRule, RuleExecutionLog, type RuleType } from '../data/entities'\nimport * as ruleEvaluator from './rule-evaluator'\nimport * as actionExecutor from './action-executor'\nimport type { RuleEvaluationContext } from './rule-evaluator'\nimport type { ActionContext, ActionExecutionOutcome } from './action-executor'\nimport { ruleEngineContextSchema, ruleDiscoveryOptionsSchema } from '../data/validators'\n\n/**\n * Constants\n */\nconst DEFAULT_ENTITY_ID = 'unknown'\nconst RULE_TYPE_GUARD = 'GUARD'\nconst EXECUTION_RESULT_ERROR = 'ERROR'\nconst EXECUTION_RESULT_SUCCESS = 'SUCCESS'\nconst EXECUTION_RESULT_FAILURE = 'FAILURE'\n\n/**\n * Execution limits\n */\nconst MAX_RULES_PER_EXECUTION = 100\nconst MAX_SINGLE_RULE_TIMEOUT_MS = 30000 // 30 seconds\nconst MAX_TOTAL_EXECUTION_TIMEOUT_MS = 60000 // 60 seconds\n\n/**\n * Rule execution context\n */\nexport interface RuleEngineContext {\n entityType: string\n entityId?: string\n eventType?: string\n data: any\n user?: {\n id?: string\n email?: string\n role?: string\n [key: string]: any\n }\n tenant?: {\n id?: string\n [key: string]: any\n }\n organization?: {\n id?: string\n [key: string]: any\n }\n tenantId: string\n organizationId: string\n executedBy?: string\n dryRun?: boolean\n [key: string]: any\n}\n\n/**\n * Single rule execution result\n */\nexport interface RuleExecutionResult {\n rule: BusinessRule\n conditionResult: boolean\n actionsExecuted: ActionExecutionOutcome | null\n executionTime: number\n error?: string\n logId?: string // Database log ID (if logged)\n}\n\n/**\n * Overall rule engine result\n */\nexport interface RuleEngineResult {\n allowed: boolean\n executedRules: RuleExecutionResult[]\n totalExecutionTime: number\n errors?: string[]\n logIds?: string[]\n}\n\n/**\n * Rule discovery options\n */\nexport interface RuleDiscoveryOptions {\n entityType: string\n eventType?: string\n tenantId: string\n organizationId: string\n ruleType?: RuleType\n}\n\nexport type RuleEngineExecutionOptions = {\n eventBus?: Pick<EventBus, 'emitEvent'> | null\n}\n\ntype RuleExecutionFailedPayload = {\n ruleId: string\n ruleName: string\n entityType?: string | null\n errorMessage?: string | null\n tenantId: string\n organizationId?: string | null\n}\n\n/**\n * Execute a function with a timeout\n */\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(`${errorMessage} (timeout: ${timeoutMs}ms)`))\n }, timeoutMs)\n })\n\n try {\n return await Promise.race([promise, timeoutPromise])\n } finally {\n clearTimeout(timeoutId!)\n }\n}\n\n/**\n * Execute all applicable rules for the given context\n */\nexport async function executeRules(\n em: EntityManager,\n context: RuleEngineContext,\n options: RuleEngineExecutionOptions = {}\n): Promise<RuleEngineResult> {\n // Validate input\n const validation = ruleEngineContextSchema.safeParse(context)\n if (!validation.success) {\n const validationErrors = validation.error.issues.map(e => `${e.path.join('.')}: ${e.message}`)\n return {\n allowed: false,\n executedRules: [],\n totalExecutionTime: 0,\n errors: validationErrors,\n }\n }\n\n const startTime = Date.now()\n const executedRules: RuleExecutionResult[] = []\n const errors: string[] = []\n const logIds: string[] = []\n\n try {\n // Discover applicable rules\n const rules = await findApplicableRules(em, {\n entityType: context.entityType,\n eventType: context.eventType,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n })\n\n // Check rule count limit\n if (rules.length > MAX_RULES_PER_EXECUTION) {\n errors.push(\n `Rule count limit exceeded: ${rules.length} rules found, maximum is ${MAX_RULES_PER_EXECUTION}`\n )\n return {\n allowed: false,\n executedRules: [],\n totalExecutionTime: Date.now() - startTime,\n errors,\n }\n }\n\n // Rules already sorted by database query (priority DESC, ruleId ASC)\n // Execute each rule with total timeout\n const executionPromise = (async () => {\n for (const rule of rules) {\n try {\n const ruleResult = await executeSingleRule(em, rule, context, options)\n executedRules.push(ruleResult)\n\n if (ruleResult.logId) {\n logIds.push(ruleResult.logId)\n }\n\n if (ruleResult.error) {\n errors.push(\n `Rule execution failed [ruleId=${rule.ruleId}, type=${rule.ruleType}, entityType=${context.entityType}]: ${ruleResult.error}`\n )\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n errors.push(\n `Unexpected error in rule execution [ruleId=${rule.ruleId}, type=${rule.ruleType}]: ${errorMessage}`\n )\n\n if (!context.dryRun) {\n await emitRuleExecutionFailed(options.eventBus, {\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n entityType: context.entityType ?? null,\n errorMessage,\n tenantId: context.tenantId,\n organizationId: context.organizationId ?? null,\n })\n }\n\n executedRules.push({\n rule,\n conditionResult: false,\n actionsExecuted: null,\n executionTime: 0,\n error: errorMessage,\n })\n }\n }\n })()\n\n // Execute with timeout\n await withTimeout(\n executionPromise,\n MAX_TOTAL_EXECUTION_TIMEOUT_MS,\n `Total rule execution timeout [entityType=${context.entityType}]`\n )\n\n // Determine overall allowed status\n // For GUARD rules: all must pass for operation to be allowed\n const guardRules = executedRules.filter((r) => r.rule.ruleType === RULE_TYPE_GUARD)\n const allowed = guardRules.length === 0 || guardRules.every((r) => r.conditionResult)\n\n const totalExecutionTime = Date.now() - startTime\n\n return {\n allowed,\n executedRules,\n totalExecutionTime,\n errors: errors.length > 0 ? errors : undefined,\n logIds: logIds.length > 0 ? logIds : undefined,\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n const stack = error instanceof Error ? error.stack : undefined\n errors.push(\n `Critical rule engine error [entityType=${context.entityType}, entityId=${context.entityId || 'unknown'}]: ${errorMessage}${stack ? `\\nStack: ${stack}` : ''}`\n )\n\n const totalExecutionTime = Date.now() - startTime\n\n return {\n allowed: false,\n executedRules,\n totalExecutionTime,\n errors,\n }\n }\n}\n\n/**\n * Execute a single rule\n */\nexport async function executeSingleRule(\n em: EntityManager,\n rule: BusinessRule,\n context: RuleEngineContext,\n options: RuleEngineExecutionOptions = {}\n): Promise<RuleExecutionResult> {\n const startTime = Date.now()\n\n try {\n // Wrap execution in timeout\n const executeWithTimeout = async () => {\n // Build evaluation context\n const evalContext: RuleEvaluationContext = {\n entityType: context.entityType,\n entityId: context.entityId,\n eventType: context.eventType,\n user: context.user,\n tenant: context.tenant,\n organization: context.organization,\n }\n\n // Evaluate rule conditions\n const result = await ruleEvaluator.evaluateSingleRule(rule, context.data, evalContext)\n\n // Check if evaluation completed (not just if conditions passed)\n if (!result.evaluationCompleted) {\n const executionTime = Date.now() - startTime\n\n let logId: string | undefined\n\n // Log failure if not dry run\n if (!context.dryRun) {\n logId = await logRuleExecution(em, {\n rule,\n context,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: result.error,\n })\n\n await emitRuleExecutionFailed(options.eventBus, {\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n entityType: context.entityType ?? null,\n errorMessage: result.error ?? null,\n tenantId: context.tenantId,\n organizationId: context.organizationId ?? null,\n })\n }\n\n return {\n rule,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: result.error,\n logId,\n }\n }\n\n // Evaluation completed successfully - determine which actions to execute\n const actions = result.conditionsPassed ? rule.successActions : rule.failureActions\n\n let actionsExecuted: ActionExecutionOutcome | null = null\n\n if (actions && Array.isArray(actions) && actions.length > 0) {\n // Build action context\n const actionContext: ActionContext = {\n ...evalContext,\n data: context.data,\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n }\n\n // Execute actions\n actionsExecuted = await actionExecutor.executeActions(actions, actionContext)\n }\n\n const executionTime = Date.now() - startTime\n\n let logId: string | undefined\n\n // Log execution if not dry run\n if (!context.dryRun) {\n logId = await logRuleExecution(em, {\n rule,\n context,\n conditionResult: result.conditionsPassed,\n actionsExecuted,\n executionTime,\n })\n }\n\n return {\n rule,\n conditionResult: result.conditionsPassed,\n actionsExecuted,\n executionTime,\n logId,\n }\n }\n\n // Execute with single rule timeout\n return await withTimeout(\n executeWithTimeout(),\n MAX_SINGLE_RULE_TIMEOUT_MS,\n `Single rule execution timeout [ruleId=${rule.ruleId}]`\n )\n } catch (error) {\n const executionTime = Date.now() - startTime\n const errorMessage = error instanceof Error ? error.message : String(error)\n const enhancedError = `Failed to execute rule [ruleId=${rule.ruleId}, entityType=${context.entityType}]: ${errorMessage}`\n\n let logId: string | undefined\n\n // Log error if not dry run\n if (!context.dryRun) {\n logId = await logRuleExecution(em, {\n rule,\n context,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: enhancedError,\n })\n\n await emitRuleExecutionFailed(options.eventBus, {\n ruleId: rule.ruleId,\n ruleName: rule.ruleName,\n entityType: context.entityType ?? null,\n errorMessage: enhancedError,\n tenantId: context.tenantId,\n organizationId: context.organizationId ?? null,\n })\n }\n\n return {\n rule,\n conditionResult: false,\n actionsExecuted: null,\n executionTime,\n error: enhancedError,\n logId,\n }\n }\n}\n\n/**\n * Find all applicable rules for the given criteria\n */\nexport async function findApplicableRules(\n em: EntityManager,\n options: RuleDiscoveryOptions\n): Promise<BusinessRule[]> {\n // Validate input\n ruleDiscoveryOptionsSchema.parse(options)\n\n const { entityType, eventType, tenantId, organizationId, ruleType } = options\n\n const where: Partial<BusinessRule> = {\n entityType,\n tenantId,\n organizationId,\n enabled: true,\n deletedAt: null,\n }\n\n if (eventType) {\n where.eventType = eventType\n }\n\n if (ruleType) {\n where.ruleType = ruleType\n }\n\n const rules = await em.find(BusinessRule, where, {\n orderBy: { priority: 'DESC', ruleId: 'ASC' },\n })\n\n // Filter by effective date range\n const now = new Date()\n return rules.filter((rule) => {\n if (rule.effectiveFrom && rule.effectiveFrom > now) {\n return false\n }\n if (rule.effectiveTo && rule.effectiveTo < now) {\n return false\n }\n return true\n })\n}\n\n/**\n * Sensitive field patterns to exclude from logs\n */\nconst SENSITIVE_FIELD_PATTERNS = [\n /password/i,\n /passwd/i,\n /pwd/i,\n /secret/i,\n /token/i,\n /api[_-]?key/i,\n /auth/i,\n /credit[_-]?card/i,\n /card[_-]?number/i,\n /cvv/i,\n /ssn/i,\n /social[_-]?security/i,\n /tax[_-]?id/i,\n /driver[_-]?license/i,\n /passport/i,\n]\n\n/**\n * Maximum depth for nested object sanitization\n */\nconst MAX_SANITIZATION_DEPTH = 5\n\n/**\n * Sanitize data for logging by removing sensitive fields\n */\nfunction sanitizeForLogging(data: any, depth: number = 0): any {\n // Prevent infinite recursion\n if (depth > MAX_SANITIZATION_DEPTH) {\n return '[Max depth exceeded]'\n }\n\n // Handle null/undefined\n if (data === null || data === undefined) {\n return data\n }\n\n // Handle primitives\n if (typeof data !== 'object') {\n return data\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map(item => sanitizeForLogging(item, depth + 1))\n }\n\n // Handle objects\n const sanitized: Record<string, any> = {}\n\n for (const [key, value] of Object.entries(data)) {\n // Check if field name matches sensitive patterns\n const isSensitive = SENSITIVE_FIELD_PATTERNS.some(pattern => pattern.test(key))\n\n if (isSensitive) {\n sanitized[key] = '[REDACTED]'\n } else if (typeof value === 'object' && value !== null) {\n sanitized[key] = sanitizeForLogging(value, depth + 1)\n } else {\n sanitized[key] = value\n }\n }\n\n return sanitized\n}\n\n/**\n * Sanitize user object for logging (keep only safe fields)\n */\nfunction sanitizeUser(user: any): any {\n if (!user) {\n return undefined\n }\n\n // Only log safe user fields\n return {\n id: user.id,\n role: user.role,\n // Don't log: email, name, phone, address, etc.\n }\n}\n\n/**\n * Log rule execution to database\n */\ninterface LogExecutionOptions {\n rule: BusinessRule\n context: RuleEngineContext\n conditionResult: boolean\n actionsExecuted: ActionExecutionOutcome | null\n executionTime: number\n error?: string\n}\n\nexport async function logRuleExecution(\n em: EntityManager,\n options: LogExecutionOptions\n): Promise<string> {\n const { rule, context, conditionResult, actionsExecuted, executionTime, error } = options\n\n const executionResult: 'SUCCESS' | 'FAILURE' | 'ERROR' = error\n ? EXECUTION_RESULT_ERROR\n : conditionResult\n ? EXECUTION_RESULT_SUCCESS\n : EXECUTION_RESULT_FAILURE\n\n const log = em.create(RuleExecutionLog, {\n rule,\n entityId: context.entityId || DEFAULT_ENTITY_ID,\n entityType: context.entityType,\n executionResult,\n inputContext: {\n data: sanitizeForLogging(context.data),\n eventType: context.eventType,\n user: sanitizeUser(context.user),\n },\n outputContext: actionsExecuted\n ? {\n conditionResult,\n actionsExecuted: actionsExecuted.results.map((r) => ({\n type: r.action.type,\n success: r.success,\n error: r.error,\n })),\n }\n : null,\n errorMessage: error || null,\n executionTimeMs: executionTime,\n tenantId: context.tenantId,\n organizationId: context.organizationId,\n executedBy: context.executedBy || null,\n })\n\n await em.persistAndFlush(log)\n\n return log.id\n}\n\nasync function emitRuleExecutionFailed(\n eventBus: Pick<EventBus, 'emitEvent'> | null | undefined,\n payload: RuleExecutionFailedPayload\n): Promise<void> {\n if (!eventBus?.emitEvent) return\n\n await eventBus.emitEvent('business_rules.rule.execution_failed', payload).catch(() => undefined)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["executionTime", "logId"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const notificationTypes = [
|
|
2
|
+
{
|
|
3
|
+
type: "business_rules.rule.execution_failed",
|
|
4
|
+
module: "business_rules",
|
|
5
|
+
titleKey: "businessRules.notifications.rule.executionFailed.title",
|
|
6
|
+
bodyKey: "businessRules.notifications.rule.executionFailed.body",
|
|
7
|
+
icon: "alert-triangle",
|
|
8
|
+
severity: "error",
|
|
9
|
+
actions: [
|
|
10
|
+
{
|
|
11
|
+
id: "view",
|
|
12
|
+
labelKey: "common.view",
|
|
13
|
+
variant: "outline",
|
|
14
|
+
href: "/backend/business-rules/{sourceEntityId}",
|
|
15
|
+
icon: "external-link"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
linkHref: "/backend/business-rules/{sourceEntityId}",
|
|
19
|
+
expiresAfterHours: 168
|
|
20
|
+
// 7 days
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
var notifications_default = notificationTypes;
|
|
24
|
+
export {
|
|
25
|
+
notifications_default as default,
|
|
26
|
+
notificationTypes
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=notifications.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/business_rules/notifications.ts"],
|
|
4
|
+
"sourcesContent": ["import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'\n\nexport const notificationTypes: NotificationTypeDefinition[] = [\n {\n type: 'business_rules.rule.execution_failed',\n module: 'business_rules',\n titleKey: 'businessRules.notifications.rule.executionFailed.title',\n bodyKey: 'businessRules.notifications.rule.executionFailed.body',\n icon: 'alert-triangle',\n severity: 'error',\n actions: [\n {\n id: 'view',\n labelKey: 'common.view',\n variant: 'outline',\n href: '/backend/business-rules/{sourceEntityId}',\n icon: 'external-link',\n },\n ],\n linkHref: '/backend/business-rules/{sourceEntityId}',\n expiresAfterHours: 168, // 7 days\n },\n]\n\nexport default notificationTypes\n"],
|
|
5
|
+
"mappings": "AAEO,MAAM,oBAAkD;AAAA,EAC7D;AAAA,IACE,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP;AAAA,QACE,IAAI;AAAA,QACJ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,UAAU;AAAA,IACV,mBAAmB;AAAA;AAAA,EACrB;AACF;AAEA,IAAO,wBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { resolveNotificationService } from "../../notifications/lib/notificationService.js";
|
|
2
|
+
import { buildFeatureNotificationFromType } from "../../notifications/lib/notificationBuilder.js";
|
|
3
|
+
import { notificationTypes } from "../notifications.js";
|
|
4
|
+
const metadata = {
|
|
5
|
+
event: "business_rules.rule.execution_failed",
|
|
6
|
+
persistent: true,
|
|
7
|
+
id: "business_rules:rule-execution-failed-notification"
|
|
8
|
+
};
|
|
9
|
+
async function handle(payload, ctx) {
|
|
10
|
+
try {
|
|
11
|
+
const notificationService = resolveNotificationService(ctx);
|
|
12
|
+
const typeDef = notificationTypes.find((type) => type.type === "business_rules.rule.execution_failed");
|
|
13
|
+
if (!typeDef) return;
|
|
14
|
+
const notificationInput = buildFeatureNotificationFromType(typeDef, {
|
|
15
|
+
requiredFeature: "business_rules.manage",
|
|
16
|
+
bodyVariables: {
|
|
17
|
+
ruleName: payload.ruleName,
|
|
18
|
+
entityType: payload.entityType ?? "",
|
|
19
|
+
errorMessage: payload.errorMessage ?? "Unknown error"
|
|
20
|
+
},
|
|
21
|
+
sourceEntityType: "business_rules:rule",
|
|
22
|
+
sourceEntityId: payload.ruleId,
|
|
23
|
+
linkHref: `/backend/business-rules/${payload.ruleId}`
|
|
24
|
+
});
|
|
25
|
+
await notificationService.createForFeature(notificationInput, {
|
|
26
|
+
tenantId: payload.tenantId,
|
|
27
|
+
organizationId: payload.organizationId ?? null
|
|
28
|
+
});
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error("[business_rules:rule-execution-failed-notification] Failed to create notification:", err);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
handle as default,
|
|
35
|
+
metadata
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=rule-execution-failed-notification.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/business_rules/subscribers/rule-execution-failed-notification.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { notificationTypes } from '../notifications'\n\nexport const metadata = {\n event: 'business_rules.rule.execution_failed',\n persistent: true,\n id: 'business_rules:rule-execution-failed-notification',\n}\n\ntype RuleExecutionFailedPayload = {\n ruleId: string\n ruleName: string\n entityType?: string | null\n errorMessage?: string | null\n tenantId: string\n organizationId?: string | null\n}\n\ntype ResolverContext = {\n resolve: <T = unknown>(name: string) => T\n}\n\nexport default async function handle(payload: RuleExecutionFailedPayload, ctx: ResolverContext) {\n try {\n const notificationService = resolveNotificationService(ctx)\n const typeDef = notificationTypes.find((type) => type.type === 'business_rules.rule.execution_failed')\n if (!typeDef) return\n\n const notificationInput = buildFeatureNotificationFromType(typeDef, {\n requiredFeature: 'business_rules.manage',\n bodyVariables: {\n ruleName: payload.ruleName,\n entityType: payload.entityType ?? '',\n errorMessage: payload.errorMessage ?? 'Unknown error',\n },\n sourceEntityType: 'business_rules:rule',\n sourceEntityId: payload.ruleId,\n linkHref: `/backend/business-rules/${payload.ruleId}`,\n })\n\n await notificationService.createForFeature(notificationInput, {\n tenantId: payload.tenantId,\n organizationId: payload.organizationId ?? null,\n })\n } catch (err) {\n console.error('[business_rules:rule-execution-failed-notification] Failed to create notification:', err)\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,kCAAkC;AAC3C,SAAS,wCAAwC;AACjD,SAAS,yBAAyB;AAE3B,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAeA,eAAO,OAA8B,SAAqC,KAAsB;AAC9F,MAAI;AACF,UAAM,sBAAsB,2BAA2B,GAAG;AAC1D,UAAM,UAAU,kBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS,sCAAsC;AACrG,QAAI,CAAC,QAAS;AAEd,UAAM,oBAAoB,iCAAiC,SAAS;AAAA,MAClE,iBAAiB;AAAA,MACjB,eAAe;AAAA,QACb,UAAU,QAAQ;AAAA,QAClB,YAAY,QAAQ,cAAc;AAAA,QAClC,cAAc,QAAQ,gBAAgB;AAAA,MACxC;AAAA,MACA,kBAAkB;AAAA,MAClB,gBAAgB,QAAQ;AAAA,MACxB,UAAU,2BAA2B,QAAQ,MAAM;AAAA,IACrD,CAAC;AAED,UAAM,oBAAoB,iBAAiB,mBAAmB;AAAA,MAC5D,UAAU,QAAQ;AAAA,MAClB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC5C,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,MAAM,sFAAsF,GAAG;AAAA,EACzG;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -326,10 +326,12 @@ function PriceKindSettings() {
|
|
|
326
326
|
{
|
|
327
327
|
items: [
|
|
328
328
|
{
|
|
329
|
+
id: "edit",
|
|
329
330
|
label: t("catalog.priceKinds.actions.edit", "Edit"),
|
|
330
331
|
onSelect: () => openDialog({ mode: "edit", entry })
|
|
331
332
|
},
|
|
332
333
|
{
|
|
334
|
+
id: "delete",
|
|
333
335
|
label: t("catalog.priceKinds.actions.delete", "Delete"),
|
|
334
336
|
destructive: true,
|
|
335
337
|
onSelect: () => {
|