2026-09-10 用户确认 F01–F12、原型通过,并要求按四阶段建议推进。原型验收:#1 评论 7498。阶段 3;覆盖 F07、F05 高亮、B02。
阅读者编辑词语释义、例句与学习状态,保存后当前和其他章节显示一致;另一用户不受影响。
前置:#6。状态:已完成(2026-09-11 用户验收通过,功能提交 8c0946a,PR #26 已合入 main,验收记录见最新评论)。前置尚未通过时不得标进行中;每单完成停在待验收,由用户验收后关闭。技术验证可与不依赖其结论的工作分工,但不提前冻结未验证契约。
参考 go-admin DTO 校验、事务与迁移;领域保存/高亮定制,不能仅套 CRUD。
沿用已验收词语面板,后端先记录词条唯一性和状态转换。
后端不为建表/API 单独画页面原型;先写数据、接口、状态、隔离与幂等契约。学习端采用 #1 已验收 v1,未做的 LinguaCafe 对照不标完成。
预计 4~6 人日(8 小时/人日),包含本单设计、前后端实现、相关测试、修正和文档;是规划估算,不是交付日期或 AI 运行时间。仅 F 范围,X 系列不纳入。数据变更先在隔离测试库验证迁移/回退,保留既有数据和原型。
实施时按影响更新 Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;需求变化更新 Product-Requirements-Overview,交付单补实际部署恢复文档。Wiki 先写再回读同步;结束评论记录测试、未验证内容、提交及 revision。工单正文保留基线,重要变化追加评论。
Gitea MCP 指向其他站点,沿用目标 git.ilapage.cn API 回退;凭据仅进入进程。
用户在当前会话确认并授权实施:身份口径「赞同」,其余三个决策点由 Agent 判断后定案。前置 #6 已由用户验收关闭,PR #25 已合入 main;本单分支 feat/7-personal-terms 从 main 33182e5 创建。本单实施期间工单状态进入「进行中」,完成测试后停在「待验收」。
feat/7-personal-terms
33182e5
(owner_id, language, normalizeWord(原词形))
Dog
dog
dogs
new
POST /terms
level
CREATE TABLE IF NOT EXISTS lexgo_terms ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, owner_id BIGINT NOT NULL, language VARCHAR(16) NOT NULL DEFAULT 'en', term VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, original_form VARCHAR(191) NOT NULL, definition TEXT NOT NULL, examples TEXT NOT NULL, status VARCHAR(16) NOT NULL, level TINYINT NOT NULL DEFAULT 0, created_at DATETIME(3) NOT NULL, updated_at DATETIME(3) NOT NULL, UNIQUE KEY uq_term_identity (owner_id, language, term), CHECK (status IN ('new','learning','known','ignored')), CHECK (level BETWEEN 0 AND 7), FOREIGN KEY (owner_id) REFERENCES sys_user(user_id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
term 使用 utf8mb4_bin:归一化由 Go 完成,避免 _ai_ci 把 resume/résumé 折成同一身份。v5 不修改任何既有表或既有数据。
term
utf8mb4_bin
_ai_ci
resume
résumé
learning
known
ignored
服务端强校验:非 learning 时 level 必须为 0;learning 且缺省时置 1。#7 不实现复习推进、到期时间与计数(归 #8/#13)。
#7
POST /api/v1/terms
{chapterId,start,end,definition,examples[],status,level?}
owner/language/term
GET /api/v1/terms/:id
GET /api/v1/chapters/:id/tokens
term:{id,status,level}
约束:definition ≤2000 字符可为空;examples ≤5 条、每条 ≤500 字符、不允许换行;start/end 必须是本人 ready 章节内的完整单词且 ≤128 码点;跨账号章节 404,非 ready 409,未知字段 400。
definition
examples
start/end
lexgo_spaces
terms
session.user
沿用已验收词语面板:释义与例句输入、四个状态选择、保存与关闭;成功后显示简短反馈并立即更新正文高亮,失败保留已输入内容与面板。沿用同一套 seq/generation 防竞态与 stale 响应。管理端无改动。
lexgo_test_issue7
v5 只新增表:停止 API → 恢复 .local/lexgo-pre-issue7.exe → 将 lexgo_schema 标记回 4 → 重启;保留 lexgo_terms 与全部既有学习数据,不删除数据、不重新 bootstrap。迁移先在 lexgo_test_issue7 验证。
.local/lexgo-pre-issue7.exe
lexgo_schema
lexgo_terms
实施后更新 Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;F07 需求文本未变,Product-Requirements-Overview 仅在需求实质变化时更新。Wiki 先改后回读,再同步镜像。
原型 v1 的「原文例句已关联到词条」需要句子切分规则,本单不实现,若用户需要则另立范围;等级编辑 UI 归 #8/#12;#7 不实现词汇库列表、短语、复习与进度。
回退说明:本会话 pi 无可用 Gitea MCP 工具,沿用本单既定回退,使用目标 git.ilapage.cn API;凭据仅从既有安全配置读入进程,不进入仓库、日志或工单正文。
git.ilapage.cn
用户确认的方案与决策见评论 7737。分支 feat/7-personal-terms 从 main 33182e5 创建,实现提交 8c0946af9f1b69cd14e474b3b0178adc92438cb6,已推送。PR #26 未合并,工单不关闭,停在待用户验收。
8c0946af9f1b69cd14e474b3b0178adc92438cb6
server/app/lexgo/database.go
(owner_id,language,term)
original_form
server/app/lexgo/terms.go
INSERT … ON DUPLICATE KEY UPDATE
{term,created}
lookup
wordAtRange
useReaderLookup.ts
LookupPanel.vue
ReaderTokens.vue
style.css
go vet ./...
LEXGO_TEST_DB_NAME=lexgo_test_issue7 python scripts/server.py test-integration
npx vitest --run
vue-tsc --build
pnpm run build
playwright test
pnpm test
pnpm lint
python -m unittest discover -s tests
harness.py check --strict
sync --check
覆盖:非法状态与等级边界、文本上限、大小写合并与词形不合并、完全相同的重复保存幂等、跨章节同形词状态一致、两账号互不影响、篡改 owner/language/term 与未知字段被拒、非本人章节 404、未登录 401、未就绪章节 409、冷启动读取。
本机开发库 lexgo_dev 已显式 v4→v5:升级前后 sys_user 6、lexgo_spaces 6、lexgo_sessions 8、lexgo_books 4、lexgo_chapters 9、lexgo_ingest_jobs 9、lexgo_dictionaries 1 全部不变,新增空的 lexgo_terms;旧二进制备份在忽略的 .local/lexgo-pre-issue7.exe,仅重启 lexgo-api,其余 11 个实例 PID 与状态未变化,8000 与两端入口均 200。
lexgo_dev
真实链路:真实 Go API+真实 MySQL 共 30 项检查通过,使用 #6 已建的虚构测试账号 issue5_a/issue5_b 与其虚构章节 1/2/8/9(凭据只从本机安全配置读入进程)。随后用临时 Playwright 用例在真实学习端+真实 API 上复核:保存释义/例句/状态 → 「已保存 · 学习中」与正文高亮 → 重新加载后高亮与预填一致 → 390×844 窄屏底部面板 → 退出并以另一账号登录,同文本章节显示该账号自己的状态、未保存的词无状态。临时用例运行后删除,截图作为附件上传。
Wiki 先写后回读,再同步镜像(镜像随本次提交):
cb6d420632527a436f8b9a7a6a18413a0773f93d
71389f97df86e17699f4af930022251fa354631b
919545b0d716180a49ac7dd2fe96bbeccdba0880
b5eaaf1d0664e1e3c564079c857ccb5042540022
6fd4c754e3bb6ab215edb6077974fbd401f24103
未提交凭据、账号密码、测试数据库数据或截图;.local/ 保持忽略。
.local/
停止 lexgo-api,恢复 .local/lexgo-pre-issue7.exe,把 lexgo_schema 标记改回 4 后启动;保留 lexgo_terms 与全部既有学习数据,不删除数据、不重新 bootstrap。
Gitea MCP 仍指向其他站点,沿用已记录的目标站点 API 回退;凭据仅从既有安全配置读入进程。推送使用同一 API 令牌经进程环境注入,未写入命令文本、.git/config 或日志。
.git/config
附件:issue7-reader-desktop.png、issue7-reader-mobile-390.png、issue7-account-b.png(本会话模型不能读取图片,截图未经 Agent 目视检查,功能断言来自程序化检查)。
补充提交 a5a8c3c(docs: 记录 #7 已确认的个人词条决策):按本项目既有惯例,把用户本轮确认的个人词条口径写入仓库根 AGENTS.md 的项目决策清单——身份为「学习者+语言+规范化词形」且不按 lemma 合并、首次保存默认新词、四状态与 1~7 级映射及原版 stage 对照、例句不自动关联原文句子。仅新增一行文档,未改动代码、数据或契约;前期提交 8c0946a 保持不变,分支 feat/7-personal-terms 已同步推送。
a5a8c3c
AGENTS.md
8c0946a
验收时间:2026-09-11 20:25 +0800(Asia/Shanghai,与 PR 合入时刻一致)。用户在当前会话明确确认「#7 通过验收」。结论:#7 验收通过,关闭工单;PR #26 已 fast-forward-only 合入 main。
合入方式为 fast-forward-only,main 直接前进到分支提交,功能提交仍为 8c0946af9f1b69cd14e474b3b0178adc92438cb6,与用户验收版本逐字节一致,没有产生合并提交、没有改写历史。分支 feat/7-personal-terms 保留;需要撤销时可在新工单中使用 revert。
验收状态文档提交 527d8af(Home、Project-Profile、Architecture-and-Code-Map、Product-Requirements-Overview)与决策记录提交 a5a8c3c(AGENTS.md)已推送。合并后复核:harness.py check --strict 通过、sync --verify 通过、治理测试 56 项通过,工作区干净,先前完整交付证据见评论 7744,不重复覆盖。
527d8af
sync --verify
长期文档 Wiki revisions:
91a2eb47ca73e41a329bccd6ceeb7498c691529c
02b7fc12b222c0050652443ca1368730f35f5652
c9dcc7a0e9739fe17c148751662acceaed41982f
d355012d0f773ab5becb8c966cecfac71e39fabe
未增加产品范围或数据库变更;schema 保持 v5,本机开发库已完成 v4→v5 迁移与 lexgo-api 重启。真机触屏详细证据与完整备份恢复演练缺口保留,后续由 #14/#15 承接;短语 #11、到期复习 #8、词汇库 #12、进度 #13、附件 #21 与列表优化 #24 仍待实施。
Gitea MCP 仍指向其他站点,沿用已记录的目标 git.ilapage.cn API 回退,凭据仅在进程环境中使用。
No dependencies set.
The note is not visible to the blocked user.
来源与目标
2026-09-10 用户确认 F01–F12、原型通过,并要求按四阶段建议推进。原型验收:#1 评论 7498。阶段 3;覆盖 F07、F05 高亮、B02。
阅读者编辑词语释义、例句与学习状态,保存后当前和其他章节显示一致;另一用户不受影响。
验收标准
依赖与执行
前置:#6。状态:已完成(2026-09-11 用户验收通过,功能提交 8c0946a,PR #26 已合入 main,验收记录见最新评论)。前置尚未通过时不得标进行中;每单完成停在待验收,由用户验收后关闭。技术验证可与不依赖其结论的工作分工,但不提前冻结未验证契约。
参考模块与设计证据
参考 go-admin DTO 校验、事务与迁移;领域保存/高亮定制,不能仅套 CRUD。
沿用已验收词语面板,后端先记录词条唯一性和状态转换。
后端不为建表/API 单独画页面原型;先写数据、接口、状态、隔离与幂等契约。学习端采用 #1 已验收 v1,未做的 LinguaCafe 对照不标完成。
工作量、范围与风险
预计 4~6 人日(8 小时/人日),包含本单设计、前后端实现、相关测试、修正和文档;是规划估算,不是交付日期或 AI 运行时间。仅 F 范围,X 系列不纳入。数据变更先在隔离测试库验证迁移/回退,保留既有数据和原型。
文档与证据
实施时按影响更新 Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;需求变化更新 Product-Requirements-Overview,交付单补实际部署恢复文档。Wiki 先写再回读同步;结束评论记录测试、未验证内容、提交及 revision。工单正文保留基线,重要变化追加评论。
Gitea MCP 指向其他站点,沿用目标 git.ilapage.cn API 回退;凭据仅进入进程。
#7 方案确认与实施启动(2026-09-11)
用户在当前会话确认并授权实施:身份口径「赞同」,其余三个决策点由 Agent 判断后定案。前置 #6 已由用户验收关闭,PR #25 已合入 main;本单分支
feat/7-personal-terms从 main33182e5创建。本单实施期间工单状态进入「进行中」,完成测试后停在「待验收」。已确认决策
(owner_id, language, normalizeWord(原词形));Dog/dog合并,dog/dogs不合并new(新词)POST /terms接受可选level并按状态校验数据结构(schema v5,纯新增表)
term使用utf8mb4_bin:归一化由 Go 完成,避免_ai_ci把resume/résumé折成同一身份。v5 不修改任何既有表或既有数据。状态与等级映射
new新词learning学习中known已知ignored忽略服务端强校验:非
learning时level必须为 0;learning且缺省时置 1。#7不实现复习推进、到期时间与计数(归 #8/#13)。接口契约
POST /api/v1/terms{chapterId,start,end,definition,examples[],status,level?};服务端按 #6 同一套 token 范围校验反推身份,owner/language/term一律不接受客户端输入;唯一键 upsert,重复保存只产生一条记录;首次 201、更新 200,返回完整 termGET /api/v1/terms/:idGET /api/v1/chapters/:id/tokensterm:{id,status,level};服务端按本章全部词形一次性查本人词条,其他章节保存的同形词同样命中(跨章节一致与 F05 高亮)约束:
definition≤2000 字符可为空;examples≤5 条、每条 ≤500 字符、不允许换行;start/end必须是本人 ready 章节内的完整单词且 ≤128 码点;跨账号章节 404,非 ready 409,未知字段 400。隔离与幂等
lexgo_spaces,term 只来自服务端分词结果:篡改 ID、用户、语言都不能越权读写,也不能伪造身份。terms状态跟随session.user变化重置,退出登录或切换账号后不保留任何前一账号的词条数据与高亮。前端
沿用已验收词语面板:释义与例句输入、四个状态选择、保存与关闭;成功后显示简短反馈并立即更新正文高亮,失败保留已输入内容与面板。沿用同一套 seq/generation 防竞态与 stale 响应。管理端无改动。
测试计划
lexgo_test_issue7,不借用其他库):v4→v5 迁移保留既有表计数;两账号互不影响;篡改 id/user/language 被拒绝;重复保存仅一条;跨章节同形词状态一致;非 ready 章节与非法范围拒绝。回退
v5 只新增表:停止 API → 恢复
.local/lexgo-pre-issue7.exe→ 将lexgo_schema标记回 4 → 重启;保留lexgo_terms与全部既有学习数据,不删除数据、不重新 bootstrap。迁移先在lexgo_test_issue7验证。文档影响
实施后更新 Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;F07 需求文本未变,Product-Requirements-Overview 仅在需求实质变化时更新。Wiki 先改后回读,再同步镜像。
遗留项
原型 v1 的「原文例句已关联到词条」需要句子切分规则,本单不实现,若用户需要则另立范围;等级编辑 UI 归 #8/#12;#7 不实现词汇库列表、短语、复习与进度。
回退说明:本会话 pi 无可用 Gitea MCP 工具,沿用本单既定回退,使用目标
git.ilapage.cnAPI;凭据仅从既有安全配置读入进程,不进入仓库、日志或工单正文。#7 实施完成,待用户验收(2026-09-11)
用户确认的方案与决策见评论 7737。分支
feat/7-personal-terms从 main33182e5创建,实现提交8c0946af9f1b69cd14e474b3b0178adc92438cb6,已推送。PR #26 未合并,工单不关闭,停在待用户验收。决策落定
Dog/dog同一条记录,dog/dogs两条new新词实现与差异
lexgo_terms(server/app/lexgo/database.go):身份唯一键(owner_id,language,term),term列用utf8mb4_bin避免折叠resume/résumé,original_form保存最近一次的原词形;检查约束只允许learning带 1~7 级。未修改任何既有表和既有数据。server/app/lexgo/terms.go:身份推导、状态/等级边界、文本上限、INSERT … ON DUPLICATE KEY UPDATE幂等保存、跨章节状态匹配。个人词条不写审计日志(私人学习内容不入审计)。POST /api/v1/terms(首次 201、重复 200,返回{term,created})、GET /api/v1/terms/:id(他人与不存在统一 404)、GET /api/v1/chapters/:id/tokens为 word 片段增加term:{id,status,level}。lookup与terms共用wordAtRange,保存与查询必须落在同一完整单词范围。useReaderLookup.ts增加释义/例句/状态、预填与保存(打开已保存词先读原内容,读取失败即禁用保存,避免空表单覆盖);LookupPanel.vue提供状态单选、释义与例句输入、保存与「已保存 · 状态」反馈;ReaderTokens.vue按状态高亮;style.css增加四种状态样式。换词/换章/离页/退出/切账号清空表单、状态与高亮。管理端无改动。实际验证
go vet ./...LEXGO_TEST_DB_NAME=lexgo_test_issue7 python scripts/server.py test-integrationnpx vitest --run/vue-tsc --build/pnpm run build/playwright testpnpm test/pnpm lintpython -m unittest discover -s tests/harness.py check --strictsync --check覆盖:非法状态与等级边界、文本上限、大小写合并与词形不合并、完全相同的重复保存幂等、跨章节同形词状态一致、两账号互不影响、篡改 owner/language/term 与未知字段被拒、非本人章节 404、未登录 401、未就绪章节 409、冷启动读取。
本机开发库
lexgo_dev已显式 v4→v5:升级前后 sys_user 6、lexgo_spaces 6、lexgo_sessions 8、lexgo_books 4、lexgo_chapters 9、lexgo_ingest_jobs 9、lexgo_dictionaries 1 全部不变,新增空的lexgo_terms;旧二进制备份在忽略的.local/lexgo-pre-issue7.exe,仅重启 lexgo-api,其余 11 个实例 PID 与状态未变化,8000 与两端入口均 200。真实链路:真实 Go API+真实 MySQL 共 30 项检查通过,使用 #6 已建的虚构测试账号 issue5_a/issue5_b 与其虚构章节 1/2/8/9(凭据只从本机安全配置读入进程)。随后用临时 Playwright 用例在真实学习端+真实 API 上复核:保存释义/例句/状态 → 「已保存 · 学习中」与正文高亮 → 重新加载后高亮与预填一致 → 390×844 窄屏底部面板 → 退出并以另一账号登录,同文本章节显示该账号自己的状态、未保存的词无状态。临时用例运行后删除,截图作为附件上传。
未验证与边界
文档
Wiki 先写后回读,再同步镜像(镜像随本次提交):
cb6d420632527a436f8b9a7a6a18413a0773f93d71389f97df86e17699f4af930022251fa354631b919545b0d716180a49ac7dd2fe96bbeccdba0880b5eaaf1d0664e1e3c564079c857ccb50425400226fd4c754e3bb6ab215edb6077974fbd401f24103未提交凭据、账号密码、测试数据库数据或截图;
.local/保持忽略。回退
停止 lexgo-api,恢复
.local/lexgo-pre-issue7.exe,把lexgo_schema标记改回 4 后启动;保留lexgo_terms与全部既有学习数据,不删除数据、不重新 bootstrap。Gitea MCP 仍指向其他站点,沿用已记录的目标站点 API 回退;凭据仅从既有安全配置读入进程。推送使用同一 API 令牌经进程环境注入,未写入命令文本、
.git/config或日志。附件:issue7-reader-desktop.png、issue7-reader-mobile-390.png、issue7-account-b.png(本会话模型不能读取图片,截图未经 Agent 目视检查,功能断言来自程序化检查)。
补充提交
a5a8c3c(docs: 记录 #7 已确认的个人词条决策):按本项目既有惯例,把用户本轮确认的个人词条口径写入仓库根AGENTS.md的项目决策清单——身份为「学习者+语言+规范化词形」且不按 lemma 合并、首次保存默认新词、四状态与 1~7 级映射及原版 stage 对照、例句不自动关联原文句子。仅新增一行文档,未改动代码、数据或契约;前期提交8c0946a保持不变,分支 feat/7-personal-terms 已同步推送。用户验收与合并收尾
验收时间:2026-09-11 20:25 +0800(Asia/Shanghai,与 PR 合入时刻一致)。用户在当前会话明确确认「#7 通过验收」。结论:#7 验收通过,关闭工单;PR #26 已 fast-forward-only 合入 main。
合入方式为 fast-forward-only,main 直接前进到分支提交,功能提交仍为
8c0946af9f1b69cd14e474b3b0178adc92438cb6,与用户验收版本逐字节一致,没有产生合并提交、没有改写历史。分支feat/7-personal-terms保留;需要撤销时可在新工单中使用 revert。验收状态文档提交
527d8af(Home、Project-Profile、Architecture-and-Code-Map、Product-Requirements-Overview)与决策记录提交a5a8c3c(AGENTS.md)已推送。合并后复核:harness.py check --strict通过、sync --verify通过、治理测试 56 项通过,工作区干净,先前完整交付证据见评论 7744,不重复覆盖。长期文档 Wiki revisions:
91a2eb47ca73e41a329bccd6ceeb7498c691529c02b7fc12b222c0050652443ca1368730f35f5652c9dcc7a0e9739fe17c148751662acceaed41982fd355012d0f773ab5becb8c966cecfac71e39fabe71389f97df86e17699f4af930022251fa354631b/919545b0d716180a49ac7dd2fe96bbeccdba0880未增加产品范围或数据库变更;schema 保持 v5,本机开发库已完成 v4→v5 迁移与 lexgo-api 重启。真机触屏详细证据与完整备份恢复演练缺口保留,后续由 #14/#15 承接;短语 #11、到期复习 #8、词汇库 #12、进度 #13、附件 #21 与列表优化 #24 仍待实施。
Gitea MCP 仍指向其他站点,沿用已记录的目标 git.ilapage.cn API 回退,凭据仅在进程环境中使用。