@open-mercato/core 0.4.2-canary-da2b080494 → 0.4.2-canary-19353c5970
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 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -0
- 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/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 +4 -2
- package/dist/modules/auth/data/validators.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 +23 -2
- 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 +3 -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/lib/rule-engine.js +33 -3
- 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/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/dictionaries/components/DictionaryTable.js +2 -0
- package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
- 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/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/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/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/commands/documents.js +53 -0
- 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/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/backend/definitions/page.js +5 -0
- package/dist/modules/workflows/backend/definitions/page.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/page.js +3 -0
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +14 -6
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- 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 -1
- package/generated/entity-fields-registry.ts +2 -0
- 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/admin/nav.ts +10 -6
- 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 +5 -2
- package/src/modules/auth/frontend/reset/[token]/page.tsx +24 -11
- package/src/modules/auth/i18n/de.json +43 -1
- package/src/modules/auth/i18n/en.json +43 -1
- package/src/modules/auth/i18n/es.json +43 -1
- package/src/modules/auth/i18n/pl.json +43 -1
- package/src/modules/auth/lib/setup-app.ts +29 -2
- package/src/modules/auth/notifications.ts +109 -0
- package/src/modules/auth/services/authService.ts +4 -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/i18n/en.json +3 -1
- package/src/modules/business_rules/lib/__tests__/rule-engine.test.ts +51 -0
- package/src/modules/business_rules/lib/rule-engine.ts +57 -3
- 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/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/dictionaries/components/DictionaryTable.tsx +2 -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 +300 -0
- package/src/modules/notifications/migrations/Migration20260123000001.ts +73 -0
- package/src/modules/notifications/migrations/Migration20260126150000.ts +39 -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/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/backend/sales/channels/offers/page.tsx +2 -0
- package/src/modules/sales/backend/sales/channels/page.tsx +2 -0
- package/src/modules/sales/commands/documents.ts +65 -0
- 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/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/backend/definitions/page.tsx +5 -0
- package/src/modules/workflows/backend/instances/page.tsx +4 -1
- package/src/modules/workflows/backend/tasks/page.tsx +4 -1
- package/src/modules/workflows/i18n/en.json +3 -1
- package/src/modules/workflows/lib/transition-handler.ts +18 -6
- package/src/modules/workflows/notifications.ts +25 -0
- package/src/modules/workflows/subscribers/task-assigned-notification.ts +53 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
2
|
+
import { resolveNotificationService } from '../../notifications/lib/notificationService'
|
|
3
|
+
import { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'
|
|
4
|
+
import { notificationTypes } from '../notifications'
|
|
5
|
+
|
|
6
|
+
export const metadata = {
|
|
7
|
+
event: 'catalog.product.stock_low',
|
|
8
|
+
persistent: true,
|
|
9
|
+
id: 'catalog:low-stock-notification',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type LowStockPayload = {
|
|
13
|
+
productId: string
|
|
14
|
+
productName: string
|
|
15
|
+
sku?: string | null
|
|
16
|
+
currentStock: number
|
|
17
|
+
threshold: number
|
|
18
|
+
tenantId: string
|
|
19
|
+
organizationId?: string | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type ResolverContext = {
|
|
23
|
+
resolve: <T = unknown>(name: string) => T
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default async function handle(payload: LowStockPayload, ctx: ResolverContext) {
|
|
27
|
+
try {
|
|
28
|
+
const notificationService = resolveNotificationService(ctx)
|
|
29
|
+
const typeDef = notificationTypes.find((type) => type.type === 'catalog.product.low_stock')
|
|
30
|
+
if (!typeDef) return
|
|
31
|
+
|
|
32
|
+
const notificationInput = buildFeatureNotificationFromType(typeDef, {
|
|
33
|
+
requiredFeature: 'catalog.products.manage',
|
|
34
|
+
bodyVariables: {
|
|
35
|
+
productName: payload.productName,
|
|
36
|
+
sku: payload.sku ?? '',
|
|
37
|
+
currentStock: String(payload.currentStock),
|
|
38
|
+
threshold: String(payload.threshold),
|
|
39
|
+
},
|
|
40
|
+
sourceEntityType: 'catalog:product',
|
|
41
|
+
sourceEntityId: payload.productId,
|
|
42
|
+
linkHref: `/backend/catalog/products/${payload.productId}`,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
await notificationService.createForFeature(notificationInput, {
|
|
46
|
+
tenantId: payload.tenantId,
|
|
47
|
+
organizationId: payload.organizationId ?? null,
|
|
48
|
+
})
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error('[catalog:low-stock-notification] Failed to create notification:', err)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -2,6 +2,7 @@ import type { ModuleCli } from '@open-mercato/shared/modules/registry'
|
|
|
2
2
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
3
3
|
import type { ModuleConfigService } from './lib/module-config-service'
|
|
4
4
|
import { parseBooleanToken } from '@open-mercato/shared/lib/boolean'
|
|
5
|
+
import { DEFAULT_NOTIFICATION_DELIVERY_CONFIG, NOTIFICATIONS_DELIVERY_CONFIG_KEY } from '../notifications/lib/deliveryConfig'
|
|
5
6
|
|
|
6
7
|
function envDisablesAutoIndexing(): boolean {
|
|
7
8
|
const raw = process.env.DISABLE_VECTOR_SEARCH_AUTOINDEXING
|
|
@@ -31,6 +32,11 @@ const restoreDefaults: ModuleCli = {
|
|
|
31
32
|
name: 'auto_index_enabled',
|
|
32
33
|
value: defaultEnabled,
|
|
33
34
|
},
|
|
35
|
+
{
|
|
36
|
+
moduleId: 'notifications',
|
|
37
|
+
name: NOTIFICATIONS_DELIVERY_CONFIG_KEY,
|
|
38
|
+
value: DEFAULT_NOTIFICATION_DELIVERY_CONFIG,
|
|
39
|
+
},
|
|
34
40
|
],
|
|
35
41
|
{ force: true },
|
|
36
42
|
)
|
|
@@ -194,7 +194,7 @@ export function CachePanel() {
|
|
|
194
194
|
<header className="space-y-1">
|
|
195
195
|
<h2 className="text-lg font-semibold">{t('configs.cache.title', 'Cache overview')}</h2>
|
|
196
196
|
<p className="text-sm text-muted-foreground">
|
|
197
|
-
{t('configs.cache.description', 'Inspect cached
|
|
197
|
+
{t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}
|
|
198
198
|
</p>
|
|
199
199
|
</header>
|
|
200
200
|
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
@@ -211,7 +211,7 @@ export function CachePanel() {
|
|
|
211
211
|
<header className="space-y-1">
|
|
212
212
|
<h2 className="text-lg font-semibold">{t('configs.cache.title', 'Cache overview')}</h2>
|
|
213
213
|
<p className="text-sm text-muted-foreground">
|
|
214
|
-
{t('configs.cache.description', 'Inspect cached
|
|
214
|
+
{t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}
|
|
215
215
|
</p>
|
|
216
216
|
</header>
|
|
217
217
|
<div className="rounded border border-red-200 bg-red-50 p-3 text-sm text-red-700">
|
|
@@ -235,7 +235,7 @@ export function CachePanel() {
|
|
|
235
235
|
<div className="space-y-1">
|
|
236
236
|
<h2 className="text-lg font-semibold">{t('configs.cache.title', 'Cache overview')}</h2>
|
|
237
237
|
<p className="text-sm text-muted-foreground">
|
|
238
|
-
{t('configs.cache.description', 'Inspect cached
|
|
238
|
+
{t('configs.cache.description', 'Inspect cached responses and clear segments when necessary.')}
|
|
239
239
|
</p>
|
|
240
240
|
{stats ? (
|
|
241
241
|
<>
|
|
@@ -342,7 +342,7 @@ export function CachePanel() {
|
|
|
342
342
|
</div>
|
|
343
343
|
) : (
|
|
344
344
|
<p className="text-sm text-muted-foreground">
|
|
345
|
-
{t('configs.cache.empty', 'No cached
|
|
345
|
+
{t('configs.cache.empty', 'No cached responses for this tenant.')}
|
|
346
346
|
</p>
|
|
347
347
|
)}
|
|
348
348
|
</div>
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"configs.systemStatus.actions.purgeCacheUnavailable": "Cache service is unavailable.",
|
|
36
36
|
"configs.config.nav.cache": "Cache",
|
|
37
37
|
"configs.cache.title": "Cache overview",
|
|
38
|
-
"configs.cache.description": "Inspect cached
|
|
38
|
+
"configs.cache.description": "Inspect cached responses and clear segments when necessary.",
|
|
39
39
|
"configs.cache.loading": "Loading cache statistics…",
|
|
40
40
|
"configs.cache.loadError": "Failed to load cache statistics.",
|
|
41
41
|
"configs.cache.retry": "Retry",
|
|
42
42
|
"configs.cache.refresh": "Refresh",
|
|
43
43
|
"configs.cache.generatedAt": "Stats generated {{timestamp}}",
|
|
44
44
|
"configs.cache.totalEntries": "{{count}} cached entries",
|
|
45
|
-
"configs.cache.empty": "No cached
|
|
45
|
+
"configs.cache.empty": "No cached responses for this tenant.",
|
|
46
46
|
"configs.cache.purgeAll": "Purge all cache",
|
|
47
47
|
"configs.cache.purgeAllLoading": "Purging…",
|
|
48
48
|
"configs.cache.purgeAllConfirm": "Purge all cached entries for this tenant?",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"configs.systemStatus.categories.profilingDescription": "Flags that control request and query profiling outputs.",
|
|
65
65
|
"configs.systemStatus.categories.logging": "Logging",
|
|
66
66
|
"configs.systemStatus.categories.loggingDescription": "Tune verbosity and SQL logging for diagnostics.",
|
|
67
|
+
"configs.systemStatus.categories.security": "Security",
|
|
68
|
+
"configs.systemStatus.categories.securityDescription": "Password policy requirements enforced at login and user creation.",
|
|
67
69
|
"configs.systemStatus.categories.caching": "Caching",
|
|
68
70
|
"configs.systemStatus.categories.cachingDescription": "Cache providers and TTL controls for backend responses.",
|
|
69
71
|
"configs.systemStatus.categories.queryIndex": "Query index",
|
|
@@ -84,6 +86,14 @@
|
|
|
84
86
|
"configs.systemStatus.variables.logVerbosity.description": "Overrides structured log verbosity such as debug or trace.",
|
|
85
87
|
"configs.systemStatus.variables.logLevel.label": "Log level",
|
|
86
88
|
"configs.systemStatus.variables.logLevel.description": "Fallback log level applied when verbosity is not set.",
|
|
89
|
+
"configs.systemStatus.variables.passwordMinLength.label": "Password min length",
|
|
90
|
+
"configs.systemStatus.variables.passwordMinLength.description": "Minimum number of characters required for passwords.",
|
|
91
|
+
"configs.systemStatus.variables.passwordRequireDigit.label": "Password requires digit",
|
|
92
|
+
"configs.systemStatus.variables.passwordRequireDigit.description": "Require at least one numeric character.",
|
|
93
|
+
"configs.systemStatus.variables.passwordRequireUppercase.label": "Password requires uppercase",
|
|
94
|
+
"configs.systemStatus.variables.passwordRequireUppercase.description": "Require at least one uppercase letter.",
|
|
95
|
+
"configs.systemStatus.variables.passwordRequireSpecial.label": "Password requires special",
|
|
96
|
+
"configs.systemStatus.variables.passwordRequireSpecial.description": "Require at least one special character.",
|
|
87
97
|
"configs.systemStatus.variables.enableCrudApiCache.label": "CRUD API cache",
|
|
88
98
|
"configs.systemStatus.variables.enableCrudApiCache.description": "Enable the CRUD API response cache layer.",
|
|
89
99
|
"configs.systemStatus.variables.cacheStrategy.label": "Cache strategy",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"configs.systemStatus.actions.purgeCacheUnavailable": "Usługa pamięci podręcznej jest niedostępna.",
|
|
36
36
|
"configs.config.nav.cache": "Pamięć podręczna",
|
|
37
37
|
"configs.cache.title": "Podgląd pamięci podręcznej",
|
|
38
|
-
"configs.cache.description": "Przeglądaj zapisane odpowiedzi
|
|
38
|
+
"configs.cache.description": "Przeglądaj zapisane odpowiedzi i czyść segmenty w razie potrzeby.",
|
|
39
39
|
"configs.cache.loading": "Ładowanie statystyk pamięci podręcznej…",
|
|
40
40
|
"configs.cache.loadError": "Nie udało się wczytać statystyk pamięci podręcznej.",
|
|
41
41
|
"configs.cache.retry": "Spróbuj ponownie",
|
|
42
42
|
"configs.cache.refresh": "Odśwież",
|
|
43
43
|
"configs.cache.generatedAt": "Statystyki z {{timestamp}}",
|
|
44
44
|
"configs.cache.totalEntries": "{{count}} wpisów w pamięci podręcznej",
|
|
45
|
-
"configs.cache.empty": "Brak zapisanych odpowiedzi
|
|
45
|
+
"configs.cache.empty": "Brak zapisanych odpowiedzi dla tego tenanta.",
|
|
46
46
|
"configs.cache.purgeAll": "Wyczyść całą pamięć",
|
|
47
47
|
"configs.cache.purgeAllLoading": "Czyszczenie…",
|
|
48
48
|
"configs.cache.purgeAllConfirm": "Wyczyścić wszystkie wpisy pamięci podręcznej dla tego tenanta?",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"configs.systemStatus.categories.profilingDescription": "Flagi sterujące generowaniem danych z profilowania zapytań i żądań.",
|
|
65
65
|
"configs.systemStatus.categories.logging": "Logowanie",
|
|
66
66
|
"configs.systemStatus.categories.loggingDescription": "Dostosuj poziom logowania i zapisywanie zapytań SQL na potrzeby diagnostyki.",
|
|
67
|
+
"configs.systemStatus.categories.security": "Bezpieczeństwo",
|
|
68
|
+
"configs.systemStatus.categories.securityDescription": "Wymagania polityki haseł stosowane przy logowaniu i tworzeniu użytkowników.",
|
|
67
69
|
"configs.systemStatus.categories.caching": "Buforowanie",
|
|
68
70
|
"configs.systemStatus.categories.cachingDescription": "Mechanizmy cache oraz kontrola czasu życia odpowiedzi backendu.",
|
|
69
71
|
"configs.systemStatus.categories.queryIndex": "Indeks zapytań",
|
|
@@ -84,6 +86,14 @@
|
|
|
84
86
|
"configs.systemStatus.variables.logVerbosity.description": "Nadpisuje poziom szczegółowości logów, np. debug lub trace.",
|
|
85
87
|
"configs.systemStatus.variables.logLevel.label": "Poziom logowania",
|
|
86
88
|
"configs.systemStatus.variables.logLevel.description": "Domyślny poziom logowania używany, gdy nie ustawiono szczegółowości.",
|
|
89
|
+
"configs.systemStatus.variables.passwordMinLength.label": "Minimalna długość hasła",
|
|
90
|
+
"configs.systemStatus.variables.passwordMinLength.description": "Minimalna liczba znaków wymagana w haśle.",
|
|
91
|
+
"configs.systemStatus.variables.passwordRequireDigit.label": "Hasło wymaga cyfry",
|
|
92
|
+
"configs.systemStatus.variables.passwordRequireDigit.description": "Wymagaj co najmniej jednej cyfry.",
|
|
93
|
+
"configs.systemStatus.variables.passwordRequireUppercase.label": "Hasło wymaga wielkiej litery",
|
|
94
|
+
"configs.systemStatus.variables.passwordRequireUppercase.description": "Wymagaj co najmniej jednej wielkiej litery.",
|
|
95
|
+
"configs.systemStatus.variables.passwordRequireSpecial.label": "Hasło wymaga znaku specjalnego",
|
|
96
|
+
"configs.systemStatus.variables.passwordRequireSpecial.description": "Wymagaj co najmniej jednego znaku specjalnego.",
|
|
87
97
|
"configs.systemStatus.variables.enableCrudApiCache.label": "Cache API CRUD",
|
|
88
98
|
"configs.systemStatus.variables.enableCrudApiCache.description": "Włącza warstwę buforowania odpowiedzi API CRUD.",
|
|
89
99
|
"configs.systemStatus.variables.cacheStrategy.label": "Strategia cache",
|
|
@@ -19,7 +19,14 @@ type SystemStatusVariableDefinition = {
|
|
|
19
19
|
defaultValue: string | null
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const CATEGORY_ORDER: SystemStatusCategoryKey[] = [
|
|
22
|
+
const CATEGORY_ORDER: SystemStatusCategoryKey[] = [
|
|
23
|
+
'profiling',
|
|
24
|
+
'logging',
|
|
25
|
+
'security',
|
|
26
|
+
'caching',
|
|
27
|
+
'query_index',
|
|
28
|
+
'entities',
|
|
29
|
+
]
|
|
23
30
|
|
|
24
31
|
const CATEGORY_METADATA: Record<
|
|
25
32
|
SystemStatusCategoryKey,
|
|
@@ -33,6 +40,10 @@ const CATEGORY_METADATA: Record<
|
|
|
33
40
|
labelKey: 'configs.systemStatus.categories.logging',
|
|
34
41
|
descriptionKey: 'configs.systemStatus.categories.loggingDescription',
|
|
35
42
|
},
|
|
43
|
+
security: {
|
|
44
|
+
labelKey: 'configs.systemStatus.categories.security',
|
|
45
|
+
descriptionKey: 'configs.systemStatus.categories.securityDescription',
|
|
46
|
+
},
|
|
36
47
|
caching: {
|
|
37
48
|
labelKey: 'configs.systemStatus.categories.caching',
|
|
38
49
|
descriptionKey: 'configs.systemStatus.categories.cachingDescription',
|
|
@@ -113,6 +124,42 @@ export const SYSTEM_STATUS_VARIABLES: SystemStatusVariableDefinition[] = [
|
|
|
113
124
|
docUrl: `${SYSTEM_STATUS_DOC_BASE}#log_level`,
|
|
114
125
|
defaultValue: '',
|
|
115
126
|
},
|
|
127
|
+
{
|
|
128
|
+
key: 'OM_PASSWORD_MIN_LENGTH',
|
|
129
|
+
category: 'security',
|
|
130
|
+
kind: 'string',
|
|
131
|
+
labelKey: 'configs.systemStatus.variables.passwordMinLength.label',
|
|
132
|
+
descriptionKey: 'configs.systemStatus.variables.passwordMinLength.description',
|
|
133
|
+
docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_min_length`,
|
|
134
|
+
defaultValue: '6',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
key: 'OM_PASSWORD_REQUIRE_DIGIT',
|
|
138
|
+
category: 'security',
|
|
139
|
+
kind: 'boolean',
|
|
140
|
+
labelKey: 'configs.systemStatus.variables.passwordRequireDigit.label',
|
|
141
|
+
descriptionKey: 'configs.systemStatus.variables.passwordRequireDigit.description',
|
|
142
|
+
docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_digit`,
|
|
143
|
+
defaultValue: 'true',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
key: 'OM_PASSWORD_REQUIRE_UPPERCASE',
|
|
147
|
+
category: 'security',
|
|
148
|
+
kind: 'boolean',
|
|
149
|
+
labelKey: 'configs.systemStatus.variables.passwordRequireUppercase.label',
|
|
150
|
+
descriptionKey: 'configs.systemStatus.variables.passwordRequireUppercase.description',
|
|
151
|
+
docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_uppercase`,
|
|
152
|
+
defaultValue: 'true',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
key: 'OM_PASSWORD_REQUIRE_SPECIAL',
|
|
156
|
+
category: 'security',
|
|
157
|
+
kind: 'boolean',
|
|
158
|
+
labelKey: 'configs.systemStatus.variables.passwordRequireSpecial.label',
|
|
159
|
+
descriptionKey: 'configs.systemStatus.variables.passwordRequireSpecial.description',
|
|
160
|
+
docUrl: `${SYSTEM_STATUS_DOC_BASE}#om_password_require_special`,
|
|
161
|
+
defaultValue: 'true',
|
|
162
|
+
},
|
|
116
163
|
{
|
|
117
164
|
key: 'ENABLE_CRUD_API_CACHE',
|
|
118
165
|
category: 'caching',
|
|
@@ -11,6 +11,7 @@ import { seedExampleWorkflows } from '@open-mercato/core/modules/workflows/lib/s
|
|
|
11
11
|
import { seedPlannerAvailabilityRuleSetDefaults, seedPlannerUnavailabilityReasons } from '@open-mercato/core/modules/planner/lib/seeds'
|
|
12
12
|
import { seedResourcesAddressTypes, seedResourcesCapacityUnits, seedResourcesResourceExamples } from '@open-mercato/core/modules/resources/lib/seeds'
|
|
13
13
|
import { seedStaffTeamExamples } from '@open-mercato/core/modules/staff/lib/seeds'
|
|
14
|
+
import { appendWidgetsToRoles, resolveAnalyticsWidgetIds } from '@open-mercato/core/modules/dashboards/lib/role-widgets'
|
|
14
15
|
import { collectCrudCacheStats, purgeCrudCacheSegment } from '@open-mercato/shared/lib/crud/cache-stats'
|
|
15
16
|
import { isCrudCacheEnabled, resolveCrudCache } from '@open-mercato/shared/lib/crud/cache'
|
|
16
17
|
import * as semver from 'semver'
|
|
@@ -370,6 +371,23 @@ export const upgradeActions: UpgradeActionDefinition[] = [
|
|
|
370
371
|
await reindexModules(em, ['planner', 'staff', 'resources'], { tenantId, organizationId, vectorService })
|
|
371
372
|
},
|
|
372
373
|
},
|
|
374
|
+
{
|
|
375
|
+
id: 'configs.upgrades.dashboards.analytics_widgets',
|
|
376
|
+
version: '0.4.2',
|
|
377
|
+
messageKey: 'upgrades.v042.message',
|
|
378
|
+
ctaKey: 'upgrades.v042.cta',
|
|
379
|
+
successKey: 'upgrades.v042.success',
|
|
380
|
+
loadingKey: 'upgrades.v042.loading',
|
|
381
|
+
async run({ em, tenantId, organizationId }) {
|
|
382
|
+
const widgetIds = await resolveAnalyticsWidgetIds()
|
|
383
|
+
await appendWidgetsToRoles(em, {
|
|
384
|
+
tenantId,
|
|
385
|
+
organizationId,
|
|
386
|
+
roleNames: ['admin', 'employee'],
|
|
387
|
+
widgetIds,
|
|
388
|
+
})
|
|
389
|
+
},
|
|
390
|
+
},
|
|
373
391
|
]
|
|
374
392
|
|
|
375
393
|
export function actionsUpToVersion(version: string): UpgradeActionDefinition[] {
|
|
@@ -256,12 +256,14 @@ export default function CurrenciesPage() {
|
|
|
256
256
|
<RowActions
|
|
257
257
|
items={[
|
|
258
258
|
{
|
|
259
|
+
id: 'edit',
|
|
259
260
|
label: t('common.edit'),
|
|
260
261
|
href: `/backend/currencies/${row.id}`,
|
|
261
262
|
},
|
|
262
263
|
...(!row.isBase
|
|
263
264
|
? [
|
|
264
265
|
{
|
|
266
|
+
id: 'set-base',
|
|
265
267
|
label: t('currencies.list.actions.setBase'),
|
|
266
268
|
onSelect: () => handleSetBase(row),
|
|
267
269
|
},
|
|
@@ -270,6 +272,7 @@ export default function CurrenciesPage() {
|
|
|
270
272
|
...(!row.isBase
|
|
271
273
|
? [
|
|
272
274
|
{
|
|
275
|
+
id: 'delete',
|
|
273
276
|
label: t('common.delete'),
|
|
274
277
|
destructive: true,
|
|
275
278
|
onSelect: () => handleDelete(row),
|
|
@@ -279,10 +279,12 @@ export default function ExchangeRatesPage() {
|
|
|
279
279
|
<RowActions
|
|
280
280
|
items={[
|
|
281
281
|
{
|
|
282
|
+
id: 'edit',
|
|
282
283
|
label: t('common.edit'),
|
|
283
284
|
href: `/backend/exchange-rates/${row.id}`,
|
|
284
285
|
},
|
|
285
286
|
{
|
|
287
|
+
id: 'delete',
|
|
286
288
|
label: t('common.delete'),
|
|
287
289
|
destructive: true,
|
|
288
290
|
onSelect: () => handleDelete(row),
|
|
@@ -597,14 +597,17 @@ export default function CustomersCompaniesPage() {
|
|
|
597
597
|
<RowActions
|
|
598
598
|
items={[
|
|
599
599
|
{
|
|
600
|
+
id: 'view',
|
|
600
601
|
label: t('customers.companies.list.actions.view'),
|
|
601
602
|
onSelect: () => { router.push(`/backend/customers/companies/${row.id}`) },
|
|
602
603
|
},
|
|
603
604
|
{
|
|
605
|
+
id: 'open-new-tab',
|
|
604
606
|
label: t('customers.companies.list.actions.openInNewTab'),
|
|
605
607
|
onSelect: () => window.open(`/backend/customers/companies/${row.id}`, '_blank', 'noopener'),
|
|
606
608
|
},
|
|
607
609
|
{
|
|
610
|
+
id: 'delete',
|
|
608
611
|
label: t('customers.companies.list.actions.delete'),
|
|
609
612
|
destructive: true,
|
|
610
613
|
onSelect: () => handleDelete(row),
|
|
@@ -889,10 +889,12 @@ export default function CustomersDealsPage() {
|
|
|
889
889
|
<RowActions
|
|
890
890
|
items={[
|
|
891
891
|
{
|
|
892
|
+
id: 'edit',
|
|
892
893
|
label: t('customers.deals.list.actions.edit', 'Edit'),
|
|
893
894
|
onSelect: () => { router.push(`/backend/customers/deals/${row.id}`) },
|
|
894
895
|
},
|
|
895
896
|
{
|
|
897
|
+
id: 'open-new-tab',
|
|
896
898
|
label: t('customers.deals.list.actions.openInNewTab', 'Open in new tab'),
|
|
897
899
|
onSelect: () => {
|
|
898
900
|
if (typeof window !== 'undefined') {
|
|
@@ -901,6 +903,7 @@ export default function CustomersDealsPage() {
|
|
|
901
903
|
},
|
|
902
904
|
},
|
|
903
905
|
{
|
|
906
|
+
id: 'delete',
|
|
904
907
|
label: isDeleting
|
|
905
908
|
? t('customers.deals.list.actions.deleting', 'Deleting…')
|
|
906
909
|
: t('customers.deals.list.actions.delete', 'Delete'),
|
|
@@ -614,14 +614,17 @@ export default function CustomersPeoplePage() {
|
|
|
614
614
|
<RowActions
|
|
615
615
|
items={[
|
|
616
616
|
{
|
|
617
|
+
id: 'view',
|
|
617
618
|
label: t('customers.people.list.actions.view'),
|
|
618
619
|
onSelect: () => { router.push(`/backend/customers/people/${row.id}`) },
|
|
619
620
|
},
|
|
620
621
|
{
|
|
622
|
+
id: 'open-new-tab',
|
|
621
623
|
label: t('customers.people.list.actions.openInNewTab'),
|
|
622
624
|
onSelect: () => window.open(`/backend/customers/people/${row.id}`, '_blank', 'noopener'),
|
|
623
625
|
},
|
|
624
626
|
{
|
|
627
|
+
id: 'delete',
|
|
625
628
|
label: t('customers.people.list.actions.delete'),
|
|
626
629
|
destructive: true,
|
|
627
630
|
onSelect: () => handleDelete(row),
|
|
@@ -35,6 +35,9 @@ import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
|
35
35
|
import type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'
|
|
36
36
|
import { E } from '#generated/entities.ids.generated'
|
|
37
37
|
import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
38
|
+
import { resolveNotificationService } from '../../notifications/lib/notificationService'
|
|
39
|
+
import { buildNotificationFromType } from '../../notifications/lib/notificationBuilder'
|
|
40
|
+
import { notificationTypes } from '../notifications'
|
|
38
41
|
|
|
39
42
|
const DEAL_ENTITY_ID = 'customers:customer_deal'
|
|
40
43
|
const dealCrudIndexer: CrudIndexerConfig<CustomerDeal> = {
|
|
@@ -281,6 +284,8 @@ const updateDealCommand: CommandHandler<DealUpdateInput, { dealId: string }> = {
|
|
|
281
284
|
ensureTenantScope(ctx, record.tenantId)
|
|
282
285
|
ensureOrganizationScope(ctx, record.organizationId)
|
|
283
286
|
|
|
287
|
+
const previousStatus = record.status
|
|
288
|
+
|
|
284
289
|
if (parsed.title !== undefined) record.title = parsed.title
|
|
285
290
|
if (parsed.description !== undefined) record.description = parsed.description ?? null
|
|
286
291
|
if (parsed.status !== undefined) record.status = parsed.status ?? record.status
|
|
@@ -319,6 +324,40 @@ const updateDealCommand: CommandHandler<DealUpdateInput, { dealId: string }> = {
|
|
|
319
324
|
indexer: dealCrudIndexer,
|
|
320
325
|
})
|
|
321
326
|
|
|
327
|
+
// Send notifications for deal won/lost status changes
|
|
328
|
+
const newStatus = record.status
|
|
329
|
+
const normalizedStatus = newStatus === 'win' ? 'won' : newStatus === 'loose' ? 'lost' : newStatus
|
|
330
|
+
if (previousStatus !== newStatus && (normalizedStatus === 'won' || normalizedStatus === 'lost') && record.ownerUserId) {
|
|
331
|
+
try {
|
|
332
|
+
const notificationService = resolveNotificationService(ctx.container)
|
|
333
|
+
const notificationType = normalizedStatus === 'won' ? 'customers.deal.won' : 'customers.deal.lost'
|
|
334
|
+
const typeDef = notificationTypes.find((type) => type.type === notificationType)
|
|
335
|
+
if (typeDef) {
|
|
336
|
+
const valueDisplay = record.valueAmount && record.valueCurrency
|
|
337
|
+
? `${record.valueCurrency} ${record.valueAmount}`
|
|
338
|
+
: ''
|
|
339
|
+
|
|
340
|
+
const notificationInput = buildNotificationFromType(typeDef, {
|
|
341
|
+
recipientUserId: record.ownerUserId,
|
|
342
|
+
bodyVariables: {
|
|
343
|
+
dealTitle: record.title,
|
|
344
|
+
dealValue: valueDisplay,
|
|
345
|
+
},
|
|
346
|
+
sourceEntityType: 'customers:customer_deal',
|
|
347
|
+
sourceEntityId: record.id,
|
|
348
|
+
linkHref: `/backend/customers/deals/${record.id}`,
|
|
349
|
+
})
|
|
350
|
+
|
|
351
|
+
await notificationService.create(notificationInput, {
|
|
352
|
+
tenantId: record.tenantId,
|
|
353
|
+
organizationId: record.organizationId,
|
|
354
|
+
})
|
|
355
|
+
}
|
|
356
|
+
} catch {
|
|
357
|
+
// Notification creation is non-critical, don't fail the command
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
322
361
|
return { dealId: record.id }
|
|
323
362
|
},
|
|
324
363
|
buildLog: async ({ snapshots, ctx }) => {
|
|
@@ -943,5 +943,9 @@
|
|
|
943
943
|
"customers.workPlan.customerTodos.table.state.empty": "No customer tasks yet.",
|
|
944
944
|
"customers.workPlan.customerTodos.table.error.load": "Failed to load customer tasks.",
|
|
945
945
|
"customers.workPlan.customerTodos.table.export.view": "Exports the current list with filters and visible columns.",
|
|
946
|
-
"customers.workPlan.customerTodos.table.export.full": "Exports every linked task field, including hidden attributes."
|
|
946
|
+
"customers.workPlan.customerTodos.table.export.full": "Exports every linked task field, including hidden attributes.",
|
|
947
|
+
"customers.notifications.deal.won.title": "Deal Won",
|
|
948
|
+
"customers.notifications.deal.won.body": "{dealTitle} has been marked as won{dealValue, select, other { ({dealValue})}}",
|
|
949
|
+
"customers.notifications.deal.lost.title": "Deal Lost",
|
|
950
|
+
"customers.notifications.deal.lost.body": "{dealTitle} has been marked as lost"
|
|
947
951
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
|
|
2
|
+
|
|
3
|
+
export const notificationTypes: NotificationTypeDefinition[] = [
|
|
4
|
+
{
|
|
5
|
+
type: 'customers.deal.won',
|
|
6
|
+
module: 'customers',
|
|
7
|
+
titleKey: 'customers.notifications.deal.won.title',
|
|
8
|
+
bodyKey: 'customers.notifications.deal.won.body',
|
|
9
|
+
icon: 'trophy',
|
|
10
|
+
severity: 'success',
|
|
11
|
+
actions: [
|
|
12
|
+
{
|
|
13
|
+
id: 'view',
|
|
14
|
+
labelKey: 'common.view',
|
|
15
|
+
variant: 'outline',
|
|
16
|
+
href: '/backend/customers/deals/{sourceEntityId}',
|
|
17
|
+
icon: 'external-link',
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
linkHref: '/backend/customers/deals/{sourceEntityId}',
|
|
21
|
+
expiresAfterHours: 168, // 7 days
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'customers.deal.lost',
|
|
25
|
+
module: 'customers',
|
|
26
|
+
titleKey: 'customers.notifications.deal.lost.title',
|
|
27
|
+
bodyKey: 'customers.notifications.deal.lost.body',
|
|
28
|
+
icon: 'x-circle',
|
|
29
|
+
severity: 'warning',
|
|
30
|
+
actions: [
|
|
31
|
+
{
|
|
32
|
+
id: 'view',
|
|
33
|
+
labelKey: 'common.view',
|
|
34
|
+
variant: 'outline',
|
|
35
|
+
href: '/backend/customers/deals/{sourceEntityId}',
|
|
36
|
+
icon: 'external-link',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
linkHref: '/backend/customers/deals/{sourceEntityId}',
|
|
40
|
+
expiresAfterHours: 168, // 7 days
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
export default notificationTypes
|
|
@@ -4,6 +4,7 @@ import type { EntityManager } from '@mikro-orm/postgresql'
|
|
|
4
4
|
import { DashboardRoleWidgets } from '@open-mercato/core/modules/dashboards/data/entities'
|
|
5
5
|
import { Role } from '@open-mercato/core/modules/auth/data/entities'
|
|
6
6
|
import { loadAllWidgets } from '@open-mercato/core/modules/dashboards/lib/widgets'
|
|
7
|
+
import { appendWidgetsToRoles, resolveAnalyticsWidgetIds } from '@open-mercato/core/modules/dashboards/lib/role-widgets'
|
|
7
8
|
import { seedAnalyticsData } from './seed/analytics'
|
|
8
9
|
|
|
9
10
|
type Args = Record<string, string>
|
|
@@ -41,15 +42,25 @@ export async function seedDashboardDefaultsForTenant(
|
|
|
41
42
|
const widgetMap = new Map(widgets.map((widget) => [widget.metadata.id, widget]))
|
|
42
43
|
const resolvedWidgetIds = widgetIds && widgetIds.length
|
|
43
44
|
? widgetIds.filter((id) => widgetMap.has(id))
|
|
44
|
-
:
|
|
45
|
+
: null
|
|
46
|
+
const defaultWidgetIds = widgets
|
|
47
|
+
.filter((widget) => widget.metadata.defaultEnabled)
|
|
48
|
+
.map((widget) => widget.metadata.id)
|
|
49
|
+
const allWidgetIds = widgets.map((widget) => widget.metadata.id)
|
|
45
50
|
|
|
46
|
-
if (
|
|
51
|
+
if (resolvedWidgetIds && resolvedWidgetIds.length === 0) {
|
|
47
52
|
log('No widgets resolved for dashboard seeding.')
|
|
48
53
|
return false
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
await em.transactional(async (tem) => {
|
|
52
57
|
for (const roleName of roleNames) {
|
|
58
|
+
const isAdminRole = roleName === 'admin' || roleName === 'superadmin'
|
|
59
|
+
const roleWidgetIds = resolvedWidgetIds ?? (isAdminRole ? allWidgetIds : defaultWidgetIds)
|
|
60
|
+
if (!roleWidgetIds.length) {
|
|
61
|
+
log(`No widgets resolved for role "${roleName}".`)
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
53
64
|
const role = await tem.findOne(Role, { name: roleName })
|
|
54
65
|
if (!role) {
|
|
55
66
|
log(`Skipping role "${roleName}" (not found)`)
|
|
@@ -62,7 +73,7 @@ export async function seedDashboardDefaultsForTenant(
|
|
|
62
73
|
deletedAt: null,
|
|
63
74
|
})
|
|
64
75
|
if (existing) {
|
|
65
|
-
existing.widgetIdsJson =
|
|
76
|
+
existing.widgetIdsJson = roleWidgetIds
|
|
66
77
|
tem.persist(existing)
|
|
67
78
|
log(`Updated dashboard widgets for role "${roleName}"`)
|
|
68
79
|
} else {
|
|
@@ -70,7 +81,7 @@ export async function seedDashboardDefaultsForTenant(
|
|
|
70
81
|
roleId: String(role.id),
|
|
71
82
|
tenantId,
|
|
72
83
|
organizationId,
|
|
73
|
-
widgetIdsJson:
|
|
84
|
+
widgetIdsJson: roleWidgetIds,
|
|
74
85
|
createdAt: new Date(),
|
|
75
86
|
updatedAt: null,
|
|
76
87
|
deletedAt: null,
|
|
@@ -120,6 +131,45 @@ const seedDefaults: ModuleCli = {
|
|
|
120
131
|
},
|
|
121
132
|
}
|
|
122
133
|
|
|
134
|
+
const enableAnalyticsWidgets: ModuleCli = {
|
|
135
|
+
command: 'enable-analytics-widgets',
|
|
136
|
+
async run(rest) {
|
|
137
|
+
const args = parseArgs(rest)
|
|
138
|
+
const tenantId = args.tenant || args.tenantId || null
|
|
139
|
+
const organizationId = args.organization || args.organizationId || args.org || null
|
|
140
|
+
const roleCsv = args.roles || 'admin,employee'
|
|
141
|
+
if (!tenantId) {
|
|
142
|
+
console.error('Usage: mercato dashboards enable-analytics-widgets --tenant <tenantId> [--org <orgId>] [--roles admin,employee]')
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const roleNames = roleCsv
|
|
147
|
+
.split(',')
|
|
148
|
+
.map((name) => name.trim())
|
|
149
|
+
.filter(Boolean)
|
|
150
|
+
|
|
151
|
+
if (!roleNames.length) {
|
|
152
|
+
console.log('No roles provided, nothing to update.')
|
|
153
|
+
return
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const { resolve } = await createRequestContainer()
|
|
157
|
+
const em = resolve('em') as EntityManager
|
|
158
|
+
const widgetIds = await resolveAnalyticsWidgetIds()
|
|
159
|
+
|
|
160
|
+
const updated = await appendWidgetsToRoles(em, {
|
|
161
|
+
tenantId,
|
|
162
|
+
organizationId,
|
|
163
|
+
roleNames,
|
|
164
|
+
widgetIds,
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
if (!updated) {
|
|
168
|
+
console.log('No dashboard role widgets updated.')
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
|
|
123
173
|
const seedAnalytics: ModuleCli = {
|
|
124
174
|
command: 'seed-analytics',
|
|
125
175
|
async run(rest) {
|
|
@@ -282,4 +332,4 @@ const debugAnalytics: ModuleCli = {
|
|
|
282
332
|
},
|
|
283
333
|
}
|
|
284
334
|
|
|
285
|
-
export default [seedDefaults, seedAnalytics, debugAnalytics]
|
|
335
|
+
export default [seedDefaults, enableAnalyticsWidgets, seedAnalytics, debugAnalytics]
|