Skip to content

开发工具和脚本

本目录包含项目开发和调试使用的实用工具脚本。


📦 代码生成

build_runner.sh

Flutter 代码生成工具,用于生成 Freezed 模型和其他注解代码。

bash
./scripts/build_runner.sh build   # 一次性生成
./scripts/build_runner.sh watch   # 监听模式
./scripts/build_runner.sh clean   # 清理生成的文件

🔧 配置和调试

check_api_config.sh

检查 API 配置状态,验证 .env 文件中的配置是否完整。

bash
./scripts/check_api_config.sh

view_app_logs.sh

查看应用实时日志(Android 设备)。

bash
./scripts/view_app_logs.sh

📊 数据管理

import_vocabulary_to_supabase.py

将本地 vocabulary.db 的数据导入到 Supabase 云端词汇库。

依赖

bash
pip install supabase pandas python-dotenv

配置:需要 .env.supabase 文件(见 docs/deployment/supabase-setup-guide.md)

用法

bash
python scripts/import_vocabulary_to_supabase.py

export_vocabulary_to_csv.py

导出词汇库数据到 CSV 文件,用于数据分析或备份。

bash
python scripts/export_vocabulary_to_csv.py

delete_supabase_words.py

删除 Supabase 中的测试词汇数据。

bash
python scripts/delete_supabase_words.py

🗄️ 数据库同步

sync_reconcile.sh

设备本地 SQLite 与 Supabase 逐 id 对账,报「谁有谁没有」。只读(本地库是 run-as cat 拷出的副本,Supabase 只发 GET),app 不必在运行。

为什么有它:sync 的丢行是静默的 —— 没有异常,getSyncStatus 只数本地脏行, 云端多出来的行不在它口径里,UI 永远显示「已同步」。历史上两次都是靠人手工比 一次两端行数才发现(「push 75→4」挂了三个月、pull 侧丢行挂了 5 天), 而比完就没了。判据不常驻就等于没有。

bash
bash scripts/sync_reconcile.sh            # 仓根或 rvh/ 下都能跑
KEEP_DB=1 bash scripts/sync_reconcile.sh  # 保留拉下来的 db 快照

退出码

  • 1 本地独有 > 0 → push 侧回归(本地行已 clean 就永远不会重推)
  • 2 有表没查成 → 本轮无结论,不算绿(写第一版时就踩到:一次 curl 抖动被当成 「云端没有」,推出的丢失链条整个是反的)
  • 0 其余。云端独有只 warn —— 逐条按打印出来的 watermark 判:晚于它 = 只是还没拉; 早于它却仍缺 = pull 侧跳过后 watermark 越过 = 永久丢失

两侧都已排除墓碑:pull 的「本地无 + remote 删」分支刻意不落墓碑, 「对端删了、本端从来没有过」是正常终局,含墓碑比会报成永久缺口。

⚠️ 需要 admin/.env.localSUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY)。 known_words 刻意不比 —— 预装的 211 个功能词按设计永不 push(born-clean)。

引擎内另有一份每轮 sync 自动跑的轻量版(只比数量、不比 id), 见 lib/features/sync/data/repositories/sync_repository_impl.dart::_reconcileRowCounts


sync_database.sh

在 Android 设备和电脑之间同步 SQLite 数据库,方便使用 DataGrip/DB Browser 等专业工具调试。

用途

  • 使用专业工具调试数据库结构和数据
  • 批量修改数据(更新/删除)
  • 数据分析和统计
  • 定期备份数据库

基本命令

bash
./scripts/sync_database.sh pull      # 从手机导出到电脑(~/Desktop/app_database_backup/)
./scripts/sync_database.sh push      # 从电脑导入到手机(需确认,自动备份)
./scripts/sync_database.sh backup    # 仅备份,不覆盖工作文件
./scripts/sync_database.sh status    # 查看手机和本地数据库状态

典型工作流程

bash
# 1. 导出数据库
./scripts/sync_database.sh pull

# 2. 在 DataGrip 中编辑
#    数据源:~/Desktop/app_database_backup/reading_vocab.db
#    执行 SQL(查询/更新/批量修改)

# 3. 导入回手机
./scripts/sync_database.sh push

