405 lines
12 KiB
Plaintext
405 lines
12 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "mysql"
|
|
}
|
|
|
|
model Category {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(50)
|
|
slug String @unique @db.VarChar(50)
|
|
icon String? @db.VarChar(100)
|
|
parentId Int? @map("parent_id")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
tools Tool[]
|
|
pendingTools PendingTool[]
|
|
parent Category? @relation("CategoryToCategory", fields: [parentId], references: [id])
|
|
children Category[] @relation("CategoryToCategory")
|
|
|
|
@@map("categories")
|
|
}
|
|
|
|
model SkillCategory {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(50)
|
|
slug String @unique @db.VarChar(50)
|
|
icon String? @db.VarChar(100)
|
|
parentId Int? @map("parent_id")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
skills Skill[]
|
|
pendingSkills PendingSkill[]
|
|
parent SkillCategory? @relation("SkillCategoryToSkillCategory", fields: [parentId], references: [id])
|
|
children SkillCategory[] @relation("SkillCategoryToSkillCategory")
|
|
|
|
@@map("skill_categories")
|
|
}
|
|
|
|
model Tool {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(100)
|
|
slug String @unique @db.VarChar(100)
|
|
categoryId Int @map("category_id")
|
|
description String @db.Text
|
|
logoUrl String? @map("logo_url") @db.VarChar(255)
|
|
websiteUrl String @map("website_url") @db.VarChar(255)
|
|
pricingModel PricingModel @default(freemium) @map("pricing_model")
|
|
pricingDetail String? @map("pricing_detail") @db.VarChar(200)
|
|
features Json?
|
|
tags Json?
|
|
viewCount Int @default(0) @map("view_count")
|
|
status Status @default(draft)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
category Category @relation(fields: [categoryId], references: [id])
|
|
favorites Favorite[]
|
|
browsingHistory BrowsingHistory[]
|
|
reviews Review[]
|
|
collectionItems CollectionItem[]
|
|
|
|
@@index([categoryId, status])
|
|
@@fulltext([name, description])
|
|
@@map("tools")
|
|
}
|
|
|
|
model PendingTool {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(100)
|
|
slug String? @db.VarChar(100)
|
|
categoryId Int? @map("category_id")
|
|
description String? @db.Text
|
|
logoUrl String? @map("logo_url") @db.VarChar(255)
|
|
websiteUrl String? @map("website_url") @db.VarChar(255)
|
|
pricingModel PricingModel? @default(freemium) @map("pricing_model")
|
|
pricingDetail String? @map("pricing_detail") @db.VarChar(200)
|
|
features Json?
|
|
tags Json?
|
|
sourceUrl String? @map("source_url") @db.VarChar(255)
|
|
status PendingStatus @default(pending)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
category Category? @relation(fields: [categoryId], references: [id])
|
|
|
|
@@map("pending_tools")
|
|
}
|
|
|
|
model Skill {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(100)
|
|
slug String @unique @db.VarChar(100)
|
|
categoryId Int @map("category_id")
|
|
description String @db.Text
|
|
logoUrl String? @map("logo_url") @db.VarChar(255)
|
|
sourceUrl String @map("source_url") @db.VarChar(255)
|
|
sourceType String @default("gitee") @map("source_type") @db.VarChar(20)
|
|
rating Float @default(0) @db.Float
|
|
features Json?
|
|
tags Json?
|
|
viewCount Int @default(0) @map("view_count")
|
|
status Status @default(draft)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
category SkillCategory @relation(fields: [categoryId], references: [id])
|
|
favorites Favorite[]
|
|
browsingHistory BrowsingHistory[]
|
|
reviews Review[]
|
|
collectionItems CollectionItem[]
|
|
skillReview SkillReview?
|
|
|
|
lastReviewedAt DateTime? @map("last_reviewed_at")
|
|
githubStarsHistory Json? @map("github_stars_history")
|
|
|
|
@@index([categoryId, status])
|
|
@@map("skills")
|
|
}
|
|
|
|
model PendingSkill {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(100)
|
|
slug String? @db.VarChar(100)
|
|
categoryId Int? @map("category_id")
|
|
description String? @db.Text
|
|
logoUrl String? @map("logo_url") @db.VarChar(255)
|
|
sourceUrl String? @map("source_url") @db.VarChar(255)
|
|
sourceType String? @map("source_type") @db.VarChar(20)
|
|
rating Float @default(0) @db.Float
|
|
features Json?
|
|
tags Json?
|
|
status PendingStatus @default(pending)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
category SkillCategory? @relation(fields: [categoryId], references: [id])
|
|
|
|
@@map("pending_skills")
|
|
}
|
|
|
|
enum PricingModel {
|
|
free
|
|
freemium
|
|
paid
|
|
subscription
|
|
}
|
|
|
|
enum Status {
|
|
draft
|
|
published
|
|
}
|
|
|
|
enum PendingStatus {
|
|
pending
|
|
approved
|
|
rejected
|
|
}
|
|
|
|
model SystemConfig {
|
|
id Int @id @default(autoincrement())
|
|
key String @unique @db.VarChar(50)
|
|
value Json
|
|
@@map("system_configs")
|
|
}
|
|
|
|
model User {
|
|
id Int @id @default(autoincrement())
|
|
email String @unique @db.VarChar(255)
|
|
passwordHash String? @db.VarChar(255)
|
|
name String? @db.VarChar(100)
|
|
avatarUrl String?
|
|
oauthProvider String? @db.VarChar(50)
|
|
oauthId String? @unique @db.VarChar(255)
|
|
role String @default("user") @db.VarChar(20)
|
|
roleId Int? @map("role_id")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
assignedRole Role? @relation(fields: [roleId], references: [id])
|
|
favorites Favorite[]
|
|
browsingHistory BrowsingHistory[]
|
|
reviews Review[]
|
|
collections Collection[]
|
|
|
|
@@unique([oauthProvider, oauthId])
|
|
@@map("users")
|
|
}
|
|
|
|
model Role {
|
|
id Int @id @default(autoincrement())
|
|
name String @db.VarChar(50)
|
|
slug String @unique @db.VarChar(50)
|
|
isSystem Boolean @default(false) @map("is_system")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
permissions RolePermission[]
|
|
users User[]
|
|
|
|
@@map("roles")
|
|
}
|
|
|
|
model Permission {
|
|
id Int @id @default(autoincrement())
|
|
groupName String @map("group_name") @db.VarChar(50)
|
|
name String @db.VarChar(50)
|
|
key String @unique @db.VarChar(80)
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
rolePermissions RolePermission[]
|
|
|
|
@@index([groupName, sortOrder])
|
|
@@map("permissions")
|
|
}
|
|
|
|
model RolePermission {
|
|
roleId Int @map("role_id")
|
|
permissionId Int @map("permission_id")
|
|
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([roleId, permissionId])
|
|
@@map("role_permissions")
|
|
}
|
|
|
|
model Favorite {
|
|
id Int @id @default(autoincrement())
|
|
userId Int @map("user_id")
|
|
toolId Int? @map("tool_id")
|
|
skillId Int? @map("skill_id")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
|
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, toolId])
|
|
@@unique([userId, skillId])
|
|
@@index([userId])
|
|
@@map("favorites")
|
|
}
|
|
|
|
model BrowsingHistory {
|
|
id Int @id @default(autoincrement())
|
|
userId Int @map("user_id")
|
|
toolId Int? @map("tool_id")
|
|
skillId Int? @map("skill_id")
|
|
viewedAt DateTime @default(now()) @updatedAt @map("viewed_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
|
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, toolId])
|
|
@@unique([userId, skillId])
|
|
@@index([userId, viewedAt])
|
|
@@map("browsing_histories")
|
|
}
|
|
|
|
model Review {
|
|
id Int @id @default(autoincrement())
|
|
userId Int @map("user_id")
|
|
toolId Int? @map("tool_id")
|
|
skillId Int? @map("skill_id")
|
|
rating Int?
|
|
comment String @db.Text
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
|
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, toolId])
|
|
@@unique([userId, skillId])
|
|
@@index([toolId, createdAt])
|
|
@@index([skillId, createdAt])
|
|
@@map("reviews")
|
|
}
|
|
|
|
model Collection {
|
|
id Int @id @default(autoincrement())
|
|
userId Int @map("user_id")
|
|
name String @db.VarChar(50)
|
|
description String? @db.Text
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
items CollectionItem[]
|
|
|
|
@@index([userId])
|
|
@@map("collections")
|
|
}
|
|
|
|
model CollectionItem {
|
|
id Int @id @default(autoincrement())
|
|
collectionId Int @map("collection_id")
|
|
toolId Int? @map("tool_id")
|
|
skillId Int? @map("skill_id")
|
|
addedAt DateTime @default(now()) @map("added_at")
|
|
|
|
collection Collection @relation(fields: [collectionId], references: [id], onDelete: Cascade)
|
|
tool Tool? @relation(fields: [toolId], references: [id], onDelete: Cascade)
|
|
skill Skill? @relation(fields: [skillId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([collectionId, toolId])
|
|
@@unique([collectionId, skillId])
|
|
@@index([collectionId])
|
|
@@map("collection_items")
|
|
}
|
|
|
|
model DailyReport {
|
|
id Int @id @default(autoincrement())
|
|
date DateTime @unique @db.Date
|
|
title String @db.VarChar(200)
|
|
summary String? @db.Text
|
|
hotCount Int @default(0) @map("hot_count")
|
|
coverUrl String? @map("cover_url") @db.VarChar(255)
|
|
status Status @default(draft)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
items DailyReportItem[]
|
|
|
|
@@index([date])
|
|
@@index([status])
|
|
@@map("daily_reports")
|
|
}
|
|
|
|
model DailyReportItem {
|
|
id Int @id @default(autoincrement())
|
|
reportId Int @map("report_id")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
category String @default("tech") @db.VarChar(20)
|
|
title String @db.VarChar(200)
|
|
summary String? @db.Text
|
|
detail String? @db.Text
|
|
sourceUrl String? @map("source_url") @db.VarChar(500)
|
|
imageUrl String? @map("image_url") @db.VarChar(255)
|
|
hotScore Int @default(0) @map("hot_score")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
report DailyReport @relation(fields: [reportId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([reportId, sortOrder])
|
|
@@map("daily_report_items")
|
|
}
|
|
|
|
model SkillReview {
|
|
id Int @id @default(autoincrement())
|
|
skillId Int @unique @map("skill_id")
|
|
skill Skill @relation(fields: [skillId], references: [id])
|
|
|
|
capability Float
|
|
devExp Float @map("dev_exp")
|
|
costLicense Float @map("cost_license")
|
|
community Float
|
|
performance Float
|
|
overall Float
|
|
|
|
reviews Json
|
|
|
|
longArticle String? @map("long_article") @db.Text
|
|
videoScript String? @map("video_script") @db.Text
|
|
socialCards Json? @map("social_cards")
|
|
|
|
status ReviewStatus @default(DRAFT)
|
|
reviewedAt DateTime @updatedAt @map("reviewed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@index([skillId])
|
|
@@index([overall])
|
|
@@map("skill_reviews")
|
|
}
|
|
|
|
model ReviewGenerationLog {
|
|
id Int @id @default(autoincrement())
|
|
skillId Int @map("skill_id")
|
|
status String @db.VarChar(20)
|
|
prompt String @db.Text
|
|
response String? @db.Text
|
|
error String? @db.Text
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@index([skillId])
|
|
@@map("review_generation_logs")
|
|
}
|
|
|
|
enum ReviewStatus {
|
|
DRAFT
|
|
PUBLISHED
|
|
REJECTED
|
|
OUTDATED
|
|
}
|
|
|