422 lines
15 KiB
Plaintext
422 lines
15 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
datasource db {
|
|
provider = "mysql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
/// 用户及个人设置
|
|
model User {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 登录用户名,唯一
|
|
username String @unique @db.VarChar(64)
|
|
/// 登录密码的 bcrypt 哈希,不存储明文
|
|
passwordHash String @db.VarChar(255)
|
|
/// 本位币代码
|
|
baseCurrency String @default("CNY") @db.Char(3)
|
|
/// 隐藏菜单标识列表
|
|
hiddenMenus String @default("") @db.VarChar(128)
|
|
/// 登录有效时长,单位小时,范围 1 至 720
|
|
sessionHours Int @default(168)
|
|
/// 查看隐藏项目是否需要再次验证密码
|
|
requireHiddenPassword Boolean @default(true)
|
|
/// 总览显示的卡片键列表,空值表示默认全部显示
|
|
overviewCards Json?
|
|
/// 独立资产是否参与资产总览和净资产轨迹
|
|
includeIndependentAssets Boolean @default(true)
|
|
/// 账户分组显示顺序;空值表示沿用默认顺序
|
|
accountGroupOrder Json?
|
|
/// 是否显示备注
|
|
showNotes Boolean @default(true)
|
|
/// 无操作退出分钟数,0 表示关闭
|
|
idleMinutes Int @default(30)
|
|
/// 记录创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
/// 记录更新时间,UTC
|
|
updatedAt DateTime @updatedAt
|
|
positions Position[]
|
|
rates ExchangeRate[]
|
|
metalPrices MetalPrice[]
|
|
sessions Session[]
|
|
icons Icon[]
|
|
transfers Transfer[]
|
|
schedules Schedule[]
|
|
agentGrants AgentGrant[]
|
|
agentOperations AgentOperation[]
|
|
agentAuthorizations AgentAuthorization[]
|
|
agentPolicy AgentPolicy?
|
|
agentCalls AgentCall[]
|
|
}
|
|
|
|
/// MCP 调用审计,不保存工具参数、令牌、密码或财务内容
|
|
model AgentCall {
|
|
/// 审计记录标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 可信认证上下文中的用户标识
|
|
userId String @db.Char(36)
|
|
/// 所属用户;注销后级联清理
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 发起调用的连接标识
|
|
grantId String @db.Char(36)
|
|
/// 工具名称
|
|
tool String @db.VarChar(100)
|
|
/// 结果状态 success 或 error
|
|
status String @db.VarChar(16)
|
|
/// 调用完成时间,UTC
|
|
createdAt DateTime @default(now())
|
|
@@index([userId,createdAt])
|
|
}
|
|
|
|
/// 用户的 Agent 写入策略
|
|
model AgentPolicy {
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @id @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 写入策略:readonly 只读、draft 草稿、direct 普通直接写入
|
|
mode String @default("draft") @db.VarChar(16)
|
|
}
|
|
|
|
/// OAuth 动态注册客户端元数据
|
|
model AgentClient {
|
|
/// 唯一标识
|
|
id String @id @db.Char(36)
|
|
/// 公开客户端注册元数据,不保存用户凭据
|
|
metadata Json
|
|
/// 创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
/// 短期 OAuth 授权请求及一次性授权码摘要
|
|
model AgentAuthorization {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String? @db.Char(36)
|
|
user User? @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// OAuth 客户端标识;个人令牌为空
|
|
clientId String @db.Char(36)
|
|
/// 具体操作参数;禁止保存密码及令牌
|
|
parameters Json
|
|
/// 一次性授权码 SHA-256 摘要
|
|
codeDigest String? @unique @db.Char(64)
|
|
/// 到期时间,UTC
|
|
expiresAt DateTime
|
|
/// 当前处理状态
|
|
status String @default("pending") @db.VarChar(16)
|
|
}
|
|
|
|
/// 用户授权连接、令牌摘要及资源权限
|
|
model AgentGrant {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// OAuth 客户端标识;个人令牌为空
|
|
clientId String? @db.Char(36)
|
|
/// 用户可见连接名称
|
|
name String @db.VarChar(100)
|
|
/// 权限列表:read、draft、write、sensitive
|
|
scopes Json
|
|
/// 令牌适用的规范 MCP 资源地址
|
|
resource String @db.VarChar(500)
|
|
/// 访问令牌 SHA-256 摘要;完整值仅颁发时返回
|
|
accessDigest String @unique @db.Char(64)
|
|
/// 刷新令牌 SHA-256 摘要,使用后轮换
|
|
refreshDigest String? @unique @db.Char(64)
|
|
/// 到期时间,UTC
|
|
expiresAt DateTime
|
|
/// 刷新授权到期时间,UTC
|
|
refreshExpiresAt DateTime?
|
|
/// 撤销时间,UTC;空表示未撤销
|
|
revokedAt DateTime?
|
|
/// 本连接的独立业务授权会话标识,不作为 MCP 凭证
|
|
sessionId String @db.Char(64)
|
|
/// 创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
@@index([userId,createdAt])
|
|
}
|
|
|
|
/// Agent 写入草稿、幂等记录及提交结果
|
|
model AgentOperation {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 发起操作的授权连接标识
|
|
grantId String @db.Char(36)
|
|
/// 同用户唯一的客户端幂等键
|
|
key String @db.VarChar(128)
|
|
/// 工具和参数的规范摘要;拒绝同键不同参数
|
|
hash String @db.Char(64)
|
|
/// 业务工具名称
|
|
tool String @db.VarChar(100)
|
|
/// 具体操作参数;禁止保存密码及令牌
|
|
parameters Json
|
|
/// 确认前的账目版本摘要,防止覆盖并发修改
|
|
snapshot String @db.Char(64)
|
|
/// 当前处理状态
|
|
status String @default("pending") @db.VarChar(16)
|
|
/// 到期时间,UTC
|
|
expiresAt DateTime
|
|
/// 结构化操作结果或最近提交失败原因
|
|
result Json?
|
|
/// 创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
/// 完成或取消时间,UTC
|
|
completedAt DateTime?
|
|
@@unique([userId,key])
|
|
@@index([userId,createdAt])
|
|
}
|
|
/// 登录会话与隐藏项目查看授权
|
|
model Session {
|
|
/// 随机会话令牌的 SHA-256 摘要
|
|
id String @id @db.Char(64)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 会话过期时间,UTC
|
|
expiresAt DateTime
|
|
/// 最后有效交互时间,UTC
|
|
lastActivity DateTime @default(now())
|
|
/// 隐藏项目授权截止时间,UTC;空表示未解锁
|
|
revealUntil DateTime?
|
|
/// 已下载备份内容的 SHA-256 摘要
|
|
backupDigest String? @db.Char(64)
|
|
/// 备份清空确认凭据截止时间,UTC
|
|
backupExpiresAt DateTime?
|
|
@@index([userId])
|
|
}
|
|
/// 持有项目:账户、独立资产和借入借出债务
|
|
model Position {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 备份导入来源项目标识,用于重复导入识别
|
|
importedFromId String? @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 项目类型:account 账户、asset 独立资产、debt 债务
|
|
kind String @db.VarChar(16)
|
|
/// 统计方向:asset 资产或借出应收、liability 负债或借入应付
|
|
side String @db.VarChar(16)
|
|
/// 显示名称
|
|
name String @db.VarChar(100)
|
|
/// 项目分类代码
|
|
category String @db.VarChar(40)
|
|
/// 自定义账户分组;空字符串表示未分组
|
|
groupName String @default("") @db.VarChar(60)
|
|
/// 原始币种代码
|
|
currency String @db.Char(3)
|
|
/// 用户备注,原文保留
|
|
notes String @db.Text
|
|
/// 是否归档;归档项目仍计入总额
|
|
archived Boolean @default(false)
|
|
/// 是否隐藏;未解锁时不参与可见范围统计
|
|
hidden Boolean @default(false)
|
|
/// 是否参与资产负债总额及净资产轨迹
|
|
included Boolean @default(true)
|
|
/// 贵金属品种:gold 黄金或 silver 白银
|
|
metalType String? @db.VarChar(12)
|
|
/// 贵金属总重量,单位克
|
|
metalGrams Decimal? @db.Decimal(24,8)
|
|
/// 贵金属纯度比例,0 至 1
|
|
metalPurity Decimal @default(1) @db.Decimal(12,8)
|
|
/// 是否随每日价格更新自动记录估值
|
|
autoValuation Boolean @default(false)
|
|
/// 记录创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
/// 记录更新时间,UTC
|
|
updatedAt DateTime @updatedAt
|
|
/// 关联账户图标标识
|
|
iconId String? @db.Char(36)
|
|
icon Icon? @relation(fields:[iconId],references:[id],onDelete:SetNull)
|
|
revisions Revision[]
|
|
outgoing PositionLink[] @relation("Source")
|
|
incoming PositionLink[] @relation("Target")
|
|
transfersOut Transfer[] @relation("TransferSource")
|
|
transfersIn Transfer[] @relation("TransferTarget")
|
|
@@index([userId,kind])
|
|
@@unique([userId,importedFromId])
|
|
}
|
|
/// 余额历史:金额为变更后的绝对余额
|
|
model Revision {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 数据库自增唯一顺序,同业务时间按此排序
|
|
sequence Int @unique @default(autoincrement())
|
|
/// 所属持有项目标识
|
|
positionId String @db.Char(36)
|
|
position Position @relation(fields:[positionId],references:[id],onDelete:Cascade)
|
|
/// 变更后的原币绝对余额,不是收支增量,禁止对全部历史求和
|
|
/// 负债账户正数为欠款,负数为溢缴存款;前端显示符号相反
|
|
amount Decimal @db.Decimal(24,8)
|
|
/// 北京时间业务时间对应的 UTC,精确到分钟
|
|
effectiveDate DateTime @db.DateTime(3)
|
|
/// 用户备注,原文保留
|
|
notes String @db.Text
|
|
/// 变更原因:初始、余额、估值、转账或借贷配对操作
|
|
reason String @db.VarChar(20)
|
|
/// 记录创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
/// 记录更新时间,UTC
|
|
updatedAt DateTime @updatedAt
|
|
@@index([positionId,effectiveDate,sequence])
|
|
@@index([positionId,reason,effectiveDate,sequence])
|
|
}
|
|
/// 项目关联关系,不参与金额求和
|
|
model PositionLink {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 关联来源项目标识,通常为债务
|
|
sourceId String @db.Char(36)
|
|
/// 关联目标项目标识,通常为账户或资产
|
|
targetId String @db.Char(36)
|
|
source Position @relation("Source",fields:[sourceId],references:[id],onDelete:Cascade)
|
|
target Position @relation("Target",fields:[targetId],references:[id],onDelete:Cascade)
|
|
@@unique([sourceId,targetId])
|
|
}
|
|
/// 用户原币兑本位币的历史汇率
|
|
model ExchangeRate {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 原始币种代码
|
|
currency String @db.Char(3)
|
|
/// 本位币代码
|
|
baseCurrency String @db.Char(3)
|
|
/// 汇率业务日期
|
|
date DateTime @db.Date
|
|
/// 每单位原币对应的本位币金额
|
|
rate Decimal @db.Decimal(24,12)
|
|
/// 汇率来源标识,保留已有历史来源
|
|
source String @db.VarChar(30)
|
|
@@unique([userId,currency,baseCurrency,date])
|
|
}
|
|
|
|
/// 可复用账户图标
|
|
model Icon {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 上传用户标识;空可表示系统图标或原用户已删除
|
|
ownerId String? @db.Char(36)
|
|
owner User? @relation(fields:[ownerId],references:[id],onDelete:SetNull)
|
|
/// 显示名称
|
|
name String @db.VarChar(100)
|
|
/// 是否公开共享给已登录用户
|
|
shared Boolean @default(false)
|
|
/// 规范化图标内容的 SHA-256 摘要
|
|
hash String @db.Char(64)
|
|
/// 规范化静态 PNG 图片二进制
|
|
data Bytes @db.MediumBlob
|
|
/// 可选公开来源网址
|
|
source String? @db.VarChar(500)
|
|
/// 记录创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
positions Position[]
|
|
@@unique([ownerId,hash,shared])
|
|
@@index([shared,name])
|
|
}
|
|
|
|
/// 资金往来及账户与债务的双边配对记账
|
|
model Transfer {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 备份导入来源项目标识,用于重复导入识别
|
|
importedFromId String? @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 来源资产账户标识
|
|
sourceId String @db.Char(36)
|
|
/// 目标账户或债务标识
|
|
targetId String @db.Char(36)
|
|
source Position @relation("TransferSource",fields:[sourceId],references:[id],onDelete:Cascade)
|
|
target Position @relation("TransferTarget",fields:[targetId],references:[id],onDelete:Cascade)
|
|
/// 来源账户配对余额历史标识
|
|
sourceRevisionId String @unique @db.Char(36)
|
|
/// 目标项目配对余额历史标识
|
|
targetRevisionId String @unique @db.Char(36)
|
|
/// 来源账户币种
|
|
sourceCurrency String @db.Char(3)
|
|
/// 目标项目币种
|
|
targetCurrency String @db.Char(3)
|
|
/// 本次来源账户本金金额,不是变更后余额
|
|
amount Decimal @db.Decimal(24,8)
|
|
/// 本次目标到账金额或债务本金金额
|
|
received Decimal @db.Decimal(24,8)
|
|
/// 来源币种手续费;负数表示优惠
|
|
fee Decimal @db.Decimal(24,8)
|
|
/// 北京时间业务时间对应的 UTC,精确到分钟
|
|
effectiveDate DateTime @db.DateTime(3)
|
|
/// 用户备注,原文保留
|
|
notes String @db.Text
|
|
/// 操作类型:transfer 转账、borrow 借入、lend 借出、collect 收款、repay 还款
|
|
operation String @default("transfer") @db.VarChar(16)
|
|
/// 记录创建时间,UTC
|
|
createdAt DateTime @default(now())
|
|
@@unique([userId,importedFromId])
|
|
@@index([userId,effectiveDate,id])
|
|
}
|
|
|
|
/// 按需执行的定时支出或转账计划
|
|
model Schedule {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 备份来源计划标识,用于重复导入识别
|
|
importedFromId String? @db.Char(36)
|
|
/// 计划显示名称
|
|
name String @db.VarChar(100)
|
|
/// 操作类型:expense 支出或 transfer 转账
|
|
operation String @db.VarChar(16)
|
|
/// 支出或转出资产账户标识
|
|
sourceId String @db.Char(36)
|
|
/// 转入账户标识;支出计划为空
|
|
targetId String? @db.Char(36)
|
|
/// 原币支出或转出金额
|
|
amount Decimal @db.Decimal(24,8)
|
|
/// 原币到账金额;支出计划为零
|
|
received Decimal @db.Decimal(24,8)
|
|
/// 下次到期业务时间对应的 UTC
|
|
nextAt DateTime @db.DateTime(3)
|
|
/// 重复间隔天数;零表示仅执行一次
|
|
intervalDays Int
|
|
/// 是否启用计划
|
|
enabled Boolean @default(true)
|
|
/// 一次性计划是否已执行完毕
|
|
completed Boolean @default(false)
|
|
/// 用户备注,原文保留
|
|
notes String @db.Text
|
|
@@index([userId,enabled,nextAt])
|
|
@@unique([userId,importedFromId])
|
|
}
|
|
|
|
/// 用户的贵金属每克参考价历史
|
|
model MetalPrice {
|
|
/// 唯一标识
|
|
id String @id @default(uuid()) @db.Char(36)
|
|
/// 所属用户标识,用于数据隔离
|
|
userId String @db.Char(36)
|
|
user User @relation(fields:[userId],references:[id],onDelete:Cascade)
|
|
/// 品种:gold 黄金或 silver 白银
|
|
metalType String @db.VarChar(12)
|
|
/// 价格币种
|
|
currency String @db.Char(3)
|
|
/// 纯金属每克价格
|
|
price Decimal @db.Decimal(24,12)
|
|
/// 报价日期,UTC+8 自然日
|
|
date DateTime @db.Date
|
|
/// 价格来源:manual 或 goldapi
|
|
source String @db.VarChar(20)
|
|
/// 报价对应时间,UTC
|
|
quotedAt DateTime @db.DateTime(3)
|
|
@@unique([userId, metalType, currency, date])
|
|
}
|