/** * 治理台路由契约(编码规范 §8.1 / §9.1)。 * 治理台九功能不设后端 governance 模块:每个功能是对应模块的管理用例 + 本文件的路由组装(§3)。 */ import { z } from 'zod'; import type { RouteContract } from './http.ts'; import { disableCheckSchema, grantSchema, positionSchema, staffSchema } from '../org.ts'; import { positionIdSchema, staffIdSchema } from '../id.ts'; /* ── 员工管理 ─────────────────────────────────────────────────────────── */ export const listStaffRoute = { method: 'GET', path: '/api/gov/staff', output: z.object({ staff: z.array(staffSchema.extend({ position: positionSchema })), positions: z.array(positionSchema), }), } as const satisfies RouteContract; export const createStaffRoute = { method: 'POST', path: '/api/gov/staff', body: z.object({ account: z.string().min(1), name: z.string().min(1), positionId: positionIdSchema, }), output: staffSchema, } as const satisfies RouteContract; export const disableStaffCheckRoute = { method: 'GET', path: '/api/gov/staff/:staffId/disable-check', params: z.object({ staffId: staffIdSchema }), output: disableCheckSchema, } as const satisfies RouteContract; export const disableStaffRoute = { method: 'POST', path: '/api/gov/staff/:staffId/disable', params: z.object({ staffId: staffIdSchema }), output: z.object({ ok: z.boolean(), check: disableCheckSchema }), } as const satisfies RouteContract; export const listGrantsRoute = { method: 'GET', path: '/api/gov/positions/:positionId/grants', params: z.object({ positionId: positionIdSchema }), output: z.object({ grants: z.array(grantSchema) }), } as const satisfies RouteContract; export const setGrantsRoute = { method: 'POST', path: '/api/gov/positions/:positionId/grants', params: z.object({ positionId: positionIdSchema }), body: z.object({ grants: z.array(grantSchema) }), output: z.object({ grants: z.array(grantSchema) }), } as const satisfies RouteContract; /* ── 系统管理 · LLM 实例(四元绑定) ────────────────────────────────── */ export const LLM_PROVIDERS = ['openai-compatible', 'openai', 'deepseek', 'anthropic', 'qwen'] as const; export const llmProviderSchema = z.enum(LLM_PROVIDERS); export type LlmProvider = z.infer; /** 活动只见自定义模型名;Provider / URL / API-Key / Model 四元在系统侧绑定,活动不触厂商与密钥 */ export const llmInstanceViewSchema = z.object({ id: z.string(), /** 自定义模型名(逻辑名)—— 活动以此声明引用 */ name: z.string().min(1), provider: llmProviderSchema, baseUrl: z.string().min(1), model: z.string().min(1), /** 密钥不出治理台:只回是否已绑定,永不回明文(OS 7.3 凭证隔离) */ apiKeyBound: z.boolean(), /** 系统用途绑定:叙述性小结 / 汇报生成 / 蒸馏钩子,计量入系统账 */ systemUse: z.boolean().default(false), enabled: z.boolean().default(true), }); export type LlmInstanceView = z.infer; export const listLlmInstancesRoute = { method: 'GET', path: '/api/gov/llm', output: z.object({ instances: z.array(llmInstanceViewSchema) }), } as const satisfies RouteContract; export const upsertLlmInstanceRoute = { method: 'POST', path: '/api/gov/llm', body: z.object({ id: z.string().optional(), name: z.string().min(1), provider: llmProviderSchema, baseUrl: z.string().min(1), model: z.string().min(1), /** 只写不读:留空表示保持原值 */ apiKey: z.string().optional(), systemUse: z.boolean().default(false), enabled: z.boolean().default(true), }), output: llmInstanceViewSchema, } as const satisfies RouteContract; export const probeLlmInstanceRoute = { method: 'POST', path: '/api/gov/llm/:id/probe', params: z.object({ id: z.string() }), output: z.object({ ok: z.boolean(), latencyMs: z.number().int().optional(), error: z.string().optional() }), } as const satisfies RouteContract;