Architecture
# Architecture
## Core Modules
- Web app: 页面渲染、API、认证、文件浏览、评论
- Worker: 处理队列、驱动容器、执行 Codex、产出扫描
- Database: 保存用户、项目、文件、会话、任务、评论
- Storage: 宿主机项目工作区目录
- Docker runtime: project 级执行隔离
## Data Flow
1. 用户注册或登录后进入项目列表
2. 创建项目时,系统复制 `templates/project-template` 到项目工作区
3. 用户上传文件,文件写入 `user/inputs`,并创建 `ProjectFile`
4. 发起运行后,API 创建 `PromptRun` 并推入 BullMQ
5. Worker 确保对应 project 容器可用,调用 Codex headless
6. Worker 扫描 `user/outputs`,写回数据库,并为 Markdown 生成 PDF
## Visibility Rules
对用户展示:
- `user/inputs/**`
- `user/outputs/**`
不对用户展示:
- `AGENTS.md`
- `skills/**`
- `system/**`
## Unified Conversation Workspace
项目工作台已经从原有三栏式页面收敛为统一对话工作区:
- 用户请求、执行过程、最终回复和产物入口按时间顺序位于同一会话列;
- run 进行中继续复用现有约五秒页面轮询,不新增 SSE / WebSocket 基础设施;
- 模型进度摘要、计划变化和工具操作由前端投影为可读的执行过程,过滤原始 stdout/stderr、usage、插件噪声和隐藏推理;
- run 完成后执行过程默认折叠为 `已处理`,用户展开时再通过项目鉴权的 run-events API 懒加载历史日志;
- 历史执行过程仍以 `system/runs/<runId>.log` 为事实来源,因此 run 日志保留策略会直接影响完成后能否展开历史过程;
- 前端只展示长任务最近的有限数量过程项,完整排障仍应查看受控的 run 日志。
本次改版没有新增数据库表或迁移;它复用现有 `PromptRun`、工作区日志、轮询和项目权限模型。
## Container Lifecycle
- 创建 run 时,worker 先查找 project 容器
- 若不存在则按模板创建并挂载 project workspace
- 容器复用以减少冷启动
- 容器必须使用非 root 用户
- 容器必须启用 CPU/内存限制
- 容器需附带健康检查,并验证 `codex` 与 workspace 可用
- 任务超时或健康检查失败后,worker 需要强制回收异常容器并标记 run 失败
## P0 Runtime Hardening
- PDF 渲染优先使用 Chromium headless,无法使用浏览器时退回 simple renderer
- `web` 暴露 `/api/health`
- `worker` 提供脚本化健康检查
- Compose 层为 `postgres`、`redis`、`web`、`worker` 配置健康检查
- 提供 runner image 构建和 project container 清理脚本
## iMUSE 临床数据库接入
当前内部小范围试用阶段采用直接只读连接:
```text
医生请求 → Codex → imuse-database-analysis Skill
→ 固定只读 Python Wrapper
→ iMUSE MySQL RDS
```
- RDS 连接参数通过 Worker 环境变量传入 project runner,不写入项目工作区或 Skill。
- Codex 必须使用 `skills/imuse-database-analysis/scripts/imuse_database.py`,不得改用 MySQL CLI、SQLAlchemy、临时 PyMySQL 脚本或通用数据库连接器。
- Wrapper 强制只读事务、单条 `SELECT/WITH`、120 秒语句上限、最多 100,000 返回行,并屏蔽已知直接身份字段、备份/复制/OCR/文件表和通配符查询。
- 当前控制模型面向可信内部用户,依赖只读 RDS 账号、固定 Wrapper、Skill 指令和维护中的敏感字段规则,不等同于多租户安全边界。
### 遗留 TODO:查询网关
在以下任一条件出现前,将 `imuse-database` 查询网关提上日程:外部医院接入、非受信用户开放、多租户项目隔离、研究中心级授权、敏感字段策略频繁变化或需要集中审计/限流。
网关实施时应:
- 将 RDS 凭证移出 project runner,只向容器签发项目范围 API Token;
- 使用 MySQL AST 与字段血缘解析,在所有 SQL 子句中执行默认拒绝策略;
- 服务端绑定用户、项目、研究、中心和字段权限;
- 统一执行超时、成本、并发、返回行/单元格/字节限制与审计;
- 保持现有 Skill 命令和输出接口稳定,只替换 Wrapper 后端。
详细的未来接口契约保留在 `templates/project-template/skills/imuse-database-analysis/references/gateway-contract.md`。