docs(routing): 计划澄清 enabled 缺省语义(必填/客户端恒发/服务端不默认)

Task 2 复核发现 plan 内部不一致(接口注释 vs 代码块)。裁决:enabled 必填,Task 6 model
恒输出 enabled=true、fromJson 容错默认 true;服务端不修正缺省(缺失=禁用属 fail-safe)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo
This commit is contained in:
wangjia
2026-07-28 07:39:51 +08:00
parent b98aa2335b
commit 3a2c48541c
@@ -249,7 +249,7 @@ func (s *Store) Upsert(ctx context.Context, userID int64, p *Profile) error {
- Create: `server/internal/routing/profile_test.go`
**Interfaces:**
- Produces: `func (p *Profile) Validate() []FieldError`(空 slice = 合法);`FieldError{Index int, Field, Reason string}`;`func (p *Profile) Normalize()`(去重、trim、修正 enabled 缺省)。
- Produces: `func (p *Profile) Validate() []FieldError`(空 slice = 合法);`FieldError{Index int, Field, Reason string}`;`func (p *Profile) Normalize()`(去重、trim)。注:`enabled` 为必填字段,客户端(Task 6 model)恒传 `true`;服务端不对缺省 enabled 做修正(缺失即零值 false=禁用,属 fail-safe 可接受)。
- Consumes: `routing.Profile`(Task 1)。
- [ ] **Step 1: 写校验测试(先失败)** `server/internal/routing/profile_test.go`
@@ -565,7 +565,7 @@ test('RoutingProfile round-trips json', () {
});
```
- [ ] **Step 2: 跑确认失败** `cd client && flutter test test/unit/routing_profile_model_test.dart` → FAIL
- [ ] **Step 3: 写 model** `client/lib/models/routing_profile.dart`(手写 fromJson/toJson,仿 `lib/models/me.dart:50`;含 `RoutingRule``Builtin``copyWith`)。字段与服务端契约一致(mode/builtin/rules/final;rule = type/value/action/note/enabled)。
- [ ] **Step 3: 写 model** `client/lib/models/routing_profile.dart`(手写 fromJson/toJson,仿 `lib/models/me.dart:50`;含 `RoutingRule``Builtin``copyWith`)。字段与服务端契约一致(mode/builtin/rules/final;rule = type/value/action/note/enabled)。**`RoutingRule` 构造默认 `enabled: true`,`toJson()` 恒输出 `enabled` 字段**(服务端不修正缺省 enabled,契约靠客户端保证;缺失=禁用属 fail-safe)。`fromJson``enabled: m['enabled'] as bool? ?? true`(读取容错默认 true)。
- [ ] **Step 4: 跑确认通过** `flutter test test/unit/routing_profile_model_test.dart` → PASS
- [ ] **Step 5: 加 API** `client/lib/services/account_api.dart`(仿 `:43` me()/`:68` renameDevice):
```dart