Files
lexgo/docs/02-architecture-and-code-map.md
T

10 KiB
Raw Blame History

generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Architecture-and-Code-Map wiki_url: https://git.ilapage.cn/OPC/lexgo/wiki/Architecture-and-Code-Map.- wiki_revision: 3b6f6db7f0fe1019b5811f70af8d6174cec0b950 synchronized_at: 2026-09-10T12:36:57Z

架构与代码地图

项目定位

Go 承担业务与后台任务,浏览器提供阅读学习界面,NLP 保留独立边界是现有分析的建议。用户区与管理区共享身份服务,但功能权限与个人数据所有权分别校验。

代码地图

现有位置 内容 能证明什么
docs/01-LinguaCafe需求提取.md、docs/linguacafe-requirements.md 两份需求研究 参考需求与上游证据索引
docs/02-Go复刻与框架选型分析.md、docs/linguacafe-go-analysis.md 两份设计建议 候选方案,含未解决差异
docs/ 核心页面 Gitea Wiki 的单向镜像 仅文档与治理准备,不是产品实现
dev_scripts/harness.py、dev_scripts/wiki_docs.py 原样复制的 DevHarness 工具 治理工具入口,无业务 API
tests/ 上游治理工具与文档结构测试 不验证阅读、NLP 或 SRS

不存在产品入口、数据库迁移或前端页面。拟定职责:identity(身份)、library(书库)、ingestion(导入)、lexicon(全局词典)、vocabulary(个人词语)、review(复习)、progress(统计)、administration(管理)。底座固定后再决定具体目录。

两条主要执行路径

目标路径一:上传文本 → 创建有所有者的导入任务 → 提取/分词/索引 → 章节就绪 → 阅读器按 token 展示原文和用户词语状态。

目标路径二:阅读保存词语或短语 → 写入个人学习状态与例句 → 查询到期词条 → 服务端计算作答后的状态 → 写入幂等事件 → 更新统计。

不可破坏的边界

  • 词典资源与个人释义分离,共享缓存不能混入个人记录。
  • Go/Python/JavaScript 的偏移契约必须统一;原文与内容版本必须保留。
  • API 与 Worker 复用业务规则;NLP 通过明确契约调用,不泄露模型内部对象到前端。
  • 任务至少可重试而不重复产出;学习事件不重复计数。
  • 共享 API/NLP/状态契约在批准后的主题 Wiki 中建立唯一来源,字段和版本尚未定案;不能以本页概要直接生成冻结接口。

管理端选型落地边界

管理端采用用户指定的 D:/github_project/goadmin,前后端固定 commit 见项目档案。后端现有入口为源仓库 main.go,业务分布于 app/cmd/common;管理前端入口为 go-admin-ui/src/main.js,页面位于 src/views,路由/API 封装位于 src/router、src/api。这些是外部参考仓库路径,尚未复制或运行于 LexGo。

当前 #2 已固定首批 LexGo 目录和身份衔接契约;通用管理能力可复用,用户与语言的数据所有权检查由业务层实现。既有分析中 gin-vue-admin 的推荐已被本次用户决策替代。

学习端与管理端的目标架构

技术方向已纳入本轮方案,以下是目标结构,尚无对应产品目录或可运行应用。

flowchart TD
    L[学习端 Vue 3 / TypeScript / Vite] --> API[共享 Go API:基于 go-admin 扩展]
    A[管理端 go-admin-ui] --> API
    API --> B[独立学习业务模块]
    B --> DB[(MySQL 8)]
    B --> W[后台任务:具体选型待验证]
    W --> N[NLP 服务:Python 方案待确认]
交付部分 建设方式 复用与自建边界
学习端 create-vue 新建独立 SPA 工程 复用 Vue Router、Pinia、Element Plus;定制书库、阅读器、划词与复习组件
管理端 指定本地 go-admin-ui 二次开发 沿用现有 Vue CLI/Vuex 工程,按 LexGo 需要适配管理页面
共享后端 指定 go-admin 后端扩展为模块化单体 复用适配后的身份、权限与管理能力;新增 library、vocabulary、review、progress 等业务模块

两个前端分别构建,共用账号体系、API 与数据库。角色权限和数据所有权分别校验,隐藏路由不能替代服务端授权。共享业务规则由后端维护;两端不各实现一套词汇或复习状态规则。

部署方向为同域名 /app 学习端、/admin 管理端、共享 API,首期不拆业务微服务。这些前缀是部署建议,具体网关、静态资源 base、路由回退和登录方式在接口/部署设计中验证后固定。学习端独立工程不要求单独部署后端。

先按浏览器响应式界面设计电脑与手机使用;PWA 保留为后续候选,完整离线同步不在本次技术确认中。最终页面和 MVP 范围将在后续需求讨论中确定。

go-admin 模块参考与原型边界(2026-09-10)

以下来自已记录固定版本的本地源码检查,尚未执行配套构建。

