docs(rules): 梦核蒸馏补缺失规则创建 rules.md

This commit is contained in:
lanrtop 2026-07-04 16:47:16 +09:00
parent f8fdb9d34e
commit 010abaa394
3 changed files with 95 additions and 30 deletions

42
.blueprint/rules.md Normal file
View File

@ -0,0 +1,42 @@
# 项目私有规则
> 本文件由梦核分析 + 用户确认后生成Claude 每次对话开始时读取并合并应用。
> 规则格式与 CONVENTIONS 自动推荐规则库相同,优先级高于全局规则。
> 来源2026-07-04 梦核分析,基于 40 条复盘笔记 + 跨项目返工数据。
## 规则列表
### P01 — Android 画布/地图叠加面板必须用 absolute 定位
- **触发条件**在地图、画布、SVG 可缩放视图上叠加侧边/底部面板
- **自动动作**:确认面板用 `position: absolute` 覆盖;严禁通过 `Animated.timing` / `LayoutAnimation` 改变父容器 flex 宽高——会触发底层视图重新布局Android 上出现闪白/黑块
- **confidence**: 0.90
- **evidence_count**: 3
- **derived_from**: FoldableLayout 3 轮返工4e1d922→cea2a5d→3dbc6f0JS 线程宽度动画两次都有 Android 渲染问题absolute 定位彻底解决
### P02 — 选图统一用 expo-document-picker禁用 expo-image-picker
- **触发条件**:需要从相册选取图片
- **自动动作**:直接使用 `expo-document-picker``ACTION_GET_CONTENT`);发现代码中引用 `expo-image-picker` 时提示替换
- **confidence**: 0.92
- **evidence_count**: 3
- **derived_from**: 摄像头任务 3 轮返工expo-image-picker SDK52 API 废弃 + 三星 Photo Picker 系统崩溃expo-document-picker 彻底绕开
### P03 — 全屏预览 Modal 不用 transparent prop
- **触发条件**:实现全屏照片预览、全屏地图等需要覆盖整个屏幕的 Modal
- **自动动作**:去掉 `transparent` prop 改为非透明黑底FlatList pagingEnabled 改为手势驱动单张渲染
- **confidence**: 0.88
- **evidence_count**: 2
- **derived_from**: MarkerPhotoPanel 返工transparent Modal 渲染范围被限制为父容器宽度FlatList 分页宽度异常)
### P04 — 列表页禁止 N+1 查询
- **触发条件**:列表组件需要展示每行的统计数据(照片数、物品数、数量合计等)
- **自动动作**:在 SQL 层通过 `LEFT JOIN` 子查询或 `GROUP BY` 一次聚合取数;发现逐行查询时标记需重构
- **confidence**: 0.80
- **evidence_count**: 1
- **derived_from**: ItemList 照片数统计 N+1 查询O(n) 查库内容量增大后有性能风险2026-04-11 复盘)
### P05 — 动态数据前置:表单骨架初始化前先确认数据源
- **触发条件**:设计表单组件 / 列表筛选 chip / 下拉选择器
- **自动动作**:先问"这些选项/分类将来是否动态?";有动态数据则在 `_layout.tsx` 根布局一次性接入对应 `Context/Provider`,不得在组件层后补
- **confidence**: 0.80
- **evidence_count**: 2
- **derived_from**: ItemFields 分类 chip 3 轮返工(硬编码→动态 CategoriesContext 后补)+ Expo 骨架 2 轮返工CategoriesProvider 初版未加)

View File

