Files
HealthLog/src/app/api/labs/ocr/capability/route.ts
T
Marc-André Bombeck bd8ea9d86b feat(ai): gate document, lab and medication extraction on their capabilities
Reading a stored document (suggest, summary, extract, index, chat,
reindex), scanning a lab report and turning medication text into a
schedule now answer under documentAi, labsOcr and medicationExtract. The
operator's master switch and the new reading-documents switch stop the
work and the egress; a module off for the record, a delegate inside
somebody else's record, and a missing receipt refuse with the capability
envelope. Existing no-provider codes keep their status.

The document pick and the labs pick re-check the capability for the
provider they picked, immediately before anything is sent, so a job
enqueued before a switch flipped finds no provider and falls back to the
provider-free text layer. Consent follows the document rule for all
three: any provider that leaves the machine needs an ai_extraction or
ai_full receipt, answered for the provider actually picked.

The fenced Coach chat and attachments answer under coach and documentAi.
Uploads are always stored and indexed; the background summary is only
enqueued while documentAi is open. The capability probes report the
capability beside the provider answer and keep a read offered when only
the receipt is missing. medications/extract keeps its 503 for no provider
and adds ai.provider.none, and its budget refusal gains the
coach.budget.exceeded code.
2026-09-24 08:44:57 +02:00

36 lines
1.2 KiB
TypeScript

/**
* v1.18.9 — GET /api/labs/ocr/capability
*
* Cheap probe (no provider call) the Labs UI uses to decide whether to show
* the "Scan a report" affordance. Returns `{ available, reason, pdfSupported }`
* for the calling user's configured AI provider. The surface stays dark for
* users with no provider configured and no local-OCR opt-in, and whenever the
* `labsOcr` capability is closed (operator switch, labs module, sharing grant);
* `ai` says which.
*/
import { apiHandler, requireAuth } from "@/lib/api-handler";
import { apiSuccess } from "@/lib/api-response";
import { resolveOcrCapability } from "@/lib/labs/ocr-capability";
import { annotate } from "@/lib/logging/context";
export const dynamic = "force-dynamic";
export const GET = apiHandler(async () => {
const { user } = await requireAuth();
const capability = await resolveOcrCapability(user.id);
annotate({
action: { name: "labs.ocr.capability" },
meta: {
available: capability.available,
mode: capability.mode,
reason: capability.reason,
pdfSupported: capability.pdfSupported,
aiReason: capability.ai.reason,
},
});
return apiSuccess(capability);
});