feat: phase1 platform upgrade with moderation, dev payments, admin panel and landing updates

This commit is contained in:
root
2026-02-06 17:26:53 +00:00
parent 4ca66ea896
commit 979adb9d3d
54 changed files with 2687 additions and 318 deletions

View File

@ -44,9 +44,12 @@ model User {
generations CourseGeneration[]
groupMembers GroupMember[]
groupMessages GroupMessage[]
uploadedSourceFiles CourseSourceFile[]
homeworkSubmissions HomeworkSubmission[]
supportTickets SupportTicket[]
ticketMessages TicketMessage[]
statusChanges CourseStatusHistory[] @relation("StatusChangedBy")
cooperationRequests CooperationRequest[]
@@map("users")
}
@ -129,7 +132,9 @@ model Subscription {
enum CourseStatus {
DRAFT
GENERATING
PENDING_MODERATION
PENDING_REVIEW
APPROVED
PUBLISHED
REJECTED
ARCHIVED
@ -189,6 +194,8 @@ model Course {
reviews Review[]
generation CourseGeneration?
groups CourseGroup[]
statusHistory CourseStatusHistory[]
sourceFiles CourseSourceFile[]
// Vector embedding for semantic search
embedding Unsupported("vector(1536)")?
@ -242,6 +249,7 @@ model Lesson {
chapter Chapter @relation(fields: [chapterId], references: [id], onDelete: Cascade)
homework Homework[]
quiz Quiz?
groupMessages GroupMessage[]
// Vector embedding for semantic search
embedding Unsupported("vector(1536)")?
@ -348,6 +356,16 @@ model Category {
@@map("categories")
}
enum PaymentMode {
DEV
PROD
}
enum PaymentProvider {
STRIPE
YOOMONEY
}
model Purchase {
id String @id @default(uuid())
userId String @map("user_id")
@ -357,6 +375,10 @@ model Purchase {
amount Decimal @db.Decimal(10, 2)
currency String @default("USD")
stripePaymentId String? @map("stripe_payment_id")
provider PaymentProvider @default(STRIPE)
mode PaymentMode @default(PROD)
eventCode String? @map("event_code")
metadata Json?
// Status
status String @default("completed") // pending, completed, refunded
@ -497,17 +519,75 @@ model GroupMessage {
id String @id @default(uuid())
groupId String @map("group_id")
userId String @map("user_id")
lessonId String? @map("lesson_id")
content String @db.Text
createdAt DateTime @default(now()) @map("created_at")
group CourseGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
lesson Lesson? @relation(fields: [lessonId], references: [id], onDelete: SetNull)
@@index([groupId])
@@index([lessonId])
@@map("group_messages")
}
model CourseStatusHistory {
id String @id @default(uuid())
courseId String @map("course_id")
fromStatus CourseStatus? @map("from_status")
toStatus CourseStatus @map("to_status")
note String? @db.Text
changedById String? @map("changed_by_id")
createdAt DateTime @default(now()) @map("created_at")
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
changedBy User? @relation("StatusChangedBy", fields: [changedById], references: [id], onDelete: SetNull)
@@index([courseId, createdAt])
@@map("course_status_history")
}
enum CourseSourceType {
PDF
DOCX
TXT
PPTX
IMAGE
ZIP
OTHER
}
enum CourseSourceParseStatus {
PENDING
PARSED
FAILED
SKIPPED
}
model CourseSourceFile {
id String @id @default(uuid())
courseId String @map("course_id")
uploadedById String @map("uploaded_by_id")
fileName String @map("file_name")
mimeType String @map("mime_type")
fileSize Int @map("file_size")
sourceType CourseSourceType @map("source_type")
storagePath String @map("storage_path")
parseStatus CourseSourceParseStatus @default(PENDING) @map("parse_status")
extractedText String? @db.Text @map("extracted_text")
extractedMeta Json? @map("extracted_meta")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
uploadedBy User @relation(fields: [uploadedById], references: [id], onDelete: Cascade)
@@index([courseId, createdAt])
@@map("course_source_files")
}
// ============================================
// Homework & Assignments
// ============================================
@ -517,6 +597,8 @@ model Homework {
lessonId String @unique @map("lesson_id")
title String
description String @db.Text
type HomeworkType @default(TEXT)
config Json?
dueDate DateTime? @map("due_date")
createdAt DateTime @default(now()) @map("created_at")
@ -535,11 +617,24 @@ enum HomeworkReviewStatus {
TEACHER_REVIEWED
}
enum HomeworkType {
TEXT
FILE
PROJECT
QUIZ
GITHUB
}
model HomeworkSubmission {
id String @id @default(uuid())
homeworkId String @map("homework_id")
userId String @map("user_id")
content String @db.Text
content String? @db.Text
answerType HomeworkType @default(TEXT) @map("answer_type")
attachmentUrl String? @map("attachment_url")
githubUrl String? @map("github_url")
projectMeta Json? @map("project_meta")
quizAnswers Json? @map("quiz_answers")
// AI grading
aiScore Int? @map("ai_score") // 1-5
@ -597,3 +692,24 @@ model TicketMessage {
@@index([ticketId])
@@map("ticket_messages")
}
model CooperationRequest {
id String @id @default(uuid())
organization String
contactName String @map("contact_name")
email String
phone String?
role String?
organizationType String? @map("organization_type")
message String @db.Text
status String @default("new")
source String? @default("landing")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
userId String? @map("user_id")
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
@@index([status, createdAt])
@@map("cooperation_requests")
}

View File

@ -32,7 +32,20 @@ export type {
Review,
Enrollment,
LessonProgress,
CourseStatusHistory,
CourseSourceFile,
CooperationRequest,
} from '@prisma/client';
// Enum re-exports
export { SubscriptionTier, CourseStatus, GenerationStatus, UserRole } from '@prisma/client';
export {
SubscriptionTier,
CourseStatus,
GenerationStatus,
UserRole,
PaymentMode,
PaymentProvider,
CourseSourceType,
CourseSourceParseStatus,
HomeworkType,
} from '@prisma/client';