react-phone-apps/CLAUDE.md

58 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# react-phone-apps
<!-- BLUEPRINT_MANAGED_START version="1.10.0" -->
## 项目蓝图
蓝图工作流规则统一维护在 @AGENTS.md 的 BLUEPRINT_MANAGED 区(跨工具单一来源,勿在此复制)。
对话开始时必须执行:
1. 读取 `.blueprint/manifest.yaml` 了解项目全景和当前状态
2. 读取 `.blueprint/CONVENTIONS.md` 了解完整工作流规则
3. 遵循 AGENTS.md 中的蓝图工作流(需求→蓝图同步、复杂度决策、两阶段提交)
<!-- BLUEPRINT_MANAGED_END -->
## 命令执行规则
**禁止把命令输出给用户手动执行。** 凡是需要运行的命令,直接用 Bash tool 自己执行。
- `pnpm install` / 依赖安装 → 直接跑,根目录或子包目录均可
- Android 构建 → 用 `run_in_background: true`避免阻塞JAVA_HOME 用 `export` 内联设置:
```
export JAVA_HOME="/c/Program Files/Android/Android Studio/jbr" && pnpm expo run:android --variant release
```
- Windows 环境变量 → bash 语法用 `export VAR=value`**不用** PowerShell 的 `$env:VAR`
- 只有以下情况才让用户手动操作:需要交互式登录(如 `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 后补返工来源)