Commit Graph

213 Commits

Author SHA1 Message Date
901906328d chore: 本机开发依赖 compose(postgres 16 + redis)
PostgreSQL 固定 16-alpine 与生产 16.10 对齐,首次启动自动灌入
docs/specs/schema.sql(仅结构)。端口错开为 5433 / 6380。

实测:34 张表与 schema.sql 逐一对应,差集 0,两个服务健康。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:32:48 -06:00
63faf5c6c0 docs: 更正本机开发环境约束 —— Docker 可用
根 CLAUDE.md 长期写着本机跑不了 Docker/PostgreSQL/Redis/判题沙箱,实测不成立:
docker 29.7.2 与 docker-compose 5.4.0 早已安装,只是服务未启用、用户不在 docker 组。
另确认判题沙箱不需要特权模式(read_only + cap_drop,只减能力不加)。

影响:阶段 2 判题竖线可在本机完整验证并反复试错,不必每次推服务器。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:30:17 -06:00
9f5dd95289 docs: raw_password 保留决策及其对 7.1 结论的影响
user.raw_password 明文列是有意的运维需求(教师查学生密码),决定保留。
据此如实收窄 7.1 的结论:argon2id 升级不防"数据库泄露",只解决 pbkdf2
的 CPU 开销和脱离 Django 哈希格式,不得描述为"提升密码安全性"。
附一条未采纳的备选(应用层可逆加密)供日后备查。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:24:01 -06:00
1251b4e27d docs(阶段0): 端点清单人工裁决完成
6 条 REVIEW 全判 KEEP:5 条是提取盲点造成的假阴性(原生 fetch 4 条、
动态变量路径 1 条),judge_server_heartbeat 是判题机注册心跳、不经前端,
新架构沙箱镜像原样复用故必须保留。

最终:新后端需实现 110 个端点,砍掉 17 个(13%)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:22:34 -06:00
f68b04baf0 chore(阶段0): 取回生产库 schema,解阻塞阶段 1
34 张表(27 业务 + 7 Django 框架),schema-only,无 COPY/INSERT、
无密码哈希、无邮箱。阶段 1 的 drizzle-kit pull 据此离线生成 TS schema。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:20:54 -06:00
e3fe9e1ab9 docs(阶段0): 更正存量盘点数字,ground truth 改为可独立核验
设计文档 §4 原写「端点 122、DEPRECATED 16、前端调用 78、疑似无人调用约
35%」四项全错:前三项来自漏抓 5 个端点的提取器和只数字面量的前端统计,
35% 是从 (122−78)/122 推的。改为实测值 127 / 17 / 148 条 method+path
(104 条不同路径)/ 23 个无调用 = 18%。减法空间是 18% 不是三分之一,
后续阶段按此排期。

实施计划里的 ground truth 原本就是那个有 bug 的脚本自己产出的,自检退化成
「脚本必须复现自己的 bug」。改为 127 / 17 / 104 并写明独立核验方式。

另:§7 引导语两处改三处;7.3 把「启动时一次性 loadDict」提成衍生约束小节,
附实测数据(200 词逐条 39.4ms vs 一次性 0.98ms,且 loadDict 语义确认为累加)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:08:53 -06:00
9069b1cdb7 chore(阶段0): 补齐 spike 依赖清单与 lockfile
.gitignore 的 docs/spikes/*.json 把 package.json 一起忽略了,bun.lock 也
单独忽略了;package.json 里又缺三个 tree-sitter 依赖(7.2 的 spike 当初在
临时目录跑的),结果 ast-spike.ts 在仓库里直接报 Cannot find package
'web-tree-sitter'。

排除规则改窄为 endpoints-*.json,补上 web-tree-sitter / tree-sitter-c /
tree-sitter-python 并提交 bun.lock。现在 bun install 后三个 spike 都能跑。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:08:53 -06:00
ae5eea7250 fix(阶段0): 端点提取器漏抓 5 个端点,补反向对账
提取器按文件名白名单扫 <app>/urls/{oj,admin}.py,漏掉两类真实挂载:
tutorial/urls/tutorial.py(文件名不在白名单)和 utils/urls.py(没有
urls/ 目录,被 statSync 的 catch 吞掉),共 5 个端点,其中 4 个前端在用。

改为以 OnlineJudge/oj/urls.py 为唯一入口解析 26 条 include,side 与路径
前缀直接取挂载前缀,app 取 Python 模块名首段。127(oj 77 / admin 50),
DEPRECATED 17,与 cat */urls/*.py utils/urls.py | grep -c "path(" 一致。

reconcile.ts 补上反向对账:前端调用了但后端查无此端点的路径会告警并写进
产出的 markdown,让同类系统性盲区不再依赖人眼评审。修完后 orphan 为 0。

另:生成日期改用本地时区(toISOString 是 UTC,本地 UTC+8 晚间会写成前一天);
补记盲点 3(src/utils/download.ts 的独立 axios 实例,提取器抓不到)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:08:53 -06:00
ec563ef64b chore(阶段0): 验证 jieba 替代方案
@node-rs/jieba@2.0.1 在 Bun 1.3.11 下通过验证:NAPI 绑定正常加载,
cut 结果符合预期,1000 次切词 2ms。API 与预期有出入——没有
insertWord/addWord,改用 loadDict 加载自定义词典缓冲区达到同等效果。
结论写入设计文档 7.3 节。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 19:48:27 -06:00
b4cbfd85b0 chore(阶段0): 端点对账脚本与机器初判清单
KEEP 100 / CUT 16 / REVIEW 6,合计 122。

修复 brief key() 里的归一化 bug:/^\/?api\/(admin\/)?/ 会把后端
admin 端点的 admin/ 前缀也剥掉,但前端 http 客户端共用一个 axios
实例(baseURL: /api),admin 接口路径是前端代码里手写的字面
admin/xxx,不该被剥。未修复时 REVIEW 卡在 40(几乎全是被误判的
admin 端点),修复后降到 6。

REVIEW 里 5 条经核实是提取脚本的已知/新发现盲点(动态变量传路径、
原生 fetch() 调用)导致的假阴性,已在生成的 markdown 里写明提示;
唯一真正需要人工裁决的是 judge_server_heartbeat(判题机而非前端
调用的接口)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 19:40:25 -06:00
6b24012dc8 chore(阶段0): 前端 API 调用提取器 2026-08-06 19:29:57 -06:00
3da7482741 docs: 阶段 0 实施计划 + 端点提取器
计划覆盖端点盘点、人工裁决、jieba 验证、取回生产库 schema 四件事。
相对设计文档有两处偏离,已在计划内说明:阶段 0 不删旧代码只产出清单
(与"旧仓库全程冻结"一致);不写测试(遵循项目既定策略)。

盘点中发现两处事实,已修正设计文档:
- /api/sessions 前端从不调用,User.session_keys 只写不读,选 opaque
  token 而非 JWT 的原始理由不成立,理由已换成账号封禁需即时生效
- SessionRecordMiddleware 每个已登录请求都写库,新后端不要复刻

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 19:24:41 -06:00
ec4f649a2e docs: OJ2 后端重写设计文档
将 Django 后端重写为 Bun + TypeScript 的设计方案,含前后端 monorepo
结构、技术选型与分阶段路线。

两处高风险技术假设已实测验证,spike 代码见 docs/spikes/:
- Django pbkdf2 密码哈希可在 Bun 侧验证,存量密码无需重置
- tree-sitter 可用 WASM 在服务端运行,且比现状更易部署

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 19:16:57 -06:00