 xuyueandClaude Opus 5.5
|
6216e1cf22
|
chore(依赖): 删掉三个没用到的 vue-flow 插件,代码高亮全站只注册一份
- @vue-flow/minimap、node-resizer、node-toolbar 一处引用都没有
- App.vue 给 n-code 另建了一份 highlight.js,还注册着判题机早就不认的 Java、
JavaScript、Go;改成空闲时加载 shared/highlight.ts 那份。62 条这三种语言的
历史提交改为不上色显示
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
2026-10-12 20:22:32 +08:00 |
|
 xuyueandClaude Opus 5.5
|
e6c02dce33
|
chore(依赖): 前后端依赖升到最新,补上机房 Chrome 105 缺的两个 polyfill
几处随升级改的:
- VueUse 15 的 useNow 不再收 interval,不传 scheduler 默认逐帧刷新。比赛列表(1 秒)
和后台建比赛(15 秒)改成用 useIntervalFn 当调度器,频率不变。
- 重新探测 modernPolyfills:mermaid 12 用了 Object.groupBy(Chrome 117),core-js 新数据
把 URL.parse(Chrome 126)也算进来了,不补的话机房老机器上静默报 TypeError。清单 52 项。
- vue-router 5.4 弃用了导航守卫里的 next(),全局守卫改成返回值。
- web-tree-sitter 0.27:AST 规则在 dev 和编译后的二进制里各跑过一遍,判过、判不过都对;
jieba 2.0.4 原生模块在仓库外起二进制能正常分词。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
2026-10-12 14:03:34 +08:00 |
|
 xuyueandClaude Opus 5.5
|
6f47ad8358
|
perf(Markdown): 题面、教程、AI 提示每次打开都去 unpkg.com 拉四个库,机房网络下又慢又不稳
md-editor-v3 的 MdPreview 不管正文里有没有代码、公式,都会从 unpkg.com 加载
highlight.js、katex、mermaid、echarts(mermaid 还是另一份 11.x)。而我们只用到最基础的
Markdown:题面 95% 是富文本存的 HTML,教程是标题、表格、图片,AI 输出是标题、列表、
表格、少量代码块,库里一处公式、mermaid 都没有。
- 显示:新组件 shared/components/Markdown.vue,直接用 markdown-it,代码高亮走本地的
highlight.js(和练一练共用 shared/highlight.ts,补了 C++ / SQL)。9 处 MdPreview 全换掉。
正文默认 16px,教程也统一成 16px。
- 编辑:后台教程编辑器换成项目已有的 CodeMirror,加一排格式按钮;图片可以按按钮选、
粘贴、拖进来,都是先上传再插入。md-editor-v3 从依赖里删掉。
- AI 生成的内容(AI 提示、AI 分析、班级报告)不再放行原生 HTML:学生能在代码里诱导
AI 吐出 <img onerror>,老师在后台一打开就执行。库里 1196 条 AI 输出没有一个 HTML
标签,关掉不影响显示。题面、教程照旧放行。
- 长英文改成在单词之间折行,原来 break-all 会把 "I live" 断成 "I l / ive"。
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
2026-10-12 14:02:54 +08:00 |
|
 xuyueandClaude Opus 5.5
|
2a4405d2ea
|
feat(题目): Python 语法错误改成中文说明,在编辑器里标出位置,中文标点可以一键换成英文
Deploy / deploy (push) Canceled after 0s
中职学生看不懂英文报错。原来提交前用浏览器里的 Skulpt 拦语法错误,只弹一句
「第 N 行存在语法错误」——Skulpt 九成报的是 bad input / bad token,没有列号。
- 提交前的语法检查挪到服务端:/code/format 先用 CPython 编译一遍(只编译不执行),
api 镜像加 python3-minimal(3.13,与判题机同版本,+17MB),前端删掉 Skulpt
- 报错按规则表翻成中文(pythonError.ts),生产库 2695 条 Python 编译错误覆盖 99.7%;
提交前拦下的和判题回来的编译错误共用同一张卡片
- 编辑器里标红出错行和 ^ 指的位置
- 中文标点(历史编译错误的 22%)一键换成英文,跳过字符串和注释、处理 f 字符串花括号;
594 条里修好 593 条,经 tokenize 核对没有改到字符串内容;走编辑器事务,可 Ctrl+Z
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
2026-09-27 21:47:01 +08:00 |
|
 xuyueandClaude Opus 5
|
ed56a209ea
|
chore(格式): Prettier 统一到全仓,后端和契约一次性格式化
Deploy / deploy (push) Has been cancelled
原来只有 `apps/web` 在 Prettier 下(配置在 `apps/web/.prettierrc.toml`、脚本在
web 的 package.json),后端和契约从来没格式化过 —— 手写在 100 列上下,`db/schema.ts`
还是 drizzle-kit pull 留下的 tab 缩进。两套口径分叉久了,跨端改一处就得记着「这边
什么风格」。
- 配置搬到根目录 `.prettierrc.toml`,内容不变(`semi=false`,其余全默认,
printWidth 80 —— 和前端已有的格式一致,不另立一套宽度);
- 脚本统一成根目录 `bun run fmt`,覆盖 `apps/*/src`、`apps/web/tests` 和两个构建
配置;web 自己那份 `fmt` 和重复的 prettier 依赖删掉;
- `.prettierignore` 挡掉两类不该碰的:drizzle-kit 生成的 `src/db/meta/` 结构快照
(它是 db:generate 的比对输入,只该由 drizzle-kit 写)、unplugin 每次 dev 都会
重写的 `auto-imports.d.ts` / `components.d.ts`;
- 全量跑了一遍。纯格式,无行为改动:api typecheck / check:routes / check:ast、
前端 type-check 全过,起 api 打了接口确认正常。前端这 39 个文件的小改动是
prettier 版本漂移(类型断言的换行口径变了),不是新配置带来的。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-16 08:27:34 -06:00 |
|
 xuyueandClaude Opus 5
|
3559ae4d6f
|
chore(前端): 浏览器基线从 Chrome < 94 提到 105,删掉 mermaid@9 那套 fallback
机房只有部分电脑还是 Chrome 105,其余更新,按最低那档定基线。
- legacy 插件留着:vite 8 的默认 build.target 是 chrome111,比机房高。
modernTargets 不写,用插件自带的 chrome>=105 基线,正好是这一档。
- polyfill 清单按 105 重新探测,63 → 50 项,仍然写死:自动探测要对每个产物
跑 Babel 扫描,构建 3s → 12s。写死后产出的 polyfills chunk 与自动探测同尺寸。
- 删 mermaid-legacy(mermaid@9)、useMermaid 里按 UA 分叉的 v9 回调式 render、
为它存在的 cytoscape UMD→ESM 别名 —— 105 直接用 mermaid 11。
- View Transitions 要 111,darkTransition 的降级分支保留,注释改成 105。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-16 07:43:21 -06:00 |
|
 xuyueandClaude Opus 5
|
4654615f89
|
feat(登录): 姓名支持拼音和拼音缩写搜索
Deploy / deploy (push) Has been cancelled
机房电脑打中文要切输入法,选姓名前先切一次法太别扭。现在 zhangsan、zs、
xiaoxian 都能搜到张三/曾小贤,中文照旧能打。
用 pinyin-pro 的 match 而不是自己拼一份拼音串比对:多音字它两个读音都认,
单田芳搜 stf 和 dtf 都出得来,曾小贤搜 zxx 和 cengxiaoxian 也都出得来 ——
自己拼只会留下默认读音那一个,姓氏恰恰是多音字重灾区。
词典有 85 KB(gzip),静态引入会压进首屏,所以改成打开登录框才 import。
已登录的人一次都不会下载(构建产物里它是独立 chunk,只被 default 布局
动态引用;实测页面加载 0 个请求,打开登录框才有 1 个)。拉不下来时退回
纯中文匹配,不至于让人登不上。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQCLjAmz6pPXMNGoZmvAmC
|
2026-09-01 07:25:21 -06:00 |
|
 xuyueandClaude Opus 5