# 4. 重启应用验证
adb shell am force-stop com.example.english_learning_app
adb shell am start -n com.example.english_learning_app/.MainActivity

⚠️ 注意事项

  • push 会覆盖手机数据库:脚本自动备份,但请谨慎操作
  • 修改后必须重启应用:应用启动时加载数据库,运行中不自动刷新
  • 外键约束:删除 reading_sources 会级联删除相关记录

文件位置

~/Desktop/app_database_backup/
├── reading_vocab.db                          # 工作文件(用于 DataGrip 编辑)
├── reading_vocab.db.backup_20260102_060000   # 自动备份(带时间戳)
└── ...

常见问题

  • push 后应用崩溃? 数据库结构被破坏,使用手机上的备份恢复
  • pull 后 DataGrip 显示"locked"? 先停止应用再 pull
  • 恢复历史备份? 运行 status 查看备份列表,复制到工作文件后 push

🗑️ 数据清理

reset_app_data.sh(推荐 ⭐)

完全重置应用数据,最快最简单的清理方式。

效率: ⚡⚡⚡⚡⚡ 最快(2秒)

用法

bash
./scripts/reset_app_data.sh

会清除

  • ❌ 所有书籍和阅读来源
  • ❌ 所有笔记本条目
  • ❌ 所有用户设置和开发者设置
  • ❌ SharedPreferences 数据

会保留

  • ✅ 无(完全清空,重启后自动导入预装词库)

适用场景

  • 想要完全重新开始
  • 最快的清理方式
  • 不需要 Root 权限

clear_test_data.sh

选择性清理测试数据,保留用户设置和单词库。

效率: ⚡⚡⚡ 较快(6秒)

用法

bash
./scripts/clear_test_data.sh

会清除

  • ❌ 所有书籍和阅读来源
  • ❌ 所有笔记本条目
  • ❌ 所有OCR单词位置
  • ❌ 所有掌握度追踪
  • ❌ 所有阅读来源-单词关系

会保留

  • ✅ 单词库(vocabulary_items)- 8614个预装词
  • ✅ 用户设置(SharedPreferences)
  • ✅ 开发者设置(OCR调试模式、图像处理开关等)

适用场景

  • 日常开发测试
  • 想保留开发者设置(避免重新配置)
  • 需要设备 Root 权限 ⚠️

使用建议

第一次清理

bash
# 使用完全重置(最快,不需要Root)
./scripts/reset_app_data.sh
# 然后配置开发者设置

之后的清理

bash
# 使用选择性清理(保留设置)
./scripts/clear_test_data.sh

🧪 测试工具

test_vocabulary_filtering.sh

测试词汇过滤功能,验证 CEFR 等级过滤逻辑。

bash
./scripts/test_vocabulary_filtering.sh

push_test_image.sh

推送测试图片到 Android 设备,用于 OCR 功能测试。

bash
./scripts/push_test_image.sh <image_path>

pull_cached_photos.sh

从 Android 设备拉取缓存的照片,用于调试图像处理流程。

bash
./scripts/pull_cached_photos.sh

📝 使用建议

  • 日常开发:主要使用 build_runner.shview_app_logs.sh
  • 配置验证:新环境使用 check_api_config.sh
  • 数据管理:Supabase 相关操作使用 import_vocabulary_to_supabase.py
  • 数据库调试:使用 sync_database.sh 在设备和电脑间同步数据库
  • 功能测试:使用测试工具验证 OCR 和词汇过滤功能

🔒 CI/CD 代码质量门禁

概述

项目配置了完整的代码质量门禁系统,包括:

  1. GitHub Actions CI - 自动化 CI/CD 流水线
  2. Pre-commit Hook - 本地预提交检查
  3. 预提交检查脚本 - 可独立运行的检查工具

install-hooks.sh

安装 Git pre-commit hook。可选、默认不装 —— 本仓质量门走 CI (仓根 .github/workflows/ci-rvh.yml),hook 只是本地提速手段,装不装都不影响 main。

bash
./scripts/install-hooks.sh

