6c45cef4b7
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
工作台新增与项目平级的全局协作台账,复用共享库在线协作能力。两本台账使用合同台账明细表、临床运营项目编号的空白模板,支持独立账号授权、在线编辑和历史版本保留,禁止删除整个台账及历史版本。 台账管理拆分为信息维护、访问与权限、历史版本三个独立入口;后两者与项目共享组件。统一项目和台账的卡片高度、数量徽标与标题布局,缩小工作台顶部留白,优化信息维护弹窗,并修复空用途说明和版本命名的默认提示。同步现有飞线图白色残影修复,以及在线文档的字体构建支持。 已验证:前端五百五十四项测试、后端台账与在线文档七十四项测试、类型检查、界面约束、运行时边界、桌面发布静态检查、网页构建和本地桌面应用构建均通过。数据库表结构升级已完成离线脚本生成检查,存储持久化检查通过。桌面凭据测试显式隔离构建环境,并覆盖使用默认服务器地址读取凭据的场景;在注入默认服务器地址的环境中完成全部前端测试。 提交包含必需的表结构升级和只有表头的初始模板;不包含本地台账业务记录、数据库导出、账号授权运行数据或上传目录中的历史文件。字体文件沿用部署方单独提供的方式。
89 lines
2.2 KiB
Python
89 lines
2.2 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, Field, field_validator
|
|
|
|
LedgerRole = Literal["VIEWER", "EDITOR", "MANAGER"]
|
|
|
|
|
|
class LedgerRead(BaseModel):
|
|
id: uuid.UUID
|
|
title: str
|
|
description: str
|
|
status: Literal["ACTIVE", "ARCHIVED"]
|
|
owner_id: uuid.UUID
|
|
owner_name: str
|
|
generation: int
|
|
updated_at: datetime
|
|
current_revision_id: uuid.UUID | None
|
|
current_revision_no: int | None
|
|
current_revision_file_size: int | None
|
|
current_revision_mime_type: str | None
|
|
current_revision_created_at: datetime | None
|
|
role: LedgerRole
|
|
can_edit: bool
|
|
can_manage: bool
|
|
can_export: bool
|
|
allow_export: bool
|
|
allow_edit_request: bool
|
|
allow_sheet_structure_edit: bool
|
|
file_type: Literal["cell"] = "cell"
|
|
extension: Literal["xlsx"] = "xlsx"
|
|
can_request_edit: bool
|
|
edit_request_status: Literal["PENDING", "APPROVED", "REJECTED"] | None = None
|
|
can_transfer_ownership: bool
|
|
|
|
|
|
class LedgerSettings(BaseModel):
|
|
title: str = Field(min_length=1, max_length=240)
|
|
description: str = Field(default="", max_length=500)
|
|
status: Literal["ACTIVE", "ARCHIVED"]
|
|
owner_id: uuid.UUID
|
|
allow_export: bool = False
|
|
allow_edit_request: bool | None = None
|
|
allow_sheet_structure_edit: bool = False
|
|
generation: int = Field(ge=1)
|
|
|
|
@field_validator("title")
|
|
@classmethod
|
|
def trim_title(cls, value):
|
|
value = value.strip()
|
|
if not value:
|
|
raise ValueError("台账名称不能为空")
|
|
return value
|
|
|
|
|
|
class LedgerMemberUpsert(BaseModel):
|
|
user_id: uuid.UUID
|
|
role: LedgerRole
|
|
|
|
|
|
class LedgerMemberRead(BaseModel):
|
|
user_id: uuid.UUID
|
|
full_name: str
|
|
email: str
|
|
role: LedgerRole
|
|
is_active: bool
|
|
protected_label: str | None = None
|
|
|
|
|
|
class LedgerCandidateRead(BaseModel):
|
|
user_id: uuid.UUID
|
|
full_name: str
|
|
email: str
|
|
role_in_study: str
|
|
can_be_editor: bool = True
|
|
can_be_manager: bool = True
|
|
|
|
|
|
class LedgerAccessSettings(BaseModel):
|
|
generation: int = Field(ge=1)
|
|
allow_export: bool | None = None
|
|
allow_edit_request: bool | None = None
|
|
allow_sheet_structure_edit: bool | None = None
|
|
|
|
|
|
class LedgerRestore(BaseModel):
|
|
generation: int = Field(ge=1)
|