feat(database): init database folder frontend and permission

This commit is contained in:
ymy
2026-07-23 23:41:11 +08:00
parent 5df1900ca8
commit 4021e58d5d
67 changed files with 9436 additions and 150 deletions
+125
View File
@@ -50,6 +50,7 @@ model Organization {
projectGroupBindings ProjectGroupBinding[]
auditEntries AuditEntry[] @relation("organizationAudit")
projectSearchDocuments ProjectSearchDocument[]
fileLibNodes FileLibNode[]
@@index([status])
}
@@ -923,3 +924,127 @@ model CapabilityCredentialVersion {
@@index([keyId])
@@index([createdByUserId])
}
// --- File library (文件库) -------------------------------------------------
//
// 独立模块,语义由仓库根《文件库-接口契约.md》(C/D 编号)与 .omo/文件库-开工计划.md
// (D11D19)锚定。与上面的 Folder/Project(hub 自己的 explorer,ADR-0021)是两套
// 体系,不复用、不互相引用。
/// 文件库目录树节点:文件夹(容器)或项目(叶子,关联 git 仓库)。
/// parentId 是树的权威关系;pathIds 是 id 编码的物化路径(派生),随 create/move
/// 在事务内维护(计划 D12;name 不入路径,rename 不重写后代)。
model FileLibNode {
id String @id
organizationId String
parentId String?
kind FileLibNodeKind
name String
/// D14:NFC+trim 的小写形式;活跃兄弟节点大小写不敏感唯一(部分唯一索引在迁移 SQL)。
nameLower String
/// id 编码物化路径,形如 "/rootId/childId/selfId"。祖先展开与前缀查询都用它。
pathIds String
/// D11:创建者不可变,自动持有 isCreatorGrant=true 的 MANAGE grant。
/// 故意不建 FK:这是不可变历史事实,不随 User 生命周期变化。
creatorId String
/// 老师可填写的简介,创建/概览页展示,通俗易懂地说明这个节点的用途。
description String?
/// 项目 provisioning 状态机(DB/git 双写协调,Metis 风险#1);文件夹恒 READY。
provisionStatus FileLibProvisionStatus @default(READY)
/// 项目仓库目录(绝对路径);文件夹为 null。
storageDir String?
deletedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
parent FileLibNode? @relation("fileLibTree", fields: [parentId], references: [id], onDelete: Restrict)
children FileLibNode[] @relation("fileLibTree")
grants FileLibGrant[]
projectSettings FileLibProjectSettings?
exportJobs FileLibExportJob[]
@@index([organizationId, parentId, deletedAt])
@@index([organizationId, pathIds])
@@index([creatorId])
}
enum FileLibNodeKind {
FOLDER
PROJECT
}
enum FileLibProvisionStatus {
PROVISIONING
READY
FAILED
}
/// 文件库权限级别:MANAGE > EDIT > VIEW(契约 2.2,只取最高、无降权)。
enum FileLibRole {
VIEW
EDIT
MANAGE
}
enum FileLibPrincipalType {
USER
GROUP
}
/// 契约 2.3:grant 直接挂在节点上,最终权限 = max(个人, 递归 Group, 祖先继承)。
/// 活跃授权唯一性由迁移里的部分唯一索引保证(revokedAt IS NULL)。
model FileLibGrant {
id String @id @default(cuid())
organizationId String
nodeId String
principalType FileLibPrincipalType
principalId String
role FileLibRole
/// D11:创建者自动 grant;独立权限开关关闭时,项目级 grant 里只有它仍生效。
isCreatorGrant Boolean @default(false)
createdByUserId String?
createdAt DateTime @default(now())
revokedAt DateTime?
node FileLibNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
@@index([organizationId, revokedAt])
@@index([principalType, principalId, revokedAt])
@@index([nodeId, revokedAt])
}
/// 契约 P5/D11:项目独立权限开关。默认关闭(仅继承);关闭时项目级非创建者
/// grant 冻结不删除,重新开启即恢复。
model FileLibProjectSettings {
nodeId String @id
independentPermissionsEnabled Boolean @default(false)
node FileLibNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
}
enum FileLibExportStatus {
QUEUED
RUNNING
DONE
FAILED
}
/// 契约 D10:导出为异步任务。外部导出工具参数 OPEN-6,adapter 就位前先建模型。
model FileLibExportJob {
id String @id @default(cuid())
organizationId String
nodeId String
target String
params Json
status FileLibExportStatus @default(QUEUED)
downloadUrl String?
error String?
createdByUserId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
node FileLibNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
@@index([organizationId, status])
}