@ -1,40 +1,14 @@
# react-phone-apps # react-phone-apps
<!-- BLUEPRINT_MANAGED_START version="1.4.3" --> <!-- BLUEPRINT_MANAGED_START version="1.10.0" -->
## 项目蓝图 ## 项目蓝图
本项目使用 `.blueprint/` 目录维护项目全景架构图,驱动需求讨论和任务管理。 蓝图工作流规则统一维护在 @AGENTS.md 的 BLUEPRINT_MANAGED 区(跨工具单一来源,勿在此复制)。
### 对话开始时必须执行
对话开始时必须执行:
1. 读取 `.blueprint/manifest.yaml` 了解项目全景和当前状态 1. 读取 `.blueprint/manifest.yaml` 了解项目全景和当前状态
2. 读取 `.blueprint/CONVENTIONS.md` 了解完整工作流规则 2. 读取 `.blueprint/CONVENTIONS.md` 了解完整工作流规则
3. 遵循 AGENTS.md 中的蓝图工作流(需求→蓝图同步、复杂度决策、两阶段提交)
### 需求讨论 → 蓝图同步规则
| 用户说的 | Claude 应做的 |
|----------|--------------|
| "我想加个 XX 功能" | 确认需求后manifest 新增模块status: concept创建 `.blueprint/modules/<id>.md` |
| "XX 功能需要 A、B、C" | 在模块文件中拆分为任务卡 |
| "这个方案确定了" | 模块 status → planned补充任务卡 files/acceptance |
| "开始做 XX" | 模块 status → in_progress |
| 没提蓝图但在讨论功能 | 主动提议更新蓝图 |
### 复杂度决策(讨论新功能 / 拆解需求时)
| complexity | 执行流程 |
|-----------|---------|
| S / M | 直接拆任务卡,确保每张卡有 `files` + `acceptance` + `complexity` → 标记 📋 |
| L复杂系统设计 | 先 `/architect` 输出设计文档,用户确认后 `/splitter` 拆成 S/M 任务卡 |
> L 级任务禁止直接写代码,必须先经过 `/architect``/splitter` 流程。
### 任务执行两阶段提交
- **开始写代码前**:任务卡前缀改为 🔵status → in_progress
- **完成验收后**:任务卡前缀改为 ✅status → done更新 manifest `updated` 日期
完整规则(迭代管理、阻塞处理、复盘笔记等)详见 `.blueprint/CONVENTIONS.md`
<!-- BLUEPRINT_MANAGED_END --> <!-- BLUEPRINT_MANAGED_END -->
## 命令执行规则 ## 命令执行规则
@ -48,3 +22,36 @@
``` ```
- Windows 环境变量 → bash 语法用 `export VAR=value`**不用** PowerShell 的 `$env:VAR` - Windows 环境变量 → bash 语法用 `export VAR=value`**不用** PowerShell 的 `$env:VAR`
- 只有以下情况才让用户手动操作:需要交互式登录(如 `gcloud auth login`)、需要输入密码、或明确的破坏性操作需确认 - 只有以下情况才让用户手动操作:需要交互式登录(如 `gcloud auth login`)、需要输入密码、或明确的破坏性操作需确认
## 开发注意事项(踩坑提炼)
### Android 平台
- **Modal 不用 `transparent` prop**transparent Modal 渲染范围被限制为父容器宽度(如侧栏 260pxFlatList pagingEnabled 等全屏功能失效。改用非透明 Modal黑底强制创建独立原生全屏窗口
- **Modal 内手势需额外 GestureHandlerRootView**Modal 是独立 native window父级 RNGH 上下文无法穿透。内容最外层必须包 `<GestureHandlerRootView style={{ flex: 1 }}>`
- **禁止在 Alert 回调内启动相机/相册**Alert 关闭动画期间 Activity 焦点未恢复intent 被系统忽略。改为 UI 直接放按钮触发
- **三星设备 Photo Picker 崩溃**:用 `expo-document-picker``ACTION_GET_CONTENT`)替代 `expo-image-picker` 的相册选择
- **手势组合用 `Simultaneous` + `maxPointers`**:避免 `Exclusive` 导致 pinch 延迟。Pan 加 `maxPointers(1)` 天然分离单指/双指
### Expo SDK 52 + pnpm Monorepo
- expo 包版本用 `~`(如 `~13.0.2`**禁止 `^`**,防止 pnpm 解析到 SDK 53+ 导致 `expo-module-gradle-plugin not found`
- 构建始终从 app 目录运行 `pnpm expo run:android`,不进 `android/` 直接执行 Gradle
- `metro.config.js` 必须设置 `unstable_serverRoot` 指向 app 目录(修复 Windows monorepo 路径解析 bug
- `expo-image-picker` v16 移除了 `MediaType` 枚举,`mediaTypes` 用字符串数组 `['images']`
### 地图与布局
- FoldableLayout 面板用 absolute 定位叠加在地图上方,地图 `flex:1` 始终满屏渲染,禁止用动画改变地图宽度(会触发 Android 地图重新布局闪白)
- SVG 地图文件更新后须重新运行生成脚本(`scripts/` 下),当前未纳入 watch 模式
### 数据库
- 新增字段时先评估未来 2-3 步迭代可能需要的字段,避免反复 ALTER TABLE初版遗漏 unit/spec/confirmed_at 导致返工)
- 迁移脚本用 `try/catch` 逐步执行,单个迁移失败不阻断后续;迁移全部幂等,多次启动安全
- 删除标记点时级联删除 items → photos 并同步删除文件系统文件,不能只删数据库行
- **列表页禁止 N+1 查询**:凡需附加统计字段(照片数、物品数等)必须在 SQL 层通过 `LEFT JOIN` 子查询或 `GROUP BY` 一次取数禁止逐行查询ItemList 照片数统计返工来源)
### 表单与组件
- **动态数据前置**:设计表单/列表骨架前,先确认 chip/下拉选项是否会变为动态数据;有则在骨架初始化时(`_layout.tsx`)一次性接入对应 `Context/Provider`,不得后补(分类 Context 后补返工来源)

16
lefthook.yml Normal file
View File

@ -0,0 +1,16 @@
# 接入包标准 lefthook 配置(炼境分发)
# 作用:强制 Conventional Commits + 提交前类型检查
# 安装pnpm add -D lefthook && pnpm exec lefthook install
pre-commit:
parallel: true
commands:
# TODO: 按项目调整 typecheck 命令与 globmonorepo 用 --filter <pkg> typecheck
typecheck:
glob: "*.{ts,tsx}"
run: pnpm typecheck
commit-msg:
commands:
conventional:
run: "head -1 .git/COMMIT_EDITMSG | grep -qE '^(feat|fix|docs|chore|refactor|ci|perf|style|test|build|revert)(\\(.+\\))?!?: .+' || exit 1"