@open-mercato/core 0.9.1-develop.7519.1.38f51f8dbb → 0.9.1-develop.7536.1.f9a5776a07

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.
Files changed (105) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/api/logout.js +14 -6
  3. package/dist/modules/auth/api/logout.js.map +2 -2
  4. package/dist/modules/auth/api/session/refresh.js +6 -1
  5. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  6. package/dist/modules/catalog/ai-tools/mutation-pack.js +10 -5
  7. package/dist/modules/catalog/ai-tools/mutation-pack.js.map +2 -2
  8. package/dist/modules/catalog/ai-tools/types.js.map +2 -2
  9. package/dist/modules/currencies/backend/currencies/[id]/page.js +5 -2
  10. package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
  11. package/dist/modules/currencies/commands/currencies.js +399 -137
  12. package/dist/modules/currencies/commands/currencies.js.map +2 -2
  13. package/dist/modules/currencies/lib/seeds.js +2 -0
  14. package/dist/modules/currencies/lib/seeds.js.map +2 -2
  15. package/dist/modules/customer_accounts/api/login.js +14 -7
  16. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  17. package/dist/modules/customer_accounts/services/customerUserService.js +10 -10
  18. package/dist/modules/customer_accounts/services/customerUserService.js.map +2 -2
  19. package/dist/modules/customers/commands/companies.js +10 -3
  20. package/dist/modules/customers/commands/companies.js.map +2 -2
  21. package/dist/modules/customers/commands/interactionRestoreDetails.js +75 -0
  22. package/dist/modules/customers/commands/interactionRestoreDetails.js.map +7 -0
  23. package/dist/modules/customers/commands/people.js +10 -3
  24. package/dist/modules/customers/commands/people.js.map +2 -2
  25. package/dist/modules/forms/api/distributions/[distributionId]/invitations/[invitationId]/route.js +1 -1
  26. package/dist/modules/forms/api/distributions/[distributionId]/invitations/[invitationId]/route.js.map +1 -1
  27. package/dist/modules/forms/api/form-submissions/[id]/submit/route.js +12 -2
  28. package/dist/modules/forms/api/form-submissions/[id]/submit/route.js.map +2 -2
  29. package/dist/modules/forms/api/form-submissions/route.js +16 -1
  30. package/dist/modules/forms/api/form-submissions/route.js.map +2 -2
  31. package/dist/modules/forms/api/public/submissions/[id]/submit/route.js +6 -1
  32. package/dist/modules/forms/api/public/submissions/[id]/submit/route.js.map +2 -2
  33. package/dist/modules/forms/api/runtime-helpers.js +16 -0
  34. package/dist/modules/forms/api/runtime-helpers.js.map +2 -2
  35. package/dist/modules/forms/data/validators.js.map +2 -2
  36. package/dist/modules/forms/lib/portal-subject-policy.js +17 -0
  37. package/dist/modules/forms/lib/portal-subject-policy.js.map +7 -0
  38. package/dist/modules/forms/lib/runtime-principal.js +27 -10
  39. package/dist/modules/forms/lib/runtime-principal.js.map +2 -2
  40. package/dist/modules/forms/services/distribution-service.js +35 -13
  41. package/dist/modules/forms/services/distribution-service.js.map +2 -2
  42. package/dist/modules/forms/services/submission-service.js +4 -0
  43. package/dist/modules/forms/services/submission-service.js.map +2 -2
  44. package/dist/modules/staff/commands/leave-requests.js +54 -24
  45. package/dist/modules/staff/commands/leave-requests.js.map +2 -2
  46. package/dist/modules/warranty_claims/api/portal/attachments/route.js +19 -7
  47. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  48. package/dist/modules/warranty_claims/commands/claims.js +1 -1
  49. package/dist/modules/warranty_claims/commands/claims.js.map +2 -2
  50. package/dist/modules/warranty_claims/subscribers/return-shipment-tracking.js +6 -6
  51. package/dist/modules/warranty_claims/subscribers/return-shipment-tracking.js.map +2 -2
  52. package/dist/modules/wms/commands/inventory-actions.js +19 -3
  53. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  54. package/dist/modules/workflows/lib/async-activity-wait.js +43 -0
  55. package/dist/modules/workflows/lib/async-activity-wait.js.map +7 -0
  56. package/dist/modules/workflows/lib/parallel-handler.js +20 -14
  57. package/dist/modules/workflows/lib/parallel-handler.js.map +2 -2
  58. package/dist/modules/workflows/lib/workflow-executor.js +21 -23
  59. package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
  60. package/package.json +7 -7
  61. package/src/modules/auth/api/logout.ts +15 -6
  62. package/src/modules/auth/api/session/refresh.ts +6 -1
  63. package/src/modules/catalog/ai-tools/mutation-pack.ts +14 -5
  64. package/src/modules/catalog/ai-tools/types.ts +1 -0
  65. package/src/modules/currencies/backend/currencies/[id]/page.tsx +5 -1
  66. package/src/modules/currencies/commands/currencies.ts +475 -168
  67. package/src/modules/currencies/i18n/de.json +4 -0
  68. package/src/modules/currencies/i18n/en.json +4 -0
  69. package/src/modules/currencies/i18n/es.json +4 -0
  70. package/src/modules/currencies/i18n/ko.json +4 -0
  71. package/src/modules/currencies/i18n/pl.json +4 -0
  72. package/src/modules/currencies/lib/seeds.ts +2 -0
  73. package/src/modules/customer_accounts/api/login.ts +15 -7
  74. package/src/modules/customer_accounts/services/customerUserService.ts +34 -10
  75. package/src/modules/customers/commands/companies.ts +16 -4
  76. package/src/modules/customers/commands/interactionRestoreDetails.ts +110 -0
  77. package/src/modules/customers/commands/people.ts +16 -4
  78. package/src/modules/forms/api/distributions/[distributionId]/invitations/[invitationId]/route.ts +1 -1
  79. package/src/modules/forms/api/form-submissions/[id]/submit/route.ts +16 -3
  80. package/src/modules/forms/api/form-submissions/route.ts +21 -2
  81. package/src/modules/forms/api/public/submissions/[id]/submit/route.ts +7 -0
  82. package/src/modules/forms/api/runtime-helpers.ts +16 -0
  83. package/src/modules/forms/data/validators.ts +2 -1
  84. package/src/modules/forms/i18n/de.json +1 -0
  85. package/src/modules/forms/i18n/en.json +1 -0
  86. package/src/modules/forms/i18n/es.json +1 -0
  87. package/src/modules/forms/i18n/ko.json +1 -0
  88. package/src/modules/forms/i18n/pl.json +1 -0
  89. package/src/modules/forms/lib/portal-subject-policy.ts +42 -0
  90. package/src/modules/forms/lib/runtime-principal.ts +35 -11
  91. package/src/modules/forms/services/distribution-service.ts +35 -13
  92. package/src/modules/forms/services/submission-service.ts +12 -0
  93. package/src/modules/staff/commands/leave-requests.ts +54 -23
  94. package/src/modules/staff/i18n/de.json +2 -0
  95. package/src/modules/staff/i18n/en.json +2 -0
  96. package/src/modules/staff/i18n/es.json +2 -0
  97. package/src/modules/staff/i18n/ko.json +2 -0
  98. package/src/modules/staff/i18n/pl.json +2 -0
  99. package/src/modules/warranty_claims/api/portal/attachments/route.ts +20 -8
  100. package/src/modules/warranty_claims/commands/claims.ts +1 -1
  101. package/src/modules/warranty_claims/subscribers/return-shipment-tracking.ts +5 -5
  102. package/src/modules/wms/commands/inventory-actions.ts +30 -10
  103. package/src/modules/workflows/lib/async-activity-wait.ts +71 -0
  104. package/src/modules/workflows/lib/parallel-handler.ts +24 -15
  105. package/src/modules/workflows/lib/workflow-executor.ts +24 -27
