10 KiB
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 校验。切换页面/账号清空日志,普通翻页保留总数,防止分页组件跳回第一页。菜单与标题按当前路由显示。