v0.11.1: 权限体系重构 + AI管线优化 + 内容整理
This commit is contained in:
@@ -0,0 +1,404 @@
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user