一、背景
公司开始推行AI First,以后所有代码都尽量让AI编写。趋势使然。那么之前培训的代码规范,现在只能告诉AI了,让它在写代码的,遵守我们的代码规范。
公司项目较多,每一个项目又有iOS、Android、flutter。所以采用二层结构:
docs/standards/IOS_DEVELOPMENT.md:通用内容。
qiji/AGENTS.md:qiji 专属内容。
编写好一个项目的规范后,其他项目直接复用。(这个明确的过程,由AI编写吧)
二、iOS 代码规范
生成此规范的时候,让AI参考了官方和大厂的规范,同时将公司的代码规范和历史风格为主。
docs/standards/IOS_DEVELOPMENT.md的内容为:
markdown
# qiji iOS 项目规范
开始任何代码修改、重构或评审前,必须先阅读并遵守 [iOS 通用开发规范](docs/standards/IOS_DEVELOPMENT.md)。
本文件只定义 qiji iOS 的项目补充规则,适用于本目录及所有子目录。开发者、AI 编程工具和自动化脚本均须遵守。
## 规则关系
- 通用规范是默认基线,本文件可以根据 qiji 项目实际情况补充或收紧规则。
- 本文件与通用规范冲突时,只有明确写出原因和适用范围的项目规则才可覆盖通用规范。
- 子目录可以通过更具体的 `AGENTS.md` 补充或收紧规则;需要放宽强制要求时,必须由模块负责人确认。
## 项目范围
- 默认只修改 `qiji/` 和 `QeekLive/` 中的自有源码。
- 禁止修改或格式化 `Pods/`、`qiji/External/`、`TencentCloudHuiyanSDKFace_framework/`、`.framework`、`.xcframework` 及其他生成或第三方代码,除非需求明确要求并经过评审。
- 修改工程配置时,只调整与当前需求相关的 target、build configuration 和文件引用,禁止无关的 `.pbxproj` 排序或重写。
## 项目技术约定
- Swift 代码必须兼容项目当前的 Swift 5.0 设置;新增 API 同时兼容其所属 target 的 Deployment Target。
- Objective-C 业务类型优先沿用所在模块已有的 `HXQ`、`HXS` 等命名前缀。
- Objective-C 实现方法的左大括号单独一行,指针星号靠近变量名。
- 新增异步代码必须沿用所在模块现有的回调、Promise 或 async/await 模式,不在单个需求中混用架构。
- Objective-C 调用 Swift 时必须核对实际生成的 `-Swift.h` 名称、Bridging Header 和所有相关调用方。
## 网络与数据
- 新增或修改接口必须复用项目现有网络层,并保留既有的鉴权、签名、加密、解密、错误映射和日志处理。
- 安全请求相关逻辑应集中在现有 Swift 网络与安全组件中,Objective-C 兼容层保持轻量,禁止在业务页面重复实现协议细节。
- 修改请求或响应模型、加密信封、序列化字段及缓存结构时,必须检查 Objective-C 和 Swift 两侧的调用与兼容性。
- Multipart 请求应区分业务字段与文件数据,禁止未经协议确认改变既有加密范围。
## 本地化与日志
- Objective-C 优先沿用项目现有的 `LS(...)` 等本地化入口;Swift 沿用所在模块已有封装。
- 不得为了单个需求新建另一套本地化机制。
- 调试日志使用项目现有日志方法;Release 环境不得新增无条件输出的 `print`、`NSLog` 或等效日志。
- 网络日志禁止输出 Token、Cookie、完整请求头、未脱敏参数、加密密钥或解密后的敏感响应。
## 依赖与格式化
- 项目依赖变更必须同时检查 `Podfile`、`Podfile.lock`、Swift Package 配置、workspace 和相关 target 链接。
- Flutter add-to-app、CocoaPods 与 Swift Package 的现有集成边界不得在无关需求中调整。
- 当前仓库未统一引入 SwiftFormat、SwiftLint 或 clang-format,不得假设这些工具可用,也不得为了单个需求擅自引入。
- 在统一工具落地前,只格式化本次实际修改的代码,并保持相邻代码风格。
- 仓库中的 Dart 格式化命令只适用于 Dart 文件,不得用于 Swift 或 Objective-C 文件。
## 编译与验收
- 修改 Swift 或 Objective-C 源码后,至少编译受影响的 target 或 scheme。
- 当前主工程使用 `qiji.xcworkspace` 和 `qiji` scheme;命令行可根据改动使用:
```bash
xcodebuild \
-workspace qiji.xcworkspace \
-scheme qiji \
-configuration Debug \
-sdk iphonesimulator \
CODE_SIGNING_ALLOWED=NO \
build
```
- 修改 workspace、依赖、脚本或多 target 共享代码时,还必须验证相应 configuration 和受影响 target。
- 因签名、依赖、模拟器或环境问题无法完成编译时,必须报告第一条真实错误、未验证项和已完成的替代检查,不得将静态检查描述为编译成功。
AGENTS.md的内容为:
markdown
# qiji iOS 项目规范
开始任何代码修改、重构或评审前,必须先阅读并遵守 [iOS 通用开发规范](docs/standards/IOS_DEVELOPMENT.md)。
本文件只定义 qiji iOS 的项目补充规则,适用于本目录及所有子目录。开发者、AI 编程工具和自动化脚本均须遵守。
## 规则关系
- 通用规范是默认基线,本文件可以根据 qiji 项目实际情况补充或收紧规则。
- 本文件与通用规范冲突时,只有明确写出原因和适用范围的项目规则才可覆盖通用规范。
- 子目录可以通过更具体的 `AGENTS.md` 补充或收紧规则;需要放宽强制要求时,必须由模块负责人确认。
## 项目范围
- 默认只修改 `qiji/` 和 `QeekLive/` 中的自有源码。
- 禁止修改或格式化 `Pods/`、`qiji/External/`、`TencentCloudHuiyanSDKFace_framework/`、`.framework`、`.xcframework` 及其他生成或第三方代码,除非需求明确要求并经过评审。
- 修改工程配置时,只调整与当前需求相关的 target、build configuration 和文件引用,禁止无关的 `.pbxproj` 排序或重写。
## 项目技术约定
- Swift 代码必须兼容项目当前的 Swift 5.0 设置;新增 API 同时兼容其所属 target 的 Deployment Target。
- Objective-C 业务类型优先沿用所在模块已有的 `HXQ`、`HXS` 等命名前缀。
- Objective-C 实现方法的左大括号单独一行,指针星号靠近变量名。
- 新增异步代码必须沿用所在模块现有的回调、Promise 或 async/await 模式,不在单个需求中混用架构。
- Objective-C 调用 Swift 时必须核对实际生成的 `-Swift.h` 名称、Bridging Header 和所有相关调用方。
## 网络与数据
- 新增或修改接口必须复用项目现有网络层,并保留既有的鉴权、签名、加密、解密、错误映射和日志处理。
- 安全请求相关逻辑应集中在现有 Swift 网络与安全组件中,Objective-C 兼容层保持轻量,禁止在业务页面重复实现协议细节。
- 修改请求或响应模型、加密信封、序列化字段及缓存结构时,必须检查 Objective-C 和 Swift 两侧的调用与兼容性。
- Multipart 请求应区分业务字段与文件数据,禁止未经协议确认改变既有加密范围。
## 本地化与日志
- Objective-C 优先沿用项目现有的 `LS(...)` 等本地化入口;Swift 沿用所在模块已有封装。
- 不得为了单个需求新建另一套本地化机制。
- 调试日志使用项目现有日志方法;Release 环境不得新增无条件输出的 `print`、`NSLog` 或等效日志。
- 网络日志禁止输出 Token、Cookie、完整请求头、未脱敏参数、加密密钥或解密后的敏感响应。
## 依赖与格式化
- 项目依赖变更必须同时检查 `Podfile`、`Podfile.lock`、Swift Package 配置、workspace 和相关 target 链接。
- Flutter add-to-app、CocoaPods 与 Swift Package 的现有集成边界不得在无关需求中调整。
- 当前仓库未统一引入 SwiftFormat、SwiftLint 或 clang-format,不得假设这些工具可用,也不得为了单个需求擅自引入。
- 在统一工具落地前,只格式化本次实际修改的代码,并保持相邻代码风格。
- 仓库中的 Dart 格式化命令只适用于 Dart 文件,不得用于 Swift 或 Objective-C 文件。
## 编译与验收
- 修改 Swift 或 Objective-C 源码后,至少编译受影响的 target 或 scheme。
- 当前主工程使用 `qiji.xcworkspace` 和 `qiji` scheme;命令行可根据改动使用:
```bash
xcodebuild \
-workspace qiji.xcworkspace \
-scheme qiji \
-configuration Debug \
-sdk iphonesimulator \
CODE_SIGNING_ALLOWED=NO \
build
```
- 修改 workspace、依赖、脚本或多 target 共享代码时,还必须验证相应 configuration 和受影响 target。
- 因签名、依赖、模拟器或环境问题无法完成编译时,必须报告第一条真实错误、未验证项和已完成的替代检查,不得将静态检查描述为编译成功。
三、 Android 代码规范
docs/standards/IOS_DEVELOPMENT.md的内容为:
markdown
# Android 通用开发规范
本规范适用于公司 Android 项目,由开发者、AI 编程工具和自动化脚本共同遵守。各项目通过项目根目录或源码目录中的 `AGENTS.md` 补充目录边界、模块架构、技术栈、构建变体、验证命令和检查工具等项目特有规则。
历史代码不要求一次性整改,但不得在新代码和实际修改的代码中继续扩大已有问题。
## 规则等级与冲突处理
- "必须"或"禁止"表示强制要求,违反时不得合并。
- "应当"或"优先"表示默认要求;确需偏离时,必须在代码评审中说明原因和影响。
- "建议"表示推荐实践,可根据具体场景决定。
- 项目规范可以补充或收紧本规范;需要放宽强制要求时,必须说明原因、影响范围和替代措施,并由模块负责人确认。
- 业务需求不能直接覆盖本规范中的强制要求。
- 本规范与历史代码风格冲突时,新增和实际修改的代码以本规范为准;未涉及的历史代码保持不变。
## 通用原则
- 只修改当前需求涉及的代码,不顺手格式化、重构或修复无关历史代码。
- 修改前必须阅读目标文件、相邻同类文件和相关调用方,复用项目现有基类、组件、网络层、路由和命名方式。
- 使用 4 个空格缩进,不使用 Tab;建议每行不超过 120 个字符,长 URL、不可拆分标识符和与既有声明保持一致等情况可以例外。
- 类型、方法和变量使用能够表达业务含义的英文名称,避免无意义缩写、拼音和含糊的通用名称。
- 一个方法应当只承担一个职责;优先提前返回,避免过深嵌套和过长方法。
- 不新增无必要的第三方依赖,不改变与当前需求无关的公共 API 或行为。
- 新增公共类型、公共方法或复杂业务逻辑时,使用简洁注释说明用途、边界或原因,不重复描述代码本身。
- 不生成占位实现、伪代码、未使用变量、无调用路径的 helper 或仅为将来可能使用而创建的抽象。
- 不通过新增 lint ignore、扩大警告抑制范围、降低检查等级或不安全转换绕过问题。
- 不对旧文件执行全文件格式化,只保证新增和实际修改的代码符合规范。
## 语言选择
- 修改已有代码时保持文件原有语言,不因局部修改在 Java 和 Kotlin 之间转换。
- 新增 Android 类优先使用 Kotlin;与现有 Java 模块或 Java API 紧密相关的小范围功能可以保持 Java。
- 未经明确要求和专项评审,不进行 Java 到 Kotlin 的整体迁移。
- 新代码必须兼容所属模块当前配置的 Java、Kotlin、Android Gradle Plugin 和 Android API 版本,不得仅依据本机工具版本使用新语法或 API。
## Java 规范
- 命名、声明和文件组织参考 Google Java Style Guide;缩进以本规范统一的 4 空格为准。
- 类和接口使用 `UpperCamelCase`;方法、字段和局部变量使用 `lowerCamelCase`;常量使用 `UPPER_SNAKE_CASE`。
- 每个文件通常只定义一个顶级类型,文件名与主要类型名一致。
- 默认使用满足需求的最小可见性;仅在确有跨类型或跨模块访问需求时放宽。
- 局部变量在不会重新赋值时优先声明为 `final`,但不为机械满足形式而降低可读性。
- 必须明确处理可空值,禁止通过捕获 `NullPointerException` 或延迟崩溃掩盖数据契约问题。
- 使用 try-with-resources 可靠关闭流、Cursor、ResponseBody 和其他 `AutoCloseable` 资源。
- 禁止新增 `AsyncTask`;后台任务使用项目现有异步框架、ExecutorService 或其他具有明确生命周期的方案。
- 匿名内部类、Listener、Runnable 和回调不得无意长期持有 Activity、Fragment 或 View。
- 覆盖父类或接口方法时必须添加 `@Override`;删除未使用的 import、字段和方法。
## Kotlin 规范
- 遵循 Kotlin 官方 Coding Conventions,并使用 4 个空格缩进。
- 类和接口使用 `UpperCamelCase`;函数、属性、局部变量和参数使用 `lowerCamelCase`;常量使用 `UPPER_SNAKE_CASE`。
- 优先使用不可变的 `val` 和只读集合;只有值或集合确实需要变化时才使用 `var` 或可变集合。
- 使用满足需求的最小可见性,私有实现优先声明为 `private`。
- 禁止新增无法证明安全的 `!!` 和不安全类型转换。平台类型、系统入口或框架约定确需使用时,必须确保生命周期和类型安全。
- 可失败操作使用明确的可空值、异常、`Result` 或项目既有错误模型表达,禁止静默吞掉异常。
- 合理使用扩展函数,禁止将有状态业务逻辑或与接收者弱相关的能力包装成全局扩展。
- 协程优先采用结构化并发;禁止使用 `GlobalScope` 承载业务任务。
- UI 和生命周期相关协程必须绑定合适的 `lifecycleScope`、`viewLifecycleOwner.lifecycleScope`、`viewModelScope` 或受控业务 Scope。
- 捕获对象前必须判断所有权和生命周期,避免协程、lambda、Flow 收集器或回调造成泄漏。
## Android 组件与生命周期
- Activity、Fragment、View、Dialog、Service 和 Receiver 必须遵守各自生命周期,不得在组件失效后继续无条件更新 UI 或访问资源。
- Fragment 的 View 引用必须在 `onDestroyView()` 释放;不得让 View 生命周期对象存活到 Fragment 生命周期结束。
- Listener、Callback、BroadcastReceiver、ContentObserver、Handler 消息、Runnable、Timer、Animator、RxJava Disposable、协程、Flow 收集和网络请求必须在适当生命周期注销或取消。
- 单例、静态字段和长生命周期对象禁止持有 Activity、Fragment、View 或其他短生命周期 Context;只在确有必要时持有 Application Context。
- UI 状态只在主线程更新;网络、数据库、文件、图片处理和其他耗时操作不得阻塞主线程。
- 异步流程必须明确成功、失败和取消路径,避免重复回调、遗漏回调、竞态条件及页面销毁后的状态回写。
- 保存和恢复页面状态时,必须考虑进程重建、配置变更、重复导航和 Intent 重放,不能只依赖内存单例。
- Service、前台服务、后台任务和通知必须符合目标 Android 版本的启动、权限、时限和用户可见性要求。
## 架构与状态管理
- 优先沿用当前模块的架构和数据流,不为单个需求引入新的架构体系。
- Activity、Fragment 和自定义 View 负责展示与用户交互,不应承载可复用的底层网络、持久化或协议实现。
- 单一状态应有明确可信来源,避免页面、单例、缓存和服务端数据各自维护且缺少同步规则。
- 修改公共 DTO、领域模型、Repository、Provider、ViewModel 或缓存结构时,必须检查全部调用方和兼容性。
- 事件、回调和观察流必须定义线程、调用次数、失败语义和生命周期;禁止依赖调用方猜测隐含约定。
- 页面跳转和业务流程必须保留现有鉴权、状态检查、路由拦截和防重复触发机制。
## 网络、存储与错误处理
- 新增接口必须沿用项目统一网络层以及既有的鉴权、签名、加密、错误映射和日志机制,不在页面中自行实现底层请求。
- 服务端字段的类型和可空性必须按实际协议建模,禁止依赖强制转换或默认值掩盖字段缺失和类型错误。
- 不得静默忽略网络、解析、解密、缓存、数据库或文件错误。无法向上抛出时,必须记录可诊断且不包含敏感信息的日志,并提供明确失败状态。
- 修改序列化字段、数据库表、SharedPreferences/DataStore key、文件格式或缓存结构时,必须评估升级、降级和新旧版本兼容性。
- 网络响应、Cursor、文件流和其他资源必须可靠关闭;文件下载应先写入临时文件,校验成功后再原子替换目标文件。
- 重试必须设置明确条件和次数上限,并考虑幂等性、退避、取消和重复提交风险。
- Intent、Bundle 和 Binder 只传递必要数据,避免超过系统事务大小限制;大对象使用持久化、缓存或稳定标识传递。
## UI、资源与无障碍
- 用户可见文案必须使用项目现有本地化机制,禁止在 Java、Kotlin、布局或 Compose 中新增硬编码业务文案。
- 带参数文案使用格式化资源,禁止通过字符串拼接改变不同语言的语序;复数、日期、数字和单位按本地化规则处理。
- 资源名称使用项目约定的模块或功能前缀,命名应表达用途而不是具体视觉值;新增前先搜索可复用资源。
- 布局应适配系统栏、安全区域、字体缩放和常见屏幕尺寸,避免依赖固定设备尺寸或不必要的绝对定位。
- 颜色、字号、间距和组件优先复用项目主题与设计系统,不在业务页面散落重复常量。
- 图片资源应选择合适格式和密度,避免提交无必要的大图、重复资源或未经压缩的资产。
- 可点击控件必须具备合理点击区域和状态反馈;图片按钮、关键状态和错误提示应提供必要的无障碍语义。
- 使用 ViewBinding、DataBinding 或 Compose 时遵循项目现有方案,不为单个页面引入另一套 UI 技术。
## 系统兼容性与权限
- 使用新 Android API 时,必须结合模块 `minSdk` 和 `targetSdk` 添加版本判断或兼容实现,不得只在当前测试设备验证。
- 新增或修改权限时遵循最小权限原则,并同步检查 Manifest、运行时授权、拒绝与永久拒绝路径以及用户说明。
- 修改定位、相机、蓝牙、存储、通知、后台运行或精确闹钟等能力时,必须检查目标 Android 版本的行为变化。
- 导出的 Activity、Service、Receiver 和 Provider 必须显式评估 `android:exported`、权限保护、Intent 输入校验和外部调用风险。
- PendingIntent 必须根据用途设置正确的可变性和唯一性;不得接受或转发未经验证的外部 Intent 数据。
- WebView 应限制不必要的文件访问、混合内容和 JavaScript 能力;JavascriptInterface、Deep Link 和 URL 跳转必须校验来源与参数。
## 安全、隐私与日志
- 禁止在日志中输出 Token、Cookie、手机号、身份证信息、精确位置、支付信息、完整请求头、密钥或其他敏感数据。
- 调试日志使用项目统一日志工具;Release 环境不得新增无条件输出的 `Log`、`println` 或等效调试日志。
- 禁止将密钥、私钥、签名密码、访问令牌或真实服务凭据提交到仓库。发现疑似凭据时必须停止传播并通知负责人进行轮换。
- 敏感数据必须使用符合项目安全要求的存储方式,禁止以明文 SharedPreferences、数据库或普通文件保存凭据和高敏感信息。
- 新增系统权限、隐私数据采集、埋点或第三方 SDK 时,必须评估数据最小化、用户授权、隐私政策、初始化时机和合规要求。
- 组件、WebView、文件、URI 和 IPC 输入必须按不可信数据处理,校验类型、长度、范围、来源和路径,防止越权、注入与路径穿越。
## 第三方依赖、生成代码与构建配置
- 引入或升级依赖前,必须评估维护状态、许可证、包体积、最低系统版本、隐私影响、传递依赖、安全风险和现有依赖冲突。
- 依赖、Gradle 插件、仓库源和构建工具变更必须在代码评审中单独说明原因和影响。
- 生成代码和资源必须通过对应工具更新,禁止直接手工修改;构建产物、本机配置和 IDE 私有文件不得提交。
- 修改 Gson/Moshi/Serializable/Parcelable 模型、反射、JNI 或动态加载逻辑时,必须检查混淆、压缩和 Release 构建兼容性。
- 禁止通过关闭 R8、资源压缩、Lint、编译警告或扩大 keep/ignore 范围掩盖问题。
- 格式化和静态检查必须使用项目已提交的版本与配置,不得假设未配置的工具可用,也不得为单个需求擅自引入。
## 测试、编译与验收
- 所有改动必须检查 `git diff`,确认没有无关修改、意外格式化、调试代码、生成产物或敏感信息。
- 修改 Java 或 Kotlin 源码后,至少编译受影响模块和 variant;具体命令由项目规范定义。
- 修复缺陷时必须验证原问题路径,并至少覆盖一个相关失败路径、边界条件或生命周期场景。
- 修改公共组件、网络层、存储层、路由、跨进程或跨语言接口时,必须检查相关调用方;有对应测试时必须运行相关测试。
- 修改资源、Manifest、构建脚本、渠道配置或混淆规则时,必须运行能够实际处理该改动的构建任务,不能只做源码编译。
- 不得新增编译或静态检查警告。历史警告不得因本次修改增加,也不得通过扩大抑制范围隐藏。
- 因签名、依赖、设备、相邻工程或本地环境问题无法完成验证时,必须报告第一条真实错误、未验证项和已完成的替代检查,不得将静态检查描述为编译成功。
## Git 提交与代码评审
- 一个提交应当聚焦一个逻辑目的,不混入无关格式化、资源变化、依赖升级、工程配置重排或临时调试代码。
- 修改依赖、权限、路由、公共 API、数据结构、持久化格式、渠道配置或混淆规则时,必须在评审中明确标注。
- 合并请求应当说明改动目的、影响范围、验证结果、兼容性和已知风险;涉及 UI 时应提供必要截图或录屏。
- 禁止通过关闭警告、降低检查等级、跳过必要验证或扩大忽略范围使检查通过。
- 提交前必须确认未覆盖工作区中他人的未提交改动,且提交内容仅包含当前任务相关文件。
## AI 编程工具附加要求
- 开始修改前必须读取项目 `AGENTS.md` 及其引用的规范,并检查工作区已有未提交改动。
- 修改前先搜索真实入口、调用方和既有实现,不得仅凭文件名或局部代码推断完整行为。
- 只能生成能够接入现有调用路径的完整实现,不得留下占位实现、伪代码或仅为将来可能使用的抽象。
- 不得自行扩大需求范围;发现无关问题时可以报告,但未经明确要求不得顺手修改。
- 对危险、不可逆、影响发布或需要新增权限的操作,必须先明确目标、影响和回滚方式,并按团队授权流程执行。
- 完成后必须报告实际修改文件、验证命令和结果;未执行或未通过的检查必须如实说明。
- 需求与规范冲突时不得自行忽略,应指出冲突并请求负责人确认。
AGENTS.md的内容为:
markdown
# qiji Android 项目规范
开始任何代码修改、重构或评审前,必须先阅读并遵守 [Android 通用开发规范](docs/standards/ANDROID_DEVELOPMENT.md)。
本文件只定义 qiji Android 的项目补充规则,适用于本目录及所有子目录。开发者、AI 编程工具和自动化脚本均须遵守。
## 规则关系
- Android 通用开发规范是默认基线,本文件可以根据 qiji 项目实际情况补充或收紧规则。
- 本文件与通用规范冲突时,只有明确写出原因和适用范围的项目规则才可覆盖通用规范。
- 子目录可以通过更具体的 `AGENTS.md` 补充或收紧规则;需要放宽强制要求时,必须说明原因、影响范围和替代措施,并由模块负责人确认。
- 历史代码不要求一次性整改;新增和实际修改的代码必须遵守当前规范,未涉及的历史代码保持不变。
## 项目范围
- 自有业务和基础模块包括 `app`、`base`、`library`、`util`、`map`、`account` 和 `pay`。
- `UdeskSDKUI` 按集成 SDK 模块管理。需求未明确涉及该模块时,禁止修改或格式化其源码;确需修改时,必须说明原因、升级兼容性和后续维护方式。
- 禁止修改或提交 `build/`、`.gradle/`、`.idea/`、Flutter 生成目录及其他构建产物或本地环境文件。
- 修改 Gradle、Manifest、资源、混淆、签名或渠道配置时,只调整当前需求涉及的配置,不得顺带升级插件、依赖或重排无关内容。
- 不得在仓库中提交 `local.properties`、签名文件、账号密码、访问令牌或其他真实凭据。
## 模块与依赖
- 修改前必须确认代码所属模块、上游调用方和下游依赖,优先复用模块现有的基类、组件、路由、网络层和数据模型。
- 公共能力应放在职责匹配的现有模块中,不得为了方便造成业务模块之间的反向依赖或循环依赖。
- 修改 `base`、`library` 或 `util` 等公共模块的 API 时,必须搜索并检查所有调用方,避免只验证当前页面。
- 未经明确需求,不得移动公共类型、扩大 API 可见性或改变既有接口语义。
## 项目技术约定
- 保持目标文件原有语言,不因局部修改在 Java 和 Kotlin 之间转换;新增 Android 类优先使用 Kotlin,与现有 Java 模块紧密相关的小范围功能优先保持 Java。
- 当前 Android 代码使用 Java 17 工具链;新增代码和依赖必须兼容项目当前的 Gradle、Android Gradle Plugin、`compileSdk`、`minSdk` 和 `targetSdk` 配置。
- 异步实现优先沿用所在模块的现有方案。Kotlin 新代码优先使用绑定生命周期的结构化协程;Java 代码沿用项目已有的 RxJava、ExecutorService 或回调体系,不在单个需求中混用或整体迁移异步架构。
- 页面跳转、登录检查、用户状态检查和业务拦截必须复用现有入口,禁止绕过前置条件直接启动目标页面。
- 修改跨模块事件、广播、路由或回调协议时,必须检查注册、触发、消费和释放的完整调用链。
## Flutter add-to-app
- 本工程通过 `settings.gradle` 引用相邻的 `../../Flutter/qiji_flutter/.android/include_flutter.groovy`,Android 构建依赖对应 Flutter 工程和其生成配置。
- 修改 MethodChannel/EventChannel 的名称、方法名、参数、返回值、错误码或线程语义时,必须同时检查 Android 与 Dart 两端;禁止只修改单侧协议。
- FlutterEngine、FlutterEngineGroup、FlutterActivity、FlutterFragment、插件注册和渲染模式必须沿用项目现有生命周期与集成方式,不得在单个页面另建不兼容的初始化流程。
- Native 与 Flutter 共享的用户、语言、定位、支付或页面数据必须保持单一可信来源,避免两端分别缓存后产生状态不一致。
- 如果因相邻 Flutter 工程缺失、生成产物不完整或 Flutter 环境异常导致无法构建,必须报告第一条真实错误、环境依赖和已完成的替代检查,不得归因成 Android 源码编译失败。
## 网络、数据与安全
- 新增或修改接口必须复用项目现有网络层,并保留既有的鉴权、签名、RSA、加密、解密、错误映射、重试和日志处理。
- 安全请求相关逻辑应集中在现有网络与安全组件中,禁止在 Activity、Fragment 或业务 Presenter 中重复实现协议细节。
- 修改请求或响应 DTO、Gson 字段名、加密信封、缓存结构或持久化格式时,必须检查序列化、混淆以及新旧版本兼容性。
- 读取 OkHttp `ResponseBody` 后,如响应仍需向下游传递,必须使用读取后的内容重建响应体,禁止传递已经消费的响应体。
- 修改 token 失效、密钥刷新、重试或并发请求逻辑时,必须检查重复刷新、重复回调、请求风暴和无限重试风险。
- 日志禁止输出 Token、Cookie、签名、密钥、完整请求头、手机号、身份证信息、精确位置、支付信息或解密后的敏感响应。
## 本地化与用户文案
- 用户可见文案必须使用项目现有 Android 资源和本地化入口,禁止在业务代码或布局中新增硬编码文案。
- 带参数文案使用格式化字符串资源,禁止通过字符串拼接改变不同语言的语序;日期、数字和单位按本地化规则处理。
- Native 与 Flutter 必须使用同一语言来源。修改语言选择、持久化或同步协议时,必须检查 Android Application/Activity 配置更新及 Flutter 同步链路。
- qiji 当前产品规则为默认跟随系统:简体中文使用中文,其他系统语言使用英文;仅保存设备本地设置。未经产品需求确认,不得扩展为服务端、H5、协议或推送语言策略。
- 迁移既有业务文案时保持语义、占位符、标点和拼接关系不变;发现疑似错字或历史不一致时先单独说明,不得顺手改写业务含义。
## 资源、Manifest 与渠道
- 资源名称沿用模块现有前缀和命名方式,新增资源前必须搜索是否已有可复用资源。
- 修改布局、Drawable、颜色、样式或主题时,检查对应状态、深色模式、字体缩放、系统栏、安全区域和基本无障碍表现。
- 修改 Manifest 组件、权限、Deep Link、Provider 或 `android:exported` 时,必须评估系统版本兼容性和安全边界。
- `app` 包含 `customer`、`myapp`、`wandoujia`、`xiaomi`、`huawei`、`vivo`、`oppo` 和 `honor` 等渠道。修改渠道资源、Manifest placeholder 或打包逻辑时,必须验证实际受影响的 flavor。
- 当前 Debug/Profile 构建使用项目配置的签名信息。不得将本地签名配置写入仓库;因签名变量缺失无法构建时,应明确报告为环境配置问题。
## 依赖与混淆
- 不随意增加第三方依赖。引入或升级依赖前,必须评估维护状态、许可证、包体积、最低系统版本、隐私影响、传递依赖和与现有 SDK 的冲突。
- 依赖版本、仓库地址、Flutter 集成或 Gradle 插件变更必须单独说明原因和影响,不得混入无关业务修改。
- 修改反射、Gson 模型、JNI、WebView JavaScript 接口、Flutter 桥接或 SDK 回调类型时,必须检查 R8/ProGuard 配置及 Release 构建兼容性。
- 禁止通过大范围 `-keep`、关闭压缩混淆或扩大 warning ignore 来掩盖 Release 问题。
## 编译与验收
- 修改 Java/Kotlin 源码后,至少编译受影响模块的对应 variant;同时包含 Java 和 Kotlin 时,两类编译链路都必须被实际构建覆盖。
- 修改 `base` 模块 Java/Kotlin 代码后,至少运行:
```bash
./gradlew :base:compileDebugJavaWithJavac
```
- 修改 App、跨模块公共代码或无法用单模块编译覆盖的内容时,默认以主开发渠道执行:
```bash
./gradlew :app:assembleCustomerDebug
```
- 修改特定模块时,应根据实际存在的任务选择该模块的 `compileDebugJavaWithJavac`、`compileDebugKotlin`、`testDebugUnitTest`、`lintDebug` 或资源合并任务;不确定任务名称时先通过 Gradle tasks 查询,禁止把不存在的任务写成验证成功。
- 修改渠道资源、Manifest、签名或打包逻辑时,验证实际受影响的 flavor/buildType;修改混淆、序列化、反射、JNI 或发布逻辑时,必须补充受影响 Release variant 的验证。
- 修复缺陷时,必须验证原问题路径,并至少覆盖一个相关失败路径或边界条件;存在自动化测试时必须运行相关测试。
- 所有修改提交前必须运行:
```bash
git diff --check
```
- 如果编译或测试失败,必须提供第一条真实错误及其上下文,并区分代码错误、既有失败和本地环境问题;同时列出未验证项和已完成的替代检查,不得把静态检查描述为编译成功。
四、 Dart代码规范
docs/standards/IOS_DEVELOPMENT.md的内容为:
markdown
# Dart / Flutter 通用开发规范
本规范适用于公司 Dart / Flutter 项目,由开发者、AI 编程工具和自动化脚本共同遵守。各项目通过项目根目录或源码目录中的 `AGENTS.md` 补充目录边界、业务架构、状态管理、平台集成、SDK 版本、验证命令和检查工具等项目特有规则。
历史代码不要求一次性整改,但不得在新增和实际修改的代码中继续扩大已有问题。
## 规则等级与冲突处理
- "必须"或"禁止"表示强制要求,违反时不得合并。
- "应当"或"优先"表示默认要求;确需偏离时,必须在代码评审中说明原因和影响。
- "建议"表示推荐实践,可根据具体场景决定。
- 项目规范可以补充或收紧本规范;需要放宽强制要求时,必须说明原因、影响范围和替代措施,并由模块负责人确认。
- 业务需求不能直接覆盖本规范中的强制要求。
- 本规范与历史代码风格冲突时,新增和实际修改的代码以本规范为准;未涉及的历史代码保持不变。
## 通用原则
- 只修改当前需求涉及的代码,不顺手格式化、重构或修复无关历史代码。
- 修改前必须阅读目标文件、相邻同类文件和相关调用方,复用项目现有组件、状态管理、网络层、路由和命名方式。
- Dart 文件使用 UTF-8、LF 和 2 个空格缩进,不使用 Tab;行宽由项目 formatter 配置决定。
- 类型、方法和变量使用能够表达业务含义的英文名称,避免无意义缩写、拼音和含糊的通用名称。
- 一个方法应当只承担一个职责;优先提前返回,避免过深嵌套和过长方法。
- 不新增无必要的第三方依赖,不改变与当前需求无关的公共 API 或行为。
- 不生成占位实现、伪代码、未使用成员、无调用路径的 helper 或仅为将来可能使用而创建的抽象。
- 不通过新增 lint ignore、扩大排除范围、降低检查等级、不安全转换或非空断言绕过问题。
## 命名、文件与 API
- 文件、目录和库使用 `lower_snake_case`;类型、扩展和枚举使用 `UpperCamelCase`;变量、方法和参数使用 `lowerCamelCase`。
- 私有成员以单个下划线开头;未使用的回调参数使用 `_`,不得用连续下划线制造无意义名称。
- 布尔值使用表达判断的问题式命名,例如 `isLoading`、`hasPermission`、`canSubmit`。
- 一个文件聚焦一个主要职责;每个文件通常只声明一个主要公开类型,文件名应与主要职责一致。
- 公共 API 必须显式声明返回类型,并使用简洁的 `///` 文档注释说明用途、边界或非显然约束。
- 默认使用满足需求的最小可见性;未经明确需求,不得扩大公共 API、改变参数语义或破坏调用兼容性。
## Dart 语言约定
- 优先使用不可变数据:能用 `final`、`const` 和只读集合时必须使用;确需改变状态时才使用 `var` 或可变集合。
- 局部变量在类型清晰时使用类型推断;公共边界、复杂泛型和容易误解的值应显式声明类型。
- 避免 `dynamic`、强制类型转换和非空断言;必须使用时,应能从相邻代码或协议约束证明类型与空安全。
- Future 必须被 `await`、返回给调用方,或通过明确方式标注为有意不等待;不得静默丢弃可能失败的异步任务。
- 只捕获能够处理或补充上下文的异常;禁止空 `catch`。重新抛出当前异常时使用 `rethrow`,不得丢失原始堆栈。
- 集合转换应保持输入、输出及空数据语义清晰,避免在一条表达式中混合解析、副作用和业务判断。
- 有业务含义的数值、时长、字符串和状态必须使用具名常量、值对象或枚举,避免魔法值。
- 注释解释"为什么"和约束条件,不重复描述代码本身;过期注释必须随代码一并更新或删除。
## Flutter UI 与生命周期
- `build` 方法只负责声明 UI,不得在其中发起网络请求、写存储、注册监听或执行其他副作用。
- Widget 构造器和静态子树能声明为 `const` 时应使用 `const`,但不得为了形式牺牲清晰度。
- 异步间隙后使用 `BuildContext` 或更新 State 前必须检查生命周期,例如 `if (!context.mounted) return;`。
- `AnimationController`、`TextEditingController`、`FocusNode`、`ScrollController`、`StreamSubscription`、Timer 和监听器必须在对应生命周期释放。
- 列表数据较多或动态增长时使用 builder;可重排或需要保持状态的节点必须提供稳定且业务唯一的 Key。
- 页面负责展示与交互编排;可复用业务逻辑放入项目既有状态或领域层,不在多个页面复制请求、缓存和解析逻辑。
- 状态更新保持最小范围,避免一次更新混合不相关状态或造成无必要的整页重建。
- UI 必须考虑安全区域、键盘、字体缩放、横竖屏和常见屏幕尺寸;关键控件应具备合理点击区域、状态反馈和无障碍语义。
## 状态管理与架构
- 沿用项目既有架构和数据流,不为单个需求引入另一套状态管理、依赖注入或路由体系。
- 单一状态应有明确可信来源,避免页面、Provider、单例、缓存和 Native 各自维护且缺少同步规则。
- 状态对象必须明确加载、成功、空数据、失败、刷新和销毁语义,避免用多个互相矛盾的布尔值表达同一状态。
- 修改公共模型、Repository、Provider、Service 或缓存结构时,必须搜索所有调用方并检查兼容性。
- 事件、回调和观察流必须定义调用次数、失败、取消及生命周期语义,不得依赖调用方猜测隐含约定。
- 页面导航必须保留现有鉴权、状态检查、路由拦截和防重复触发机制。
## 异步、并发与错误处理
- 异步流程必须明确成功、失败和取消路径,避免重复提交、重复回调、竞态条件及页面销毁后的状态回写。
- 并发请求必须明确覆盖、合并、排队或取消策略;不得让过期响应覆盖较新的页面或业务状态。
- 重试必须设置明确条件和次数上限,并考虑幂等性、退避、取消和重复副作用。
- 不得静默忽略网络、解析、解密、缓存、数据库或文件错误。无法向上传递时,必须记录不包含敏感信息的诊断上下文并提供明确失败状态。
- 面向用户的提示与诊断日志分离;用户文案不得直接展示堆栈、内部错误码或敏感协议细节。
## 网络、数据与存储
- 新增接口必须沿用项目统一网络层以及既有鉴权、签名、加密、错误映射和日志机制,不在页面中自行实现底层请求。
- 服务端字段的类型和可空性必须按实际协议建模,禁止依赖强制转换或默认值掩盖字段缺失和类型错误。
- 响应优先转换为明确实体类型,不得在 UI 层散落 `Map<String, dynamic>` 字段访问。
- 修改序列化字段、数据库结构、首选项 key、文件格式或缓存结构时,必须评估升级、降级和新旧版本兼容性。
- 文件下载应先写入临时文件,校验成功后再替换目标文件;Stream、数据库和平台资源必须可靠关闭。
- 跨 isolate 或平台通道传递的数据必须可序列化、大小受控,并明确类型、空值和版本兼容语义。
## Import、依赖与生成代码
- import 按 Dart SDK、Flutter/第三方 package、项目 package 分组,并删除未使用 import;项目内引用方式遵循所在仓库约定。
- 引入或升级依赖前,必须评估维护状态、许可证、包体积、最低平台版本、隐私影响、传递依赖和现有依赖冲突。
- 依赖、插件、仓库源和构建工具变更必须在代码评审中单独说明原因和影响。
- 生成代码和资源必须通过对应工具更新,禁止直接手工修改;构建产物、本机配置和 IDE 私有文件不得提交。
- 禁止通过 dependency override、扩大 analyzer exclude、关闭 lint 或降低 SDK 约束掩盖问题。
## 本地化、资源与无障碍
- 用户可见文案必须使用项目现有本地化机制,禁止在 Dart、Widget 或平台代码中新增硬编码业务文案。
- 带参数文案使用本地化占位符,禁止通过字符串拼接改变不同语言的语序;复数、日期、数字和单位按本地化规则处理。
- 图片、字体和其他资源应选择合适格式与尺寸,新增前先搜索可复用资源,避免提交重复或未经压缩的大文件。
- 颜色、字号、间距和组件优先复用项目主题与设计系统,不在业务页面散落重复常量。
- 可点击控件、图片按钮、关键状态和错误提示必须提供必要的语义、状态反馈和合理点击区域。
## 平台集成与权限
- MethodChannel、EventChannel、FFI 和插件接口必须明确方法名、参数、返回值、错误、线程及版本兼容语义,并同步检查 Dart 与平台两端。
- 平台回调必须与页面或业务生命周期绑定,避免重复注册、遗漏注销、内存泄漏及组件销毁后的 UI 更新。
- 修改定位、相机、蓝牙、存储、通知、后台运行或系统跳转时,必须检查 Android/iOS 的权限声明、授权结果和系统版本差异。
- 新增权限遵循最小权限原则,并覆盖拒绝、永久拒绝、受限、取消和重新授权路径。
- 外部 URL、Deep Link、文件路径及平台传入数据均按不可信输入处理,校验类型、长度、范围、来源和协议。
## 安全、隐私与日志
- 禁止在日志中输出 Token、Cookie、手机号、身份证信息、精确位置、支付信息、完整请求头、密钥或其他敏感数据。
- 使用项目统一日志工具;Release 环境不得新增无条件执行的 `print`、`debugPrint` 或等效调试输出。
- 禁止将密钥、私钥、签名密码、访问令牌或真实服务凭据提交到仓库。发现疑似凭据时必须停止传播并通知负责人轮换。
- 敏感数据必须使用符合项目要求的安全存储,不得以普通首选项、数据库或文件明文保存凭据和高敏感信息。
- 新增权限、隐私数据采集、埋点或第三方 SDK 时,必须评估数据最小化、用户授权、隐私政策、初始化时机和合规要求。
## 测试、格式化与验收
- 使用项目提交的 `analysis_options.yaml`、formatter 配置和 SDK 版本;自动化工具结果是可执行规则的最终依据。
- 每个新增或修改的 Dart 文件必须执行项目规定的 `dart format` 和增量 analyze,不得新增 error、warning 或 info。
- 修复缺陷时必须验证原问题路径,并至少覆盖一个相关失败、边界、并发或生命周期场景;存在对应测试时必须运行。
- 纯业务逻辑应覆盖正常、边界和失败路径;测试名称描述行为和预期结果,不描述实现细节。
- 跨模块、公共层、网络层、状态管理或平台接口修改必须运行完整静态检查和相关测试套件。
- 修改资源、依赖、生成配置或平台工程时,必须运行能够实际处理该改动的生成或构建任务,不能只做 Dart 源码分析。
- 所有改动必须检查完整 diff 和空白错误,确认没有无关修改、意外格式化、调试代码、生成产物或敏感信息。
- 检查失败时必须提供第一条真实错误及其上下文,并区分代码问题、既有告警、依赖失败和本地环境问题;未执行的检查必须如实说明。
## Git 提交与代码评审
- 一个提交应聚焦一个逻辑目的,不混入无关格式化、资源变化、依赖升级、工程配置重排或临时调试代码。
- 修改依赖、权限、路由、公共 API、数据结构、持久化格式或平台协议时,必须在评审中明确标注。
- 合并请求应说明改动目的、影响范围、验证结果、平台兼容性和已知风险;涉及 UI 时应提供必要截图或录屏。
- 禁止通过关闭警告、降低检查等级、跳过必要验证或扩大忽略范围使检查通过。
- 提交前必须确认未覆盖工作区中他人的未提交改动,且提交内容仅包含当前任务相关文件。
## AI 编程工具附加要求
- 开始修改前必须读取项目 `AGENTS.md` 及其引用的规范,并检查工作区已有未提交改动。
- 修改前先搜索真实入口、调用方和既有实现,不得仅凭文件名或局部代码推断完整行为。
- 只能生成能够接入现有调用路径的完整实现,不得留下占位实现、伪代码或仅为将来可能使用的抽象。
- 不得自行扩大需求范围;发现无关问题时可以报告,但未经明确要求不得顺手修改。
- 对危险、不可逆、影响发布或需要新增权限的操作,必须先明确目标、影响和回滚方式,并按团队授权流程执行。
- 完成后必须报告实际修改文件、验证命令和结果;未执行或未通过的检查必须如实说明。
- 需求与规范冲突时不得自行忽略,应指出冲突并请求负责人确认。
AGENTS.md的内容为:
markdown
# qiji Flutter 项目规范
开始任何代码修改、重构或评审前,必须先阅读并遵守 [Dart / Flutter 通用开发规范](docs/standards/FLUTTER_DEVELOPMENT.md)。
本文件只定义 qiji Flutter 的项目补充规则,适用于本目录及所有子目录。开发者、AI 编程工具和自动化脚本均须遵守。
## 规则关系
- 通用开发规范是默认基线,本文件可以根据 qiji Flutter 的实际情况补充或收紧规则。
- 本文件与通用规范冲突时,只有明确写出原因和适用范围的项目规则才可覆盖通用规范。
- 子目录可以通过更具体的 `AGENTS.md` 补充或收紧规则;需要放宽强制要求时,必须说明原因、影响范围和替代措施,并由模块负责人确认。
- 历史代码不要求一次性整改;新增和实际修改的代码必须遵守当前规范,未涉及的历史代码保持不变。
## 项目定位与范围
- 本工程是 Flutter module,为骑迹用户端、调度端和换电端的 Android、iOS 宿主提供共享页面与能力,不按独立 Flutter App 假设设计业务入口。
- `lib/page/customer`、`lib/page/dispatcher` 和 `lib/page/service` 分别承载用户端、调度端和换电端业务;公共能力放在职责匹配的 `common`、`api`、`repository`、`model` 或现有状态管理目录中。
- 修改公共能力前必须搜索三个业务端及 Native 宿主的调用方,避免只验证当前页面。
- `lib/generated/`、`lib/l10n/generated/`、`lib/gen_a/` 和各平台生成目录必须通过对应工具维护,禁止手工修改。
- 禁止修改或提交 `.dart_tool/`、`build/`、`.android/Flutter/build/`、`.android/plugins_build_output/`、Pods、IDE 配置及其他构建产物或本地环境文件。
## 架构与依赖
- 修改前必须确认真实入口、调用链、状态所有者和平台边界,优先复用项目现有 Provider、Repository、API、模型、公共组件和工具类。
- 页面负责展示和交互编排;请求、缓存和可复用业务状态应由现有 Provider/Repository 等职责层持有,不在多个页面重复维护。
- 同一业务状态必须有单一可信来源。修改 Provider、Repository、公共模型或缓存结构时,必须搜索全部读写方并检查刷新、失败、空数据和销毁路径。
- 保留既有公开字段、构造参数、路由参数、MethodChannel 协议和调用语义;未经明确需求,不移动公共类型、扩大 API 可见性或进行破坏性变更。
- 不为单个需求引入新的状态管理、网络、序列化或路由体系;新增依赖前先确认现有依赖和 SDK 无法满足需求。
## Native add-to-app 与平台通信
- 修改 MethodChannel/EventChannel 的 channel 名、方法名、参数、返回值、错误码或线程语义时,必须同时检查 Dart 与 Android/iOS 宿主实现,禁止只修改单侧协议。
- 平台消息必须明确成功、失败、取消、重复回调和页面销毁后的处理;不得假设宿主始终返回完整、类型固定的数据。
- Native 与 Flutter 共享的用户、租户、语言、定位、车辆和行程状态必须保持单一可信来源,避免两端独立缓存后产生不一致。
- 修改插件、FlutterEngine、路由入口、渲染模式或平台构建配置时,必须检查三个宿主工程的集成兼容性,并说明无法在当前仓库完成的宿主侧验证。
- `.android/` 是 module 的生成宿主。除非需求明确涉及生成模板或集成排障,不得把其中生成文件作为长期业务实现位置。
## 网络、数据与安全
- 新增或修改接口必须复用 `lib/api` 和 `lib/repository` 的既有链路,保留鉴权、签名、RSA、加解密、错误映射、重试和日志约定。
- 响应数据优先转换为明确模型;不得在 UI 层新增分散的 `Map<String, dynamic>` 字段解析、协议默认值或底层异常转换。
- 修改请求/响应模型、序列化字段、加密信封、缓存 key 或持久化格式时,必须检查字段可空性、新旧版本兼容性及 Native 交互边界。
- 重试、token 或密钥刷新必须有明确上限,并检查并发刷新、重复请求、重复回调和无限重试风险。
- 日志禁止输出 Token、Cookie、签名、密钥、完整请求头、手机号、身份证信息、精确位置或解密后的响应内容。
## 本地化与用户文案
- 用户可见文案必须使用项目现有本地化资源和统一语言入口,禁止在 Widget、Provider 或平台桥接代码中新增硬编码业务文案。
- 带参数文案使用本地化占位符,禁止通过字符串拼接改变不同语言的语序;日期、数字和单位按本地化规则处理。
- 系统语言为默认来源:简体中文使用中文,其他语言使用英文;语言设置仅保存在设备本地,Native 与 Flutter 必须使用同一语言来源。
- 迁移既有业务文案时保持语义、占位符、标点和拼接关系不变;疑似错字或历史不一致必须单独说明,不得顺手改写。
- ARB 或生成配置变化后使用项目既有生成流程更新产物;禁止直接编辑 `lib/l10n/generated/`。
## Flutter UI 与生命周期
- `build` 只声明 UI,不在其中发起请求、写存储、注册监听或执行其他副作用。
- 异步回调使用 `BuildContext` 前必须确认仍然 mounted;Controller、FocusNode、StreamSubscription、Timer、Animation 和平台监听必须在适当生命周期释放。
- 修改页面状态时覆盖加载、成功、空数据、失败、重试和重复触发;状态更新范围保持最小,避免无关页面整体刷新。
- 颜色、字号、间距、图标和组件优先复用项目现有主题、资源与 `cupertino_ui`、`material_ui` 能力,不在业务页面散落重复常量。
- UI 修改必须检查 Android/iOS 表现、安全区域、键盘、字体缩放、深色模式(如项目支持)和基本无障碍语义。
## 依赖与平台兼容
- Dart 和 Flutter SDK 下限以 `pubspec.yaml` 为准;新增语法、API 和依赖必须兼容项目约束及 Android/iOS 宿主当前工具链。
- `cupertino_ui` 和 `material_ui` 是项目既有 UI 依赖;调整其接口或版本时必须检查全部调用方和宿主打包影响。
- 修改地图、定位、相机、蓝牙、扫码、权限、WebView 或文件能力时,必须同步检查 Android/iOS 权限、生命周期和插件版本兼容性。
- 不得以 `any`、dependency override、降低 SDK 约束或扩大 analyzer ignore 的方式掩盖依赖冲突。
- 修改 `pubspec.yaml`、插件版本、资源声明或平台配置时,必须单独说明原因和影响,禁止混入无关升级。
## 编译与验收
- 所有改动提交前必须运行 `git diff --check` 并检查完整 diff,确认没有无关修改、意外格式化、调试代码、生成产物或敏感信息。
- 修改 Dart 文件后,必须对每个实际修改文件执行:
```bash
dart format --line-length 130 <changed-file.dart>
flutter analyze <changed-file.dart>
```
- 小范围修改应运行相关 focused tests;跨目录、公共层、状态管理、网络或平台通信修改必须运行完整 `flutter analyze` 和相关测试套件。
- 修改 ARB、资源、`pubspec.yaml`、插件或平台集成时,必须运行能够实际处理该改动的生成或构建命令;不能把源码静态检查描述为构建成功。
- 涉及 Native 协议或 add-to-app 集成时,除 Flutter 侧检查外还必须验证受影响宿主;当前环境无法覆盖时,应列出未验证宿主及已完成的替代检查。
- 检查失败时必须报告第一条真实错误及其上下文,并区分本次代码问题、既有告警、依赖失败和本地环境问题。
尾声
AI是必然的趋势,那么就好好为AI制定规范。让它按我们的想法来实施。
有一个疑问:现在AI开发效率高了那么多,如果公司的需求都开发完成,不需要那么多开发人员了。那开发人员何去何从呢。