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:
@@ -181,14 +181,16 @@ async function upload() {
|
||||
const file = new File([blob], "testcase.zip", { type: "application/zip" })
|
||||
|
||||
const res = await uploadTestcases(file, { sql: true })
|
||||
const testcases: Testcase[] = res.data.info
|
||||
const baseScore = Math.floor(100 / testcases.length)
|
||||
const remainder = 100 - baseScore * testcases.length
|
||||
testcases.forEach((tc, i) => {
|
||||
tc.score = String(
|
||||
i === testcases.length - 1 ? baseScore + remainder : baseScore,
|
||||
)
|
||||
})
|
||||
// score 不在上传响应里,是这里按测试点数量平分补上的(余数给最后一个)
|
||||
const entries = res.data.info
|
||||
const baseScore = Math.floor(100 / entries.length)
|
||||
const remainder = 100 - baseScore * entries.length
|
||||
const testcases: Testcase[] = entries.map((entry, i) => ({
|
||||
...entry,
|
||||
score: String(
|
||||
i === entries.length - 1 ? baseScore + remainder : baseScore,
|
||||
),
|
||||
}))
|
||||
|
||||
emit("uploaded", res.data.id, testcases)
|
||||
message.success("上传成功")
|
||||
|
||||
@@ -169,14 +169,16 @@ async function upload() {
|
||||
const file = new File([blob], "testcase.zip", { type: "application/zip" })
|
||||
|
||||
const res = await uploadTestcases(file)
|
||||
const testcases: Testcase[] = res.data.info
|
||||
const baseScore = Math.floor(100 / testcases.length)
|
||||
const remainder = 100 - baseScore * testcases.length
|
||||
testcases.forEach((tc, i) => {
|
||||
tc.score = String(
|
||||
i === testcases.length - 1 ? baseScore + remainder : baseScore,
|
||||
)
|
||||
})
|
||||
// score 不在上传响应里,是这里按测试点数量平分补上的(余数给最后一个)
|
||||
const entries = res.data.info
|
||||
const baseScore = Math.floor(100 / entries.length)
|
||||
const remainder = 100 - baseScore * entries.length
|
||||
const testcases: Testcase[] = entries.map((entry, i) => ({
|
||||
...entry,
|
||||
score: String(
|
||||
i === entries.length - 1 ? baseScore + remainder : baseScore,
|
||||
),
|
||||
}))
|
||||
|
||||
emit("uploaded", res.data.id, testcases)
|
||||
message.success("上传成功")
|
||||
|
||||
@@ -294,10 +294,12 @@ async function handleUploadTestcases({ file }: UploadCustomRequestOptions) {
|
||||
message.error("上传测试用例失败")
|
||||
return
|
||||
}
|
||||
const testcases = res.data.info
|
||||
for (let file of testcases) {
|
||||
file.score = (100 / testcases.length).toFixed(0)
|
||||
}
|
||||
// score 不在上传响应里,前端按测试点数量平分补上
|
||||
const entries = res.data.info
|
||||
const testcases: Testcase[] = entries.map((entry) => ({
|
||||
...entry,
|
||||
score: (100 / entries.length).toFixed(0),
|
||||
}))
|
||||
problem.value.testCaseScore = testcases
|
||||
problem.value.testCaseId = res.data.id
|
||||
} catch (err) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import CodeEditor from "shared/components/CodeEditor.vue"
|
||||
import MarkdownEditor from "shared/components/MarkdownEditor.vue"
|
||||
import type { Tutorial } from "utils/types"
|
||||
import type { TutorialEdit } from "utils/types"
|
||||
import { createTutorial, getTutorial, updateTutorial } from "../api"
|
||||
import ExerciseManager from "./components/ExerciseManager.vue"
|
||||
|
||||
@@ -13,7 +13,7 @@ const route = useRoute()
|
||||
const message = useMessage()
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const tutorial = reactive<Tutorial>({
|
||||
const tutorial = reactive<TutorialEdit>({
|
||||
id: 0,
|
||||
title: "",
|
||||
content: "",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { NFlex, NTag } from "naive-ui"
|
||||
import { useRouteQuery } from "@vueuse/router"
|
||||
import { getProblemList } from "oj/api"
|
||||
import { getTagColor } from "utils/functions"
|
||||
import type { ProblemFiltered } from "utils/types"
|
||||
import type { ProblemFiltered, Tag as ContractTag } from "utils/types"
|
||||
import { getProblemTagList } from "shared/api"
|
||||
import Hitokoto from "shared/components/Hitokoto.vue"
|
||||
import Pagination from "shared/components/Pagination.vue"
|
||||
@@ -16,11 +16,8 @@ import ProblemStatus from "./components/ProblemStatus.vue"
|
||||
import AuthorSelect from "shared/components/AuthorSelect.vue"
|
||||
import ProblemListTitle from "./components/ProblemListTitle.vue"
|
||||
|
||||
interface Tag {
|
||||
id: number
|
||||
name: string
|
||||
checked: boolean
|
||||
}
|
||||
// 列表页的标签是个视图模型:契约的标签 + 本地的选中态
|
||||
type Tag = ContractTag & { checked: boolean }
|
||||
|
||||
interface ProblemQuery {
|
||||
keyword: string
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function getProfile(
|
||||
}
|
||||
|
||||
export function getProblemTagList() {
|
||||
return api2.get<Array<Tag & { problemCount: number }>>("problem-tags")
|
||||
return api2.get<Tag[]>("problem-tags")
|
||||
}
|
||||
|
||||
export function getHitokoto() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { LANGUAGE_SHOW_VALUE } from "./constants"
|
||||
import type {
|
||||
AdminProblem as ContractAdminProblem,
|
||||
SubmissionDetail,
|
||||
@@ -9,6 +8,7 @@ import type {
|
||||
SessionUser,
|
||||
UserProfile,
|
||||
EmbeddedSubmission as ContractEmbeddedSubmission,
|
||||
Message as ContractMessage,
|
||||
Grade,
|
||||
ProblemDetail,
|
||||
ProblemDifficulty,
|
||||
@@ -32,9 +32,6 @@ export interface AcmProblemsStatus {
|
||||
}
|
||||
}
|
||||
|
||||
export type UserAdminType =
|
||||
"Regular User" | "Student Admin" | "Teacher Admin" | "Super Admin"
|
||||
|
||||
/**
|
||||
* 后台用户管理里的用户。`rawPassword` 是明文密码,只有超管专属接口下发 ——
|
||||
* 老师要能查学生密码,见契约 adminUserSchema 的注释。
|
||||
@@ -86,24 +83,17 @@ export interface SQLDisplay {
|
||||
| { changed_tables: SQLDisplayTable[] }
|
||||
}
|
||||
|
||||
export type LANGUAGE_SHOW_LABEL =
|
||||
(typeof LANGUAGE_SHOW_VALUE)[keyof typeof LANGUAGE_SHOW_VALUE]
|
||||
|
||||
export type SUBMISSION_RESULT =
|
||||
-2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
|
||||
export type ProblemStatus = "passed" | "failed" | "not_test"
|
||||
|
||||
interface SampleUser {
|
||||
id: number
|
||||
username: string
|
||||
realName: string | null
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
/**
|
||||
* 题目标签。用契约的 —— 它比手抄那份多一个 `problemCount`,
|
||||
* shared/api.ts 原来还得用 `Tag & { problemCount: number }` 把它补回来。
|
||||
*/
|
||||
export type { Tag } from "@oj2/contract"
|
||||
|
||||
export type {
|
||||
AdminTag,
|
||||
@@ -113,16 +103,18 @@ export type {
|
||||
GenerateSqlTestCaseResponse,
|
||||
} from "@oj2/contract"
|
||||
|
||||
export interface TestcaseUploadedReturns {
|
||||
id: string
|
||||
info: Testcase[]
|
||||
}
|
||||
/**
|
||||
* 上传测试点的返回。取契约 —— 手抄那份少了三个字段
|
||||
* (stripped_output_md5 / input_size / output_size)。这套键名保持 snake_case
|
||||
* 是因为它会原样落进 problem.test_case_score 和判题沙箱读的 info 文件。
|
||||
*/
|
||||
export type { UploadTestCaseResponse as TestcaseUploadedReturns } from "@oj2/contract"
|
||||
|
||||
export interface Testcase {
|
||||
input_name: string
|
||||
output_name: string
|
||||
score: string
|
||||
}
|
||||
/**
|
||||
* 题目表单里的测试点:上传返回的条目 + 前端本地算出的分值。
|
||||
* `score` **不在响应里** —— 是上传完成后按测试点数量平分补上去的。
|
||||
*/
|
||||
export type Testcase = TestCaseEntry & { score: string }
|
||||
|
||||
/**
|
||||
* 题目详情。以契约的 ProblemDetail 为准,只在这里补两处前端自己的窄化:
|
||||
@@ -275,11 +267,9 @@ export interface Code {
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface SubmitCodePayload {
|
||||
problemId: number
|
||||
/** 提交代码的请求体。取契约的形状,只把 language 收窄成前端的 LANGUAGE 联合 */
|
||||
export type SubmitCodePayload = Omit<CreateSubmissionRequest, "language"> & {
|
||||
language: LANGUAGE
|
||||
code: string
|
||||
contestId?: number
|
||||
}
|
||||
|
||||
// ==================== 流程图相关类型 ====================
|
||||
@@ -465,52 +455,56 @@ export interface Announcement extends AnnouncementEdit {
|
||||
/** 列表不下发正文:公告是 8MB 上限的富文本,列表页只显示标题 */
|
||||
export type AnnouncementListItem = Omit<Announcement, "content">
|
||||
|
||||
export interface Message {
|
||||
id: number
|
||||
sender: SampleUser
|
||||
createTime: string
|
||||
message: string
|
||||
/**
|
||||
* 站内信。取契约的形状,只把 `submission` 换成前端窄化过的那个
|
||||
* (statisticInfo / language 在契约里是 unknown,见 EmbeddedSubmission)。
|
||||
*/
|
||||
export type Message = Omit<ContractMessage, "submission"> & {
|
||||
submission: EmbeddedSubmission
|
||||
}
|
||||
|
||||
export interface CreateMessage {
|
||||
sender: string
|
||||
recipient: string
|
||||
submission: string
|
||||
message: string
|
||||
}
|
||||
/**
|
||||
* 题目表情。三个类型都直接取自契约 —— 语义 key 必须与后端 reaction/models.py
|
||||
* 的 ReactionType 一致(见根 CLAUDE.md),手抄一份迟早对不上。
|
||||
*
|
||||
* 注意 `ReactionCounts` 是 Partial 的:后端只下发有票的类型,没人投的键不出现。
|
||||
*/
|
||||
export type {
|
||||
ReactionKey,
|
||||
ReactionCounts,
|
||||
ReactionState,
|
||||
} from "@oj2/contract"
|
||||
import type { ReactionKey, SampleUser } from "@oj2/contract"
|
||||
|
||||
export type ReactionKey =
|
||||
| "too_easy"
|
||||
| "too_hard"
|
||||
| "confusing"
|
||||
| "buggy"
|
||||
| "learned"
|
||||
| "interesting"
|
||||
| "want_explain"
|
||||
/**
|
||||
* 教程。直接取契约 —— 手抄的那份把 `createdBy` 写成了可选的 `User`(后端下发的是
|
||||
* SampleUser),`createdAt` / `updatedAt` 也写成了可选,列表页因此被迫写
|
||||
* `row.createdBy?.username` 和 `row.createdAt!`。
|
||||
*
|
||||
* 列表项也用契约的:它比 `Omit<Tutorial, "content">` **还少一个 code** ——
|
||||
* 后端列表接口连 code 一起省了,手抄那份声称它在。
|
||||
*/
|
||||
export type {
|
||||
AdminTutorial as Tutorial,
|
||||
AdminTutorialListItem as TutorialListItem,
|
||||
} from "@oj2/contract"
|
||||
import type {
|
||||
AdminExercise,
|
||||
AdminTutorial,
|
||||
CreateSubmissionRequest,
|
||||
TestCaseEntry,
|
||||
} from "@oj2/contract"
|
||||
|
||||
export type ReactionCounts = Record<ReactionKey, number>
|
||||
|
||||
export interface ReactionState {
|
||||
mine: ReactionKey | null
|
||||
counts: ReactionCounts | null
|
||||
}
|
||||
|
||||
export interface Tutorial {
|
||||
id: number
|
||||
title: string
|
||||
content: string
|
||||
code: string
|
||||
isPublic: boolean
|
||||
order: number
|
||||
type: "python" | "c"
|
||||
createdBy?: User
|
||||
updatedAt?: string
|
||||
createdAt?: string
|
||||
}
|
||||
|
||||
/** 后台教程列表不下发正文:教程正文是整篇 markdown,列表只排序和切换可见性 */
|
||||
export type TutorialListItem = Omit<Tutorial, "content">
|
||||
/**
|
||||
* 教程编辑表单。只留可编辑字段 —— createdBy / createdAt / updatedAt 由后端产出,
|
||||
* 新建时压根不存在(对齐 BlankProblem / BlankContest 的写法)。
|
||||
*
|
||||
* `code` 收窄成 string:读回来时统一 `?? ""`,代码编辑器的 v-model 不接受 null。
|
||||
*/
|
||||
export type TutorialEdit = Omit<
|
||||
AdminTutorial,
|
||||
"createdBy" | "createdAt" | "updatedAt" | "code"
|
||||
> & { code: string }
|
||||
|
||||
export interface ExerciseMcqData {
|
||||
question: string
|
||||
@@ -555,12 +549,13 @@ export interface ExerciseGroupData {
|
||||
answer: number[]
|
||||
}
|
||||
|
||||
export type ExerciseType =
|
||||
"mcq" | "sort" | "fill" | "match" | "predict" | "debug" | "group"
|
||||
export type { ExerciseType } from "@oj2/contract"
|
||||
|
||||
export interface Exercise {
|
||||
id: number
|
||||
type: ExerciseType
|
||||
/**
|
||||
* 练习题。契约里 `data` 是 Record<string, unknown>(各题型结构不同,后端不校验),
|
||||
* 前端按题型收窄成判别联合 —— 组件靠它区分七种题型的字段。
|
||||
*/
|
||||
export type Exercise = Omit<AdminExercise, "data"> & {
|
||||
data:
|
||||
| ExerciseMcqData
|
||||
| ExerciseSortData
|
||||
@@ -569,7 +564,6 @@ export interface Exercise {
|
||||
| ExercisePredictData
|
||||
| ExerciseDebugData
|
||||
| ExerciseGroupData
|
||||
order: number
|
||||
}
|
||||
|
||||
export type {
|
||||
|
||||
@@ -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