2026-09-26 01:12:10 +08:00

TraceIQ 财务分析工作台

响应式 Web 前端 + Django API + PostgreSQL。基于分享会话、医院财务 Excel 原始附件及 AG Grid 开发计划实现,当前交付是可运行、经过本地回归的核心业务版本,不等于全部需求完成或已获生产上线认证。缺口与上线门禁见 验收状态。

已实现

  • XLSX / UTF-8 CSV 导入、双行表头、原始解释保留、字段语义确认、产品毛利率及自营产品范围配置。
  • 原始文件私有存储、组织内文件 SHA-256 去重、导入事务、持久队列、PostgreSQL worker 崩溃恢复。
  • 实际收入、成本、毛利、两种明确 ROI 公式、去重人数、客单价、毛利率、产品扣率、自营收入、升单率、原价客单价。
  • 同比、环比、自定义等长月份范围;缺基期禁止比较,缺成本显示不可用,缺月份趋势断开。
  • 总览、异常追踪、贡献分解、自定义下钻层级、面包屑、原始行证据分页、CSV / XLSX 证据导出。
  • 个人设置保存/取消/预览与乐观锁;调查备注与状态持久化;账号启停、角色及科室范围、操作审计。
  • 本地规则助手;可选 OpenAI Responses 结构化意图接口,用户同意后仅发送问题与维度/当前筛选,查询仍受后端权限约束。

当前原附件没有医生、成本和连续月度数据,不会生成虚构的医生排名、ROI 或环比结论。毛利是根据产品分类毛利率计算的贡献值,不等同于已审计净利润。

技术结构

目录 职责
frontend/src React 19 / TypeScript、AG Grid、ECharts、响应式 UI
finance/importing.py 解析、映射、Decimal 校验、批量导入
finance/analysis.py 权限内聚合、比较、异常与贡献
finance/views.py 身份认证、受控 API、导出、设置、账号、审计
finance/assistant.py 规则助手及外部模型意图校验
server Django 配置、路由、WSGI
tests PostgreSQL 集成测试、Playwright 浏览器回归
scripts 本地账号初始化、原始附件独立对账

后端金额使用 NUMERIC(44,24),Python Decimal 精度 60;JSON 金额为字符串。浏览器 Number 仅用于绘图与显示,不作为账务计算或持久化来源。Excel 精确金额以文本单元格导出,避免 Excel 的 15 位有效数字上限。客户端不会一次加载 33 万条明细,只加载聚合结果,证据查询每页最多 200 行。

本地运行

需要 Node.js 22、uv、Python 3.12、PostgreSQL 17。所有示例从仓库根目录执行。

uv sync --frozen --python 3.12
npm ci --registry=https://registry.npmjs.org
export DATABASE_URL='postgresql://USER:PASSWORD@127.0.0.1:5432/traceiq'
uv run python manage.py migrate
PYTHONPATH=. uv run python scripts/init_local.py
npm run build
uv run python manage.py collectstatic --noinput
uv run python manage.py runserver 127.0.0.1:8000 --noreload

另一个终端启动导入 worker:

export DATABASE_URL='postgresql://USER:PASSWORD@127.0.0.1:5432/traceiq'
uv run python manage.py import_worker

访问 http://127.0.0.1:8000,本地随机账号保存在 var/local-access.txt,文件权限 0600。该脚本拒绝生产模式。开发热更新可在第三个终端运行 npm run dev,Vite 将 /api 代理到 8000。

本次本机验证使用专属集群 var/postgres、端口 55432、库 traceiq:

/opt/homebrew/opt/postgresql@17/bin/pg_ctl -D var/postgres -l var/postgres.log -o '-h 127.0.0.1 -p 55432' start
export DATABASE_URL='postgresql://jianwel@127.0.0.1:55432/traceiq'

该集群只监听本机,使用开发认证策略,不可公开端口或复制到生产。没有设置开机自启。SQLite 仅作轻量开发后备,不保证高精度金额聚合,禁止财务验收和生产使用。

生产部署

  1. 在独立服务器配置域名 DNS、防火墙及 TLS,创建 .env,参考 .env.example。生成至少 50 字符随机 SECRET_KEY、数据库强密码,两处数据库密码需一致;密码有特殊字符时 DATABASE_URL 中必须 URL 编码。
  2. 设置准确的 DOMAIN、ALLOWED_HOSTS、CSRF_TRUSTED_ORIGINS。仅开放 Caddy 80/443;数据库与 Gunicorn 不发布主机端口。
  3. 执行 docker compose --env-file .env config --quiet,再执行 docker compose up --build -d。migrate 服务成功后才启动 web/worker,Caddy 自动申请 HTTPS 证书。
  4. 执行 docker compose exec web python manage.py bootstrap --username admin --organization '医院财务中心',交互输入管理员密码,无默认生产密码。
  5. 执行 docker compose exec web python manage.py check --deploy,在隔离预生产环境运行验收,完成下面运维门禁再上线。

