From fd37ff6383c4f2e074afc2b8324935e7a26a67fe Mon Sep 17 00:00:00 2001 From: ila Date: Sun, 21 Jun 2026 14:03:36 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=BB=BA=E7=AB=8B=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BD=93=E7=B3=BB=EF=BC=88vision/requirement?= =?UTF-8?q?s/tech-stack/architecture/coding-rules=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/01-vision 核心目标、目标用户、产品原则、非目标 - docs/02-requirements 产品语言需求 + MVP 验收标准(无技术词) - docs/03-tech-stack go-app / 纯CSS / SQLite / Session Cookie / 单二进制部署 - docs/04-architecture 系统结构、前后端职责、真实 episodes.json 数据模型、技术难点 - docs/05-coding-rules AI 写代码前必读的硬约束(防跑偏) - CLAUDE.md AI 入口:文档地图、真实数据 schema、强制必读编码规则 Co-Authored-By: Claude Opus 4.8 --- CLAUDE.md | 102 +++++++++++++++++++++++++++++++++++ docs/01-vision.md | 44 +++++++++++++++ docs/02-requirements.md | 84 +++++++++++++++++++++++++++++ docs/03-tech-stack.md | 41 ++++++++++++++ docs/04-architecture.md | 115 ++++++++++++++++++++++++++++++++++++++++ docs/05-coding-rules.md | 88 ++++++++++++++++++++++++++++++ docs/README.md | 27 ++++++++++ 7 files changed, 501 insertions(+) create mode 100644 CLAUDE.md create mode 100644 docs/01-vision.md create mode 100644 docs/02-requirements.md create mode 100644 docs/03-tech-stack.md create mode 100644 docs/04-architecture.md create mode 100644 docs/05-coding-rules.md create mode 100644 docs/README.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2cb65b7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,102 @@ +# CLAUDE.md — 走遍美国 · 英语学习 PWA + +> 给 AI 编程助手的项目上下文。先读本文件,再按需查 `docs/`。 +> +> ⚠️ **写任何代码前,必须先读完 [`docs/05-coding-rules.md`](docs/05-coding-rules.md)(编码规则)。** 这是保证代码不跑偏、质量稳定的硬约束。 + +## 一句话 + +用 **go-app (Go → WebAssembly)** 构建的 PWA,基于「走遍美国 (Family Album, U.S.A.)」音频素材,做**音频 + 逐句同步字幕**的英语精听学习工具。大屏手机 / 平板优先,可安装、可离线,账号化同步进度与生词本。 + +## 文档地图(`docs/`) + +三份文档职责分层,按需读对应那份;**不要把技术细节往 vision/requirements 里塞**: + +| 文档 | 职责(回答什么) | 该查它当… | +| --- | --- | --- | +| [`docs/README.md`](docs/README.md) | 项目概览与导航 | 想先有个整体印象 | +| [`docs/01-vision.md`](docs/01-vision.md) | **为什么 / 为谁 / 产品原则 / 不做什么** | 拿不准取舍方向、判断某需求该不该做 | +| [`docs/02-requirements.md`](docs/02-requirements.md) | **要什么 + 怎么算达成**(产品语言,无技术词、含验收标准) | 确认功能范围、优先级、验收判据 | +| [`docs/03-tech-stack.md`](docs/03-tech-stack.md) | **用什么**:框架 / 数据库 / UI / 状态管理 / 部署(速查,含待定项) | 想知道某层用哪个技术 | +| [`docs/04-architecture.md`](docs/04-architecture.md) | **怎么搭**:系统结构、职责划分、**数据模型**、技术难点 | 实际写代码、查数据结构与字段 | +| [`docs/05-coding-rules.md`](docs/05-coding-rules.md) | **编码规则**:写代码的硬约束与"完成"的定义 | ⚠️ 动手写代码**之前**必读 | + +> 写代码前的判断链路:`vision`(方向对不对)→ `requirements`(要做成什么样、怎么算对)→ `tech-stack`(用什么)→ `architecture` + 本文件(怎么搭、查字段)→ `coding-rules`(怎么写)。 +> +> `notion_docs/` 是 Notion 原始导出,**只读存档,勿改、勿作为事实来源**。一切以 `docs/` 与真实代码/数据为准。 + +## 技术栈 + +完整选型与理由见 [`docs/03-tech-stack.md`](docs/03-tech-stack.md);速览: + +| 层 | 选型 | +| --- | --- | +| 前端 | go-app(Go → WebAssembly),PWA 可安装 / 离线 | +| UI 样式 | 纯 CSS 文件(移动优先),经 `Handler.Styles` 引入 | +| 状态管理 | go-app 原生(局部状态 + `ctx` 全局观察者),不引第三方 | +| 后端 | Go `net/http` 标准库 | +| 数据库 | SQLite(仅存用户态:账号 / 进度 / 生词本) | +| 鉴权 | httpOnly Session Cookie | +| 音频控制 | 浏览器 Audio API(经 `syscall/js` 互操作) | +| 部署 | 单 Go 二进制自托管(wasm + 静态 + 音频 + API) | + +## 目录结构 + +``` +lingo/ +├── CLAUDE.md # 本文件 +├── docs/ # 规范化项目文档(事实来源) +├── notion_docs/ # Notion 原始导出(只读存档) +└── family-album-usa/ # 内容素材 + ├── episodes.json # 全部课程内容(约 700KB) + └── audio/ # 50 个 mp3,命名 u{集}{幕}.mp3,如 u0101.mp3 +``` + +> 当前**尚无 Go 代码**(无 `go.mod`)。开始编码时在仓库根初始化 go-app 项目结构。 + +## 内容数据:`family-album-usa/episodes.json`(关键,勿臆测) + +结构 **episode(集)→ act(幕)→ line(句)**: + +```json +{ + "meta": { "totalEpisodes": 26, "totalActs": 50 }, + "episodes": [ + { "id": 1, "title": "46 Linden Street", "titleCn": "林登大街46号", + "acts": [ + { "act": 1, "label": "Act I", "audio": "/family-album/audio/u0101.mp3", + "hasAudio": true, "lineCount": 86, + "lines": [ { "t": 34.18, "en": "Excuse me. My name is Richard Stewart." } ] } + ] } + ] +} +``` + +必须记住的事实: + +- **line 只有 `{ t, en }`**——`t` 是音频时间戳(秒),`en` 是英文句。**没有 `zh`(行级中文翻译)字段**,别去读它。 +- episode 有 `titleCn`(集标题中文,26 集全有);行级中文目前不存在。 +- 规模:26 集 / 78 个 act 条目,其中 49 个 `hasAudio=true`;`audio/` 共 50 个 mp3 / 合计 6335 句。 +- **路径映射**:JSON 中的 `/family-album/audio/...` 是服务路径,磁盘实际在 `family-album-usa/audio/`,后端路由需映射。 +- `audio/episode12_act2.mp3` 命名不符 `u####.mp3` 且未被 JSON 引用,属游离文件,勿默认它有效。 + +详见 `docs/04-architecture.md` 第三节(含 SQLite 用户表设计)。 + +## 字幕同步(核心功能,最难) + +播放时用音频 `currentTime` 匹配 line 的 `t` 字段定位当前句 → 逐句高亮;点击某句 → seek 到该句 `t`。比解析 .srt 更直接。go-app 下需经 `syscall/js` 调浏览器 Audio API,建议封装成可复用组件。 + +## 推荐开发顺序(先验证最难的) + +1. **「音频 + 时间戳字幕同步」最小原型**(最难一环,先跑通) +2. 课程列表 + 播放页骨架(读 `episodes.json` 渲染) +3. 后端账号体系 + 鉴权(JWT 或 session) +4. 生词本(前端 UI + 后端 API) +5. 进度同步 +6. PWA manifest + Service Worker 离线化 +7. (V2)复读 / 测验 / 打卡 + +## 约定 + +- 文档与 UI 文案用**中文**;代码标识符用英文。 +- 改动内容数据结构时,**同步更新** `docs/04-architecture.md` 与本文件的 schema 段,避免文档与数据漂移。 diff --git a/docs/01-vision.md b/docs/01-vision.md new file mode 100644 index 0000000..14d2fee --- /dev/null +++ b/docs/01-vision.md @@ -0,0 +1,44 @@ +# 项目愿景 + +## 一、核心目标 + +「走遍美国」(Family Album, U.S.A.) 是经典的英语听力 / 口语教材,以生活化场景短剧呈现地道美式英语。本项目把这一素材改造为现代化、可随身携带、可离线使用的移动端学习工具。 + +> 让每一位想提升英语听力的学习者,都能随时随地、沉浸式地跟随「走遍美国」精听每一句地道英语,并在过程中积累自己的词汇与进步。 + +它不是又一个提供视频的网站,而是一个为**精听、跟读、复读**而生的学习闭环:音频与字幕逐句对齐、点句即跳转、生词随手收集、进度跨设备延续。 + +## 二、目标用户 + +- 想系统提升英语听力的中高阶学习者 +- 喜欢用碎片化、集中时间精听的自学者 +- 习惯在大屏手机 / 平板上学习、偏好随身随地、无网也能学的人 + +## 三、产品原则 + +指导取舍的几条底线,遇到选择时以此为准: + +- **精听优先**:为逐句精听、跟读、复读而设计,不追求泛听或刷剧的"量"。 +- **随身随地、无网可用**:移动优先,断网也能继续学,不让网络成为学习的前提。 +- **积累可见**:学习要留下痕迹(生词、进度、连续天数),让人看到自己在进步。 +- **真实不浮夸**:激励来自用户真实数据与真实学习经历,不灌空洞鸡汤。 +- **一处学习、处处延续**:以学习者为中心,换设备也无缝衔接。 +- **长期多教材**:走遍美国是第一个教材,体验与内容组织面向"未来接入更多教材"而设计。 + +## 四、核心价值主张 + +| 价值点 | 说明 | +| --- | --- | +| 精听体验 | 音频与字幕逐句对齐、逐句高亮,点句跳转,AB 复读 / 变速(后续) | +| 随手积累 | 遇生词一点加入生词本,形成个人词汇库 | +| 随时可用 | 装到主屏即可打开,离线也能学,无网不中断 | +| 跨设备 | 学习进度与生词本跨设备延续,手机平板无缝切换 | + +## 五、不做什么(非目标) + +- 不做视频播放(素材为音频) +- 不做中英对照(目前缺行级中文翻译,待补齐后再开启) +- 不做社区 / 分享 / 社交功能 +- 不做 AI 口语评分(可作为远期设想) + +> MVP 的具体功能范围与"怎么算做到了"的验收标准,见 [需求](02-requirements.md)。 diff --git a/docs/02-requirements.md b/docs/02-requirements.md new file mode 100644 index 0000000..0f9f842 --- /dev/null +++ b/docs/02-requirements.md @@ -0,0 +1,84 @@ +# 需求 + +> 本文只描述**要什么**与**怎么算达成**,用产品 / 用户语言表达,**不涉及技术实现**。 +> 技术方案、数据结构、字段定义见 [架构设计](04-architecture.md);内容数据的字段与校验见 `scripts/`。 + +## 一、素材现状(产品视角) + +| 项 | 状态 | +| --- | --- | +| 音频 | ep1–17 基本齐全;**ep18–26 暂缺音频**(共 9 集只有文稿) | +| 英文文稿 | 26 集逐句英文文稿,且与音频**逐句对齐**(可点句定位) | +| 中文翻译 | 行级暂无;仅每集有中文标题 | +| 视频 | 无(本产品不涉及视频) | + +> 音频缺口意味着 MVP 的精听闭环建议先锁定 ep1–17;ep18–26 待补音频后纳入。 + +## 二、用户角色 + +- **登录用户**:拥有账号,学习进度与生词本跨设备延续 +- 游客是否可浏览:待定(见待确认问题) + +## 三、功能清单 + +### 第一版 MVP(最小闭环) + +| 功能 | 用户能做什么 | 优先级 | +| --- | --- | --- | +| 课程列表 | 按集 / 幕浏览课程,看到自己学到哪、学了多少 | P0 | +| 音频播放 | 播放 / 暂停 / 拖动进度 | P0 | +| 逐句同步 | 字幕随音频逐句高亮;点任一句,音频跳到该句重听 | P0 核心 | +| 生词本 | 看到生词点一下加入生词本,随时查看列表 | P0 | +| 账号与同步 | 登录后,换设备进度与生词本仍在 | P0 | +| 离线可用 | 无网时也能继续学已缓存的课程,并可装到主屏 | P0 | + +### 后续迭代 + +| 功能 | 描述 | 阶段 | +| --- | --- | --- | +| 复读 / 精听 | AB 复读、单句循环、变速 | V2 | +| 测验 | 听写 / 选择 / 填空 | V2 | +| 学习打卡 | 记录学到哪、连续天数 | V2 | +| 激励模块 | 「打鸡血」板块:联网时每天推荐一个英语学习成功案例;优先结合用户自身数据(连续天数、精听句数)做真实激励 | V2 | +| 多教材扩展 | 接入新概念英语等更多教材(为多教材预留空间) | V2+ | +| 中英对照 | 补齐行级中文翻译后开启 | V3 | +| 生词复习 | 间隔重复记忆(SRS) | V3 | + +## 四、核心用户故事(MVP) + +1. 作为学习者,我打开 App 看到课程列表,知道自己学到了哪。 +2. 我点进一集,音频开始播放,字幕随之逐句高亮。 +3. 有一句没听懂,我点那句字幕,音频跳回那句重听。 +4. 遇到生词,我点一下加入生词本。 +5. 换了平板登录,我的进度和生词本都还在。 +6. 坐地铁没网,我依然能打开已缓存的课程继续学。 + +## 五、验收标准(MVP · 怎么算做到了) + +每条 P0 功能对应可验证的判据(产品语言,不含实现细节): + +- **课程列表**:打开即见课程清单,每项显示学习进度(如"2/3 幕"或百分比)。 +- **音频播放**:任选一幕能在约 2 秒内开始播放,可暂停、可拖动进度。 +- **逐句同步**:播放时高亮的句子与人耳听到的一致;点任一句,音频在约 1 秒内跳到该句开头。 +- **生词本**:点词后该词出现在生词本列表;刷新或重进后仍在。 +- **账号与同步**:A 设备登录学习后,B 设备登录同一账号能看到相同的进度与生词本。 +- **离线可用**:断网后仍能打开已学过的课程并播放;可安装到手机主屏。 + +## 六、范围边界与决策 + +| 问题 | 决策 | +| --- | --- | +| 平台优先级 | 大屏手机 / 平板优先,按触控 + 中大屏设计 | +| 是否带账号 | 是,需登录账号 | +| 中英对照 | 第一版纯英文(暂无行级中文),后续补齐再开启 | +| 第一版范围 | 列表 + 播放 + 逐句同步 + 生词本跑通,再加测验 / 打卡 | +| MVP 内容范围 | 先锁定有音频的 ep1–17 | + +## 七、待确认 / 风险点 + +- ❗ **版权**:「走遍美国」素材的使用授权。若公开发布或商用,需确认音频与文稿的授权问题。 +- ❗ **逐句同步是核心体验,也是实现上最难的一环**,建议先单独验证原型再往上搭(技术原因见 [架构设计](04-architecture.md))。 +- ❗ **内容缺口**:ep18–26 缺音频,需补料;具体清单见数据校验脚本。 +- 生词本是否需要查词 / 释义?(MVP 可先只存单词,不接词典) +- ❗ **激励模块内容来源待定**:成功案例库需自行精选、可信,避免空洞鸡汤与版权问题;建议以用户真实进步数据为主、名人真实学语经历为辅。 +- 📌 **本项目定位为长期多教材英语学习平台**,「走遍美国」是第一个教材,后续接入新概念英语等。 diff --git a/docs/03-tech-stack.md b/docs/03-tech-stack.md new file mode 100644 index 0000000..c7f086c --- /dev/null +++ b/docs/03-tech-stack.md @@ -0,0 +1,41 @@ +# 技术栈(Tech Stack) + +> "用什么"的统一速查表。选型与理由在此集中维护;"怎么把它们搭起来"见 [架构设计](04-architecture.md)。 +> ⚠️ 标 **待定** 的项目尚未决策,**不要在代码里擅自选定**——先在此文档定下来再用。 + +## 一、技术栈一览 + +| 维度 | 选型 | 状态 | 理由 / 说明 | +| --- | --- | --- | --- | +| 前端框架 | go-app (Go → WebAssembly) | ✅ 已定 | 纯 Go 写全栈,组件化 PWA,可安装 / 离线 | +| UI 样式方案 | 纯 CSS 文件(移动优先) | ✅ 已定 | 经 `Handler.Styles` 引入;零构建、全控制、可随 PWA 离线缓存。设计 token 用 CSS 变量 | +| 状态管理 | go-app 原生 | ✅ 已定 | 组件局部状态 + `ctx.SetState/ObserveState` 全局观察者(当前播放句 / 生词本 / 登录态),零依赖、控 wasm 体积。不够再议 | +| 后端 | Go `net/http` 标准库 | ✅ 已定 | 最轻、依赖少、好维护 | +| 数据库 | SQLite | ✅ 已定 | 起步足够、零运维,后续可换 Postgres | +| 鉴权方式 | httpOnly Session Cookie | ✅ 已定 | 服务端会话,cookie 不暴露给 JS、抗 XSS;登出简单。跨设备同步靠后端,与鉴权方式无关 | +| 音频控制 | 浏览器 Audio API(经 `syscall/js`) | ✅ 已定 | go-app 通过 JS 互操作调用 | +| 离线 / 安装 | PWA manifest + Service Worker | ✅ 已定 | 可安装到主屏、缓存音频与文稿 | +| 部署方式 | 单 Go 二进制自托管 | ✅ 已定 | 一个二进制供 wasm + 静态 + 音频 + API,运维最省,与 SQLite"零运维"一致;前置反代上 TLS。带宽吃紧后再把音频外挂 CDN / 对象存储 | +| 参考实现 | go-app 官方 examples、lofimusic | ✅ 参考 | 前者提供骨架;后者参考播放器组织(但它无"按时间戳同步字幕"逻辑,需自写) | + +## 二、决策记录与后续可能的演进 + +MVP 的技术栈已全部敲定(上表均为 ✅)。以下是几条"现在这么选、将来可能调整"的备注: + +- **状态管理**:先用 go-app 原生;若跨组件状态变复杂(如全局播放器 + 多页联动),再评估抽一层轻量 store,但不提前引第三方库。 +- **数据库**:SQLite 起步;用户量 / 并发上来后可平滑迁 Postgres(表结构保持兼容)。 +- **音频分发**:MVP 由单二进制直接提供;带宽吃紧后把 `audio/` 外挂到对象存储 / CDN,仅改静态资源路由。 +- **鉴权**:Session Cookie 起步;若将来要做第三方客户端 / 开放 API,再考虑补 JWT 通道。 + +> 选型不臆造、未定先标待定的纪律见 [编码规则](05-coding-rules.md);取舍方向见 [项目愿景](01-vision.md) 的"产品原则"。 + +## 三、构建与运行命令 + +| 用途 | 命令 | +| --- | --- | +| 构建前端(wasm) | `GOOS=js GOARCH=wasm go build -o app.wasm` | +| 构建 / 运行后端 | `go build` / `go run .` | +| 格式化 / 静态检查 | `gofmt -w .` · `go vet ./...` | +| 校验内容数据 | `python3 scripts/validate_episodes.py` | + +> 实际目录布局、模块划分、数据模型见 [架构设计](04-architecture.md);真实数据 schema 另见 `CLAUDE.md`。 diff --git a/docs/04-architecture.md b/docs/04-architecture.md new file mode 100644 index 0000000..62c23ee --- /dev/null +++ b/docs/04-architecture.md @@ -0,0 +1,115 @@ +# 架构设计 + +> 本文讲"怎么把技术栈搭起来":系统结构、前后端职责、数据模型、技术难点、开发顺序。 +> 具体用了哪些框架 / 库 / 数据库 / 部署方式,见 [技术栈](03-tech-stack.md)。 + +## 一、系统结构 + +``` +┐ +│ 用户浏览器 (大屏手机 / 平板) +│ │ +│ ▼ 安装为 PWA,离线缓存 +│ 前端 go-app (app.wasm) +│ - 课程列表 / 播放器 / 字幕同步 / 生词本 UI +│ - Service Worker 缓存音频与文稿 +│ │ +│ ▼ REST API (JSON over HTTPS) +│ 后端 Go net/http +│ - 账号鉴权 / 进度 / 生词本 +│ │ +│ ▼ +│ SQLite 数据库 +┘ +``` + +## 二、前后端职责划分 + +**前端(go-app / wasm)** + +- 课程列表、音频播放器 +- 字幕同步高亮 + 点击跳转(核心,自写) +- 生词本界面 +- PWA manifest + Service Worker + +**后端(net/http)** + +- 用户注册 / 登录 / 鉴权(方式见技术栈,待定) +- 生词本增删查 +- 学习进度读写 +- (静态音频与文稿可由 go-app Handler 或 CDN 提供) + +## 三、数据模型 + +数据分两类:**内容数据(静态、只读)** 与 **用户数据(动态、需后端)**。 + +### 3.1 内容数据 — 静态 `episodes.json`(前端直接读,不入库) + +实际素材已存在:`family-album-usa/episodes.json`(约 700KB)+ `family-album-usa/audio/*.mp3`。 +结构为 **episode(集)→ act(幕)→ line(句)** 三级(以下为真实结构): + +```json +{ + "meta": { "version": "1.0.0", "title": "走遍美国 Family Album U.S.A.", + "totalEpisodes": 26, "totalActs": 78, "audioActs": 49, "lastUpdated": "2026-05-29" }, + "episodes": [ + { + "id": 1, "title": "46 Linden Street", "titleCn": "林登大街46号", + "acts": [ + { + "act": 1, "label": "Act I", + "audio": "/family-album/audio/u0101.mp3", + "hasAudio": true, "lineCount": 86, + "lines": [ + { "t": 34.18, "en": "Excuse me. My name is Richard Stewart." } + ] + } + ] + } + ] +} +``` + +要点(**以实际数据为准,勿臆测字段**): + +- **集 episode**:`id` / `title` / `titleCn`(26 集**全部**有中文标题)/ `acts[]` +- **幕 act**:`act` 序号 / `label` / `audio`(服务路径 `/family-album/audio/u{集}{幕}.mp3`)/ `hasAudio` / `lineCount` / `lines[]` +- **句 line**:**只有 `{ t, en }` 两个字段**。`t` 为音频时间戳(秒),`en` 为英文原句。**无 `zh` 字段**——行级中文翻译目前不存在,未来要补需扩展 schema +- 规模:26 集 / 78 个 act 条目,其中 49 个 `hasAudio=true`;`audio/` 目录共 50 个 mp3,合计 6335 句 +- ⚠️ **路径映射**:JSON 里的 `/family-album/audio/...` 是**对外服务路径**,对应磁盘目录 `family-album-usa/audio/`,后端路由需做这层映射 +- ⚠️ `audio/episode12_act2.mp3` 命名不符合 `u####.mp3` 规则且未被 JSON 引用,属游离文件,接入时需核对 + +> 多教材扩展:未来接入新概念英语等,可沿用「教材 → 单元 → 句子」三级抽象——「走遍美国」即一个教材。新教材未必每句有时间戳,line 的 `t` 允许缺省。第一版无需为此提前建库,前端按 JSON 渲染即可。 + +### 3.2 用户数据 — SQLite(需账号,后端读写) + +仅存「用户态」,**内容数据不入库**: + +**users** — id, email, password_hash, created_at + +**progress** — user_id, episode_id, act, last_position(秒), completed, updated_at + +**vocab** — id, user_id, word, episode_id, act, context_sentence, created_at + +**功能模块化**:字幕同步、生词本、播放器做成可复用组件,不同教材按需启用(走遍美国用字幕同步;新概念可能更重单词表与语法)。 + +## 四、关键技术难点 + +| 难点 | 说明 | 应对 | +| --- | --- | --- | +| 字幕同步 | 音频 currentTime 匹配 `t`,逐句高亮 + 点句跳转 | 先出最小原型验证 | +| Audio API 互操 | go-app 需通过 syscall/js 调浏览器 | 封装成可复用组件 | +| wasm 首屏体积 | Go wasm 最小约 2MB,首屏较慢 | 离线缓存后续访问快 | +| 离线音频 | 大体积音频缓存策略 | Service Worker 按需缓存 | + +## 五、推荐开发顺序 + +1. **先写「音频 + 时间戳字幕同步」最小原型**(验证最难一环) +2. 搭课程列表 + 播放页骨架 +3. 后端账号体系 + 鉴权 +4. 生词本(前端 UI + 后端 API) +5. 进度同步 +6. PWA manifest + Service Worker 离线化 +7. (V2)复读 / 测验 / 打卡 + +> 原则:先验证最难的字幕同步,跑通再往上搭架子,避免先搭一堆架构最后卡在核心功能。 diff --git a/docs/05-coding-rules.md b/docs/05-coding-rules.md new file mode 100644 index 0000000..8e66672 --- /dev/null +++ b/docs/05-coding-rules.md @@ -0,0 +1,88 @@ +# 编码规则(Coding Rules) + +> **每次写代码前先读完本文件。** 这是让 AI 不跑偏、代码质量稳定的"宪法"。 +> 与技术细节冲突时,以 [技术栈](03-tech-stack.md) / [架构设计](04-architecture.md) 和 `CLAUDE.md` 的事实为准;与"该不该做"冲突时,以 [需求](02-requirements.md) 为准。 + +## 0. 黄金法则(记住这 5 条就够稳) + +1. **不臆造**:数据字段、文件、接口、依赖,不确定就去查 / 去问,绝不凭印象编。 +2. **守范围**:只做被要求的事,MVP 只做 ep1–17 的 P0,不顺手加 V2/V3。 +3. **照架构**:用既定技术栈(go-app / net/http / SQLite),不擅自引入新框架或依赖。 +4. **小步改**:一次只解决一个问题,不夹带无关重构、不整文件重排版。 +5. **可验证**:改完必须能构建、过校验、对得上验收标准,再说"完成"。 + +## 1. 动手前 + +- 按链路确认:`vision`(方向)→ `requirements`(要什么 + 验收标准)→ `tech-stack` + `architecture` + `CLAUDE.md`(怎么做)。 +- 找到对应的**验收标准**(02-requirements 第五节),写之前就知道"怎么算做对"。 +- 需求含糊、或一个改动会偏离原则 / 架构时——**先问,不要猜着做**。 +- 动手前先找现有的函数 / 组件 / 工具能不能复用,**别重复造轮子**。 + +## 2. 事实来源纪律(最容易踩的坑) + +- **内容数据只信 `family-album-usa/episodes.json` 的真实结构**: + - `line` 只有 `{ t, en }`——**没有 `zh`**,不要读、不要假设有行级中文。 + - 三级是 `episode → act → line`,不是 `course/lesson`。 + - `audio` 字段是**服务路径** `/family-album/audio/u{集}{幕}.mp3`,磁盘在 `family-album-usa/audio/`,**必须做映射**,不能当文件路径直接用。 +- **不要为 ep18–26 补造音频或假数据**——这 9 集真的没音频,MVP 不依赖它们。 +- **改了 `episodes.json` 或它的结构,必须**:① 跑 `python3 scripts/validate_episodes.py` 过校验;② 同步更新 [架构设计](04-architecture.md) 第三节 + `CLAUDE.md` 的 schema 段(防文档漂移)。 +- `notion_docs/` 和 `*.bak` 是只读存档,**不读作事实、不修改、不删除**。 + +## 3. 范围纪律(防镀金 / 防跑题) + +- MVP 范围 = **ep1–17 + 6 个 P0 功能**(课程列表 / 播放 / 逐句同步 / 生词本 / 账号同步 / 离线)。其余一律不做。 +- 看到"顺便也能做 X"的冲动先停下:X 在 requirements 里是 P0 吗?不是就**不做**,最多记成 TODO。 +- 不做需求里明确的非目标:视频、行级中英对照、社交、AI 口语评分。 +- 不为"将来可能用到"提前抽象(多教材结构架构已预留,按现状写即可,别过度设计)。 + +## 4. 架构纪律 + +- **技术栈固定**:以 [技术栈](03-tech-stack.md) 为准(前端 go-app、后端 `net/http`、数据库 SQLite)。要加任何第三方依赖,**先说明理由并征求同意**。 +- **标"待定"的栈项不要擅自选定**(UI 样式 / 状态管理 / 鉴权方式 / 部署)——先在 tech-stack 文档定下来再用,别在代码里替项目拍板。 +- **内容数据 vs 用户数据分清**:教材内容(episodes.json)前端直接读、**不入库**;SQLite **只存**用户态(users / progress / vocab)。别把课程内容写进数据库。 +- 把浏览器互操作(`syscall/js`、Audio API)**封装成可复用组件**,不要散落在各处业务代码里。 +- 进度 / 生词本的字段以 [架构设计](04-architecture.md) 第 3.2 节为准(按 `episode_id + act` 定位,不是抽象 lesson_id)。 + +## 5. Go / go-app 代码规范 + +- 提交前过 `gofmt` 和 `go vet`;构建用 `GOOS=js GOARCH=wasm go build`(前端)/ 普通 `go build`(后端)。 +- **错误必须处理**:不忽略 `err`、不用 `_` 吞错;正常流程里不 `panic`(初始化致命错误除外)。 +- 包 / 文件按职责划分,对照 [架构设计](04-architecture.md) 第二节的前后端职责组织(列表 / 播放器 / 字幕同步 / 生词本 / API 封装)。 +- 控制 wasm 体积:不引重型库;公共逻辑抽函数,避免复制粘贴。 +- 不留 `TODO` 就当没事——要么实现,要么在 PR / 回复里**明确标注未完成项**。 + +## 6. 字幕同步专项(核心功能,最易出 bug) + +- 定位当前句:用音频 `currentTime` 在该 act 的 `lines[].t` 上**二分查找**,不要线性扫每帧。 +- **时间戳可能非严格递增**(已知 ep18/ep25 有倒退):定位逻辑要对乱序 / 相等 `t` 容错,不能假设严格单调。 +- 点句跳转:seek 到该句 `t`;高亮的句子必须和正在播放的一致(验收标准里有这条)。 +- `hasAudio=false` 的 act:没有音频可同步,UI 要**优雅降级**(只显示文本 / 标注无音频),不要崩。 + +## 7. 命名与风格 + +- 代码标识符用**英文**;UI 文案、注释、文档用**中文**(与项目现状一致)。 +- 写新代码前先看邻近代码的命名、缩进、注释密度,**与之保持一致**,不要自带一套风格。 +- 注释解释"为什么",不复述"做了什么"。 + +## 8. 改完之前("完成"的定义) + +逐项过,全绿才算完成: + +- [ ] 能构建通过(前端 wasm / 后端 二进制) +- [ ] 碰过内容数据就跑了 `validate_episodes.py`,0 ERROR +- [ ] 对得上相关功能的**验收标准** +- [ ] 没有夹带无关改动、没有整文件重排版 +- [ ] 涉及数据结构变化的,文档(tech-stack / architecture / CLAUDE.md)已同步 +- [ ] 如实汇报:跑了什么、结果如何;测试失败就说失败,别粉饰 + +## 9. 绝不 + +- 绝不把密钥 / token 写进代码或提交(用环境变量 / 配置)。 +- 绝不删除或覆盖 `notion_docs/`、`*.bak`、`episodes.json`(改它先靠 `fix_episodes.py` 备份)。 +- 绝不为了让测试 / 校验通过而改判据、删用例、注释掉检查。 +- 绝不引入版权存疑的素材或内容。 +- 绝不在没说明的情况下"顺手"重构、改公共接口、升级依赖。 + +## 10. 拿不准就问 + +宁可停下来问一句,也不要猜着写半天最后方向错了。问题要具体,给出你倾向的选项和理由。 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..5285482 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,27 @@ +# 走遍美国 · 英语学习 PWA + +> 一个用 Go (go-app + WebAssembly) 构建的渐进式 Web 应用 (PWA),基于「走遍美国 (Family Album, U.S.A.)」素材,帮助用户通过音频 + 同步字幕进行沉浸式英语听力学习。 + +本主页汇总项目的核心文档,按"为什么 → 要什么 → 用什么 → 怎么搭 → 怎么写"分层。 + +## 📌 一句话定位 + +大屏手机 / 平板优先,可安装、可离线,账号化的「走遍美国」音频精听学习工具。 + +## 🗂 文档导航 + +- [项目愿景](01-vision.md) — 为什么 / 为谁 / 产品原则 / 不做什么 +- [需求](02-requirements.md) — 要什么 + 验收标准(产品语言,无技术词) +- [技术栈](03-tech-stack.md) — 用什么:框架 / 数据库 / UI / 状态管理 / 部署(速查) +- [架构设计](04-architecture.md) — 怎么搭:系统结构、职责划分、数据模型、技术难点 +- [编码规则](05-coding-rules.md) — 怎么写:AI 写代码前必读的硬约束 + +## ⚡ 当前阶段 + +第一版 (MVP) 最小闭环:**课程列表 + 音频播放 + 字幕同步 + 生词本 + 账号同步**。后续迭代加入测验与打卡。 + +## 🛠 技术栈速览 + +- 前端:go-app (Go → WebAssembly),PWA 可安装 / 离线 +- 后端:Go `net/http` + SQLite +- 素材:26 集英文文稿 + 逐句时间戳(音频覆盖 ep1–17,ep18–26 待补)