/** * Sales verification labels (§39, §205). A HEURISTIC over fields RareIndex already stores — it never * claims a transaction was independently confirmed. Labels: * verified — an auction-house / grading-company result, an auction with a confident match, or a * high-trust source with a very confident match * likely — a valid, confidently matched completed listing from an ordinary source * unverified — flagged by outlier detection, weak identification, or a low-trust source * excluded — bundles, zero prices and other records the pipeline excluded from valuation */ export type SaleVerification = 'verified' | 'likely' | 'unverified' | 'excluded'; export interface SaleVerificationInput { status: string | null | undefined; // valid | flagged | excluded confidence: number | null | undefined; // 0–1 identification confidence flags?: string[] | null; sourceType?: string | null; // marketplace | auction_house | grading_company | dealer | … saleType?: string | null; // auction | fixed_price | best_offer | private | dealer | unknown trust?: number | null; // 0–1 source trust score } export const VERIFIED_SOURCE_TYPES = new Set(['auction_house', 'grading_company']); export function classifySale(i: SaleVerificationInput): { label: SaleVerification; reason: string } { const conf = i.confidence ?? 0; const trust = i.trust ?? 0.5; if (i.status === 'excluded') return { label: 'excluded', reason: (i.flags ?? []).join(', ') || 'excluded by the pipeline' }; if (i.status === 'flagged') return { label: 'unverified', reason: `flagged: ${(i.flags ?? []).join(', ') || 'outlier'}` }; if (conf < 0.6) return { label: 'unverified', reason: 'weak identification' }; if (trust < 0.5) return { label: 'unverified', reason: 'low-trust source' }; if (i.sourceType && VERIFIED_SOURCE_TYPES.has(i.sourceType)) return { label: 'verified', reason: `${i.sourceType.replace('_', ' ')} result` }; if (i.saleType === 'auction' && conf >= 0.8) return { label: 'verified', reason: 'auction result, confident match' }; if (trust >= 0.8 && conf >= 0.85) return { label: 'verified', reason: 'high-trust source, confident match' }; return { label: 'likely', reason: 'completed listing, confident match' }; } export function countVerification(labels: SaleVerification[]): Record { const out: Record = { verified: 0, likely: 0, unverified: 0, excluded: 0 }; for (const l of labels) out[l]++; return out; }