本页注释仓库各目录的职责(以 lib/ 为主,并覆盖 backend/ 与其它顶层目录),并标注几个大文件的当前行数。Agent 要改动代码前应该先看这里。所有行数为 2026-06-21 wc -l 实测值——线条会漂移,重新计算请勿信旧值。
顶层目录:lib/(Flutter 客户端,下面详述)、backend/(账户系统 + CM4 云端)、android/ ios/ web/(平台 target)、assets/、l10n.yaml 生成的 lib/l10n/、test/、tools/、protocol-docs/、docs/。
| 文件 |
行数 |
作用 |
main.dart |
1033 |
入口:初始化顺序严格——WidgetsFlutterBinding → 屏幕方向锁竖屏 → DevLogService.init()(必须 first awaited) → APP_START 锚点 + 元数据 → 非首次启动时 AppPermissions.requestAllUpfront()(首次启动推迟到权限介绍页) → 显式 ProviderContainer → runApp() → _AppExitObserver(lifecycle)+ MethodChannel culinatech.app/lifecycle(native onDestroy)。_AppExit.run() 双触发幂等(dart-detached / native-onDestroy 谁先到谁赢) |
app.dart |
234 |
MaterialApp、onGenerateRoute 处理 10 个带参路由(ConnectionModePage / WifiNetworkSelectPage / WifiSetupPage / BoosterConfigurationsPage / FirmwareUpgradePage / SignInLandingPage / EmailAuthPage / EmailCodePage / ForgotPasswordPage / CookingPage)+ 12 个静态路由表、rootNavigatorKey + rootRouteObserver、safety alarm 全屏推送监听(internalOverTemp / ambientOverTemp → WarningPage,其它类型走 AlarmBannerHost banner)、Live Activity sync provider 订阅 |
| 文件 |
行数 |
内容 |
booster.dart |
377 |
Booster(设备快照) + DeviceStatus 枚举(connected / lostConnection / boosterShuttingDown / boosterOff / allDocked) + WifiStatus / ServerRegion + devicePrefix() / deviceTypeLabel() / getProbeCount() 工具方法;export BoosterFamily 自 transport |
probe.dart |
399 |
Probe(探针快照) + ProbeNumber 枚举(含 colorName / firmwareIndex / labelFor()) + ProbeAddress 常量(pen1=0x0A 等) + MeatType / Doneness 枚举;2026-04 重构后 ProbeAlarmConfig / ProbeSensorFlags 等烹饪/报警/范围标志已迁出,详见 状态模型 §探针级 |
cooking_session.dart |
515 |
CookingSession + CookSessionStatus(active / completed / cancelled / disconnected) + 序列化逻辑 |
connection_display_state.dart |
243 |
UI 连接展示层:除 ConnectionDisplayState 外还定义 BtLinkDisplayState;其派生不只依赖 Booster + Probe,还依赖 graceActive、manualReconnectInProgress、cloudLive 等状态 |
2026-05 前 cm4_data_parser.dart 是 1061 行的 "多协议巨型解析器";现已拆成 6 个文件,按职责切分:
| 文件 |
行数 |
作用 |
cm4_protocol.dart |
301 |
CM4 ASCII 命令构造器(SET_RD、SET_F/SET_C、CNT_0、SET_BL/WH/BU/YE=ABCDEF、BL_LVL=、RI_LVL=、SSID=/PSWD=、USUS=、OTA 等) |
legacy_protocol.dart |
164 |
CM1/CM2/CM3 传统字节命令(0x55AB、0x55AE、0x55B1、0x55AD、0x55AF/B0/B2 SET_TARGET) + commandByteFromAddress() 地址→命令字节映射 + reconstructMacFromCompressed() |
cm4_data_parser.dart |
478 |
CM4 ASCII 解析(D=、PENON/PENOFF、SETT==、VER=、WIFI_STS=、MQTT_STS=、M_ID OK/M_PD OK、RI_CNT=、<deviceId> online 等推送) |
legacy_data_parser.dart |
429 |
legacy 二进制解析(12B 设置响应、15B 探针温度、2B 心跳、0x55AA 入仓) |
booster_message.dart |
481 |
解析输出的统一消息类型层(CM4Message 家族 + CM4SettingsResponse) |
temperature_lookup.dart |
199 |
ADC→°C 查表 LUT(tempIntArray 内温 / tempExtArray 外温)——抽出公共 LUT,CM4 / legacy 解析共享 |
| 文件 |
内容 |
booster_transport.dart |
abstract class BoosterTransport:connect / disconnect / setProbeTarget / setUnit / muteAlarm / queryStatus + dataStream / connectionStateStream / rssiStream |
booster_family.dart |
enum BoosterFamily { legacy, cm4 } + BoosterFamilyExt(心跳 bytes/cadence、MTU 决策) + BoosterFamilyDeviceId 扩展('CM4_xxx'.boosterFamily) |
legacy_booster_transport.dart |
legacy 实现(45s 0x55B1 心跳、0x55AB 单位、0x55AD mute、0x55AF/B0/B2 SET_TARGET) |
cm4_booster_transport.dart |
CM4 实现(45s CNT_0 独占锁刷新——per Liang 2026-06-06 / c613148 起与 legacy 对齐;ASCII 命令、512 MTU 协商) |
BleDeviceService._transportFor(deviceId) 按 deviceId.boosterFamily 懒创建并缓存到 _transports[deviceId]。详见 04-规划与跟进/02-传输层重构。
| 文件 |
行数 |
内容 |
device_providers.dart |
3645 |
所有 Riverpod StateNotifier 集中:boosterProvider.family / connectedBoostersProvider / cookingSessionsProvider / cookLogProvider(持久化,capped 50 条) / alarmStateProvider(threshold 评估,main.dart 的 listen+Timer 驱动重评) / temperatureUnitProvider / appLanguageProvider / lastBoosterNameProvider。文件大,建议按功能拆:booster / cooking / alarm / settings |
| 文件 |
行数 |
作用 |
ble_service.dart |
2208 |
BLE 底层 I/O:连接、特征发现、读/订阅;连接单飞门 _connectGate 串行化 connect()/directConnect();锁刷新写按 deviceId.hashCode 相位错峰(ble_service.dart:1354);buffer 策略(Strategy A 逐探针节流、Strategy B 缓冲刷新) |
ble_device_service.dart |
4880 |
复杂度热点:多设备状态追踪、_transportFor 路由、重连节奏(前台 + 后台 <4h 始终 15s 不衰减;后台 ≥4h _bgTieredCadenceArmDuration 触发 15/60s/5m 分级)、90s 宽限期(gracePeriod)、入仓关机分类(_dockShutoffWindow=1s + _dockShutoffUiDelay=10s + _dockShutoffReconnectDelay=8s)、packet dispatch、staleness 检查(60s 全沉默 → lostConnection、20s 15B 沉默 → 探针置灰)、_QueryTracker 跟踪 0x55AE↔12B 响应(3s window)、readRssi() 每 10s 采样 Booster.rssi |
device_connection_manager.dart |
626 |
BLE vs MQTT 优先级编排,统一遥测流 |
device_service.dart |
75 |
抽象接口(DeviceService) |
mock_device_service.dart |
354 |
Mock 实现(dev/test 用) |
alarm_service.dart |
1312 |
每设备报警栈(_active[(deviceId, ProbeNumber?, AlarmType)])、优先级轮换、声音 + 震动派发;AlarmType 13 类(per Liang 2026-04-30 #18 从 7 类扩到 12,2026-05 再加 ambientUnderTemp 共 13);AlarmThresholds(internalOverTempF=212 / internalHiClampC=101 / ambientOverTempF=527 / lowBatteryTrigger=2 等);末尾托管 ProbeSensorFlags + probeSensorFlagsProvider、ProbeAlarmConfig + probeAlarmConfigProvider(5 字段,固定代码);critical battery(≤10%)每 10 min 重复(TAPD #1003012) |
mqtt_service.dart |
1110 |
MQTT 云端 fallback,仅 WiFi-enabled CM4 使用;区域由 region_service.dart 决定 broker |
notification_service.dart |
589 |
Android 前台服务桥 + 本地通知调度;updateLocalizations() 在 app.dart builder 每次 rebuild 同步当前 locale(per Liang TAPD i18n bug);_alarmContent / startBackgroundMonitoring 走 AppLocalizations 的 notify* / bgMon* 路径 |
foreground_service.dart |
65 |
Android 前台服务通道(小封装) |
permissions_service.dart |
278 |
权限请求:requestAllUpfront() 启动时统一请求 + BLE 路径 lazy 重试;currentStatuses() + isEffectivelyGranted() 给 main.dart 的 "missing perms" 弹窗用 |
dev_log_service.dart |
852 |
结构化日志(APP / BLE / PARSER / TRACE / PERMISSION / CORE 事件),含 packet seq #<seq> 关联 |
dev_log_decoder.dart |
279 |
开发者日志导出与解码(base64 / 人类可读 / JSON 三种格式) |
region_service.dart |
211 |
MQTT 区域自动检测(IP 地理定位 → China/US/EU,失败默认 China);与 booster 的 USUS= 命令独立——App 选自己的 broker,不写回 booster |
known_devices_service.dart |
159 |
SharedPreferences 持久化已配对设备(deviceId、connectionMode、名字);main.dart 启动后 _initKnownDevices() seed reconnect queue |
cooking_live_activity_service.dart |
241 |
iOS Live Activities(实时活动)—— 锁屏 / 灵动岛烹饪温度卡,详见 实时活动 |
theme/app_theme.dart:深色主题、颜色常量、kAmbientMaxLabelC/F(外温 LUT 上限标签)等
utils/anonymous_id.dart:匿名 ID(日志去识别化)
utils/log_timestamp.dart:日志时间戳格式化
utils/meat_localization.dart:肉种/熟度的本地化字符串映射
utils/navigation_utils.dart:Navigator helper(safe pop / 路由判断)
| 子目录 |
文件 |
datasources/ |
ble_thermometer_datasource.dart / cloud_thermometer_datasource.dart / mock_thermometer_service.dart |
repositories/ |
thermometer_repository_impl.dart(对 BLE 数据源的薄封装) |
¶ domain/
| 子目录 |
文件 |
entities/ |
device_type.dart / probe_reading.dart / thermometer_device.dart / thermometer_snapshot.dart |
repositories/ |
thermometer_repository.dart(接口,依赖反转) |
完整路径:lib/features/thermometer/presentation/
pages/(18 个页面文件,每屏一个;详见界面解析 起的逐屏文档)—— 最大的两个:
dashboard_page.dart(2449 行)—— 多设备卡片网格、连接状态 banner、长按忘记设备
cooking_page.dart(2095 行)—— 实时温度图、计时器、目标选择、报警评估、连接 overlay
widgets/ —— 共享控件:
probe_gauge.dart —— 圆形温度表
magnifying_ruler.dart —— 目标温度滚动尺
temperature_gradient_bar.dart —— 渐变温度条
quick_target_sheet.dart —— 快选目标 bottom sheet
dev_overlay.dart —— 开发者悬浮调试层
glassmorphic_card.dart —— 玻璃拟态卡片样式
alarm_banner.dart —— 顶部 alarm banner host(非 safety alarm 用)
alarm_visual_card.dart —— alarm 视觉卡片
help_previews.dart —— 帮助中心的预览控件
providers/thermometer_providers.dart —— 业务层 Riverpod Provider
controllers/connection_manager.dart —— 业务层连接控制器
- ARB 源:
app_en.arb / app_de.arb / app_es.arb / app_fr.arb / app_it.arb / app_zh.arb
- 自动生成:
app_localizations_*.dart + 基类 app_localizations.dart
- 配置:根目录
l10n.yaml + pubspec.yaml 的 flutter: generate: true
¶ android/ 与 ios/ — 平台特化
android/app/src/main/kotlin/com/example/culinatech_app/MainActivity.kt —— 重写 onDestroy 通过 MethodChannel culinatech.app/lifecycle 通知 Dart 层做 BLE+MQTT 清理。未重写 onTaskRemoved(需要 Service 子类,见 待解决问题 TAPD #9)。同目录下 BleMonitoringService.kt 是 Android 前台服务通道
ios/Podfile —— platform :ios, '16.0';Live Activities 需要 iOS 16.1+ 单独 Widget Extension target(见 ios/CulinaTechLiveActivity/SETUP.md)
CM4 账户系统与云端 onboarding 的服务端部分。权威设计见仓库根 PLAN_ACCOUNT_SYSTEM.md(先读它)。技术栈(PLAN §3,2026-06-05 锁定):Supabase(Auth + Postgres + RLS) + 自建 Mosquitto(mosquitto-go-auth 插件直接对 Supabase Postgres 鉴权)。无 AWS、无 EMQX。
| 子目录 / 文件 |
作用 |
CM4_BROKER_CONNECTION.md |
固件连接规范(host、TLS、鉴权、topic) |
fleet/ |
多区域 CM4 云 broker 集群(见下) |
mosquitto/ |
broker 栈:docker-compose.yml + mosquitto.conf + mosquitto-go-auth,对 supabase/migrations/0002_mqtt_authz.sql 实时鉴权 |
supabase/migrations/ |
0001_app_schema.sql(账户/设备表) / 0002_mqtt_authz.sql(broker 鉴权) / 0003_account_delete.sql(账户注销) |
tls/ |
gen-ca.sh——自建 CA + broker 证书;CA root 嵌入固件并打包进 App(assets/certs/culinatech_ca.crt),全集群共用一个 CA,加区域无需重刷固件 |
每个 box 跑与新加坡 dev broker 相同的自建栈,由同一个 CA 签发。拓扑:Test cm4-hk(阿里云 HK)/ Americas cm4-us(弗吉尼亚)/ EMEA cm4-eu(伦敦)/ APAC cm4-sg(新加坡,原始);均 SWAS 2vCPU/2GiB、Ubuntu 24.04、TLS :8883。脚本读 ~/.culinatech/.env 的阿里云 key。
| 脚本 |
作用 |
provision_one.py <region> |
新建一台 SWAS box + 设密码 + 开 8883 + 重启 |
configure_keepers.py |
给 keeper box 设 root 密码、开 8883、重启 |
list_fleet.py |
跨区域清点所有 SWAS 实例 |
deploy_box.py <hk\|us\|eu> |
从 SG 拉栈 bundle、推到 box、装 Docker、起栈 |
replicate_accounts.py |
把 mqtt_accounts 表 SG → 新 box 复制 |
verify_brokers.py |
TLS + 鉴权 + pub/sub 往返健康检查 |
na_broker_geo.py |
按 Shopify 订单分布分析北美 broker 选址(弗吉尼亚依据) |
| 目录 |
内容 |
assets/ |
图片资源(含 6 语 probe_*_<lang>.png 设备指南图)、assets/certs/culinatech_ca.crt(CM4 云 CA root) |
test/ |
Flutter 单元 / widget 测试 |
tools/ |
纯前端 HTML 预览页(设备指南 / 帮助 / 图标 / 目标设定 预览),开发期可视化用 |
web/ |
Flutter web target 脚手架(favicon / icons / index.html / manifest),非主要交付 |
protocol-docs/ |
协议原始稿(CM1/CM2/CM3 v4/v5、CM4 的 .docx/.md)——固件团队来源文档 |
docs/ |
仓库内文档,含 docs/claude-memory/ 知识库 |
| 文件 |
行数 |
建议拆分方向 |
ble_device_service.dart |
4880 |
已通过 transport-split 卸下了 family-specific 写命令;剩余主体仍可拆:重连循环 / 入仓关机处理器 / packet dispatch 路由 / staleness+RSSI 监控 |
device_providers.dart |
3645 |
按功能拆:booster / cooking / alarm / settings |
ble_service.dart |
2208 |
抽 buffer 策略 + 锁相位错峰 |
dashboard_page.dart |
2449 |
抽出卡片渲染为独立 widget 文件 |
cooking_page.dart |
2095 |
抽出目标选择器 + 温度图为子 widget |
alarm_service.dart |
1312 |
13 类 AlarmType 评估器可按 Tier S/A/B/C/D 拆 |