thread-master/docs/product/demand-radar/tasks/T511-service-profile-api-ge...

72 lines
2.9 KiB
Markdown
Raw Permalink Normal View History

2026-08-03 05:52:02 +00:00
# T511 — service-profile-api-get-put
> Status: `done`2026-07-31
> Milestone: `M1`
> Kind: `feat`
> Est. change: `~160 lines`
## Goal
完成後系統應:`GET``PUT /api/v1/radar/service-profile` 真實可用,欄位完整往返並以 `owner_uid` 隔離。
## Depends on
- T500、T510
## Inputs
- Spec`../spec.md` §4.1、§5.1、§5.6、§9.1SP-02
- 既有 logic 模式:`apps/backend/internal/logic/scout/**`
## Outputs
### 程式變更(預期路徑)
| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/generate/api/radar.api` | edit | service-profile reqresp type 定稿 |
| `apps/backend/internal/logic/radar/getServiceProfileLogic.go` | edit | 讀取;未建立回明確「尚未建立」狀態 |
| `apps/backend/internal/logic/radar/putServiceProfileLogic.go` | edit | 整份 upsert驗證錯誤映射 |
| `apps/backend/internal/svc/servicecontext.go` | edit | 掛入 radar usecase |
### 行為變更
- 成功 `102000`;驗證失敗回明確 message欄位名原因非空成功。
- 只能讀寫自己的檔案;`owner_uid` 一律取 JWTrequest 帶的 uid 忽略。
### API / 契約
- `GET``{ exists, services[], cases[], forbidden[], faq[], service_areas[], remote_ok, availability, tone_note, updated_at }`
- `PUT` 回更新後全量。
## Out of scope
- 前端畫面T515
- watch 前置條件檢查T513
## Acceptance
- [x] SP-02填寫後 `GET` 欄位完整、`forbidden[]` 可讀
- [x] 別人的 uid 無法讀寫(回越權錯誤)
- [x] 指令:
```bash
cd apps/backend && make gen-api && go test ./internal/logic/radar/... -count=1 && make build
```
## Notes2026-07-31
| 路徑 | 動作 |
|------|------|
| `internal/logic/radarmap/map.go` | adddomain ↔ types 映射,含 `Pagination` helper |
| `internal/logic/radar/owner.go` | add`ownerUID`:一律取 JWTrequest 帶的 uid 忽略) |
| `internal/logic/radar/{get,upsert}_service_profile_logic.go` | edit |
| `internal/svc/service_context.go` | edit`Radar *radarUC.Service` |
| `internal/middleware/auth.go` | edit新增 `WithUID`,見下) |
| `internal/logic/radar/service_profile_logic_test.go` | add5 則) |
- `generate/api/radar.api` **未改**T500 定的 reqresp 型別已足夠,不需要重跑契約。
- **未建檔回 `exists=false` 的 200不是 404。** 表單得先開得起來才有東西填;誠實之處在 `exists` 欄位,而不是用錯誤碼表達。空陣列而非 `null`,前端不必每個欄位判空。
- **驗證錯誤映射成 400100**`cleanBizMessage` 會把 `radar validation: ` 前綴切掉所以前端拿到的是「services[0].name required」這種能對到欄位的訊息。
- **`middleware.WithUID` 是新增的匯出入口。** `ctxUID` 是私有型別,沒有它就只能繞過 `UIDFrom` 來測,那測到的就不是真的授權路徑。測試證明別人的 uid 讀不到也寫不壞自己的檔案。