diff --git a/.mosaic/orchestrator/mission.json b/.mosaic/orchestrator/mission.json index 9175d8a..8b95e42 100644 --- a/.mosaic/orchestrator/mission.json +++ b/.mosaic/orchestrator/mission.json @@ -1,14 +1,69 @@ { "schema_version": 1, - "mission_id": "prd-implementation-20260222", - "name": "PRD implementation", - "description": "", + "mission_id": "ms21-multi-tenant-rbac-data-migration-20260228", + "name": "MS21 Multi-Tenant RBAC Data Migration", + "description": "Build multi-tenant user/workspace/team management, break-glass auth, RBAC UI enforcement, and migrate jarvis-brain data into Mosaic Stack", "project_path": "/home/jwoltje/src/mosaic-stack", - "created_at": "2026-02-23T03:20:55Z", + "created_at": "2026-02-28T17:10:22Z", "status": "active", - "task_prefix": "", - "quality_gates": "", - "milestone_version": "0.0.20", - "milestones": [], + "task_prefix": "MS21", + "quality_gates": "pnpm lint && pnpm build && pnpm test", + "milestone_version": "0.0.21", + "milestones": [ + { + "id": "phase-1", + "name": "Schema and Admin API", + "status": "pending", + "branch": "schema-and-admin-api", + "issue_ref": "", + "started_at": "", + "completed_at": "" + }, + { + "id": "phase-2", + "name": "Break-Glass Authentication", + "status": "pending", + "branch": "break-glass-authentication", + "issue_ref": "", + "started_at": "", + "completed_at": "" + }, + { + "id": "phase-3", + "name": "Data Migration", + "status": "pending", + "branch": "data-migration", + "issue_ref": "", + "started_at": "", + "completed_at": "" + }, + { + "id": "phase-4", + "name": "Admin UI", + "status": "pending", + "branch": "admin-ui", + "issue_ref": "", + "started_at": "", + "completed_at": "" + }, + { + "id": "phase-5", + "name": "RBAC UI Enforcement", + "status": "pending", + "branch": "rbac-ui-enforcement", + "issue_ref": "", + "started_at": "", + "completed_at": "" + }, + { + "id": "phase-6", + "name": "Verification", + "status": "pending", + "branch": "verification", + "issue_ref": "", + "started_at": "", + "completed_at": "" + } + ], "sessions": [] } diff --git a/docs/MISSION-MANIFEST.md b/docs/MISSION-MANIFEST.md index b1a999e..ed22e85 100644 --- a/docs/MISSION-MANIFEST.md +++ b/docs/MISSION-MANIFEST.md @@ -1,81 +1,52 @@ -# Mission Manifest — MS20 Site Stabilization +# Mission Manifest — MS21 Multi-Tenant RBAC Data Migration > Persistent document tracking full mission scope, status, and session history. > Updated by the orchestrator at each phase transition and milestone completion. ## Mission -**ID:** ms20-site-stabilization-20260227 -**Statement:** Fix runtime bugs, missing API endpoints, orchestrator connectivity, and feature gaps discovered during live site testing at mosaic.woltje.com -**Phase:** Complete -**Current Milestone:** MS20-SiteStabilization -**Progress:** 1 / 1 milestones -**Status:** completed -**Last Updated:** 2026-02-27T12:15Z +**ID:** ms21-multi-tenant-rbac-data-migration-20260228 +**Statement:** Build multi-tenant user/workspace/team management, break-glass auth, RBAC UI enforcement, and migrate jarvis-brain data into Mosaic Stack +**Phase:** Intake +**Current Milestone:** — +**Progress:** 0 / 6 milestones +**Status:** active +**Last Updated:** 2026-02-28 17:10 UTC ## Success Criteria -1. Domains page: can create and list domains without workspace errors — **PASS** (PR #536) -2. Projects page: can create new projects without workspace errors — **PASS** (already working) -3. Personalities page: full CRUD works with proper dark mode theming — **PASS** (PR #537, #540) -4. User preferences endpoint (`/users/me/preferences`) returns data — **PASS** (PR #539) -5. Credentials page: can add, view credentials (not just disabled stub) — **PASS** (PR #545) -6. Orchestrator proxy endpoints return real data (no 502) — **PASS** (PR #542; 502s remain because orchestrator service not active in prod, but proxy route works) -7. Orchestrator WebSocket connects successfully — **PASS** (PR #547, #548, #549) -8. Dashboard Agent Status, Task Progress, Orchestrator Events widgets work — **PARTIAL** (widgets render, but orchestrator service not active in prod so data endpoints return 502) -9. Terminal has dedicated `/terminal` page route — **PASS** (PR #538) -10. favicon.ico serves correctly (no 404) — **PASS** (PR #541, #544) -11. `useWorkspaceId` warning resolved — workspace ID persists in localStorage — **PASS** (already in main via auth-context.tsx) -12. All 5 themes render correctly on all affected pages — **PASS** (verified dark mode on personalities, credentials, domains, dashboard) -13. Lint, typecheck, and tests pass — **PASS** (pipeline 680 green — 1445 web tests, 3316 API tests) -14. Deployed and verified at mosaic.woltje.com — **PASS** (Portainer stack 121 redeployed, all pages verified) - -## Existing Infrastructure - -Key components already built that MS20 builds upon: - -| Component | Status | Location | -| ------------------------- | --------------- | ----------------------------------------------- | -| WorkspaceGuard | Working | `apps/api/src/common/guards/workspace.guard.ts` | -| Auto-detect workspace ID | Working (reads) | `apps/web/src/lib/api/client.ts` | -| Credentials API backend | Built (M7) | `apps/api/src/credentials/` | -| Orchestrator proxy routes | Fixed (MS20) | `apps/web/src/app/api/orchestrator/` | -| Terminal components | Built (MS19) | `apps/web/src/components/terminal/` | -| Theme system | Working (MS18) | `apps/web/src/lib/themes/` | + ## Milestones -| # | ID | Name | Status | Branch | Issue | Started | Completed | -| --- | ---- | ------------------ | --------- | ------------------------- | ----- | ---------- | ---------- | -| 1 | MS20 | Site Stabilization | completed | per-task feature branches | #534 | 2026-02-27 | 2026-02-27 | +| # | ID | Name | Status | Branch | Issue | Started | Completed | +| --- | ------- | -------------------------- | ------- | ------ | ----- | ------- | --------- | +| 1 | phase-1 | Schema and Admin API | pending | — | — | — | — | +| 2 | phase-2 | Break-Glass Authentication | pending | — | — | — | — | +| 3 | phase-3 | Data Migration | pending | — | — | — | — | +| 4 | phase-4 | Admin UI | pending | — | — | — | — | +| 5 | phase-5 | RBAC UI Enforcement | pending | — | — | — | — | +| 6 | phase-6 | Verification | pending | — | — | — | — | ## Deployment -| Target | URL | Method | -| --------- | ----------------- | --------------------------- | -| Portainer | mosaic.woltje.com | CI/CD pipeline (Woodpecker) | +| Target | URL | Method | +| ------ | --- | ------ | +| — | — | — | ## Token Budget -| Metric | Value | -| ------ | -------------------- | -| Budget | ~400K (estimated) | -| Used | ~263K (across S1-S4) | -| Mode | normal | +| Metric | Value | +| ------ | ------ | +| Budget | — | +| Used | 0 | +| Mode | normal | ## Session History -| Session | Runtime | Started | Duration | Ended Reason | Last Task | -| ------- | --------------- | ----------------- | -------- | ------------------ | -------------------- | -| S1 | Claude Opus 4.6 | 2026-02-27T05:30Z | ~30m | Planning done | PLAN-001 | -| S2 | Claude Opus 4.6 | 2026-02-27T06:00Z | ~2h | Context exhaustion | 5 workers dispatched | -| S3 | Claude Opus 4.6 | 2026-02-27T08:00Z | ~1.5h | Context exhaustion | Recovery + 2 workers | -| S4 | Claude Opus 4.6 | 2026-02-27T10:30Z | ~2h | Mission complete | VER-001 + DOC-001 | - -## PRs Merged - -13 code PRs + 1 docs PR = 14 total: #536, #537, #538, #539, #540, #541, #542, #543, #544, #545, #547, #548, #549 +| Session | Runtime | Started | Duration | Ended Reason | Last Task | +| ------- | ------- | ------- | -------- | ------------ | --------- | ## Scratchpad -Path: `docs/scratchpads/ms20-site-stabilization-20260227.md` +Path: `docs/scratchpads/ms21-multi-tenant-rbac-data-migration-20260228.md` diff --git a/docs/PRD-MS21.md b/docs/PRD-MS21.md new file mode 100644 index 0000000..aa0b66f --- /dev/null +++ b/docs/PRD-MS21.md @@ -0,0 +1,246 @@ +# PRD: MS21 — Multi-Tenant Platform, RBAC Enforcement, and Data Migration + +## Metadata + +- Owner: Jason Woltje +- Orchestrator: Jarvis (OpenClaw) +- Date: 2026-02-28 +- Status: in-progress +- Version: 0.0.21 + +## Problem Statement + +Mosaic Stack is a single-user deployment. The Workspace, Team, WorkspaceMember, and RBAC infrastructure exist in the schema and codebase (PermissionGuard, WorkspaceGuard, roles: OWNER/ADMIN/MEMBER/GUEST), but there is no admin UI for managing users, workspaces, or teams. There is no invitation flow, no user management page, and no break-glass authentication mechanism for emergency access without OIDC. Additionally, the platform has no real operational data — jarvis-brain contains 106 projects and 95 tasks that need migrating into Mosaic Stack to make the dashboard, kanban, and project pages useful. + +## Objectives + +1. Build admin UI for user management (list, invite, deactivate, assign roles) +2. Build workspace management UI (create, configure, manage members) +3. Build team management UI (create teams within workspaces, assign members) +4. Implement user invitation flow (email or link-based) +5. Implement break-glass local authentication (bypass OIDC for emergency access) +6. Enforce RBAC across all UI surfaces (show/hide based on role) +7. Build admin Settings pages for workspace and platform configuration +8. Migrate jarvis-brain data (95 tasks, 106 projects) into Mosaic Stack PostgreSQL +9. Build data import API endpoint for bulk task/project creation + +## Completed Work + +### Existing Infrastructure (Already Built) + +| Component | Status | Location | +| ----------------------------------------------------------------- | -------- | ------------------------------------------------------- | +| Prisma models: User, Workspace, WorkspaceMember, Team, TeamMember | Complete | apps/api/prisma/schema.prisma | +| WorkspaceMemberRole enum (OWNER, ADMIN, MEMBER, GUEST) | Complete | schema.prisma | +| TeamMemberRole enum (OWNER, ADMIN, MEMBER) | Complete | schema.prisma | +| PermissionGuard with role hierarchy | Complete | apps/api/src/common/guards/permission.guard.ts | +| Permission decorator (@RequirePermission) | Complete | apps/api/src/common/decorators/permissions.decorator.ts | +| Permission enum (WORKSPACE_OWNER, ADMIN, MEMBER, ANY) | Complete | permissions.decorator.ts | +| WorkspaceGuard | Complete | apps/api/src/common/guards/workspace.guard.ts | +| RBAC applied to 18+ controllers | Complete | All resource controllers | +| Workspaces CRUD API | Complete | apps/api/src/workspaces/ | +| BetterAuth + Authentik OIDC | Complete | apps/api/src/auth/ | +| AdminGuard | Complete | apps/api/src/auth/guards/admin.guard.ts | + +## Scope + +### In Scope (MS21) + +#### S1: Admin API Endpoints (Backend) + +1. GET /api/admin/users — List all users with workspace memberships and roles +2. POST /api/admin/users/invite — Generate invitation (email or link) +3. PATCH /api/admin/users/:id — Update user metadata (deactivate, change global role) +4. DELETE /api/admin/users/:id — Deactivate user (soft delete, preserve data) +5. POST /api/admin/workspaces — Create workspace with owner assignment +6. PATCH /api/admin/workspaces/:id — Update workspace settings +7. POST /api/workspaces/:id/members — Add member to workspace with role +8. PATCH /api/workspaces/:id/members/:userId — Change member role +9. DELETE /api/workspaces/:id/members/:userId — Remove member from workspace +10. POST /api/workspaces/:id/teams — Create team within workspace +11. POST /api/workspaces/:id/teams/:teamId/members — Add member to team +12. DELETE /api/workspaces/:id/teams/:teamId/members/:userId — Remove from team +13. POST /api/import/tasks — Bulk import tasks from jarvis-brain format +14. POST /api/import/projects — Bulk import projects from jarvis-brain format + +#### S2: Break-Glass Authentication + +15. Add isLocalAuth boolean field to User model (Prisma migration) +16. Add passwordHash optional field to User model (for local auth users) +17. Implement /api/auth/local/login endpoint (email + password, bcrypt) +18. Implement /api/auth/local/setup endpoint (first-time break-glass user creation, requires admin token from env) +19. Break-glass user bypasses OIDC entirely — session-based auth via BetterAuth +20. Environment variable BREAKGLASS_SETUP_TOKEN controls initial setup access + +#### S3: Admin UI Pages (Frontend) + +21. /settings/users — User management page (table: name, email, role, status, workspaces, last login) +22. User detail/edit dialog (change role, deactivate, view workspace memberships) +23. Invite user dialog (email input, workspace selection, role selection) +24. /settings/workspaces — Workspace management page (list workspaces, member counts) +25. Workspace detail page (members list, team list, settings) +26. Add/remove workspace member dialog with role picker +27. /settings/teams — Team management within workspace context +28. Create team dialog, add/remove team members + +#### S4: RBAC UI Enforcement + +29. Navigation sidebar: show/hide admin items based on user role +30. Settings pages: restrict access to admin-only pages +31. Action buttons: disable/hide create/delete based on permission level +32. User profile: show current role and workspace memberships + +#### S5: Data Migration + +33. Build scripts/migrate-brain.ts — TypeScript migration script +34. Read jarvis-brain data/tasks/\*.json (v2.0 format: { version, domain, tasks: [...] }) +35. Read jarvis-brain data/projects/\*.json (format: { version, project: {...}, tasks: [...] }) +36. Map brain status to Mosaic TaskStatus (done->COMPLETED, in-progress->IN_PROGRESS, backlog/pending/scheduled/not-started/planned->NOT_STARTED, blocked/on-hold->PAUSED, cancelled->ARCHIVED) +37. Map brain priority to Mosaic TaskPriority (critical/high->HIGH, medium->MEDIUM, low->LOW) +38. Create Domain records for unique domains (work, homelab, finances, family, etc.) +39. Create Project records from project data, linking to domains +40. Create Task records linking to projects, preserving brain-specific fields in metadata JSON +41. Preserve blocks, blocked_by, repo, branch, current_milestone, notes in task/project metadata +42. Dry-run mode with validation report before actual import +43. Idempotent — skip records that already exist (match by metadata.brainId) + +### Out of Scope + +- Federation (MS22) +- Agent task mapping and telemetry (MS23) +- Playwright E2E tests (MS24) +- Email delivery service (invitations stored as links for now) +- User self-registration (admin-only invitation model) + +## User/Stakeholder Requirements + +1. Jason (admin) can invite Melanie to a shared workspace +2. Jason can create a "USC IT" workspace and invite employees +3. Each user sees only their workspace(s) data +4. Break-glass user can log in without Authentik being available +5. Admin pages are only visible to OWNER/ADMIN roles +6. Data from jarvis-brain appears in the dashboard, kanban, and project pages after migration +7. All existing tests continue to pass after changes + +## Functional Requirements + +### FR-001: Admin User Management API + +- AdminGuard protects all /api/admin/\* routes +- List users returns: id, name, email, emailVerified, createdAt, workspace memberships with roles +- Invite creates a User record with a pending invitation token +- Deactivate sets a deactivatedAt timestamp (new field), does not delete data +- ASSUMPTION: User deactivation is soft-delete via new deactivatedAt field on User model. Rationale: Hard delete would cascade and destroy workspace data. + +### FR-002: Workspace Member Management API + +- Add member requires WORKSPACE_ADMIN or WORKSPACE_OWNER permission +- Role changes require equal or higher permission (MEMBER cannot promote to ADMIN) +- Cannot remove the last OWNER of a workspace +- Cannot change own role to lower than OWNER if sole owner + +### FR-003: Break-Glass Authentication + +- Local auth is opt-in per deployment via ENABLE_LOCAL_AUTH=true env var +- Break-glass setup requires a one-time setup token from environment +- Password stored as bcrypt hash, minimum 12 characters +- Break-glass user gets OWNER role on default workspace +- Session management identical to OIDC users (BetterAuth session tokens) +- ASSUMPTION: BetterAuth supports custom credential providers alongside OIDC. Rationale: BetterAuth documentation confirms credential-based auth as a built-in feature. + +### FR-004: Admin UI + +- User management table with search, sort, filter by role/status +- Inline role editing via dropdown +- Confirmation dialog for destructive actions (deactivate user, remove from workspace) +- PDA-friendly language: "Deactivate" not "Delete", "Pending" not "Expired" +- Responsive design matching existing Settings page patterns +- Dark/light theme support via existing design token system + +### FR-005: Data Migration Script + +- Standalone TypeScript script in scripts/migrate-brain.ts +- Reads from jarvis-brain path (configurable via --brain-path flag) +- Connects to Mosaic Stack database via DATABASE_URL +- Requires target workspace ID (--workspace-id flag) +- Requires creator user ID (--user-id flag) +- Outputs validation report before writing (dry-run by default) +- --apply flag to execute the migration +- Creates Activity log entries for all imported records + +## Technical Design + +### Schema Changes (Prisma Migration) + +Add to User model: + +- deactivatedAt DateTime? (soft delete) +- isLocalAuth Boolean default(false) +- passwordHash String? (bcrypt hash for local auth) +- invitedBy String? Uuid (FK to inviting user) +- invitationToken String? unique +- invitedAt DateTime? + +### New NestJS Module: AdminModule + +Location: apps/api/src/admin/ +Files: admin.module.ts, admin.controller.ts, admin.service.ts, DTOs, specs + +### New NestJS Module: LocalAuthModule (Break-Glass) + +Location: apps/api/src/auth/local/ +Files: local-auth.controller.ts, local-auth.service.ts, DTOs, specs + +### Frontend Pages + +Location: apps/web/app/(authenticated)/settings/ + +- users/page.tsx — User management +- workspaces/page.tsx — Workspace list +- workspaces/[id]/page.tsx — Workspace detail (members, teams) +- teams/page.tsx — Team management + +## Testing and Verification + +1. Baseline: pnpm lint && pnpm build && pnpm test must pass +2. Unit tests for AdminService (user CRUD, invitation flow, permission checks) +3. Unit tests for LocalAuthService (bcrypt hashing, token validation) +4. Unit tests for AdminController (route guards, DTO validation) +5. Integration test: invitation -> acceptance -> workspace access +6. Integration test: break-glass setup -> login -> workspace access +7. Integration test: RBAC prevents unauthorized role changes +8. Migration script test: dry-run produces valid report, apply creates correct records +9. Frontend: admin pages render with correct role gating +10. All 4,772+ existing tests continue to pass + +## Quality Gates + +pnpm lint && pnpm build && pnpm test + +## Delivery Phases + +| Phase | Focus | Tasks | +| ----------------------- | ----------------------------------------------------------------------- | ----------------- | +| P1: Schema + Admin API | Prisma migration, AdminModule, user/workspace/team management endpoints | S1 items 1-12 | +| P2: Break-Glass Auth | LocalAuthModule, credential provider, setup flow | S2 items 15-20 | +| P3: Data Migration | Migration script, jarvis-brain to PostgreSQL | S5 items 33-43 | +| P4: Admin UI | Settings pages for users, workspaces, teams | S3 items 21-28 | +| P5: RBAC UI Enforcement | Frontend permission gating, navigation filtering | S4 items 29-32 | +| P6: Verification | Full test pass, deployment, smoke test | All quality gates | + +## Risks and Open Questions + +1. Risk: BetterAuth credential provider may require specific adapter configuration. Mitigation: Review BetterAuth docs for credential auth alongside OIDC; test in isolation first. +2. Risk: Schema migration on production database. Mitigation: Use Prisma migration with --create-only for review before applying. +3. Risk: jarvis-brain data has fields that don't map 1:1 to Mosaic schema. Mitigation: Use metadata JSON field for overflow; validate with dry-run. +4. Open: Should deactivated users retain active sessions? ASSUMPTION: No, deactivation immediately invalidates all sessions. Rationale: Security best practice. +5. Open: Should break-glass user be auto-created on first deployment? ASSUMPTION: No, requires explicit setup via API with env token. Rationale: Prevents accidental exposure. + +## Assumptions + +1. User deactivation is soft-delete via deactivatedAt field. Hard delete cascades and destroys workspace data. +2. BetterAuth supports custom credential providers alongside OIDC. +3. Invitation flow uses link-based tokens (no email service required initially). +4. Break-glass auth is off by default, controlled by ENABLE_LOCAL_AUTH env var. +5. Migration script runs outside the API server as a standalone script. +6. Admin pages follow existing Settings page UI patterns (cards, tables, dialogs). diff --git a/docs/TASKS.md b/docs/TASKS.md index 906a127..71c2883 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -1,70 +1,37 @@ -# Tasks — MS20 Site Stabilization +# Tasks — MS21 Multi-Tenant RBAC Data Migration -> Single-writer: orchestrator only. Workers read but never modify. +> Single-writer: orchestrator (Jarvis/OpenClaw) only. Workers read but never modify. -| id | status | description | issue | repo | branch | depends_on | blocks | agent | started_at | completed_at | estimate | used | notes | -| ----------- | ----------- | ---------------------------------------------------------------------------------------- | ----- | ------- | ----------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------ | ------------ | ---------- | ------------ | -------- | ---- | ------------------------------------------------------------------------------------------- | -| SS-PLAN-001 | done | Plan MS20 task breakdown, create milestone + issues, populate TASKS.md | — | — | — | | SS-WS-001,SS-ORCH-001,SS-API-001,SS-UI-001 | orchestrator | 2026-02-27 | 2026-02-27 | 15K | ~15K | Planning complete | -| SS-WS-001 | done | Fix workspace context for domain creation — domains page POST sends workspace ID | #534 | web | fix/workspace-domain-project-create | SS-PLAN-001 | SS-WS-002 | worker-1 | 2026-02-27 | 2026-02-27 | 15K | ~37K | PR #536 merged. CreateDomainDialog + wsId threading. QA remediated | -| SS-WS-002 | done | Fix workspace context for project creation — projects page POST sends workspace ID | #534 | web | fix/workspace-domain-project-create | SS-WS-001 | SS-VER-001 | worker-1 | 2026-02-27 | 2026-02-27 | 10K | 0K | Already working — projects/page.tsx uses useWorkspaceId correctly | -| SS-WS-003 | done | Fix useWorkspaceId localStorage initialization — ensure workspace ID persists from login | #534 | web | — | SS-PLAN-001 | SS-VER-001 | — | 2026-02-27 | 2026-02-27 | 15K | 0K | Already in main — auth-context.tsx has WORKSPACE_STORAGE_KEY persistence. PR #546 closed. | -| SS-ORCH-001 | done | Fix orchestrator 502 — diagnose and fix proxy connectivity to orchestrator service | #534 | web,api | fix/orchestrator-connectivity | SS-PLAN-001 | SS-ORCH-002 | worker-6 | 2026-02-27 | 2026-02-27 | 25K | ~30K | PR #542 merged. Proxy config + CORS + health endpoint. | -| SS-ORCH-002 | done | Fix WebSocket "Reconnecting to server..." — cookie auth + CORS + withCredentials | #534 | web,api | fix/websocket-reconnect | SS-ORCH-001 | SS-VER-001 | worker-8 | 2026-02-27 | 2026-02-27 | 15K | ~25K | PR #547 merged (auth fix), PR #548 (test), PR #549 (CORS origins). All green. | -| SS-API-001 | done | Implement personalities API — controller, service, DTOs, Prisma model for CRUD | #534 | api | feat/personalities-api | SS-PLAN-001 | SS-UI-002 | worker-2 | 2026-02-27 | 2026-02-27 | 30K | ~45K | PR #537 merged. Full CRUD, migration, field mapping. Review: 3 should-fix logged | -| SS-API-002 | done | Implement /users/me/preferences endpoint — wire to UserPreference model | #534 | api | feat/user-preferences-endpoint | SS-PLAN-001 | SS-VER-001 | worker-4 | 2026-02-27 | 2026-02-27 | 15K | ~18K | PR #539 merged. Added PATCH endpoint + fixed /api prefix in profile/appearance pages | -| SS-UI-001 | done | Credential management UI — enable Add Credential button, create/view forms, wire to API | #534 | web | feat/credential-management-ui | SS-PLAN-001 | SS-VER-001 | worker-9 | 2026-02-27 | 2026-02-27 | 25K | ~25K | PR #545 merged. Full CRUD forms, credential type switching, API wiring. | -| SS-UI-002 | done | Fix personalities page — dark mode Formality dropdown, save functionality, wire to API | #534 | web | fix/personalities-page | SS-API-001 | SS-VER-001 | worker-5 | 2026-02-27 | 2026-02-27 | 15K | ~10K | PR #540 merged. Select dark mode, 204 handler, deletePersonality type. Review: 3 should-fix | -| SS-UI-003 | done | Terminal page route — create /terminal page with full-screen terminal panel | #534 | web | feat/terminal-page-route | SS-PLAN-001 | SS-VER-001 | worker-3 | 2026-02-27 | 2026-02-27 | 10K | ~15K | PR #538 merged. /terminal page + sidebar link. Review: 2 should-fix logged | -| SS-UI-004 | done | Add favicon.ico and fix dark mode polish | #534 | web | fix/favicon-polish | SS-PLAN-001 | SS-VER-001 | worker-7 | 2026-02-27 | 2026-02-27 | 5K | ~8K | PR #541 merged. favicon.ico added + layout metadata | -| SS-VER-001 | done | Verification — full site test, deploy, smoke test | #534 | web,api | fix/websocket-cors-origins | SS-WS-002,SS-WS-003,SS-ORCH-002,SS-API-002,SS-UI-001,SS-UI-002,SS-UI-003,SS-UI-004 | SS-DOC-001 | orchestrator | 2026-02-27 | 2026-02-27 | 15K | ~20K | All pages verified. PR #548 test fix, PR #549 CORS fix. Deployed pipeline 680. | -| SS-DOC-001 | in-progress | Documentation — update PRD status, manifest, scratchpad, close mission | #534 | — | — | SS-VER-001 | | orchestrator | 2026-02-27 | | 5K | | | - -## Summary - -| Metric | Value | -| --------------- | ---------------------- | -| Total tasks | 14 | -| Completed | 13 | -| In Progress | 1 (SS-DOC-001) | -| Remaining | 0 | -| Estimated total | ~215K tokens | -| Used | ~263K tokens | -| Milestone | MS20-SiteStabilization | - -## Dependency Graph - -``` -PLAN-001 ✓ ──┬──→ WS-001 ✓ ──→ WS-002 ✓ ──→ VER-001 ✓ ──→ DOC-001 (in-progress) - │ - ├──→ WS-003 ✓ ──→ VER-001 ✓ - │ - ├──→ ORCH-001 ✓ ──→ ORCH-002 ✓ ──→ VER-001 ✓ - │ - ├──→ API-001 ✓ ──→ UI-002 ✓ ──→ VER-001 ✓ - │ - ├──→ API-002 ✓ ──→ VER-001 ✓ - │ - ├──→ UI-001 ✓ ──→ VER-001 ✓ - │ - ├──→ UI-003 ✓ ──→ VER-001 ✓ - │ - └──→ UI-004 ✓ ──→ VER-001 ✓ -``` - -## PRs Merged (14 total) - -| PR | Title | Branch | -| ---- | ------------------------------------------------------------------ | ----------------------------------- | -| #536 | fix(web): add workspace context to domain creation | fix/workspace-domain-project-create | -| #537 | feat(api): implement personalities CRUD API | feat/personalities-api | -| #538 | feat(web): add dedicated /terminal page route | feat/terminal-page-route | -| #539 | feat(api): implement /users/me/preferences endpoint | feat/user-preferences-endpoint | -| #540 | fix(web): fix personalities page dark mode theming and wire to API | fix/personalities-page | -| #541 | fix(web): add favicon.ico | fix/favicon-polish | -| #542 | fix(web,api): fix orchestrator proxy 502 connectivity | fix/orchestrator-connectivity | -| #543 | chore(orchestrator): update MS20 task tracking for S3 | — | -| #544 | fix(web): convert favicon.ico to RGBA format for Turbopack | fix/favicon-rgba | -| #545 | feat(web): implement credential management UI | feat/credential-management-ui | -| #547 | fix(web,api): fix WebSocket authentication for chat real-time | fix/websocket-reconnect | -| #548 | fix(web): update useWebSocket test for withCredentials | fix/websocket-test-assertion | -| #549 | fix(api): use getTrustedOrigins() for WebSocket CORS | fix/websocket-cors-origins | +| id | status | milestone | description | pr | agent | notes | +| ------------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------- | --- | ------------ | ------------------------------- | +| MS21-PLAN-001 | done | phase-1 | Write PRD, init mission, populate TASKS.md | — | orchestrator | PRD at docs/PRD-MS21.md | +| MS21-DB-001 | not-started | phase-1 | Prisma migration: add deactivatedAt, isLocalAuth, passwordHash, invitedBy, invitationToken, invitedAt to User model | — | — | Schema changes for auth + admin | +| MS21-API-001 | not-started | phase-1 | AdminModule: admin.module.ts, admin.service.ts, admin.controller.ts with AdminGuard | — | — | Full CRUD for user management | +| MS21-API-002 | not-started | phase-1 | Admin user endpoints: GET /admin/users, POST /admin/users/invite, PATCH /admin/users/:id, DELETE /admin/users/:id | — | — | Requires MS21-DB-001 | +| MS21-API-003 | not-started | phase-1 | Workspace member management: POST/PATCH/DELETE /workspaces/:id/members endpoints | — | — | Role hierarchy enforcement | +| MS21-API-004 | not-started | phase-1 | Team management: POST /workspaces/:id/teams, team member CRUD | — | — | Extends existing Team model | +| MS21-API-005 | not-started | phase-1 | Admin workspace endpoints: POST/PATCH /admin/workspaces with owner assignment | — | — | | +| MS21-TEST-001 | not-started | phase-1 | Unit tests for AdminService and AdminController (spec files) | — | — | Minimum coverage: 85% | +| MS21-AUTH-001 | not-started | phase-2 | LocalAuthModule: local-auth.controller.ts, local-auth.service.ts | — | — | bcrypt password hashing | +| MS21-AUTH-002 | not-started | phase-2 | Break-glass setup endpoint: /api/auth/local/setup with BREAKGLASS_SETUP_TOKEN validation | — | — | First-time admin creation | +| MS21-AUTH-003 | not-started | phase-2 | Break-glass login endpoint: /api/auth/local/login with session creation | — | — | BetterAuth session compat | +| MS21-AUTH-004 | not-started | phase-2 | Deactivation session invalidation: deactivating user kills all active sessions | — | — | Security requirement | +| MS21-TEST-002 | not-started | phase-2 | Unit tests for LocalAuthService and LocalAuthController | — | — | | +| MS21-MIG-001 | not-started | phase-3 | Migration script: scripts/migrate-brain.ts — read jarvis-brain data files | — | — | v2.0 format parsing | +| MS21-MIG-002 | not-started | phase-3 | Migration mapping: status/priority/domain mapping + metadata preservation | — | — | See PRD field mapping | +| MS21-MIG-003 | not-started | phase-3 | Migration execution: dry-run + apply modes, idempotent, activity logging | — | — | | +| MS21-MIG-004 | not-started | phase-3 | Import API endpoints: POST /api/import/tasks, POST /api/import/projects | — | — | For future bulk imports | +| MS21-TEST-003 | not-started | phase-3 | Migration script tests: validate dry-run output, mapping accuracy | — | — | | +| MS21-UI-001 | not-started | phase-4 | Settings/users page: user management table with search, sort, filter | — | — | | +| MS21-UI-002 | not-started | phase-4 | User detail/edit dialog and invite user dialog | — | — | | +| MS21-UI-003 | not-started | phase-4 | Settings/workspaces page: workspace list, member counts, detail view | — | — | | +| MS21-UI-004 | not-started | phase-4 | Workspace member management: add/remove dialog with role picker | — | — | | +| MS21-UI-005 | not-started | phase-4 | Settings/teams page: team list, create dialog, member management | — | — | | +| MS21-TEST-004 | not-started | phase-4 | Frontend component tests for admin pages | — | — | | +| MS21-RBAC-001 | not-started | phase-5 | Sidebar navigation: show/hide admin items based on user role | — | — | | +| MS21-RBAC-002 | not-started | phase-5 | Settings pages: restrict access to admin-only routes | — | — | | +| MS21-RBAC-003 | not-started | phase-5 | Action buttons: disable/hide based on permission level | — | — | | +| MS21-RBAC-004 | not-started | phase-5 | User profile: show current role and workspace memberships | — | — | | +| MS21-VER-001 | not-started | phase-6 | Full quality gate pass: pnpm lint && pnpm build && pnpm test | — | — | All 4772+ tests + new | +| MS21-VER-002 | not-started | phase-6 | Deploy to mosaic.woltje.com, smoke test all pages | — | — | | +| MS21-VER-003 | not-started | phase-6 | Tag v0.0.21, update PRD status to complete | — | — | | diff --git a/docs/scratchpads/ms21-multi-tenant-rbac-data-migration-20260228.md b/docs/scratchpads/ms21-multi-tenant-rbac-data-migration-20260228.md new file mode 100644 index 0000000..1365799 --- /dev/null +++ b/docs/scratchpads/ms21-multi-tenant-rbac-data-migration-20260228.md @@ -0,0 +1,49 @@ +# Mission Scratchpad — MS21 Multi-Tenant RBAC Data Migration + +> Append-only log. NEVER delete entries. NEVER overwrite sections. + +## Original Mission Prompt + +``` +Build multi-tenant user/workspace/team management with admin UI, break-glass +local authentication (bypass OIDC for emergencies), enforce RBAC across all +UI surfaces, and migrate jarvis-brain data (95 tasks, 106 projects) into +Mosaic Stack PostgreSQL. This unlocks multi-user access for Melanie and +USC employees. +``` + +## Planning Decisions + +### 2026-02-28 — Initial Planning (Orchestrator: Jarvis/OpenClaw) + +1. **Phase order**: Schema+API first, then break-glass auth, then data migration, then UI, then RBAC enforcement, then verification. Rationale: Backend must exist before frontend can wire to it; migration can run independently once schema is ready. + +2. **Worker strategy**: Up to 6 parallel workers (2 Claude, 2 Codex, 2 GLM). Claude for complex multi-file implementations. Codex for targeted single-file tasks. GLM for documentation and test writing. + +3. **Phase 1 parallelization plan**: + - Worker A (Claude): MS21-DB-001 (Prisma migration) — must complete first + - After DB-001 done: + - Worker B (Claude): MS21-API-001 + MS21-API-002 (AdminModule + user endpoints) + - Worker C (Codex): MS21-API-003 (workspace member management) + - Worker D (Codex): MS21-API-004 (team management) + - Worker E (Claude): MS21-API-005 (admin workspace endpoints) + - Worker F (GLM): MS21-TEST-001 (unit tests for admin module) + +4. **PRD location**: docs/PRD-MS21.md (separate from main PRD.md to preserve history) + +5. **Orchestrator is Jarvis (OpenClaw)** — not a Claude Code session. This is the first hybrid orchestration: OpenClaw manages mission, dispatches workers via mosaic yolo claude, codex exec, and OpenClaw subagents. + +## Session Log + +| Session | Date | Milestone | Tasks Done | Outcome | +| ------- | ---------- | --------- | ------------- | --------------------------------------------- | +| S1 | 2026-02-28 | Planning | MS21-PLAN-001 | PRD written, mission init, TASKS.md populated | + +## Open Questions + +- BetterAuth credential provider config alongside OIDC — needs verification in worker task +- Exact sidebar items to gate behind admin role — review during RBAC phase + +## Corrections + +(none yet)