/** * Car-angle captures must live under {@code media.carAngles} with lowercase keys * {@code front | back | left | right}. Clients sometimes send Title Case keys or * mistakenly use {@code captureType: "part"} for angles, which previously wrote * into {@code media.damagedParts} and broke step-completion checks. */ export const CLAIM_CAR_ANGLE_KEYS = ["front", "back", "left", "right"] as const; export type ClaimCarAngleKey = (typeof CLAIM_CAR_ANGLE_KEYS)[number]; export function canonicalizeClaimCarAngleKey( raw: string | undefined | null, ): ClaimCarAngleKey | null { const t = String(raw ?? "").trim().toLowerCase(); return (CLAIM_CAR_ANGLE_KEYS as readonly string[]).includes(t) ? (t as ClaimCarAngleKey) : null; } function getCaptureBlob(data: unknown, key: string): unknown { if (data == null) return undefined; if (data instanceof Map) return (data as Map).get(key); return (data as Record)[key]; } /** Prefer carAngles; fall back to legacy mis-placed blobs under damagedParts. */ export function getClaimCarAngleCaptureBlob( carAnglesData: unknown, damagedPartsData: unknown, angle: ClaimCarAngleKey, ): unknown { return ( getCaptureBlob(carAnglesData, angle) ?? getCaptureBlob(damagedPartsData, angle) ?? getCaptureBlob( damagedPartsData, angle.charAt(0).toUpperCase() + angle.slice(1), ) ); } export function hasClaimCarAngleCapture( carAnglesData: unknown, damagedPartsData: unknown, angle: ClaimCarAngleKey, ): boolean { return getClaimCarAngleCaptureBlob(carAnglesData, damagedPartsData, angle) != null; } /** * Field names under media.damagedParts that should be removed when we persist the * same shot under media.carAngles (migration). Skips keys that are also real selected part ids. */ export function legacyAngleDamagedPartFieldKeysToUnset( canonical: ClaimCarAngleKey, rawCaptureKey: string, selectedParts: string[], ): string[] { const selected = new Set((selectedParts ?? []).map((p) => String(p))); const variants = new Set( [ rawCaptureKey, canonical, canonical.charAt(0).toUpperCase() + canonical.slice(1), ].filter(Boolean), ); const out: string[] = []; for (const k of variants) { if (canonicalizeClaimCarAngleKey(k) === null) continue; if (selected.has(k)) continue; out.push(k); } return [...new Set(out)]; }