|
ffabcd4a0d
|
fix(collab): 提示会丢、排队位置不刷新;显式声明 lib0
Deploy / deploy (push) Has been cancelled
- 一次性提示原来挂在题目页的 Form.vue 上消费:学生排着队切去看提交记录,
老师这时取消了他的求助,那条提示就永远没人消费。挪到顶栏统一弹,
教师端的 error 提示同理。另外加了序号——连着两次同样的文案在 Vue 眼里
=== 相等,watch(notice) 不会第二次触发。
- queueAhead 原来只在「建请求 / 重连 / 退回排队」推过,前面的人被接走或
被取消之后不重算,第五个学生会一直显示「前面还有 4 人」。跟着
broadcastRequests 一起推,两件事永远同时发生。
- collabDoc 动态 import 了 lib0/encoding 和 lib0/decoding,但 lib0 不在
package.json 里,靠 yjs 提升到根 node_modules 才能解析。上游依赖树一变
就断,而且断在运行时不在构建时。按现装的 0.2.117 钉住。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DHxhKNxXfG89JnVzHbvgj
|
2026-08-30 09:38:04 -06:00 |
|
 xuyueandClaude Opus 5
|
d1fc6349b7
|
refactor(web): 删掉 y-webrtc 协同编辑的旧实现
sync.ts / syncStatus.ts、y-webrtc 依赖、PUBLIC_SIGNALING_URL 全部移除,
外部信令服务器 signaling.xuyue.cc 不再被使用。
顺带修掉 CLAUDE.md 里「协作在流程图编辑器」这句一直是错的描述。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DHxhKNxXfG89JnVzHbvgj
|
2026-08-30 08:22:06 -06:00 |
|
 xuyueandClaude Opus 5
|
86857dedf0
|
feat(web): 协作编辑走 collab 通道
Yjs sync/awareness 协议直接跑在 /ws/collab 上,服务端哑转发。
内容源是学生:学生端先把编辑器内容写进 ytext 再挂 yCollab,
教师端 seedContent 恒为 null —— 这条根治了老实现里谁的代码活下来看运气的问题。
订正 brief 里的一处疏漏:SyncCodeEditor.vue 挂在每个用户的题目页上,教师也不例外
(ProblemEditor.vue 只按语言是不是 Flowchart 分支,不看角色)。教师接单同样会让
collabStore.room 非空,若不按角色收窄,教师自己停在某道题页面上接单时,这个组件
会把教师自己的编辑器内容当成种子插入文档,还会跟 CollabModal 抢
setBinaryHandler 这个单例槽位。改为 `room && !collabStore.isTeacher` 才起协作,
教师端的协作只归 CollabModal 管。
另外两处修正:
- editorView 用 shallowRef 而非 ref —— CodeMirror 的 EditorView 是带 getter 的类
实例,ref() 的深度 UnwrapRef 会把它拆成丢了原型方法的假类型,vue-tsc 报错。
- Header.vue 挂 CollabModal 放进根 n-flex 内部而不是同级 —— 组件一旦变成多根
fragment,default.vue 里 `<Header class="header" />` 的 class 就没有单一根节点
可以落地,header 行会丢掉居中样式(实测触发了 Vue 的
Extraneous non-props attributes 警告)。n-modal 默认 teleport 到 body,塞在
这里不影响其实际渲染位置。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K1d8B3f4SXJwDvUY625eQd
|
2026-08-28 07:43:08 -06:00 |
|
 xuyueandClaude Opus 5
