754 lines
32 KiB
Plaintext
754 lines
32 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
authUserId String? @unique @map("auth_user_id") @db.Uuid
|
|
email String @unique
|
|
name String?
|
|
authRole String? @map("auth_role")
|
|
primaryOrganizationId String? @map("primary_organization_id") @db.Uuid
|
|
primaryOrganizationName String? @map("primary_organization_name")
|
|
primaryOrganizationType String? @map("primary_organization_type")
|
|
department String?
|
|
position String?
|
|
createdAt DateTime @default(now()) @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @db.Timestamptz(3)
|
|
courses Course[] @relation("CourseTeacher")
|
|
progress CourseStudentProgress[]
|
|
weekProgress CourseStudentWeekProgress[]
|
|
groupMemberships StudentGroupMember[]
|
|
enrollments StudentEnrollment[]
|
|
studentChatThreads ChatThread[] @relation("ChatThreadStudent")
|
|
assignedChatThreads ChatThread[] @relation("ChatThreadInstructor")
|
|
chatMessages ChatMessage[]
|
|
platformControlSessions PlatformControlSession[]
|
|
platformControlQueueEntries PlatformControlQueueEntry[]
|
|
studioRepositories StudioRepository[]
|
|
savedMaps StudentSavedMap[]
|
|
customModules StudentCustomModule[]
|
|
submissionScores SubmissionScore[]
|
|
submissionTotalScores SubmissionTotalScore[]
|
|
|
|
@@index([authRole])
|
|
@@index([primaryOrganizationId])
|
|
@@map("users")
|
|
}
|
|
|
|
model StudentEnrollment {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
status String @default("ACTIVE")
|
|
removedAt DateTime? @map("removed_at") @db.Timestamptz(3)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, courseId])
|
|
@@index([courseId, status])
|
|
@@index([organizationId, status])
|
|
@@index([organizationName, status])
|
|
@@map("student_enrollments")
|
|
}
|
|
|
|
model StudentGroup {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
name String
|
|
week Int @default(1)
|
|
status String @default("진행중")
|
|
platformName String? @map("platform_name")
|
|
instructorPlatformId String? @map("instructor_platform_id") @db.Uuid
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
members StudentGroupMember[]
|
|
instructorPlatform InstructorPlatform? @relation(fields: [instructorPlatformId], references: [id], onDelete: SetNull)
|
|
platformControlSessions PlatformControlSession[]
|
|
platformControlQueueEntries PlatformControlQueueEntry[]
|
|
curriculumSettings InstructorCurriculumSetting[]
|
|
|
|
@@unique([organizationName, name])
|
|
@@index([organizationId])
|
|
@@index([organizationName])
|
|
@@index([instructorPlatformId])
|
|
@@map("student_groups")
|
|
}
|
|
|
|
model InstructorPlatform {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
platformId String @map("platform_id") @db.Uuid
|
|
displayName String @map("display_name")
|
|
instanceNo Int @map("instance_no")
|
|
status String @default("대기")
|
|
battery Int @default(100)
|
|
uptimeMinutes Int @default(0) @map("uptime_minutes")
|
|
speedMeters Decimal @default(0) @map("speed_meters") @db.Decimal(6, 2)
|
|
errorCount Int @default(0) @map("error_count")
|
|
emergencyStop Boolean @default(false) @map("emergency_stop")
|
|
vehicleType String @default("MK-mini") @map("vehicle_type")
|
|
wheelbaseMeters Decimal @default(0.325) @map("wheelbase_meters") @db.Decimal(6, 3)
|
|
maxSpeedMetersPerSecond Decimal @default(7.0) @map("max_speed_meters_per_second") @db.Decimal(6, 2)
|
|
maxSteeringAngleDegrees Decimal @default(30) @map("max_steering_angle_degrees") @db.Decimal(6, 2)
|
|
sensors Json @default("[]")
|
|
drivers Json @default("[]")
|
|
algorithms Json @default("{}")
|
|
studioSettingsOverride Json? @map("studio_settings_override")
|
|
controlDurationMinutes Int @default(30) @map("control_duration_minutes")
|
|
controlWarningMinutes Int @default(5) @map("control_warning_minutes")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
platform Platform @relation(fields: [platformId], references: [id], onDelete: Restrict)
|
|
assignedGroups StudentGroup[]
|
|
controlSessions PlatformControlSession[]
|
|
controlQueueEntries PlatformControlQueueEntry[]
|
|
|
|
@@unique([organizationName, displayName])
|
|
@@unique([organizationName, platformId, instanceNo])
|
|
@@index([organizationId])
|
|
@@index([organizationName])
|
|
@@index([platformId])
|
|
@@map("instructor_platforms")
|
|
}
|
|
|
|
model StudentGroupMember {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
groupId String @map("group_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
group StudentGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([groupId, userId])
|
|
@@index([userId])
|
|
@@map("student_group_members")
|
|
}
|
|
|
|
model Course {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
slug String @unique
|
|
title String
|
|
subtitle String?
|
|
description String?
|
|
organizationName String @map("organization_name")
|
|
teacherId String @map("teacher_id") @db.Uuid
|
|
isActive Boolean @default(true) @map("is_active")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
teacher User @relation("CourseTeacher", fields: [teacherId], references: [id], onDelete: Restrict)
|
|
weeks CourseWeek[]
|
|
platforms CoursePlatform[]
|
|
studentProgress CourseStudentProgress[]
|
|
studentWeekProgress CourseStudentWeekProgress[]
|
|
chatThreads ChatThread[]
|
|
enrollments StudentEnrollment[]
|
|
instructorCurriculumSettings InstructorCurriculumSetting[]
|
|
instructorCurriculumWeekOverrides InstructorCurriculumWeekOverride[]
|
|
environmentProfiles CourseEnvironmentProfile[]
|
|
visualizationSelections CourseWeekVisualizationPlatform[]
|
|
maps CourseMap[]
|
|
weekMaps CourseWeekMap[]
|
|
savedMaps StudentSavedMap[]
|
|
customModules StudentCustomModule[]
|
|
submissionScores SubmissionScore[]
|
|
submissionTotalScores SubmissionTotalScore[]
|
|
|
|
@@index([isActive])
|
|
@@index([teacherId])
|
|
@@map("courses")
|
|
}
|
|
|
|
model CourseEnvironmentProfile {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
platformKey String @default("futuredrive-local-pc") @map("platform_key")
|
|
profileType String @map("profile_type")
|
|
name String
|
|
config Json
|
|
enabled Boolean @default(true)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([courseId, week, platformKey])
|
|
@@index([courseId, week])
|
|
@@index([profileType])
|
|
@@map("course_environment_profiles")
|
|
}
|
|
|
|
model VisualizationPlatform {
|
|
key String @id @map("platform_key")
|
|
type String @unique
|
|
displayName String @map("display_name")
|
|
description String?
|
|
defaultConfig Json @map("default_config")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
enabled Boolean @default(true)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
courseWeekSelections CourseWeekVisualizationPlatform[]
|
|
|
|
@@index([enabled, sortOrder])
|
|
@@map("visualization_platforms")
|
|
}
|
|
|
|
model CourseWeekVisualizationPlatform {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
platformKey String @map("platform_key")
|
|
enabled Boolean @default(true)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
platform VisualizationPlatform @relation(fields: [platformKey], references: [key], onDelete: Cascade)
|
|
|
|
@@unique([courseId, week, platformKey])
|
|
@@index([courseId, week])
|
|
@@index([platformKey])
|
|
@@map("course_week_visualization_platforms")
|
|
}
|
|
|
|
model CourseMap {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
key String
|
|
name String
|
|
description String?
|
|
platformKey String @default("NAV2") @map("platform_key")
|
|
worldFile String @default("empty_world.world") @map("world_file")
|
|
viewerModel String @default("turtlebot3_world") @map("viewer_model")
|
|
layout Json @default("{\"version\":1,\"objects\":[]}")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([courseId, key])
|
|
@@index([courseId, platformKey])
|
|
@@map("course_maps")
|
|
}
|
|
|
|
model CourseWeekMap {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
mapKey String @map("map_key")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([courseId, week, mapKey])
|
|
@@index([courseId, week])
|
|
@@map("course_week_maps")
|
|
}
|
|
|
|
model StudentSavedMap {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
name String
|
|
sourceMapKey String @map("source_map_key")
|
|
worldFile String @map("world_file")
|
|
viewerModel String @map("viewer_model")
|
|
yamlPath String @map("yaml_path")
|
|
pgmPath String @map("pgm_path")
|
|
previewPgm String? @map("preview_pgm")
|
|
databasePath String? @map("database_path")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, courseId, week, yamlPath])
|
|
@@index([userId, courseId, week, createdAt])
|
|
@@map("student_saved_maps")
|
|
}
|
|
|
|
model StudentCustomModule {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
sortOrder Int @map("sort_order")
|
|
category String
|
|
name String
|
|
folderName String @map("folder_name")
|
|
dockerImage String? @map("docker_image")
|
|
packageName String @map("package_name")
|
|
launchFile String @map("launch_file")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, courseId, week, folderName])
|
|
@@index([userId, courseId, week, sortOrder])
|
|
@@map("student_custom_modules")
|
|
}
|
|
|
|
model InstructorCurriculumSetting {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
groupId String? @map("group_id") @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
activeWeek Int @default(1) @map("active_week")
|
|
activeLearningStep String? @map("active_learning_step")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Restrict)
|
|
group StudentGroup? @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([organizationId])
|
|
@@index([organizationName])
|
|
@@index([groupId])
|
|
@@index([courseId])
|
|
@@map("instructor_curriculum_settings")
|
|
}
|
|
|
|
model InstructorCurriculumWeekOverride {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
tagLabel String? @map("tag_label")
|
|
title String?
|
|
duration String?
|
|
overview String?
|
|
deliverable String?
|
|
requiresSourceSubmission Boolean? @default(true) @map("requires_source_submission")
|
|
learningSteps Json? @map("learning_steps")
|
|
topics Json?
|
|
topicDetails Json? @map("topic_details")
|
|
topicVideoUrls Json? @map("topic_video_urls")
|
|
practiceContents Json? @map("practice_contents")
|
|
disabledModuleIds Json? @map("disabled_module_ids")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([organizationName, courseId, week])
|
|
@@index([organizationId])
|
|
@@index([organizationName])
|
|
@@index([courseId])
|
|
@@map("instructor_curriculum_week_overrides")
|
|
}
|
|
|
|
model Platform {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
platformKey String @unique @map("platform_key")
|
|
displayName String @map("display_name")
|
|
description String
|
|
organizationName String @map("organization_name")
|
|
iconKey String @map("icon_key")
|
|
isActive Boolean @default(true) @map("is_active")
|
|
curriculumTagOnly Boolean @default(false) @map("curriculum_tag_only")
|
|
vehicleType String @default("MK-mini") @map("vehicle_type")
|
|
wheelbaseMeters Decimal @default(0.325) @map("wheelbase_meters") @db.Decimal(6, 3)
|
|
maxSpeedMetersPerSecond Decimal @default(7.0) @map("max_speed_meters_per_second") @db.Decimal(6, 2)
|
|
maxSteeringAngleDegrees Decimal @default(30) @map("max_steering_angle_degrees") @db.Decimal(6, 2)
|
|
sensors Json @default("[]")
|
|
drivers Json @default("[]")
|
|
algorithms Json @default("{}")
|
|
defaultStudioSettings Json @default("{\"workspaceRoot\":\"~/autonomy-studio/workspaces\",\"giteaBaseUrl\":\"http://localhost:3000\",\"giteaOwner\":\"student\"}") @map("default_studio_settings")
|
|
controlDurationMinutes Int @default(30) @map("control_duration_minutes")
|
|
controlWarningMinutes Int @default(5) @map("control_warning_minutes")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
courses CoursePlatform[]
|
|
instructorPlatforms InstructorPlatform[]
|
|
controlSessions PlatformControlSession[]
|
|
controlQueueEntries PlatformControlQueueEntry[]
|
|
|
|
@@index([organizationName])
|
|
@@index([isActive])
|
|
@@map("platforms")
|
|
}
|
|
|
|
model CoursePlatform {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
platformId String @map("platform_id") @db.Uuid
|
|
status String
|
|
action String
|
|
state String
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
platform Platform @relation(fields: [platformId], references: [id], onDelete: Restrict)
|
|
|
|
@@unique([courseId, platformId])
|
|
@@index([courseId, sortOrder])
|
|
@@index([platformId])
|
|
@@map("course_platforms")
|
|
}
|
|
|
|
model PlatformControlSession {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
platformId String? @map("platform_id") @db.Uuid
|
|
instructorPlatformId String? @map("instructor_platform_id") @db.Uuid
|
|
holderUserId String @map("holder_user_id") @db.Uuid
|
|
groupId String? @map("group_id") @db.Uuid
|
|
status String @default("ACTIVE")
|
|
startedAt DateTime @default(now()) @map("started_at") @db.Timestamptz(3)
|
|
endsAt DateTime @map("ends_at") @db.Timestamptz(3)
|
|
warningAt DateTime @map("warning_at") @db.Timestamptz(3)
|
|
warningSentAt DateTime? @map("warning_sent_at") @db.Timestamptz(3)
|
|
extensionCount Int @default(0) @map("extension_count")
|
|
releasedAt DateTime? @map("released_at") @db.Timestamptz(3)
|
|
endReason String? @map("end_reason")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
platform Platform? @relation(fields: [platformId], references: [id], onDelete: Restrict)
|
|
instructorPlatform InstructorPlatform? @relation(fields: [instructorPlatformId], references: [id], onDelete: Restrict)
|
|
holderUser User @relation(fields: [holderUserId], references: [id], onDelete: Cascade)
|
|
group StudentGroup? @relation(fields: [groupId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([organizationId])
|
|
@@index([organizationName])
|
|
@@index([platformId, status])
|
|
@@index([instructorPlatformId, status])
|
|
@@index([holderUserId, status])
|
|
@@index([endsAt, status])
|
|
@@map("platform_control_sessions")
|
|
}
|
|
|
|
model PlatformControlQueueEntry {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
organizationId String? @map("organization_id") @db.Uuid
|
|
organizationName String @map("organization_name")
|
|
platformId String? @map("platform_id") @db.Uuid
|
|
instructorPlatformId String? @map("instructor_platform_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
groupId String? @map("group_id") @db.Uuid
|
|
status String @default("WAITING")
|
|
requestedAt DateTime @default(now()) @map("requested_at") @db.Timestamptz(3)
|
|
grantedAt DateTime? @map("granted_at") @db.Timestamptz(3)
|
|
canceledAt DateTime? @map("canceled_at") @db.Timestamptz(3)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
platform Platform? @relation(fields: [platformId], references: [id], onDelete: Restrict)
|
|
instructorPlatform InstructorPlatform? @relation(fields: [instructorPlatformId], references: [id], onDelete: Restrict)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
group StudentGroup? @relation(fields: [groupId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([organizationId])
|
|
@@index([organizationName])
|
|
@@index([platformId, status, requestedAt])
|
|
@@index([instructorPlatformId, status, requestedAt])
|
|
@@index([userId, status])
|
|
@@map("platform_control_queue_entries")
|
|
}
|
|
|
|
model CourseStudentProgress {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
completedWeeks Int @default(0) @map("completed_weeks")
|
|
totalWeeks Int @default(0) @map("total_weeks")
|
|
learningHours Int @default(0) @map("learning_hours")
|
|
commitCount Int @default(0) @map("commit_count")
|
|
averageScore Int @default(0) @map("average_score")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([courseId, userId])
|
|
@@index([userId])
|
|
@@map("course_student_progress")
|
|
}
|
|
|
|
model CourseStudentWeekProgress {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
week Int
|
|
submittedAt DateTime? @map("submitted_at") @db.Timestamptz(3)
|
|
commitCount Int @default(0) @map("commit_count")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([courseId, userId, week])
|
|
@@index([userId])
|
|
@@map("course_student_week_progress")
|
|
}
|
|
|
|
model CourseWeek {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
week Int
|
|
title String
|
|
tags String[]
|
|
progress Int @default(0)
|
|
state String
|
|
duration String
|
|
github String
|
|
overview String
|
|
deliverable String
|
|
requiresSourceSubmission Boolean @default(true) @map("requires_source_submission")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
topics CourseWeekTopic[]
|
|
practices CourseWeekPractice[]
|
|
references CourseWeekReference[]
|
|
modules CourseWeekModule[]
|
|
chatThreads ChatThread[]
|
|
submissionScores SubmissionScore[]
|
|
submissionTotalScores SubmissionTotalScore[]
|
|
|
|
@@unique([courseId, week])
|
|
@@index([courseId])
|
|
@@map("course_weeks")
|
|
}
|
|
|
|
model CourseWeekModule {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
sortOrder Int @map("sort_order")
|
|
category String
|
|
name String
|
|
folderName String @map("folder_name")
|
|
templateRepositoryUrl String? @map("template_repository_url")
|
|
sourceType String @default("GIT") @map("source_type")
|
|
prebuiltArtifacts Json @default("[]") @map("prebuilt_artifacts")
|
|
defaultParameters Json @default("[]") @map("default_parameters")
|
|
dockerImage String? @map("docker_image")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
|
studioRepositories StudioRepository[]
|
|
submissionScores SubmissionScore[]
|
|
|
|
@@unique([weekId, folderName])
|
|
@@unique([weekId, sortOrder])
|
|
@@index([weekId])
|
|
@@map("course_week_modules")
|
|
}
|
|
|
|
model StudioRepository {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
userId String @map("user_id") @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
moduleId String @map("module_id") @db.Uuid
|
|
repoOwner String @map("repo_owner")
|
|
repoName String @map("repo_name")
|
|
repositoryUrl String @map("repository_url")
|
|
templateRepositoryUrl String @map("template_repository_url")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
module CourseWeekModule @relation(fields: [moduleId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, moduleId])
|
|
@@index([weekId])
|
|
@@index([repoOwner, repoName])
|
|
@@map("studio_repositories")
|
|
}
|
|
|
|
model SubmissionScore {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
moduleId String @map("module_id") @db.Uuid
|
|
studentId String @map("student_id") @db.Uuid
|
|
score Int @default(0)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
|
module CourseWeekModule @relation(fields: [moduleId], references: [id], onDelete: Cascade)
|
|
student User @relation(fields: [studentId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([studentId, moduleId])
|
|
@@index([courseId])
|
|
@@index([weekId])
|
|
@@index([moduleId])
|
|
@@map("submission_scores")
|
|
}
|
|
|
|
model SubmissionTotalScore {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
studentId String @map("student_id") @db.Uuid
|
|
score Int @default(0)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
|
student User @relation(fields: [studentId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([studentId, weekId])
|
|
@@index([courseId])
|
|
@@index([weekId])
|
|
@@map("submission_total_scores")
|
|
}
|
|
|
|
model CourseWeekTopic {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
title String
|
|
detail String
|
|
sortOrder Int @map("sort_order")
|
|
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([weekId, sortOrder])
|
|
@@index([weekId])
|
|
@@map("course_week_topics")
|
|
}
|
|
|
|
model CourseWeekPractice {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
title String
|
|
description String
|
|
sortOrder Int @map("sort_order")
|
|
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([weekId, sortOrder])
|
|
@@index([weekId])
|
|
@@map("course_week_practices")
|
|
}
|
|
|
|
model CourseWeekReference {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
weekId String @map("week_id") @db.Uuid
|
|
kind String @default("REFERENCE")
|
|
title String
|
|
originalFileName String @map("original_file_name")
|
|
storedFileName String @map("stored_file_name")
|
|
contentType String? @map("content_type")
|
|
fileSizeBytes Int @default(0) @map("file_size_bytes")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([weekId, storedFileName])
|
|
@@index([weekId])
|
|
@@index([weekId, kind])
|
|
@@map("course_week_references")
|
|
}
|
|
|
|
enum ChatThreadType {
|
|
AI
|
|
INSTRUCTOR
|
|
MIXED
|
|
}
|
|
|
|
enum ChatThreadStatus {
|
|
OPEN
|
|
WAITING_INSTRUCTOR
|
|
RESOLVED
|
|
ARCHIVED
|
|
}
|
|
|
|
enum ChatSenderType {
|
|
STUDENT
|
|
AI
|
|
INSTRUCTOR
|
|
SYSTEM
|
|
}
|
|
|
|
enum ChatContentFormat {
|
|
TEXT
|
|
MARKDOWN
|
|
}
|
|
|
|
enum ChatMessageStatus {
|
|
ACTIVE
|
|
CANCELED
|
|
}
|
|
|
|
enum AiChatRunStatus {
|
|
SUCCEEDED
|
|
FAILED
|
|
}
|
|
|
|
model ChatThread {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
courseId String @map("course_id") @db.Uuid
|
|
weekId String? @map("week_id") @db.Uuid
|
|
studentId String @map("student_id") @db.Uuid
|
|
assignedInstructorId String? @map("assigned_instructor_id") @db.Uuid
|
|
type ChatThreadType
|
|
status ChatThreadStatus @default(OPEN)
|
|
title String?
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
lastMessageAt DateTime @default(now()) @map("last_message_at") @db.Timestamptz(3)
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
week CourseWeek? @relation(fields: [weekId], references: [id], onDelete: SetNull)
|
|
student User @relation("ChatThreadStudent", fields: [studentId], references: [id], onDelete: Cascade)
|
|
assignedInstructor User? @relation("ChatThreadInstructor", fields: [assignedInstructorId], references: [id], onDelete: SetNull)
|
|
messages ChatMessage[]
|
|
|
|
@@index([courseId, type, lastMessageAt])
|
|
@@index([studentId, type, lastMessageAt])
|
|
@@index([weekId])
|
|
@@index([assignedInstructorId])
|
|
@@map("chat_threads")
|
|
}
|
|
|
|
model ChatMessage {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
threadId String @map("thread_id") @db.Uuid
|
|
senderType ChatSenderType @map("sender_type")
|
|
senderUserId String? @map("sender_user_id") @db.Uuid
|
|
content String
|
|
contentFormat ChatContentFormat @default(TEXT) @map("content_format")
|
|
status ChatMessageStatus @default(ACTIVE)
|
|
metadata Json?
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
canceledAt DateTime? @map("canceled_at") @db.Timestamptz(3)
|
|
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(3)
|
|
thread ChatThread @relation(fields: [threadId], references: [id], onDelete: Cascade)
|
|
senderUser User? @relation(fields: [senderUserId], references: [id], onDelete: SetNull)
|
|
aiRun AiChatRun?
|
|
|
|
@@index([threadId, createdAt])
|
|
@@index([threadId, status, createdAt])
|
|
@@index([senderUserId])
|
|
@@map("chat_messages")
|
|
}
|
|
|
|
model AiChatRun {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
messageId String @unique @map("message_id") @db.Uuid
|
|
model String
|
|
promptTokens Int? @map("prompt_tokens")
|
|
completionTokens Int? @map("completion_tokens")
|
|
totalTokens Int? @map("total_tokens")
|
|
latencyMs Int? @map("latency_ms")
|
|
status AiChatRunStatus
|
|
error String?
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
message ChatMessage @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([status, createdAt])
|
|
@@map("ai_chat_runs")
|
|
}
|