refactor(契约): 补齐 80 个类型导出,前端不再手抄形状
契约原来有 184 个 schema 但只导出了 104 个类型,缺的那 80 个前端只能照着
手抄一遍 —— 这是「表格列静默空白」那一类 bug 的根因(d3348f9、2edb8cf,
以及上一个 commit 修的 Top100 两列)。现在 186 个 schema 对 186 个类型,
一一对应,下次要用直接 import。
补导出是机械的(fooSchema → Foo),零命名冲突。真正有价值的是换的过程中
契约逼出来的 5 处分歧 —— 手抄那份在说谎,而 vue-tsc 拦不住,因为类型说它是对的:
- Tutorial.createdBy 手抄成了可选的 `User`(即 AdminUser,带 email、
rawPassword),后端下发的是必有的 SampleUser。读 createdBy.email 会拿到
undefined。列表页因此被迫写 `row.createdBy?.username` 和 `row.createdAt!`,
换成契约类型后两处断言都不需要了。
- TutorialListItem 手抄成 `Omit<Tutorial, "content">`,但后端列表接口连 code
一起省了 —— 类型声称 code 在。
- Testcase 手抄成 `{input_name, output_name, score}`:响应实际有 5 个字段,
且**没有 score**。score 是上传完成后前端按测试点数量平分补上去的,手抄那份
把本地字段说成了响应字段。现在写成 `TestCaseEntry & { score: string }`。
- Tag 手抄成 `{id, name}`,契约是 `{id, name, problemCount}` —— shared/api.ts
只好用 `Tag & { problemCount: number }` 把丢掉的补回来。
- CreateMessage 是旧后端按名字投递的形状(sender/recipient/submission),
契约要的是 recipientId/submissionId。全仓零引用,删掉。
同时删掉另外两个零引用的手写类型:LANGUAGE_SHOW_LABEL、UserAdminType;
本地重复的 SampleUser 换成契约的;oj/problem/list.vue 里本地第三份 Tag 改成
`ContractTag & { checked: boolean }`。
需要收窄的一律**从契约派生再收窄**,字段名跟着契约走,只有真正本地的那一两个
键是自己的:
export type Exercise = Omit<AdminExercise, "data"> & { data: 七种题型的联合 }
export type SubmitCodePayload =
Omit<CreateSubmissionRequest, "language"> & { language: LANGUAGE }
保留不动的窄化:StatisticInfo / SubmissionInfo(判题 JSONB 原文,snake_case)、
SQLDisplay*、ProblemFiltered(视图模型)、Exercise*Data(契约里 data 就是
Record<string, unknown>,七种题型结构不同,后端本来也不校验)。
types.ts 的手写 interface 从 31 个降到 22 个。
顺带修的代码:admin/tutorial/detail.vue 新建教程的表单对象缺三个后端产出的
字段,加了 TutorialEdit(对齐 BlankProblem / BlankContest 的写法);三处测试点
上传原来是拿响应对象原地塞 score,改成 map 出新对象,分数算法一字未改。
验证:apps/api tsc(7.0.2) 0 error、check:routes 168 条无遮蔽、
apps/web vue-tsc 0 error、vite build 通过。改动绝大部分在类型层,运行时只有
测试点上传那三处(等价替换)—— **那条路径要传 zip 才能实跑,没有实打**,
只做了代码等价性核对。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -67,3 +67,5 @@ export type UserRank = z.infer<typeof userRankSchema>
|
||||
export type MyRank = z.infer<typeof myRankSchema>
|
||||
export type ActivityRankItem = z.infer<typeof activityRankItemSchema>
|
||||
export type Metrics = z.infer<typeof metricsSchema>
|
||||
|
||||
export type PublicProfile = z.infer<typeof publicProfileSchema>
|
||||
|
||||
@@ -67,3 +67,5 @@ export type AchievementSummary = z.infer<typeof achievementSummarySchema>
|
||||
export type AchievementRarity = z.infer<typeof achievementRaritySchema>
|
||||
export type AchievementRarityStat = z.infer<typeof achievementRarityStatSchema>
|
||||
export type AchievementNotification = z.infer<typeof achievementNotificationSchema>
|
||||
|
||||
export type MarkAchievementsRead = z.infer<typeof markAchievementsReadSchema>
|
||||
|
||||
@@ -668,3 +668,58 @@ export type BatchProblemTagResponse = z.infer<typeof batchProblemTagResponseSche
|
||||
export type SqlTestCaseScript = z.infer<typeof sqlTestCaseScriptSchema>
|
||||
export type GenerateSqlTestCaseResponse = z.infer<typeof generateSqlTestCaseResponseSchema>
|
||||
export type AdminProblemSetProgress = z.infer<typeof adminProblemSetProgressSchema>
|
||||
|
||||
export type AdminAnnouncementList = z.infer<typeof adminAnnouncementListSchema>
|
||||
export type CreateAnnouncementRequest = z.infer<typeof createAnnouncementRequestSchema>
|
||||
export type UpdateAnnouncementRequest = z.infer<typeof updateAnnouncementRequestSchema>
|
||||
export type TutorialType = z.infer<typeof tutorialTypeSchema>
|
||||
export type AdminTutorial = z.infer<typeof adminTutorialSchema>
|
||||
export type AdminTutorialListItem = z.infer<typeof adminTutorialListItemSchema>
|
||||
export type AdminTutorialGroups = z.infer<typeof adminTutorialGroupsSchema>
|
||||
export type CreateTutorialRequest = z.infer<typeof createTutorialRequestSchema>
|
||||
export type UpdateTutorialRequest = z.infer<typeof updateTutorialRequestSchema>
|
||||
export type SetTutorialVisibilityRequest = z.infer<typeof setTutorialVisibilityRequestSchema>
|
||||
export type ExerciseType = z.infer<typeof exerciseTypeSchema>
|
||||
export type AdminExercise = z.infer<typeof adminExerciseSchema>
|
||||
export type CreateExerciseRequest = z.infer<typeof createExerciseRequestSchema>
|
||||
export type UpdateExerciseRequest = z.infer<typeof updateExerciseRequestSchema>
|
||||
export type ToggleAiReportPinResponse = z.infer<typeof toggleAiReportPinResponseSchema>
|
||||
export type AchievementOperator = z.infer<typeof achievementOperatorSchema>
|
||||
export type CreateAchievementRequest = z.infer<typeof createAchievementRequestSchema>
|
||||
export type UpdateAchievementRequest = z.infer<typeof updateAchievementRequestSchema>
|
||||
export type UpdateUserRequest = z.infer<typeof updateUserRequestSchema>
|
||||
export type ImportUsersRequest = z.infer<typeof importUsersRequestSchema>
|
||||
export type DeleteUsersRequest = z.infer<typeof deleteUsersRequestSchema>
|
||||
export type ResetPasswordResponse = z.infer<typeof resetPasswordResponseSchema>
|
||||
export type UpdateWebsiteConfigRequest = z.infer<typeof updateWebsiteConfigRequestSchema>
|
||||
export type UpdateJudgeServerRequest = z.infer<typeof updateJudgeServerRequestSchema>
|
||||
export type UploadImageResponse = z.infer<typeof uploadImageResponseSchema>
|
||||
export type CreateContestRequest = z.infer<typeof createContestRequestSchema>
|
||||
export type UpdateContestRequest = z.infer<typeof updateContestRequestSchema>
|
||||
export type UpdateAcmHelperRequest = z.infer<typeof updateAcmHelperRequestSchema>
|
||||
export type ProblemSetDifficulty = z.infer<typeof problemSetDifficultySchema>
|
||||
export type ProblemSetStatus = z.infer<typeof problemSetStatusSchema>
|
||||
export type BadgeConditionType = z.infer<typeof badgeConditionTypeSchema>
|
||||
export type AdminProblemSet = z.infer<typeof adminProblemSetSchema>
|
||||
export type AdminProblemSetList = z.infer<typeof adminProblemSetListSchema>
|
||||
export type CreateProblemSetRequest = z.infer<typeof createProblemSetRequestSchema>
|
||||
export type UpdateProblemSetRequest = z.infer<typeof updateProblemSetRequestSchema>
|
||||
export type UpdateProblemSetStatusRequest = z.infer<typeof updateProblemSetStatusRequestSchema>
|
||||
export type AdminProblemSetProblem = z.infer<typeof adminProblemSetProblemSchema>
|
||||
export type AddProblemToSetRequest = z.infer<typeof addProblemToSetRequestSchema>
|
||||
export type UpdateProblemInSetRequest = z.infer<typeof updateProblemInSetRequestSchema>
|
||||
export type AdminProblemSetBadge = z.infer<typeof adminProblemSetBadgeSchema>
|
||||
export type CreateProblemSetBadgeRequest = z.infer<typeof createProblemSetBadgeRequestSchema>
|
||||
export type UpdateProblemSetBadgeRequest = z.infer<typeof updateProblemSetBadgeRequestSchema>
|
||||
export type RenameTagRequest = z.infer<typeof renameTagRequestSchema>
|
||||
export type BatchProblemTagRequest = z.infer<typeof batchProblemTagRequestSchema>
|
||||
export type AcTrendYear = z.infer<typeof acTrendYearSchema>
|
||||
export type GenerateFlowchartRequest = z.infer<typeof generateFlowchartRequestSchema>
|
||||
export type GenerateFlowchartResponse = z.infer<typeof generateFlowchartResponseSchema>
|
||||
export type UpdateProblemRequest = z.infer<typeof updateProblemRequestSchema>
|
||||
export type MakeProblemPublicRequest = z.infer<typeof makeProblemPublicRequestSchema>
|
||||
export type AddContestProblemRequest = z.infer<typeof addContestProblemRequestSchema>
|
||||
export type TestCaseEntry = z.infer<typeof testCaseEntrySchema>
|
||||
export type UploadTestCaseResponse = z.infer<typeof uploadTestCaseResponseSchema>
|
||||
export type SqlPreviewRequest = z.infer<typeof sqlPreviewRequestSchema>
|
||||
export type GenerateSqlTestCaseRequest = z.infer<typeof generateSqlTestCaseRequestSchema>
|
||||
|
||||
@@ -109,3 +109,8 @@ export type AiDetail = z.infer<typeof aiDetailSchema>
|
||||
export type HeatmapItem = z.infer<typeof heatmapItemSchema>
|
||||
export type AiAnalysisRecord = z.infer<typeof aiAnalysisRecordSchema>
|
||||
export type LoginSummary = z.infer<typeof loginSummarySchema>
|
||||
|
||||
export type AiAnalysisRequest = z.infer<typeof aiAnalysisRequestSchema>
|
||||
export type AiHintRequest = z.infer<typeof aiHintRequestSchema>
|
||||
export type ClassAnalysisRequest = z.infer<typeof classAnalysisRequestSchema>
|
||||
export type ClassPkAnalysisRequest = z.infer<typeof classPkAnalysisRequestSchema>
|
||||
|
||||
@@ -67,3 +67,6 @@ export type ClassRankItem = z.infer<typeof classRankItemSchema>
|
||||
export type ClassUserRank = z.infer<typeof classUserRankSchema>
|
||||
export type ClassComparison = z.infer<typeof classComparisonSchema>
|
||||
export type ClassComparisonResponse = z.infer<typeof classComparisonResponseSchema>
|
||||
|
||||
export type ClassUserRankItem = z.infer<typeof classUserRankItemSchema>
|
||||
export type ClassComparisonRequest = z.infer<typeof classComparisonRequestSchema>
|
||||
|
||||
@@ -19,3 +19,5 @@ export function paginatedSchema<T extends z.ZodType>(item: T) {
|
||||
}
|
||||
|
||||
export type SampleUser = z.infer<typeof sampleUserSchema>
|
||||
|
||||
export type PaginationQuery = z.infer<typeof paginationQuerySchema>
|
||||
|
||||
@@ -77,3 +77,12 @@ export type Message = z.infer<typeof messageSchema>
|
||||
export type MessageList = z.infer<typeof messageListSchema>
|
||||
export type Announcement = z.infer<typeof announcementSchema>
|
||||
export type TutorialSummary = z.infer<typeof tutorialSummarySchema>
|
||||
|
||||
export type AnnouncementList = z.infer<typeof announcementListSchema>
|
||||
export type CreateMessageRequest = z.infer<typeof createMessageRequestSchema>
|
||||
export type ReactionKey = z.infer<typeof reactionKeySchema>
|
||||
export type ReactionCounts = z.infer<typeof reactionCountsSchema>
|
||||
export type ReactionState = z.infer<typeof reactionStateSchema>
|
||||
export type SetReactionRequest = z.infer<typeof setReactionRequestSchema>
|
||||
export type Tutorial = z.infer<typeof tutorialSchema>
|
||||
export type Exercise = z.infer<typeof exerciseSchema>
|
||||
|
||||
@@ -46,3 +46,7 @@ export type ContestList = z.infer<typeof contestListSchema>
|
||||
export type ContestRankItem = z.infer<typeof contestRankItemSchema>
|
||||
export type ContestRank = z.infer<typeof contestRankSchema>
|
||||
export type ContestAccess = z.infer<typeof contestAccessSchema>
|
||||
|
||||
export type ContestStatus = z.infer<typeof contestStatusSchema>
|
||||
export type ContestPasswordRequest = z.infer<typeof contestPasswordRequestSchema>
|
||||
export type ContestProblems = z.infer<typeof contestProblemsSchema>
|
||||
|
||||
@@ -96,3 +96,5 @@ export type FlowchartCurrent = z.infer<typeof flowchartCurrentSchema>
|
||||
export type FlowchartDetail = z.infer<typeof flowchartDetailSchema>
|
||||
export type CreateFlowchartResponse = z.infer<typeof createFlowchartResponseSchema>
|
||||
export type CreateFlowchartRequest = z.infer<typeof createFlowchartRequestSchema>
|
||||
|
||||
export type FlowchartStatus = z.infer<typeof flowchartStatusSchema>
|
||||
|
||||
@@ -107,3 +107,7 @@ export type ProblemSetProgress = z.infer<typeof problemSetProgressSchema>
|
||||
export type ProblemSetProgressList = z.infer<typeof problemSetProgressListSchema>
|
||||
export type UserBadge = z.infer<typeof userBadgeSchema>
|
||||
export type CompletedProblem = z.infer<typeof completedProblemSchema>
|
||||
|
||||
export type ProblemSetUserProgressSummary = z.infer<typeof problemSetUserProgressSummarySchema>
|
||||
export type JoinProblemSetRequest = z.infer<typeof joinProblemSetRequestSchema>
|
||||
export type UpdateProblemSetProgressRequest = z.infer<typeof updateProblemSetProgressRequestSchema>
|
||||
|
||||
@@ -146,3 +146,6 @@ export type SubmissionList = z.infer<typeof submissionListSchema>
|
||||
export type EmbeddedSubmission = z.infer<typeof embeddedSubmissionSchema>
|
||||
export type CreateSubmissionResponse = z.infer<typeof createSubmissionResponseSchema>
|
||||
export type FormatCodeResponse = z.infer<typeof formatCodeResponseSchema>
|
||||
|
||||
export type ShareSubmissionRequest = z.infer<typeof shareSubmissionRequestSchema>
|
||||
export type FormatCodeRequest = z.infer<typeof formatCodeRequestSchema>
|
||||
|
||||
Reference in New Issue
Block a user