统一鉴权中心接入(ADR-012):org 重写为 Keycloak 身份 + 角色→端;中间件按路由归属统一判;口令/会话/岗位授权退役;迁移 0032

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kAzS35kMnZNt4YGgJXtfw
This commit is contained in:
xcs
2026-08-25 17:40:55 +08:00
co-authored by Claude Opus 5
parent 81a185cd61
commit dd31b91829
38 changed files with 1236 additions and 1485 deletions
+7 -10
View File
@@ -23,13 +23,10 @@ import { MinuteNotFoundError, ResolutionAlreadyRegisteredError } from '@modules/
import type { Report } from '@modules/report';
import { ReportAlreadySubmittedError, ReportNotFoundError } from '@modules/report';
import type { Container } from '../container.ts';
import { staffOf } from '../http-env.ts';
import type { AppEnv } from '../http-env.ts';
export function registerDeskElementRoutes(app: Hono<AppEnv>, container: Container): void {
async function me(account: string) {
return container.org.findByAccount(account);
}
const unauthenticated: ApiError = { code: 'unauthenticated', message: '会话无效' };
/** 汇报投影:草案内容平铺,前端不必知道 draft 的嵌套 */
@@ -85,7 +82,7 @@ export function registerDeskElementRoutes(app: Hono<AppEnv>, container: Containe
});
app.post(createMinuteRoute.path, async (c) => {
const staff = await me(c.get('account'));
const staff = staffOf(c);
if (staff === undefined) return c.json(unauthenticated, 401);
const parsed = createMinuteRoute.body.safeParse(await c.req.json());
if (!parsed.success) {
@@ -104,7 +101,7 @@ export function registerDeskElementRoutes(app: Hono<AppEnv>, container: Containe
});
app.post(appendResolutionRoute.path, async (c) => {
const staff = await me(c.get('account'));
const staff = staffOf(c);
if (staff === undefined) return c.json(unauthenticated, 401);
const parsed = appendResolutionRoute.body.safeParse(await c.req.json());
if (!parsed.success) {
@@ -129,7 +126,7 @@ export function registerDeskElementRoutes(app: Hono<AppEnv>, container: Containe
/** 决议 → 登记起单:登记人即来源(OS 3.1) */
app.post(registerResolutionRoute.path, async (c) => {
const staff = await me(c.get('account'));
const staff = staffOf(c);
if (staff === undefined) return c.json(unauthenticated, 401);
const parsed = registerResolutionRoute.body.safeParse(await c.req.json());
if (!parsed.success) {
@@ -167,14 +164,14 @@ export function registerDeskElementRoutes(app: Hono<AppEnv>, container: Containe
/* ── 汇报 ─────────────────────────────────────────────────────────── */
app.get(listReportsRoute.path, async (c) => {
const staff = await me(c.get('account'));
const staff = staffOf(c);
if (staff === undefined) return c.json(unauthenticated, 401);
const reports = await container.report.list(staff.id);
return c.json({ reports: reports.map(toReportView) });
});
app.get(draftReportRoute.path, async (c) => {
const staff = await me(c.get('account'));
const staff = staffOf(c);
if (staff === undefined) return c.json(unauthenticated, 401);
const period = reportPeriodSchema.safeParse(c.req.param('period'));
if (!period.success) {
@@ -186,7 +183,7 @@ export function registerDeskElementRoutes(app: Hono<AppEnv>, container: Containe
});
app.post(submitReportRoute.path, async (c) => {
const staff = await me(c.get('account'));
const staff = staffOf(c);
if (staff === undefined) return c.json(unauthenticated, 401);
const parsed = submitReportRoute.body.safeParse(await c.req.json().catch(() => ({})));
try {