// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema // Get a free hosted Postgres database in seconds: `npx create-db` generator client { provider = "prisma-client" output = "../generated/prisma" } datasource db { provider = "mysql" } model User { id Int @id @default(autoincrement()) name String email String @unique password String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Article { id Int @id @default(autoincrement()) title String slug String @unique content String date String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Strategy { id Int @id @default(autoincrement()) name String description String data Json createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Indicator { id Int @id @default(autoincrement()) name String @unique groupName String title String @default("") unit String @default("") source String @default("") frequency String @default("month") // year | quarter | month | day hidden Boolean @default(false) // true = 数据/脚本保留, 但不在前端展示 points IndicatorPoint[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model IndicatorPoint { id Int @id @default(autoincrement()) indicatorId Int indicator Indicator @relation(fields: [indicatorId], references: [id], onDelete: Cascade) period String // "2024" | "2024-Q1" | "2024-01" | "2024-01-15" value Float createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([indicatorId, period]) } // 新闻: 每天 3 点由 mx_finance_search_news 拉取, 按影响大小排序, 累加多日供首页无限滚动 model News { id Int @id @default(autoincrement()) title String summary String @default("") content String? @db.Text source String @default("") url String @default("") publishedAt DateTime impactRank Int createdAt DateTime @default(now()) @@unique([title, publishedAt]) @@index([publishedAt]) } // 报警: refresh 写库时比对同 (indicatorName, period) 的跨源数据, 差异超阈值记录 model Alert { id Int @id @default(autoincrement()) indicatorName String period String valueA Float valueB Float sourceA String sourceB String diff Float diffRatio Float createdAt DateTime @default(now()) @@index([createdAt]) } // 服务器监控: 对接 komari 公开 API model ServerNode { id Int @id @default(autoincrement()) uuid String @unique name String cpuName String @default("") os String @default("") region String @default("") memTotal BigInt @default(0) diskTotal BigInt @default(0) cpuCores Int @default(0) // 最新实时快照 cpuUsage Float @default(0) ramUsed BigInt @default(0) swapUsed BigInt @default(0) load1 Float @default(0) load5 Float @default(0) load15 Float @default(0) diskUsed BigInt @default(0) netIn BigInt @default(0) netOut BigInt @default(0) uptime BigInt @default(0) process Int @default(0) connections Int @default(0) status String @default("unknown") // online | offline | unknown recordedAt DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } // 时序历史: 每节点每分钟一条 (komari records 1 分钟粒度) model ServerNodeHistory { id Int @id @default(autoincrement()) uuid String period DateTime cpu Float @default(0) ram BigInt @default(0) load Float @default(0) disk BigInt @default(0) netIn BigInt @default(0) netOut BigInt @default(0) process Int @default(0) connections Int @default(0) createdAt DateTime @default(now()) @@unique([uuid, period]) @@index([uuid, period]) } // 服务健康检查: 本应用自检 (健康端点 / DB / 第三方) model ServiceCheck { id Int @id @default(autoincrement()) name String @unique url String status String @default("unknown") // up | down | unknown latencyMs Int @default(0) message String @default("") lastCheckAt DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Econ_SowInventory { id Int @id @default(autoincrement()) month String @unique inventory Int // 能繁母猪数量(万头) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model ScraperCache { id Int @id @default(autoincrement()) scraperName String @unique // 爬虫名称,如:sow-inventory lastDataHash String? // 上次数据指纹 lastUpdateAt DateTime // 上次更新时间 metadata Json? // 其他元数据 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }