|
|
cbff292551
|
feat(切换): compose 支持「只换前后端」,接着用旧栈的 postgres/redis
演练把一件事盖住了:当时是把生产 dump 恢复进 `OJ2/data/postgres` 的,
所以没人发现新 compose 在 `OJ2/docker/` 下,`../data` 解析出来是 `OJ2/data`,
而旧栈用的是 `<部署目录>/data`(服务器上是 `/root/OJDeploy/data`)。
照原手册切过去,postgres 会在一个空目录上初始化一个全新的空库 —— 站点起得来,
但没有用户没有题、判题全挂、题面图片 404。旧数据完好,回滚正常,但当天会白吓一场。
## 改法
三组 env 旋钮,默认值保持原样,不影响本机和演练那条路:
DATA_DIR 所有数据卷的根,默认 ../data
DB_HOST/PORT 默认 oj-postgres:5432
REDIS_HOST/PORT 默认 oj-redis:6379
postgres 和 redis 挪进 `profiles: ["local-data"]`,默认不起 —— 否则会跟旧栈
那两个抢 5445 / 5446。配套给 depends_on 加 `required: false`:实测严格的
depends_on 碰上未启用的 profile 会让整个 project 直接 invalid,不是可选项。
代价写进注释了:自带数据形态下 postgres 起不来时 compose 只警告不中止。
给 api / worker 加 host-gateway 映射,DB_HOST 填 host.docker.internal 就行,
不用去猜 docker0 的网段。数据库流量不出本机。
school 那套的 7 个挂载点同样换成 DATA_DIR —— 机房那台也有自己的旧数据目录,
测试点和题面图片都在里面,同一个坑。
## 验证
用 docs/specs/schema.sql 起了个发布在宿主机 5445 的 postgres 冒充旧栈:
正好 4 个容器(没有 postgres/redis)、oj-api healthy、首页与 /api/site
/api/problems 200、未登录进后台 401。读写两个方向都验了 —— 那个库的
pg_stat_activity 里有来自 172.17.0.1 的 postgres.js 连接,judge_server 表里
也出现了新判题机写进去的心跳行。
四份 compose 的 `config -q` 全通过。
手册第三、四、六节按这个形态重写:停旧栈改成只 stop oj-backend / oj-judge
(旧判题机会争 data/judge_server/run,旧 backend 占着 8080),回滚变成把这两个
再 start 起来,数据库进程全程不停。
**DATA_DIR 漏填不会报错**(它有默认值),是切换当天唯一会静默走歪的地方,
手册里给了 `config | grep source:` 的自查和两种症状的区分。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-16 08:57:25 -06:00 |
|
|
|
967e9ef7f7
|
feat: 路由遮蔽检查脚本;切换前把前后端接口逐条对了一遍
## 切换前核对:前端调的接口后端有没有漏
写脚本把前端 224 个调用点和后端注册的路由逐条比对。**零缺口** —— 唯一报出来的
一条是我的正则被嵌套括号截断了(`users/${encodeURIComponent(...)}/badges`),
后端那条路由是有的。「后端有、前端没调」那 25 条也逐个看过,全是脚本的假阳性
(把 `.get("user")` 这类非路由调用当成了路由)和假阴性(前端用三元表达式拼路径,
正则看不见,比如 `GET /me` 其实在 shared/api.ts 里被调)。
结论是没发现缺口,但这个脚本不够可靠、不足以证明"一定没有",所以没留进仓库。
## 路由遮蔽检查(留成常驻脚本)
比"有没有漏"更值得防的是遮蔽:**Hono 按注册顺序匹配,不是静态优先**。
`/problems/:id` 注册在 `/problems/random` 前面的话,后者永远进不去 ——
不报错、不警告,只是静默走进前一条的 handler。阶段 4 真实发生过一次,
两个教师用的分析端点被吃掉,一直到评审才发现。
全仓 167 条路由按真实注册顺序扫:**零遮蔽**。
这个结论敢下,是因为检测器本身也验了:
- 自检用例里放了阶段 4 那个历史真实案例,能抓到;边界(两边都是参数、
段数不同、不同前缀)不误报
- 核对了 24 个 router 全在扫描范围内,没有漏扫
- 反向验证:往 problem.ts 末尾加一条注册在 `:displayId` 之后的字面量路由,
脚本立刻报出来并 exit 1
未经验证的检测器报"没问题"是没有意义的 —— 这个教训今天已经吃过两次
(tree-sitter 那次、SQL 内存那次)。
脚本落在 apps/api/src/scripts/check-route-shadowing.ts,
`bun run --filter '@oj2/api' check:routes`,加完路由跑一下。
CLAUDE.md 里也写了。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-08 03:42:37 -06:00 |
|
|
|
f6bc42f534
|
docs: 给 OJ2 补一份自己的 CLAUDE.md;Dockerfile 拷上 bunfig.toml
## bunfig.toml 没拷进容器,才是那批「本地能过、容器过不了」的根因
bunfig.toml 里设了 `linker = "hoisted"`,但 Dockerfile 只拷了 package.json 和
bun.lock,于是容器里用的是默认的 isolated 布局(包都在 node_modules/.bun/ 下),
本地靠"提升"才解析得到的包在容器里一律 Could not resolve —— 而本地构建始终是好的,
只有镜像构建才炸。之前是一个一个补直接依赖补过去的(那是对的、该保留),
这里让两边布局一致,是第二道保险。
带上之后装 622 个包(isolated 是 1238),镜像重建通过,二进制在容器里
serve + healthcheck 正常。
顺手补了 main.ts 帮助文本里漏掉的 healthcheck 子命令(compose 里把 command
写错时,看到的就是这行)。
## OJ2/CLAUDE.md
OJ2 是独立仓库,之前没有自己的项目指引。写了一份,重点是几条「不知道就会踩」的:
- **本机 Docker 可用**,整套依赖和上线演练都能在本机跑 —— 别沿用上一代
"本机跑不起来后端"的旧假设
- 单二进制不能依赖 node_modules,`.node` 资源导入 dev 和编译两种形态行为不同,
**改完两种形态都要跑**
- SQL 判题 spawn 的是二进制自己,入口必须有 argv 分发,那道递归闸不能删
- 判题状态码三处同步、raw_password 要保留、比赛只有 ACM、前端要兼容老 Chrome
- 不写迁移:新旧后端跑同一套表结构,这是回滚能成立的前提
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-08 03:37:45 -06:00 |
|