refactor(prisma): simplify schema and remove zod-prisma-types

- Reorganized Prisma schema structure with simplified models and relations
- Removed zod-prisma-types generator as it's no longer needed
- Consolidated problem content types into a single ProblemLocalization model
- Simplified testcase and template structures
- Removed unused prisma types file
This commit is contained in:
cfngc4594 2025-05-12 18:32:46 +08:00
parent 0e9207bfce
commit 15b3f630d5
3 changed files with 155 additions and 243 deletions

View File

@ -78,7 +78,6 @@
"vscode-languageclient": "^9.0.1",
"vscode-ws-jsonrpc": "^3.4.0",
"zod": "^3.24.2",
"zod-prisma-types": "^3.2.4",
"zustand": "^5.0.3"
},
"devDependencies": {

View File

@ -1,151 +1,39 @@
generator client {
provider = "prisma-client-js"
output = "../src/generated/client"
}
generator zod {
provider = "zod-prisma-types"
output = "../src/generated/zod"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
output = "../src/generated/client"
}
enum Role {
ADMIN
GUEST
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
password String?
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
// Optional for WebAuthn support
Authenticator Authenticator[]
role Role @default(GUEST)
problems Problem[]
submissions Submission[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
enum Difficulty {
EASY
MEDIUM
HARD
}
model Problem {
id String @id @default(cuid())
displayId Int @unique
titles ProblemTitle[]
descriptions ProblemDescription[]
solutions ProblemSolution[]
difficulty Difficulty @default(EASY)
published Boolean @default(false)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
timeLimit Int @default(1000)
memoryLimit Int @default(128)
templates Template[]
testcases Testcase[]
submissions Submission[]
@@index([userId])
@@index([difficulty])
}
enum Language {
enum Locale {
en
zh
}
model ProblemTitle {
id String @id @default(cuid())
language Language
content String
problemId String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
@@unique([problemId, language])
}
model ProblemDescription {
id String @id @default(cuid())
language Language
content String
problemId String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
@@unique([problemId, language])
}
model ProblemSolution {
id String @id @default(cuid())
language Language
content String
problemId String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
@@unique([problemId, language])
}
enum EditorLanguage {
enum Language {
c
cpp
}
model EditorLanguageConfig {
language EditorLanguage @unique
label String
fileName String
fileExtension String
languageServerConfig LanguageServerConfig? @relation
dockerConfig DockerConfig? @relation
}
enum LanguageServerProtocol {
enum Protocol {
ws
wss
}
model LanguageServerConfig {
language EditorLanguage @unique
protocol LanguageServerProtocol
hostname String
port Int?
path String?
editorLanguageConfig EditorLanguageConfig @relation(fields: [language], references: [language])
}
model DockerConfig {
language EditorLanguage @unique
image String
tag String
workingDir String
compileOutputLimit Int
runOutputLimit Int
editorLanguageConfig EditorLanguageConfig @relation(fields: [language], references: [language])
}
model Template {
language EditorLanguage
template String
problemId String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
@@id([problemId, language])
}
enum Status {
PD // PENDING
QD // QUEUED
@ -161,42 +49,119 @@ enum Status {
SE // System Error
}
enum ProblemContentType {
TITLE
DESCRIPTION
SOLUTION
}
model User {
id String @id @default(cuid())
name String?
email String @unique
emailVerified DateTime?
image String?
role Role @default(GUEST)
accounts Account[]
sessions Session[]
// Optional for WebAuthn support
Authenticator Authenticator[]
problems Problem[]
submissions Submission[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Problem {
id String @id @default(cuid())
displayId Int @unique
difficulty Difficulty @default(EASY)
isPublished Boolean @default(false)
timeLimit Int @default(1000)
memoryLimit Int @default(134217728)
localizations ProblemLocalization[]
templates Template[]
testcases Testcase[]
submissions Submission[]
userId String?
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ProblemLocalization {
problemId String
locale Locale
type ProblemContentType
content String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
@@id([problemId, locale, type])
}
model Template {
problemId String
language Language
content String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
@@id([problemId, language])
}
model Submission {
id String @id @default(cuid())
language EditorLanguage
code String
language Language
content String
status Status
message String?
executionTime Int?
timeUsage Int?
memoryUsage Int?
testcaseResults TestcaseResult[]
userId String
problemId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
testcaseResults TestcaseResult[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Testcase {
id String @id @default(cuid())
problemId String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
data TestcaseData[]
expectedOutput String
inputs TestcaseInput[]
testcaseResults TestcaseResult[]
problemId String
problem Problem @relation(fields: [problemId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model TestcaseData {
model TestcaseInput {
id String @id @default(cuid())
index Int
label String
name String
value String
testcaseId String
testcase Testcase @relation(fields: [testcaseId], references: [id], onDelete: Cascade)
}
@ -204,12 +169,12 @@ model TestcaseResult {
id String @id @default(cuid())
isCorrect Boolean
output String
executionTime Int?
timeUsage Int?
memoryUsage Int?
submissionId String
testcaseId String
submission Submission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
testcase Testcase @relation(fields: [testcaseId], references: [id], onDelete: Cascade)
@ -217,6 +182,37 @@ model TestcaseResult {
updatedAt DateTime @updatedAt
}
model LanguageConfig {
language Language @id
displayName String
fileName String
fileExtension String
dockerConfig DockerConfig?
languageServerConfig LanguageServerConfig?
}
model DockerConfig {
language Language @id
image String
tag String
workingDir String
compileOutputLimit Int @default(1048576)
runOutputLimit Int @default(1048576)
languageConfig LanguageConfig @relation(fields: [language], references: [language], onDelete: Cascade)
}
model LanguageServerConfig {
language Language @id
protocol Protocol
hostname String
port Int?
path String?
languageConfig LanguageConfig @relation(fields: [language], references: [language], onDelete: Cascade)
}
model Account {
userId String
type String
@ -230,11 +226,11 @@ model Account {
id_token String?
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([provider, providerAccountId])
}
@ -242,6 +238,7 @@ model Session {
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())

View File

@ -1,84 +0,0 @@
import prisma from "@/lib/prisma";
type ThenArg<T> = T extends PromiseLike<infer U> ? U : T;
export async function getAllProblems() {
return await prisma.problem.findMany({
include: {
templates: true,
testcases: {
include: {
data: true,
},
},
},
});
}
export type ProblemWithDetails = ThenArg<
ReturnType<typeof getAllProblems>
>[number];
export async function getAllProblemsWithTestcases() {
return await prisma.problem.findMany({
include: {
testcases: {
include: {
data: true,
},
},
},
});
}
export type ProblemWithTestcases = ThenArg<
ReturnType<typeof getAllProblemsWithTestcases>
>[number];
export async function getAllTestcases() {
return await prisma.testcase.findMany({
include: {
data: true,
},
});
}
export type TestcaseWithDetails = ThenArg<
ReturnType<typeof getAllTestcases>
>;
export async function getAllSubmissionsWithTestcaseResults() {
return await prisma.submission.findMany({
include: {
testcaseResults: {
include: {
testcase: {
include: {
data: true,
}
}
}
}
}
})
}
export type SubmissionWithTestcaseResult = ThenArg<
ReturnType<typeof getAllSubmissionsWithTestcaseResults>
>[number];
export async function getAllTestcaseResultWithTestcase() {
return await prisma.testcaseResult.findMany({
include:{
testcase:{
include:{
data:true
}
}
}
})
}
export type TestcaseResultWithTestcase=ThenArg<
ReturnType<typeof getAllTestcaseResultWithTestcase>
>[number];