|
6e905085a1
|
chore(依赖): 后端升到 TypeScript 7,前端被 vue-tsc 挡住留在 5.9
apps/api 单独嵌套 typescript ^7.0.2,`bun run --filter '@oj2/api' typecheck`
从此跑的是原生版;根和 apps/web 留在 5.9.3。api 在 TS 7 下 0 error,
另外塞了个故意写错的文件复检过,确认它真在报错、不是静默跳过。
前端升不了:vue-tsc 启动时要 require.resolve("typescript/lib/tsc"),
而 TS 7 的 exports 里已经没有这个子路径,直接
ERR_PACKAGE_PATH_NOT_EXPORTED。vue-tsc@latest 就是仓库里的 3.3.11,
还没有支持 TS 7 的版本 —— 它 peer 写的是 typescript >=5.0.0,范围太松,
装上去不报冲突、一跑就炸。读源码看到 resolveTscPath 里唯一的适配分支是认
@typescript/typescript6,可见 Vue 侧目前给的路只到 6。硬上的代价是丢掉
刚清零的前端类型门禁,不值得。
顺带清掉一处假配置:apps/web 原本声明着 "typescript": "^7.0.2",是
ae1fb32 从 ojnext 原样搬过来的,**从来没生效过** —— vue-tsc 被 hoist 在根
node_modules/,解析 typescript 时看的是根上那份 5.9.3,压根看不见
apps/web 里嵌套的 7.0.2。留着它有两个坏处:白拉 20 个
@typescript/typescript-* 平台包;哪天 bun 换个 hoist 策略把它提到根上,
vue-tsc 就会以那个看不懂的 ERR_PACKAGE_PATH_NOT_EXPORTED 挂掉。改成显式
跟随根版本。
所以现在的分工是:**vue-tsc 把根上的 typescript 钉死在 5.x**,谁要升根
版本谁先解决 vue-tsc。等 vue-tsc 支持 TS 7,把 apps/api 那行删掉、
根上升到 7 即可。
验证(删空 node_modules 重装后):apps/api tsc 7.0.2 下 0 error、
check:routes 167 条无遮蔽、apps/web vue-tsc 0 error、vite build 通过、
drizzle-kit v0.31.10 正常。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-25 17:39:50 -06:00 |
|
 xuyueandClaude Opus 5
|
0e1e024fa4
|
chore(依赖): 升一批 patch/minor,锁死 mermaid-legacy 和 TypeScript 大版本
后端:@node-rs/jieba 2.0.1→2.0.2(含精确 pin 的 -linux-x64-gnu)、
bullmq 6.0.9→6.2.2、postgres→3.4.9、sql.js→1.14.2、web-tree-sitter→0.26.13;
hono ^4.0.0→^4.13.4 与 zod ^4.0.0→^4.4.3 只是把范围收紧到实装版本。
前端:@codemirror/view→6.43.9、highlight.js→11.12.0、mermaid→11.17.2、
naive-ui→2.45.2、pinia→4.0.3、y-codemirror.next→0.3.6、vite→8.2.2、
@types/node→26.3.0。
刻意没动两个:
- mermaid-legacy(npm:mermaid@^9.4.3)保持 9.4.3,vite 的 build target
也没碰 —— 机房 Chrome < 94 的兜底,legacy polyfill 产物照常生成。
- typescript 停在 5.9.3(只把根上的范围从 ^5.7.0 收到 ^5.9.3)。
7.0.2 是 Go 原生重写版,另开一个 commit 处理。
踩到的坑记一笔:`bun install` 不清理旧的嵌套副本。升完 @codemirror/view 后
md-editor-v3/node_modules/ 下留着一份 6.43.8,vue-tsc 立刻报
dispatchTransactions 私有属性冲突 —— 看起来像版本不兼容,其实
md-editor-v3 要的是 ^6.38.2,6.43.9 完全满足。当时全仓有十几处这种残留。
**升完依赖必须 rm -rf node_modules && bun install 再验类型**,否则会
对着一堆假的类型冲突查半天。
验证(删空 node_modules 重装后):apps/api tsc 0 error、check:routes 167 条
无遮蔽、apps/web vue-tsc 0 error、vite build 通过、单二进制在仓库外起得来
并打库返回真数据、jieba 原生模块 dev 与编译两种形态都验过、BullMQ 两个
worker 正常 ready。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-25 17:39:06 -06:00 |
|
 xuyueandClaude Opus 5