@@ -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 loadEffectiveProfileForVariant(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n catalogVariantId: string,\n scope: Scope,\n) {\n const variantProfile = await loadProfileForVariant(em, ctx, catalogVariantId, scope)\n if (variantProfile) return variantProfile\n const rows = await em.getConnection().execute<Array<{ product_id: string | null }>>(\n `select product_id from catalog_product_variants\n where id = ? and organization_id = ? and tenant_id = ? and deleted_at is null\n limit 1`,\n [catalogVariantId, scope.organizationId, scope.tenantId],\n )\n const catalogProductId = rows[0]?.product_id\n if (!catalogProductId) return null\n const productProfile = await findOneWithDecryption(\n em,\n ProductInventoryProfile,\n {\n catalogProductId,\n catalogVariantId: null,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n if (!productProfile) return null\n ensureTenantScope(ctx, productProfile.tenantId)\n ensureOrganizationScope(ctx, productProfile.organizationId)\n return productProfile\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 loadEffectiveProfileForVariant(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 if (delta < 0 && getAvailableQuantity(balance) < Math.abs(delta) - 0.000001) {\n throw new CrudHttpError(409, {\n error: 'insufficient_stock',\n countedQuantity: toNumericString(input.countedQuantity),\n committedQuantity: toNumericString(\n toNumber(balance.quantityReserved) + toNumber(balance.quantityAllocated),\n ),\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 loadEffectiveProfileForVariant(\n em: EntityManager,\n ctx: CommandRuntimeContext,\n catalogVariantId: string,\n scope: Scope,\n) {\n const variantProfile = await loadProfileForVariant(em, ctx, catalogVariantId, scope)\n if (variantProfile) return variantProfile\n const rows = await em.getConnection().execute<Array<{ product_id: string | null }>>(\n `select product_id from catalog_product_variants\n where id = ? and organization_id = ? and tenant_id = ? and deleted_at is null\n limit 1`,\n [catalogVariantId, scope.organizationId, scope.tenantId],\n )\n const catalogProductId = rows[0]?.product_id\n if (!catalogProductId) return null\n const productProfile = await findOneWithDecryption(\n em,\n ProductInventoryProfile,\n {\n catalogProductId,\n catalogVariantId: null,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n },\n undefined,\n scope,\n )\n if (!productProfile) return null\n ensureTenantScope(ctx, productProfile.tenantId)\n ensureOrganizationScope(ctx, productProfile.organizationId)\n return productProfile\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 loadEffectiveProfileForVariant(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\ntype BalanceBucketInput = {\n warehouseId: string\n locationId: string\n catalogVariantId: string\n lotId?: string\n serialNumber?: string\n}\n\nconst BALANCE_BUCKET_CREATE_LOCK_SQL = 'select pg_advisory_xact_lock(hashtextextended(?, 0))'\n\nfunction balanceBucketCreateLockKey(input: BalanceBucketInput): string {\n return [\n 'wms:inventory-balance-bucket',\n input.warehouseId.toLowerCase(),\n input.locationId.toLowerCase(),\n input.catalogVariantId.toLowerCase(),\n input.lotId?.toLowerCase() ?? '',\n input.serialNumber ?? '',\n ].join(':')\n}\n\nasync function upsertBalanceBucket(\n em: EntityManager,\n scope: Scope,\n input: BalanceBucketInput,\n): Promise<{ balance: InventoryBalance; created: boolean }> {\n const existing = await findExactBalanceForUpdate(em, scope, input)\n if (existing) return { balance: existing, created: false }\n await em.execute(BALANCE_BUCKET_CREATE_LOCK_SQL, [balanceBucketCreateLockKey(input)])\n const createdConcurrently = await findExactBalanceForUpdate(em, scope, input)\n if (createdConcurrently) return { balance: createdConcurrently, 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 sourceBalance = await findExactBalanceForUpdate(trx, scope, {\n warehouseId: input.warehouseId,\n locationId: input.fromLocationId,\n catalogVariantId: input.catalogVariantId,\n lotId: input.lotId,\n serialNumber: input.serialNumber,\n })\n if (!sourceBalance) {\n throw new CrudHttpError(409, { error: 'insufficient_stock' })\n }\n const sourceBalanceAction = '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 if (delta < 0 && getAvailableQuantity(balance) < Math.abs(delta) - 0.000001) {\n throw new CrudHttpError(409, {\n error: 'insufficient_stock',\n countedQuantity: toNumericString(input.countedQuantity),\n committedQuantity: toNumericString(\n toNumber(balance.quantityReserved) + toNumber(balance.quantityAllocated),\n ),\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
  }
@@ -0,0 +1,43 @@
1
+ const ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES = ["ACTIVITY_COMPLETED", "ACTIVITY_FAILED"];
2
+ function readPendingAsyncJobIds(pending) {
3
+ if (!Array.isArray(pending)) return [];
4
+ const jobIds = [];
5
+ for (const entry of pending) {
6
+ const jobId = entry && typeof entry === "object" ? entry.jobId : void 0;
7
+ if (typeof jobId === "string" && jobId.length > 0 && !jobIds.includes(jobId)) jobIds.push(jobId);
8
+ }
9
+ return jobIds;
10
+ }
11
+ function resolveAsyncActivityWait(pendingJobIds, events) {
12
+ const completedByJob = /* @__PURE__ */ new Map();
13
+ const failedByJob = /* @__PURE__ */ new Map();
14
+ for (const event of events) {
15
+ const jobId = event.eventData?.jobId;
16
+ if (typeof jobId !== "string") continue;
17
+ if (event.eventType === "ACTIVITY_COMPLETED") completedByJob.set(jobId, event);
18
+ else if (event.eventType === "ACTIVITY_FAILED") failedByJob.set(jobId, event);
19
+ }
20
+ const completed = [];
21
+ const failed = [];
22
+ let settled = true;
23
+ for (const jobId of pendingJobIds) {
24
+ const completion = completedByJob.get(jobId);
25
+ if (completion) {
26
+ completed.push(completion);
27
+ continue;
28
+ }
29
+ const failure = failedByJob.get(jobId);
30
+ if (failure) {
31
+ failed.push(failure);
32
+ continue;
33
+ }
34
+ settled = false;
35
+ }
36
+ return { settled, completed, failed };
37
+ }
38
+ export {
39
+ ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES,
40
+ readPendingAsyncJobIds,
41
+ resolveAsyncActivityWait
42
+ };
43
+ //# sourceMappingURL=async-activity-wait.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/workflows/lib/async-activity-wait.ts"],
4
+ "sourcesContent": ["/**\n * Async-activity wait resolution, PURE.\n *\n * A transition that queues async activities parks its token (instance or\n * branch) and records the queue job ids it is waiting for in\n * `_pendingAsyncActivities`. The worker logs one `ACTIVITY_COMPLETED` /\n * `ACTIVITY_FAILED` event per delivery attempt, keyed by `jobId`, and the event\n * log keeps every earlier wait's events. The wait is therefore decided by the\n * outcome of exactly the jobs it queued \u2014 one outcome per job \u2014 and never by\n * events of an earlier wait, an earlier attempt of the run, or a duplicate\n * delivery. A job with a completed attempt counts as completed; otherwise any\n * logged failed attempt counts as its failure, whether or not the queue retries\n * it later. `events` must be in log order: the last event per job and outcome\n * is the one used.\n */\n\nexport const ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES = ['ACTIVITY_COMPLETED', 'ACTIVITY_FAILED'] as const\n\nexport type AsyncActivityOutcomeEvent = {\n eventType: string\n eventData: Record<string, unknown> | null | undefined\n}\n\nexport type AsyncActivityWaitResolution<TEvent extends AsyncActivityOutcomeEvent> = {\n settled: boolean\n completed: TEvent[]\n failed: TEvent[]\n}\n\nexport function readPendingAsyncJobIds(pending: unknown): string[] {\n if (!Array.isArray(pending)) return []\n const jobIds: string[] = []\n for (const entry of pending) {\n const jobId = entry && typeof entry === 'object' ? (entry as { jobId?: unknown }).jobId : undefined\n if (typeof jobId === 'string' && jobId.length > 0 && !jobIds.includes(jobId)) jobIds.push(jobId)\n }\n return jobIds\n}\n\nexport function resolveAsyncActivityWait<TEvent extends AsyncActivityOutcomeEvent>(\n pendingJobIds: readonly string[],\n events: readonly TEvent[],\n): AsyncActivityWaitResolution<TEvent> {\n const completedByJob = new Map<string, TEvent>()\n const failedByJob = new Map<string, TEvent>()\n for (const event of events) {\n const jobId = event.eventData?.jobId\n if (typeof jobId !== 'string') continue\n if (event.eventType === 'ACTIVITY_COMPLETED') completedByJob.set(jobId, event)\n else if (event.eventType === 'ACTIVITY_FAILED') failedByJob.set(jobId, event)\n }\n\n const completed: TEvent[] = []\n const failed: TEvent[] = []\n let settled = true\n for (const jobId of pendingJobIds) {\n const completion = completedByJob.get(jobId)\n if (completion) {\n completed.push(completion)\n continue\n }\n const failure = failedByJob.get(jobId)\n if (failure) {\n failed.push(failure)\n continue\n }\n settled = false\n }\n\n return { settled, completed, failed }\n}\n"],
5
+ "mappings": "AAgBO,MAAM,qCAAqC,CAAC,sBAAsB,iBAAiB;AAanF,SAAS,uBAAuB,SAA4B;AACjE,MAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,QAAO,CAAC;AACrC,QAAM,SAAmB,CAAC;AAC1B,aAAW,SAAS,SAAS;AAC3B,UAAM,QAAQ,SAAS,OAAO,UAAU,WAAY,MAA8B,QAAQ;AAC1F,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO,KAAK,KAAK;AAAA,EACjG;AACA,SAAO;AACT;AAEO,SAAS,yBACd,eACA,QACqC;AACrC,QAAM,iBAAiB,oBAAI,IAAoB;AAC/C,QAAM,cAAc,oBAAI,IAAoB;AAC5C,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,MAAM,WAAW;AAC/B,QAAI,OAAO,UAAU,SAAU;AAC/B,QAAI,MAAM,cAAc,qBAAsB,gBAAe,IAAI,OAAO,KAAK;AAAA,aACpE,MAAM,cAAc,kBAAmB,aAAY,IAAI,OAAO,KAAK;AAAA,EAC9E;AAEA,QAAM,YAAsB,CAAC;AAC7B,QAAM,SAAmB,CAAC;AAC1B,MAAI,UAAU;AACd,aAAW,SAAS,eAAe;AACjC,UAAM,aAAa,eAAe,IAAI,KAAK;AAC3C,QAAI,YAAY;AACd,gBAAU,KAAK,UAAU;AACzB;AAAA,IACF;AACA,UAAM,UAAU,YAAY,IAAI,KAAK;AACrC,QAAI,SAAS;AACX,aAAO,KAAK,OAAO;AACnB;AAAA,IACF;AACA,cAAU;AAAA,EACZ;AAEA,SAAO,EAAE,SAAS,WAAW,OAAO;AACtC;",
6
+ "names": []
7
+ }