Skip to content

feat: ctrl role permission matrix and surface access control #89

@ssilvius

Description

@ssilvius

Goal

Implement role-based access control across all ctrl surfaces and display the permission matrix.

Requirements

  • apps/ctrl/src/routes/_ctrl/settings/roles.tsx: roles tab showing permission matrix table
  • Permission matrix: rows = surfaces (Dashboard, Content, Email, Listen, Team, Analytics, Settings/*), columns = roles (admin, member, viewer), cells = access level (full, read/write, read, none)
  • apps/ctrl/src/lib/permissions.ts: typed permission constant defining the matrix. Used by both UI and route guards
  • Surface route guards: each _ctrl surface route's beforeLoad checks capabilities.role against permissions. Unauthorized: redirect to /ctrl with toast "You don't have access to [surface]"
  • API route guards: extend requireOrgRole usage across all ctrl API routes per the matrix:
    • admin: all access
    • member: content r/w, email r/w, team r/w, listen r, analytics r
    • viewer: dashboard r, team r, listen r

Out of Scope

  • Custom role creation
  • Per-resource permissions (e.g., per-mailbox access)

Complete when: Permission matrix displays in settings, all surface routes enforce role-based access, API routes enforce role middleware.

Dev Workflow

Each step is mandatory. No exceptions. No skipping steps. No committing to main. No solo merges.

  1. Branch -- Create feat/<issue#>-<description> from main. Use git worktrees for parallel work.
  2. Implement -- Write the feature. Write tests alongside code. Run pnpm test, pnpm check (oxlint + oxc-format). All must pass.
  3. Commit -- Commit to the feature branch. Descriptive message focused on the "why."
  4. Simplify -- Run /simplify on all changed files. Accept structural improvements, flatten unnecessary abstractions, remove dead code. Commit the result.
  5. PR -- Create the PR. Reference this issue number.
  6. PR Review -- Run /review-pr which launches parallel review agents (code review, silent failure hunter, type design analysis). Fix every issue found. Re-run tests after fixes.
  7. Team Review -- Post PR to the legion bullpen. Get consensus from the team before merging.
  8. Request Merge -- Only after consensus. Never merge your own PR without review.

Platform Rules

  • No any -- use unknown and narrow
  • No emoji in code, comments, or commits
  • UUIDv7 for all identifiers
  • Zod is source of truth for schemas
  • Wrangler owns all D1 migrations (never drizzle-kit)
  • pnpm only (never npm/yarn)
  • Tests in tests/ mirroring source tree, never colocated

Done When

  • Feature branch created
  • All tests pass
  • Simplify pass completed and committed
  • PR created and linked to this issue
  • PR review completed and issues fixed
  • Team consensus on the bullpen
  • Merge requested (not self-merged)

Metadata

Metadata

Assignees

No one assigned

    Labels

    ctrlctrl dashboard surfaceenhancementNew feature or requestphase-5Dashboard home + notifications

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions