refactor(后端): 权限判断收到一处,路由文件之间不再互相 import

- services/permissions.ts:「超管或创建者」原来在比赛、题单、比赛题目(4 处)、
  services/contest.ts 各抄一遍,「题目全部权限」在题目和标签两个路由各写一份
- services/submission-filters.ts:提交列表的用户名 / 班级 / 题号筛选,原来
  submission.ts、flowchart.ts 从 submission-statistics.ts 这个路由文件里拿
- services/class-activity.ts:课堂做题记录的口径和「正在上课的班」,原来后台
  conf.ts 从 classroom.ts 路由里拿
- services/problem-tags.ts:标签名去重、按名查标签,原来 tag.ts 从 admin/problem.ts 拿

纯搬家。三种身份(超管 / 老师 / 学生)打了 26 个受影响的接口,改前改后状态码和响应体
逐字节一致,包括「不是自己的比赛 / 题单 / 题目报不存在」那几条。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-16 14:53:24 +08:00
1 parent 5787efe023
commit 465dbfd42f
14 files changed
+388 -361

No files matched your search

+2 -1
View File
@@ -17,6 +17,7 @@ import type { AuthUser } from "../auth/session"
import { getContestPassword } from "../auth/session"
import { db, schema } from "../db"
import { failure } from "../http"
import { ownsOrSuper } from "./permissions"
export type ContestRow = typeof schema.contest.$inferSelect
@@ -39,7 +40,7 @@ export function contestStatus(contest: ContestRow) {
}
export function isContestAdmin(user: AuthUser | null | undefined, contest: ContestRow) {
return Boolean(user && (user.id === contest.createdById || user.adminType === "Super Admin"))
return Boolean(user && ownsOrSuper(user, contest))
}
export function contestDetailsAllowed(user: AuthUser | null | undefined, contest: ContestRow) {