mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
feat(documents): gate document, lab and medication reading on their capabilities
Reading a document, scanning a lab report and turning a medication description into a schedule follow documentAi, labsOcr and medicationExtract. Unavailable, the action is not offered. With only the document-reading consent missing, the place that reads asks for it and grants exactly that (ai_extraction), nothing wider. Refusals are read by meta.errorCode: a 403 is no longer always called a missing consent, and a spent daily budget no longer shows the rate-limit sentence.
This commit is contained in:
1 parent
48d97ef70d
commit
4449b34ac7
15 files changed
+466
-40
No files matched your search
@@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiPost } from "@/lib/api/api-fetch";
|
||||
import { queryKeys } from "@/lib/query-keys";
|
||||
|
||||
/**
|
||||
* Grant the consent for reading documents (`ai_extraction`) from the place
|
||||
* that needs it.
|
||||
*
|
||||
* Sending a document, a lab report scan or a typed medication description to
|
||||
* an AI service outside this server needs its own receipt. The narrow kind
|
||||
* covers exactly that and never the Coach or AI analysis, so asking for it
|
||||
* where a document is being read asks for no more than the reader is about to
|
||||
* do. The tap on the prompt IS the consent act; the receipt records it with
|
||||
* its source, the same way the web settings record a full grant.
|
||||
*
|
||||
* On success `/api/auth/me` is refetched, because the capabilities it
|
||||
* publishes (`documentAi`, `labsOcr`, `medicationExtract`) are what every
|
||||
* reading surface renders from.
|
||||
*/
|
||||
export function useGrantDocumentReadingConsent() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationKey: queryKeys.aiExtractionConsentGrant(),
|
||||
mutationFn: async () => {
|
||||
const signedAt = new Date().toISOString();
|
||||
return apiPost("/api/consent/ai", {
|
||||
kind: "ai_extraction",
|
||||
signedAt,
|
||||
artefact: JSON.stringify({
|
||||
source: "web",
|
||||
kind: "ai_extraction",
|
||||
grantedAt: signedAt,
|
||||
note: "In-app affirmative consent to reading documents, granted via the web client.",
|
||||
}),
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
void queryClient.invalidateQueries({ queryKey: queryKeys.authMe() });
|
||||
void queryClient.invalidateQueries({
|
||||
queryKey: queryKeys.aiConsentReceipt("ai_extraction"),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user