Q3-B业务规则、正文检索和原文件预览同步版本:1.4。实现必须服从
DMS_FUNCTION_CONTRACT.md1.4和DMS_API_CONTRACT.md1.4。
本文档用于指导 Codex 在本项目中实现文档管理系统的后端持久化能力。实施时必须以当前 React 前端已经表达的业务交互为范围,优先完成最小可用闭环,不扩展与当前任务无关的功能。
本文档是后续编码工作的基线。开始编码前,应先重新检查当前工作区、Git 状态和既有后端代码,避免覆盖用户修改。
backend/dms-storage/ 保存文档文件。backend/dms-storage/ 是文件内容的事实来源。is_deleted = 0。/api/v1 前缀;现有 /api AI 接口暂不改动。存储根目录固定为:
<project-root>/backend/dms-storage/
后续实现时创建以下目录:
backend/dms-storage/
├── original/ # 正式原始文件
├── preview/ # PDF或其他预览衍生文件
├── extracted/ # 提取后的纯文本或结构化衍生文件
├── temporary/ # 上传过程中的临时文件
├── quarantine/ # 格式异常或校验失败文件
└── recycle/ # 预留目录;B8恢复不移动文件到此目录
backend/dms-storage/ 下的业务文件不得提交到 Git。.gitkeep,并通过 .gitignore 忽略其他内容。.gitignore,只做必要的最小修改。正式文件建议保存为:
original/{yyyy}/{MM}/{documentId}/{fileUuid}.{extension}
示例:
original/2026/07/125/8e79b8be-2cdd-4fbc-a459-268fd83bc230.docx
数据库中的 file_relative_path 只能保存上述相对路径。后端使用配置的存储根目录解析真实路径,并校验解析结果仍然位于 backend/dms-storage/ 内。
第一阶段建立以下 7 张表:
| 表名 | 用途 |
|---|---|
sys_organization |
组织机构树 |
sys_user |
登录用户及固定角色 |
doc_category |
方案计划分类树 |
doc_document |
文档元数据、文件信息及主从关系 |
doc_attachment_binding |
主案与共享附件的多对多挂载关系 |
doc_permission |
组织和人员文档权限 |
sys_audit_log |
登录、查看、下载、上传、删除和权限变更日志 |
本阶段不建立通用文档关系表、标签表、文件版本表、角色表、菜单表、审批表和向量索引表。附件挂载使用专用最小关系表。
erDiagram
SYS_ORGANIZATION {
bigint id PK
bigint parent_id
varchar org_code
varchar org_name
varchar ancestor_path
varchar full_path_name
int tree_level
boolean is_deleted
datetime created_at
datetime updated_at
datetime deleted_at
}
SYS_USER {
bigint id PK
varchar username
varchar password_hash
varchar real_name
bigint organization_id FK
varchar organization_name
varchar role_code
varchar security_level
varchar status
boolean is_deleted
datetime created_at
datetime updated_at
datetime deleted_at
}
DOC_CATEGORY {
bigint id PK
bigint parent_id
varchar category_code
varchar category_name
varchar category_type
varchar ancestor_path
varchar full_path_name
int document_count
boolean is_deleted
datetime created_at
datetime updated_at
datetime deleted_at
}
DOC_DOCUMENT {
bigint id PK
varchar document_no
varchar document_name
varchar document_type
bigint parent_document_id
bigint root_document_id
bigint category_id FK
varchar category_name
varchar category_path
text summary
varchar security_level
varchar visibility_type
varchar visibility_text
json tags
varchar document_status
varchar file_relative_path
varchar file_hash
varchar version_no
boolean is_deleted
datetime created_at
datetime updated_at
datetime deleted_at
}
DOC_PERMISSION {
bigint id PK
bigint document_id FK
varchar subject_type
bigint subject_id
varchar subject_name
boolean can_view
boolean can_download
boolean can_edit
boolean can_manage_permission
boolean can_delete
boolean is_deleted
datetime created_at
datetime updated_at
datetime deleted_at
}
DOC_ATTACHMENT_BINDING {
bigint id PK
bigint main_document_id FK
bigint attachment_document_id FK
int sort_no
boolean is_deleted
datetime created_at
datetime updated_at
datetime deleted_at
}
SYS_AUDIT_LOG {
bigint id PK
bigint user_id
varchar username
bigint organization_id
varchar organization_name
varchar action_type
varchar target_type
bigint target_id
varchar target_name
varchar operation_result
varchar client_ip
varchar request_id
json operation_detail
datetime created_at
}
SYS_ORGANIZATION ||--o{ SYS_ORGANIZATION : "包含下级组织"
SYS_ORGANIZATION ||--o{ SYS_USER : "拥有用户"
DOC_CATEGORY ||--o{ DOC_CATEGORY : "包含子分类"
DOC_CATEGORY ||--o{ DOC_DOCUMENT : "归类文档"
DOC_DOCUMENT ||--o{ DOC_DOCUMENT : "包含子方案"
DOC_DOCUMENT ||--o{ DOC_ATTACHMENT_BINDING : "主案挂载"
DOC_DOCUMENT ||--o{ DOC_ATTACHMENT_BINDING : "附件被挂载"
DOC_DOCUMENT ||--o{ DOC_PERMISSION : "配置权限"
SYS_USER ||--o{ SYS_AUDIT_LOG : "产生操作日志"
DOC_DOCUMENT ||--o{ SYS_AUDIT_LOG : "成为操作对象"
除审计日志外,核心业务表统一使用:
created_by BIGINT NULL,
updated_by BIGINT NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
ON UPDATE CURRENT_TIMESTAMP(3),
deleted_at DATETIME(3) NULL,
is_deleted TINYINT(1) NOT NULL DEFAULT 0,
row_version INT NOT NULL DEFAULT 0
更新业务数据时,使用类似条件:
UPDATE doc_document
SET document_name = ?, row_version = row_version + 1
WHERE id = ? AND is_deleted = 0 AND row_version = ?;
影响行数为 0 时,后端返回并发冲突,不得静默覆盖。
第一阶段不建立字典表,使用后端枚举校验。
用户角色 role_code:
USER, ADMIN
用户状态 status:
ENABLED, LOCKED, DISABLED
分类类型 category_type:
SCENE, STYLE, SITUATION, VERSION, OTHER
文档类型 document_type:
MAIN, SUB_PLAN, ATTACHMENT
文档状态 document_status:
DRAFT, PUBLISHED, ARCHIVED
权限主体 subject_type:
ORG, USER
权限来源 permission_source:
DIRECT, INHERITED
日志结果 operation_result:
SUCCESS, FAIL, DENIED
sys_organization必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
parent_id BIGINT NULL
org_code VARCHAR(64) NOT NULL
org_name VARCHAR(128) NOT NULL
ancestor_path VARCHAR(1000) NOT NULL DEFAULT '/'
full_path_name VARCHAR(1000) NOT NULL
tree_level INT NOT NULL DEFAULT 1
sort_no INT NOT NULL DEFAULT 0
status VARCHAR(20) NOT NULL DEFAULT 'ENABLED'
created_by BIGINT NULL
updated_by BIGINT NULL
created_at DATETIME(3)
updated_at DATETIME(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
row_version INT NOT NULL DEFAULT 0
索引:
UNIQUE(org_code) 或采用有效记录唯一策略
INDEX(parent_id, is_deleted, sort_no)
INDEX(status, is_deleted)
删除有下级组织或有效用户的组织时,默认拒绝,不级联删除。
sys_user必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
username VARCHAR(64) NOT NULL
password_hash VARCHAR(255) NOT NULL
real_name VARCHAR(64) NOT NULL
organization_id BIGINT NULL
organization_name VARCHAR(128) NULL
role_code VARCHAR(32) NOT NULL DEFAULT 'USER'
security_level VARCHAR(32) NULL
status VARCHAR(20) NOT NULL DEFAULT 'ENABLED'
last_login_at DATETIME(3) NULL
last_login_ip VARCHAR(64) NULL
created_by BIGINT NULL
updated_by BIGINT NULL
created_at DATETIME(3)
updated_at DATETIME(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
row_version INT NOT NULL DEFAULT 0
要求:
doc_category必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
parent_id BIGINT NULL
category_code VARCHAR(64) NOT NULL
category_name VARCHAR(128) NOT NULL
category_type VARCHAR(32) NOT NULL DEFAULT 'OTHER'
ancestor_path VARCHAR(1000) NOT NULL DEFAULT '/'
full_path_name VARCHAR(1000) NOT NULL
tree_level INT NOT NULL DEFAULT 1
document_count INT NOT NULL DEFAULT 0
sort_no INT NOT NULL DEFAULT 0
status VARCHAR(20) NOT NULL DEFAULT 'ENABLED'
created_by BIGINT NULL
updated_by BIGINT NULL
created_at DATETIME(3)
updated_at DATETIME(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
row_version INT NOT NULL DEFAULT 0
要求:
ancestor_path 和 full_path_name。category_name 和 category_path。doc_document必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
document_no VARCHAR(64) NULL
document_name VARCHAR(255) NOT NULL
document_type VARCHAR(32) NOT NULL
parent_document_id BIGINT NULL
root_document_id BIGINT NULL
category_id BIGINT NULL
category_name VARCHAR(128) NULL
category_path VARCHAR(1000) NULL
summary TEXT NULL
security_level VARCHAR(32) NOT NULL DEFAULT 'INTERNAL'
visibility_type VARCHAR(32) NOT NULL DEFAULT 'CUSTOM'
visibility_text VARCHAR(500) NULL
tags JSON NULL
search_text TEXT NULL
document_status VARCHAR(32) NOT NULL DEFAULT 'PUBLISHED'
version_no VARCHAR(32) NOT NULL DEFAULT 'V1'
sort_no INT NOT NULL DEFAULT 0
file_original_name VARCHAR(255) NOT NULL
file_storage_name VARCHAR(255) NOT NULL
file_relative_path VARCHAR(1000) NOT NULL
file_extension VARCHAR(20) NOT NULL
file_mime_type VARCHAR(128) NULL
file_size BIGINT NOT NULL DEFAULT 0
file_hash CHAR(64) NOT NULL
preview_relative_path VARCHAR(1000) NULL
extracted_text_path VARCHAR(1000) NULL
child_count INT NOT NULL DEFAULT 0
attachment_count INT NOT NULL DEFAULT 0
view_count BIGINT NOT NULL DEFAULT 0
download_count BIGINT NOT NULL DEFAULT 0
last_viewed_at DATETIME(3) NULL
created_by BIGINT NULL
created_by_name VARCHAR(64) NULL
updated_by BIGINT NULL
updated_by_name VARCHAR(64) NULL
created_at DATETIME(3)
updated_at DATETIME(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
row_version INT NOT NULL DEFAULT 0
关系规则:
MAIN:
parent_document_id = NULL
root_document_id = 自身ID
SUB_PLAN:
parent_document_id = 所属主案ID
root_document_id = 所属主案ID
ATTACHMENT:
parent_document_id = NULL
root_document_id = NULL
通过 doc_attachment_binding 挂载到一个或多个主案
第一阶段约束:
search_text 是有意冗余字段,由后端拼接文档名称、概述、标签等内容,第一阶段用于普通数据库检索;不得在本阶段接入向量逻辑。
建议索引:
INDEX(document_type, is_deleted, updated_at)
INDEX(parent_document_id, document_type, is_deleted)
INDEX(root_document_id, is_deleted)
INDEX(category_id, is_deleted)
INDEX(document_status, is_deleted)
INDEX(security_level, is_deleted)
INDEX(file_hash)
INDEX(created_by, is_deleted)
INDEX(is_deleted, deleted_at, id) # B8由0002迁移增加
doc_permission必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
document_id BIGINT NOT NULL
subject_type VARCHAR(20) NOT NULL
subject_id BIGINT NOT NULL
subject_name VARCHAR(255) NOT NULL
can_view TINYINT(1) NOT NULL DEFAULT 1
can_download TINYINT(1) NOT NULL DEFAULT 0
can_edit TINYINT(1) NOT NULL DEFAULT 0
can_manage_permission TINYINT(1) NOT NULL DEFAULT 0
can_delete TINYINT(1) NOT NULL DEFAULT 0
permission_source VARCHAR(20) NOT NULL DEFAULT 'DIRECT'
created_by BIGINT NULL
updated_by BIGINT NULL
created_at DATETIME(3)
updated_at DATETIME(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
row_version INT NOT NULL DEFAULT 0
要求:
subject_type = ORG 时,subject_id 表示组织ID。subject_type = USER 时,subject_id 表示用户ID。INHERITED,以换取简单查询。建议索引:
INDEX(document_id, is_deleted)
INDEX(subject_type, subject_id, is_deleted)
INDEX(document_id, subject_type, subject_id, is_deleted)
doc_attachment_binding必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
main_document_id BIGINT NOT NULL
attachment_document_id BIGINT NOT NULL
sort_no INT NOT NULL DEFAULT 0
created_by BIGINT NULL
updated_by BIGINT NULL
created_at DATETIME(3)
updated_at DATETIME(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
row_version INT NOT NULL DEFAULT 0
要求:
main_document_id必须指向有效的MAIN文档。attachment_document_id必须指向有效的ATTACHMENT文档。attachment_count更新必须在一个事务中完成。建议索引:
INDEX(main_document_id, is_deleted, sort_no)
INDEX(attachment_document_id, is_deleted)
INDEX(main_document_id, attachment_document_id, is_deleted)
sys_audit_log必需字段:
id BIGINT AUTO_INCREMENT PRIMARY KEY
user_id BIGINT NULL
username VARCHAR(64) NULL
real_name VARCHAR(64) NULL
organization_id BIGINT NULL
organization_name VARCHAR(128) NULL
action_type VARCHAR(32) NOT NULL
target_type VARCHAR(32) NULL
target_id BIGINT NULL
target_name VARCHAR(255) NULL
operation_result VARCHAR(20) NOT NULL
failure_reason VARCHAR(1000) NULL
client_ip VARCHAR(64) NULL
user_agent VARCHAR(500) NULL
request_id VARCHAR(64) NULL
operation_detail JSON NULL
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
deleted_at DATETIME(3) NULL
is_deleted TINYINT(1) NOT NULL DEFAULT 0
审计日志保存操作发生时的名称快照,不依赖用户、组织或文档当前名称。
需要记录的操作至少包括:
LOGIN
LOGOUT
VIEW_DOCUMENT
DOWNLOAD_DOCUMENT
UPLOAD_DOCUMENT
BATCH_IMPORT
EDIT_DOCUMENT
DELETE_DOCUMENT
RESTORE_DOCUMENT
CHANGE_PERMISSION
CREATE_CATEGORY
EDIT_CATEGORY
DELETE_CATEGORY
建议索引:
INDEX(created_at)
INDEX(user_id, created_at)
INDEX(action_type, created_at)
INDEX(target_type, target_id, created_at)
INDEX(operation_result, created_at)
INDEX(request_id)
普通业务代码不得更新或删除审计日志。
所有正常查询默认包含:
WHERE is_deleted = 0
删除文档时必须:
is_deleted = 1 和 deleted_at。child_count;解除附件挂载时更新attachment_count。删除主案时,如果存在有效子方案,第一阶段默认拒绝;主案的附件挂载关系可以随主案逻辑删除,但共享附件本身必须保留。
正式接口只允许:
GET /api/v1/recycle-bin/documents
POST /api/v1/recycle-bin/documents/{id}/restore
旧 /api/v1/documents/{id}/restore 永久废止,不得实现重定向、别名或兼容调用。
仅ADMIN可以查询回收站和单条恢复MAIN、SUB_PLAN或ATTACHMENT。不恢复分类、用户或组织,不支持批量恢复、物理删除、自动清理、独立恢复ACL或挂载关系,也不移动文件到 recycle/。
回收站固定查询 is_deleted=1 AND deleted_at IS NOT NULL。支持keyword、documentType、categoryId、deletedFrom、deletedTo、分页和受限排序;默认 deleted_at DESC, id DESC。删除人使用最近一次匹配的成功 DELETE_DOCUMENT审计窗口查询获取,无可靠审计时返回null,不得用 updated_by冒充。
通用恢复必须验证:
文件检查使用两阶段方案:事务前完成哈希和格式校验,保持文件句柄并记录文件状态;事务内锁定记录后、提交前复核状态。变化时返回 RESTORE_FILE_CHANGED。数据库事务无法锁定磁盘文件,当前以应用独占管理UUID文件为前提。恢复不移动、复制或删除文件。
MAIN采用关系恢复方案B:通过相同documentId、deletedAt和updatedBy识别本次删除批次,只恢复其中仍有效且不冲突的ACL和挂载关系。无效或禁用主体、已删除或不存在附件跳过并计数;有效关系冲突整体回滚。
SUB_PLAN不恢复独立ACL,恢复后继承主案当前最新权限并重算父主案childCount。ATTACHMENT继续固定PUBLIC和ALL_AUTHENTICATED,不恢复ACL或历史挂载;异常存在有效挂载时拒绝恢复。
文档名称、原文件名、分类下名称、同一主案下子方案名称和文件哈希允许重复。不同文档可以使用相同哈希,但继续使用各自独立文件路径。
恢复文档、恢复关系、重算计数和成功 RESTORE_DOCUMENT审计必须原子提交。恢复响应必须纯序列化,不增加viewCount或产生 VIEW_DOCUMENT审计。最小范围内恢复失败不写业务审计。
第一阶段建议明确允许:
.doc
.docx
.pdf
.xls
.xlsx
不能只检查扩展名,还要检查文件头或 MIME 类型。无法确认格式的文件放入 quarantine/,不得进入正式目录。
flowchart TD
A[接收上传] --> B[写入 temporary]
B --> C[校验文件类型与大小]
C --> D[计算 SHA-256]
D --> E[创建文档数据库记录]
E --> F[创建正式目录]
F --> G[原子移动到 original]
G --> H[更新相对路径]
H --> I[提交数据库事务]
I --> J[记录审计日志]
失败补偿:
文件不能通过 Flask 静态目录直接暴露。必须经过后端接口:
file_hash。新增业务接口使用 /api/v1。接口响应必须采用统一结构,并区分业务错误、权限错误和系统错误。
POST /api/v1/auth/login
POST /api/v1/auth/logout
GET /api/v1/users/me
GET /api/v1/organizations/tree
GET /api/v1/users?organizationId=&keyword=
GET /api/v1/categories/tree
POST /api/v1/categories
PUT /api/v1/categories/{id}
DELETE /api/v1/categories/{id}
GET /api/v1/documents
GET /api/v1/documents/{id}
GET /api/v1/documents/{id}/children
GET /api/v1/documents/{id}/materials
GET /api/v1/documents/recent
GET /api/v1/documents/search?keyword=
列表接口至少支持:
page
pageSize
documentType
categoryId
keyword
securityLevel
status
sortBy
sortDirection
POST /api/v1/documents
PUT /api/v1/documents/{id}
DELETE /api/v1/documents/{id}
GET /api/v1/documents/{id}/preview
GET /api/v1/documents/{id}/download
POST /api/v1/documents/batch-import
POST /documents 使用 multipart/form-data,同时提交文件和文档元数据。批量导入第一阶段可以同步返回逐文件结果,但应限制文件数量和请求总大小。
文档恢复使用独立回收站资源:
GET /api/v1/recycle-bin/documents
POST /api/v1/recycle-bin/documents/{id}/restore
旧 /api/v1/documents/{id}/restore 永久废止。
GET /api/v1/documents/{id}/permissions
PUT /api/v1/documents/{id}/permissions
PUT 应接收完整权限集合,在一个事务内完成新增、更新和逻辑删除。
GET /api/v1/audit/logs
GET /api/v1/audit/statistics/trend
GET /api/v1/audit/statistics/actions
GET /api/v1/audit/statistics/users
GET /api/v1/statistics/documents
统计数据从 doc_document 和 sys_audit_log 查询,不在第一阶段额外建立统计表。
第一阶段采用固定角色加文档 ACL:
ADMIN 可以进入后台管理,但文档下载等敏感操作仍应记录审计。ADMIN 可以查看审计日志并具有 AUDIT_LOG 模块;USER不能访问审计接口。USER 只能访问拥有查看权限的文档。权限查询可以使用:
subject_type = USER 的记录;subject_type = ORG 的记录;后续编码前应先确定“直接拒绝是否覆盖组织允许”。第一阶段若不实现显式拒绝,则权限表只表达允许,查询逻辑更简单。
以下字段不得由前端自由指定:
organization_namecategory_namecategory_pathcreated_by_nameupdated_by_namesubject_namechild_countattachment_countview_countdownload_countsearch_text后端维护规则:
organization_name;历史日志不更新。child_count。attachment_count,不得复制或删除共享附件文件。search_text。subject_name;历史日志不更新。不要在代码中写死密码和环境相关配置。建议使用环境变量:
DMS_DB_HOST=127.0.0.1
DMS_DB_PORT=3306
DMS_DB_NAME=dms
DMS_DB_USER=dms_app
DMS_DB_PASSWORD=change-me
DMS_STORAGE_ROOT=<project-root>/backend/dms-storage
DMS_MAX_FILE_SIZE_MB=100
DMS_BATCH_MAX_FILES=50
本地开发可以提供不包含真实密码的 .env.example。真实 .env 必须被 Git 忽略。
数据库要求:
MySQL 8.0+
字符集 utf8mb4
排序规则优先 utf8mb4_0900_ai_ci,若需要严格区分则在实现时确认
存储引擎 InnoDB
事务隔离级别默认 READ COMMITTED 或 MySQL 默认级别,实施时统一选择并记录
Codex 后续编码时按以下顺序进行,每一步完成后先验证,再继续下一步。
backend/dms-storage/ 目录结构并配置 Git 忽略。row_version 冲突。../ 等方式访问存储根目录外文件。本阶段只有同时满足以下条件才算完成:
backend/dms-storage/ 按约定保存真实文件。以下内容不在当前任务中,但未来可以在不破坏现有模型的情况下增加:
doc_file_version:文档历史版本。doc_relation:一个资料关联多个主案或通用关系。doc_tag、doc_document_tag:标签管理和统计。sys_role、sys_permission、sys_user_role:动态 RBAC。doc_import_job、doc_import_item:持久化批量任务。doc_vector_index:未来记录 Milvus 索引状态。未经用户明确确认,Codex 不应在当前阶段提前实现这些扩展。
B8实现必须创建 0002_add_restore_audit_action,不得修改 0001_initial_schema。迁移要求:
sys_audit_log.action_type CHECK,加入 RESTORE_DOCUMENT;doc_document增加 (is_deleted, deleted_at, id)索引;固定锁顺序:
rowVersion规则:
新增错误码:
DOCUMENT_NOT_DELETED 409
FILE_INTEGRITY_MISMATCH 409
FILE_PATH_INVALID 500
RESTORE_FILE_CHANGED 409
RESTORE_CATEGORY_INVALID 409
RESTORE_PARENT_INVALID 409
RESTORE_PERMISSION_INVALID 409
RESTORE_RELATION_CONFLICT 409
错误响应不得包含绝对路径、哈希、SQL、数据库连接信息或内部异常堆栈。
backend/dms/resources/ui-dictionaries.zh-CN.json,部署覆盖变量为 DMS_UI_DICTIONARY_CONFIG_PATH。backend/dms/common/enums.py 的对应枚举完全一致,配置只能调整中文标签和排序号,不能增加或修改英文代码。GET /api/v1/config/ui-dictionaries仅使用已加载内存对象。除现有认证校验外,不得查询业务数据库,不得写审计日志,不得读取磁盘。sortNo、code排序,遵循统一响应、requestId和 /api/v1 CORS规则,不返回外部配置绝对路径、加载时间、原始文件内容或内部错误。1.2.0,只增加字典查询路径及对应DTO、401和500响应。updatedFrom、updatedTo,要求ISO 8601且包含明确时区,统一转换为UTC无时区值后与MySQL UTC DATETIME比较。updatedFrom采用 >=,updatedTo采用 <=;同时存在时先验证开始时间不晚于结束时间。doc_document.updated_at;已挂载附件仍过滤附件对应的 doc_document.updated_at,禁止过滤 doc_attachment_binding时间或排序号。where条件必须在查询执行和分页前形成,不得在Python中进行时间过滤。1.3.0。0003_q3_business_alignment_and_content_search:doc_document.search_text升级为LONGTEXT,新增content_text LONGTEXT NULL、content_extract_status VARCHAR(32)、content_extracted_at DATETIME(3) NULL,并将用户角色CHECK收敛为USER、ADMIN。python -m dms.backfill_document_content要求显式数据库URL并校验SELECT DATABASE()严格等于dms_test,不得自动运行或连接dms主库。0002_add_restore_audit_action与0003_q3_business_alignment_and_content_search。若正文已写入或LONGTEXT内容无法安全降为TEXT,0003 downgrade应明确阻止而非静默丢失。LIKE满足现阶段数据规模;随着文档数量和正文体积增长,会出现大文本扫描性能风险。引入MySQL FULLTEXT或独立搜索服务前必须完成中文分词、相关性、权限过滤和迁移方案评审,不得在本阶段自行扩展。