2 Commits

Author SHA1 Message Date
59c57fa481 feat(device): WP-B repository 接 agents 模型 + exchange 重塑(A' 走向第二階段 Go 層)
- Device struct 加 4 欄(agent_id/agent_local_device_id/registered_at/
  is_representative)+ deviceColumns 13→17 + scanDevice/SaveTx 讀寫新欄
- 新增 internal/agent package(domain + interface + in-memory + PG repo):
  GetOrCreateAgentTx/GetByOwnerTx,advisory lock 序列化同 owner get-or-create
- exchange 重塑:建/復用 agent → representative device(綁 session_tokens、
  serial=NULL)→ loop 建 N 顆真 USB device(R1 完整 N 顆非只第一顆)
- List filter is_representative=false + DeviceListItem 回傳 agent_id/registered_at
- 併入 WP-0/0005 follow-up Minor:Mi#2 lost-update 收斂(tx 內查詢+局部更新)
  / Mi#3 過時註解 / Mi#4 空 serial 回 ErrNotFound / Mi#5 serial 白名單
  ^0x[0-9A-Fa-f]{8}$ + 去重 / S-1 firmware forward-compat / S-2 device Name 衍生

守 ADR-018 A'(一 owner N agents、session_tokens FK 物理不動、不加 owner
unique 為多機器留路)。Reviewer 通過(0C/0M)。5 套件 dbtest 130 全綠
(db 19/device 37/agent 13/api 172/cmd 60)、build/vet/test 綠。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 11:40:17 +08:00
8369cab85c feat(db): migration 0005 agents 模型(個人設備管理 A' 走向第二階段地基)
- 新增 agents 表 + devices 加 4 欄(agent_id/agent_local_device_id/
  registered_at/is_representative)+ 2 index + 純 SQL data migration
- data migration 採 R-A:agent.id := device.id 決定性推導、冪等、
  soft-deleted device 排除(WHERE deleted_at IS NULL)
- 守住 ADR-018 走向 A':不碰 session_tokens FK、不改現有 partial
  unique index uq_devices_owner_serial_active、對 0001-0003 零破壞
- migrate_0005_db_test.go 6 個 dbtest case(apply/data migration/
  rollback 對稱/re-apply 冪等/session_tokens 零影響/既有 device 讀寫回歸)
- 修 TestMigrate_UpDownUp 編號 gap 假設(0001/2/3/5 無 0004):
  assert.Equal(topVer-1) → assert.Less(downVer, topVer)
- .gitignore 加 .logs/ + **/.logs/(本機執行 log per-branch 不進 git)

Reviewer 通過(0 Critical/0 Major/3 Minor/4 Sug)。全 db package 41
dbtest 130 綠、build/vet/test 綠、gitleaks 0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 04:05:53 +08:00