mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
feat(api): gate assistant endpoints on the feature-flag matrix
Every LLM-driven endpoint now reads the operator flag set near the
top of the handler and throws `AssistantDisabledError` when the
relevant surface is off. The api-handler catches the typed error
and returns the 403 envelope:
{ data: null, error: "...", meta: { errorCode: "assistant.disabled.<surface>" } }
Gates per the v1.4.31 brief:
/api/insights/chat → coach (POST + GET rail)
/api/insights/generate → coach
/api/insights/comprehensive → coach
/api/insights/cards → insightStatus
/api/insights/correlations → correlations
/api/insights/{weight,bmi,blood-pressure,pulse,mood,
medication-compliance}-status → insightStatus
Master `assistantEnabled = false` forces every sub-flag false in
the resolver, so flipping the master 403s every endpoint at once.
Older iOS clients see a generic 403 (their existing 403-handler
covers the case); v1.4.31+ clients read the `errorCode` to render
the `<AssistantDisabledNotice>` empty state. Locked per
`.planning/RESPONSE-TO-IOS-TEAM-2026-05-16.md` §3 R5.
This commit is contained in:
1 parent
61c9a1e792
commit
aeff47afde
16 files changed
+239
-2
No files matched your search
+19
-1
@@ -9,6 +9,7 @@ import { getSession } from "./auth/session";
|
||||
import { hashToken } from "./auth/hmac";
|
||||
import { prisma } from "./db";
|
||||
import { auditLog } from "./auth/audit";
|
||||
import { AssistantDisabledError } from "./feature-flags";
|
||||
|
||||
/**
|
||||
* Custom error class for HTTP errors with status codes.
|
||||
@@ -162,7 +163,24 @@ export function apiHandler<T extends (...args: any[]) => Promise<Response>>(
|
||||
try {
|
||||
response = await handler(...args);
|
||||
} catch (error) {
|
||||
if (error instanceof HttpError) {
|
||||
if (error instanceof AssistantDisabledError) {
|
||||
// v1.4.31 — operator has disabled the assistant surface.
|
||||
// The 403 + `errorCode: "assistant.disabled.<surface>"`
|
||||
// envelope is locked per
|
||||
// `.planning/RESPONSE-TO-IOS-TEAM-2026-05-16.md` §3 R5.
|
||||
// Older iOS clients that don't know the errorCode surface
|
||||
// this as a generic 403; v1.4.31+ clients render the
|
||||
// `<AssistantDisabledNotice>` empty state.
|
||||
evt.setError(error);
|
||||
response = NextResponse.json(
|
||||
{
|
||||
data: null,
|
||||
error: error.message,
|
||||
meta: { errorCode: error.errorCode },
|
||||
},
|
||||
{ status: 403 },
|
||||
);
|
||||
} else if (error instanceof HttpError) {
|
||||
evt.setError(error);
|
||||
response = NextResponse.json(
|
||||
{ data: null, error: error.message },
|
||||
|
||||
Reference in new issue
Block a user