数据模型与状态流转
本文整合旧的数据模型实现稿、状态流转草案、SQL 规划说明和相关 OpenSpec 约束。
核心表
P0/v1.4.1 基线使用 11 张核心表:
usersrolesuser_rolesinspection_taskssamplessample_resultsexceptionsanalysis_jobsaudit_eventsapi_tokensuser_preferences
数据关系
users ----< inspection_tasks ----< samples ----< sample_results
| | | \
| | | \-> exceptions
| | |
| | \-> analysis_jobs
|
\----< user_roles >---- roles
users ----< audit_events >---- auditable resources
users ----< api_tokens
users ---- user_preferences
exceptions 通过 resource_type + resource_id 关联任务、样本或结果记录。
audit_events 同样使用 resource_type + resource_id,从而在不把审计日志强耦合到单一业务表的情况下记录任务、样本、结果、异常和分析作业事件。
数据库实现基线
- 目标数据库:
MariaDB - 字符集:
utf8mb4 - 主键策略:
BIGINT UNSIGNED AUTO_INCREMENT - 时间字段:
DATETIME - 状态字段:
VARCHAR(20) - JSON 字段:用于结果内容和分析任务参数/摘要
治理基线
v1.4.0 在不改变 Laravel 长期业务所有权的前提下增加基础治理层:
X-Ocean-Actor-Id是内部身份注入桥接。- SPA 登录使用存储在
api_tokens中的数据库 bearer token。 users、roles、user_roles仍是基础身份 / RBAC 表。- v1.4.1 面向用户的工作区偏好持久化在
user_preferences中,并归属于单个users记录。 - baseline seed 角色包括
admin、inspector、analyst、worker。 - 旧 payload 身份字段只作为归因兼容路径继续保留。
audit_events.actor_source记录归因来自request_header还是旧payload。
user_preferences
user_preferences 将用户专属工作区设置与全局身份数据分离:
user_id唯一并引用users.idlanguage存储偏好的 UI 语言,例如zh-Hans或endisplay_density存储轻量显示偏好,目前为comfortable或compactdefault_workspace_tab存储 SPA 工作区默认进入的标签页settings_json预留给后续每用户偏好扩展,避免改变核心身份语义
识别人员身份的资料字段仍保存在 users(username、display_name、email、status)。角色分配仍保存在 user_roles。设置不是授权数据,不能用于 RBAC 决策。
状态机
inspection_tasks
状态集合:
assignedin_progresssubmittedcompletedcancelled
assigned -> in_progress -> submitted -> completed
\ \
\----------------------------> cancelled
当前显式 P0 动作:
start:assigned -> in_progresssubmit:in_progress -> submitted
samples
状态集合:
registeredreceivedtestingreviewedarchivedinvalid
registered -> received -> testing -> reviewed -> archived
\ \ \ \
\ \ \-----------> invalid
\------------\--------------------> invalid
说明:
POST /api/samples创建时默认registered- 当前 P0 的样本状态推进由后端服务层规则显式负责
- v1.0.0 P0 明确规则:创建 sample result 时,
registered或received推进到testing - v1.0.0 P0 明确规则:
invalid和archived状态的样本禁止接收新结果,并返回409 INVALID_STATE
sample_results
状态集合:
draftsubmittedapprovedrejected
draft -> submitted -> approved
\
\-> rejected
说明:
- 结果创建默认进入
draft - 当前主流程由
status驱动 review_status为后续扩展预留
exceptions
状态集合:
openresolveddismissed
open -> resolved
\
\-> dismissed
当前 P0 动作:
resolve:open -> resolved
analysis_jobs
状态集合:
queuedrunningsucceededfailedcancelled
queued -> running -> succeeded
| \
| \-> failed
\
\-> cancelled
关键重试规则:
- 重试失败任务不能复活原记录
- 原
failed记录必须保留在历史中 - 重试会创建新的
queued记录 - 每条新的
queued记录都会通过ANALYSIS_JOB_REDIS_QUEUE配置的 Redis 队列交给 analysis-worker - Redis 队列项只是交接信号,数据库记录仍是持久状态来源
初始化与迁移原则
- Laravel migration / seeder 是长期初始化主路径
- 原始 SQL 草案可以保留为参考资料,但不再是主生命周期入口
- 基础角色至少包括
inspector、analyst、admin和worker - baseline seeder 需要提供一条幂等的核心链路样例:
inspection_task + sample + sample_result + exception + analysis_job