|
ae71055818
|
chore(前端): 接上 vue-tsc,模板里的字段名从此有类型检查
vite 不做类型检查,改错一个字段名只会在运行时变成静默 undefined ——
tsconfig.app.json 本来就 include 了 .vue,只是没人跑。装上 vue-tsc,
加 `bun run type-check`。
实测确认它能查到模板里的属性访问(往模板塞一个不存在的字段,如实报错)。
注意:它查不出模板编译错误(比如 v-model 绑了非 lvalue 的表达式),
所以 build 还是要跑,两者不能互相替代。
当前有 143 条既有错误,都是历史遗留,本次不清理。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-25 13:43:37 -06:00 |
|
 xuyueandClaude Opus 5
|
ea521e7b0a
|
feat(阶段5): 镜像、三套 compose,前端切回 /api 与 /ws
## 镜像
一个 Dockerfile 两个 target:api(单二进制)和 web(Caddy + 前端产物)。
旧后端是一个容器里用 supervisord 跑 caddy+gunicorn+dramatiq,这里拆成
oj-web / oj-api / oj-worker 三个容器 —— Docker 本身就是进程管理器,
拆开之后 worker 挂了能单独重启、日志也分得开,少一层 supervisord 要维护。
同一个镜像换个子命令就是 worker,镜像里只有一份运行时。
新增 healthcheck 子命令:运行镜像是 debian-slim,没有 curl/wget,
让二进制自己打 /health(只打 /health 不碰库 —— 库挂了该由库的 healthcheck 报,
不该让 api 跟着被判不健康然后被重启)。
**数据目录照抄旧后端**(test_case、public/upload、public/avatar)。
不是审美问题:切换那天不用搬动任何文件,回滚时旧后端立刻能找到自己的数据。
少一次几十 GB 的 mv,就少一个在停机窗口里出错的机会。
构建路上踩到三个坑,都是「本地能过、容器里过不了」那一类:
- 构建上下文吸进了 data/,judge_server/run 是判题沙箱用别的 uid 建的,
docker 连 stat 都做不了,构建直接失败 → 补 .dockerignore
- mermaid@9.4.3(机房老 Chrome 的 legacy 依赖,不能砍)从容器里连
registry.npmjs.com 稳定失败,主机上没问题 → 换 npmmirror,并重试两次
- 容器里 bun 用 isolated 布局,本地是扁平的。靠「提升」才能解析到的包
在容器里一律解析不到:@node-rs/jieba-linux-x64-gnu(编译要 import 它的 .node)、
以及前端的 @codemirror/{language,state,view} 和 @lezer/highlight。
这些本来就是代码直接 import 的,补成直接依赖。顺手写了个脚本扫全仓,
确认只有这 4 个。
## 前端切回 /api、/ws
迁移期用 /api2、/ws2 指新后端,/api、/ws 还指着 Django。端点已全部搬完,
临时前缀去掉。改动只有三处(api2.ts 的 baseURL、websocket.ts 的两个 URL),
`api2` 那些 import 是模块名不是路径,不动。vite 代理同步收敛成三条。
## compose
- debian:全套(含 postgres,对外开 5445 给机房连)
- school:**没有 postgres**,连服务器的库;本地 Redis + 本地判题沙箱
- 两边共用一个库但各有各的队列和 WS 推送,和旧后端的 Dramatiq/Channels 拓扑一致
密钥一律走 env 且带 `:?`,没设置就直接报错退出,不静默用弱默认值。
COOKIE_SECURE 在机房必须是 false(http 直连 IP,带 Secure 的 Cookie 发不回来,
表现是「登录成功但立刻又变未登录」)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 23:41:20 -06:00 |
|
xuyue
|
ae1fb329b5
|
feat(阶段1): 搬入 ojnext 为 apps/web,未改业务代码
|
2026-08-06 21:18:16 -06:00 |
|