LexGo 内容 参考来源 复用边界与设计证据
账号、角色、菜单和 API 权限 后端 app/admin 的 sys_user/sys_role 路由、API、service/DTO/model;前端 src/views/admin/sys-user、sys-role 两端用户名+密码登录;账号页面沿用表格/弹窗,字段说明即可;学习接口另加强制用户归属
语言资源列表、配置 SysConfig、SysDict 与管理前端对应列表/表单 复用表单模式;SysDict 是系统枚举,不能作为自然语言词典;简单配置不另画全套原型
文本处理状态 app/jobs 的 SysJob 状态操作可参考 原版是 cron 任务管理,不能作为可靠文本队列的证据;新任务需明确持久状态、恢复和幂等
学习领域 API 与表 router/apis/service/dto/models、版本迁移机制 沿用结构,独立设计词条身份、归属、原文位置与复习事务;后端无需 UI 原型
阅读、查词、短语、复习 已验收 Quant-UX v1 与运行划词小样 使用定制学习组件,主要交互改变时补关键原型;真实触摸/连续选择必须运行验证

源码检查发现 common/actions/permission.go 允许关闭 EnableDP,且 DataScope 默认分支不添加过滤;该机制用于管理数据范围,不能单独保证私人学习数据隔离。学习接口必须强制按认证用户归属查询,不允许客户端指定用户替代认证身份。

仅当管理流程引入多步安装、处理中/失败重试等明显交互不确定性时,补关键状态原型。通常的列表、编辑、删除确认沿用 go-admin 表格、表单和弹窗,记录字段、权限、异常和验收即可。

已实现工程入口(#2)

路径 职责
server/cmd/lexgo/main.go 配置连接、migrate/bootstrap/serve 命令;默认只监听 127.0.0.1:8000
server/app/admin/models、server/common/models 按 upstream.json 原样选用的 go-admin 模型和约定
server/app/lexgo/database.go MySQL 8 显式版本迁移、所有权标记、启动检查
server/app/lexgo/service.go 用户名校验、账号创建、bcrypt、随机会话摘要和撤销
server/app/lexgo/router.go JSON 请求、角色和归属授权、API 路由和安全错误响应
server/app/lexgo/*_test.go 真实 MySQL 隔离、撤销、并发创建、迁移拒绝/恢复、bootstrap 验证
admin/src/views、admin/src/session.mjs 基于 go-admin-ui 的账号页面与管理端会话
learner/src/views、learner/src/stores/session.ts 独立学习端登录与私人空空间、会话及迟到响应隔离
scripts/server.py 安全读取本机 .env.local,传入子进程;不输出秘密

账号 API v1

请求使用 JSON;受保护接口使用 Authorization: Bearer。成功结构 {code:200,data:...},创建账号 HTTP 201;失败使用实际 HTTP 400/401/403/404/409/429/500 和 {code:状态码,msg:必要提示}。响应 Cache-Control:no-store。

方法与路径 行为和权限
POST /api/v1/login username/password,返回 token、expiresAt、user;不要求邮箱
GET /api/v1/me 当前登录者 id/username/role/disabled
POST /api/v1/logout 撤销当前会话
GET /api/v1/space 当前用户英语空间;拒绝查询参数指定用户
GET /api/v1/spaces/:id 仅本人的空间可读,他人编号返回 404
GET /api/v1/accounts 管理员查看账号列表;只输出必要字段
POST /api/v1/accounts 管理员创建 learner;拒绝客户端 role 等未知字段
PATCH /api/v1/accounts/:id 管理员启停或重置 learner 密码;不能修改自己或其他管理员
GET /healthz 检查数据库连接,仅返回健康状态

schema v1:sys_user 保留选用 go-admin 模型字段,唯一小写用户名;lexgo_spaces 以 owner_id 为主键;lexgo_sessions 保存 token_hash/owner_id/expires_at;lexgo_schema 记录版本与产品所有权。服务启动不自动迁移。迁移仅接受空库或合法已有 LexGo marker,拒绝空 marker、其他产品、负版本与未来版本;版本 0 可重试部分迁移,版本 1 幂等。

凭据字段只存在本地环境和必要数据库哈希中。后台账号密码更新使用表/字段更新,避免上游 BeforeUpdate hook 对已有哈希再次加密。账号行再会话行的锁顺序用于串行化撤销与请求;API 在事务提交后才返回成功。

登录与操作审计(#18)

server/app/lexgo/audit.go 定义两类白名单字段日志、筛选分页、失败记录和过期清理;router.go 在登录/账号操作边界接入。登录成功时会话与日志同一事务;账号操作成功时业务写入与日志同一事务;失败时先回滚业务,再以独立、有 3 秒超时的事务写失败记录。日志写入失败返回通用 500,不输出数据库原始错误或凭据。

database.go 显式迁移至 v2,两张新增表均以 created_at/id 建立排序清理索引,账号字段建查询索引,无业务表级联删除。cmd/lexgo/main.go 的服务进程在启动和每小时执行审计清理,每次最多运行一分钟、每批删除 1000 条,仅影响过期审计记录。

admin/src/views/AuditLogs.vue 通过 kind 复用登录/操作列表;audit-logs.mjs 负责筛选编码和请求序号,session.mjs 继续进行管理员及会话 generation 校验。切换页面/账号清空日志,普通翻页保留总数,防止分页组件跳回第一页。菜单与标题按当前路由显示。