adding claude file and some plans

This commit is contained in:
2026-08-12 18:55:18 -06:00
parent b206964417
commit 4da16c7573
19 changed files with 1294 additions and 0 deletions
+176
View File
@@ -0,0 +1,176 @@
# 16 — Phased Roadmap
Eleven phases, each independently buildable and verifiable. A build agent starting a phase should read: `00`, `01`, `02`, the files listed for the phase, and nothing else. **Check off tasks and acceptance criteria here (and the phase box in `00-overview.md`) as they are completed and verified.**
Dependency graph: `0 → 1 → 2 → 3 → 4 → 5 → 6 → {7, 8} → 9 → 10` (7 and 8 are parallel-safe after 6).
## Phase 0 — Foundation
Spec files: [01-architecture.md](01-architecture.md), [14-design-system.md](14-design-system.md), [15-deployment.md](15-deployment.md)
- [ ] Repo skeleton per architecture layout; Go module `solopm.com/solopm-server`
- [ ] chi server + middleware chain (minus auth resolver), slog, request logging, graceful shutdown
- [ ] Config loader with full env var set + `.env.example`
- [ ] golang-migrate wired (embedded migrations) + migration 0001 (extensions + enums); sqlc configured and generating
- [ ] Vue app scaffolded (Vite, TS, Pinia, Router, Tailwind) with design system copied to `web/design-system/` and wired; AppShell (sidebar/navbar) renders
- [ ] `go:embed` SPA serving with deep-link fallback; Vite dev proxy
- [ ] docker-compose (app + postgres + meilisearch + mailhog dev profile); Makefile targets
- [ ] `/healthz`
Acceptance:
- [ ] `docker compose up` serves the SPA shell at `:4080`; `/healthz` reports db ok
- [ ] `make migrate-up && make migrate-down` cycles cleanly
- [ ] Shell passes the design-system conformity checklist
## Phase 1 — Auth & users
Spec files: [05-auth.md](05-auth.md) · Depends: 0
- [ ] Migrations: users (+seeds), oauth_accounts, sessions, api_tokens
- [ ] Register/login/logout with scs sessions; first-user-becomes-admin; rate limiting
- [ ] GitHub + Gitea OAuth (linking rules incl. verified-email guard)
- [ ] PAT create/list/revoke + bearer middleware
- [ ] `/me` endpoints, `/users` picker, admin user endpoints
- [ ] Frontend: login/register/oauth-callback pages, auth store + guard, settings→profile/security/tokens tabs, admin users page
Acceptance (scriptable with curl):
- [ ] Register → is_admin true; second register → false
- [ ] Cookie-authed and PAT-authed `GET /me` both succeed; revoked PAT → 401
- [ ] system/zombie users absent from `/users`; login as ids 12 impossible
- [ ] OAuth flow against a real or mocked provider produces a linked account (verified-email path unit-tested)
## Phase 2 — Event backbone & audit
Spec files: [03-domain-events.md](03-domain-events.md) · Depends: 1
- [ ] Migrations: audit_log, events, jobs
- [ ] `events.Emit` (audit + outbox in-tx), pg_notify, dispatcher goroutine, job worker pool with backoff/dead states
- [ ] `auth.*` and `user.*` events emitting through the pipeline
- [ ] Admin jobs inspection endpoint
Acceptance:
- [ ] Login writes an audit row and a processed event row
- [ ] `kill -9` during a pending job → job retried after restart (integration test)
- [ ] A job failing 8 times lands in `dead` and is visible via admin endpoint
## Phase 3 — Projects core
Spec files: [06-projects.md](06-projects.md) · Depends: 2
- [ ] Migrations: projects, project_members, project_dependencies, project_favorites, labels
- [ ] Project CRUD + status/completed_at automation + owner transfer + membership + favorites + label CRUD/seeding + dependencies with cycle detection
- [ ] `RequireProjectMember`/`RequireProjectOwner` middleware; non-member 404s
- [ ] Activity feed endpoints (project + dashboard)
- [ ] All mutations emit events per taxonomy
Acceptance:
- [ ] Non-member GET on another's project → 404
- [ ] Dependency cycle attempt → 409 `cycle_detected`
- [ ] Every mutation appears in `/projects/{id}/activity` with correct actor
- [ ] Sole-owner cannot be removed/deleted without transfer (409)
## Phase 4 — Issues & epics
Spec files: [07-issues-epics.md](07-issues-epics.md) · Depends: 3
- [ ] Migrations: epics, issues, issue_blockers, issue_labels, issue_watchers
- [ ] Issue CRUD, numbering, sub-issues, blockers + cycles, labels, points, completed_at automation
- [ ] board_rank helpers (`Between/Before/After`) with unit tests; `?view=board`; list filters/sort
- [ ] Epic CRUD, attach/detach/reorder issues, computed progress (counts + points)
Acceptance:
- [ ] Two projects both mint `#1`; 20 parallel creates in one project yield 20 unique consecutive numbers
- [ ] Status→done sets completed_at; back to in_progress clears it
- [ ] Blocker cycle → 409; epic progress matches a hand-computed fixture
- [ ] Board view returns rank-ordered groups; a move lands between its neighbors
## Phase 5 — Views (frontend core)
Spec files: [13-frontend.md](13-frontend.md) (+ [14-design-system.md](14-design-system.md)) · Depends: 4
- [ ] Dashboard, project list/overview, project settings (general/members/labels tabs)
- [ ] Issue table with FilterBar + URL-synced state
- [ ] Kanban board with optimistic drag-and-drop
- [ ] Issue detail page (all sidebar fields editable, sub-issues, blockers)
- [ ] Epic list/detail pages
- [ ] Stores: projects, issues, board, epics; badges/pickers/dialog components
Acceptance:
- [ ] Drag card between columns → persists after reload (status + position)
- [ ] Filters/sort survive refresh via URL; shareable link reproduces the view
- [ ] Failed PATCH rolls back the optimistic move with a toast
- [ ] New pages pass the conformity checklist
## Phase 6 — Collaboration
Spec files: [08-collaboration.md](08-collaboration.md) · Depends: 5
- [ ] Migrations: comments, links, attachments, wiki_pages
- [ ] Comments CRUD + resolve; polymorphic links/attachments + `/files/` auth-checked serving; wiki CRUD with slug rules + conflict warning
- [ ] Server-side mention/#ref extraction into event payloads; watcher auto-watch/mute semantics
- [ ] Frontend: MarkdownEditor/MarkdownView (mention + #ref autocomplete/rendering, paste-to-attach), comments UI with resolve, attachments/links UI, wiki pages, WatchButton + watcher list
Acceptance:
- [ ] `@user` in a comment produces a mention entry in the event payload; `#3` renders as a link to issue 3
- [ ] Resolving collapses the thread; unresolve restores it
- [ ] Upload lands at the specified disk path; non-member GET on `/files/…` → 404; oversized upload → 413
- [ ] Unwatch (mute) then comment again → no re-auto-watch
## Phase 7 — Notifications & real-time
Spec files: [09-notifications-realtime.md](09-notifications-realtime.md) · Depends: 6
- [ ] Migration: notifications
- [ ] Fan-out consumer (rules + precedence + dedupe), inbox/bell endpoints
- [ ] SSE hub + `/stream` + heartbeats; frontend sse.ts + realtime store + in-place updates
- [ ] SMTP sender, instant emails, daily digest job, email_mode setting UI
Acceptance:
- [ ] Two-browser test: assign in A → B's bell increments and B's board card moves within 2s, no reload
- [ ] Actor never notified of own action; `mentioned` wins precedence over `commented`
- [ ] MailHog shows instant email; digest job groups a day of notifications into one email
- [ ] Muted watcher gets neither bell nor email
## Phase 8 — Search (parallel-safe with 7)
Spec files: [10-search.md](10-search.md) · Depends: 6
- [ ] Meilisearch client, index bootstrap, event→sync mapping, `search_sync` job handler
- [ ] `/search` endpoint with membership filtering; reindex CLI + admin endpoint
- [ ] CommandPalette (Cmd+K) + `/search` page
Acceptance:
- [ ] Created issue findable in < 5s; soft-deleted issue disappears from results
- [ ] Non-member's content never appears (integration test with two users)
- [ ] `solopm reindex` rebuilds equal counts from Postgres truth
- [ ] Palette opens with Cmd+K, arrows navigate, Enter routes
## Phase 9 — Integrations
Spec files: [11-integrations.md](11-integrations.md) · Depends: 7
- [ ] Migrations: incoming_webhook_receipts, outgoing_webhooks, outgoing_webhook_deliveries
- [ ] Incoming endpoint: HMAC verify, receipts, repo routing, closes-#N automation (system user, via_webhook), replay
- [ ] Outgoing: CRUD, signed delivery jobs, delivery log, test endpoint, SSRF guard
- [ ] Export JSON + CSV streaming
- [ ] Frontend: settings→webhooks tab (secret, receipts, outgoing CRUD + deliveries), export tab
Acceptance:
- [ ] Replayed GitHub PR-merged fixture with valid signature closes `#N`; audit shows system user with via_webhook=true; bad signature → 401 with receipt logged invalid
- [ ] Duplicate delivery id → 200 without reprocessing
- [ ] Outgoing delivery retries against a flaky test receiver, then records success with correct `X-SoloPM-Signature`
- [ ] JSON export contains every entity family; CSV opens with correct columns
## Phase 10 — Retention & hardening
Spec files: [12-retention.md](12-retention.md) · Depends: 9
- [ ] Cull job + CLI + admin endpoint with dry-run; cascade scopes incl. disk files; zombie reassignment; auxiliary retention (notifications/events/jobs/receipts/deliveries)
- [ ] Backup/restore docs + drill; systemd unit example; reverse-proxy doc
- [ ] Final pass: rate limits verified, error envelope consistency, `/healthz` complete, README quickstart
Acceptance:
- [ ] Dry-run reports the exact would-delete set with zero deletions
- [ ] Culling a project removes all its rows **and** files (orphan-check test passes)
- [ ] Culled user's comments render as "Deleted User"; audit keeps original id
- [ ] Fresh-clone `docker compose up` walkthrough from the README works end-to-end