默认单个导入 worker 用 PostgreSQL advisory lock 防止重复处理;其他 worker 获取不到锁会退出。worker 异常退出,数据库回滚未完成的 Fact 事务并释放锁,下次启动会重新处理 processing。需要受控停机时先等任务 ready 再停,强制停止会导致整个文件重新导入。通过 import_file PATH --username admin --confirm-mapping 的 CLI 导入也入队,不绕过 worker。

TRUST_PROXY=1 仅用于 web 无公网直连、反向代理覆盖 X-Forwarded-Proto 和 X-Real-IP 的部署。登录 IP 限流在此模式使用经过校验的 X-Real-IP,未启用时忽略该头。.env.example 的 DB_SSLMODE=disable 仅适用同宿主私有容器网络;跨主机数据库用 verify-full 与受信证书。代理上传上限 66 MB、应用文件上限 64 MiB。生产使用环境变量/密钥服务注入密码,不提交 .env。

备份与运维

  • 同时备份 PostgreSQL 与 uploads 卷,不能只备份其中一个。uploads 包含原始财务/客户标识,需加密磁盘、受控访问及留存期限。
  • 低频窗口暂停新上传,等待当前导入完成并停止 worker;用 pg_dump -Fc 创建数据库备份,再快照 uploads,记录同一备份批次。将备份放在加密、异地主机或受控对象存储。
  • 恢复到隔离新库和新卷,使用 pg_restore --exit-on-error 后检查迁移、账号范围、导入状态,执行金额/人数对账,抽查原始行与导出,再切换流量。未完成恢复演练不能上线。
  • 定时执行 python manage.py clearsessions;监控 /api/health、HTTP 5xx、查询 P95、导入队列等待时间、processing 持续时间、磁盘/数据库容量、失败审计与备份新鲜度。当前未配置外部告警渠道。
  • 管理员忘记密码由运维执行 python manage.py changepassword USERNAME,现阶段没有邮件找回、自助密码修改、SSO 或 MFA。
  • 审计记录对网页用户只读,但数据库管理员仍可修改;需要不可抵赖审计时,应外送到独立追加写日志平台。
  • 发布前备份并固定镜像 digest;失败时回滚应用镜像。涉及不可逆数据迁移不得直接反向迁移,按批准的数据库恢复方案操作。

测试

测试数据库需要 CREATE DATABASE 权限。测试账号和 fixture 均为虚构数据。

uv run ruff check server finance tests scripts
uv run ruff format --check server finance tests scripts
uv run python manage.py makemigrations --check --dry-run
uv run pytest --cov=finance --cov-report=term-missing --cov-fail-under=85
npm run build
npm run test:e2e
npm audit --omit=dev --registry=https://registry.npmjs.org
uv run pip-audit

Playwright 需要正在运行的本地 API 和 worker,可用 E2E_PASSWORD 指定测试 admin 密码,默认读取本地凭据文件。首次执行 npx playwright install chromium。浏览器 fixture 测试会新建 e2e-finance.csv 数据集,不可指向正式生产环境。.github/workflows/ci.yml 在独立 PostgreSQL 上执行同样流程,尚未推送到远端触发。

原附件只在本机使用,不在仓库中:

uv run python scripts/inspect_source.py '/Users/jianwel/Downloads/分析数据_原稿(1).xlsx'
PYTHONPATH=. uv run python scripts/reconcile_reference.py
REFERENCE_DATASET_NAME='分析数据_原稿(1).xlsx' npm run test:e2e

AI 与跨平台

默认 AI_ENABLED=0。启用外部模型需配置 AI_ENABLED=1、OPENAI_API_KEY、OPENAI_MODEL,并完成机构数据处理审批。密钥只在后端。用户自由输入的问题也可能含敏感信息,不能仅凭不发送原始行就认定无隐私风险。模型不能提交 SQL、修改金额或修改账号;输出只允许受控意图,异常/拒答关闭执行。

前端为标准 Web,API 无平台耦合,可由后续 PWA、Tauri 或 Capacitor 客户端复用。当前没有打包桌面/移动客户端,也不在浏览器离线缓存财务数据。

AG Grid Community 默认可运行;设置 VITE_AG_GRID_LICENSE_KEY 后注册 Enterprise 模块并启用已接入的侧栏/状态栏。必须自行取得合适的商用许可证。SSRM / Pivot / Master-Detail 尚未接入,不能因存在 Enterprise 依赖就声称已完成这些功能。

S
Description
No description provided
Readme
361 KiB
Languages
Python 61.4%
TypeScript 30%
CSS 7.2%
Shell 1%
Dockerfile 0.3%
Other 0.1%