@open-mercato/core 0.10.1-develop.7749.1.ea3edf75e3 → 0.10.1-develop.7752.1.fd7c06569b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/dist/modules/api_keys/services/principalService.js +3 -2
- package/dist/modules/api_keys/services/principalService.js.map +2 -2
- package/dist/modules/api_keys/services/sessionKeyRoles.js +29 -0
- package/dist/modules/api_keys/services/sessionKeyRoles.js.map +7 -0
- package/dist/modules/auth/cli.js +13 -2
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/services/rbacService.js +18 -10
- package/dist/modules/auth/services/rbacService.js.map +2 -2
- package/dist/modules/business_rules/lib/action-executor.js +2 -1
- package/dist/modules/business_rules/lib/action-executor.js.map +2 -2
- package/dist/modules/directory/utils/organizationScope.js +11 -4
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/subscribers/seed-tenant-encryption-maps-retry.js +14 -0
- package/dist/modules/entities/subscribers/seed-tenant-encryption-maps-retry.js.map +7 -0
- package/dist/modules/entities/subscribers/seed-tenant-encryption-maps.js +37 -0
- package/dist/modules/entities/subscribers/seed-tenant-encryption-maps.js.map +7 -0
- package/dist/modules/warranty_claims/commands/claim-lines.js +25 -1
- package/dist/modules/warranty_claims/commands/claim-lines.js.map +3 -3
- package/dist/modules/warranty_claims/commands/claims.js +19 -1
- package/dist/modules/warranty_claims/commands/claims.js.map +2 -2
- package/dist/modules/warranty_claims/commands/shared.js +30 -0
- package/dist/modules/warranty_claims/commands/shared.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/api_keys/services/principalService.ts +3 -2
- package/src/modules/api_keys/services/sessionKeyRoles.ts +35 -0
- package/src/modules/auth/cli.ts +11 -4
- package/src/modules/auth/services/rbacService.ts +22 -9
- package/src/modules/business_rules/lib/action-executor.ts +2 -3
- package/src/modules/directory/utils/organizationScope.ts +11 -4
- package/src/modules/entities/subscribers/seed-tenant-encryption-maps-retry.ts +12 -0
- package/src/modules/entities/subscribers/seed-tenant-encryption-maps.ts +38 -0
- package/src/modules/warranty_claims/commands/claim-lines.ts +26 -1
- package/src/modules/warranty_claims/commands/claims.ts +19 -1
- package/src/modules/warranty_claims/commands/shared.ts +36 -1
- package/src/modules/warranty_claims/i18n/de.json +1 -0
- package/src/modules/warranty_claims/i18n/en.json +1 -0
- package/src/modules/warranty_claims/i18n/es.json +1 -0
- package/src/modules/warranty_claims/i18n/ko.json +1 -0
- package/src/modules/warranty_claims/i18n/pl.json +1 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/warranty_claims/commands/claim-lines.ts"],
|
|
4
|
-
"sourcesContent": ["import { randomUUID } from 'crypto'\nimport { LockMode } from '@mikro-orm/core'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { registerCommand, type CommandHandler, type CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { invalidateCrudCache } from '@open-mercato/shared/lib/crud/cache'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { E } from '#generated/entities.ids.generated'\nimport { WarrantyClaim, WarrantyClaimLine } from '../data/entities'\nimport {\n claimLineCreateSchema,\n claimLineReceiveSchema,\n claimLineReleaseQuarantineSchema,\n claimLineUpdateSchema,\n type ClaimLineCreateInput,\n type ClaimLineReceiveInput,\n type ClaimLineReleaseQuarantineInput,\n type ClaimLineUpdateInput,\n type WarrantyClaimDisposition,\n type WarrantyClaimLineStatus,\n type WarrantyClaimWarrantyStatus,\n} from '../data/validators'\nimport { emitWarrantyClaimsEvent } from '../events'\nimport {\n assertDispositionAllowedForGrade,\n suggestedDispositionForGrade,\n type ConditionGrade,\n} from '../lib/grading'\nimport { assertDispositionAllowedForType, resolveClaimTypeUiConfig } from '../lib/claimTypeConfig'\nimport { resolveEffectiveWarrantyClaimSettings } from '../lib/settings'\nimport { computeHeaderRollups, lineStatusGuards } from '../lib/stateMachine'\nimport {\n WARRANTY_CLAIM_LINE_RESOURCE_KIND,\n WARRANTY_CLAIM_RESOURCE_KIND,\n appendClaimEvent,\n enforceWarrantyClaimOptimisticLock,\n ensureOrganizationScope,\n ensureTenantScope,\n extractUndoPayload,\n requireScopedClaim,\n throwUndoRefusal,\n type WarrantyClaimScope,\n} from './shared'\nimport { assertPendingClaimQuantitiesWithinSold, validateClaimReferences } from './claims'\n\nconst claimCrudEvents: CrudEventsConfig = {\n module: 'warranty_claims',\n entity: 'claim',\n persistent: true,\n}\n\nconst lineDeleteSchema = z\n .object({\n id: z.string().uuid(),\n claimId: z.string().uuid().optional(),\n organizationId: z.string().uuid().optional(),\n tenantId: z.string().uuid().optional(),\n })\n .strict()\n\ntype LineDeleteInput = z.infer<typeof lineDeleteSchema>\n\nconst lineSetAssessmentSchema = z\n .object({\n id: z.string().uuid(),\n organizationId: z.string().uuid().optional(),\n tenantId: z.string().uuid().optional(),\n assessmentPayload: z.record(z.string(), z.unknown()),\n updatedAt: z.union([z.string().datetime(), z.date()]).nullable().optional(),\n })\n .strict()\n\ntype LineSetAssessmentInput = z.infer<typeof lineSetAssessmentSchema>\n\ntype ScopeInput = {\n organizationId?: string | null\n tenantId?: string | null\n}\n\ntype LineSnapshot = {\n id: string\n claimId: string\n organizationId: string\n tenantId: string\n lineNo: number\n productId: string | null\n variantId: string | null\n sku: string | null\n productName: string | null\n orderLineId: string | null\n serialNumber: string | null\n lotNumber: string | null\n purchaseDate: string | null\n warrantyMonths: number | null\n warrantyExpiresAt: string | null\n warrantyStatus: WarrantyClaimWarrantyStatus\n faultCode: string | null\n faultDescription: string | null\n qtyClaimed: string\n qtyApproved: string | null\n qtyReceived: string | null\n conditionOnReceipt: string | null\n conditionGrade: string | null\n quarantineStatus: string\n inspectionNotes: string | null\n assessmentPayload: Record<string, unknown> | null\n disposition: WarrantyClaimDisposition | null\n lineStatus: WarrantyClaimLineStatus\n creditAmount: string | null\n restockingFee: string | null\n coreChargeAmount: string | null\n coreCreditAmount: string | null\n vendorClaimLineId: string | null\n vendorName: string | null\n deletedAt: string | null\n updatedAt: string | null\n}\n\ntype LineUndoPayload = {\n before?: LineSnapshot | null\n after?: LineSnapshot | null\n}\n\nconst mutableParentStatuses = new Set([\n 'draft',\n 'submitted',\n 'in_review',\n 'info_requested',\n 'approved',\n 'received',\n 'inspecting',\n])\n\nconst receivingParentStatuses = new Set(['received', 'inspecting'])\n\ntype LineUndoParentRule = {\n allowedParentStatuses: ReadonlySet<string>\n lockedKey: string\n lockedFallback: string\n}\n\ntype LineUndoState = {\n claim: WarrantyClaim\n line: WarrantyClaimLine\n}\n\nconst mutableParentUndoRule: LineUndoParentRule = {\n allowedParentStatuses: mutableParentStatuses,\n lockedKey: 'warranty_claims.errors.lineLocked',\n lockedFallback: 'This line is locked in the current claim status.',\n}\n\nconst receivingParentUndoRule: LineUndoParentRule = {\n allowedParentStatuses: receivingParentStatuses,\n lockedKey: 'warranty_claims.errors.receivingStatusInvalid',\n lockedFallback: 'Receiving details can only be saved when the claim is received or under inspection.',\n}\n\nfunction parseCommandInput<T>(schema: z.ZodType<T>, rawInput: unknown): T {\n const result = schema.safeParse(rawInput ?? {})\n if (!result.success) {\n throw new CrudHttpError(400, { error: '[internal] invalid warranty claim line command input' })\n }\n return result.data\n}\n\nfunction hasOwn(input: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(input, key)\n}\n\nfunction resolveScope(ctx: CommandRuntimeContext, input: ScopeInput): WarrantyClaimScope {\n const tenantId = input.tenantId ?? ctx.auth?.tenantId ?? null\n const organizationId = input.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n if (!tenantId) throw new CrudHttpError(400, { error: '[internal] tenant scope required for warranty claim line command' })\n if (!organizationId) throw new CrudHttpError(400, { error: '[internal] organization scope required for warranty claim line command' })\n ensureTenantScope(ctx, tenantId)\n ensureOrganizationScope(ctx, organizationId)\n return { tenantId, organizationId }\n}\n\nfunction toIso(value: Date | string | null | undefined): string | null {\n if (!value) return null\n const date = value instanceof Date ? value : new Date(value)\n return Number.isNaN(date.getTime()) ? null : date.toISOString()\n}\n\nfunction toDate(value: string | null): Date | null {\n if (!value) return null\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction toDateOnlyIso(value: Date | string | null | undefined): string | null {\n const iso = toIso(value)\n return iso ? iso.slice(0, 10) : null\n}\n\nfunction toDateOnly(value: string | null): Date | null {\n if (!value) return null\n const date = new Date(`${value}T00:00:00.000Z`)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction amountString(value: number | string | null | undefined, fallback = '0'): string | null {\n if (value === null) return null\n if (value === undefined) return fallback\n const parsed = typeof value === 'number' ? value : Number(value)\n if (!Number.isFinite(parsed)) return fallback\n return String(parsed)\n}\n\nfunction nullableAmountString(value: number | string | null | undefined): string | null {\n if (value === undefined || value === null) return null\n return amountString(value, '0')\n}\n\nfunction numberValue(value: string | number | null | undefined): number {\n if (value === null || value === undefined) return 0\n const parsed = typeof value === 'number' ? value : Number(value)\n return Number.isFinite(parsed) ? parsed : 0\n}\n\nfunction addMonths(date: Date, months: number): Date {\n const target = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1))\n const lastDay = new Date(Date.UTC(target.getUTCFullYear(), target.getUTCMonth() + 1, 0)).getUTCDate()\n const copy = new Date(date.getTime())\n copy.setUTCDate(1)\n copy.setUTCFullYear(target.getUTCFullYear(), target.getUTCMonth(), Math.min(date.getUTCDate(), lastDay))\n return copy\n}\n\nfunction computeWarrantyDates(\n purchaseDate: Date | null | undefined,\n warrantyMonths: number | null | undefined,\n): { warrantyExpiresAt: Date | null; warrantyStatus: WarrantyClaimWarrantyStatus } {\n if (!purchaseDate || warrantyMonths === null || warrantyMonths === undefined) {\n return { warrantyExpiresAt: null, warrantyStatus: 'unknown' }\n }\n const warrantyExpiresAt = addMonths(purchaseDate, warrantyMonths)\n const warrantyStatus = warrantyExpiresAt.getTime() >= Date.now() ? 'in_warranty' : 'out_of_warranty'\n return { warrantyExpiresAt, warrantyStatus }\n}\n\nfunction claimIdOf(line: WarrantyClaimLine): string {\n const claim = line.claim\n if (typeof claim === 'object' && claim && 'id' in claim && typeof claim.id === 'string') return claim.id\n return String(claim)\n}\n\nfunction claimOf(line: WarrantyClaimLine): WarrantyClaim | null {\n const claim = line.claim\n if (typeof claim === 'object' && claim && 'id' in claim && typeof claim.id === 'string') return claim as WarrantyClaim\n return null\n}\n\nfunction sameDateValue(left: Date | null | undefined, right: Date | null | undefined): boolean {\n const leftTime = left instanceof Date ? left.getTime() : null\n const rightTime = right instanceof Date ? right.getTime() : null\n return leftTime === rightTime\n}\n\nfunction assertParentMutable(claim: WarrantyClaim): void {\n if (!mutableParentStatuses.has(claim.status)) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n}\n\nfunction assertReceivingStatus(claim: WarrantyClaim): void {\n if (claim.status !== 'received' && claim.status !== 'inspecting') {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.receivingStatusInvalid' })\n }\n}\n\nfunction toConditionGrade(value: string | null | undefined): ConditionGrade | null {\n if (value === 'A' || value === 'B' || value === 'C' || value === 'D') return value\n return null\n}\n\nfunction assertLineQuantities(line: WarrantyClaimLine): void {\n const qtyClaimed = numberValue(line.qtyClaimed)\n const qtyApproved = line.qtyApproved === null || line.qtyApproved === undefined ? null : numberValue(line.qtyApproved)\n const qtyReceived = line.qtyReceived === null || line.qtyReceived === undefined ? null : numberValue(line.qtyReceived)\n if (qtyClaimed < 0 || (qtyApproved !== null && qtyApproved < 0) || (qtyReceived !== null && qtyReceived < 0)) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n if (qtyApproved !== null && qtyApproved > qtyClaimed) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n if (qtyReceived !== null && qtyReceived > qtyClaimed) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n}\n\nfunction assertLineStatusMove(from: WarrantyClaimLineStatus, to: WarrantyClaimLineStatus): void {\n if (from === to) return\n if (lineStatusGuards[from].includes(to)) return\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.invalidTransition' })\n}\n\nfunction buildLineCreateData(\n claim: WarrantyClaim,\n input: ClaimLineCreateInput,\n lineNo: number,\n): Partial<WarrantyClaimLine> & {\n id: string\n claim: WarrantyClaim\n organizationId: string\n tenantId: string\n lineNo: number\n qtyClaimed: string\n lineStatus: WarrantyClaimLineStatus\n warrantyStatus: WarrantyClaimWarrantyStatus\n createdAt: Date\n updatedAt: Date\n} {\n const purchaseDate = input.purchaseDate ?? null\n const warrantyMonths = input.warrantyMonths ?? null\n const computedWarranty = computeWarrantyDates(purchaseDate, warrantyMonths)\n return {\n id: randomUUID(),\n claim,\n organizationId: claim.organizationId,\n tenantId: claim.tenantId,\n lineNo,\n productId: input.productId ?? null,\n variantId: input.variantId ?? null,\n sku: input.sku ?? null,\n productName: input.productName ?? null,\n orderLineId: input.orderLineId ?? null,\n serialNumber: input.serialNumber ?? null,\n lotNumber: input.lotNumber ?? null,\n purchaseDate,\n warrantyMonths,\n warrantyExpiresAt: input.warrantyExpiresAt ?? computedWarranty.warrantyExpiresAt,\n warrantyStatus: input.warrantyStatus ?? computedWarranty.warrantyStatus,\n faultCode: input.faultCode ?? null,\n faultDescription: input.faultDescription ?? null,\n qtyClaimed: amountString(input.qtyClaimed, '1') ?? '1',\n qtyApproved: nullableAmountString(input.qtyApproved),\n qtyReceived: nullableAmountString(input.qtyReceived),\n conditionOnReceipt: input.conditionOnReceipt ?? null,\n inspectionNotes: input.inspectionNotes ?? null,\n disposition: input.disposition ?? null,\n vendorName: input.vendorName ?? null,\n lineStatus: 'pending',\n creditAmount: nullableAmountString(input.creditAmount),\n restockingFee: nullableAmountString(input.restockingFee),\n coreChargeAmount: nullableAmountString(input.coreChargeAmount),\n coreCreditAmount: nullableAmountString(input.coreCreditAmount),\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n}\n\nfunction applyLineUpdate(line: WarrantyClaimLine, input: ClaimLineUpdateInput): void {\n const purchaseDateChanged = hasOwn(input, 'purchaseDate') && !sameDateValue(line.purchaseDate ?? null, input.purchaseDate ?? null)\n const warrantyMonthsChanged = hasOwn(input, 'warrantyMonths') && (line.warrantyMonths ?? null) !== (input.warrantyMonths ?? null)\n const hasExplicitWarranty = hasOwn(input, 'warrantyExpiresAt') || hasOwn(input, 'warrantyStatus')\n if (hasOwn(input, 'lineNo') && input.lineNo !== undefined) line.lineNo = input.lineNo\n if (hasOwn(input, 'productId')) line.productId = input.productId ?? null\n if (hasOwn(input, 'variantId')) line.variantId = input.variantId ?? null\n if (hasOwn(input, 'sku')) line.sku = input.sku ?? null\n if (hasOwn(input, 'productName')) line.productName = input.productName ?? null\n if (hasOwn(input, 'orderLineId')) line.orderLineId = input.orderLineId ?? null\n if (hasOwn(input, 'serialNumber')) line.serialNumber = input.serialNumber ?? null\n if (hasOwn(input, 'lotNumber')) line.lotNumber = input.lotNumber ?? null\n if (hasOwn(input, 'purchaseDate')) line.purchaseDate = input.purchaseDate ?? null\n if (hasOwn(input, 'warrantyMonths')) line.warrantyMonths = input.warrantyMonths ?? null\n if (hasOwn(input, 'warrantyExpiresAt')) line.warrantyExpiresAt = input.warrantyExpiresAt ?? null\n if (hasOwn(input, 'warrantyStatus') && input.warrantyStatus) line.warrantyStatus = input.warrantyStatus\n if (hasOwn(input, 'faultCode')) line.faultCode = input.faultCode ?? null\n if (hasOwn(input, 'faultDescription')) line.faultDescription = input.faultDescription ?? null\n if (hasOwn(input, 'qtyClaimed') && input.qtyClaimed !== undefined) line.qtyClaimed = amountString(input.qtyClaimed, '1') ?? '1'\n if (hasOwn(input, 'qtyApproved')) line.qtyApproved = nullableAmountString(input.qtyApproved)\n if (hasOwn(input, 'qtyReceived')) line.qtyReceived = nullableAmountString(input.qtyReceived)\n if (hasOwn(input, 'conditionOnReceipt')) line.conditionOnReceipt = input.conditionOnReceipt ?? null\n if (hasOwn(input, 'inspectionNotes')) line.inspectionNotes = input.inspectionNotes ?? null\n if (hasOwn(input, 'disposition')) line.disposition = input.disposition ?? null\n if (hasOwn(input, 'vendorName')) line.vendorName = input.vendorName ?? null\n if (hasOwn(input, 'lineStatus') && input.lineStatus) {\n assertLineStatusMove(line.lineStatus, input.lineStatus)\n line.lineStatus = input.lineStatus\n }\n if (hasOwn(input, 'creditAmount')) line.creditAmount = nullableAmountString(input.creditAmount)\n if (hasOwn(input, 'restockingFee')) line.restockingFee = nullableAmountString(input.restockingFee)\n if (hasOwn(input, 'coreChargeAmount')) line.coreChargeAmount = nullableAmountString(input.coreChargeAmount)\n if (hasOwn(input, 'coreCreditAmount')) line.coreCreditAmount = nullableAmountString(input.coreCreditAmount)\n if ((purchaseDateChanged || warrantyMonthsChanged) && !hasExplicitWarranty) {\n const computedWarranty = computeWarrantyDates(line.purchaseDate ?? null, line.warrantyMonths ?? null)\n line.warrantyExpiresAt = computedWarranty.warrantyExpiresAt\n line.warrantyStatus = computedWarranty.warrantyStatus\n }\n line.updatedAt = new Date()\n}\n\nfunction snapshotLine(line: WarrantyClaimLine): LineSnapshot {\n return {\n id: line.id,\n claimId: claimIdOf(line),\n organizationId: line.organizationId,\n tenantId: line.tenantId,\n lineNo: line.lineNo,\n productId: line.productId ?? null,\n variantId: line.variantId ?? null,\n sku: line.sku ?? null,\n productName: line.productName ?? null,\n orderLineId: line.orderLineId ?? null,\n serialNumber: line.serialNumber ?? null,\n lotNumber: line.lotNumber ?? null,\n purchaseDate: toDateOnlyIso(line.purchaseDate),\n warrantyMonths: line.warrantyMonths ?? null,\n warrantyExpiresAt: toDateOnlyIso(line.warrantyExpiresAt),\n warrantyStatus: line.warrantyStatus,\n faultCode: line.faultCode ?? null,\n faultDescription: line.faultDescription ?? null,\n qtyClaimed: line.qtyClaimed,\n qtyApproved: line.qtyApproved ?? null,\n qtyReceived: line.qtyReceived ?? null,\n conditionOnReceipt: line.conditionOnReceipt ?? null,\n conditionGrade: line.conditionGrade ?? null,\n quarantineStatus: line.quarantineStatus,\n inspectionNotes: line.inspectionNotes ?? null,\n assessmentPayload: line.assessmentPayload ?? null,\n disposition: line.disposition ?? null,\n lineStatus: line.lineStatus,\n creditAmount: line.creditAmount ?? null,\n restockingFee: line.restockingFee ?? null,\n coreChargeAmount: line.coreChargeAmount ?? null,\n coreCreditAmount: line.coreCreditAmount ?? null,\n vendorClaimLineId: line.vendorClaimLineId ?? null,\n vendorName: line.vendorName ?? null,\n deletedAt: toIso(line.deletedAt),\n updatedAt: toIso(line.updatedAt),\n }\n}\n\nasync function loadLineSnapshot(\n em: EntityManager,\n lineId: string,\n scope: WarrantyClaimScope,\n): Promise<LineSnapshot | null> {\n const line = await findOneWithDecryption(\n em,\n WarrantyClaimLine,\n { id: lineId, tenantId: scope.tenantId, organizationId: scope.organizationId },\n { populate: ['claim'] },\n scope,\n )\n return line ? snapshotLine(line) : null\n}\n\nfunction restoreLineFromSnapshot(line: WarrantyClaimLine, snapshot: LineSnapshot): void {\n line.lineNo = snapshot.lineNo\n line.productId = snapshot.productId\n line.variantId = snapshot.variantId\n line.sku = snapshot.sku\n line.productName = snapshot.productName\n line.orderLineId = snapshot.orderLineId\n line.serialNumber = snapshot.serialNumber\n line.lotNumber = snapshot.lotNumber\n line.purchaseDate = toDateOnly(snapshot.purchaseDate)\n line.warrantyMonths = snapshot.warrantyMonths\n line.warrantyExpiresAt = toDateOnly(snapshot.warrantyExpiresAt)\n line.warrantyStatus = snapshot.warrantyStatus\n line.faultCode = snapshot.faultCode\n line.faultDescription = snapshot.faultDescription\n line.qtyClaimed = snapshot.qtyClaimed\n line.qtyApproved = snapshot.qtyApproved\n line.qtyReceived = snapshot.qtyReceived\n line.conditionOnReceipt = snapshot.conditionOnReceipt\n line.conditionGrade = snapshot.conditionGrade\n line.quarantineStatus = snapshot.quarantineStatus\n line.inspectionNotes = snapshot.inspectionNotes\n line.assessmentPayload = snapshot.assessmentPayload\n line.disposition = snapshot.disposition\n line.lineStatus = snapshot.lineStatus\n line.creditAmount = snapshot.creditAmount\n line.restockingFee = snapshot.restockingFee\n line.coreChargeAmount = snapshot.coreChargeAmount\n line.coreCreditAmount = snapshot.coreCreditAmount\n line.vendorClaimLineId = snapshot.vendorClaimLineId\n line.vendorName = snapshot.vendorName\n line.deletedAt = toDate(snapshot.deletedAt)\n line.updatedAt = new Date()\n}\n\nasync function recomputeClaimRollups(em: EntityManager, claim: WarrantyClaim): Promise<void> {\n const lines = await findWithDecryption(\n em,\n WarrantyClaimLine,\n {\n claim: claim.id,\n tenantId: claim.tenantId,\n organizationId: claim.organizationId,\n deletedAt: null,\n },\n {},\n { tenantId: claim.tenantId, organizationId: claim.organizationId },\n )\n const totals = computeHeaderRollups(lines, { claimType: claim.claimType })\n claim.totalClaimedAmount = String(totals.totalClaimedAmount)\n claim.totalApprovedAmount = String(totals.totalApprovedAmount)\n claim.updatedAt = new Date()\n}\n\nfunction refuseLineUndoConflict(): Promise<never> {\n return throwUndoRefusal('warranty_claims.errors.conflict', 'This claim changed while you were editing it.')\n}\n\nasync function requireCurrentLineUndoState(\n em: EntityManager,\n after: LineSnapshot | null | undefined,\n rule: LineUndoParentRule,\n): Promise<LineUndoState> {\n if (!after) return refuseLineUndoConflict()\n const scope: WarrantyClaimScope = { tenantId: after.tenantId, organizationId: after.organizationId }\n const claim = await findOneWithDecryption(\n em,\n WarrantyClaim,\n { id: after.claimId, tenantId: scope.tenantId, organizationId: scope.organizationId, deletedAt: null },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n if (!claim) return refuseLineUndoConflict()\n if (!rule.allowedParentStatuses.has(claim.status)) return throwUndoRefusal(rule.lockedKey, rule.lockedFallback)\n const line = await findOneWithDecryption(\n em,\n WarrantyClaimLine,\n { id: after.id, tenantId: scope.tenantId, organizationId: scope.organizationId },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n if (!line || !after.updatedAt || toIso(line.updatedAt) !== after.updatedAt) return refuseLineUndoConflict()\n return { claim, line }\n}\n\nasync function requireScopedLine(\n em: EntityManager,\n lineId: string,\n scope: WarrantyClaimScope,\n): Promise<WarrantyClaimLine> {\n const line = await findOneWithDecryption(\n em,\n WarrantyClaimLine,\n { id: lineId, tenantId: scope.tenantId, organizationId: scope.organizationId, deletedAt: null },\n { populate: ['claim'] },\n scope,\n )\n if (!line) throw new CrudHttpError(404, { error: 'warranty_claims.errors.notFound' })\n return line\n}\n\nasync function emitClaimUpdated(ctx: CommandRuntimeContext, claim: WarrantyClaim): Promise<void> {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: claim,\n identifiers: { id: claim.id, organizationId: claim.organizationId, tenantId: claim.tenantId },\n indexer: { entityType: E.warranty_claims.warranty_claim },\n events: claimCrudEvents,\n })\n await invalidateCrudCache(\n ctx.container,\n 'warranty_claims.claim',\n { id: claim.id, organizationId: claim.organizationId, tenantId: claim.tenantId },\n ctx.auth?.tenantId ?? null,\n 'warranty_claims.claim_line.rollup',\n )\n}\n\nasync function emitLineCrud(\n ctx: CommandRuntimeContext,\n action: 'created' | 'updated' | 'deleted',\n line: WarrantyClaimLine,\n): Promise<void> {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action,\n entity: line,\n identifiers: { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n indexer: { entityType: E.warranty_claims.warranty_claim_line },\n })\n await invalidateCrudCache(\n ctx.container,\n 'warranty_claims.claim_line',\n { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n ctx.auth?.tenantId ?? null,\n `warranty_claims.claim_line.${action}`,\n )\n}\n\nasync function emitLineUndoCrud(\n ctx: CommandRuntimeContext,\n action: 'created' | 'updated' | 'deleted',\n line: WarrantyClaimLine,\n): Promise<void> {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action,\n entity: line,\n identifiers: { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n indexer: { entityType: E.warranty_claims.warranty_claim_line },\n })\n await invalidateCrudCache(\n ctx.container,\n 'warranty_claims.claim_line',\n { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n ctx.auth?.tenantId ?? null,\n `warranty_claims.claim_line.undo.${action}`,\n )\n}\n\nasync function buildLineLog(\n actionLabelKey: string,\n actionLabelFallback: string,\n resourceId: string,\n snapshots: { before?: unknown; after?: unknown },\n): Promise<{\n actionLabel: string\n resourceKind: string\n resourceId: string\n parentResourceKind: string | null\n parentResourceId: string | null\n tenantId: string | null\n organizationId: string | null\n snapshotBefore: unknown\n snapshotAfter: unknown\n payload: { undo: LineUndoPayload }\n}> {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as LineSnapshot | null | undefined\n const before = snapshots.before as LineSnapshot | null | undefined\n return {\n actionLabel: translate(actionLabelKey, actionLabelFallback),\n resourceKind: WARRANTY_CLAIM_LINE_RESOURCE_KIND,\n resourceId,\n parentResourceKind: WARRANTY_CLAIM_RESOURCE_KIND,\n parentResourceId: after?.claimId ?? before?.claimId ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n snapshotAfter: after ?? null,\n payload: { undo: { before: before ?? null, after: after ?? null } },\n }\n}\n\nconst createClaimLineCommand: CommandHandler<ClaimLineCreateInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.create',\n isUndoable: true,\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineCreateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const claim = await requireScopedClaim(em, input.claimId, scope)\n assertDispositionAllowedForType(claim.claimType, input.disposition ?? null)\n await enforceWarrantyClaimOptimisticLock(ctx, claim)\n assertParentMutable(claim)\n let line!: WarrantyClaimLine\n let nextLineNo = input.lineNo ?? 1\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE, refresh: true })\n assertParentMutable(claim)\n if (input.orderLineId) {\n await validateClaimReferences(ctx, scope, {\n lineOrderRefs: [{ orderLineId: input.orderLineId, orderId: claim.orderId ?? null }],\n })\n }\n const existingLines = await findWithDecryption(\n em,\n WarrantyClaimLine,\n {\n claim: claim.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n {},\n scope,\n )\n if (input.orderLineId) {\n await assertPendingClaimQuantitiesWithinSold(em, scope, new Map([[input.orderLineId, [{\n orderLineId: input.orderLineId,\n qtyClaimed: amountString(input.qtyClaimed, '1') ?? '1',\n }]]]), { currentClaimId: claim.id })\n }\n nextLineNo = input.lineNo ?? existingLines.reduce((max, entry) => Math.max(max, entry.lineNo), 0) + 1\n },\n () => {\n line = em.create(WarrantyClaimLine, buildLineCreateData(claim, input, nextLineNo))\n assertLineQuantities(line)\n em.persist(line)\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.create' })\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'created', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineCreateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.create', 'Add claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n },\n () => {\n state.line.deletedAt = new Date()\n state.line.updatedAt = new Date()\n },\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.create.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'deleted', state.line)\n },\n}\n\nconst updateClaimLineCommand: CommandHandler<ClaimLineUpdateInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.update',\n isUndoable: true,\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(claimLineUpdateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineUpdateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = claimOf(line) ?? await requireScopedClaim(em, input.claimId ?? claimIdOf(line), scope)\n if (input.claimId && input.claimId !== claim.id) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.notFound' })\n }\n assertParentMutable(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND)\n const effectiveOrderLineId = hasOwn(input, 'orderLineId') ? (input.orderLineId ?? null) : (line.orderLineId ?? null)\n if (hasOwn(input, 'disposition')) {\n assertDispositionAllowedForType(claim.claimType, input.disposition ?? null)\n assertDispositionAllowedForGrade(toConditionGrade(line.conditionGrade), input.disposition ?? null)\n }\n const guardsClaimedQty = hasOwn(input, 'qtyClaimed') || hasOwn(input, 'orderLineId')\n await withAtomicFlush(em, [\n async () => {\n if (!guardsClaimedQty && !effectiveOrderLineId) return\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE, refresh: true })\n assertParentMutable(claim)\n if (effectiveOrderLineId && (claim.orderId || effectiveOrderLineId !== (line.orderLineId ?? null))) {\n await validateClaimReferences(ctx, scope, {\n lineOrderRefs: [{\n orderLineId: effectiveOrderLineId,\n orderId: claim.orderId ?? null,\n allowMissing: effectiveOrderLineId === (line.orderLineId ?? null),\n }],\n })\n }\n if (!guardsClaimedQty) return\n const orderLineId = hasOwn(input, 'orderLineId') ? (input.orderLineId ?? null) : (line.orderLineId ?? null)\n if (orderLineId) {\n await assertPendingClaimQuantitiesWithinSold(\n em,\n scope,\n new Map([[orderLineId, [{\n id: line.id,\n orderLineId,\n qtyClaimed: hasOwn(input, 'qtyClaimed')\n ? (amountString(input.qtyClaimed, '1') ?? '1')\n : line.qtyClaimed,\n }]]]),\n { currentClaimId: claim.id, excludedLineIds: new Set([line.id]) },\n )\n }\n },\n () => {\n applyLineUpdate(line, input)\n assertLineQuantities(line)\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.update' })\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineUpdateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.update', 'Update claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.update.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nconst deleteClaimLineCommand: CommandHandler<LineDeleteInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.delete',\n isUndoable: true,\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(lineDeleteSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(lineDeleteSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = claimOf(line) ?? await requireScopedClaim(em, input.claimId ?? claimIdOf(line), scope)\n if (input.claimId && input.claimId !== claim.id) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.notFound' })\n }\n assertParentMutable(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND)\n await withAtomicFlush(em, [\n () => {\n line.deletedAt = new Date()\n line.updatedAt = new Date()\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.delete' })\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'deleted', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(lineDeleteSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.delete', 'Delete claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n },\n () => {\n restoreLineFromSnapshot(state.line, before)\n state.line.deletedAt = null\n },\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.delete.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'created', state.line)\n },\n}\n\nconst receiveClaimLineCommand: CommandHandler<ClaimLineReceiveInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.receive',\n isUndoable: true,\n redo: ({ input, ctx }) => receiveClaimLineCommand.execute({ ...input, updatedAt: undefined }, ctx),\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(claimLineReceiveSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineReceiveSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = await requireScopedClaim(em, claimIdOf(line), scope)\n assertReceivingStatus(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND, input.updatedAt ?? undefined)\n\n const grade: ConditionGrade = input.conditionGrade\n const effectiveSettings = await resolveEffectiveWarrantyClaimSettings(em, scope)\n const shouldQuarantine = Boolean(effectiveSettings.quarantineGrades?.includes(grade))\n\n await withAtomicFlush(em, [\n () => {\n line.conditionGrade = grade\n if (input.inspectionNotes !== undefined) line.inspectionNotes = input.inspectionNotes ?? null\n\n const suggestedDisposition = suggestedDispositionForGrade(grade)\n if (!line.disposition && suggestedDisposition && resolveClaimTypeUiConfig(claim.claimType).allowedDispositions.includes(suggestedDisposition)) {\n assertDispositionAllowedForGrade(grade, suggestedDisposition)\n if (suggestedDisposition === 'restock' || suggestedDisposition === 'repair' || suggestedDisposition === 'scrap') {\n line.disposition = suggestedDisposition\n }\n }\n assertDispositionAllowedForGrade(grade, line.disposition ?? null)\n\n if (shouldQuarantine) line.quarantineStatus = 'held'\n line.updatedAt = new Date()\n appendClaimEvent(em, claim, 'system', {\n visibility: 'internal',\n payload: {\n action: 'line_received',\n lineId: line.id,\n conditionGrade: grade,\n disposition: line.disposition ?? null,\n quarantineStatus: line.quarantineStatus,\n quarantineHeld: shouldQuarantine,\n },\n actorUserId: ctx.auth?.sub ?? null,\n })\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.receive' })\n\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n if (shouldQuarantine) {\n await emitWarrantyClaimsEvent('warranty_claims.claim_line.quarantined', {\n id: line.id,\n claimId: claim.id,\n lineId: line.id,\n grade,\n scope,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n }, {\n persistent: true,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n }\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineReceiveSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.receive', 'Receive claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, receivingParentUndoRule)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.receive.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nconst releaseClaimLineQuarantineCommand: CommandHandler<ClaimLineReleaseQuarantineInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.release_quarantine',\n isUndoable: true,\n redo: ({ input, ctx }) => releaseClaimLineQuarantineCommand.execute({ ...input, updatedAt: undefined }, ctx),\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(claimLineReleaseQuarantineSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineReleaseQuarantineSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = await requireScopedClaim(em, claimIdOf(line), scope)\n assertReceivingStatus(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND, input.updatedAt ?? undefined)\n\n await withAtomicFlush(em, [\n () => {\n line.quarantineStatus = 'released'\n line.updatedAt = new Date()\n appendClaimEvent(em, claim, 'system', {\n visibility: 'internal',\n payload: {\n action: 'line_quarantine_released',\n lineId: line.id,\n quarantineStatus: line.quarantineStatus,\n },\n actorUserId: ctx.auth?.sub ?? null,\n })\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.release_quarantine' })\n\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineReleaseQuarantineSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.release_quarantine', 'Release line from quarantine', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, receivingParentUndoRule)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.release_quarantine.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nconst setClaimLineAssessmentCommand: CommandHandler<LineSetAssessmentInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.set_assessment',\n isUndoable: true,\n redo: ({ input, ctx }) => setClaimLineAssessmentCommand.execute({ ...input, updatedAt: undefined }, ctx),\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(lineSetAssessmentSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(lineSetAssessmentSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = claimOf(line) ?? await requireScopedClaim(em, claimIdOf(line), scope)\n assertParentMutable(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND, input.updatedAt ?? undefined)\n\n await withAtomicFlush(em, [\n () => {\n line.assessmentPayload = input.assessmentPayload\n line.updatedAt = new Date()\n claim.updatedAt = new Date()\n appendClaimEvent(em, claim, 'system', {\n visibility: 'internal',\n payload: {\n action: 'ai_assessment_recorded',\n lineId: line.id,\n },\n actorUserId: ctx.auth?.sub ?? null,\n })\n },\n ], { transaction: true, label: 'warranty_claims.claim_line.set_assessment' })\n\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(lineSetAssessmentSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.set_assessment', 'Record line assessment', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.set_assessment.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nregisterCommand(createClaimLineCommand)\nregisterCommand(updateClaimLineCommand)\nregisterCommand(deleteClaimLineCommand)\nregisterCommand(receiveClaimLineCommand)\nregisterCommand(releaseClaimLineQuarantineCommand)\nregisterCommand(setClaimLineAssessmentCommand)\n\nexport const claimLineCommands = [\n createClaimLineCommand,\n updateClaimLineCommand,\n deleteClaimLineCommand,\n receiveClaimLineCommand,\n releaseClaimLineQuarantineCommand,\n setClaimLineAssessmentCommand,\n]\n\nexport {\n createClaimLineCommand,\n updateClaimLineCommand,\n deleteClaimLineCommand,\n receiveClaimLineCommand,\n releaseClaimLineQuarantineCommand,\n setClaimLineAssessmentCommand,\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AAEzB,SAAS,SAAS;AAClB,SAAS,uBAAwE;AACjF,SAAS,uBAAuB;AAChC,SAAS,qBAAqB,+BAA+B;AAG7D,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,SAAS;AAClB,SAAS,eAAe,yBAAyB;AACjD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAQK;AACP,SAAS,+BAA+B;AACxC;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,iCAAiC,gCAAgC;AAC1E,SAAS,6CAA6C;AACtD,SAAS,sBAAsB,wBAAwB;AACvD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,wCAAwC,+BAA+B;AAEhF,MAAM,kBAAoC;AAAA,EACxC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AACd;AAEA,MAAM,mBAAmB,EACtB,OAAO;AAAA,EACN,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACpC,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC3C,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AACvC,CAAC,EACA,OAAO;AAIV,MAAM,0BAA0B,EAC7B,OAAO;AAAA,EACN,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EAC3C,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACrC,mBAAmB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACnD,WAAW,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS;AAC5E,CAAC,EACA,OAAO;AAqDV,MAAM,wBAAwB,oBAAI,IAAI;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,0BAA0B,oBAAI,IAAI,CAAC,YAAY,YAAY,CAAC;AAalE,MAAM,wBAA4C;AAAA,EAChD,uBAAuB;AAAA,EACvB,WAAW;AAAA,EACX,gBAAgB;AAClB;AAEA,MAAM,0BAA8C;AAAA,EAClD,uBAAuB;AAAA,EACvB,WAAW;AAAA,EACX,gBAAgB;AAClB;AAEA,SAAS,kBAAqB,QAAsB,UAAsB;AACxE,QAAM,SAAS,OAAO,UAAU,YAAY,CAAC,CAAC;AAC9C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,uDAAuD,CAAC;AAAA,EAChG;AACA,SAAO,OAAO;AAChB;AAEA,SAAS,OAAO,OAAe,KAAsB;AACnD,SAAO,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG;AACxD;AAEA,SAAS,aAAa,KAA4B,OAAuC;AACvF,QAAM,WAAW,MAAM,YAAY,IAAI,MAAM,YAAY;AACzD,QAAM,iBAAiB,MAAM,kBAAkB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAChG,MAAI,CAAC,SAAU,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,mEAAmE,CAAC;AACzH,MAAI,CAAC,eAAgB,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,yEAAyE,CAAC;AACrI,oBAAkB,KAAK,QAAQ;AAC/B,0BAAwB,KAAK,cAAc;AAC3C,SAAO,EAAE,UAAU,eAAe;AACpC;AAEA,SAAS,MAAM,OAAwD;AACrE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAC3D,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO,KAAK,YAAY;AAChE;AAEA,SAAS,OAAO,OAAmC;AACjD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO;AAC/C;AAEA,SAAS,cAAc,OAAwD;AAC7E,QAAM,MAAM,MAAM,KAAK;AACvB,SAAO,MAAM,IAAI,MAAM,GAAG,EAAE,IAAI;AAClC;AAEA,SAAS,WAAW,OAAmC;AACrD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,oBAAI,KAAK,GAAG,KAAK,gBAAgB;AAC9C,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO;AAC/C;AAEA,SAAS,aAAa,OAA2C,WAAW,KAAoB;AAC9F,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAC/D,MAAI,CAAC,OAAO,SAAS,MAAM,EAAG,QAAO;AACrC,SAAO,OAAO,MAAM;AACtB;AAEA,SAAS,qBAAqB,OAA0D;AACtF,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAO,aAAa,OAAO,GAAG;AAChC;AAEA,SAAS,YAAY,OAAmD;AACtE,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAC/D,SAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAC5C;AAEA,SAAS,UAAU,MAAY,QAAsB;AACnD,QAAM,SAAS,IAAI,KAAK,KAAK,IAAI,KAAK,eAAe,GAAG,KAAK,YAAY,IAAI,QAAQ,CAAC,CAAC;AACvF,QAAM,UAAU,IAAI,KAAK,KAAK,IAAI,OAAO,eAAe,GAAG,OAAO,YAAY,IAAI,GAAG,CAAC,CAAC,EAAE,WAAW;AACpG,QAAM,OAAO,IAAI,KAAK,KAAK,QAAQ,CAAC;AACpC,OAAK,WAAW,CAAC;AACjB,OAAK,eAAe,OAAO,eAAe,GAAG,OAAO,YAAY,GAAG,KAAK,IAAI,KAAK,WAAW,GAAG,OAAO,CAAC;AACvG,SAAO;AACT;AAEA,SAAS,qBACP,cACA,gBACiF;AACjF,MAAI,CAAC,gBAAgB,mBAAmB,QAAQ,mBAAmB,QAAW;AAC5E,WAAO,EAAE,mBAAmB,MAAM,gBAAgB,UAAU;AAAA,EAC9D;AACA,QAAM,oBAAoB,UAAU,cAAc,cAAc;AAChE,QAAM,iBAAiB,kBAAkB,QAAQ,KAAK,KAAK,IAAI,IAAI,gBAAgB;AACnF,SAAO,EAAE,mBAAmB,eAAe;AAC7C;AAEA,SAAS,UAAU,MAAiC;AAClD,QAAM,QAAQ,KAAK;AACnB,MAAI,OAAO,UAAU,YAAY,SAAS,QAAQ,SAAS,OAAO,MAAM,OAAO,SAAU,QAAO,MAAM;AACtG,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,QAAQ,MAA+C;AAC9D,QAAM,QAAQ,KAAK;AACnB,MAAI,OAAO,UAAU,YAAY,SAAS,QAAQ,SAAS,OAAO,MAAM,OAAO,SAAU,QAAO;AAChG,SAAO;AACT;AAEA,SAAS,cAAc,MAA+B,OAAyC;AAC7F,QAAM,WAAW,gBAAgB,OAAO,KAAK,QAAQ,IAAI;AACzD,QAAM,YAAY,iBAAiB,OAAO,MAAM,QAAQ,IAAI;AAC5D,SAAO,aAAa;AACtB;AAEA,SAAS,oBAAoB,OAA4B;AACvD,MAAI,CAAC,sBAAsB,IAAI,MAAM,MAAM,GAAG;AAC5C,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,oCAAoC,CAAC;AAAA,EAC7E;AACF;AAEA,SAAS,sBAAsB,OAA4B;AACzD,MAAI,MAAM,WAAW,cAAc,MAAM,WAAW,cAAc;AAChE,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,gDAAgD,CAAC;AAAA,EACzF;AACF;AAEA,SAAS,iBAAiB,OAAyD;AACjF,MAAI,UAAU,OAAO,UAAU,OAAO,UAAU,OAAO,UAAU,IAAK,QAAO;AAC7E,SAAO;AACT;AAEA,SAAS,qBAAqB,MAA+B;AAC3D,QAAM,aAAa,YAAY,KAAK,UAAU;AAC9C,QAAM,cAAc,KAAK,gBAAgB,QAAQ,KAAK,gBAAgB,SAAY,OAAO,YAAY,KAAK,WAAW;AACrH,QAAM,cAAc,KAAK,gBAAgB,QAAQ,KAAK,gBAAgB,SAAY,OAAO,YAAY,KAAK,WAAW;AACrH,MAAI,aAAa,KAAM,gBAAgB,QAAQ,cAAc,KAAO,gBAAgB,QAAQ,cAAc,GAAI;AAC5G,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,oCAAoC,CAAC;AAAA,EAC7E;AACA,MAAI,gBAAgB,QAAQ,cAAc,YAAY;AACpD,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,oCAAoC,CAAC;AAAA,EAC7E;AACA,MAAI,gBAAgB,QAAQ,cAAc,YAAY;AACpD,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,oCAAoC,CAAC;AAAA,EAC7E;AACF;AAEA,SAAS,qBAAqB,MAA+B,IAAmC;AAC9F,MAAI,SAAS,GAAI;AACjB,MAAI,iBAAiB,IAAI,EAAE,SAAS,EAAE,EAAG;AACzC,QAAM,IAAI,cAAc,KAAK,EAAE,OAAO,2CAA2C,CAAC;AACpF;AAEA,SAAS,oBACP,OACA,OACA,QAYA;AACA,QAAM,eAAe,MAAM,gBAAgB;AAC3C,QAAM,iBAAiB,MAAM,kBAAkB;AAC/C,QAAM,mBAAmB,qBAAqB,cAAc,cAAc;AAC1E,SAAO;AAAA,IACL,IAAI,WAAW;AAAA,IACf;AAAA,IACA,gBAAgB,MAAM;AAAA,IACtB,UAAU,MAAM;AAAA,IAChB;AAAA,IACA,WAAW,MAAM,aAAa;AAAA,IAC9B,WAAW,MAAM,aAAa;AAAA,IAC9B,KAAK,MAAM,OAAO;AAAA,IAClB,aAAa,MAAM,eAAe;AAAA,IAClC,aAAa,MAAM,eAAe;AAAA,IAClC,cAAc,MAAM,gBAAgB;AAAA,IACpC,WAAW,MAAM,aAAa;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,mBAAmB,MAAM,qBAAqB,iBAAiB;AAAA,IAC/D,gBAAgB,MAAM,kBAAkB,iBAAiB;AAAA,IACzD,WAAW,MAAM,aAAa;AAAA,IAC9B,kBAAkB,MAAM,oBAAoB;AAAA,IAC5C,YAAY,aAAa,MAAM,YAAY,GAAG,KAAK;AAAA,IACnD,aAAa,qBAAqB,MAAM,WAAW;AAAA,IACnD,aAAa,qBAAqB,MAAM,WAAW;AAAA,IACnD,oBAAoB,MAAM,sBAAsB;AAAA,IAChD,iBAAiB,MAAM,mBAAmB;AAAA,IAC1C,aAAa,MAAM,eAAe;AAAA,IAClC,YAAY,MAAM,cAAc;AAAA,IAChC,YAAY;AAAA,IACZ,cAAc,qBAAqB,MAAM,YAAY;AAAA,IACrD,eAAe,qBAAqB,MAAM,aAAa;AAAA,IACvD,kBAAkB,qBAAqB,MAAM,gBAAgB;AAAA,IAC7D,kBAAkB,qBAAqB,MAAM,gBAAgB;AAAA,IAC7D,WAAW,oBAAI,KAAK;AAAA,IACpB,WAAW,oBAAI,KAAK;AAAA,EACtB;AACF;AAEA,SAAS,gBAAgB,MAAyB,OAAmC;AACnF,QAAM,sBAAsB,OAAO,OAAO,cAAc,KAAK,CAAC,cAAc,KAAK,gBAAgB,MAAM,MAAM,gBAAgB,IAAI;AACjI,QAAM,wBAAwB,OAAO,OAAO,gBAAgB,MAAM,KAAK,kBAAkB,WAAW,MAAM,kBAAkB;AAC5H,QAAM,sBAAsB,OAAO,OAAO,mBAAmB,KAAK,OAAO,OAAO,gBAAgB;AAChG,MAAI,OAAO,OAAO,QAAQ,KAAK,MAAM,WAAW,OAAW,MAAK,SAAS,MAAM;AAC/E,MAAI,OAAO,OAAO,WAAW,EAAG,MAAK,YAAY,MAAM,aAAa;AACpE,MAAI,OAAO,OAAO,WAAW,EAAG,MAAK,YAAY,MAAM,aAAa;AACpE,MAAI,OAAO,OAAO,KAAK,EAAG,MAAK,MAAM,MAAM,OAAO;AAClD,MAAI,OAAO,OAAO,aAAa,EAAG,MAAK,cAAc,MAAM,eAAe;AAC1E,MAAI,OAAO,OAAO,aAAa,EAAG,MAAK,cAAc,MAAM,eAAe;AAC1E,MAAI,OAAO,OAAO,cAAc,EAAG,MAAK,eAAe,MAAM,gBAAgB;AAC7E,MAAI,OAAO,OAAO,WAAW,EAAG,MAAK,YAAY,MAAM,aAAa;AACpE,MAAI,OAAO,OAAO,cAAc,EAAG,MAAK,eAAe,MAAM,gBAAgB;AAC7E,MAAI,OAAO,OAAO,gBAAgB,EAAG,MAAK,iBAAiB,MAAM,kBAAkB;AACnF,MAAI,OAAO,OAAO,mBAAmB,EAAG,MAAK,oBAAoB,MAAM,qBAAqB;AAC5F,MAAI,OAAO,OAAO,gBAAgB,KAAK,MAAM,eAAgB,MAAK,iBAAiB,MAAM;AACzF,MAAI,OAAO,OAAO,WAAW,EAAG,MAAK,YAAY,MAAM,aAAa;AACpE,MAAI,OAAO,OAAO,kBAAkB,EAAG,MAAK,mBAAmB,MAAM,oBAAoB;AACzF,MAAI,OAAO,OAAO,YAAY,KAAK,MAAM,eAAe,OAAW,MAAK,aAAa,aAAa,MAAM,YAAY,GAAG,KAAK;AAC5H,MAAI,OAAO,OAAO,aAAa,EAAG,MAAK,cAAc,qBAAqB,MAAM,WAAW;AAC3F,MAAI,OAAO,OAAO,aAAa,EAAG,MAAK,cAAc,qBAAqB,MAAM,WAAW;AAC3F,MAAI,OAAO,OAAO,oBAAoB,EAAG,MAAK,qBAAqB,MAAM,sBAAsB;AAC/F,MAAI,OAAO,OAAO,iBAAiB,EAAG,MAAK,kBAAkB,MAAM,mBAAmB;AACtF,MAAI,OAAO,OAAO,aAAa,EAAG,MAAK,cAAc,MAAM,eAAe;AAC1E,MAAI,OAAO,OAAO,YAAY,EAAG,MAAK,aAAa,MAAM,cAAc;AACvE,MAAI,OAAO,OAAO,YAAY,KAAK,MAAM,YAAY;AACnD,yBAAqB,KAAK,YAAY,MAAM,UAAU;AACtD,SAAK,aAAa,MAAM;AAAA,EAC1B;AACA,MAAI,OAAO,OAAO,cAAc,EAAG,MAAK,eAAe,qBAAqB,MAAM,YAAY;AAC9F,MAAI,OAAO,OAAO,eAAe,EAAG,MAAK,gBAAgB,qBAAqB,MAAM,aAAa;AACjG,MAAI,OAAO,OAAO,kBAAkB,EAAG,MAAK,mBAAmB,qBAAqB,MAAM,gBAAgB;AAC1G,MAAI,OAAO,OAAO,kBAAkB,EAAG,MAAK,mBAAmB,qBAAqB,MAAM,gBAAgB;AAC1G,OAAK,uBAAuB,0BAA0B,CAAC,qBAAqB;AAC1E,UAAM,mBAAmB,qBAAqB,KAAK,gBAAgB,MAAM,KAAK,kBAAkB,IAAI;AACpG,SAAK,oBAAoB,iBAAiB;AAC1C,SAAK,iBAAiB,iBAAiB;AAAA,EACzC;AACA,OAAK,YAAY,oBAAI,KAAK;AAC5B;AAEA,SAAS,aAAa,MAAuC;AAC3D,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,SAAS,UAAU,IAAI;AAAA,IACvB,gBAAgB,KAAK;AAAA,IACrB,UAAU,KAAK;AAAA,IACf,QAAQ,KAAK;AAAA,IACb,WAAW,KAAK,aAAa;AAAA,IAC7B,WAAW,KAAK,aAAa;AAAA,IAC7B,KAAK,KAAK,OAAO;AAAA,IACjB,aAAa,KAAK,eAAe;AAAA,IACjC,aAAa,KAAK,eAAe;AAAA,IACjC,cAAc,KAAK,gBAAgB;AAAA,IACnC,WAAW,KAAK,aAAa;AAAA,IAC7B,cAAc,cAAc,KAAK,YAAY;AAAA,IAC7C,gBAAgB,KAAK,kBAAkB;AAAA,IACvC,mBAAmB,cAAc,KAAK,iBAAiB;AAAA,IACvD,gBAAgB,KAAK;AAAA,IACrB,WAAW,KAAK,aAAa;AAAA,IAC7B,kBAAkB,KAAK,oBAAoB;AAAA,IAC3C,YAAY,KAAK;AAAA,IACjB,aAAa,KAAK,eAAe;AAAA,IACjC,aAAa,KAAK,eAAe;AAAA,IACjC,oBAAoB,KAAK,sBAAsB;AAAA,IAC/C,gBAAgB,KAAK,kBAAkB;AAAA,IACvC,kBAAkB,KAAK;AAAA,IACvB,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,mBAAmB,KAAK,qBAAqB;AAAA,IAC7C,aAAa,KAAK,eAAe;AAAA,IACjC,YAAY,KAAK;AAAA,IACjB,cAAc,KAAK,gBAAgB;AAAA,IACnC,eAAe,KAAK,iBAAiB;AAAA,IACrC,kBAAkB,KAAK,oBAAoB;AAAA,IAC3C,kBAAkB,KAAK,oBAAoB;AAAA,IAC3C,mBAAmB,KAAK,qBAAqB;AAAA,IAC7C,YAAY,KAAK,cAAc;AAAA,IAC/B,WAAW,MAAM,KAAK,SAAS;AAAA,IAC/B,WAAW,MAAM,KAAK,SAAS;AAAA,EACjC;AACF;AAEA,eAAe,iBACb,IACA,QACA,OAC8B;AAC9B,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,QAAQ,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,IAC7E,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,IACtB;AAAA,EACF;AACA,SAAO,OAAO,aAAa,IAAI,IAAI;AACrC;AAEA,SAAS,wBAAwB,MAAyB,UAA8B;AACtF,OAAK,SAAS,SAAS;AACvB,OAAK,YAAY,SAAS;AAC1B,OAAK,YAAY,SAAS;AAC1B,OAAK,MAAM,SAAS;AACpB,OAAK,cAAc,SAAS;AAC5B,OAAK,cAAc,SAAS;AAC5B,OAAK,eAAe,SAAS;AAC7B,OAAK,YAAY,SAAS;AAC1B,OAAK,eAAe,WAAW,SAAS,YAAY;AACpD,OAAK,iBAAiB,SAAS;AAC/B,OAAK,oBAAoB,WAAW,SAAS,iBAAiB;AAC9D,OAAK,iBAAiB,SAAS;AAC/B,OAAK,YAAY,SAAS;AAC1B,OAAK,mBAAmB,SAAS;AACjC,OAAK,aAAa,SAAS;AAC3B,OAAK,cAAc,SAAS;AAC5B,OAAK,cAAc,SAAS;AAC5B,OAAK,qBAAqB,SAAS;AACnC,OAAK,iBAAiB,SAAS;AAC/B,OAAK,mBAAmB,SAAS;AACjC,OAAK,kBAAkB,SAAS;AAChC,OAAK,oBAAoB,SAAS;AAClC,OAAK,cAAc,SAAS;AAC5B,OAAK,aAAa,SAAS;AAC3B,OAAK,eAAe,SAAS;AAC7B,OAAK,gBAAgB,SAAS;AAC9B,OAAK,mBAAmB,SAAS;AACjC,OAAK,mBAAmB,SAAS;AACjC,OAAK,oBAAoB,SAAS;AAClC,OAAK,aAAa,SAAS;AAC3B,OAAK,YAAY,OAAO,SAAS,SAAS;AAC1C,OAAK,YAAY,oBAAI,KAAK;AAC5B;AAEA,eAAe,sBAAsB,IAAmB,OAAqC;AAC3F,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,MAAM;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,WAAW;AAAA,IACb;AAAA,IACA,CAAC;AAAA,IACD,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,QAAM,SAAS,qBAAqB,OAAO,EAAE,WAAW,MAAM,UAAU,CAAC;AACzE,QAAM,qBAAqB,OAAO,OAAO,kBAAkB;AAC3D,QAAM,sBAAsB,OAAO,OAAO,mBAAmB;AAC7D,QAAM,YAAY,oBAAI,KAAK;AAC7B;AAEA,SAAS,yBAAyC;AAChD,SAAO,iBAAiB,mCAAmC,+CAA+C;AAC5G;AAEA,eAAe,4BACb,IACA,OACA,MACwB;AACxB,MAAI,CAAC,MAAO,QAAO,uBAAuB;AAC1C,QAAM,QAA4B,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AACnG,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,MAAM,SAAS,UAAU,MAAM,UAAU,gBAAgB,MAAM,gBAAgB,WAAW,KAAK;AAAA,IACrG,EAAE,UAAU,SAAS,kBAAkB;AAAA,IACvC;AAAA,EACF;AACA,MAAI,CAAC,MAAO,QAAO,uBAAuB;AAC1C,MAAI,CAAC,KAAK,sBAAsB,IAAI,MAAM,MAAM,EAAG,QAAO,iBAAiB,KAAK,WAAW,KAAK,cAAc;AAC9G,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,MAAM,IAAI,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,IAC/E,EAAE,UAAU,SAAS,kBAAkB;AAAA,IACvC;AAAA,EACF;AACA,MAAI,CAAC,QAAQ,CAAC,MAAM,aAAa,MAAM,KAAK,SAAS,MAAM,MAAM,UAAW,QAAO,uBAAuB;AAC1G,SAAO,EAAE,OAAO,KAAK;AACvB;AAEA,eAAe,kBACb,IACA,QACA,OAC4B;AAC5B,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,QAAQ,UAAU,MAAM,UAAU,gBAAgB,MAAM,gBAAgB,WAAW,KAAK;AAAA,IAC9F,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,IACtB;AAAA,EACF;AACA,MAAI,CAAC,KAAM,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kCAAkC,CAAC;AACpF,SAAO;AACT;AAEA,eAAe,iBAAiB,KAA4B,OAAqC;AAC/F,QAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,aAAa,EAAE,IAAI,MAAM,IAAI,gBAAgB,MAAM,gBAAgB,UAAU,MAAM,SAAS;AAAA,IAC5F,SAAS,EAAE,YAAY,EAAE,gBAAgB,eAAe;AAAA,IACxD,QAAQ;AAAA,EACV,CAAC;AACD,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,IACA,EAAE,IAAI,MAAM,IAAI,gBAAgB,MAAM,gBAAgB,UAAU,MAAM,SAAS;AAAA,IAC/E,IAAI,MAAM,YAAY;AAAA,IACtB;AAAA,EACF;AACF;AAEA,eAAe,aACb,KACA,QACA,MACe;AACf,QAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,aAAa,EAAE,IAAI,KAAK,IAAI,gBAAgB,KAAK,gBAAgB,UAAU,KAAK,SAAS;AAAA,IACzF,SAAS,EAAE,YAAY,EAAE,gBAAgB,oBAAoB;AAAA,EAC/D,CAAC;AACD,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,IACA,EAAE,IAAI,KAAK,IAAI,gBAAgB,KAAK,gBAAgB,UAAU,KAAK,SAAS;AAAA,IAC5E,IAAI,MAAM,YAAY;AAAA,IACtB,8BAA8B,MAAM;AAAA,EACtC;AACF;AAEA,eAAe,iBACb,KACA,QACA,MACe;AACf,QAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,QAAM,wBAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,aAAa,EAAE,IAAI,KAAK,IAAI,gBAAgB,KAAK,gBAAgB,UAAU,KAAK,SAAS;AAAA,IACzF,SAAS,EAAE,YAAY,EAAE,gBAAgB,oBAAoB;AAAA,EAC/D,CAAC;AACD,QAAM;AAAA,IACJ,IAAI;AAAA,IACJ;AAAA,IACA,EAAE,IAAI,KAAK,IAAI,gBAAgB,KAAK,gBAAgB,UAAU,KAAK,SAAS;AAAA,IAC5E,IAAI,MAAM,YAAY;AAAA,IACtB,mCAAmC,MAAM;AAAA,EAC3C;AACF;AAEA,eAAe,aACb,gBACA,qBACA,YACA,WAYC;AACD,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,QAAM,QAAQ,UAAU;AACxB,QAAM,SAAS,UAAU;AACzB,SAAO;AAAA,IACL,aAAa,UAAU,gBAAgB,mBAAmB;AAAA,IAC1D,cAAc;AAAA,IACd;AAAA,IACA,oBAAoB;AAAA,IACpB,kBAAkB,OAAO,WAAW,QAAQ,WAAW;AAAA,IACvD,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,IACjD,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,IACnE,gBAAgB,UAAU;AAAA,IAC1B,eAAe,SAAS;AAAA,IACxB,SAAS,EAAE,MAAM,EAAE,QAAQ,UAAU,MAAM,OAAO,SAAS,KAAK,EAAE;AAAA,EACpE;AACF;AAEA,MAAM,yBAAoG;AAAA,EACxG,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,kBAAkB,uBAAuB,QAAQ;AAC/D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,QAAQ,MAAM,mBAAmB,IAAI,MAAM,SAAS,KAAK;AAC/D,oCAAgC,MAAM,WAAW,MAAM,eAAe,IAAI;AAC1E,UAAM,mCAAmC,KAAK,KAAK;AACnD,wBAAoB,KAAK;AACzB,QAAI;AACJ,QAAI,aAAa,MAAM,UAAU;AACjC,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mBAAmB,IAAI,MAAM,IAAI,OAAO,EAAE,UAAU,SAAS,mBAAmB,SAAS,KAAK,CAAC;AACrG,4BAAoB,KAAK;AACzB,YAAI,MAAM,aAAa;AACrB,gBAAM,wBAAwB,KAAK,OAAO;AAAA,YACxC,eAAe,CAAC,EAAE,aAAa,MAAM,aAAa,SAAS,MAAM,WAAW,KAAK,CAAC;AAAA,UACpF,CAAC;AAAA,QACH;AACA,cAAM,gBAAgB,MAAM;AAAA,UAC1B;AAAA,UACA;AAAA,UACA;AAAA,YACE,OAAO,MAAM;AAAA,YACb,UAAU,MAAM;AAAA,YAChB,gBAAgB,MAAM;AAAA,YACtB,WAAW;AAAA,UACb;AAAA,UACA,CAAC;AAAA,UACD;AAAA,QACF;AACA,YAAI,MAAM,aAAa;AACrB,gBAAM,uCAAuC,IAAI,OAAO,oBAAI,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC;AAAA,YACpF,aAAa,MAAM;AAAA,YACnB,YAAY,aAAa,MAAM,YAAY,GAAG,KAAK;AAAA,UACrD,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,gBAAgB,MAAM,GAAG,CAAC;AAAA,QACrC;AACA,qBAAa,MAAM,UAAU,cAAc,OAAO,CAAC,KAAK,UAAU,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG,CAAC,IAAI;AAAA,MACtG;AAAA,MACA,MAAM;AACJ,eAAO,GAAG,OAAO,mBAAmB,oBAAoB,OAAO,OAAO,UAAU,CAAC;AACjF,6BAAqB,IAAI;AACzB,WAAG,QAAQ,IAAI;AAAA,MACjB;AAAA,MACA,MAAM,sBAAsB,IAAI,KAAK;AAAA,IACvC,GAAG,EAAE,aAAa,MAAM,OAAO,oCAAoC,CAAC;AACpE,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,aAAa,KAAK,WAAW,IAAI;AACvC,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,EAC9C;AAAA,EACA,cAAc,OAAO,UAAU,QAAQ,QAAQ;AAC7C,UAAM,QAAQ,kBAAkB,uBAAuB,QAAQ;AAC/D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,iBAAiB,IAAI,OAAO,QAAQ,KAAK;AAAA,EAClD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM,aAAa,2CAA2C,kBAAkB,OAAO,QAAQ,SAAS;AAAA,EAC7I,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAoC,QAAQ;AAC5D,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,gBAAQ,MAAM,4BAA4B,IAAI,SAAS,OAAO,qBAAqB;AAAA,MACrF;AAAA,MACA,MAAM;AACJ,cAAM,KAAK,YAAY,oBAAI,KAAK;AAChC,cAAM,KAAK,YAAY,oBAAI,KAAK;AAAA,MAClC;AAAA,MACA,MAAM,sBAAsB,IAAI,MAAM,KAAK;AAAA,IAC7C,GAAG,EAAE,aAAa,MAAM,OAAO,yCAAyC,CAAC;AACzE,UAAM,iBAAiB,KAAK,MAAM,KAAK;AACvC,UAAM,iBAAiB,KAAK,WAAW,MAAM,IAAI;AAAA,EACnD;AACF;AAEA,MAAM,yBAAoG;AAAA,EACxG,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,QAAQ,kBAAkB,uBAAuB,QAAQ;AAC/D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,EAAE,QAAQ,MAAM,iBAAiB,IAAI,MAAM,IAAI,KAAK,EAAE;AAAA,EAC/D;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,kBAAkB,uBAAuB,QAAQ;AAC/D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM,kBAAkB,IAAI,MAAM,IAAI,KAAK;AACxD,UAAM,QAAQ,QAAQ,IAAI,KAAK,MAAM,mBAAmB,IAAI,MAAM,WAAW,UAAU,IAAI,GAAG,KAAK;AACnG,QAAI,MAAM,WAAW,MAAM,YAAY,MAAM,IAAI;AAC/C,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kCAAkC,CAAC;AAAA,IAC3E;AACA,wBAAoB,KAAK;AACzB,UAAM,mCAAmC,KAAK,MAAM,iCAAiC;AACrF,UAAM,uBAAuB,OAAO,OAAO,aAAa,IAAK,MAAM,eAAe,OAAS,KAAK,eAAe;AAC/G,QAAI,OAAO,OAAO,aAAa,GAAG;AAChC,sCAAgC,MAAM,WAAW,MAAM,eAAe,IAAI;AAC1E,uCAAiC,iBAAiB,KAAK,cAAc,GAAG,MAAM,eAAe,IAAI;AAAA,IACnG;AACA,UAAM,mBAAmB,OAAO,OAAO,YAAY,KAAK,OAAO,OAAO,aAAa;AACnF,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,YAAI,CAAC,oBAAoB,CAAC,qBAAsB;AAChD,cAAM,mBAAmB,IAAI,MAAM,IAAI,OAAO,EAAE,UAAU,SAAS,mBAAmB,SAAS,KAAK,CAAC;AACrG,4BAAoB,KAAK;AACzB,YAAI,yBAAyB,MAAM,WAAW,0BAA0B,KAAK,eAAe,QAAQ;AAClG,gBAAM,wBAAwB,KAAK,OAAO;AAAA,YACxC,eAAe,CAAC;AAAA,cACd,aAAa;AAAA,cACb,SAAS,MAAM,WAAW;AAAA,cAC1B,cAAc,0BAA0B,KAAK,eAAe;AAAA,YAC9D,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,YAAI,CAAC,iBAAkB;AACvB,cAAM,cAAc,OAAO,OAAO,aAAa,IAAK,MAAM,eAAe,OAAS,KAAK,eAAe;AACtG,YAAI,aAAa;AACf,gBAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA,oBAAI,IAAI,CAAC,CAAC,aAAa,CAAC;AAAA,cACtB,IAAI,KAAK;AAAA,cACT;AAAA,cACA,YAAY,OAAO,OAAO,YAAY,IACjC,aAAa,MAAM,YAAY,GAAG,KAAK,MACxC,KAAK;AAAA,YACX,CAAC,CAAC,CAAC,CAAC;AAAA,YACJ,EAAE,gBAAgB,MAAM,IAAI,iBAAiB,oBAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM;AACJ,wBAAgB,MAAM,KAAK;AAC3B,6BAAqB,IAAI;AAAA,MAC3B;AAAA,MACA,MAAM,sBAAsB,IAAI,KAAK;AAAA,IACvC,GAAG,EAAE,aAAa,MAAM,OAAO,oCAAoC,CAAC;AACpE,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,aAAa,KAAK,WAAW,IAAI;AACvC,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,EAC9C;AAAA,EACA,cAAc,OAAO,UAAU,QAAQ,QAAQ;AAC7C,UAAM,QAAQ,kBAAkB,uBAAuB,QAAQ;AAC/D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,iBAAiB,IAAI,OAAO,QAAQ,KAAK;AAAA,EAClD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM,aAAa,2CAA2C,qBAAqB,OAAO,QAAQ,SAAS;AAAA,EAChJ,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAoC,QAAQ;AAC5D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,gBAAQ,MAAM,4BAA4B,IAAI,SAAS,OAAO,qBAAqB;AAAA,MACrF;AAAA,MACA,MAAM,wBAAwB,MAAM,MAAM,MAAM;AAAA,MAChD,MAAM,sBAAsB,IAAI,MAAM,KAAK;AAAA,IAC7C,GAAG,EAAE,aAAa,MAAM,OAAO,yCAAyC,CAAC;AACzE,UAAM,iBAAiB,KAAK,MAAM,KAAK;AACvC,UAAM,iBAAiB,KAAK,WAAW,MAAM,IAAI;AAAA,EACnD;AACF;AAEA,MAAM,yBAA+F;AAAA,EACnG,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,QAAQ,kBAAkB,kBAAkB,QAAQ;AAC1D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,EAAE,QAAQ,MAAM,iBAAiB,IAAI,MAAM,IAAI,KAAK,EAAE;AAAA,EAC/D;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,kBAAkB,kBAAkB,QAAQ;AAC1D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM,kBAAkB,IAAI,MAAM,IAAI,KAAK;AACxD,UAAM,QAAQ,QAAQ,IAAI,KAAK,MAAM,mBAAmB,IAAI,MAAM,WAAW,UAAU,IAAI,GAAG,KAAK;AACnG,QAAI,MAAM,WAAW,MAAM,YAAY,MAAM,IAAI;AAC/C,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kCAAkC,CAAC;AAAA,IAC3E;AACA,wBAAoB,KAAK;AACzB,UAAM,mCAAmC,KAAK,MAAM,iCAAiC;AACrF,UAAM,gBAAgB,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,YAAY,oBAAI,KAAK;AAC1B,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B;AAAA,MACA,MAAM,sBAAsB,IAAI,KAAK;AAAA,IACvC,GAAG,EAAE,aAAa,MAAM,OAAO,oCAAoC,CAAC;AACpE,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,aAAa,KAAK,WAAW,IAAI;AACvC,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,EAC9C;AAAA,EACA,cAAc,OAAO,UAAU,QAAQ,QAAQ;AAC7C,UAAM,QAAQ,kBAAkB,kBAAkB,QAAQ;AAC1D,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,iBAAiB,IAAI,OAAO,QAAQ,KAAK;AAAA,EAClD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM,aAAa,2CAA2C,qBAAqB,OAAO,QAAQ,SAAS;AAAA,EAChJ,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAoC,QAAQ;AAC5D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,gBAAQ,MAAM,4BAA4B,IAAI,SAAS,OAAO,qBAAqB;AAAA,MACrF;AAAA,MACA,MAAM;AACJ,gCAAwB,MAAM,MAAM,MAAM;AAC1C,cAAM,KAAK,YAAY;AAAA,MACzB;AAAA,MACA,MAAM,sBAAsB,IAAI,MAAM,KAAK;AAAA,IAC7C,GAAG,EAAE,aAAa,MAAM,OAAO,yCAAyC,CAAC;AACzE,UAAM,iBAAiB,KAAK,MAAM,KAAK;AACvC,UAAM,iBAAiB,KAAK,WAAW,MAAM,IAAI;AAAA,EACnD;AACF;AAEA,MAAM,0BAAsG;AAAA,EAC1G,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,MAAM,CAAC,EAAE,OAAO,IAAI,MAAM,wBAAwB,QAAQ,EAAE,GAAG,OAAO,WAAW,OAAU,GAAG,GAAG;AAAA,EACjG,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,QAAQ,kBAAkB,wBAAwB,QAAQ;AAChE,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,EAAE,QAAQ,MAAM,iBAAiB,IAAI,MAAM,IAAI,KAAK,EAAE;AAAA,EAC/D;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,kBAAkB,wBAAwB,QAAQ;AAChE,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM,kBAAkB,IAAI,MAAM,IAAI,KAAK;AACxD,UAAM,QAAQ,MAAM,mBAAmB,IAAI,UAAU,IAAI,GAAG,KAAK;AACjE,0BAAsB,KAAK;AAC3B,UAAM,mCAAmC,KAAK,MAAM,mCAAmC,MAAM,aAAa,MAAS;AAEnH,UAAM,QAAwB,MAAM;AACpC,UAAM,oBAAoB,MAAM,sCAAsC,IAAI,KAAK;AAC/E,UAAM,mBAAmB,QAAQ,kBAAkB,kBAAkB,SAAS,KAAK,CAAC;AAEpF,UAAM,gBAAgB,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,iBAAiB;AACtB,YAAI,MAAM,oBAAoB,OAAW,MAAK,kBAAkB,MAAM,mBAAmB;AAEzF,cAAM,uBAAuB,6BAA6B,KAAK;AAC/D,YAAI,CAAC,KAAK,eAAe,wBAAwB,yBAAyB,MAAM,SAAS,EAAE,oBAAoB,SAAS,oBAAoB,GAAG;AAC7I,2CAAiC,OAAO,oBAAoB;AAC5D,cAAI,yBAAyB,aAAa,yBAAyB,YAAY,yBAAyB,SAAS;AAC/G,iBAAK,cAAc;AAAA,UACrB;AAAA,QACF;AACA,yCAAiC,OAAO,KAAK,eAAe,IAAI;AAEhE,YAAI,iBAAkB,MAAK,mBAAmB;AAC9C,aAAK,YAAY,oBAAI,KAAK;AAC1B,yBAAiB,IAAI,OAAO,UAAU;AAAA,UACpC,YAAY;AAAA,UACZ,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ,KAAK;AAAA,YACb,gBAAgB;AAAA,YAChB,aAAa,KAAK,eAAe;AAAA,YACjC,kBAAkB,KAAK;AAAA,YACvB,gBAAgB;AAAA,UAClB;AAAA,UACA,aAAa,IAAI,MAAM,OAAO;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,MACA,MAAM,sBAAsB,IAAI,KAAK;AAAA,IACvC,GAAG,EAAE,aAAa,MAAM,OAAO,qCAAqC,CAAC;AAErE,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,aAAa,KAAK,WAAW,IAAI;AACvC,QAAI,kBAAkB;AACpB,YAAM,wBAAwB,0CAA0C;AAAA,QACtE,IAAI,KAAK;AAAA,QACT,SAAS,MAAM;AAAA,QACf,QAAQ,KAAK;AAAA,QACb;AAAA,QACA;AAAA,QACA,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,MAClB,GAAG;AAAA,QACD,YAAY;AAAA,QACZ,UAAU,MAAM;AAAA,QAChB,gBAAgB,MAAM;AAAA,MACxB,CAAC;AAAA,IACH;AACA,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,EAC9C;AAAA,EACA,cAAc,OAAO,UAAU,QAAQ,QAAQ;AAC7C,UAAM,QAAQ,kBAAkB,wBAAwB,QAAQ;AAChE,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,iBAAiB,IAAI,OAAO,QAAQ,KAAK;AAAA,EAClD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM,aAAa,4CAA4C,sBAAsB,OAAO,QAAQ,SAAS;AAAA,EAClJ,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAoC,QAAQ;AAC5D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,gBAAQ,MAAM,4BAA4B,IAAI,SAAS,OAAO,uBAAuB;AAAA,MACvF;AAAA,MACA,MAAM,wBAAwB,MAAM,MAAM,MAAM;AAAA,MAChD,MAAM,sBAAsB,IAAI,MAAM,KAAK;AAAA,IAC7C,GAAG,EAAE,aAAa,MAAM,OAAO,0CAA0C,CAAC;AAC1E,UAAM,iBAAiB,KAAK,MAAM,KAAK;AACvC,UAAM,iBAAiB,KAAK,WAAW,MAAM,IAAI;AAAA,EACnD;AACF;AAEA,MAAM,oCAA0H;AAAA,EAC9H,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,MAAM,CAAC,EAAE,OAAO,IAAI,MAAM,kCAAkC,QAAQ,EAAE,GAAG,OAAO,WAAW,OAAU,GAAG,GAAG;AAAA,EAC3G,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,QAAQ,kBAAkB,kCAAkC,QAAQ;AAC1E,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,EAAE,QAAQ,MAAM,iBAAiB,IAAI,MAAM,IAAI,KAAK,EAAE;AAAA,EAC/D;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,kBAAkB,kCAAkC,QAAQ;AAC1E,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM,kBAAkB,IAAI,MAAM,IAAI,KAAK;AACxD,UAAM,QAAQ,MAAM,mBAAmB,IAAI,UAAU,IAAI,GAAG,KAAK;AACjE,0BAAsB,KAAK;AAC3B,UAAM,mCAAmC,KAAK,MAAM,mCAAmC,MAAM,aAAa,MAAS;AAEnH,UAAM,gBAAgB,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,mBAAmB;AACxB,aAAK,YAAY,oBAAI,KAAK;AAC1B,yBAAiB,IAAI,OAAO,UAAU;AAAA,UACpC,YAAY;AAAA,UACZ,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ,KAAK;AAAA,YACb,kBAAkB,KAAK;AAAA,UACzB;AAAA,UACA,aAAa,IAAI,MAAM,OAAO;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,MACA,MAAM,sBAAsB,IAAI,KAAK;AAAA,IACvC,GAAG,EAAE,aAAa,MAAM,OAAO,gDAAgD,CAAC;AAEhF,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,aAAa,KAAK,WAAW,IAAI;AACvC,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,EAC9C;AAAA,EACA,cAAc,OAAO,UAAU,QAAQ,QAAQ;AAC7C,UAAM,QAAQ,kBAAkB,kCAAkC,QAAQ;AAC1E,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,iBAAiB,IAAI,OAAO,QAAQ,KAAK;AAAA,EAClD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM,aAAa,uDAAuD,gCAAgC,OAAO,QAAQ,SAAS;AAAA,EACvK,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAoC,QAAQ;AAC5D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,gBAAQ,MAAM,4BAA4B,IAAI,SAAS,OAAO,uBAAuB;AAAA,MACvF;AAAA,MACA,MAAM,wBAAwB,MAAM,MAAM,MAAM;AAAA,MAChD,MAAM,sBAAsB,IAAI,MAAM,KAAK;AAAA,IAC7C,GAAG,EAAE,aAAa,MAAM,OAAO,qDAAqD,CAAC;AACrF,UAAM,iBAAiB,KAAK,MAAM,KAAK;AACvC,UAAM,iBAAiB,KAAK,WAAW,MAAM,IAAI;AAAA,EACnD;AACF;AAEA,MAAM,gCAA6G;AAAA,EACjH,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,MAAM,CAAC,EAAE,OAAO,IAAI,MAAM,8BAA8B,QAAQ,EAAE,GAAG,OAAO,WAAW,OAAU,GAAG,GAAG;AAAA,EACvG,SAAS,OAAO,UAAU,QAAQ;AAChC,UAAM,QAAQ,kBAAkB,yBAAyB,QAAQ;AACjE,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,EAAE,QAAQ,MAAM,iBAAiB,IAAI,MAAM,IAAI,KAAK,EAAE;AAAA,EAC/D;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,QAAQ,kBAAkB,yBAAyB,QAAQ;AACjE,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM,kBAAkB,IAAI,MAAM,IAAI,KAAK;AACxD,UAAM,QAAQ,QAAQ,IAAI,KAAK,MAAM,mBAAmB,IAAI,UAAU,IAAI,GAAG,KAAK;AAClF,wBAAoB,KAAK;AACzB,UAAM,mCAAmC,KAAK,MAAM,mCAAmC,MAAM,aAAa,MAAS;AAEnH,UAAM,gBAAgB,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,oBAAoB,MAAM;AAC/B,aAAK,YAAY,oBAAI,KAAK;AAC1B,cAAM,YAAY,oBAAI,KAAK;AAC3B,yBAAiB,IAAI,OAAO,UAAU;AAAA,UACpC,YAAY;AAAA,UACZ,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ,KAAK;AAAA,UACf;AAAA,UACA,aAAa,IAAI,MAAM,OAAO;AAAA,QAChC,CAAC;AAAA,MACH;AAAA,IACF,GAAG,EAAE,aAAa,MAAM,OAAO,4CAA4C,CAAC;AAE5E,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,aAAa,KAAK,WAAW,IAAI;AACvC,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,MAAM,GAAG;AAAA,EAC9C;AAAA,EACA,cAAc,OAAO,UAAU,QAAQ,QAAQ;AAC7C,UAAM,QAAQ,kBAAkB,yBAAyB,QAAQ;AACjE,UAAM,QAAQ,aAAa,KAAK,KAAK;AACrC,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,iBAAiB,IAAI,OAAO,QAAQ,KAAK;AAAA,EAClD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM,aAAa,mDAAmD,0BAA0B,OAAO,QAAQ,SAAS;AAAA,EAC7J,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAoC,QAAQ;AAC5D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,gBAAQ,MAAM,4BAA4B,IAAI,SAAS,OAAO,qBAAqB;AAAA,MACrF;AAAA,MACA,MAAM,wBAAwB,MAAM,MAAM,MAAM;AAAA,MAChD,MAAM,sBAAsB,IAAI,MAAM,KAAK;AAAA,IAC7C,GAAG,EAAE,aAAa,MAAM,OAAO,iDAAiD,CAAC;AACjF,UAAM,iBAAiB,KAAK,MAAM,KAAK;AACvC,UAAM,iBAAiB,KAAK,WAAW,MAAM,IAAI;AAAA,EACnD;AACF;AAEA,gBAAgB,sBAAsB;AACtC,gBAAgB,sBAAsB;AACtC,gBAAgB,sBAAsB;AACtC,gBAAgB,uBAAuB;AACvC,gBAAgB,iCAAiC;AACjD,gBAAgB,6BAA6B;AAEtC,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import { randomUUID } from 'crypto'\nimport { LockMode } from '@mikro-orm/core'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { z } from 'zod'\nimport { registerCommand, type CommandHandler, type CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { invalidateCrudCache } from '@open-mercato/shared/lib/crud/cache'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { E } from '#generated/entities.ids.generated'\nimport { WarrantyClaim, WarrantyClaimLine } from '../data/entities'\nimport {\n claimLineCreateSchema,\n claimLineReceiveSchema,\n claimLineReleaseQuarantineSchema,\n claimLineUpdateSchema,\n type ClaimLineCreateInput,\n type ClaimLineReceiveInput,\n type ClaimLineReleaseQuarantineInput,\n type ClaimLineUpdateInput,\n type WarrantyClaimDisposition,\n type WarrantyClaimLineStatus,\n type WarrantyClaimWarrantyStatus,\n} from '../data/validators'\nimport { emitWarrantyClaimsEvent } from '../events'\nimport {\n assertDispositionAllowedForGrade,\n suggestedDispositionForGrade,\n type ConditionGrade,\n} from '../lib/grading'\nimport { assertDispositionAllowedForType, resolveClaimTypeUiConfig } from '../lib/claimTypeConfig'\nimport { resolveEffectiveWarrantyClaimSettings } from '../lib/settings'\nimport { computeHeaderRollups, lineStatusGuards } from '../lib/stateMachine'\nimport {\n WARRANTY_CLAIM_LINE_RESOURCE_KIND,\n WARRANTY_CLAIM_RESOURCE_KIND,\n appendClaimEvent,\n assertClaimLineNumberAvailable,\n assertUniqueClaimLineNumbers,\n enforceWarrantyClaimOptimisticLock,\n ensureOrganizationScope,\n ensureTenantScope,\n extractUndoPayload,\n requireScopedClaim,\n throwUndoRefusal,\n type WarrantyClaimScope,\n} from './shared'\nimport { assertPendingClaimQuantitiesWithinSold, validateClaimReferences } from './claims'\n\nconst claimCrudEvents: CrudEventsConfig = {\n module: 'warranty_claims',\n entity: 'claim',\n persistent: true,\n}\n\nconst lineDeleteSchema = z\n .object({\n id: z.string().uuid(),\n claimId: z.string().uuid().optional(),\n organizationId: z.string().uuid().optional(),\n tenantId: z.string().uuid().optional(),\n })\n .strict()\n\ntype LineDeleteInput = z.infer<typeof lineDeleteSchema>\n\nconst lineSetAssessmentSchema = z\n .object({\n id: z.string().uuid(),\n organizationId: z.string().uuid().optional(),\n tenantId: z.string().uuid().optional(),\n assessmentPayload: z.record(z.string(), z.unknown()),\n updatedAt: z.union([z.string().datetime(), z.date()]).nullable().optional(),\n })\n .strict()\n\ntype LineSetAssessmentInput = z.infer<typeof lineSetAssessmentSchema>\n\ntype ScopeInput = {\n organizationId?: string | null\n tenantId?: string | null\n}\n\ntype LineSnapshot = {\n id: string\n claimId: string\n organizationId: string\n tenantId: string\n lineNo: number\n productId: string | null\n variantId: string | null\n sku: string | null\n productName: string | null\n orderLineId: string | null\n serialNumber: string | null\n lotNumber: string | null\n purchaseDate: string | null\n warrantyMonths: number | null\n warrantyExpiresAt: string | null\n warrantyStatus: WarrantyClaimWarrantyStatus\n faultCode: string | null\n faultDescription: string | null\n qtyClaimed: string\n qtyApproved: string | null\n qtyReceived: string | null\n conditionOnReceipt: string | null\n conditionGrade: string | null\n quarantineStatus: string\n inspectionNotes: string | null\n assessmentPayload: Record<string, unknown> | null\n disposition: WarrantyClaimDisposition | null\n lineStatus: WarrantyClaimLineStatus\n creditAmount: string | null\n restockingFee: string | null\n coreChargeAmount: string | null\n coreCreditAmount: string | null\n vendorClaimLineId: string | null\n vendorName: string | null\n deletedAt: string | null\n updatedAt: string | null\n}\n\ntype LineUndoPayload = {\n before?: LineSnapshot | null\n after?: LineSnapshot | null\n}\n\nconst mutableParentStatuses = new Set([\n 'draft',\n 'submitted',\n 'in_review',\n 'info_requested',\n 'approved',\n 'received',\n 'inspecting',\n])\n\nconst receivingParentStatuses = new Set(['received', 'inspecting'])\n\ntype LineUndoParentRule = {\n allowedParentStatuses: ReadonlySet<string>\n lockedKey: string\n lockedFallback: string\n}\n\ntype LineUndoState = {\n claim: WarrantyClaim\n line: WarrantyClaimLine\n}\n\nconst mutableParentUndoRule: LineUndoParentRule = {\n allowedParentStatuses: mutableParentStatuses,\n lockedKey: 'warranty_claims.errors.lineLocked',\n lockedFallback: 'This line is locked in the current claim status.',\n}\n\nconst receivingParentUndoRule: LineUndoParentRule = {\n allowedParentStatuses: receivingParentStatuses,\n lockedKey: 'warranty_claims.errors.receivingStatusInvalid',\n lockedFallback: 'Receiving details can only be saved when the claim is received or under inspection.',\n}\n\nfunction parseCommandInput<T>(schema: z.ZodType<T>, rawInput: unknown): T {\n const result = schema.safeParse(rawInput ?? {})\n if (!result.success) {\n throw new CrudHttpError(400, { error: '[internal] invalid warranty claim line command input' })\n }\n return result.data\n}\n\nfunction hasOwn(input: object, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(input, key)\n}\n\nfunction resolveScope(ctx: CommandRuntimeContext, input: ScopeInput): WarrantyClaimScope {\n const tenantId = input.tenantId ?? ctx.auth?.tenantId ?? null\n const organizationId = input.organizationId ?? ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n if (!tenantId) throw new CrudHttpError(400, { error: '[internal] tenant scope required for warranty claim line command' })\n if (!organizationId) throw new CrudHttpError(400, { error: '[internal] organization scope required for warranty claim line command' })\n ensureTenantScope(ctx, tenantId)\n ensureOrganizationScope(ctx, organizationId)\n return { tenantId, organizationId }\n}\n\nfunction toIso(value: Date | string | null | undefined): string | null {\n if (!value) return null\n const date = value instanceof Date ? value : new Date(value)\n return Number.isNaN(date.getTime()) ? null : date.toISOString()\n}\n\nfunction toDate(value: string | null): Date | null {\n if (!value) return null\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction toDateOnlyIso(value: Date | string | null | undefined): string | null {\n const iso = toIso(value)\n return iso ? iso.slice(0, 10) : null\n}\n\nfunction toDateOnly(value: string | null): Date | null {\n if (!value) return null\n const date = new Date(`${value}T00:00:00.000Z`)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction amountString(value: number | string | null | undefined, fallback = '0'): string | null {\n if (value === null) return null\n if (value === undefined) return fallback\n const parsed = typeof value === 'number' ? value : Number(value)\n if (!Number.isFinite(parsed)) return fallback\n return String(parsed)\n}\n\nfunction nullableAmountString(value: number | string | null | undefined): string | null {\n if (value === undefined || value === null) return null\n return amountString(value, '0')\n}\n\nfunction numberValue(value: string | number | null | undefined): number {\n if (value === null || value === undefined) return 0\n const parsed = typeof value === 'number' ? value : Number(value)\n return Number.isFinite(parsed) ? parsed : 0\n}\n\nfunction addMonths(date: Date, months: number): Date {\n const target = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + months, 1))\n const lastDay = new Date(Date.UTC(target.getUTCFullYear(), target.getUTCMonth() + 1, 0)).getUTCDate()\n const copy = new Date(date.getTime())\n copy.setUTCDate(1)\n copy.setUTCFullYear(target.getUTCFullYear(), target.getUTCMonth(), Math.min(date.getUTCDate(), lastDay))\n return copy\n}\n\nfunction computeWarrantyDates(\n purchaseDate: Date | null | undefined,\n warrantyMonths: number | null | undefined,\n): { warrantyExpiresAt: Date | null; warrantyStatus: WarrantyClaimWarrantyStatus } {\n if (!purchaseDate || warrantyMonths === null || warrantyMonths === undefined) {\n return { warrantyExpiresAt: null, warrantyStatus: 'unknown' }\n }\n const warrantyExpiresAt = addMonths(purchaseDate, warrantyMonths)\n const warrantyStatus = warrantyExpiresAt.getTime() >= Date.now() ? 'in_warranty' : 'out_of_warranty'\n return { warrantyExpiresAt, warrantyStatus }\n}\n\nfunction claimIdOf(line: WarrantyClaimLine): string {\n const claim = line.claim\n if (typeof claim === 'object' && claim && 'id' in claim && typeof claim.id === 'string') return claim.id\n return String(claim)\n}\n\nfunction claimOf(line: WarrantyClaimLine): WarrantyClaim | null {\n const claim = line.claim\n if (typeof claim === 'object' && claim && 'id' in claim && typeof claim.id === 'string') return claim as WarrantyClaim\n return null\n}\n\nfunction sameDateValue(left: Date | null | undefined, right: Date | null | undefined): boolean {\n const leftTime = left instanceof Date ? left.getTime() : null\n const rightTime = right instanceof Date ? right.getTime() : null\n return leftTime === rightTime\n}\n\nfunction assertParentMutable(claim: WarrantyClaim): void {\n if (!mutableParentStatuses.has(claim.status)) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n}\n\nfunction assertReceivingStatus(claim: WarrantyClaim): void {\n if (claim.status !== 'received' && claim.status !== 'inspecting') {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.receivingStatusInvalid' })\n }\n}\n\nfunction toConditionGrade(value: string | null | undefined): ConditionGrade | null {\n if (value === 'A' || value === 'B' || value === 'C' || value === 'D') return value\n return null\n}\n\nfunction assertLineQuantities(line: WarrantyClaimLine): void {\n const qtyClaimed = numberValue(line.qtyClaimed)\n const qtyApproved = line.qtyApproved === null || line.qtyApproved === undefined ? null : numberValue(line.qtyApproved)\n const qtyReceived = line.qtyReceived === null || line.qtyReceived === undefined ? null : numberValue(line.qtyReceived)\n if (qtyClaimed < 0 || (qtyApproved !== null && qtyApproved < 0) || (qtyReceived !== null && qtyReceived < 0)) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n if (qtyApproved !== null && qtyApproved > qtyClaimed) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n if (qtyReceived !== null && qtyReceived > qtyClaimed) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.lineLocked' })\n }\n}\n\nfunction assertLineStatusMove(from: WarrantyClaimLineStatus, to: WarrantyClaimLineStatus): void {\n if (from === to) return\n if (lineStatusGuards[from].includes(to)) return\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.invalidTransition' })\n}\n\nfunction buildLineCreateData(\n claim: WarrantyClaim,\n input: ClaimLineCreateInput,\n lineNo: number,\n): Partial<WarrantyClaimLine> & {\n id: string\n claim: WarrantyClaim\n organizationId: string\n tenantId: string\n lineNo: number\n qtyClaimed: string\n lineStatus: WarrantyClaimLineStatus\n warrantyStatus: WarrantyClaimWarrantyStatus\n createdAt: Date\n updatedAt: Date\n} {\n const purchaseDate = input.purchaseDate ?? null\n const warrantyMonths = input.warrantyMonths ?? null\n const computedWarranty = computeWarrantyDates(purchaseDate, warrantyMonths)\n return {\n id: randomUUID(),\n claim,\n organizationId: claim.organizationId,\n tenantId: claim.tenantId,\n lineNo,\n productId: input.productId ?? null,\n variantId: input.variantId ?? null,\n sku: input.sku ?? null,\n productName: input.productName ?? null,\n orderLineId: input.orderLineId ?? null,\n serialNumber: input.serialNumber ?? null,\n lotNumber: input.lotNumber ?? null,\n purchaseDate,\n warrantyMonths,\n warrantyExpiresAt: input.warrantyExpiresAt ?? computedWarranty.warrantyExpiresAt,\n warrantyStatus: input.warrantyStatus ?? computedWarranty.warrantyStatus,\n faultCode: input.faultCode ?? null,\n faultDescription: input.faultDescription ?? null,\n qtyClaimed: amountString(input.qtyClaimed, '1') ?? '1',\n qtyApproved: nullableAmountString(input.qtyApproved),\n qtyReceived: nullableAmountString(input.qtyReceived),\n conditionOnReceipt: input.conditionOnReceipt ?? null,\n inspectionNotes: input.inspectionNotes ?? null,\n disposition: input.disposition ?? null,\n vendorName: input.vendorName ?? null,\n lineStatus: 'pending',\n creditAmount: nullableAmountString(input.creditAmount),\n restockingFee: nullableAmountString(input.restockingFee),\n coreChargeAmount: nullableAmountString(input.coreChargeAmount),\n coreCreditAmount: nullableAmountString(input.coreCreditAmount),\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n}\n\nfunction applyLineUpdate(line: WarrantyClaimLine, input: ClaimLineUpdateInput): void {\n const purchaseDateChanged = hasOwn(input, 'purchaseDate') && !sameDateValue(line.purchaseDate ?? null, input.purchaseDate ?? null)\n const warrantyMonthsChanged = hasOwn(input, 'warrantyMonths') && (line.warrantyMonths ?? null) !== (input.warrantyMonths ?? null)\n const hasExplicitWarranty = hasOwn(input, 'warrantyExpiresAt') || hasOwn(input, 'warrantyStatus')\n if (hasOwn(input, 'lineNo') && input.lineNo !== undefined) line.lineNo = input.lineNo\n if (hasOwn(input, 'productId')) line.productId = input.productId ?? null\n if (hasOwn(input, 'variantId')) line.variantId = input.variantId ?? null\n if (hasOwn(input, 'sku')) line.sku = input.sku ?? null\n if (hasOwn(input, 'productName')) line.productName = input.productName ?? null\n if (hasOwn(input, 'orderLineId')) line.orderLineId = input.orderLineId ?? null\n if (hasOwn(input, 'serialNumber')) line.serialNumber = input.serialNumber ?? null\n if (hasOwn(input, 'lotNumber')) line.lotNumber = input.lotNumber ?? null\n if (hasOwn(input, 'purchaseDate')) line.purchaseDate = input.purchaseDate ?? null\n if (hasOwn(input, 'warrantyMonths')) line.warrantyMonths = input.warrantyMonths ?? null\n if (hasOwn(input, 'warrantyExpiresAt')) line.warrantyExpiresAt = input.warrantyExpiresAt ?? null\n if (hasOwn(input, 'warrantyStatus') && input.warrantyStatus) line.warrantyStatus = input.warrantyStatus\n if (hasOwn(input, 'faultCode')) line.faultCode = input.faultCode ?? null\n if (hasOwn(input, 'faultDescription')) line.faultDescription = input.faultDescription ?? null\n if (hasOwn(input, 'qtyClaimed') && input.qtyClaimed !== undefined) line.qtyClaimed = amountString(input.qtyClaimed, '1') ?? '1'\n if (hasOwn(input, 'qtyApproved')) line.qtyApproved = nullableAmountString(input.qtyApproved)\n if (hasOwn(input, 'qtyReceived')) line.qtyReceived = nullableAmountString(input.qtyReceived)\n if (hasOwn(input, 'conditionOnReceipt')) line.conditionOnReceipt = input.conditionOnReceipt ?? null\n if (hasOwn(input, 'inspectionNotes')) line.inspectionNotes = input.inspectionNotes ?? null\n if (hasOwn(input, 'disposition')) line.disposition = input.disposition ?? null\n if (hasOwn(input, 'vendorName')) line.vendorName = input.vendorName ?? null\n if (hasOwn(input, 'lineStatus') && input.lineStatus) {\n assertLineStatusMove(line.lineStatus, input.lineStatus)\n line.lineStatus = input.lineStatus\n }\n if (hasOwn(input, 'creditAmount')) line.creditAmount = nullableAmountString(input.creditAmount)\n if (hasOwn(input, 'restockingFee')) line.restockingFee = nullableAmountString(input.restockingFee)\n if (hasOwn(input, 'coreChargeAmount')) line.coreChargeAmount = nullableAmountString(input.coreChargeAmount)\n if (hasOwn(input, 'coreCreditAmount')) line.coreCreditAmount = nullableAmountString(input.coreCreditAmount)\n if ((purchaseDateChanged || warrantyMonthsChanged) && !hasExplicitWarranty) {\n const computedWarranty = computeWarrantyDates(line.purchaseDate ?? null, line.warrantyMonths ?? null)\n line.warrantyExpiresAt = computedWarranty.warrantyExpiresAt\n line.warrantyStatus = computedWarranty.warrantyStatus\n }\n line.updatedAt = new Date()\n}\n\nfunction snapshotLine(line: WarrantyClaimLine): LineSnapshot {\n return {\n id: line.id,\n claimId: claimIdOf(line),\n organizationId: line.organizationId,\n tenantId: line.tenantId,\n lineNo: line.lineNo,\n productId: line.productId ?? null,\n variantId: line.variantId ?? null,\n sku: line.sku ?? null,\n productName: line.productName ?? null,\n orderLineId: line.orderLineId ?? null,\n serialNumber: line.serialNumber ?? null,\n lotNumber: line.lotNumber ?? null,\n purchaseDate: toDateOnlyIso(line.purchaseDate),\n warrantyMonths: line.warrantyMonths ?? null,\n warrantyExpiresAt: toDateOnlyIso(line.warrantyExpiresAt),\n warrantyStatus: line.warrantyStatus,\n faultCode: line.faultCode ?? null,\n faultDescription: line.faultDescription ?? null,\n qtyClaimed: line.qtyClaimed,\n qtyApproved: line.qtyApproved ?? null,\n qtyReceived: line.qtyReceived ?? null,\n conditionOnReceipt: line.conditionOnReceipt ?? null,\n conditionGrade: line.conditionGrade ?? null,\n quarantineStatus: line.quarantineStatus,\n inspectionNotes: line.inspectionNotes ?? null,\n assessmentPayload: line.assessmentPayload ?? null,\n disposition: line.disposition ?? null,\n lineStatus: line.lineStatus,\n creditAmount: line.creditAmount ?? null,\n restockingFee: line.restockingFee ?? null,\n coreChargeAmount: line.coreChargeAmount ?? null,\n coreCreditAmount: line.coreCreditAmount ?? null,\n vendorClaimLineId: line.vendorClaimLineId ?? null,\n vendorName: line.vendorName ?? null,\n deletedAt: toIso(line.deletedAt),\n updatedAt: toIso(line.updatedAt),\n }\n}\n\nasync function loadLineSnapshot(\n em: EntityManager,\n lineId: string,\n scope: WarrantyClaimScope,\n): Promise<LineSnapshot | null> {\n const line = await findOneWithDecryption(\n em,\n WarrantyClaimLine,\n { id: lineId, tenantId: scope.tenantId, organizationId: scope.organizationId },\n { populate: ['claim'] },\n scope,\n )\n return line ? snapshotLine(line) : null\n}\n\nasync function assertLineSnapshotNumberAvailable(em: EntityManager, claim: WarrantyClaim, snapshot: LineSnapshot): Promise<void> {\n if (!snapshot.deletedAt) await assertClaimLineNumberAvailable(em, claim, snapshot.lineNo, snapshot.id, true)\n else await requireScopedClaim(em, claim.id, { tenantId: claim.tenantId, organizationId: claim.organizationId }, { lockMode: LockMode.PESSIMISTIC_WRITE })\n}\n\nfunction restoreLineFromSnapshot(line: WarrantyClaimLine, snapshot: LineSnapshot): void {\n line.lineNo = snapshot.lineNo\n line.productId = snapshot.productId\n line.variantId = snapshot.variantId\n line.sku = snapshot.sku\n line.productName = snapshot.productName\n line.orderLineId = snapshot.orderLineId\n line.serialNumber = snapshot.serialNumber\n line.lotNumber = snapshot.lotNumber\n line.purchaseDate = toDateOnly(snapshot.purchaseDate)\n line.warrantyMonths = snapshot.warrantyMonths\n line.warrantyExpiresAt = toDateOnly(snapshot.warrantyExpiresAt)\n line.warrantyStatus = snapshot.warrantyStatus\n line.faultCode = snapshot.faultCode\n line.faultDescription = snapshot.faultDescription\n line.qtyClaimed = snapshot.qtyClaimed\n line.qtyApproved = snapshot.qtyApproved\n line.qtyReceived = snapshot.qtyReceived\n line.conditionOnReceipt = snapshot.conditionOnReceipt\n line.conditionGrade = snapshot.conditionGrade\n line.quarantineStatus = snapshot.quarantineStatus\n line.inspectionNotes = snapshot.inspectionNotes\n line.assessmentPayload = snapshot.assessmentPayload\n line.disposition = snapshot.disposition\n line.lineStatus = snapshot.lineStatus\n line.creditAmount = snapshot.creditAmount\n line.restockingFee = snapshot.restockingFee\n line.coreChargeAmount = snapshot.coreChargeAmount\n line.coreCreditAmount = snapshot.coreCreditAmount\n line.vendorClaimLineId = snapshot.vendorClaimLineId\n line.vendorName = snapshot.vendorName\n line.deletedAt = toDate(snapshot.deletedAt)\n line.updatedAt = new Date()\n}\n\nasync function recomputeClaimRollups(em: EntityManager, claim: WarrantyClaim): Promise<void> {\n const lines = await findWithDecryption(\n em,\n WarrantyClaimLine,\n {\n claim: claim.id,\n tenantId: claim.tenantId,\n organizationId: claim.organizationId,\n deletedAt: null,\n },\n {},\n { tenantId: claim.tenantId, organizationId: claim.organizationId },\n )\n const totals = computeHeaderRollups(lines, { claimType: claim.claimType })\n claim.totalClaimedAmount = String(totals.totalClaimedAmount)\n claim.totalApprovedAmount = String(totals.totalApprovedAmount)\n claim.updatedAt = new Date()\n}\n\nfunction refuseLineUndoConflict(): Promise<never> {\n return throwUndoRefusal('warranty_claims.errors.conflict', 'This claim changed while you were editing it.')\n}\n\nasync function requireCurrentLineUndoState(\n em: EntityManager,\n after: LineSnapshot | null | undefined,\n rule: LineUndoParentRule,\n): Promise<LineUndoState> {\n if (!after) return refuseLineUndoConflict()\n const scope: WarrantyClaimScope = { tenantId: after.tenantId, organizationId: after.organizationId }\n const claim = await findOneWithDecryption(\n em,\n WarrantyClaim,\n { id: after.claimId, tenantId: scope.tenantId, organizationId: scope.organizationId, deletedAt: null },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n if (!claim) return refuseLineUndoConflict()\n if (!rule.allowedParentStatuses.has(claim.status)) return throwUndoRefusal(rule.lockedKey, rule.lockedFallback)\n const line = await findOneWithDecryption(\n em,\n WarrantyClaimLine,\n { id: after.id, tenantId: scope.tenantId, organizationId: scope.organizationId },\n { lockMode: LockMode.PESSIMISTIC_WRITE },\n scope,\n )\n if (!line || !after.updatedAt || toIso(line.updatedAt) !== after.updatedAt) return refuseLineUndoConflict()\n return { claim, line }\n}\n\nasync function requireScopedLine(\n em: EntityManager,\n lineId: string,\n scope: WarrantyClaimScope,\n): Promise<WarrantyClaimLine> {\n const line = await findOneWithDecryption(\n em,\n WarrantyClaimLine,\n { id: lineId, tenantId: scope.tenantId, organizationId: scope.organizationId, deletedAt: null },\n { populate: ['claim'] },\n scope,\n )\n if (!line) throw new CrudHttpError(404, { error: 'warranty_claims.errors.notFound' })\n return line\n}\n\nasync function emitClaimUpdated(ctx: CommandRuntimeContext, claim: WarrantyClaim): Promise<void> {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: claim,\n identifiers: { id: claim.id, organizationId: claim.organizationId, tenantId: claim.tenantId },\n indexer: { entityType: E.warranty_claims.warranty_claim },\n events: claimCrudEvents,\n })\n await invalidateCrudCache(\n ctx.container,\n 'warranty_claims.claim',\n { id: claim.id, organizationId: claim.organizationId, tenantId: claim.tenantId },\n ctx.auth?.tenantId ?? null,\n 'warranty_claims.claim_line.rollup',\n )\n}\n\nasync function emitLineCrud(\n ctx: CommandRuntimeContext,\n action: 'created' | 'updated' | 'deleted',\n line: WarrantyClaimLine,\n): Promise<void> {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action,\n entity: line,\n identifiers: { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n indexer: { entityType: E.warranty_claims.warranty_claim_line },\n })\n await invalidateCrudCache(\n ctx.container,\n 'warranty_claims.claim_line',\n { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n ctx.auth?.tenantId ?? null,\n `warranty_claims.claim_line.${action}`,\n )\n}\n\nasync function emitLineUndoCrud(\n ctx: CommandRuntimeContext,\n action: 'created' | 'updated' | 'deleted',\n line: WarrantyClaimLine,\n): Promise<void> {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action,\n entity: line,\n identifiers: { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n indexer: { entityType: E.warranty_claims.warranty_claim_line },\n })\n await invalidateCrudCache(\n ctx.container,\n 'warranty_claims.claim_line',\n { id: line.id, organizationId: line.organizationId, tenantId: line.tenantId },\n ctx.auth?.tenantId ?? null,\n `warranty_claims.claim_line.undo.${action}`,\n )\n}\n\nasync function buildLineLog(\n actionLabelKey: string,\n actionLabelFallback: string,\n resourceId: string,\n snapshots: { before?: unknown; after?: unknown },\n): Promise<{\n actionLabel: string\n resourceKind: string\n resourceId: string\n parentResourceKind: string | null\n parentResourceId: string | null\n tenantId: string | null\n organizationId: string | null\n snapshotBefore: unknown\n snapshotAfter: unknown\n payload: { undo: LineUndoPayload }\n}> {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as LineSnapshot | null | undefined\n const before = snapshots.before as LineSnapshot | null | undefined\n return {\n actionLabel: translate(actionLabelKey, actionLabelFallback),\n resourceKind: WARRANTY_CLAIM_LINE_RESOURCE_KIND,\n resourceId,\n parentResourceKind: WARRANTY_CLAIM_RESOURCE_KIND,\n parentResourceId: after?.claimId ?? before?.claimId ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n snapshotAfter: after ?? null,\n payload: { undo: { before: before ?? null, after: after ?? null } },\n }\n}\n\nconst createClaimLineCommand: CommandHandler<ClaimLineCreateInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.create',\n isUndoable: true,\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineCreateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const claim = await requireScopedClaim(em, input.claimId, scope)\n assertDispositionAllowedForType(claim.claimType, input.disposition ?? null)\n await enforceWarrantyClaimOptimisticLock(ctx, claim)\n assertParentMutable(claim)\n let line!: WarrantyClaimLine\n let nextLineNo = input.lineNo ?? 1\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE, refresh: true })\n assertParentMutable(claim)\n if (input.orderLineId) {\n await validateClaimReferences(ctx, scope, {\n lineOrderRefs: [{ orderLineId: input.orderLineId, orderId: claim.orderId ?? null }],\n })\n }\n const existingLines = await findWithDecryption(\n em,\n WarrantyClaimLine,\n {\n claim: claim.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n {},\n scope,\n )\n if (input.orderLineId) {\n await assertPendingClaimQuantitiesWithinSold(em, scope, new Map([[input.orderLineId, [{\n orderLineId: input.orderLineId,\n qtyClaimed: amountString(input.qtyClaimed, '1') ?? '1',\n }]]]), { currentClaimId: claim.id })\n }\n nextLineNo = input.lineNo ?? existingLines.reduce((max, entry) => Math.max(max, entry.lineNo), 0) + 1\n await assertUniqueClaimLineNumbers([nextLineNo, ...existingLines.filter((line) => line.lineNo === nextLineNo).map((line) => line.lineNo)])\n },\n () => {\n line = em.create(WarrantyClaimLine, buildLineCreateData(claim, input, nextLineNo))\n assertLineQuantities(line)\n em.persist(line)\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.create' })\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'created', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineCreateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.create', 'Add claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n },\n () => {\n state.line.deletedAt = new Date()\n state.line.updatedAt = new Date()\n },\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.create.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'deleted', state.line)\n },\n}\n\nconst updateClaimLineCommand: CommandHandler<ClaimLineUpdateInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.update',\n isUndoable: true,\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(claimLineUpdateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineUpdateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = claimOf(line) ?? await requireScopedClaim(em, input.claimId ?? claimIdOf(line), scope)\n if (input.claimId && input.claimId !== claim.id) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.notFound' })\n }\n assertParentMutable(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND)\n const effectiveOrderLineId = hasOwn(input, 'orderLineId') ? (input.orderLineId ?? null) : (line.orderLineId ?? null)\n if (hasOwn(input, 'disposition')) {\n assertDispositionAllowedForType(claim.claimType, input.disposition ?? null)\n assertDispositionAllowedForGrade(toConditionGrade(line.conditionGrade), input.disposition ?? null)\n }\n const guardsClaimedQty = hasOwn(input, 'qtyClaimed') || hasOwn(input, 'orderLineId')\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE, refresh: true })\n assertParentMutable(claim)\n if (input.lineNo !== undefined) await assertClaimLineNumberAvailable(em, claim, input.lineNo, line.id)\n if (effectiveOrderLineId && (claim.orderId || effectiveOrderLineId !== (line.orderLineId ?? null))) {\n await validateClaimReferences(ctx, scope, {\n lineOrderRefs: [{\n orderLineId: effectiveOrderLineId,\n orderId: claim.orderId ?? null,\n allowMissing: effectiveOrderLineId === (line.orderLineId ?? null),\n }],\n })\n }\n if (!guardsClaimedQty) return\n const orderLineId = hasOwn(input, 'orderLineId') ? (input.orderLineId ?? null) : (line.orderLineId ?? null)\n if (orderLineId) {\n await assertPendingClaimQuantitiesWithinSold(\n em,\n scope,\n new Map([[orderLineId, [{\n id: line.id,\n orderLineId,\n qtyClaimed: hasOwn(input, 'qtyClaimed')\n ? (amountString(input.qtyClaimed, '1') ?? '1')\n : line.qtyClaimed,\n }]]]),\n { currentClaimId: claim.id, excludedLineIds: new Set([line.id]) },\n )\n }\n },\n () => {\n applyLineUpdate(line, input)\n assertLineQuantities(line)\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.update' })\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineUpdateSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.update', 'Update claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n await assertLineSnapshotNumberAvailable(em, state.claim, before)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.update.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nconst deleteClaimLineCommand: CommandHandler<LineDeleteInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.delete',\n isUndoable: true,\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(lineDeleteSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(lineDeleteSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = claimOf(line) ?? await requireScopedClaim(em, input.claimId ?? claimIdOf(line), scope)\n if (input.claimId && input.claimId !== claim.id) {\n throw new CrudHttpError(400, { error: 'warranty_claims.errors.notFound' })\n }\n assertParentMutable(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND)\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE })\n },\n () => {\n line.deletedAt = new Date()\n line.updatedAt = new Date()\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.delete' })\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'deleted', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(lineDeleteSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.delete', 'Delete claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n await assertLineSnapshotNumberAvailable(em, state.claim, before)\n },\n () => {\n restoreLineFromSnapshot(state.line, before)\n state.line.deletedAt = null\n },\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.delete.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'created', state.line)\n },\n}\n\nconst receiveClaimLineCommand: CommandHandler<ClaimLineReceiveInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.receive',\n isUndoable: true,\n redo: ({ input, ctx }) => receiveClaimLineCommand.execute({ ...input, updatedAt: undefined }, ctx),\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(claimLineReceiveSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineReceiveSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = await requireScopedClaim(em, claimIdOf(line), scope)\n assertReceivingStatus(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND, input.updatedAt ?? undefined)\n\n const grade: ConditionGrade = input.conditionGrade\n const effectiveSettings = await resolveEffectiveWarrantyClaimSettings(em, scope)\n const shouldQuarantine = Boolean(effectiveSettings.quarantineGrades?.includes(grade))\n\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE })\n },\n () => {\n line.conditionGrade = grade\n if (input.inspectionNotes !== undefined) line.inspectionNotes = input.inspectionNotes ?? null\n\n const suggestedDisposition = suggestedDispositionForGrade(grade)\n if (!line.disposition && suggestedDisposition && resolveClaimTypeUiConfig(claim.claimType).allowedDispositions.includes(suggestedDisposition)) {\n assertDispositionAllowedForGrade(grade, suggestedDisposition)\n if (suggestedDisposition === 'restock' || suggestedDisposition === 'repair' || suggestedDisposition === 'scrap') {\n line.disposition = suggestedDisposition\n }\n }\n assertDispositionAllowedForGrade(grade, line.disposition ?? null)\n\n if (shouldQuarantine) line.quarantineStatus = 'held'\n line.updatedAt = new Date()\n appendClaimEvent(em, claim, 'system', {\n visibility: 'internal',\n payload: {\n action: 'line_received',\n lineId: line.id,\n conditionGrade: grade,\n disposition: line.disposition ?? null,\n quarantineStatus: line.quarantineStatus,\n quarantineHeld: shouldQuarantine,\n },\n actorUserId: ctx.auth?.sub ?? null,\n })\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.receive' })\n\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n if (shouldQuarantine) {\n await emitWarrantyClaimsEvent('warranty_claims.claim_line.quarantined', {\n id: line.id,\n claimId: claim.id,\n lineId: line.id,\n grade,\n scope,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n }, {\n persistent: true,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n })\n }\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineReceiveSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.receive', 'Receive claim line', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, receivingParentUndoRule)\n await assertLineSnapshotNumberAvailable(em, state.claim, before)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.receive.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nconst releaseClaimLineQuarantineCommand: CommandHandler<ClaimLineReleaseQuarantineInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.release_quarantine',\n isUndoable: true,\n redo: ({ input, ctx }) => releaseClaimLineQuarantineCommand.execute({ ...input, updatedAt: undefined }, ctx),\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(claimLineReleaseQuarantineSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(claimLineReleaseQuarantineSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = await requireScopedClaim(em, claimIdOf(line), scope)\n assertReceivingStatus(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND, input.updatedAt ?? undefined)\n\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE })\n },\n () => {\n line.quarantineStatus = 'released'\n line.updatedAt = new Date()\n appendClaimEvent(em, claim, 'system', {\n visibility: 'internal',\n payload: {\n action: 'line_quarantine_released',\n lineId: line.id,\n quarantineStatus: line.quarantineStatus,\n },\n actorUserId: ctx.auth?.sub ?? null,\n })\n },\n () => recomputeClaimRollups(em, claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.release_quarantine' })\n\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(claimLineReleaseQuarantineSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.release_quarantine', 'Release line from quarantine', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, receivingParentUndoRule)\n await assertLineSnapshotNumberAvailable(em, state.claim, before)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.release_quarantine.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nconst setClaimLineAssessmentCommand: CommandHandler<LineSetAssessmentInput, { lineId: string; claimId: string }> = {\n id: 'warranty_claims.claim_line.set_assessment',\n isUndoable: true,\n redo: ({ input, ctx }) => setClaimLineAssessmentCommand.execute({ ...input, updatedAt: undefined }, ctx),\n prepare: async (rawInput, ctx) => {\n const input = parseCommandInput(lineSetAssessmentSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return { before: await loadLineSnapshot(em, input.id, scope) }\n },\n async execute(rawInput, ctx) {\n const input = parseCommandInput(lineSetAssessmentSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const line = await requireScopedLine(em, input.id, scope)\n const claim = claimOf(line) ?? await requireScopedClaim(em, claimIdOf(line), scope)\n assertParentMutable(claim)\n await enforceWarrantyClaimOptimisticLock(ctx, line, WARRANTY_CLAIM_LINE_RESOURCE_KIND, input.updatedAt ?? undefined)\n\n await withAtomicFlush(em, [\n async () => {\n await requireScopedClaim(em, claim.id, scope, { lockMode: LockMode.PESSIMISTIC_WRITE })\n },\n () => {\n line.assessmentPayload = input.assessmentPayload\n line.updatedAt = new Date()\n claim.updatedAt = new Date()\n appendClaimEvent(em, claim, 'system', {\n visibility: 'internal',\n payload: {\n action: 'ai_assessment_recorded',\n lineId: line.id,\n },\n actorUserId: ctx.auth?.sub ?? null,\n })\n },\n ], { transaction: true, label: 'warranty_claims.claim_line.set_assessment' })\n\n await emitClaimUpdated(ctx, claim)\n await emitLineCrud(ctx, 'updated', line)\n return { lineId: line.id, claimId: claim.id }\n },\n captureAfter: async (rawInput, result, ctx) => {\n const input = parseCommandInput(lineSetAssessmentSchema, rawInput)\n const scope = resolveScope(ctx, input)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadLineSnapshot(em, result.lineId, scope)\n },\n buildLog: async ({ result, snapshots }) => buildLineLog('warranty_claims.audit.claim_line.set_assessment', 'Record line assessment', result.lineId, snapshots),\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<LineUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let state!: LineUndoState\n await withAtomicFlush(em, [\n async () => {\n state = await requireCurrentLineUndoState(em, payload?.after, mutableParentUndoRule)\n await assertLineSnapshotNumberAvailable(em, state.claim, before)\n },\n () => restoreLineFromSnapshot(state.line, before),\n () => recomputeClaimRollups(em, state.claim),\n ], { transaction: true, label: 'warranty_claims.claim_line.set_assessment.undo' })\n await emitClaimUpdated(ctx, state.claim)\n await emitLineUndoCrud(ctx, 'updated', state.line)\n },\n}\n\nregisterCommand(createClaimLineCommand)\nregisterCommand(updateClaimLineCommand)\nregisterCommand(deleteClaimLineCommand)\nregisterCommand(receiveClaimLineCommand)\nregisterCommand(releaseClaimLineQuarantineCommand)\nregisterCommand(setClaimLineAssessmentCommand)\n\nexport const claimLineCommands = [\n createClaimLineCommand,\n updateClaimLineCommand,\n deleteClaimLineCommand,\n receiveClaimLineCommand,\n releaseClaimLineQuarantineCommand,\n setClaimLineAssessmentCommand,\n]\n\nexport {\n createClaimLineCommand,\n updateClaimLineCommand,\n deleteClaimLineCommand,\n receiveClaimLineCommand,\n releaseClaimLineQuarantineCommand,\n setClaimLineAssessmentCommand,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["line"]
|
|
7
7
|
}
|
|
@@ -40,6 +40,7 @@ import { evaluateClaimRisk } from "../lib/risk.js";
|
|
|
40
40
|
import {
|
|
41
41
|
WARRANTY_CLAIM_RESOURCE_KIND,
|
|
42
42
|
appendClaimEvent,
|
|
43
|
+
assertUniqueClaimLineNumbers,
|
|
43
44
|
enforceWarrantyClaimOptimisticLock,
|
|
44
45
|
ensureOrganizationScope,
|
|
45
46
|
ensureTenantScope,
|
|
@@ -444,9 +445,25 @@ async function assertUndoSnapshotCurrent(ctx, after) {
|
|
|
444
445
|
}
|
|
445
446
|
async function restoreSnapshot(em, before, after) {
|
|
446
447
|
const { claim, lines } = await requireCurrentUndoSnapshot(em, after);
|
|
447
|
-
restoreClaimDelta(claim, before, after);
|
|
448
448
|
const beforeLinesById = new Map((Array.isArray(before.lines) ? before.lines : []).map((line) => [line.id, line]));
|
|
449
449
|
const afterLinesById = new Map((Array.isArray(after.lines) ? after.lines : []).map((line) => [line.id, line]));
|
|
450
|
+
const projectedLines = [];
|
|
451
|
+
for (const line of lines) {
|
|
452
|
+
const beforeLine = beforeLinesById.get(line.id);
|
|
453
|
+
const afterLine = afterLinesById.get(line.id);
|
|
454
|
+
if (!beforeLine || !afterLine) return throwClaimUndoConflict();
|
|
455
|
+
const deletedAt = beforeLine.deletedAt !== afterLine.deletedAt ? beforeLine.deletedAt : line.deletedAt;
|
|
456
|
+
const lineNo = beforeLine.lineNo !== afterLine.lineNo ? beforeLine.lineNo : line.lineNo;
|
|
457
|
+
projectedLines.push({ id: line.id, lineNo, deletedAt, changesNumber: Boolean(line.deletedAt) || lineNo !== line.lineNo });
|
|
458
|
+
}
|
|
459
|
+
for (const projected of projectedLines) {
|
|
460
|
+
if (projected.deletedAt || !projected.changesNumber) continue;
|
|
461
|
+
await assertUniqueClaimLineNumbers([
|
|
462
|
+
projected.lineNo,
|
|
463
|
+
...projectedLines.filter((line) => !line.deletedAt && line.id !== projected.id && line.lineNo === projected.lineNo).map((line) => line.lineNo)
|
|
464
|
+
]);
|
|
465
|
+
}
|
|
466
|
+
restoreClaimDelta(claim, before, after);
|
|
450
467
|
for (const line of lines) {
|
|
451
468
|
const beforeLine = beforeLinesById.get(line.id);
|
|
452
469
|
const afterLine = afterLinesById.get(line.id);
|
|
@@ -955,6 +972,7 @@ const createClaimCommand = {
|
|
|
955
972
|
isUndoable: true,
|
|
956
973
|
async execute(rawInput, ctx) {
|
|
957
974
|
const input = parseCommandInput(claimCreateSchema, rawInput);
|
|
975
|
+
await assertUniqueClaimLineNumbers((input.lines ?? []).map((line, index) => line.lineNo ?? index + 1));
|
|
958
976
|
const scope = resolveScope(ctx, input);
|
|
959
977
|
const em = ctx.container.resolve("em").fork();
|
|
960
978
|
await validateClaimReferences(ctx, scope, {
|