|
|
b4b61af6b0
|
fix(阶段3): 匿名不可读用户档案,真名改为默认不下发
F1:GET /profiles/:username 只挂了 optionalAuth、handler 内无登录判断,
匿名可读 email、adminType、className、lastLogin。用户名又能经 /rankings/users
公开枚举,等于可以无 cookie 批量收集全校学生的邮箱与最后登录时间。
handler 开头补上未登录即返回空,对齐旧后端 account/views/oj.py 的
UserProfileAPI.get 首行 `if not user.is_authenticated: return self.success()`。
F2:旧后端把「是否下发真名」做成 UsernameSerializer(need_real_name=False)
的默认关闭开关,全仓 11 处调用只有比赛榜单一处显式打开;新后端没搬这一层,
真名随用户对象无条件下发,13 个下发点里 8 个匿名可达。
这里补回同一层:helpers.ts 新增 sampleUser(),realName 默认不下发,
需要的地方显式传 { includeRealName: true }。12 个下发点改为走这个函数,
只有比赛榜单一处打开(对齐 contest/serializers.py:84 的 is_contest_admin)。
没有逐处删字段 —— 那样下次新增端点还会重犯。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 01:59:05 -06:00 |
|
|
|
9c04b00e3f
|
docs(阶段3): 权限与泄露双评审报告 + 合并修复清单
两份评审独立进行、互不知情,各自命中同两条问题(匿名可读用户档案、
realName 无条件下发),独立复现提高可信度。严重度取更严一方 ——
使用者是中职学生,姓名邮箱班级属个人信息。
3 Critical / 3 Important,F1-F3 已由控制方独立实跑复现。
无敏感字段泄露、无泄题,比赛权限重建得最好。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 01:43:55 -06:00 |
|
|
|
0f999aa5b1
|
docs: 阶段 0/1/2 出口标准核验 + 阶段 3 覆盖率对账
核验为逐条实跑,不采信文档声称。阶段 0/1/2 出口标准全部通过,
其中阶段 2 判题链路端到端实测(注册→登录→提交→JudgeServer→WS 推送)。
覆盖率对账:oj 侧 65 条已全部实现,admin 侧 45 条一条未做。
新旧路径不同名(API 已重新设计),对照关系为人工按语义逐条比对。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 01:25:36 -06:00 |
|
|
|
8c00cdc947
|
feat(阶段3): oj 侧端点铺开(基线提交,未经评审)
由外部 agent (Codex) 在本会话额度中断期间完成。原样提交作为基线,
后续修复单独成 commit,便于区分与回退。
覆盖 oj 侧 65 个端点,新增 9 组路由(account/achievement/ai/classroom/
content/contest/flowchart/problemset/site)与对应 Zod 契约。
已核验:tsc --noEmit 退出码 0;API 可启动;/api/problems 返回真实数据;
judge 与 flowchart worker 均 ready。
未核验:权限边界与数据泄露,评审进行中。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 01:25:36 -06:00 |
|
|
|
ec274419c3
|
Build Phase 2 judge vertical slice
|
2026-08-06 22:42:39 -06:00 |
|
|
|
e6329ecabb
|
feat(阶段1): 端到端串通,前端显示本地库真实题目
|
2026-08-06 21:19:52 -06:00 |
|
|
|
ae1fb329b5
|
feat(阶段1): 搬入 ojnext 为 apps/web,未改业务代码
|
2026-08-06 21:18:16 -06:00 |
|
|
|
3c975e85ee
|
feat(阶段1): Hono 应用与题目列表接口,读通本地真实数据
|
2026-08-06 21:14:58 -06:00 |
|
|
|
0a8fcef3f2
|
chore(阶段1): 题目样本导入脚本(不含用户数据)
|
2026-08-06 21:14:23 -06:00 |
|
|
|
0f0a5cb65a
|
fix(阶段1): 修正 problem 主键与展示编号映射
|
2026-08-06 21:11:44 -06:00 |
|
|
|
f635737453
|
feat(阶段1): drizzle schema 从本地库生成并剪掉 Django 框架表
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-06 20:45:51 -06:00 |
|
|
|
9bfe629cd7
|
feat(阶段1): monorepo 骨架与 @oj2/contract 契约包
|
2026-08-06 20:39:39 -06:00 |
|
|
|
39ad431e31
|
docs: 阶段 1 骨架实施计划
6 个任务:monorepo 骨架与契约包、drizzle schema 生成剪枝、题目样本导入、
Hono 题目接口、搬入 ojnext、端到端串通。
相对设计文档两处偏离已说明:出口标准改为本地 PG + 生产题目样本(比原设想强,
能在浏览器端到端验证);不写测试(遵循项目既定策略)。
额外补 Task 3 样本数据 —— 本地库只有结构无数据,否则无法验证出口标准。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-06 20:36:44 -06:00 |
|
|
|
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 |
|