Deploy / deploy (push) Canceled after 0s
- 前端 oj/api.ts、admin/api.ts、shared/api.ts 的 post / put 请求体一律 `satisfies XxxRequest`, 只在编译期检查,不加运行时校验(和「只在三处挂运行时闸门」的规矩一致) - 契约里的 XxxRequest 从 z.infer 改成 z.input:请求类型描述的是「客户端可以发什么」, 带默认值的字段可以不传。后端从不用这些类型(它用 parse 出来的 data),不受影响 - 补了四个漏导出的请求类型(比赛题目排序、题单题目排序、标签分类、检查用户名) - 接上之后对不上的几处:编辑用户的角色和题目权限经 toAdminType / toProblemPermission 收窄,导入用户的行改成四元组,练习题数据改成 Record,格式化的语言只收后端认的四种 (isFormatLanguage)。出题页和成就的请求体是「表单校验兜底、出站补默认值」, 用 Partial<…> 只核键名和值的类型 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
34 lines
983 B
TypeScript
34 lines
983 B
TypeScript
import { z } from "zod"
|
|
|
|
export const loginRequestSchema = z.object({
|
|
username: z.string().trim().min(1).max(150),
|
|
password: z.string().min(1).max(1024),
|
|
})
|
|
|
|
export const sessionUserSchema = z.object({
|
|
id: z.number().int(),
|
|
username: z.string(),
|
|
email: z.string().nullable(),
|
|
adminType: z.string(),
|
|
problemPermission: z.string(),
|
|
createTime: z.string().nullable(),
|
|
lastLogin: z.string().nullable(),
|
|
isDisabled: z.boolean(),
|
|
className: z.string().nullable(),
|
|
})
|
|
|
|
export const userProfileSchema = z.object({
|
|
id: z.number().int(),
|
|
user: sessionUserSchema,
|
|
realName: z.string().nullable(),
|
|
acmProblemsStatus: z.record(z.string(), z.unknown()),
|
|
avatar: z.string(),
|
|
mood: z.string().nullable(),
|
|
acceptedNumber: z.number().int(),
|
|
submissionNumber: z.number().int(),
|
|
})
|
|
|
|
export type LoginRequest = z.input<typeof loginRequestSchema>
|
|
export type SessionUser = z.infer<typeof sessionUserSchema>
|
|
export type UserProfile = z.infer<typeof userProfileSchema>
|