安装后效果

  • hook 装在仓根 .git/hooks/pre-commit(合仓后 rvh/ 无独立 .git
  • 只有本次暂存区碰了 rvh/ 下的文件时才真跑检查,纯 RB 提交直接放行
  • 检查失败会阻止提交;git commit --no-verify 可跳过

🔴 2026-08-30 修好之前它是坏的(合仓遗留):脚本检查 rvh/ 下的 .git 目录,而合仓后那个目录已不存在, 一进门就 exit 1;即使绕过,生成的 hook 又去调仓根 scripts/ 下的 pre-commit-check.sh(那个位置没有这个文件) —— 那个文件在 rvh/scripts/ 下。两处都是「路径写死了单仓时期的形状」。

pre-commit-check.sh

独立的代码质量检查脚本,可手动运行或被 Git hook 调用。

bash
./scripts/pre-commit-check.sh        # 完整检查(含单元测试)
./scripts/pre-commit-check.sh --quick # 快速检查(跳过测试)

检查内容

检查项说明快速模式
代码格式dart format 检查
静态分析flutter analyze 检查
架构合规Clean Architecture 规则检查
单元测试flutter test❌ 跳过

架构合规性检查规则

  1. Presentation → Data 违规

    • Presentation 层不应直接导入 Data 层的 models
    • Presentation 层不应直接导入 Data 层的 datasources
    • Presentation 层不应直接导入 Repository 实现
  2. Domain 层纯净性

    • Domain 层不应依赖 Flutter UI 框架(flutter/foundation.dart 除外)
    • Domain 层不应依赖 Data 层

GitHub Actions CI

🔴 合仓后位置变了:RVH 的 CI 是仓根.github/workflows/ci-rvh.yml, 子项目自己那个 .github 目录已于 2026-08-28(合仓 T3-6)整目录删除。触发条件:

  • 任意分支 push / PR,且改动命中 paths: rvh/**(纯 RB 提交不触发)
  • 所有 run: 步骤默认在 rvh/ 下执行(defaults.run.working-directory

⚠️ 那道 dart format已于 2026-08-29 删除 —— 它在任何能解析本项目依赖的 Flutter 上都会因 tall-style 重写当场红 502 个文件。要不要做一次全仓重排版记在 仓根 docs/plans/backlog.md(做了会冲掉几乎每个 .dart 的 blame)。

CI Jobs

  1. Code Analysis - 代码格式和静态分析
  2. Architecture Compliance - Clean Architecture 合规性检查
  3. Unit Tests - 运行单元测试
  4. Coverage Report - 生成测试覆盖率报告(仅 PR)

doc-consistency-check.sh

文档一致性检查脚本,验证文档间的版本号、链接等一致性。

bash
./scripts/doc-consistency-check.sh

检查内容(6 步):

  • Schema 版本号一致性(4 个权威文件)
  • 数据库文档命名规范
  • 通用 Claude Code 教程不得复活(2026-08-29 T2-2 删除后的负向断言)
  • 断链检查 —— 委托仓根 scripts/check-doc-links.mjs(2026-08-30 改)
  • 表数量一致性
  • 词汇库大小一致性

🔴 断链那一步 2026-08-30 之前是假的:它是一张写死 3 个文件名的黑名单 (testing.md / performance.md / DEVLOG.md),名字叫「断链检查」却对任何 新造的断链恒绿 —— T4-3 归档 plan 当天在 rvh/docs/README.md 造出 2 处真悬挂, 它照样打印「✅ 无常见断链」。现改为调用仓根闸门(模式 B 覆盖 rvh/docs/ 全树), 不在这里造第二个实现

⚠️ 本脚本与 rvh:doc-consistency-check skill 是两套并行实现(skill 内联 9 个检查, 本脚本 6 步,交集只有版本号与词汇库)。skill 是活的路径,本脚本长期没人跑 —— 上面那道假闸门就是这么烂掉的。要不要收敛成一套记在 rvh/docs/plans/backlog.md


📝 使用建议

  • 日常开发:主要使用 build_runner.shview_app_logs.sh
  • 配置验证:新环境使用 check_api_config.sh
  • 数据管理:Supabase 相关操作使用 import_vocabulary_to_supabase.py
  • 数据库调试:使用 sync_database.sh 在设备和电脑间同步数据库
  • 功能测试:使用测试工具验证 OCR 和词汇过滤功能
  • 提交前检查:使用 pre-commit-check.sh 确保代码质量
  • 安装 hooks:使用 install-hooks.sh 配置自动检查

最后更新:2026-02-04