generator client { provider = "prisma-client-js" previewFeatures = ["postgresqlExtensions"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model external_links { id String @id type LinkType url String title String? projectId String projects projects @relation(fields: [projectId], references: [id], onDelete: Cascade) @@unique([projectId, url]) @@index([projectId], map: "idx_link_projectId") @@index([type], map: "idx_link_type") @@index([type, url], map: "idx_link_type_url") @@index([url], map: "idx_link_url") } model keyword_cloud_error_logs { id Int @id @default(autoincrement()) quarter String keyword String? errorType String errorMessage String rawData Json? createdAt DateTime @default(now()) @@index([errorType], map: "idx_keywordCloudErrorLog_errorType") @@index([quarter], map: "idx_keywordCloudErrorLog_quarter") } model keywords { id Int @id @default(autoincrement()) word String trendScore Int quarterId Int description String descriptionEn String? detailPoints Json detailPointsEn Json? visualConfig Json createdAt DateTime @default(now()) updatedAt DateTime quarters quarters @relation(fields: [quarterId], references: [id], onDelete: Cascade) @@index([quarterId], map: "idx_keyword_quarterId") @@index([trendScore], map: "idx_keyword_trendScore") @@index([word], map: "idx_keyword_word") } model project_discovery_tasks { id String @id status TaskStatus @default(PENDING) sourceUrl String sourceType String @default("manual") explorationData Json? explorationSummary String? errorMessage String? retryCount Int @default(0) lastRetryAt DateTime? projectId String? createdAt DateTime @default(now()) startedAt DateTime? completedAt DateTime? updatedAt DateTime projects projects? @relation(fields: [projectId], references: [id]) @@index([projectId], map: "idx_task_project_id") @@index([sourceUrl], map: "idx_task_source_url") @@index([status, createdAt], map: "idx_task_status_created") } model project_tags { projectId String tagId String projects projects @relation(fields: [projectId], references: [id], onDelete: Cascade) tags tags @relation(fields: [tagId], references: [id], onDelete: Cascade) @@id([projectId, tagId]) @@index([tagId]) } model projects { id String @id name String nameEn String? slug String @unique description String descriptionEn String? content String? contentEn String? status ProjectStatus @default(ACTIVE) source String? createdAt DateTime @default(now()) updatedAt DateTime embedding Unsupported("vector")? embeddingUpdatedAt DateTime? external_links external_links[] project_discovery_tasks project_discovery_tasks[] project_tags project_tags[] @@index([embedding], map: "idx_project_embedding_cosine") @@index([slug], map: "idx_project_slug") @@index([status, createdAt], map: "idx_project_status_createdAt") } model quarters { id Int @id @default(autoincrement()) quarter String @unique title String titleEn String? subtitle String? subtitleEn String? displayOrder Int @default(0) isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime keywords keywords[] @@index([displayOrder], map: "idx_quarter_displayOrder") @@index([quarter], map: "idx_quarter_quarter") } model tags { id String @id name String @unique nameEn String? slug String @unique createdAt DateTime @default(now()) project_tags project_tags[] @@index([slug], map: "idx_tag_slug") } model visual_style_rules { id Int @id @default(autoincrement()) name String @unique minScore Int maxScore Int color String size String border String rotation String? priority Int @default(0) enabled Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @@index([enabled], map: "idx_visualStyleRule_enabled") @@index([minScore, maxScore], map: "idx_visualStyleRule_scoreRange") } enum LinkType { WEBSITE GITHUB HUGGINGFACE PAPER } enum ProjectStatus { ACTIVE ARCHIVED } enum TaskStatus { PENDING IN_PROGRESS COMPLETED FAILED } // ================================ // AI Timeline System Models // ================================ model AIEvent { id String @id @default(cuid()) title String titleEn String? eventDate DateTime description String descriptionEn String? imageUrl String sourceUrl String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([eventDate(sort: Desc)]) @@index([createdAt]) @@map("ai_events") }