Files
ClaudeDo/docs/superpowers/plans/2026-06-10-online-inbox.md
2026-06-10 09:35:20 +02:00

3.7 KiB

Online Inbox — implementation plan

Date: 2026-06-10 Spec: docs/superpowers/specs/2026-06-10-online-inbox-design.md Contract: docs/online-inbox-api-contract.md

TDD, one commit per task, Conventional Commits. Build with -c Release per CLAUDE.md.

Phase 1 — Worker sync engine (buildable now, no Zitadel package needed)

Task 1 — Config

  • Add OnlineInboxConfig + nested ZitadelClientConfig records.
  • Add online_inbox (OnlineInbox) property to WorkerConfig; default enabled=false.
  • Load leaves it untouched when absent (defaults = disabled).
  • Test: missing section → disabled defaults; populated section round-trips.

Task 2 — DTOs + Idle-backlog helper

  • Online/Dtos.cs: RemoteList(Id, Name), RemoteTask(Id, ListId, Title, Description, CreatedAt), MirrorTask(Id, ListId, Title, Description).
  • Online/OnlineBacklog.cs: static Task<List<MirrorTask>> CurrentAsync(TaskRepository/ctx) + the filter predicate (Idle, no parent, PlanningPhase None, BlockedBy null).
  • Test the filter against real SQLite seeded with mixed tasks.

Task 3 — Auth abstraction + token store

  • Online/Interfaces/IOnlineAuthProvider.cs.
  • Online/OnlineTokenStore.cs: DPAPI CurrentUser persistence at ~/.todo-app/online-inbox.token; Save(refreshToken), Read(), Clear(). (Windows-only encryption; thin + guarded.)
  • A trivial StaticTokenAuthProvider (returns a configured token or null) for tests + as the temporary default until Zitadel is wired.
  • Test: token store round-trip (Windows); static provider returns/omits token.

Task 4 — API client

  • Online/IOnlineInboxApi.cs + Online/OnlineInboxApiClient.cs (typed HttpClient).
  • Attaches Authorization: Bearer from IOnlineAuthProvider; refuses non-HTTPS non-loopback base URLs; throws a typed OnlineInboxException on non-2xx.
  • Test with a stubbed HttpMessageHandler: each method hits the right path/verb/body; 401 surfaces; bearer attached.

Task 5 — Sync service

  • Online/OnlineSyncService.cs (BackgroundService) implementing the §5 reconcile loop.
  • DI: register only when enabled; resolve repos per-cycle via a scope.
  • Per-cycle try/catch + structured logging; skip when no token; unknown-list skip.
  • Test against a fake IOnlineInboxApi + real SQLite: pull→import→flag creates local Idle tasks; mirror payload == Idle backlog; lists pushed; unknown list skipped & not flagged; disabled/no-token = no api calls.

Task 6 — Wire-up + docs

  • Register the stack in Program.cs behind the enabled flag.
  • Update src/ClaudeDo.Worker/CLAUDE.md (new Online/ area) and src/ClaudeDo.Worker/Config notes. Add online_inbox to the config section.

Phase 2 — UI + real auth (AFTER the VPS reports client config)

Task 7 — Hub + config plumbing

  • Hub: GetOnlineInboxConfig / SetOnlineInboxConfig / SetOnlineInboxAuth(refreshToken) / ClearOnlineInboxAuth. Update IWorkerClient + WorkerClient + test fakes (both test projects — see the IWorkerClient-fakes memory).

Task 8 — Settings UI

  • "Online Inbox" section in SettingsModalViewModel: enable toggle, base URL, Sign in/out, status. Localized keys in en.json + de.json (parity).
  • Visual verification = manual (flag it).

Task 9 — ZitadelAuthProvider

  • Add the Zitadel package reference; implement ZitadelAuthProvider (refresh-token → access token, cached to expiry) using the reported authority/client-id/flow.
  • Swap it in for StaticTokenAuthProvider in DI when enabled.
  • Manual smoke against the live VPS API (tracked, not an automated test).

Notes

  • No real network / no real Zitadel / no real Claude in any automated test.
  • Stage files by explicit path in subagents; sonnet model; build+test+commit by the orchestrator.