编码约定(模块边界、命名、错误处理、可测试性)
1) 目标
本约定的目标是让项目在持续迭代中保持:
- 可读(容易理解)
- 可改(容易扩展)
- 可测(容易验证)
- 可诊断(出问题容易定位)
2) 模块边界(建议的分层)
- models/:领域模型 + 稳定编码/解析/展示逻辑(不要在这里写 SQL)
- db/:SQL + 类型转换 + Repository(不要在这里写 UI)
- services/:跨模块业务计算(偏离/收益等),避免页面堆业务逻辑
- state/:全局状态(Signal Context),尽量保持“数据结构 + 少量纯函数”
- pages/:页面级装配与数据流协调(加载/刷新/路由入口)
- components/:可复用 UI 组件(尽量纯 props 驱动)
- utils/:与业务无关的工具函数(格式化、通用 helper)
- error.rs:统一错误类型
AppError与AppResult<T>
3) 命名与可读性(贴近《代码整洁之道》)
- 函数名优先用动词短语:
find_all、find_by_id、set_active
- 布尔变量表达意图:
is_active、inventory_mode
- 避免缩写与魔法字符串:
- 类别/口径/工具类型使用 enum +
as_str/from_str
- 类别/口径/工具类型使用 enum +
4) 错误处理(当前设计与改进方向)
项目已在 src/error.rs 定义统一错误类型:
AppError(使用thiserror)type AppResult<T> = Result<T, AppError>
Repository 层(src/db/*_repo.rs)现已返回 AppResult<T>。
原则:
- 不要静默吞错(例如
row_to_xxx中的unwrap_or_default()把脏数据变默认值,仍待改进) - 用户输入/DB/IO 必须返回 Result,不要 panic
- 测试里可以 unwrap,但要保证失败信息可读(
expect更好)
5) 数据建模与持久化
原则:
- DB 里存稳定编码(TEXT)
- 模型负责提供编码 ↔ enum 的转换函数
- 重要不变量写进模型(例如
Asset::validate()/ 方案占比合计 100%)
6) Dioxus 组件与状态管理
建议:
- 页面负责“加载/刷新”,组件负责“渲染/交互”
- 尽量不要在渲染路径写 state(优先
use_effect) - 缩小
.read()/.write()的借用作用域,避免借用冲突
7) 测试策略(学习期可从最小集开始)
建议从两类测试开始:
- 模型纯函数测试:
AssetSubCategory::from_code、Category::from_str、收益/偏离计算 - DB 集成测试:设置
ASSET_LIGHT_DB_PATH指向临时文件,跑init_database,验证 CRUD
目标不是追求覆盖率,而是建立“重构有安全网”的能力。