// Synthetic teaching example. This is not a production CRM client or an access-control system. export type Inspection = { id: string; jobId: string; version: number; approved: boolean; approvedBy: string; note: string; task: { owner: string; text: string }; }; export type Receipt = { key: string; jobId: string; note: string; task: { owner: string; text: string } }; export type Destination = { getJob(id: string): Promise<{ id: string } | null>; find(key: string): Promise; write(receipt: Receipt): Promise; }; export type Event = { at: string; action: string; detail: string }; export type Outcome = { status: 'confirmed' | 'pending' | 'uncertain' | 'held'; events: Event[]; next: string }; export type Failure = 'unavailable' | 'response-lost' | 'none'; export const inspection: Inspection = { id: 'INS-DEMO-204', jobId: 'DEMO-204', version: 1, approved: true, approvedBy: 'Morgan', note: 'Estimator to assess chimney flashing; replacement not confirmed. Customer asks whether it is included in the proposed scope.', task: { owner: 'Morgan', text: 'Review flashing evidence before the revised proposal.' }, }; export function receiptFor(record: Inspection): Receipt { return { key: `${record.id}:approved-v${record.version}`, jobId: record.jobId, note: record.note, task: { ...record.task } }; } export function sameReceipt(a: Receipt, b: Receipt) { return a.key === b.key && a.jobId === b.jobId && a.note === b.note && a.task.owner === b.task.owner && a.task.text === b.task.text; } export class DestinationError extends Error { definiteRejection: boolean; constructor(definiteRejection: boolean) { super(definiteRejection ? 'Write rejected' : 'Confirmation unavailable'); this.definiteRejection = definiteRejection; } } // Both the browser exercise and HTTP fixture tests use this exact orchestration. // A real implementation must enforce approval and authorization in trusted server-side code. export async function sendInspection(record: Inspection, destination: Destination): Promise { const events: Event[] = []; const log = (action: string, detail: string) => events.push({ at: new Date().toISOString(), action, detail }); const held = (reason: string): Outcome => { log('Handoff held', reason); return { status: 'held', events, next: 'Morgan: resolve the record or approval issue before sending.' }; }; if (!record.approved || !record.approvedBy) return held('Manager approval is required. No destination request was made.'); const expected = receiptFor(record); try { const job = await destination.getJob(record.jobId); if (!job || job.id !== record.jobId) return held('The destination job did not match the inspection job. No write was made.'); log('Job matched', `Inspection and destination both identify ${record.jobId}.`); const existing = await destination.find(expected.key); if (existing) { if (!sameReceipt(existing, expected)) return held('An existing result differs from the approved version. It needs review.'); log('Existing result verified', 'The approved note and assigned task already exist. No additional write was sent.'); return { status: 'confirmed', events, next: `${record.task.owner}: ${record.task.text}` }; } log('Destination checked', 'No result for this approved version. Sending one note and one assigned task.'); await destination.write(expected); // A successful write response is not the completion signal: inspect the saved result. const saved = await destination.find(expected.key); if (!saved || !sameReceipt(saved, expected)) { log('Verification incomplete', 'The saved note and task could not be verified against the approved version.'); return { status: 'uncertain', events, next: 'Morgan: inspect the destination before retrying.' }; } log('Saved result verified', `One approved note and one assigned task confirmed on ${record.jobId}.`); return { status: 'confirmed', events, next: `${record.task.owner}: ${record.task.text}` }; } catch (error) { const rejected = error instanceof DestinationError && error.definiteRejection; log(rejected ? 'Write rejected' : 'Confirmation unavailable', rejected ? 'The mock CRM rejected the write. The handoff remains pending.' : 'The sender cannot confirm the result. It may already exist; do not replay it blindly.'); return { status: rejected ? 'pending' : 'uncertain', events, next: 'Morgan: restore the connection, check the destination, then retry only if absent.' }; } } // Per-component state only. No real records, persistent storage or provider calls. export function memoryDestination(initial: Failure) { const receipts = new Map(); let failure = initial; let writeRequests = 0; const destination: Destination = { async getJob(id) { return id === inspection.jobId ? { id } : null; }, async find(key) { const result = receipts.get(key); return result ? structuredClone(result) : null; }, async write(receipt) { writeRequests++; if (failure === 'unavailable') throw new DestinationError(true); const prior = receipts.get(receipt.key); if (prior && !sameReceipt(prior, receipt)) throw new DestinationError(true); receipts.set(receipt.key, structuredClone(receipt)); if (failure === 'response-lost') { failure = 'none'; throw new DestinationError(false); } }, }; return { destination, restore: () => { failure = 'none'; }, snapshot: () => ({ receipts: [...receipts.values()].map(x => structuredClone(x)), writeRequests }) }; }