由外部 agent (Codex) 在本会话额度中断期间完成。原样提交作为基线, 后续修复单独成 commit,便于区分与回退。 覆盖 oj 侧 65 个端点,新增 9 组路由(account/achievement/ai/classroom/ content/contest/flowchart/problemset/site)与对应 Zod 契约。 已核验:tsc --noEmit 退出码 0;API 可启动;/api/problems 返回真实数据; judge 与 flowchart worker 均 ready。 未核验:权限边界与数据泄露,评审进行中。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import { z } from "zod"
|
|
|
|
export const classRankItemSchema = z.object({
|
|
className: z.string(),
|
|
userCount: z.number().int(),
|
|
totalAc: z.number().int(),
|
|
totalSubmission: z.number().int(),
|
|
avgAc: z.number(),
|
|
acRate: z.number(),
|
|
rank: z.number().int(),
|
|
})
|
|
|
|
export const classUserRankItemSchema = z.object({
|
|
userId: z.number().int(),
|
|
username: z.string(),
|
|
acceptedNumber: z.number().int(),
|
|
submissionNumber: z.number().int(),
|
|
rank: z.number().int(),
|
|
})
|
|
|
|
export const classUserRankSchema = z.object({
|
|
className: z.string(),
|
|
myRank: z.number().int(),
|
|
total: z.number().int(),
|
|
ranks: z.array(classUserRankItemSchema),
|
|
})
|
|
|
|
export const classComparisonSchema = z.object({
|
|
className: z.string(),
|
|
userCount: z.number().int(),
|
|
totalAc: z.number().int(),
|
|
totalSubmission: z.number().int(),
|
|
avgAc: z.number(),
|
|
medianAc: z.number(),
|
|
q1Ac: z.number(),
|
|
q3Ac: z.number(),
|
|
iqr: z.number(),
|
|
stdDev: z.number(),
|
|
top10Avg: z.number(),
|
|
middle80Avg: z.number(),
|
|
bottom10Avg: z.number(),
|
|
excellentRate: z.number(),
|
|
passRate: z.number(),
|
|
activeRate: z.number(),
|
|
acRate: z.number(),
|
|
compositeScore: z.number(),
|
|
recentTotalAc: z.number().int().optional(),
|
|
recentTotalSubmission: z.number().int().optional(),
|
|
recentAvgAc: z.number().optional(),
|
|
recentMedianAc: z.number().optional(),
|
|
recentTop10Avg: z.number().optional(),
|
|
recentActiveCount: z.number().int().optional(),
|
|
})
|
|
|
|
export const classComparisonRequestSchema = z.object({
|
|
classNames: z.array(z.string()).min(1),
|
|
startTime: z.string().optional(),
|
|
endTime: z.string().optional(),
|
|
})
|
|
|
|
export const classComparisonResponseSchema = z.object({
|
|
comparisons: z.array(classComparisonSchema),
|
|
hasTimeRange: z.boolean(),
|
|
})
|