@open-mercato/core 0.7.0 → 0.7.1-develop.7103.1.41ff100d93
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/.turbo/turbo-build.log +1 -1
- package/dist/helpers/integration/api.js +13 -1
- package/dist/helpers/integration/api.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +19 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
- package/dist/modules/api_keys/api/keys/route.js +1 -1
- package/dist/modules/api_keys/api/keys/route.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +3 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/api_keys/di.js +9 -0
- package/dist/modules/api_keys/di.js.map +7 -0
- package/dist/modules/api_keys/services/principalService.js +31 -0
- package/dist/modules/api_keys/services/principalService.js.map +7 -0
- package/dist/modules/attachments/api/route.js +2 -2
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js +2 -0
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/attachments/di.js +11 -1
- package/dist/modules/attachments/di.js.map +2 -2
- package/dist/modules/attachments/index.js.map +1 -1
- package/dist/modules/attachments/lib/attachment-service.js +313 -0
- package/dist/modules/attachments/lib/attachment-service.js.map +7 -0
- package/dist/modules/attachments/lib/scoped-upload-service.js +15 -2
- package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
- package/dist/modules/attachments/lib/upload-limits.js +6 -2
- package/dist/modules/attachments/lib/upload-limits.js.map +2 -2
- package/dist/modules/audit_logs/backend/audit-logs/page.js +6 -0
- package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
- package/dist/modules/audit_logs/lib/display-helpers.js +19 -11
- package/dist/modules/audit_logs/lib/display-helpers.js.map +2 -2
- package/dist/modules/audit_logs/services/actionLogService.js +57 -12
- package/dist/modules/audit_logs/services/actionLogService.js.map +3 -3
- package/dist/modules/auth/acl.js +30 -5
- package/dist/modules/auth/acl.js.map +2 -2
- package/dist/modules/auth/api/feature-check.js +8 -2
- package/dist/modules/auth/api/feature-check.js.map +2 -2
- package/dist/modules/auth/api/login.js +4 -1
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/api/reset/validate.js +55 -0
- package/dist/modules/auth/api/reset/validate.js.map +7 -0
- package/dist/modules/auth/api/roles/acl/route.js +28 -33
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/session/refresh.js +25 -1
- package/dist/modules/auth/api/session/refresh.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +96 -51
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +13 -5
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js +5 -1
- package/dist/modules/auth/backend/roles/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +3 -1
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.meta.js +5 -1
- package/dist/modules/auth/backend/users/[id]/edit/page.meta.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +2 -1
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/commands/acl.js +254 -0
- package/dist/modules/auth/commands/acl.js.map +7 -0
- package/dist/modules/auth/components/AclEditor.js +39 -30
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/data/validators.js +5 -1
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/auth/di.js +35 -9
- package/dist/modules/auth/di.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +46 -0
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/grantChecks.js.map +2 -2
- package/dist/modules/auth/lib/userIdFilter.js +16 -0
- package/dist/modules/auth/lib/userIdFilter.js.map +7 -0
- package/dist/modules/auth/services/authService.js +16 -2
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/auth/services/principalService.js +200 -0
- package/dist/modules/auth/services/principalService.js.map +7 -0
- package/dist/modules/auth/services/rbacService.js +67 -24
- package/dist/modules/auth/services/rbacService.js.map +3 -3
- package/dist/modules/auth/services/roleOrganizationScope.js +41 -0
- package/dist/modules/auth/services/roleOrganizationScope.js.map +7 -0
- package/dist/modules/business_rules/backend/logs/page.js +3 -1
- package/dist/modules/business_rules/backend/logs/page.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +3 -1
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +3 -1
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/business_rules/lib/expression-evaluator.js +9 -9
- package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-evaluator.js +10 -9
- package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
- package/dist/modules/catalog/ai-agents.js +1 -1
- package/dist/modules/catalog/ai-agents.js.map +1 -1
- package/dist/modules/catalog/ai-tools/merchandising-pack.js +2 -2
- package/dist/modules/catalog/ai-tools/merchandising-pack.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +5 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -0
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +7 -1
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js +2 -0
- package/dist/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js +9 -1
- package/dist/modules/communication_channels/api/post/channels/[id]/test-send/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +95 -10
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +3 -0
- package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js +14 -1
- package/dist/modules/communication_channels/commands/ingest-inbound-message.js.map +2 -2
- package/dist/modules/communication_channels/di.js +7 -1
- package/dist/modules/communication_channels/di.js.map +2 -2
- package/dist/modules/communication_channels/lib/email-capabilities.js +4 -1
- package/dist/modules/communication_channels/lib/email-capabilities.js.map +2 -2
- package/dist/modules/communication_channels/lib/outbound-recipient.js +33 -0
- package/dist/modules/communication_channels/lib/outbound-recipient.js.map +7 -0
- package/dist/modules/communication_channels/lib/resolve-channel-type.js +51 -0
- package/dist/modules/communication_channels/lib/resolve-channel-type.js.map +7 -0
- package/dist/modules/communication_channels/lib/test-seed.js +41 -2
- package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
- package/dist/modules/configs/lib/system-status.js +9 -0
- package/dist/modules/configs/lib/system-status.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +3 -1
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +3 -1
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/currencies/services/rateFetchingService.js +6 -1
- package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js +9 -0
- package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +3 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +3 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
- package/dist/modules/customer_accounts/services/domainMappingService.js +10 -0
- package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
- package/dist/modules/customers/ai-tools/companies-pack.js +4 -1
- package/dist/modules/customers/ai-tools/companies-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +13 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/deals-pack.js +52 -6
- package/dist/modules/customers/ai-tools/deals-pack.js.map +2 -2
- package/dist/modules/customers/ai-tools/people-pack.js +4 -1
- package/dist/modules/customers/ai-tools/people-pack.js.map +2 -2
- package/dist/modules/customers/api/activities/route.js +48 -6
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/people/route.js +20 -64
- package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +17 -94
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js +8 -5
- package/dist/modules/customers/api/dashboard/widgets/customer-todos/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/companies/route.js +1 -1
- package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/people/route.js +1 -1
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/route.js +8 -25
- package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/stats/route.js +3 -22
- package/dist/modules/customers/api/deals/[id]/stats/route.js.map +2 -2
- package/dist/modules/customers/api/deals/aggregate/route.js +14 -9
- package/dist/modules/customers/api/deals/aggregate/route.js.map +2 -2
- package/dist/modules/customers/api/deals/map/route.js +5 -5
- package/dist/modules/customers/api/deals/map/route.js.map +2 -2
- package/dist/modules/customers/api/deals/route.js +38 -1
- package/dist/modules/customers/api/deals/route.js.map +2 -2
- package/dist/modules/customers/api/entity-roles-factory.js +4 -4
- package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +3 -1
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/tasks/route.js +27 -4
- package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +4 -3
- package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/context.js +1 -1
- package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +1 -1
- package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/route.js +11 -10
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/check-phone/route.js +51 -9
- package/dist/modules/customers/api/people/check-phone/route.js.map +2 -2
- package/dist/modules/customers/api/todos/route.js +30 -5
- package/dist/modules/customers/api/todos/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +4 -2
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +6 -1
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +5 -2
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js +4 -13
- package/dist/modules/customers/backend/customers/deals/pipeline/components/Lane.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js +85 -14
- package/dist/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js +18 -0
- package/dist/modules/customers/backend/customers/deals/pipeline/components/toneClasses.js.map +7 -0
- package/dist/modules/customers/backend/customers/people/page.js +4 -2
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js +9 -3
- package/dist/modules/customers/backend/hooks/useEmailDuplicateCheck.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +21 -34
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js.map +1 -1
- package/dist/modules/customers/commands/personCompanyLinks.js +131 -2
- package/dist/modules/customers/commands/personCompanyLinks.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/components/DealsKpiStrip.js +7 -6
- package/dist/modules/customers/components/DealsKpiStrip.js.map +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js +2 -2
- package/dist/modules/customers/components/calendar/AgendaList.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +1 -1
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
- package/dist/modules/customers/components/calendar/EventBlock.js +1 -1
- package/dist/modules/customers/components/calendar/EventBlock.js.map +2 -2
- package/dist/modules/customers/components/calendar/EventPeekPopover.js +3 -2
- package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PeopleField.js +40 -5
- package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/hooks.js +2 -1
- package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
- package/dist/modules/customers/components/calendar/types.js +1 -1
- package/dist/modules/customers/components/calendar/types.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyKpiBar.js +5 -4
- package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -1
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +19 -7
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealsSection.js +6 -5
- package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
- package/dist/modules/customers/components/detail/EntityTagsDialog.js +35 -11
- package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js +3 -1
- package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +19 -13
- package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -4
- package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +3 -3
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/components/detail/utils.js +5 -5
- package/dist/modules/customers/components/detail/utils.js.map +2 -2
- package/dist/modules/customers/data/entities.js.map +1 -1
- package/dist/modules/customers/data/validators.js +32 -3
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/events.js +5 -0
- package/dist/modules/customers/events.js.map +2 -2
- package/dist/modules/customers/lib/calendar/conflicts.js +8 -2
- package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js +3 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
- package/dist/modules/customers/lib/calendar/mapItem.js +8 -3
- package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
- package/dist/modules/customers/lib/calendar/participantIdentity.js +9 -0
- package/dist/modules/customers/lib/calendar/participantIdentity.js.map +7 -0
- package/dist/modules/customers/lib/closureStage.js +45 -0
- package/dist/modules/customers/lib/closureStage.js.map +7 -0
- package/dist/modules/customers/lib/dealStatus.js +30 -0
- package/dist/modules/customers/lib/dealStatus.js.map +2 -2
- package/dist/modules/customers/lib/detailReadAccess.js +12 -0
- package/dist/modules/customers/lib/detailReadAccess.js.map +7 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js +1 -0
- package/dist/modules/customers/lib/findPeopleByAddresses.js.map +2 -2
- package/dist/modules/customers/lib/personCompanies.js +100 -2
- package/dist/modules/customers/lib/personCompanies.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +12 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/dashboards/lib/widgetScope.js +6 -1
- package/dist/modules/dashboards/lib/widgetScope.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +3 -1
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/lib/abandoned-run.js +19 -0
- package/dist/modules/data_sync/lib/abandoned-run.js.map +7 -0
- package/dist/modules/data_sync/lib/sync-engine.js +72 -6
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-export.js +5 -1
- package/dist/modules/data_sync/workers/sync-export.js.map +2 -2
- package/dist/modules/data_sync/workers/sync-import.js +5 -1
- package/dist/modules/data_sync/workers/sync-import.js.map +2 -2
- package/dist/modules/devices/acl.js +9 -1
- package/dist/modules/devices/acl.js.map +2 -2
- package/dist/modules/devices/api/admin/devices/[id]/route.js +5 -32
- package/dist/modules/devices/api/admin/devices/[id]/route.js.map +2 -2
- package/dist/modules/devices/api/admin/devices/route.js +14 -1
- package/dist/modules/devices/api/admin/devices/route.js.map +2 -2
- package/dist/modules/devices/api/deviceList.js +99 -12
- package/dist/modules/devices/api/deviceList.js.map +2 -2
- package/dist/modules/devices/api/deviceSerialization.js +46 -0
- package/dist/modules/devices/api/deviceSerialization.js.map +7 -0
- package/dist/modules/devices/api/openapi.js +3 -1
- package/dist/modules/devices/api/openapi.js.map +2 -2
- package/dist/modules/devices/api/route.js +9 -1
- package/dist/modules/devices/api/route.js.map +2 -2
- package/dist/modules/devices/backend/devices/[id]/page.js +10 -26
- package/dist/modules/devices/backend/devices/[id]/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/create/page.js +17 -1
- package/dist/modules/devices/backend/devices/create/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/page.js +28 -34
- package/dist/modules/devices/backend/devices/page.js.map +2 -2
- package/dist/modules/devices/backend/devices/useDeviceUserLabels.js +34 -0
- package/dist/modules/devices/backend/devices/useDeviceUserLabels.js.map +7 -0
- package/dist/modules/devices/backend/devices/userOptions.js +52 -0
- package/dist/modules/devices/backend/devices/userOptions.js.map +7 -0
- package/dist/modules/devices/setup.js +6 -2
- package/dist/modules/devices/setup.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/directory/di.js +9 -0
- package/dist/modules/directory/di.js.map +2 -2
- package/dist/modules/directory/services/organizationHierarchyService.js +29 -0
- package/dist/modules/directory/services/organizationHierarchyService.js.map +7 -0
- package/dist/modules/directory/services/organizationScopeService.js +56 -0
- package/dist/modules/directory/services/organizationScopeService.js.map +7 -0
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/records.js +4 -2
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +3 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/eudr/api/plots/route.js +5 -1
- package/dist/modules/eudr/api/plots/route.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/plots/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/plots/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +2 -2
- package/dist/modules/eudr/backend/eudr/statements/page.js +3 -0
- package/dist/modules/eudr/backend/eudr/statements/page.js.map +2 -2
- package/dist/modules/eudr/commands/statements.js +0 -3
- package/dist/modules/eudr/commands/statements.js.map +2 -2
- package/dist/modules/eudr/data/validators.js +4 -1
- package/dist/modules/eudr/data/validators.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +1 -0
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/OverridesTable.js +1 -0
- package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
- package/dist/modules/feature_toggles/defaults.json +0 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js +3 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/log/page.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js +3 -0
- package/dist/modules/inbox_ops/backend/inbox-ops/page.js.map +2 -2
- package/dist/modules/inbox_ops/lib/htmlToPlainText.js +1 -12
- package/dist/modules/inbox_ops/lib/htmlToPlainText.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +6 -1
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +38 -29
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +36 -9
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/credential-secret-fields.js +55 -0
- package/dist/modules/integrations/backend/integrations/credential-secret-fields.js.map +7 -0
- package/dist/modules/integrations/data/validators.js +11 -3
- package/dist/modules/integrations/data/validators.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-masking.js +6 -2
- package/dist/modules/integrations/lib/credentials-masking.js.map +2 -2
- package/dist/modules/messages/api/[id]/route.js +29 -1
- package/dist/modules/messages/api/[id]/route.js.map +2 -2
- package/dist/modules/messages/api/openapi.js +17 -2
- package/dist/modules/messages/api/openapi.js.map +2 -2
- package/dist/modules/messages/api/route.js +17 -2
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +7 -14
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/inboxFilters.js +15 -0
- package/dist/modules/messages/components/inboxFilters.js.map +2 -2
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js +11 -1
- package/dist/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js +3 -1
- package/dist/modules/messages/components/message-detail/panels/MessageHeader.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +2 -1
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
- package/dist/modules/messages/components/messageListLabels.js +14 -2
- package/dist/modules/messages/components/messageListLabels.js.map +2 -2
- package/dist/modules/messages/data/validators.js +18 -4
- package/dist/modules/messages/data/validators.js.map +2 -2
- package/dist/modules/messages/lib/channel-sender-identity.js +26 -0
- package/dist/modules/messages/lib/channel-sender-identity.js.map +7 -0
- package/dist/modules/messages/lib/composeSourceChannelType.js +41 -0
- package/dist/modules/messages/lib/composeSourceChannelType.js.map +7 -0
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +4 -6
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -1
- package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
- package/dist/modules/payment_gateways/lib/webhook-processor.js +7 -0
- package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +3 -0
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/page.js +3 -1
- package/dist/modules/push_notifications/backend/push_notifications/page.js.map +2 -2
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js +1 -1
- package/dist/modules/push_notifications/backend/push_notifications/send/page.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +150 -51
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/search-entity-policy.js +14 -0
- package/dist/modules/query_index/lib/search-entity-policy.js.map +7 -0
- package/dist/modules/query_index/lib/search-tokens.js +79 -3
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +3 -1
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +3 -1
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +3 -0
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +3 -0
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +10 -8
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +79 -1
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/components/PriceWithCurrency.js +7 -5
- package/dist/modules/sales/components/PriceWithCurrency.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +3 -0
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +8 -6
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +51 -22
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +83 -18
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +23 -9
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ReturnsSection.js +8 -6
- package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +68 -14
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js +6 -5
- package/dist/modules/sales/components/documents/SalesOrderDraftLines.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +5 -4
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentsSection.js +8 -6
- package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/lineItemShipmentLock.js +54 -0
- package/dist/modules/sales/components/documents/lineItemShipmentLock.js.map +7 -0
- package/dist/modules/sales/components/documents/lineItemUtils.js +2 -2
- package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
- package/dist/modules/sales/data/entities.js +8 -2
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/sales/extension-points.js +1 -0
- package/dist/modules/sales/extension-points.js.map +2 -2
- package/dist/modules/sales/lib/salesChannelsToggleSeed.js +33 -0
- package/dist/modules/sales/lib/salesChannelsToggleSeed.js.map +7 -0
- package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js +32 -0
- package/dist/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.js.map +7 -0
- package/dist/modules/sales/setup.js +2 -0
- package/dist/modules/sales/setup.js.map +2 -2
- package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js +10 -2
- package/dist/modules/sales/widgets/injection/payment-gateway-status-column/widget.js.map +2 -2
- package/dist/modules/sales/widgets/injection-table.js +4 -7
- package/dist/modules/sales/widgets/injection-table.js.map +2 -2
- package/dist/modules/staff/backend/staff/leave-requests/page.js +3 -0
- package/dist/modules/staff/backend/staff/leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js +3 -0
- package/dist/modules/staff/backend/staff/my-leave-requests/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/page.js +3 -0
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +3 -0
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +3 -0
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +3 -0
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/page.js +29 -18
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +3 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
- package/dist/modules/sync_excel/lib/adapters/customers.js +1 -0
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
- package/dist/modules/warranty_claims/api/assignees/route.js +3 -3
- package/dist/modules/warranty_claims/api/assignees/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/route.js +12 -9
- package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
- package/dist/modules/warranty_claims/backend/page.js +3 -0
- package/dist/modules/warranty_claims/backend/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/registrations/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js +3 -0
- package/dist/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.js.map +2 -2
- package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -0
- package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
- package/dist/modules/wms/api/warehouseSearch.js +21 -0
- package/dist/modules/wms/api/warehouseSearch.js.map +7 -0
- package/dist/modules/wms/api/warehouses/route.js +13 -9
- package/dist/modules/wms/api/warehouses/route.js.map +2 -2
- package/dist/modules/wms/api/zones/route.js +15 -2
- package/dist/modules/wms/api/zones/route.js.map +2 -2
- package/dist/modules/wms/commands/configuration.js +121 -9
- package/dist/modules/wms/commands/configuration.js.map +2 -2
- package/dist/modules/wms/commands/inventory-actions.js +3 -0
- package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
- package/dist/modules/wms/commands/shared.js +9 -1
- package/dist/modules/wms/commands/shared.js.map +2 -2
- package/dist/modules/wms/components/backend/WarehouseEditDialog.js +158 -0
- package/dist/modules/wms/components/backend/WarehouseEditDialog.js.map +7 -0
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js +76 -111
- package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +3 -3
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +1 -0
- package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotsListPage.js +1 -0
- package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js +27 -20
- package/dist/modules/wms/components/backend/inventoryMutationLoaders.js.map +2 -2
- package/dist/modules/wms/components/backend/warehouseFormOptions.js +66 -0
- package/dist/modules/wms/components/backend/warehouseFormOptions.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/page.js +3 -1
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/page.js +3 -1
- package/dist/modules/workflows/backend/events/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +3 -1
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +3 -1
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +4 -0
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/package.json +9 -10
- package/src/helpers/integration/api.ts +33 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +69 -1
- package/src/modules/api_keys/api/keys/route.ts +3 -1
- package/src/modules/api_keys/backend/api-keys/page.tsx +4 -1
- package/src/modules/api_keys/di.ts +7 -0
- package/src/modules/api_keys/services/principalService.ts +33 -0
- package/src/modules/attachments/AGENTS.md +15 -0
- package/src/modules/attachments/api/route.ts +2 -2
- package/src/modules/attachments/components/AttachmentLibrary.tsx +3 -0
- package/src/modules/attachments/di.ts +16 -0
- package/src/modules/attachments/i18n/de.json +5 -0
- package/src/modules/attachments/i18n/en.json +5 -0
- package/src/modules/attachments/i18n/es.json +5 -0
- package/src/modules/attachments/i18n/ko.json +5 -0
- package/src/modules/attachments/i18n/pl.json +5 -0
- package/src/modules/attachments/index.ts +10 -0
- package/src/modules/attachments/lib/attachment-service.ts +468 -0
- package/src/modules/attachments/lib/scoped-upload-service.ts +46 -0
- package/src/modules/attachments/lib/upload-limits.ts +6 -2
- package/src/modules/audit_logs/backend/audit-logs/page.tsx +8 -0
- package/src/modules/audit_logs/lib/display-helpers.tsx +42 -32
- package/src/modules/audit_logs/services/actionLogService.ts +74 -11
- package/src/modules/auth/acl.ts +30 -6
- package/src/modules/auth/api/feature-check.ts +10 -3
- package/src/modules/auth/api/login.ts +9 -1
- package/src/modules/auth/api/reset/validate.ts +57 -0
- package/src/modules/auth/api/roles/acl/route.ts +42 -39
- package/src/modules/auth/api/session/refresh.ts +32 -1
- package/src/modules/auth/api/users/acl/route.ts +177 -53
- package/src/modules/auth/api/users/route.ts +18 -5
- package/src/modules/auth/backend/roles/[id]/edit/page.meta.ts +5 -2
- package/src/modules/auth/backend/roles/page.tsx +4 -2
- package/src/modules/auth/backend/users/[id]/edit/page.meta.ts +5 -2
- package/src/modules/auth/backend/users/page.tsx +3 -2
- package/src/modules/auth/commands/acl.ts +495 -0
- package/src/modules/auth/components/AclEditor.tsx +63 -33
- package/src/modules/auth/data/entities.ts +4 -1
- package/src/modules/auth/data/validators.ts +5 -0
- package/src/modules/auth/di.ts +46 -16
- package/src/modules/auth/frontend/reset/[token]/page.tsx +74 -0
- package/src/modules/auth/i18n/de.json +389 -0
- package/src/modules/auth/i18n/en.json +389 -0
- package/src/modules/auth/i18n/es.json +389 -0
- package/src/modules/auth/i18n/ko.json +389 -0
- package/src/modules/auth/i18n/pl.json +391 -2
- package/src/modules/auth/lib/grantChecks.ts +6 -0
- package/src/modules/auth/lib/userIdFilter.ts +31 -0
- package/src/modules/auth/services/authService.ts +18 -2
- package/src/modules/auth/services/principalService.ts +266 -0
- package/src/modules/auth/services/rbacService.ts +110 -24
- package/src/modules/auth/services/roleOrganizationScope.ts +70 -0
- package/src/modules/business_rules/backend/logs/page.tsx +4 -1
- package/src/modules/business_rules/backend/rules/page.tsx +4 -1
- package/src/modules/business_rules/backend/sets/page.tsx +4 -1
- package/src/modules/business_rules/lib/expression-evaluator.ts +9 -9
- package/src/modules/business_rules/lib/rule-evaluator.ts +10 -9
- package/src/modules/catalog/ai-agents.ts +1 -1
- package/src/modules/catalog/ai-tools/merchandising-pack.ts +2 -2
- package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +12 -5
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +3 -0
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +7 -0
- package/src/modules/catalog/i18n/de.json +1 -0
- package/src/modules/catalog/i18n/en.json +1 -0
- package/src/modules/catalog/i18n/es.json +1 -0
- package/src/modules/catalog/i18n/ko.json +1 -0
- package/src/modules/catalog/i18n/pl.json +1 -0
- package/src/modules/catalog/widgets/injection/merchandising-assistant-trigger/widget.client.tsx +4 -0
- package/src/modules/communication_channels/api/post/channels/[id]/test-send/route.ts +17 -1
- package/src/modules/communication_channels/api/post/test-seed/route.ts +155 -16
- package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +4 -0
- package/src/modules/communication_channels/commands/ingest-inbound-message.ts +38 -1
- package/src/modules/communication_channels/di.ts +7 -0
- package/src/modules/communication_channels/lib/adapter.ts +14 -0
- package/src/modules/communication_channels/lib/email-capabilities.ts +4 -0
- package/src/modules/communication_channels/lib/outbound-recipient.ts +71 -0
- package/src/modules/communication_channels/lib/resolve-channel-type.ts +99 -0
- package/src/modules/communication_channels/lib/test-seed.ts +64 -4
- package/src/modules/configs/i18n/de.json +2 -0
- package/src/modules/configs/i18n/en.json +2 -0
- package/src/modules/configs/i18n/es.json +2 -0
- package/src/modules/configs/i18n/ko.json +2 -0
- package/src/modules/configs/i18n/pl.json +2 -0
- package/src/modules/configs/lib/system-status.ts +9 -0
- package/src/modules/currencies/AGENTS.md +3 -0
- package/src/modules/currencies/backend/currencies/page.tsx +4 -1
- package/src/modules/currencies/backend/exchange-rates/page.tsx +4 -1
- package/src/modules/currencies/services/README.md +45 -0
- package/src/modules/currencies/services/rateFetchingService.ts +6 -1
- package/src/modules/customer_accounts/api/admin/domain-mappings.ts +7 -0
- package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +4 -1
- package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +4 -1
- package/src/modules/customer_accounts/services/domainMappingService.ts +10 -0
- package/src/modules/customers/ai-tools/companies-pack.ts +4 -1
- package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +17 -2
- package/src/modules/customers/ai-tools/deals-pack.ts +66 -1
- package/src/modules/customers/ai-tools/people-pack.ts +4 -1
- package/src/modules/customers/api/activities/route.ts +45 -0
- package/src/modules/customers/api/companies/[id]/people/route.ts +24 -73
- package/src/modules/customers/api/companies/[id]/route.ts +24 -107
- package/src/modules/customers/api/dashboard/widgets/customer-todos/route.ts +16 -8
- package/src/modules/customers/api/deals/[id]/companies/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/people/route.ts +4 -1
- package/src/modules/customers/api/deals/[id]/route.ts +17 -28
- package/src/modules/customers/api/deals/[id]/stats/route.ts +10 -25
- package/src/modules/customers/api/deals/aggregate/route.ts +17 -9
- package/src/modules/customers/api/deals/map/route.ts +4 -4
- package/src/modules/customers/api/deals/route.ts +50 -1
- package/src/modules/customers/api/entity-roles-factory.ts +8 -4
- package/src/modules/customers/api/interactions/route.ts +8 -2
- package/src/modules/customers/api/interactions/tasks/route.ts +24 -1
- package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +12 -4
- package/src/modules/customers/api/people/[id]/companies/context.ts +4 -1
- package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +4 -1
- package/src/modules/customers/api/people/[id]/route.ts +16 -11
- package/src/modules/customers/api/people/check-phone/route.ts +75 -10
- package/src/modules/customers/api/todos/route.ts +27 -2
- package/src/modules/customers/backend/customers/companies/page.tsx +5 -2
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +7 -2
- package/src/modules/customers/backend/customers/deals/page.tsx +8 -2
- package/src/modules/customers/backend/customers/deals/pipeline/components/Lane.tsx +5 -14
- package/src/modules/customers/backend/customers/deals/pipeline/components/StatusFilterPopover.tsx +109 -27
- package/src/modules/customers/backend/customers/deals/pipeline/components/toneClasses.ts +21 -0
- package/src/modules/customers/backend/customers/people/page.tsx +5 -2
- package/src/modules/customers/backend/hooks/useEmailDuplicateCheck.ts +12 -4
- package/src/modules/customers/commands/deals.ts +34 -59
- package/src/modules/customers/commands/interactions.ts +1 -1
- package/src/modules/customers/commands/personCompanyLinks.ts +224 -8
- package/src/modules/customers/components/CustomerTodosTable.tsx +2 -0
- package/src/modules/customers/components/DealsKpiStrip.tsx +7 -7
- package/src/modules/customers/components/calendar/AgendaList.tsx +3 -3
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -1
- package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
- package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +1 -1
- package/src/modules/customers/components/calendar/EventBlock.tsx +2 -2
- package/src/modules/customers/components/calendar/EventPeekPopover.tsx +4 -2
- package/src/modules/customers/components/calendar/editor/PeopleField.tsx +61 -5
- package/src/modules/customers/components/calendar/editor/hooks.ts +7 -1
- package/src/modules/customers/components/calendar/types.ts +2 -2
- package/src/modules/customers/components/detail/CompanyKpiBar.tsx +5 -4
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +8 -1
- package/src/modules/customers/components/detail/DealForm.tsx +22 -2
- package/src/modules/customers/components/detail/DealsSection.tsx +11 -5
- package/src/modules/customers/components/detail/EntityTagsDialog.tsx +58 -12
- package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +8 -1
- package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +23 -14
- package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +5 -5
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +5 -5
- package/src/modules/customers/components/detail/types.ts +1 -1
- package/src/modules/customers/components/detail/utils.ts +15 -5
- package/src/modules/customers/data/entities.ts +1 -1
- package/src/modules/customers/data/validators.ts +50 -9
- package/src/modules/customers/events.ts +5 -0
- package/src/modules/customers/i18n/de.json +9 -1
- package/src/modules/customers/i18n/en.json +9 -1
- package/src/modules/customers/i18n/es.json +9 -1
- package/src/modules/customers/i18n/ko.json +9 -1
- package/src/modules/customers/i18n/pl.json +9 -1
- package/src/modules/customers/lib/calendar/conflicts.ts +10 -2
- package/src/modules/customers/lib/calendar/editorPayload.ts +4 -3
- package/src/modules/customers/lib/calendar/mapItem.ts +8 -3
- package/src/modules/customers/lib/calendar/participantIdentity.ts +17 -0
- package/src/modules/customers/lib/closureStage.ts +76 -0
- package/src/modules/customers/lib/dealStatus.ts +42 -0
- package/src/modules/customers/lib/detailReadAccess.ts +35 -0
- package/src/modules/customers/lib/findPeopleByAddresses.ts +8 -6
- package/src/modules/customers/lib/personCompanies.ts +136 -1
- package/src/modules/customers/lib/todoCompatibility.ts +19 -1
- package/src/modules/dashboards/i18n/es.json +4 -4
- package/src/modules/dashboards/i18n/pl.json +7 -7
- package/src/modules/dashboards/lib/widgetScope.ts +6 -0
- package/src/modules/data_sync/AGENTS.md +1 -1
- package/src/modules/data_sync/backend/data-sync/page.tsx +4 -1
- package/src/modules/data_sync/lib/abandoned-run.ts +56 -0
- package/src/modules/data_sync/lib/adapter.ts +36 -0
- package/src/modules/data_sync/lib/sync-engine.ts +113 -5
- package/src/modules/data_sync/workers/sync-export.ts +4 -0
- package/src/modules/data_sync/workers/sync-import.ts +4 -0
- package/src/modules/devices/AGENTS.md +20 -1
- package/src/modules/devices/acl.ts +9 -1
- package/src/modules/devices/api/admin/devices/[id]/route.ts +5 -34
- package/src/modules/devices/api/admin/devices/route.ts +14 -1
- package/src/modules/devices/api/deviceList.ts +135 -11
- package/src/modules/devices/api/deviceSerialization.ts +50 -0
- package/src/modules/devices/api/openapi.ts +9 -1
- package/src/modules/devices/api/route.ts +9 -1
- package/src/modules/devices/backend/devices/[id]/page.tsx +18 -32
- package/src/modules/devices/backend/devices/create/page.tsx +17 -1
- package/src/modules/devices/backend/devices/page.tsx +44 -45
- package/src/modules/devices/backend/devices/useDeviceUserLabels.ts +45 -0
- package/src/modules/devices/backend/devices/userOptions.ts +99 -0
- package/src/modules/devices/i18n/de.json +3 -2
- package/src/modules/devices/i18n/en.json +3 -2
- package/src/modules/devices/i18n/es.json +3 -2
- package/src/modules/devices/i18n/ko.json +3 -2
- package/src/modules/devices/i18n/pl.json +3 -2
- package/src/modules/devices/setup.ts +6 -2
- package/src/modules/directory/backend/directory/organizations/page.tsx +3 -1
- package/src/modules/directory/backend/directory/tenants/page.tsx +3 -1
- package/src/modules/directory/di.ts +14 -2
- package/src/modules/directory/services/organizationHierarchyService.ts +34 -0
- package/src/modules/directory/services/organizationScopeService.ts +85 -0
- package/src/modules/directory/utils/organizationScope.ts +4 -15
- package/src/modules/entities/api/records.ts +2 -0
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +4 -1
- package/src/modules/eudr/api/plots/route.ts +4 -0
- package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/plots/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +4 -0
- package/src/modules/eudr/backend/eudr/statements/page.tsx +4 -0
- package/src/modules/eudr/commands/statements.ts +0 -3
- package/src/modules/eudr/data/validators.ts +16 -1
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +2 -1
- package/src/modules/feature_toggles/components/OverridesTable.tsx +2 -1
- package/src/modules/feature_toggles/defaults.json +0 -8
- package/src/modules/inbox_ops/backend/inbox-ops/log/page.tsx +4 -0
- package/src/modules/inbox_ops/backend/inbox-ops/page.tsx +4 -0
- package/src/modules/inbox_ops/lib/htmlToPlainText.ts +1 -17
- package/src/modules/integrations/api/[id]/credentials/route.ts +6 -4
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +61 -31
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +44 -9
- package/src/modules/integrations/backend/integrations/credential-secret-fields.ts +84 -0
- package/src/modules/integrations/data/validators.ts +12 -2
- package/src/modules/integrations/i18n/de.json +1 -0
- package/src/modules/integrations/i18n/en.json +1 -0
- package/src/modules/integrations/i18n/es.json +1 -0
- package/src/modules/integrations/i18n/ko.json +1 -0
- package/src/modules/integrations/i18n/pl.json +1 -0
- package/src/modules/integrations/lib/credentials-masking.ts +10 -6
- package/src/modules/messages/api/[id]/route.ts +55 -1
- package/src/modules/messages/api/openapi.ts +20 -0
- package/src/modules/messages/api/route.ts +31 -2
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +9 -16
- package/src/modules/messages/components/inboxFilters.ts +36 -0
- package/src/modules/messages/components/message-detail/hooks/useMessageDetailsConversation.ts +14 -1
- package/src/modules/messages/components/message-detail/panels/MessageHeader.tsx +3 -1
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +2 -1
- package/src/modules/messages/components/message-detail/types.ts +3 -0
- package/src/modules/messages/components/messageListLabels.ts +52 -3
- package/src/modules/messages/data/validators.ts +43 -4
- package/src/modules/messages/lib/channel-sender-identity.ts +55 -0
- package/src/modules/messages/lib/composeSourceChannelType.ts +95 -0
- package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +4 -6
- package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +4 -1
- package/src/modules/payment_gateways/lib/webhook-processor.ts +11 -0
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +4 -0
- package/src/modules/push_notifications/backend/push_notifications/page.tsx +4 -1
- package/src/modules/push_notifications/backend/push_notifications/send/page.tsx +4 -4
- package/src/modules/query_index/lib/engine.ts +249 -61
- package/src/modules/query_index/lib/search-entity-policy.ts +46 -0
- package/src/modules/query_index/lib/search-tokens.ts +135 -3
- package/src/modules/resources/backend/resources/resource-types/page.tsx +4 -1
- package/src/modules/resources/backend/resources/resources/page.tsx +4 -1
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +4 -0
- package/src/modules/sales/backend/sales/channels/page.tsx +4 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +14 -8
- package/src/modules/sales/commands/documents.ts +93 -0
- package/src/modules/sales/components/PriceWithCurrency.tsx +17 -5
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +4 -0
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +6 -5
- package/src/modules/sales/components/documents/ItemsSection.tsx +56 -18
- package/src/modules/sales/components/documents/LineItemDialog.tsx +137 -20
- package/src/modules/sales/components/documents/PaymentsSection.tsx +20 -9
- package/src/modules/sales/components/documents/ReturnsSection.tsx +6 -5
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +106 -14
- package/src/modules/sales/components/documents/SalesOrderDraftLines.tsx +6 -5
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +5 -4
- package/src/modules/sales/components/documents/ShipmentsSection.tsx +6 -5
- package/src/modules/sales/components/documents/lineItemShipmentLock.ts +74 -0
- package/src/modules/sales/components/documents/lineItemUtils.ts +7 -2
- package/src/modules/sales/data/entities.ts +6 -0
- package/src/modules/sales/extension-points.ts +1 -0
- package/src/modules/sales/i18n/de.json +8 -0
- package/src/modules/sales/i18n/en.json +8 -0
- package/src/modules/sales/i18n/es.json +8 -0
- package/src/modules/sales/i18n/ko.json +8 -0
- package/src/modules/sales/i18n/pl.json +8 -0
- package/src/modules/sales/lib/salesChannelsToggleSeed.ts +42 -0
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +60 -0
- package/src/modules/sales/migrations/Migration20260821120000_sales_notes_addresses_context_idx.ts +87 -0
- package/src/modules/sales/setup.ts +2 -0
- package/src/modules/sales/widgets/injection/payment-gateway-status-column/widget.ts +9 -1
- package/src/modules/sales/widgets/injection-table.ts +4 -7
- package/src/modules/staff/backend/staff/leave-requests/page.tsx +4 -0
- package/src/modules/staff/backend/staff/my-leave-requests/page.tsx +4 -0
- package/src/modules/staff/backend/staff/team-members/page.tsx +6 -0
- package/src/modules/staff/backend/staff/team-roles/page.tsx +4 -0
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +4 -0
- package/src/modules/staff/backend/staff/teams/page.tsx +4 -0
- package/src/modules/staff/backend/staff/timesheets/page.tsx +12 -1
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +4 -0
- package/src/modules/sync_excel/lib/adapters/customers.ts +5 -0
- package/src/modules/warranty_claims/api/assignees/route.ts +3 -3
- package/src/modules/warranty_claims/api/portal/attachments/route.ts +2 -2
- package/src/modules/warranty_claims/api/portal/claims/route.ts +12 -9
- package/src/modules/warranty_claims/backend/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/registrations/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/troubleshooting-guides/page.tsx +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/vendor-policies/page.tsx +4 -0
- package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +4 -0
- package/src/modules/wms/api/warehouseSearch.ts +23 -0
- package/src/modules/wms/api/warehouses/route.ts +13 -9
- package/src/modules/wms/api/zones/route.ts +16 -0
- package/src/modules/wms/commands/configuration.ts +159 -10
- package/src/modules/wms/commands/inventory-actions.ts +3 -0
- package/src/modules/wms/commands/shared.ts +17 -0
- package/src/modules/wms/components/backend/WarehouseEditDialog.tsx +216 -0
- package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +95 -141
- package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +2 -0
- package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -0
- package/src/modules/wms/components/backend/inventoryMutationLoaders.ts +36 -20
- package/src/modules/wms/components/backend/warehouseFormOptions.ts +72 -0
- package/src/modules/wms/i18n/de.json +2 -0
- package/src/modules/wms/i18n/en.json +2 -0
- package/src/modules/wms/i18n/es.json +2 -0
- package/src/modules/wms/i18n/ko.json +2 -0
- package/src/modules/wms/i18n/pl.json +2 -0
- package/src/modules/workflows/backend/definitions/page.tsx +4 -1
- package/src/modules/workflows/backend/events/page.tsx +4 -1
- package/src/modules/workflows/backend/instances/page.tsx +4 -1
- package/src/modules/workflows/backend/tasks/page.tsx +4 -1
- package/src/modules/workflows/lib/activity-executor.ts +9 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/wms/commands/inventory-actions.ts"],
|
|
4
|
-
"sourcesContent": ["// =============================================================================\n// WMS Inventory Mutation Commands \u2014 Undo Policy\n// =============================================================================\n//\n// All inventory-mutation commands in this file are deliberately registered\n// with `isUndoable: false` and therefore opt out of the generic command-bus\n// undo flow. WMS inventory is modeled as an append-only ledger\n// (`inventory_movements`) that drives live balances; subsequent reservations\n// and movements may be made on top of any prior state, so a per-record\n// \"undo\" cannot safely re-derive a point-in-time balance without a\n// stop-the-world replay.\n//\n// Reversal is therefore exposed as an explicit, auditable counter-action in\n// the domain model rather than as a generic undo verb:\n// - reserve \u2194 release\n// - allocate \u2194 release (cancels the allocation)\n// - adjust(+N) \u2194 adjust(-N)\n// - receive \u2194 adjust / RMA flow\n// - move(A \u2192 B) \u2194 move(B \u2192 A)\n// - cycle count \u2194 cycle count (re-recount)\n//\n// The audit log still captures the full before/after via `buildLog`, so any\n// reversing counter-action is fully traceable.\n// =============================================================================\nimport { LockMode } from '@mikro-orm/core'\nimport { randomUUID } from 'crypto'\nimport type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { emitWmsEvent } from '../events'\nimport { E } from '#generated/entities.ids.generated'\nimport type { QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport {\n InventoryBalance,\n InventoryLot,\n InventoryMovement,\n InventoryReservation,\n ProductInventoryProfile,\n Warehouse,\n WarehouseLocation,\n type InventoryStrategy,\n} from '../data/entities'\nimport {\n inventoryAdjustSchema,\n inventoryCycleCountSchema,\n inventoryMoveSchema,\n inventoryReceiveSchema,\n inventoryReservationAllocateSchema,\n inventoryReservationCreateSchema,\n inventoryReservationReleaseSchema,\n type InventoryAdjustInput,\n type InventoryCycleCountInput,\n type InventoryMoveInput,\n type InventoryReceiveInput,\n type InventoryReservationAllocateInput,\n type InventoryReservationCreateInput,\n type InventoryReservationReleaseInput,\n} from '../data/validators'\nimport {\n evaluateLowStock,\n isLotEligible,\n resolveReservationStrategyFromProfile,\n sortBucketsForStrategy,\n type InventoryStrategyBucket,\n} from '../lib/inventoryPolicy'\nimport { enforceInventoryTrackingRequirements } from '../lib/inventoryTrackingValidation'\nimport {\n buildMovementIdempotencyKey,\n buildReservationIdempotencyKey,\n} from '../lib/inventoryIdempotency'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n inventoryBalanceCrudEvents,\n inventoryBalanceCrudIndexer,\n inventoryMovementCrudEvents,\n inventoryMovementCrudIndexer,\n inventoryReservationCrudEvents,\n inventoryReservationCrudIndexer,\n requireId,\n toNumericString,\n WMS_INVENTORY_BALANCE_RESOURCE,\n WMS_INVENTORY_MOVEMENT_RESOURCE,\n WMS_INVENTORY_RESERVATION_RESOURCE,\n} from './shared'\n\ntype Scope = { tenantId: string; organizationId: string }\ntype AllocationBucket = {\n balanceId: string\n locationId: string\n lotId: string | null\n serialNumber: string | null\n quantity: number\n}\n\ntype ReservationMetadata = {\n allocatedBuckets?: AllocationBucket[]\n allocationState?: 'reserved' | 'allocated'\n strategy?: InventoryStrategy\n releasedReason?: string\n releasedAt?: string\n allocatedAt?: string\n [key: string]: unknown\n}\n\ntype ReservationCommandResult = {\n reservationId: string\n allocatedBuckets: Array<{ locationId: string; lotId: string | null; quantity: string }>\n}\n\ntype MutationLogInput = {\n actionKey: string\n fallbackLabel: string\n resourceKind: string\n resourceId: string | null\n parentResourceId?: string | null\n tenantId: string | null\n organizationId: string | null\n cacheAliases?: string[]\n}\n\ntype AffectedReservation = { entity: InventoryReservation; action: 'created' | 'updated' | 'deleted' }\ntype AffectedMovement = { entity: InventoryMovement; action: 'created' | 'updated' | 'deleted' }\ntype AffectedBalance = { entity: InventoryBalance; action: 'created' | 'updated' | 'deleted' }\n\ntype AffectedSideEffects = {\n reservations?: AffectedReservation[]\n movements?: AffectedMovement[]\n balances?: AffectedBalance[]\n}\n\nasync function emitInventorySideEffects(\n ctx: CommandRuntimeContext,\n affected: AffectedSideEffects,\n): Promise<void> {\n let de: DataEngine | null = null\n try {\n de = ctx.container.resolve('dataEngine') as DataEngine\n } catch {\n de = null\n }\n if (!de) return\n\n for (const { entity, action } of affected.reservations ?? []) {\n await emitCrudSideEffects({\n dataEngine: de,\n action,\n entity,\n identifiers: {\n id: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n },\n indexer: inventoryReservationCrudIndexer,\n events: inventoryReservationCrudEvents,\n })\n }\n for (const { entity, action } of affected.movements ?? []) {\n await emitCrudSideEffects({\n dataEngine: de,\n action,\n entity,\n identifiers: {\n id: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n },\n indexer: inventoryMovementCrudIndexer,\n events: inventoryMovementCrudEvents,\n })\n }\n for (const { entity, action } of affected.balances ?? []) {\n await emitCrudSideEffects({\n dataEngine: de,\n action,\n entity,\n identifiers: {\n id: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n },\n indexer: inventoryBalanceCrudIndexer,\n events: inventoryBalanceCrudEvents,\n })\n }\n}\n\nfunction resolveScope(ctx: CommandRuntimeContext, fallback?: { tenantId?: string | null; organizationId?: string | null }): Scope {\n const tenantId = fallback?.tenantId ?? ctx.auth?.tenantId ?? null\n const organizationId = fallback?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n if (!tenantId || !organizationId) {\n throw new CrudHttpError(400, { error: 'Tenant and organization scope are required.' })\n }\n return { tenantId, organizationId }\n}\n\nfunction resolveEm(ctx: CommandRuntimeContext): EntityManager {\n return (ctx.container.resolve('em') as EntityManager).fork()\n}\n\nasync function runInTransaction<TResult>(\n em: EntityManager,\n operation: (trx: EntityManager) => Promise<TResult>,\n): Promise<TResult> {\n const transactionalEm = em as EntityManager & {\n transactional?: (callback: (trx: EntityManager) => Promise<TResult>) => Promise<TResult>\n }\n if (typeof transactionalEm.transactional === 'function') {\n return transactionalEm.transactional((trx) => operation(trx))\n }\n return operation(em)\n}\n\nfunction toNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n }\n return 0\n}\n\nfunction isUniqueConstraintError(error: unknown): boolean {\n if (!error || typeof error !== 'object') return false\n const code = (error as { code?: string }).code\n if (code === '23505') return true\n const name = (error as { name?: string }).name\n return name === 'UniqueConstraintViolationException'\n}\n\nasync function findExistingMovementByIdempotencyKey(\n em: EntityManager,\n scope: Scope,\n idempotencyKey: string,\n): Promise<InventoryMovement | null> {\n return findOneWithDecryption(\n em,\n InventoryMovement,\n {\n organizationId: scope.organizationId,\n idempotencyKey,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n}\n\nasync function findExistingActiveReservationByIdempotencyKey(\n em: EntityManager,\n scope: Scope,\n idempotencyKey: string,\n): Promise<InventoryReservation | null> {\n return findOneWithDecryption(\n em,\n InventoryReservation,\n {\n organizationId: scope.organizationId,\n idempotencyKey,\n status: 'active',\n deletedAt: null,\n },\n undefined,\n scope,\n )\n}\n\nfunction resolveLotFromBalance(balance: InventoryBalance): InventoryLot | null {\n const lotRaw = balance.lot ?? null\n if (!lotRaw || typeof lotRaw === 'string') return null\n return lotRaw\n}\n\nfunction balanceHasEligibleLot(balance: InventoryBalance, now: Date): boolean {\n const lot = resolveLotFromBalance(balance)\n return isLotEligible(lot, now)\n}\n\nfunction setNumeric(target: { [key: string]: unknown }, key: string, value: number) {\n target[key] = toNumericString(value)\n}\n\nfunction getAvailableQuantity(balance: InventoryBalance): number {\n return toNumber(balance.quantityOnHand) - toNumber(balance.quantityReserved) - toNumber(balance.quantityAllocated)\n}\n\nfunction extractReservationMetadata(reservation: InventoryReservation): ReservationMetadata {\n if (!reservation.metadata || typeof reservation.metadata !== 'object' || Array.isArray(reservation.metadata)) {\n return {}\n }\n return { ...(reservation.metadata as Record<string, unknown>) }\n}\n\nfunction buildBucketKey(input: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId: string | null\n serialNumber: string | null\n}): string {\n return [\n input.warehouseId,\n input.locationId,\n input.catalogVariantId,\n input.lotId ?? '',\n input.serialNumber ?? '',\n ].join('::')\n}\n\nfunction serializeAllocationBuckets(buckets: AllocationBucket[]): Array<{ locationId: string; lotId: string | null; quantity: string }> {\n return buckets.map((bucket) => ({\n locationId: bucket.locationId,\n lotId: bucket.lotId,\n quantity: toNumericString(bucket.quantity),\n }))\n}\n\nasync function buildMutationLog(input: MutationLogInput) {\n const { translate } = await resolveTranslations()\n const aliases = Array.from(\n new Set((input.cacheAliases ?? []).filter((alias) => typeof alias === 'string' && alias.length > 0)),\n )\n return {\n actionLabel: translate(input.actionKey, input.fallbackLabel),\n resourceKind: input.resourceKind,\n resourceId: input.resourceId,\n parentResourceKind: input.parentResourceId ? 'wms.inventory' : null,\n parentResourceId: input.parentResourceId ?? null,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n ...(aliases.length ? { context: { cacheAliases: aliases } } : {}),\n }\n}\n\nasync function requireWarehouse(em: EntityManager, ctx: CommandRuntimeContext, warehouseId: string, scope?: Scope) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const warehouse = await findOneWithDecryption(\n em,\n Warehouse,\n { id: warehouseId, deletedAt: null },\n undefined,\n resolvedScope,\n )\n if (!warehouse) throw new CrudHttpError(404, { error: 'Warehouse not found.' })\n ensureTenantScope(ctx, warehouse.tenantId)\n ensureOrganizationScope(ctx, warehouse.organizationId)\n return warehouse\n}\n\nasync function requireLocation(em: EntityManager, ctx: CommandRuntimeContext, locationId: string, scope?: Scope) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const location = await findOneWithDecryption(\n em,\n WarehouseLocation,\n { id: locationId, deletedAt: null },\n undefined,\n resolvedScope,\n )\n if (!location) throw new CrudHttpError(404, { error: 'Warehouse location not found.' })\n ensureTenantScope(ctx, location.tenantId)\n ensureOrganizationScope(ctx, location.organizationId)\n return location\n}\n\nasync function requireReservation(em: EntityManager, ctx: CommandRuntimeContext, reservationId: string, scope?: Scope, lock = false) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const reservation = await findOneWithDecryption(\n em,\n InventoryReservation,\n { id: reservationId, deletedAt: null },\n lock ? { lockMode: LockMode.PESSIMISTIC_WRITE } : undefined,\n resolvedScope,\n )\n if (!reservation) throw new CrudHttpError(404, { error: 'Inventory reservation not found.' })\n ensureTenantScope(ctx, reservation.tenantId)\n ensureOrganizationScope(ctx, reservation.organizationId)\n return reservation\n}\n\nasync function loadProfileForVariant(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n catalogVariantId: string,\n scope?: Scope,\n) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const profile = await findOneWithDecryption(\n em,\n ProductInventoryProfile,\n { catalogVariantId, deletedAt: null },\n undefined,\n resolvedScope,\n )\n if (!profile) return null\n ensureTenantScope(ctx, profile.tenantId)\n ensureOrganizationScope(ctx, profile.organizationId)\n return profile\n}\n\nasync function resolveReceiveLotId(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n scope: Scope,\n input: Pick<InventoryReceiveInput, 'catalogVariantId' | 'lotId' | 'lotNumber'>,\n): Promise<string | undefined> {\n if (input.lotId?.trim()) return input.lotId.trim()\n const lotNumber = input.lotNumber?.trim()\n if (!lotNumber) return undefined\n\n const existing = await findOneWithDecryption(\n em,\n InventoryLot,\n {\n catalogVariantId: input.catalogVariantId,\n lotNumber,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n if (existing) return existing.id\n\n const queryEngine = ctx.container.resolve<QueryEngine>('queryEngine')\n const variantResult = await queryEngine.query(E.catalog.catalog_product_variant, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n filters: { id: { $eq: input.catalogVariantId } },\n fields: ['id', 'sku'],\n page: { page: 1, pageSize: 1 },\n })\n const firstItem: unknown = variantResult.items?.[0]\n const sku =\n typeof firstItem === 'object' && firstItem !== null\n ? String((firstItem as Record<string, unknown>).sku ?? '').trim()\n : ''\n if (!sku) {\n throw new CrudHttpError(422, { error: 'variant_sku_missing' })\n }\n\n // Use a client-side UUID so the lot entity can be persisted into the\n // surrounding transaction without a premature flush (defaultRaw would\n // otherwise require a DB round-trip to obtain the generated id).\n const lot = em.create(InventoryLot, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n catalogVariantId: input.catalogVariantId,\n sku,\n lotNumber,\n status: 'available',\n })\n em.persist(lot)\n return lot.id\n}\n\nasync function listCandidateBalances(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n input: {\n warehouseId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n },\n scope: Scope,\n) {\n const where: Record<string, unknown> = {\n warehouse: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n deletedAt: null,\n }\n if (input.lotId) where.lot = input.lotId\n if (input.serialNumber) where.serialNumber = input.serialNumber\n const balances = await findWithDecryption(\n em,\n InventoryBalance,\n where,\n {\n populate: ['lot', 'location'],\n lockMode: LockMode.PESSIMISTIC_WRITE,\n orderBy: { createdAt: 'asc', id: 'asc' },\n },\n scope,\n )\n for (const balance of balances) {\n ensureTenantScope(ctx, balance.tenantId)\n ensureOrganizationScope(ctx, balance.organizationId)\n }\n return balances\n}\n\nasync function listBalancesForVariant(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n catalogVariantId: string,\n scope: Scope,\n) {\n const balances = await findWithDecryption(\n em,\n InventoryBalance,\n {\n catalogVariantId,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n for (const balance of balances) {\n ensureTenantScope(ctx, balance.tenantId)\n ensureOrganizationScope(ctx, balance.organizationId)\n }\n return balances\n}\n\nasync function emitLowStockEventIfNeeded(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n scope: Scope,\n catalogVariantId: string,\n) {\n const profile = await loadProfileForVariant(em, ctx, catalogVariantId, scope)\n if (!profile) return\n\n const balances = await listBalancesForVariant(em, ctx, catalogVariantId, scope)\n const availableQuantity = balances.reduce((total, balance) => total + getAvailableQuantity(balance), 0)\n const lowStock = evaluateLowStock(profile, availableQuantity)\n if (!lowStock) return\n\n await emitWmsEvent('wms.inventory.low_stock', {\n id: catalogVariantId,\n catalogVariantId,\n availableQuantity: lowStock.availableQuantity,\n reorderPoint: lowStock.reorderPoint,\n safetyStock: lowStock.safetyStock,\n state: lowStock.state,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n}\n\nasync function loadReceivedAtByBucket(\n em: EntityManager,\n balances: InventoryBalance[],\n scope: Scope,\n): Promise<Map<string, Date>> {\n if (balances.length === 0) return new Map()\n const locationIds = Array.from(\n new Set(\n balances.map((balance) => (typeof balance.location === 'string' ? balance.location : balance.location.id)),\n ),\n )\n const warehouseId = typeof balances[0].warehouse === 'string' ? balances[0].warehouse : balances[0].warehouse.id\n const catalogVariantId = balances[0].catalogVariantId\n const movements = await findWithDecryption(\n em,\n InventoryMovement,\n {\n warehouse: warehouseId,\n catalogVariantId,\n deletedAt: null,\n $or: [\n { locationFrom: { $in: locationIds } },\n { locationTo: { $in: locationIds } },\n ],\n },\n {\n orderBy: { receivedAt: 'asc' },\n },\n scope,\n )\n const map = new Map<string, Date>()\n for (const movement of movements) {\n const locationIdRaw = movement.locationTo ?? movement.locationFrom ?? null\n const locationId =\n typeof locationIdRaw === 'string'\n ? locationIdRaw\n : locationIdRaw?.id ?? null\n if (!locationId) continue\n const lotIdRaw = movement.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const key = buildBucketKey({\n warehouseId,\n locationId,\n catalogVariantId: movement.catalogVariantId,\n lotId,\n serialNumber: movement.serialNumber ?? null,\n })\n if (!map.has(key)) {\n map.set(key, movement.receivedAt)\n }\n }\n return map\n}\n\ntype BalanceSortRow = InventoryStrategyBucket & { balance: InventoryBalance }\n\nfunction sortBalancesForStrategy(\n balances: InventoryBalance[],\n strategy: InventoryStrategy,\n receiptMap: Map<string, Date>,\n): InventoryBalance[] {\n const rows: BalanceSortRow[] = balances.map((balance) => {\n const warehouseId = typeof balance.warehouse === 'string' ? balance.warehouse : balance.warehouse.id\n const locationId = typeof balance.location === 'string' ? balance.location : balance.location.id\n const lotIdRaw = balance.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const lot = typeof balance.lot === 'string' ? null : balance.lot\n return {\n balance,\n warehouseId,\n locationId,\n catalogVariantId: balance.catalogVariantId,\n createdAt: balance.createdAt,\n lotId,\n lotExpiresAt: lot?.expiresAt ?? null,\n serialNumber: balance.serialNumber ?? null,\n }\n })\n const sorted = sortBucketsForStrategy(rows, strategy, receiptMap)\n return sorted.map((row) => row.balance)\n}\n\nasync function resolveReservationStrategy(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n input: InventoryReservationCreateInput,\n scope: Scope,\n): Promise<InventoryStrategy> {\n const profile = await loadProfileForVariant(em, ctx, input.catalogVariantId, scope)\n return resolveReservationStrategyFromProfile(profile, input.strategy)\n}\n\nfunction requireSufficientAvailability(remaining: number) {\n if (remaining > 0.000001) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n}\n\nasync function findExactBalanceForUpdate(\n em: EntityManager,\n scope: Scope,\n input: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n },\n) {\n return findOneWithDecryption(\n em,\n InventoryBalance,\n {\n warehouse: input.warehouseId,\n location: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lot: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n deletedAt: null,\n },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n}\n\nasync function findReservationBucketBalance(\n em: EntityManager,\n scope: Scope,\n reservation: InventoryReservation,\n bucket: AllocationBucket,\n) {\n const warehouseId =\n typeof reservation.warehouse === 'string'\n ? reservation.warehouse\n : reservation.warehouse.id\n\n if (typeof bucket.balanceId === 'string' && bucket.balanceId.length > 0) {\n const balance = await findOneWithDecryption(\n em,\n InventoryBalance,\n { id: bucket.balanceId, deletedAt: null },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n if (balance) return balance\n }\n\n return findExactBalanceForUpdate(em, scope, {\n warehouseId,\n locationId: bucket.locationId,\n catalogVariantId: reservation.catalogVariantId,\n lotId: bucket.lotId ?? undefined,\n serialNumber: bucket.serialNumber ?? undefined,\n })\n}\n\nasync function upsertBalanceBucket(\n em: EntityManager,\n scope: Scope,\n input: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n },\n): Promise<{ balance: InventoryBalance; created: boolean }> {\n const existing = await findExactBalanceForUpdate(em, scope, input)\n if (existing) return { balance: existing, created: false }\n const balance = em.create(InventoryBalance, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n warehouse: em.getReference(Warehouse, input.warehouseId),\n location: em.getReference(WarehouseLocation, input.locationId),\n catalogVariantId: input.catalogVariantId,\n lot: input.lotId ? em.getReference(InventoryLot, input.lotId) : null,\n serialNumber: input.serialNumber ?? null,\n quantityOnHand: '0',\n quantityReserved: '0',\n quantityAllocated: '0',\n metadata: null,\n })\n em.persist(balance)\n await em.flush()\n return { balance, created: true }\n}\n\nasync function resolveReceivedAtForBalance(\n em: EntityManager,\n balance: InventoryBalance | null,\n scope: Scope,\n fallback: Date,\n): Promise<Date> {\n if (!balance) return fallback\n const warehouseId = typeof balance.warehouse === 'string' ? balance.warehouse : balance.warehouse.id\n const locationId = typeof balance.location === 'string' ? balance.location : balance.location.id\n const lotIdRaw = balance.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const movement = await findOneWithDecryption(\n em,\n InventoryMovement,\n {\n warehouse: warehouseId,\n catalogVariantId: balance.catalogVariantId,\n lot: lotId,\n serialNumber: balance.serialNumber ?? null,\n deletedAt: null,\n $or: [\n { locationFrom: locationId },\n { locationTo: locationId },\n ],\n },\n { orderBy: { receivedAt: 'asc' } },\n scope,\n )\n return movement?.receivedAt ?? fallback\n}\n\nasync function createMovement(\n em: EntityManager,\n scope: Scope,\n input: {\n warehouseId: string\n locationFromId?: string | null\n locationToId?: string | null\n catalogVariantId: string\n lotId?: string | null\n serialNumber?: string | null\n quantity: number\n type: InventoryMovement['type']\n referenceType: InventoryMovement['referenceType']\n referenceId: string\n performedBy: string\n performedAt: Date\n receivedAt: Date\n reason?: string | null\n reasonCode?: string | null\n metadata?: Record<string, unknown> | null\n idempotencyKey: string\n },\n) {\n const movement = em.create(InventoryMovement, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n warehouse: em.getReference(Warehouse, input.warehouseId),\n locationFrom: input.locationFromId ? em.getReference(WarehouseLocation, input.locationFromId) : null,\n locationTo: input.locationToId ? em.getReference(WarehouseLocation, input.locationToId) : null,\n catalogVariantId: input.catalogVariantId,\n lot: input.lotId ? em.getReference(InventoryLot, input.lotId) : null,\n serialNumber: input.serialNumber ?? null,\n quantity: toNumericString(input.quantity),\n type: input.type,\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt: input.performedAt,\n receivedAt: input.receivedAt,\n reason: input.reason ?? null,\n reasonCode: input.reasonCode ?? null,\n metadata: input.metadata ?? null,\n idempotencyKey: input.idempotencyKey,\n })\n em.persist(movement)\n return movement\n}\n\ntype MovementMutationInput = {\n warehouseId: string\n locationFromId?: string | null\n locationToId?: string | null\n catalogVariantId: string\n lotId?: string | null\n serialNumber?: string | null\n quantity: number\n type: InventoryMovement['type']\n referenceType: InventoryMovement['referenceType']\n referenceId: string\n performedBy: string\n performedAt: Date\n receivedAt: Date\n reason?: string | null\n reasonCode?: string | null\n metadata?: Record<string, unknown> | null\n}\n\nasync function persistMovementWithIdempotency(\n em: EntityManager,\n scope: Scope,\n input: MovementMutationInput,\n): Promise<{ movement: InventoryMovement; idempotentReplay: boolean }> {\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n type: input.type,\n warehouseId: input.warehouseId,\n locationFromId: input.locationFromId,\n locationToId: input.locationToId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n quantity: input.quantity,\n })\n const existing = await findExistingMovementByIdempotencyKey(em, scope, idempotencyKey)\n if (existing) {\n return { movement: existing, idempotentReplay: true }\n }\n try {\n const movement = await createMovement(em, scope, {\n ...input,\n idempotencyKey,\n })\n return { movement, idempotentReplay: false }\n } catch (error) {\n if (!isUniqueConstraintError(error)) throw error\n const raced = await findExistingMovementByIdempotencyKey(em, scope, idempotencyKey)\n if (!raced) throw error\n return { movement: raced, idempotentReplay: true }\n }\n}\n\nasync function emitBalanceDriftIfNeeded(\n balance: InventoryBalance,\n field: 'quantityReserved' | 'quantityAllocated',\n attemptedValue: number,\n scope: Scope,\n reservationId: string,\n) {\n if (attemptedValue >= -0.000001) return\n await emitWmsEvent('wms.inventory.balance_drift', {\n id: balance.id,\n balanceId: balance.id,\n reservationId,\n field,\n attemptedValue: toNumericString(attemptedValue),\n clampedValue: '0',\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n}\n\nfunction enforceNonNegativeBalance(\n balance: InventoryBalance,\n field: 'quantityReserved' | 'quantityAllocated',\n nextValue: number,\n reservationId: string,\n scope: Scope,\n) {\n if (nextValue < -0.000001) {\n void emitBalanceDriftIfNeeded(balance, field, nextValue, scope, reservationId)\n throw new CrudHttpError(409, { error: 'balance_integrity_violation' })\n }\n setNumeric(balance as unknown as Record<string, unknown>, field, nextValue)\n}\n\nconst reserveInventoryCommand: CommandHandler<InventoryReservationCreateInput, ReservationCommandResult> = {\n id: 'wms.inventory.reserve',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReservationCreateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const reservationIdempotencyKey = buildReservationIdempotencyKey({\n sourceType: input.sourceType,\n sourceId: input.sourceId,\n catalogVariantId: input.catalogVariantId,\n warehouseId: input.warehouseId,\n quantity: input.quantity,\n })\n const existingReservation = await findExistingActiveReservationByIdempotencyKey(\n trx,\n scope,\n reservationIdempotencyKey,\n )\n if (existingReservation) {\n const metadata = extractReservationMetadata(existingReservation)\n const buckets = Array.isArray(metadata.allocatedBuckets)\n ? (metadata.allocatedBuckets as AllocationBucket[])\n : []\n return {\n reservationId: existingReservation.id,\n allocatedBuckets: serializeAllocationBuckets(buckets),\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n reservationEntity: existingReservation,\n touchedBalances: [] as InventoryBalance[],\n idempotentReplay: true,\n }\n }\n const strategy = await resolveReservationStrategy(trx, ctx, input, scope)\n const balances = await listCandidateBalances(trx, ctx, input, scope)\n const receiptMap = await loadReceivedAtByBucket(trx, balances, scope)\n const now = new Date()\n const ordered = sortBalancesForStrategy(\n balances.filter(\n (balance) => balanceHasEligibleLot(balance, now) && getAvailableQuantity(balance) > 0,\n ),\n strategy,\n receiptMap,\n )\n let remaining = input.quantity\n const buckets: AllocationBucket[] = []\n const touchedBalances: InventoryBalance[] = []\n for (const balance of ordered) {\n if (remaining <= 0) break\n const available = getAvailableQuantity(balance)\n if (available <= 0) continue\n const quantity = Math.min(available, remaining)\n const locationId = typeof balance.location === 'string' ? balance.location : balance.location.id\n const lotIdRaw = balance.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const persistedBalance = await findExactBalanceForUpdate(trx, scope, {\n warehouseId: input.warehouseId,\n locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: lotId ?? undefined,\n serialNumber: balance.serialNumber ?? undefined,\n })\n if (!persistedBalance) {\n throw new CrudHttpError(409, { error: 'invalid_tracking_state' })\n }\n setNumeric(\n persistedBalance as unknown as Record<string, unknown>,\n 'quantityReserved',\n toNumber(persistedBalance.quantityReserved) + quantity,\n )\n touchedBalances.push(persistedBalance)\n buckets.push({\n balanceId: persistedBalance.id,\n locationId,\n lotId,\n serialNumber: balance.serialNumber ?? null,\n quantity,\n })\n remaining -= quantity\n }\n requireSufficientAvailability(remaining)\n let reservation: InventoryReservation\n try {\n reservation = trx.create(InventoryReservation, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n warehouse: trx.getReference(Warehouse, input.warehouseId),\n catalogVariantId: input.catalogVariantId,\n lot: buckets.length === 1 && buckets[0].lotId ? trx.getReference(InventoryLot, buckets[0].lotId) : null,\n serialNumber: buckets.length === 1 ? buckets[0].serialNumber : null,\n quantity: toNumericString(input.quantity),\n sourceType: input.sourceType,\n sourceId: input.sourceId,\n expiresAt: input.expiresAt ?? null,\n status: 'active',\n idempotencyKey: reservationIdempotencyKey,\n metadata: {\n ...(input.metadata ?? {}),\n allocatedBuckets: buckets,\n allocationState: 'reserved',\n strategy,\n },\n })\n trx.persist(reservation)\n await trx.flush()\n } catch (error) {\n if (!isUniqueConstraintError(error)) throw error\n const raced = await findExistingActiveReservationByIdempotencyKey(\n trx,\n scope,\n reservationIdempotencyKey,\n )\n if (!raced) throw error\n const metadata = extractReservationMetadata(raced)\n const racedBuckets = Array.isArray(metadata.allocatedBuckets)\n ? (metadata.allocatedBuckets as AllocationBucket[])\n : []\n return {\n reservationId: raced.id,\n allocatedBuckets: serializeAllocationBuckets(racedBuckets),\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n reservationEntity: raced,\n touchedBalances: [] as InventoryBalance[],\n idempotentReplay: true,\n }\n }\n return {\n reservationId: reservation.id,\n allocatedBuckets: serializeAllocationBuckets(buckets),\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n reservationEntity: reservation,\n touchedBalances,\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n reservations: [{ entity: result.reservationEntity, action: 'created' }],\n balances: result.touchedBalances.map((entity) => ({ entity, action: 'updated' as const })),\n })\n void emitWmsEvent('wms.inventory.reserved', {\n id: result.reservationId,\n reservationId: result.reservationId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return {\n reservationId: result.reservationId,\n allocatedBuckets: result.allocatedBuckets,\n }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.reserve',\n fallbackLabel: 'Reserve inventory',\n resourceKind: WMS_INVENTORY_RESERVATION_RESOURCE,\n resourceId: result?.reservationId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst releaseInventoryReservationCommand: CommandHandler<InventoryReservationReleaseInput, { reservationId: string }> = {\n id: 'wms.inventory.release',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReservationReleaseSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n const reservation = await requireReservation(trx, ctx, input.reservationId, scope, true)\n const metadata = extractReservationMetadata(reservation)\n const buckets = Array.isArray(metadata.allocatedBuckets) ? (metadata.allocatedBuckets as AllocationBucket[]) : []\n const allocationState = metadata.allocationState ?? 'reserved'\n const touchedBalances: InventoryBalance[] = []\n for (const bucket of buckets) {\n const balance = await findReservationBucketBalance(\n trx,\n scope,\n reservation,\n bucket,\n )\n if (!balance) continue\n if (allocationState === 'allocated') {\n enforceNonNegativeBalance(\n balance,\n 'quantityAllocated',\n toNumber(balance.quantityAllocated) - bucket.quantity,\n reservation.id,\n scope,\n )\n } else {\n enforceNonNegativeBalance(\n balance,\n 'quantityReserved',\n toNumber(balance.quantityReserved) - bucket.quantity,\n reservation.id,\n scope,\n )\n }\n touchedBalances.push(balance)\n }\n reservation.status = 'released'\n reservation.metadata = {\n ...metadata,\n releasedReason: input.reason,\n releasedAt: new Date().toISOString(),\n }\n await trx.flush()\n return {\n reservationId: reservation.id,\n warehouseId: typeof reservation.warehouse === 'string' ? reservation.warehouse : reservation.warehouse.id,\n catalogVariantId: reservation.catalogVariantId,\n quantity: reservation.quantity,\n tenantId: reservation.tenantId,\n organizationId: reservation.organizationId,\n reservationEntity: reservation,\n touchedBalances,\n }\n })\n await emitInventorySideEffects(ctx, {\n reservations: [{ entity: result.reservationEntity, action: 'updated' }],\n balances: result.touchedBalances.map((entity) => ({ entity, action: 'updated' as const })),\n })\n void emitWmsEvent('wms.inventory.released', {\n id: result.reservationId,\n reservationId: result.reservationId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: result.quantity,\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n return { reservationId: result.reservationId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.release',\n fallbackLabel: 'Release inventory reservation',\n resourceKind: WMS_INVENTORY_RESERVATION_RESOURCE,\n resourceId: result?.reservationId ?? input?.reservationId ?? null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst allocateInventoryReservationCommand: CommandHandler<InventoryReservationAllocateInput, { reservationId: string; allocationState: 'allocated' }> = {\n id: 'wms.inventory.allocate',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReservationAllocateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n const reservation = await requireReservation(trx, ctx, input.reservationId, scope, true)\n const metadata = extractReservationMetadata(reservation)\n if (metadata.allocationState === 'allocated') {\n return {\n reservationId: reservation.id,\n allocationState: 'allocated' as const,\n warehouseId: typeof reservation.warehouse === 'string' ? reservation.warehouse : reservation.warehouse.id,\n catalogVariantId: reservation.catalogVariantId,\n quantity: reservation.quantity,\n tenantId: reservation.tenantId,\n organizationId: reservation.organizationId,\n reservationEntity: reservation,\n touchedBalances: [] as InventoryBalance[],\n }\n }\n const buckets = Array.isArray(metadata.allocatedBuckets) ? (metadata.allocatedBuckets as AllocationBucket[]) : []\n const touchedBalances: InventoryBalance[] = []\n for (const bucket of buckets) {\n const balance = await findReservationBucketBalance(\n trx,\n scope,\n reservation,\n bucket,\n )\n if (!balance) throw new CrudHttpError(409, { error: 'invalid_tracking_state' })\n if (toNumber(balance.quantityReserved) < bucket.quantity - 0.000001) {\n throw new CrudHttpError(409, { error: 'invalid_tracking_state' })\n }\n // Guard above ensures the subtraction is non-negative within numeric(16,4) precision.\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityReserved',\n toNumber(balance.quantityReserved) - bucket.quantity,\n )\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityAllocated',\n toNumber(balance.quantityAllocated) + bucket.quantity,\n )\n touchedBalances.push(balance)\n }\n reservation.metadata = {\n ...metadata,\n allocationState: 'allocated',\n allocatedAt: new Date().toISOString(),\n }\n await trx.flush()\n return {\n reservationId: reservation.id,\n allocationState: 'allocated' as const,\n warehouseId: typeof reservation.warehouse === 'string' ? reservation.warehouse : reservation.warehouse.id,\n catalogVariantId: reservation.catalogVariantId,\n quantity: reservation.quantity,\n tenantId: reservation.tenantId,\n organizationId: reservation.organizationId,\n reservationEntity: reservation,\n touchedBalances,\n }\n })\n await emitInventorySideEffects(ctx, {\n reservations: [{ entity: result.reservationEntity, action: 'updated' }],\n balances: result.touchedBalances.map((entity) => ({ entity, action: 'updated' as const })),\n })\n void emitWmsEvent('wms.inventory.allocated', {\n id: result.reservationId,\n reservationId: result.reservationId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: result.quantity,\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n return { reservationId: result.reservationId, allocationState: result.allocationState }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.allocate',\n fallbackLabel: 'Allocate inventory reservation',\n resourceKind: WMS_INVENTORY_RESERVATION_RESOURCE,\n resourceId: result?.reservationId ?? input?.reservationId ?? null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst adjustInventoryCommand: CommandHandler<InventoryAdjustInput, { movementId: string }> = {\n id: 'wms.inventory.adjust',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryAdjustSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const location = await requireLocation(trx, ctx, input.locationId, scope)\n const locationWarehouseId = typeof location.warehouse === 'string' ? location.warehouse : location.warehouse.id\n if (locationWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const { balance, created: balanceWasNew } = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const delta = input.delta\n const performedAt = input.performedAt ?? new Date()\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationToId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: delta,\n type: 'adjust',\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt: performedAt,\n reason: input.reason,\n reasonCode: input.reasonCode ?? null,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: delta,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n idempotentReplay: true,\n }\n }\n if (delta < 0 && getAvailableQuantity(balance) < Math.abs(delta) - 0.000001) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(balance.quantityOnHand) + delta,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n movementId: movement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: delta,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement,\n balanceEntity: balance,\n balanceAction: balanceWasNew ? ('created' as const) : ('updated' as const),\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: [{ entity: result.movementEntity, action: 'created' }],\n balances: [{ entity: result.balanceEntity, action: result.balanceAction }],\n })\n void emitWmsEvent('wms.inventory.adjusted', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return { movementId: result.movementId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.adjust',\n fallbackLabel: 'Adjust inventory',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst receiveInventoryCommand: CommandHandler<InventoryReceiveInput, { movementId: string }> = {\n id: 'wms.inventory.receive',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReceiveSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const location = await requireLocation(trx, ctx, input.locationId, scope)\n const locationWarehouseId = typeof location.warehouse === 'string' ? location.warehouse : location.warehouse.id\n if (locationWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const profile = await loadProfileForVariant(trx, ctx, input.catalogVariantId, scope)\n const resolvedLotId = await resolveReceiveLotId(trx, ctx, scope, input)\n enforceInventoryTrackingRequirements(profile, {\n lotId: resolvedLotId ?? null,\n serialNumber: input.serialNumber ?? null,\n })\n const { balance, created: balanceWasNew } = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: resolvedLotId,\n serialNumber: input.serialNumber,\n })\n const receivedAt = input.receivedAt ?? input.performedAt ?? new Date()\n const performedAt = input.performedAt ?? receivedAt\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationToId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: resolvedLotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: input.quantity,\n type: 'receipt',\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt,\n reason: input.reason,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n idempotentReplay: true,\n }\n }\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(balance.quantityOnHand) + input.quantity,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n movementId: movement.id,\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement,\n balanceEntity: balance,\n balanceAction: balanceWasNew ? ('created' as const) : ('updated' as const),\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: [{ entity: result.movementEntity, action: 'created' }],\n balances: [{ entity: result.balanceEntity, action: result.balanceAction }],\n })\n void emitWmsEvent('wms.inventory.received', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n locationId: result.locationId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return { movementId: result.movementId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.receive',\n fallbackLabel: 'Receive inventory',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst moveInventoryCommand: CommandHandler<InventoryMoveInput, { movementId: string }> = {\n id: 'wms.inventory.move',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryMoveSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const sourceLocation = await requireLocation(trx, ctx, input.fromLocationId, scope)\n const targetLocation = await requireLocation(trx, ctx, input.toLocationId, scope)\n const sourceWarehouseId = typeof sourceLocation.warehouse === 'string' ? sourceLocation.warehouse : sourceLocation.warehouse.id\n const targetWarehouseId = typeof targetLocation.warehouse === 'string' ? targetLocation.warehouse : targetLocation.warehouse.id\n if (sourceWarehouseId !== input.warehouseId || targetWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const sourceResult = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.fromLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const sourceBalance = sourceResult.balance\n const sourceBalanceAction = sourceResult.created ? ('created' as const) : ('updated' as const)\n const targetResult = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.toLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const targetBalance = targetResult.balance\n const targetBalanceAction = targetResult.created ? ('created' as const) : ('updated' as const)\n const performedAt = input.performedAt ?? new Date()\n const receivedAt = await resolveReceivedAtForBalance(trx, sourceBalance, scope, performedAt)\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationFromId: input.fromLocationId,\n locationToId: input.toLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: input.quantity,\n type: input.type ?? 'transfer',\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt,\n reason: input.reason,\n reasonCode: input.reasonCode ?? null,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balances: [\n { entity: sourceBalance, action: sourceBalanceAction },\n { entity: targetBalance, action: targetBalanceAction },\n ] as AffectedBalance[],\n idempotentReplay: true,\n }\n }\n if (getAvailableQuantity(sourceBalance) < input.quantity - 0.000001) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n setNumeric(\n sourceBalance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(sourceBalance.quantityOnHand) - input.quantity,\n )\n setNumeric(\n targetBalance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(targetBalance.quantityOnHand) + input.quantity,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n movementId: movement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement,\n balances: [\n { entity: sourceBalance, action: sourceBalanceAction },\n { entity: targetBalance, action: targetBalanceAction },\n ] as AffectedBalance[],\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: [{ entity: result.movementEntity, action: 'created' }],\n balances: result.balances,\n })\n void emitWmsEvent('wms.inventory.moved', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return { movementId: result.movementId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.move',\n fallbackLabel: 'Move inventory',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst cycleCountInventoryCommand: CommandHandler<InventoryCycleCountInput, { adjustmentDelta: string; movementId?: string | null }> = {\n id: 'wms.inventory.cycleCount',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryCycleCountSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const location = await requireLocation(trx, ctx, input.locationId, scope)\n const locationWarehouseId = typeof location.warehouse === 'string' ? location.warehouse : location.warehouse.id\n if (locationWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const { balance, created: balanceWasNew } = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const currentOnHand = toNumber(balance.quantityOnHand)\n const delta = input.countedQuantity - currentOnHand\n if (delta === 0) {\n return {\n adjustmentDelta: '0',\n movementId: null as string | null,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: null as InventoryMovement | null,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n }\n }\n if (!input.autoAdjust) {\n throw new CrudHttpError(422, { error: 'auto_adjust_required' })\n }\n const performedAt = input.performedAt ?? new Date()\n const receivedAt = await resolveReceivedAtForBalance(trx, balance, scope, performedAt)\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationToId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: delta,\n type: 'cycle_count',\n referenceType: 'manual',\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt,\n reason: input.reason,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n adjustmentDelta: toNumericString(delta),\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n idempotentReplay: true,\n }\n }\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n input.countedQuantity,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n adjustmentDelta: toNumericString(delta),\n movementId: movement.id as string | null,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement as InventoryMovement | null,\n balanceEntity: balance,\n balanceAction: balanceWasNew ? ('created' as const) : ('updated' as const),\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: result.movementEntity ? [{ entity: result.movementEntity, action: 'created' }] : [],\n balances: [{ entity: result.balanceEntity, action: result.balanceAction }],\n })\n if (result.movementId) {\n void emitWmsEvent('wms.inventory.reconciled', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n adjustmentDelta: result.adjustmentDelta,\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n }\n return {\n adjustmentDelta: result.adjustmentDelta,\n movementId: result.movementId ?? null,\n }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.cycleCount',\n fallbackLabel: 'Run cycle count reconciliation',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nregisterCommand(reserveInventoryCommand)\nregisterCommand(releaseInventoryReservationCommand)\nregisterCommand(allocateInventoryReservationCommand)\nregisterCommand(adjustInventoryCommand)\nregisterCommand(receiveInventoryCommand)\nregisterCommand(moveInventoryCommand)\nregisterCommand(cycleCountInventoryCommand)\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// =============================================================================\n// WMS Inventory Mutation Commands \u2014 Undo Policy\n// =============================================================================\n//\n// All inventory-mutation commands in this file are deliberately registered\n// with `isUndoable: false` and therefore opt out of the generic command-bus\n// undo flow. WMS inventory is modeled as an append-only ledger\n// (`inventory_movements`) that drives live balances; subsequent reservations\n// and movements may be made on top of any prior state, so a per-record\n// \"undo\" cannot safely re-derive a point-in-time balance without a\n// stop-the-world replay.\n//\n// Reversal is therefore exposed as an explicit, auditable counter-action in\n// the domain model rather than as a generic undo verb:\n// - reserve \u2194 release\n// - allocate \u2194 release (cancels the allocation)\n// - adjust(+N) \u2194 adjust(-N)\n// - receive \u2194 adjust / RMA flow\n// - move(A \u2192 B) \u2194 move(B \u2192 A)\n// - cycle count \u2194 cycle count (re-recount)\n//\n// The audit log still captures the full before/after via `buildLog`, so any\n// reversing counter-action is fully traceable.\n// =============================================================================\nimport { LockMode } from '@mikro-orm/core'\nimport { randomUUID } from 'crypto'\nimport type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { emitWmsEvent } from '../events'\nimport { E } from '#generated/entities.ids.generated'\nimport type { QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport {\n InventoryBalance,\n InventoryLot,\n InventoryMovement,\n InventoryReservation,\n ProductInventoryProfile,\n Warehouse,\n WarehouseLocation,\n type InventoryStrategy,\n} from '../data/entities'\nimport {\n inventoryAdjustSchema,\n inventoryCycleCountSchema,\n inventoryMoveSchema,\n inventoryReceiveSchema,\n inventoryReservationAllocateSchema,\n inventoryReservationCreateSchema,\n inventoryReservationReleaseSchema,\n type InventoryAdjustInput,\n type InventoryCycleCountInput,\n type InventoryMoveInput,\n type InventoryReceiveInput,\n type InventoryReservationAllocateInput,\n type InventoryReservationCreateInput,\n type InventoryReservationReleaseInput,\n} from '../data/validators'\nimport {\n evaluateLowStock,\n isLotEligible,\n resolveReservationStrategyFromProfile,\n sortBucketsForStrategy,\n type InventoryStrategyBucket,\n} from '../lib/inventoryPolicy'\nimport { enforceInventoryTrackingRequirements } from '../lib/inventoryTrackingValidation'\nimport {\n buildMovementIdempotencyKey,\n buildReservationIdempotencyKey,\n} from '../lib/inventoryIdempotency'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n inventoryBalanceCrudEvents,\n inventoryBalanceCrudIndexer,\n inventoryMovementCrudEvents,\n inventoryMovementCrudIndexer,\n inventoryReservationCrudEvents,\n inventoryReservationCrudIndexer,\n requireId,\n toNumericString,\n WMS_INVENTORY_BALANCE_RESOURCE,\n WMS_INVENTORY_MOVEMENT_RESOURCE,\n WMS_INVENTORY_RESERVATION_RESOURCE,\n} from './shared'\n\ntype Scope = { tenantId: string; organizationId: string }\ntype AllocationBucket = {\n balanceId: string\n locationId: string\n lotId: string | null\n serialNumber: string | null\n quantity: number\n}\n\ntype ReservationMetadata = {\n allocatedBuckets?: AllocationBucket[]\n allocationState?: 'reserved' | 'allocated'\n strategy?: InventoryStrategy\n releasedReason?: string\n releasedAt?: string\n allocatedAt?: string\n [key: string]: unknown\n}\n\ntype ReservationCommandResult = {\n reservationId: string\n allocatedBuckets: Array<{ locationId: string; lotId: string | null; quantity: string }>\n}\n\ntype MutationLogInput = {\n actionKey: string\n fallbackLabel: string\n resourceKind: string\n resourceId: string | null\n parentResourceId?: string | null\n tenantId: string | null\n organizationId: string | null\n cacheAliases?: string[]\n}\n\ntype AffectedReservation = { entity: InventoryReservation; action: 'created' | 'updated' | 'deleted' }\ntype AffectedMovement = { entity: InventoryMovement; action: 'created' | 'updated' | 'deleted' }\ntype AffectedBalance = { entity: InventoryBalance; action: 'created' | 'updated' | 'deleted' }\n\ntype AffectedSideEffects = {\n reservations?: AffectedReservation[]\n movements?: AffectedMovement[]\n balances?: AffectedBalance[]\n}\n\nasync function emitInventorySideEffects(\n ctx: CommandRuntimeContext,\n affected: AffectedSideEffects,\n): Promise<void> {\n let de: DataEngine | null = null\n try {\n de = ctx.container.resolve('dataEngine') as DataEngine\n } catch {\n de = null\n }\n if (!de) return\n\n for (const { entity, action } of affected.reservations ?? []) {\n await emitCrudSideEffects({\n dataEngine: de,\n action,\n entity,\n identifiers: {\n id: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n },\n indexer: inventoryReservationCrudIndexer,\n events: inventoryReservationCrudEvents,\n })\n }\n for (const { entity, action } of affected.movements ?? []) {\n await emitCrudSideEffects({\n dataEngine: de,\n action,\n entity,\n identifiers: {\n id: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n },\n indexer: inventoryMovementCrudIndexer,\n events: inventoryMovementCrudEvents,\n })\n }\n for (const { entity, action } of affected.balances ?? []) {\n await emitCrudSideEffects({\n dataEngine: de,\n action,\n entity,\n identifiers: {\n id: entity.id,\n organizationId: entity.organizationId,\n tenantId: entity.tenantId,\n },\n indexer: inventoryBalanceCrudIndexer,\n events: inventoryBalanceCrudEvents,\n })\n }\n}\n\nfunction resolveScope(ctx: CommandRuntimeContext, fallback?: { tenantId?: string | null; organizationId?: string | null }): Scope {\n const tenantId = fallback?.tenantId ?? ctx.auth?.tenantId ?? null\n const organizationId = fallback?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n if (!tenantId || !organizationId) {\n throw new CrudHttpError(400, { error: 'Tenant and organization scope are required.' })\n }\n return { tenantId, organizationId }\n}\n\nfunction resolveEm(ctx: CommandRuntimeContext): EntityManager {\n return (ctx.container.resolve('em') as EntityManager).fork()\n}\n\nasync function runInTransaction<TResult>(\n em: EntityManager,\n operation: (trx: EntityManager) => Promise<TResult>,\n): Promise<TResult> {\n const transactionalEm = em as EntityManager & {\n transactional?: (callback: (trx: EntityManager) => Promise<TResult>) => Promise<TResult>\n }\n if (typeof transactionalEm.transactional === 'function') {\n return transactionalEm.transactional((trx) => operation(trx))\n }\n return operation(em)\n}\n\nfunction toNumber(value: unknown): number {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n }\n return 0\n}\n\nfunction isUniqueConstraintError(error: unknown): boolean {\n if (!error || typeof error !== 'object') return false\n const code = (error as { code?: string }).code\n if (code === '23505') return true\n const name = (error as { name?: string }).name\n return name === 'UniqueConstraintViolationException'\n}\n\nasync function findExistingMovementByIdempotencyKey(\n em: EntityManager,\n scope: Scope,\n idempotencyKey: string,\n): Promise<InventoryMovement | null> {\n return findOneWithDecryption(\n em,\n InventoryMovement,\n {\n organizationId: scope.organizationId,\n idempotencyKey,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n}\n\nasync function findExistingActiveReservationByIdempotencyKey(\n em: EntityManager,\n scope: Scope,\n idempotencyKey: string,\n): Promise<InventoryReservation | null> {\n return findOneWithDecryption(\n em,\n InventoryReservation,\n {\n organizationId: scope.organizationId,\n idempotencyKey,\n status: 'active',\n deletedAt: null,\n },\n undefined,\n scope,\n )\n}\n\nfunction resolveLotFromBalance(balance: InventoryBalance): InventoryLot | null {\n const lotRaw = balance.lot ?? null\n if (!lotRaw || typeof lotRaw === 'string') return null\n return lotRaw\n}\n\nfunction balanceHasEligibleLot(balance: InventoryBalance, now: Date): boolean {\n const lot = resolveLotFromBalance(balance)\n return isLotEligible(lot, now)\n}\n\nfunction setNumeric(target: { [key: string]: unknown }, key: string, value: number) {\n target[key] = toNumericString(value)\n}\n\nfunction getAvailableQuantity(balance: InventoryBalance): number {\n return toNumber(balance.quantityOnHand) - toNumber(balance.quantityReserved) - toNumber(balance.quantityAllocated)\n}\n\nfunction extractReservationMetadata(reservation: InventoryReservation): ReservationMetadata {\n if (!reservation.metadata || typeof reservation.metadata !== 'object' || Array.isArray(reservation.metadata)) {\n return {}\n }\n return { ...(reservation.metadata as Record<string, unknown>) }\n}\n\nfunction buildBucketKey(input: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId: string | null\n serialNumber: string | null\n}): string {\n return [\n input.warehouseId,\n input.locationId,\n input.catalogVariantId,\n input.lotId ?? '',\n input.serialNumber ?? '',\n ].join('::')\n}\n\nfunction serializeAllocationBuckets(buckets: AllocationBucket[]): Array<{ locationId: string; lotId: string | null; quantity: string }> {\n return buckets.map((bucket) => ({\n locationId: bucket.locationId,\n lotId: bucket.lotId,\n quantity: toNumericString(bucket.quantity),\n }))\n}\n\nasync function buildMutationLog(input: MutationLogInput) {\n const { translate } = await resolveTranslations()\n const aliases = Array.from(\n new Set((input.cacheAliases ?? []).filter((alias) => typeof alias === 'string' && alias.length > 0)),\n )\n return {\n actionLabel: translate(input.actionKey, input.fallbackLabel),\n resourceKind: input.resourceKind,\n resourceId: input.resourceId,\n parentResourceKind: input.parentResourceId ? 'wms.inventory' : null,\n parentResourceId: input.parentResourceId ?? null,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n ...(aliases.length ? { context: { cacheAliases: aliases } } : {}),\n }\n}\n\nasync function requireWarehouse(em: EntityManager, ctx: CommandRuntimeContext, warehouseId: string, scope?: Scope) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const warehouse = await findOneWithDecryption(\n em,\n Warehouse,\n { id: warehouseId, deletedAt: null },\n undefined,\n resolvedScope,\n )\n if (!warehouse) throw new CrudHttpError(404, { error: 'Warehouse not found.' })\n ensureTenantScope(ctx, warehouse.tenantId)\n ensureOrganizationScope(ctx, warehouse.organizationId)\n return warehouse\n}\n\nasync function requireLocation(em: EntityManager, ctx: CommandRuntimeContext, locationId: string, scope?: Scope) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const location = await findOneWithDecryption(\n em,\n WarehouseLocation,\n { id: locationId, deletedAt: null },\n undefined,\n resolvedScope,\n )\n if (!location) throw new CrudHttpError(404, { error: 'Warehouse location not found.' })\n ensureTenantScope(ctx, location.tenantId)\n ensureOrganizationScope(ctx, location.organizationId)\n return location\n}\n\nasync function requireReservation(em: EntityManager, ctx: CommandRuntimeContext, reservationId: string, scope?: Scope, lock = false) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const reservation = await findOneWithDecryption(\n em,\n InventoryReservation,\n { id: reservationId, deletedAt: null },\n lock ? { lockMode: LockMode.PESSIMISTIC_WRITE } : undefined,\n resolvedScope,\n )\n if (!reservation) throw new CrudHttpError(404, { error: 'Inventory reservation not found.' })\n ensureTenantScope(ctx, reservation.tenantId)\n ensureOrganizationScope(ctx, reservation.organizationId)\n return reservation\n}\n\nasync function loadProfileForVariant(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n catalogVariantId: string,\n scope?: Scope,\n) {\n const resolvedScope = scope ?? resolveScope(ctx)\n const profile = await findOneWithDecryption(\n em,\n ProductInventoryProfile,\n { catalogVariantId, deletedAt: null },\n undefined,\n resolvedScope,\n )\n if (!profile) return null\n ensureTenantScope(ctx, profile.tenantId)\n ensureOrganizationScope(ctx, profile.organizationId)\n return profile\n}\n\nasync function resolveReceiveLotId(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n scope: Scope,\n input: Pick<InventoryReceiveInput, 'catalogVariantId' | 'lotId' | 'lotNumber'>,\n): Promise<string | undefined> {\n if (input.lotId?.trim()) return input.lotId.trim()\n const lotNumber = input.lotNumber?.trim()\n if (!lotNumber) return undefined\n\n const existing = await findOneWithDecryption(\n em,\n InventoryLot,\n {\n catalogVariantId: input.catalogVariantId,\n lotNumber,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n if (existing) return existing.id\n\n const queryEngine = ctx.container.resolve<QueryEngine>('queryEngine')\n const variantResult = await queryEngine.query(E.catalog.catalog_product_variant, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n filters: { id: { $eq: input.catalogVariantId } },\n fields: ['id', 'sku'],\n page: { page: 1, pageSize: 1 },\n })\n const firstItem: unknown = variantResult.items?.[0]\n const sku =\n typeof firstItem === 'object' && firstItem !== null\n ? String((firstItem as Record<string, unknown>).sku ?? '').trim()\n : ''\n if (!sku) {\n throw new CrudHttpError(422, { error: 'variant_sku_missing' })\n }\n\n // Use a client-side UUID so the lot entity can be persisted into the\n // surrounding transaction without a premature flush (defaultRaw would\n // otherwise require a DB round-trip to obtain the generated id).\n const lot = em.create(InventoryLot, {\n id: randomUUID(),\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n catalogVariantId: input.catalogVariantId,\n sku,\n lotNumber,\n status: 'available',\n })\n em.persist(lot)\n return lot.id\n}\n\nasync function listCandidateBalances(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n input: {\n warehouseId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n },\n scope: Scope,\n) {\n const where: Record<string, unknown> = {\n warehouse: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n deletedAt: null,\n }\n if (input.lotId) where.lot = input.lotId\n if (input.serialNumber) where.serialNumber = input.serialNumber\n const balances = await findWithDecryption(\n em,\n InventoryBalance,\n where,\n {\n populate: ['lot', 'location'],\n lockMode: LockMode.PESSIMISTIC_WRITE,\n orderBy: { createdAt: 'asc', id: 'asc' },\n },\n scope,\n )\n for (const balance of balances) {\n ensureTenantScope(ctx, balance.tenantId)\n ensureOrganizationScope(ctx, balance.organizationId)\n }\n return balances\n}\n\nasync function listBalancesForVariant(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n catalogVariantId: string,\n scope: Scope,\n) {\n const balances = await findWithDecryption(\n em,\n InventoryBalance,\n {\n catalogVariantId,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n for (const balance of balances) {\n ensureTenantScope(ctx, balance.tenantId)\n ensureOrganizationScope(ctx, balance.organizationId)\n }\n return balances\n}\n\nasync function emitLowStockEventIfNeeded(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n scope: Scope,\n catalogVariantId: string,\n) {\n const profile = await loadProfileForVariant(em, ctx, catalogVariantId, scope)\n if (!profile) return\n\n const balances = await listBalancesForVariant(em, ctx, catalogVariantId, scope)\n const availableQuantity = balances.reduce((total, balance) => total + getAvailableQuantity(balance), 0)\n const lowStock = evaluateLowStock(profile, availableQuantity)\n if (!lowStock) return\n\n await emitWmsEvent('wms.inventory.low_stock', {\n id: catalogVariantId,\n catalogVariantId,\n availableQuantity: lowStock.availableQuantity,\n reorderPoint: lowStock.reorderPoint,\n safetyStock: lowStock.safetyStock,\n state: lowStock.state,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n}\n\nasync function loadReceivedAtByBucket(\n em: EntityManager,\n balances: InventoryBalance[],\n scope: Scope,\n): Promise<Map<string, Date>> {\n if (balances.length === 0) return new Map()\n const locationIds = Array.from(\n new Set(\n balances.map((balance) => (typeof balance.location === 'string' ? balance.location : balance.location.id)),\n ),\n )\n const warehouseId = typeof balances[0].warehouse === 'string' ? balances[0].warehouse : balances[0].warehouse.id\n const catalogVariantId = balances[0].catalogVariantId\n const movements = await findWithDecryption(\n em,\n InventoryMovement,\n {\n warehouse: warehouseId,\n catalogVariantId,\n deletedAt: null,\n $or: [\n { locationFrom: { $in: locationIds } },\n { locationTo: { $in: locationIds } },\n ],\n },\n {\n orderBy: { receivedAt: 'asc' },\n },\n scope,\n )\n const map = new Map<string, Date>()\n for (const movement of movements) {\n const locationIdRaw = movement.locationTo ?? movement.locationFrom ?? null\n const locationId =\n typeof locationIdRaw === 'string'\n ? locationIdRaw\n : locationIdRaw?.id ?? null\n if (!locationId) continue\n const lotIdRaw = movement.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const key = buildBucketKey({\n warehouseId,\n locationId,\n catalogVariantId: movement.catalogVariantId,\n lotId,\n serialNumber: movement.serialNumber ?? null,\n })\n if (!map.has(key)) {\n map.set(key, movement.receivedAt)\n }\n }\n return map\n}\n\ntype BalanceSortRow = InventoryStrategyBucket & { balance: InventoryBalance }\n\nfunction sortBalancesForStrategy(\n balances: InventoryBalance[],\n strategy: InventoryStrategy,\n receiptMap: Map<string, Date>,\n): InventoryBalance[] {\n const rows: BalanceSortRow[] = balances.map((balance) => {\n const warehouseId = typeof balance.warehouse === 'string' ? balance.warehouse : balance.warehouse.id\n const locationId = typeof balance.location === 'string' ? balance.location : balance.location.id\n const lotIdRaw = balance.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const lot = typeof balance.lot === 'string' ? null : balance.lot\n return {\n balance,\n warehouseId,\n locationId,\n catalogVariantId: balance.catalogVariantId,\n createdAt: balance.createdAt,\n lotId,\n lotExpiresAt: lot?.expiresAt ?? null,\n serialNumber: balance.serialNumber ?? null,\n }\n })\n const sorted = sortBucketsForStrategy(rows, strategy, receiptMap)\n return sorted.map((row) => row.balance)\n}\n\nasync function resolveReservationStrategy(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n input: InventoryReservationCreateInput,\n scope: Scope,\n): Promise<InventoryStrategy> {\n const profile = await loadProfileForVariant(em, ctx, input.catalogVariantId, scope)\n return resolveReservationStrategyFromProfile(profile, input.strategy)\n}\n\nfunction requireSufficientAvailability(remaining: number) {\n if (remaining > 0.000001) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n}\n\nasync function findExactBalanceForUpdate(\n em: EntityManager,\n scope: Scope,\n input: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n },\n) {\n return findOneWithDecryption(\n em,\n InventoryBalance,\n {\n warehouse: input.warehouseId,\n location: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lot: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n deletedAt: null,\n },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n}\n\nasync function findReservationBucketBalance(\n em: EntityManager,\n scope: Scope,\n reservation: InventoryReservation,\n bucket: AllocationBucket,\n) {\n const warehouseId =\n typeof reservation.warehouse === 'string'\n ? reservation.warehouse\n : reservation.warehouse.id\n\n if (typeof bucket.balanceId === 'string' && bucket.balanceId.length > 0) {\n const balance = await findOneWithDecryption(\n em,\n InventoryBalance,\n { id: bucket.balanceId, deletedAt: null },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n if (balance) return balance\n }\n\n return findExactBalanceForUpdate(em, scope, {\n warehouseId,\n locationId: bucket.locationId,\n catalogVariantId: reservation.catalogVariantId,\n lotId: bucket.lotId ?? undefined,\n serialNumber: bucket.serialNumber ?? undefined,\n })\n}\n\nasync function upsertBalanceBucket(\n em: EntityManager,\n scope: Scope,\n input: {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n },\n): Promise<{ balance: InventoryBalance; created: boolean }> {\n const existing = await findExactBalanceForUpdate(em, scope, input)\n if (existing) return { balance: existing, created: false }\n const balance = em.create(InventoryBalance, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n warehouse: em.getReference(Warehouse, input.warehouseId),\n location: em.getReference(WarehouseLocation, input.locationId),\n catalogVariantId: input.catalogVariantId,\n lot: input.lotId ? em.getReference(InventoryLot, input.lotId) : null,\n serialNumber: input.serialNumber ?? null,\n quantityOnHand: '0',\n quantityReserved: '0',\n quantityAllocated: '0',\n metadata: null,\n })\n em.persist(balance)\n await em.flush()\n return { balance, created: true }\n}\n\nasync function resolveReceivedAtForBalance(\n em: EntityManager,\n balance: InventoryBalance | null,\n scope: Scope,\n fallback: Date,\n): Promise<Date> {\n if (!balance) return fallback\n const warehouseId = typeof balance.warehouse === 'string' ? balance.warehouse : balance.warehouse.id\n const locationId = typeof balance.location === 'string' ? balance.location : balance.location.id\n const lotIdRaw = balance.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const movement = await findOneWithDecryption(\n em,\n InventoryMovement,\n {\n warehouse: warehouseId,\n catalogVariantId: balance.catalogVariantId,\n lot: lotId,\n serialNumber: balance.serialNumber ?? null,\n deletedAt: null,\n $or: [\n { locationFrom: locationId },\n { locationTo: locationId },\n ],\n },\n { orderBy: { receivedAt: 'asc' } },\n scope,\n )\n return movement?.receivedAt ?? fallback\n}\n\nasync function createMovement(\n em: EntityManager,\n scope: Scope,\n input: {\n warehouseId: string\n locationFromId?: string | null\n locationToId?: string | null\n catalogVariantId: string\n lotId?: string | null\n serialNumber?: string | null\n quantity: number\n type: InventoryMovement['type']\n referenceType: InventoryMovement['referenceType']\n referenceId: string\n performedBy: string\n performedAt: Date\n receivedAt: Date\n reason?: string | null\n reasonCode?: string | null\n metadata?: Record<string, unknown> | null\n idempotencyKey: string\n },\n) {\n const movement = em.create(InventoryMovement, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n warehouse: em.getReference(Warehouse, input.warehouseId),\n locationFrom: input.locationFromId ? em.getReference(WarehouseLocation, input.locationFromId) : null,\n locationTo: input.locationToId ? em.getReference(WarehouseLocation, input.locationToId) : null,\n catalogVariantId: input.catalogVariantId,\n lot: input.lotId ? em.getReference(InventoryLot, input.lotId) : null,\n serialNumber: input.serialNumber ?? null,\n quantity: toNumericString(input.quantity),\n type: input.type,\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt: input.performedAt,\n receivedAt: input.receivedAt,\n reason: input.reason ?? null,\n reasonCode: input.reasonCode ?? null,\n metadata: input.metadata ?? null,\n idempotencyKey: input.idempotencyKey,\n })\n em.persist(movement)\n return movement\n}\n\ntype MovementMutationInput = {\n warehouseId: string\n locationFromId?: string | null\n locationToId?: string | null\n catalogVariantId: string\n lotId?: string | null\n serialNumber?: string | null\n quantity: number\n type: InventoryMovement['type']\n referenceType: InventoryMovement['referenceType']\n referenceId: string\n performedBy: string\n performedAt: Date\n receivedAt: Date\n reason?: string | null\n reasonCode?: string | null\n metadata?: Record<string, unknown> | null\n}\n\nasync function persistMovementWithIdempotency(\n em: EntityManager,\n scope: Scope,\n input: MovementMutationInput,\n): Promise<{ movement: InventoryMovement; idempotentReplay: boolean }> {\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n type: input.type,\n warehouseId: input.warehouseId,\n locationFromId: input.locationFromId,\n locationToId: input.locationToId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n quantity: input.quantity,\n })\n const existing = await findExistingMovementByIdempotencyKey(em, scope, idempotencyKey)\n if (existing) {\n return { movement: existing, idempotentReplay: true }\n }\n try {\n const movement = await createMovement(em, scope, {\n ...input,\n idempotencyKey,\n })\n return { movement, idempotentReplay: false }\n } catch (error) {\n if (!isUniqueConstraintError(error)) throw error\n const raced = await findExistingMovementByIdempotencyKey(em, scope, idempotencyKey)\n if (!raced) throw error\n return { movement: raced, idempotentReplay: true }\n }\n}\n\nasync function emitBalanceDriftIfNeeded(\n balance: InventoryBalance,\n field: 'quantityReserved' | 'quantityAllocated',\n attemptedValue: number,\n scope: Scope,\n reservationId: string,\n) {\n if (attemptedValue >= -0.000001) return\n await emitWmsEvent('wms.inventory.balance_drift', {\n id: balance.id,\n balanceId: balance.id,\n reservationId,\n field,\n attemptedValue: toNumericString(attemptedValue),\n clampedValue: '0',\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n}\n\nfunction enforceNonNegativeBalance(\n balance: InventoryBalance,\n field: 'quantityReserved' | 'quantityAllocated',\n nextValue: number,\n reservationId: string,\n scope: Scope,\n) {\n if (nextValue < -0.000001) {\n void emitBalanceDriftIfNeeded(balance, field, nextValue, scope, reservationId)\n throw new CrudHttpError(409, { error: 'balance_integrity_violation' })\n }\n setNumeric(balance as unknown as Record<string, unknown>, field, nextValue)\n}\n\nconst reserveInventoryCommand: CommandHandler<InventoryReservationCreateInput, ReservationCommandResult> = {\n id: 'wms.inventory.reserve',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReservationCreateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const reservationIdempotencyKey = buildReservationIdempotencyKey({\n sourceType: input.sourceType,\n sourceId: input.sourceId,\n catalogVariantId: input.catalogVariantId,\n warehouseId: input.warehouseId,\n quantity: input.quantity,\n })\n const existingReservation = await findExistingActiveReservationByIdempotencyKey(\n trx,\n scope,\n reservationIdempotencyKey,\n )\n if (existingReservation) {\n const metadata = extractReservationMetadata(existingReservation)\n const buckets = Array.isArray(metadata.allocatedBuckets)\n ? (metadata.allocatedBuckets as AllocationBucket[])\n : []\n return {\n reservationId: existingReservation.id,\n allocatedBuckets: serializeAllocationBuckets(buckets),\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n reservationEntity: existingReservation,\n touchedBalances: [] as InventoryBalance[],\n idempotentReplay: true,\n }\n }\n const strategy = await resolveReservationStrategy(trx, ctx, input, scope)\n const balances = await listCandidateBalances(trx, ctx, input, scope)\n const receiptMap = await loadReceivedAtByBucket(trx, balances, scope)\n const now = new Date()\n const ordered = sortBalancesForStrategy(\n balances.filter(\n (balance) => balanceHasEligibleLot(balance, now) && getAvailableQuantity(balance) > 0,\n ),\n strategy,\n receiptMap,\n )\n let remaining = input.quantity\n const buckets: AllocationBucket[] = []\n const touchedBalances: InventoryBalance[] = []\n for (const balance of ordered) {\n if (remaining <= 0) break\n const available = getAvailableQuantity(balance)\n if (available <= 0) continue\n const quantity = Math.min(available, remaining)\n const locationId = typeof balance.location === 'string' ? balance.location : balance.location.id\n const lotIdRaw = balance.lot ?? null\n const lotId = typeof lotIdRaw === 'string' ? lotIdRaw : lotIdRaw?.id ?? null\n const persistedBalance = await findExactBalanceForUpdate(trx, scope, {\n warehouseId: input.warehouseId,\n locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: lotId ?? undefined,\n serialNumber: balance.serialNumber ?? undefined,\n })\n if (!persistedBalance) {\n throw new CrudHttpError(409, { error: 'invalid_tracking_state' })\n }\n setNumeric(\n persistedBalance as unknown as Record<string, unknown>,\n 'quantityReserved',\n toNumber(persistedBalance.quantityReserved) + quantity,\n )\n touchedBalances.push(persistedBalance)\n buckets.push({\n balanceId: persistedBalance.id,\n locationId,\n lotId,\n serialNumber: balance.serialNumber ?? null,\n quantity,\n })\n remaining -= quantity\n }\n requireSufficientAvailability(remaining)\n let reservation: InventoryReservation\n try {\n reservation = trx.create(InventoryReservation, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n warehouse: trx.getReference(Warehouse, input.warehouseId),\n catalogVariantId: input.catalogVariantId,\n lot: buckets.length === 1 && buckets[0].lotId ? trx.getReference(InventoryLot, buckets[0].lotId) : null,\n serialNumber: buckets.length === 1 ? buckets[0].serialNumber : null,\n quantity: toNumericString(input.quantity),\n sourceType: input.sourceType,\n sourceId: input.sourceId,\n expiresAt: input.expiresAt ?? null,\n status: 'active',\n idempotencyKey: reservationIdempotencyKey,\n metadata: {\n ...(input.metadata ?? {}),\n allocatedBuckets: buckets,\n allocationState: 'reserved',\n strategy,\n },\n })\n trx.persist(reservation)\n await trx.flush()\n } catch (error) {\n if (!isUniqueConstraintError(error)) throw error\n const raced = await findExistingActiveReservationByIdempotencyKey(\n trx,\n scope,\n reservationIdempotencyKey,\n )\n if (!raced) throw error\n const metadata = extractReservationMetadata(raced)\n const racedBuckets = Array.isArray(metadata.allocatedBuckets)\n ? (metadata.allocatedBuckets as AllocationBucket[])\n : []\n return {\n reservationId: raced.id,\n allocatedBuckets: serializeAllocationBuckets(racedBuckets),\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n reservationEntity: raced,\n touchedBalances: [] as InventoryBalance[],\n idempotentReplay: true,\n }\n }\n return {\n reservationId: reservation.id,\n allocatedBuckets: serializeAllocationBuckets(buckets),\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n reservationEntity: reservation,\n touchedBalances,\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n reservations: [{ entity: result.reservationEntity, action: 'created' }],\n balances: result.touchedBalances.map((entity) => ({ entity, action: 'updated' as const })),\n })\n void emitWmsEvent('wms.inventory.reserved', {\n id: result.reservationId,\n reservationId: result.reservationId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return {\n reservationId: result.reservationId,\n allocatedBuckets: result.allocatedBuckets,\n }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.reserve',\n fallbackLabel: 'Reserve inventory',\n resourceKind: WMS_INVENTORY_RESERVATION_RESOURCE,\n resourceId: result?.reservationId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst releaseInventoryReservationCommand: CommandHandler<InventoryReservationReleaseInput, { reservationId: string }> = {\n id: 'wms.inventory.release',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReservationReleaseSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n const reservation = await requireReservation(trx, ctx, input.reservationId, scope, true)\n const metadata = extractReservationMetadata(reservation)\n const buckets = Array.isArray(metadata.allocatedBuckets) ? (metadata.allocatedBuckets as AllocationBucket[]) : []\n const allocationState = metadata.allocationState ?? 'reserved'\n const touchedBalances: InventoryBalance[] = []\n for (const bucket of buckets) {\n const balance = await findReservationBucketBalance(\n trx,\n scope,\n reservation,\n bucket,\n )\n if (!balance) continue\n if (allocationState === 'allocated') {\n enforceNonNegativeBalance(\n balance,\n 'quantityAllocated',\n toNumber(balance.quantityAllocated) - bucket.quantity,\n reservation.id,\n scope,\n )\n } else {\n enforceNonNegativeBalance(\n balance,\n 'quantityReserved',\n toNumber(balance.quantityReserved) - bucket.quantity,\n reservation.id,\n scope,\n )\n }\n touchedBalances.push(balance)\n }\n reservation.status = 'released'\n reservation.metadata = {\n ...metadata,\n releasedReason: input.reason,\n releasedAt: new Date().toISOString(),\n }\n await trx.flush()\n return {\n reservationId: reservation.id,\n warehouseId: typeof reservation.warehouse === 'string' ? reservation.warehouse : reservation.warehouse.id,\n catalogVariantId: reservation.catalogVariantId,\n quantity: reservation.quantity,\n tenantId: reservation.tenantId,\n organizationId: reservation.organizationId,\n reservationEntity: reservation,\n touchedBalances,\n }\n })\n await emitInventorySideEffects(ctx, {\n reservations: [{ entity: result.reservationEntity, action: 'updated' }],\n balances: result.touchedBalances.map((entity) => ({ entity, action: 'updated' as const })),\n })\n void emitWmsEvent('wms.inventory.released', {\n id: result.reservationId,\n reservationId: result.reservationId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: result.quantity,\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n return { reservationId: result.reservationId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.release',\n fallbackLabel: 'Release inventory reservation',\n resourceKind: WMS_INVENTORY_RESERVATION_RESOURCE,\n resourceId: result?.reservationId ?? input?.reservationId ?? null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst allocateInventoryReservationCommand: CommandHandler<InventoryReservationAllocateInput, { reservationId: string; allocationState: 'allocated' }> = {\n id: 'wms.inventory.allocate',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReservationAllocateSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n const reservation = await requireReservation(trx, ctx, input.reservationId, scope, true)\n if (reservation.status !== 'active') {\n throw new CrudHttpError(409, { error: 'invalid_reservation_state' })\n }\n const metadata = extractReservationMetadata(reservation)\n if (metadata.allocationState === 'allocated') {\n return {\n reservationId: reservation.id,\n allocationState: 'allocated' as const,\n warehouseId: typeof reservation.warehouse === 'string' ? reservation.warehouse : reservation.warehouse.id,\n catalogVariantId: reservation.catalogVariantId,\n quantity: reservation.quantity,\n tenantId: reservation.tenantId,\n organizationId: reservation.organizationId,\n reservationEntity: reservation,\n touchedBalances: [] as InventoryBalance[],\n }\n }\n const buckets = Array.isArray(metadata.allocatedBuckets) ? (metadata.allocatedBuckets as AllocationBucket[]) : []\n const touchedBalances: InventoryBalance[] = []\n for (const bucket of buckets) {\n const balance = await findReservationBucketBalance(\n trx,\n scope,\n reservation,\n bucket,\n )\n if (!balance) throw new CrudHttpError(409, { error: 'invalid_tracking_state' })\n if (toNumber(balance.quantityReserved) < bucket.quantity - 0.000001) {\n throw new CrudHttpError(409, { error: 'invalid_tracking_state' })\n }\n // Guard above ensures the subtraction is non-negative within numeric(16,4) precision.\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityReserved',\n toNumber(balance.quantityReserved) - bucket.quantity,\n )\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityAllocated',\n toNumber(balance.quantityAllocated) + bucket.quantity,\n )\n touchedBalances.push(balance)\n }\n reservation.metadata = {\n ...metadata,\n allocationState: 'allocated',\n allocatedAt: new Date().toISOString(),\n }\n await trx.flush()\n return {\n reservationId: reservation.id,\n allocationState: 'allocated' as const,\n warehouseId: typeof reservation.warehouse === 'string' ? reservation.warehouse : reservation.warehouse.id,\n catalogVariantId: reservation.catalogVariantId,\n quantity: reservation.quantity,\n tenantId: reservation.tenantId,\n organizationId: reservation.organizationId,\n reservationEntity: reservation,\n touchedBalances,\n }\n })\n await emitInventorySideEffects(ctx, {\n reservations: [{ entity: result.reservationEntity, action: 'updated' }],\n balances: result.touchedBalances.map((entity) => ({ entity, action: 'updated' as const })),\n })\n void emitWmsEvent('wms.inventory.allocated', {\n id: result.reservationId,\n reservationId: result.reservationId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: result.quantity,\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n return { reservationId: result.reservationId, allocationState: result.allocationState }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.allocate',\n fallbackLabel: 'Allocate inventory reservation',\n resourceKind: WMS_INVENTORY_RESERVATION_RESOURCE,\n resourceId: result?.reservationId ?? input?.reservationId ?? null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst adjustInventoryCommand: CommandHandler<InventoryAdjustInput, { movementId: string }> = {\n id: 'wms.inventory.adjust',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryAdjustSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const location = await requireLocation(trx, ctx, input.locationId, scope)\n const locationWarehouseId = typeof location.warehouse === 'string' ? location.warehouse : location.warehouse.id\n if (locationWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const { balance, created: balanceWasNew } = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const delta = input.delta\n const performedAt = input.performedAt ?? new Date()\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationToId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: delta,\n type: 'adjust',\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt: performedAt,\n reason: input.reason,\n reasonCode: input.reasonCode ?? null,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: delta,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n idempotentReplay: true,\n }\n }\n if (delta < 0 && getAvailableQuantity(balance) < Math.abs(delta) - 0.000001) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(balance.quantityOnHand) + delta,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n movementId: movement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: delta,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement,\n balanceEntity: balance,\n balanceAction: balanceWasNew ? ('created' as const) : ('updated' as const),\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: [{ entity: result.movementEntity, action: 'created' }],\n balances: [{ entity: result.balanceEntity, action: result.balanceAction }],\n })\n void emitWmsEvent('wms.inventory.adjusted', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return { movementId: result.movementId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.adjust',\n fallbackLabel: 'Adjust inventory',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst receiveInventoryCommand: CommandHandler<InventoryReceiveInput, { movementId: string }> = {\n id: 'wms.inventory.receive',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryReceiveSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const location = await requireLocation(trx, ctx, input.locationId, scope)\n const locationWarehouseId = typeof location.warehouse === 'string' ? location.warehouse : location.warehouse.id\n if (locationWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const profile = await loadProfileForVariant(trx, ctx, input.catalogVariantId, scope)\n const resolvedLotId = await resolveReceiveLotId(trx, ctx, scope, input)\n enforceInventoryTrackingRequirements(profile, {\n lotId: resolvedLotId ?? null,\n serialNumber: input.serialNumber ?? null,\n })\n const { balance, created: balanceWasNew } = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: resolvedLotId,\n serialNumber: input.serialNumber,\n })\n const receivedAt = input.receivedAt ?? input.performedAt ?? new Date()\n const performedAt = input.performedAt ?? receivedAt\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationToId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: resolvedLotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: input.quantity,\n type: 'receipt',\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt,\n reason: input.reason,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n idempotentReplay: true,\n }\n }\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(balance.quantityOnHand) + input.quantity,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n movementId: movement.id,\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement,\n balanceEntity: balance,\n balanceAction: balanceWasNew ? ('created' as const) : ('updated' as const),\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: [{ entity: result.movementEntity, action: 'created' }],\n balances: [{ entity: result.balanceEntity, action: result.balanceAction }],\n })\n void emitWmsEvent('wms.inventory.received', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n locationId: result.locationId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return { movementId: result.movementId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.receive',\n fallbackLabel: 'Receive inventory',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst moveInventoryCommand: CommandHandler<InventoryMoveInput, { movementId: string }> = {\n id: 'wms.inventory.move',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryMoveSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const sourceLocation = await requireLocation(trx, ctx, input.fromLocationId, scope)\n const targetLocation = await requireLocation(trx, ctx, input.toLocationId, scope)\n const sourceWarehouseId = typeof sourceLocation.warehouse === 'string' ? sourceLocation.warehouse : sourceLocation.warehouse.id\n const targetWarehouseId = typeof targetLocation.warehouse === 'string' ? targetLocation.warehouse : targetLocation.warehouse.id\n if (sourceWarehouseId !== input.warehouseId || targetWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const sourceResult = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.fromLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const sourceBalance = sourceResult.balance\n const sourceBalanceAction = sourceResult.created ? ('created' as const) : ('updated' as const)\n const targetResult = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.toLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const targetBalance = targetResult.balance\n const targetBalanceAction = targetResult.created ? ('created' as const) : ('updated' as const)\n const performedAt = input.performedAt ?? new Date()\n const receivedAt = await resolveReceivedAtForBalance(trx, sourceBalance, scope, performedAt)\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationFromId: input.fromLocationId,\n locationToId: input.toLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: input.quantity,\n type: input.type ?? 'transfer',\n referenceType: input.referenceType,\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt,\n reason: input.reason,\n reasonCode: input.reasonCode ?? null,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balances: [\n { entity: sourceBalance, action: sourceBalanceAction },\n { entity: targetBalance, action: targetBalanceAction },\n ] as AffectedBalance[],\n idempotentReplay: true,\n }\n }\n if (getAvailableQuantity(sourceBalance) < input.quantity - 0.000001) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n setNumeric(\n sourceBalance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(sourceBalance.quantityOnHand) - input.quantity,\n )\n setNumeric(\n targetBalance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n toNumber(targetBalance.quantityOnHand) + input.quantity,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n movementId: movement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n quantity: input.quantity,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement,\n balances: [\n { entity: sourceBalance, action: sourceBalanceAction },\n { entity: targetBalance, action: targetBalanceAction },\n ] as AffectedBalance[],\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: [{ entity: result.movementEntity, action: 'created' }],\n balances: result.balances,\n })\n void emitWmsEvent('wms.inventory.moved', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n quantity: toNumericString(result.quantity),\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n return { movementId: result.movementId }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.move',\n fallbackLabel: 'Move inventory',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nconst cycleCountInventoryCommand: CommandHandler<InventoryCycleCountInput, { adjustmentDelta: string; movementId?: string | null }> = {\n id: 'wms.inventory.cycleCount',\n // See \"WMS Inventory Mutation Commands \u2014 Undo Policy\" at top of file.\n isUndoable: false,\n async execute(rawInput, ctx) {\n const input = inventoryCycleCountSchema.parse(rawInput ?? {})\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const em = resolveEm(ctx)\n const result = await runInTransaction(em, async (trx) => {\n const scope = resolveScope(ctx, input)\n await requireWarehouse(trx, ctx, input.warehouseId, scope)\n const location = await requireLocation(trx, ctx, input.locationId, scope)\n const locationWarehouseId = typeof location.warehouse === 'string' ? location.warehouse : location.warehouse.id\n if (locationWarehouseId !== input.warehouseId) {\n throw new CrudHttpError(422, { error: 'invalid_location' })\n }\n const { balance, created: balanceWasNew } = await upsertBalanceBucket(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n const currentOnHand = toNumber(balance.quantityOnHand)\n const delta = input.countedQuantity - currentOnHand\n if (delta === 0) {\n return {\n adjustmentDelta: '0',\n movementId: null as string | null,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: null as InventoryMovement | null,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n }\n }\n if (!input.autoAdjust) {\n throw new CrudHttpError(422, { error: 'auto_adjust_required' })\n }\n const performedAt = input.performedAt ?? new Date()\n const receivedAt = await resolveReceivedAtForBalance(trx, balance, scope, performedAt)\n const movementInput: MovementMutationInput = {\n warehouseId: input.warehouseId,\n locationToId: input.locationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId ?? null,\n serialNumber: input.serialNumber ?? null,\n quantity: delta,\n type: 'cycle_count',\n referenceType: 'manual',\n referenceId: input.referenceId,\n performedBy: input.performedBy,\n performedAt,\n receivedAt,\n reason: input.reason,\n metadata: input.metadata ?? null,\n }\n const idempotencyKey = buildMovementIdempotencyKey({\n referenceType: movementInput.referenceType,\n referenceId: movementInput.referenceId,\n type: movementInput.type,\n warehouseId: movementInput.warehouseId,\n locationFromId: movementInput.locationFromId,\n locationToId: movementInput.locationToId,\n catalogVariantId: movementInput.catalogVariantId,\n lotId: movementInput.lotId,\n serialNumber: movementInput.serialNumber,\n quantity: movementInput.quantity,\n })\n const existingMovement = await findExistingMovementByIdempotencyKey(trx, scope, idempotencyKey)\n if (existingMovement) {\n return {\n adjustmentDelta: toNumericString(delta),\n movementId: existingMovement.id,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: existingMovement,\n balanceEntity: balance,\n balanceAction: ('updated' as const),\n idempotentReplay: true,\n }\n }\n setNumeric(\n balance as unknown as Record<string, unknown>,\n 'quantityOnHand',\n input.countedQuantity,\n )\n const { movement } = await persistMovementWithIdempotency(trx, scope, movementInput)\n await trx.flush()\n return {\n adjustmentDelta: toNumericString(delta),\n movementId: movement.id as string | null,\n warehouseId: input.warehouseId,\n catalogVariantId: input.catalogVariantId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n movementEntity: movement as InventoryMovement | null,\n balanceEntity: balance,\n balanceAction: balanceWasNew ? ('created' as const) : ('updated' as const),\n idempotentReplay: false,\n }\n })\n if (!result.idempotentReplay) {\n await emitInventorySideEffects(ctx, {\n movements: result.movementEntity ? [{ entity: result.movementEntity, action: 'created' }] : [],\n balances: [{ entity: result.balanceEntity, action: result.balanceAction }],\n })\n if (result.movementId) {\n void emitWmsEvent('wms.inventory.reconciled', {\n id: result.movementId,\n movementId: result.movementId,\n warehouseId: result.warehouseId,\n catalogVariantId: result.catalogVariantId,\n adjustmentDelta: result.adjustmentDelta,\n tenantId: result.tenantId,\n organizationId: result.organizationId,\n }).catch(() => undefined)\n void emitLowStockEventIfNeeded(\n resolveEm(ctx),\n ctx,\n { tenantId: result.tenantId, organizationId: result.organizationId },\n result.catalogVariantId,\n ).catch(() => undefined)\n }\n }\n return {\n adjustmentDelta: result.adjustmentDelta,\n movementId: result.movementId ?? null,\n }\n },\n buildLog: async ({ input, result, ctx }) =>\n buildMutationLog({\n actionKey: 'wms.audit.inventory.cycleCount',\n fallbackLabel: 'Run cycle count reconciliation',\n resourceKind: WMS_INVENTORY_MOVEMENT_RESOURCE,\n resourceId: result?.movementId ?? null,\n parentResourceId:\n input?.warehouseId && input?.catalogVariantId\n ? `${input.warehouseId}:${input.catalogVariantId}`\n : null,\n tenantId: input?.tenantId ?? ctx.auth?.tenantId ?? null,\n organizationId: input?.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n cacheAliases: [WMS_INVENTORY_BALANCE_RESOURCE],\n }),\n}\n\nregisterCommand(reserveInventoryCommand)\nregisterCommand(releaseInventoryReservationCommand)\nregisterCommand(allocateInventoryReservationCommand)\nregisterCommand(adjustInventoryCommand)\nregisterCommand(receiveInventoryCommand)\nregisterCommand(moveInventoryCommand)\nregisterCommand(cycleCountInventoryCommand)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["buckets"]
|
|
7
7
|
}
|
|
@@ -30,6 +30,12 @@ const inventoryReservationCrudIndexer = {
|
|
|
30
30
|
const inventoryMovementCrudIndexer = {
|
|
31
31
|
entityType: E.wms.inventory_movement
|
|
32
32
|
};
|
|
33
|
+
const warehouseZoneCrudIndexer = {
|
|
34
|
+
entityType: E.wms.warehouse_zone
|
|
35
|
+
};
|
|
36
|
+
const warehouseCrudIndexer = {
|
|
37
|
+
entityType: E.wms.warehouse
|
|
38
|
+
};
|
|
33
39
|
const inventoryBalanceCrudEvents = {
|
|
34
40
|
module: "wms",
|
|
35
41
|
entity: "inventory_balance",
|
|
@@ -77,6 +83,8 @@ export {
|
|
|
77
83
|
inventoryReservationCrudIndexer,
|
|
78
84
|
normalizeOptionalString,
|
|
79
85
|
requireId,
|
|
80
|
-
toNumericString
|
|
86
|
+
toNumericString,
|
|
87
|
+
warehouseCrudIndexer,
|
|
88
|
+
warehouseZoneCrudIndexer
|
|
81
89
|
};
|
|
82
90
|
//# sourceMappingURL=shared.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/wms/commands/shared.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { ensureOrganizationScope } from '@open-mercato/shared/lib/commands/scope'\nimport type { CrudIndexerConfig, CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport {\n InventoryBalance,\n InventoryMovement,\n InventoryReservation,\n} from '../data/entities'\n\nexport function ensureTenantScope(ctx: CommandRuntimeContext, tenantId: string): void {\n const currentTenant = ctx.auth?.tenantId ?? null\n if (currentTenant && currentTenant !== tenantId) {\n throw new CrudHttpError(403, { error: 'Forbidden' })\n }\n}\n\nexport function requireId(id: string | null | undefined, label: string): string {\n if (typeof id === 'string' && id.trim().length > 0) return id.trim()\n throw new CrudHttpError(400, { error: `${label} id is required.` })\n}\n\nexport function normalizeOptionalString(value: string | null | undefined): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\nexport function toNumericString(value: number | string | null | undefined, fallback = '0'): string {\n if (typeof value === 'string' && value.trim().length > 0) return value.trim()\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n return fallback\n}\n\n// CRUD indexer configs \u2014 used by emitCrudSideEffects to drive query_index updates.\n// Cache invalidation cross-aliases (e.g. balance lists invalidated when a reservation mutates)\n// are declared in command-level metadata.context.cacheAliases so the command bus picks them up.\nexport const inventoryBalanceCrudIndexer: CrudIndexerConfig<InventoryBalance> = {\n entityType: E.wms.inventory_balance,\n}\n\nexport const inventoryReservationCrudIndexer: CrudIndexerConfig<InventoryReservation> = {\n entityType: E.wms.inventory_reservation,\n}\n\nexport const inventoryMovementCrudIndexer: CrudIndexerConfig<InventoryMovement> = {\n entityType: E.wms.inventory_movement,\n}\n\nexport const inventoryBalanceCrudEvents: CrudEventsConfig<InventoryBalance> = {\n module: 'wms',\n entity: 'inventory_balance',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nexport const inventoryReservationCrudEvents: CrudEventsConfig<InventoryReservation> = {\n module: 'wms',\n entity: 'inventory_reservation',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nexport const inventoryMovementCrudEvents: CrudEventsConfig<InventoryMovement> = {\n module: 'wms',\n entity: 'inventory_movement',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\n// Cache alias resource kinds used to extend command-level cache invalidation\n// when a single mutation impacts multiple list resources.\nexport const WMS_INVENTORY_BALANCE_RESOURCE = 'wms.inventoryBalance'\nexport const WMS_INVENTORY_RESERVATION_RESOURCE = 'wms.inventoryReservation'\nexport const WMS_INVENTORY_MOVEMENT_RESOURCE = 'wms.inventoryMovement'\n\nexport { ensureOrganizationScope }\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,qBAAqB;AAC9B,SAAS,+BAA+B;AAExC,SAAS,SAAS;
|
|
4
|
+
"sourcesContent": ["import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { ensureOrganizationScope } from '@open-mercato/shared/lib/commands/scope'\nimport type { CrudIndexerConfig, CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport {\n InventoryBalance,\n InventoryMovement,\n InventoryReservation,\n Warehouse,\n WarehouseZone,\n} from '../data/entities'\n\nexport function ensureTenantScope(ctx: CommandRuntimeContext, tenantId: string): void {\n const currentTenant = ctx.auth?.tenantId ?? null\n if (currentTenant && currentTenant !== tenantId) {\n throw new CrudHttpError(403, { error: 'Forbidden' })\n }\n}\n\nexport function requireId(id: string | null | undefined, label: string): string {\n if (typeof id === 'string' && id.trim().length > 0) return id.trim()\n throw new CrudHttpError(400, { error: `${label} id is required.` })\n}\n\nexport function normalizeOptionalString(value: string | null | undefined): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\nexport function toNumericString(value: number | string | null | undefined, fallback = '0'): string {\n if (typeof value === 'string' && value.trim().length > 0) return value.trim()\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n return fallback\n}\n\n// CRUD indexer configs \u2014 used by emitCrudSideEffects to drive query_index updates.\n// Cache invalidation cross-aliases (e.g. balance lists invalidated when a reservation mutates)\n// are declared in command-level metadata.context.cacheAliases so the command bus picks them up.\nexport const inventoryBalanceCrudIndexer: CrudIndexerConfig<InventoryBalance> = {\n entityType: E.wms.inventory_balance,\n}\n\nexport const inventoryReservationCrudIndexer: CrudIndexerConfig<InventoryReservation> = {\n entityType: E.wms.inventory_reservation,\n}\n\nexport const inventoryMovementCrudIndexer: CrudIndexerConfig<InventoryMovement> = {\n entityType: E.wms.inventory_movement,\n}\n\n// Zones are read through the hybrid query engine, which projects `cf:*` out of\n// `entity_indexes` rather than joining `custom_field_values`. Without this indexer the\n// zone commands write custom field values that no read path can ever see (#5239).\nexport const warehouseZoneCrudIndexer: CrudIndexerConfig<WarehouseZone> = {\n entityType: E.wms.warehouse_zone,\n}\n\n// Warehouse list/search goes through the hybrid query engine. Writing a custom\n// field upserts `entity_indexes`; delete must tombstone that row. A leftover\n// live index document makes `indexAnyRows` true and hides later warehouses that\n// were never indexed (empty combobox on the same integration shard).\nexport const warehouseCrudIndexer: CrudIndexerConfig<Warehouse> = {\n entityType: E.wms.warehouse,\n}\n\nexport const inventoryBalanceCrudEvents: CrudEventsConfig<InventoryBalance> = {\n module: 'wms',\n entity: 'inventory_balance',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nexport const inventoryReservationCrudEvents: CrudEventsConfig<InventoryReservation> = {\n module: 'wms',\n entity: 'inventory_reservation',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nexport const inventoryMovementCrudEvents: CrudEventsConfig<InventoryMovement> = {\n module: 'wms',\n entity: 'inventory_movement',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\n// Cache alias resource kinds used to extend command-level cache invalidation\n// when a single mutation impacts multiple list resources.\nexport const WMS_INVENTORY_BALANCE_RESOURCE = 'wms.inventoryBalance'\nexport const WMS_INVENTORY_RESERVATION_RESOURCE = 'wms.inventoryReservation'\nexport const WMS_INVENTORY_MOVEMENT_RESOURCE = 'wms.inventoryMovement'\n\nexport { ensureOrganizationScope }\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,qBAAqB;AAC9B,SAAS,+BAA+B;AAExC,SAAS,SAAS;AASX,SAAS,kBAAkB,KAA4B,UAAwB;AACpF,QAAM,gBAAgB,IAAI,MAAM,YAAY;AAC5C,MAAI,iBAAiB,kBAAkB,UAAU;AAC/C,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,EACrD;AACF;AAEO,SAAS,UAAU,IAA+B,OAAuB;AAC9E,MAAI,OAAO,OAAO,YAAY,GAAG,KAAK,EAAE,SAAS,EAAG,QAAO,GAAG,KAAK;AACnE,QAAM,IAAI,cAAc,KAAK,EAAE,OAAO,GAAG,KAAK,mBAAmB,CAAC;AACpE;AAEO,SAAS,wBAAwB,OAAiD;AACvF,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEO,SAAS,gBAAgB,OAA2C,WAAW,KAAa;AACjG,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO,MAAM,KAAK;AAC5E,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO,OAAO,KAAK;AAC5E,SAAO;AACT;AAKO,MAAM,8BAAmE;AAAA,EAC9E,YAAY,EAAE,IAAI;AACpB;AAEO,MAAM,kCAA2E;AAAA,EACtF,YAAY,EAAE,IAAI;AACpB;AAEO,MAAM,+BAAqE;AAAA,EAChF,YAAY,EAAE,IAAI;AACpB;AAKO,MAAM,2BAA6D;AAAA,EACxE,YAAY,EAAE,IAAI;AACpB;AAMO,MAAM,uBAAqD;AAAA,EAChE,YAAY,EAAE,IAAI;AACpB;AAEO,MAAM,6BAAiE;AAAA,EAC5E,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAEO,MAAM,iCAAyE;AAAA,EACpF,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAEO,MAAM,8BAAmE;AAAA,EAC9E,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAIO,MAAM,iCAAiC;AACvC,MAAM,qCAAqC;AAC3C,MAAM,kCAAkC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|