feat(提交): 采集编辑过程信号,落进 submission_trace
Deploy / deploy (push) Has been cancelled

AI 时代 OJ 设计的第 1 步:给「可信 AC」和学情分析攒数据,本身不判任何事。
- 契约:提交请求加可选的 trace(活跃时长、键入/粘贴/删除字符数、切后台次数等,
  只有计数、不含按键内容);写成 .optional().catch(undefined),坏了就当没带,
  不让附带数据把提交挡成 400
- 迁移 0016 建 submission_trace,与 submission 一对一、CASCADE;since_prev_ms
  由服务端在同一条 INSERT 里算(排掉自身),bigint —— 实测已有 44 天的间隔,int4 装不下
- 后端写 trace 失败只记日志,不影响提交
- 前端 oj/problem/utils/editTrace.ts 是模块单例(扩展对象不能过 Pinia 的响应式代理),
  只数带 userEvent 的事务:格式化回写 / 载入草稿 / 协作对方的改动天然排除;
  closeBrackets 越过右括号时是原样替换,按 no-op 跳过。比赛编辑器同样挂上
- 实跑:后端四种请求、前端浏览器里键入/粘贴/删除/setCode 回写/切后台/提交后清零,
  计数与预期逐项一致

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5 committed 2026-09-19 05:46:55 -06:00
1 parent 20a6ddc79c
commit a0ef204bd2
12 files changed
+4152

No files matched your search

@@ -4,6 +4,7 @@ import { python } from "@codemirror/lang-python"
import { sql, SQLite } from "@codemirror/lang-sql"
import { bracketMatching } from "@codemirror/language"
import { Codemirror } from "vue-codemirror"
import type { Extension } from "@codemirror/state"
import {
autocompletion,
closeBrackets,
@@ -21,6 +22,8 @@ interface Props {
height?: string
readonly?: boolean
placeholder?: string
/** 追加的 CodeMirror 扩展。传一个稳定的数组实例,每次渲染新建会让编辑器反复重配 */
extraExtensions?: Extension[]
}
const {
@@ -29,6 +32,7 @@ const {
height = "100%",
readonly = false,
placeholder = "",
extraExtensions = [],
} = defineProps<Props>()
const code = defineModel<string>("value")
@@ -49,6 +53,7 @@ const extensions = computed(() => [
override: [enhanceCompletion(language), completeAnyWord],
}),
isDark.value ? oneDark : smoothy,
...extraExtensions,
])
</script>