mirror of
https://github.com/temetro/temetro.git
synced 2026-09-03 14:27:58 +00:00
feat(ai): clinic-wide AI kill-switch (admin-controlled)
- new org_ai_policy table + GET/PUT /api/ai/policy (read for any member, write owner/admin only); migration 0018 - /api/chat hard-blocks (403) when AI is off for the caller - Settings → AI "Availability" section: enable AI, or disable for employees only (owners/admins keep access); read-only for non-admins - sidebar, command palette and route guard hide/redirect the AI chat when it's disabled for the current user Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
import { recordActivity } from "../services/activity.js";
|
||||
import * as aiChat from "../services/ai-chat.js";
|
||||
import { getAiSettings } from "../services/ai/config.js";
|
||||
import { aiAllowedFor, getPolicy } from "../services/ai/policy.js";
|
||||
import { resolveModel } from "../services/ai/provider.js";
|
||||
import { createChatTools } from "../services/ai/tools.js";
|
||||
import { createVeil } from "../services/ai/veil.js";
|
||||
@@ -146,6 +147,13 @@ chatRouter.post("/", async (req, res, next) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Honour the clinic's AI kill-switch — employees can't reach the agent even
|
||||
// by bypassing the (also-gated) UI.
|
||||
const policy = await getPolicy(req.organizationId!);
|
||||
if (!aiAllowedFor(policy, req.memberRole)) {
|
||||
throw new HttpError(403, "The AI assistant is disabled for your account.");
|
||||
}
|
||||
|
||||
const settings = await getAiSettings(req.user!.id);
|
||||
const modelId = requestedModel || settings.defaultModel;
|
||||
const resolved = resolveModel(settings, modelId);
|
||||
|
||||
Reference in New Issue
Block a user