feat(crm): client-meeting batch — contact-pill cleanup, assignment toggle, receipt manual mode
CM-4: remove Email/Call/WhatsApp deep-link pills from the client + interest detail headers; relocate GDPR export into the client-header action cluster as a compact icon. Keeps the interest "Log contact" quick action. CM-5: gate the interest assignment feature behind a per-port `assignment_enabled` setting (default OFF for single-rep ports). Hides the AssignedToChip + residential assigned-to row and skips tier-2/3 auto-assign on create; the column + data are preserved and reversible. Tests cover the auto-assign guard. CM-6: add a per-port `manualEntry` receipt mode (skip all parsing → empty form). Threaded through ocr-config.service, the admin OCR form, the scan-receipt route, and the scanner shell (skips Tesseract + the server call). Tests cover the save/resolve round-trip. Verified: tsc clean, lint 0 errors, 1631 vitest pass, prod build green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { ScanShell } from '@/components/scan/scan-shell';
|
||||
import { db } from '@/lib/db';
|
||||
import { ports } from '@/lib/db/schema/ports';
|
||||
import { getPortBrandingConfig } from '@/lib/services/port-config';
|
||||
import { getResolvedOcrConfig } from '@/lib/services/ocr-config.service';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Scan receipt',
|
||||
@@ -14,5 +15,14 @@ export default async function ScanPage({ params }: { params: Promise<{ portSlug:
|
||||
const { portSlug } = await params;
|
||||
const port = await db.query.ports.findFirst({ where: eq(ports.slug, portSlug) });
|
||||
const branding = port ? await getPortBrandingConfig(port.id).catch(() => null) : null;
|
||||
return <ScanShell logoUrl={branding?.logoUrl ?? null} portName={port?.name ?? null} />;
|
||||
// CM-6: manual-entry mode is resolved server-side so the client can skip
|
||||
// on-device parsing entirely (no wasted Tesseract pass) and open an empty form.
|
||||
const ocr = port ? await getResolvedOcrConfig(port.id).catch(() => null) : null;
|
||||
return (
|
||||
<ScanShell
|
||||
logoUrl={branding?.logoUrl ?? null}
|
||||
portName={port?.name ?? null}
|
||||
manualEntry={ocr?.manualEntry ?? false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user