本项目是基于 Java 17 的 Kotlin/Gradle 多模块工程。
apps/android/:Android 客户端,使用 Jetpack Compose 与 Room;apps/android/src/main/java生产代码位置;apps/android/src/test/java单元测试和 Robolectric 测试位置;apps/android/src/main/res资源位置;apps/android/schemas/Room schema 位置。services/backend/:Ktor 后端、PostgreSQL 持久化实现及后端测试。shared/api/:客户端与服务端共享的 Kotlin API 契约。docs/:产品、架构、合规、发布、ADR 与阶段规划文档。
注意:功能代码应放入所属模块;测试目录应镜像生产代码的包路径。各子目录(如 apps/android/、services/backend/、shared/api/ 及 docs/)均包含特定模块的 AGENTS.md 指南文件,在开发相应模块时请同时遵从子模块规范。
在 PowerShell 中使用仓库自带的 Gradle Wrapper:
-
.\gradlew.bat :apps:android:testDebugUnitTest --tests "com.bks.<layer>.<area>.<TestClass>":运行指定 Android JVM、Compose、Room 或 Robolectric 测试;将占位符替换为真实测试类名。 -
.\gradlew.bat :services:backend:test:运行后端单元测试及 Ktor 集成测试。 -
.\gradlew.bat coverageReport:运行三个模块的测试并生成各模块 JaCoCo HTML/XML 覆盖率报告。 -
.\gradlew.bat detekt:运行 Kotlin 静态检查,检查范围由 Gradle 任务配置决定,不保证仅检查暂存文件;专项检查可使用对应模块的 Detekt 任务。快速验证时可用-x detekt跳过,但交付前仍需完成本次适用的检查。 -
.\gradlew.bat :apps:android:assembleDebug:构建调试版 APK。 -
.\gradlew.bat :apps:android:assembleRelease:构建 Release APK;只有本地 keystore 与三项签名凭据齐全时才会生成可分发的已签名产物。 -
.\gradlew.bat :services:backend:run:本地启动后端。 -
.\gradlew.bat build:编译并测试全部模块。 -
.\gradlew.bat --stop:停止 Gradle Daemon。 -
先运行与改动最相关的最窄测试;
-
代码跨模块或影响较大时,在提交前运行完整
build;纯文档、规则或 Skill 文本修改检查格式、引用与指令一致性,不因此运行 Android 全套构建。 -
最终测试或构建完成后,运行
.\gradlew.bat --stop释放 Gradle Daemon。 -
真机账号验收使用本地安全保存的专用测试凭据;不得把账号、密码或其他认证秘密写入仓库、命令输出或验收记录。
指定重构 Step 时只完成该 Step 及其实际适用的 Execution Record/README 更新,不推进后续 Step,也不为吻合旧计划强建类。其他任务只同步实际受影响的现行说明,不自动创建阶段记录。缺少真机或生产条件时,完成可独立推进的实现与本地检查,明确未验证的验收项;不能把这些项标成通过。
- 本地
git commit不触发 CI;推送master才在 GitHub 托管 Runner 上运行完整 CI。 - Termux CD 必须显式创建并推送新的严格语义版本标签,例如
v0.1.1;普通masterpush 不发布 Release,也不部署服务器。 - 发布标签、GitHub prerelease 和已发布资产不得复用或覆盖。创建标签属于发布 操作,必须得到用户明确要求,并先确认目标提交的 CI 已通过。
- 完整发布链、服务器目录、健康检查与回滚步骤见
docs/TERMUX-DEPLOYMENT.md。
- 遵循 Kotlin 官方代码风格(
kotlin.code.style=official),使用四空格缩进; - 类、对象及 Compose 函数使用
PascalCase; - 普通函数和属性使用
camelCase; - 包名使用
com.bks下的全小写名称; - 每个文件应聚焦一个主要职责;
- Android 生产代码只使用
com.bks.model、com.bks.viewmodel、com.bks.view三个顶层包;业务名称位于层级之下,不再使用 feature-first 顶层目录; - 数据持久层通过
LedgerRepository、PreferencesRepository、ReviewQueueRepository等领域接口向上提供能力;Room Entity、DAO 与Local*/Http*实现不得进入 ViewModel 或 View; - Activity 回调与自动记账界面状态由
view.common.platform.BillSyncStateCoordinator托管,组合导航状态由view.common.BksAppState管理; - 优先沿用现有领域接口、application coordinator 与 platform adapter,不为简单问题引入新抽象。重大架构与业务规则变更同步更新
docs/下对应现行基线文档。
- 测试框架为 JUnit 4。Android 测试可使用 Robolectric、Compose UI Test 与 Room Testing;后端测试使用 Ktor Test Host 和 H2;
- 测试文件以
*Test.kt结尾,覆盖本次实际受影响的行为和风险;成功、失败、空值及持久化场景按适用性选择,不要求每次改动重建全套场景。数据库迁移改变 schema 时,必须同步提交更新后的 Room schema JSON。 - 对照验收条件检查界面文本、页面跳转、持久化结果和关键日志,报告实际结果与证据;未经用户明确许可,不修改系统授权、不清除应用数据、不卸载应用,也不执行验收用例之外的真机操作。
- 运行
adb devices -l确认目标真机状态为device,记录序列号(连接多台设备时,以下所有命令都必须使用adb -s <serial> ...指定目标); - 运行
adb -s <serial> shell wm size记录设备逻辑分辨率; - 运行
adb -s <serial> shell dumpsys package com.bks确认已安装版本、权限与包状态符合测试前提;
- 测试开始前,运行
adb -s <serial> logcat -c清空旧日志和运行adb -s <serial> shell am force-stop com.bks重置进程; - 运行
adb -s <serial> shell monkey -p com.bks -c android.intent.category.LAUNCHER 1启动应用。
- 使用
adb -s <serial> shell input tap <x> <y>、swipe、text和keyevent操作界面; - 普通页面的关键状态可运行
adb -s <serial> shell uiautomator dump /sdcard/window.xml与adb -s <serial> shell screencap -p /sdcard/screen.png,再将 XML 和截图拉取到版本库外的本机临时目录作为证据。 - 涉及权限或自动记账无障碍服务时,分别使用
adb -s <serial> shell dumpsys accessibility、dumpsys package com.bks和相关系统服务的dumpsys输出核对真实状态;Xiaomi/MIUI 上验证无障碍服务时禁止使用uiautomator dump,避免测试工具临时重建服务并制造错误状态,此时只使用普通截图和dumpsys。复现后用adb -s <serial> logcat -d获取日志,并在展示或保存前过滤无关内容、脱敏敏感数据。
- 修改与验证不自动授权 Git 提交、推送或发布。用户说“提交吧”授权当前已验证改动的一次本地提交;推送和发布须在用户请求中明确包含,已有授权不重复确认。暂存只选本次文件,保留无关改动。
- 近期提交通常使用简短、祈使语气的标题,并优先采用
feat:、fix:、refactor:、docs:、config:或chore:等前缀。每个提交只包含一个逻辑变更。 - Pull Request 应说明行为变化、列出验证命令并关联对应 issue 或阶段文档。
- Android 界面发生可见变化时附截图;
- 迁移、配置变更及已知后续工作必须明确标注。
- 禁止提交凭据、令牌、签名材料、
local.properties和生产配置; - 不得在终端输出、文档、提交或 PR 中复制其内容。
- 敏感配置应通过环境变量或本地 Gradle 属性提供;
- 输出日志前先脱敏,并保留后端现有的密钥扫描测试;
- Android Release 签名使用
apps/android/release.jks与根目录local.properties中的RELEASE_STORE_PASSWORD、RELEASE_KEY_ALIAS、RELEASE_KEY_PASSWORD。这些文件和值仅限本机使用,均已被 Git 忽略; - 修改本地签名配置后,以
:apps:android:assembleRelease构建,并用apksigner verify --verbose校验生成的 APK。