← Command Center
Phase 2
Teams + Roles
Internal first (Derek/Will), architect lean for future product. Depends on Phase 1 (Vault).
First Principle: Internal first (Derek/Will), architect lean for future product. Low-overhead multi-tenant that could become paid seats. Don't build billing/onboarding now. Clean tenant isolation only.
Second-Order Effects
- Internal Velocity
- Derek and Will operate independently. No shared credentials, no stepping on pages.
- Product Path
- Same tables/RLS that serve internal team become the basis for paid team seats later.
- BYOK Per Team
- Each team member brings their own keys. Team admins can also set shared team keys.
- Domain Scoping
- Domains belong to teams. Members see only their team's domains and pages.
Roles
Admin
- ✓ Manage team members
- ✓ Manage team vault
- ✓ Create/edit/delete pages
- ✓ Manage domains
- ✓ Run Reveal
Editor
- ✗ Manage team members
- ✗ Manage team vault
- ✓ Create/edit/delete pages
- ✗ Manage domains
- ✓ Run Reveal
Viewer
- ✗ Manage team members
- ✗ Manage team vault
- ✗ Create/edit/delete pages
- ✗ Manage domains
- ✓ View pages + analytics
Atomic Parts
2.1
Migration: teams + team_members tables
teams: id, name, slug (unique), created_by, created_at. team_members: id, team_id, user_id, role ('admin'|'editor'|'viewer'), invited_by, joined_at. Unique on (team_id, user_id). RLS: members see own team, admins manage members.
2.2
Migration: Link domains to teams
ALTER TABLE domains ADD COLUMN team_id. Domains with team_id are shared; without are personal.
2.3
Migration: Vault RLS for teams
Team members can SELECT team secrets. Team admins can ALL on team secrets. Extends the vault_secrets RLS from Phase 1.
2.4
Types
Team and TeamMember interfaces in types/database.ts.
2.5
Teams API
GET: list user's teams. POST: create team (creator becomes admin).
2.6
Members API
GET: list members. POST: invite (email + role). DELETE: remove member. PATCH: change role.
2.7
Vault: Team resolution
resolveSecret() order: user vault → team vault → env var. Team ID from user's membership.
2.8
TeamManager UI
Team name, member list with roles, invite form (email + role picker), remove member (admin only).
2.9
Dashboard: Team context
If user belongs to a team, domains/pages scoped by team. Team selector for multi-team users. Role-based UI restrictions.
2.10
Onboarding: Derek/Will
Create Supabase auth accounts. Create "Athio" team. Jason=admin, Derek=editor, Will=admin. Share relevant root domains.
Key Files
| File | Role |
| app/api/teams/route.ts | Team CRUD |
| app/api/teams/members/route.ts | Member management |
| components/TeamManager.tsx | Team UI component |
| lib/vault/service.ts | Update resolveSecret for teams |
| components/DashboardContent.tsx | Team context + selector |
Risk to Mitigate: Don't build billing or onboarding flows. No invite emails, no Stripe. Manual account creation in Supabase dashboard is fine for now. Clean tenant isolation only.
Verification
- Create "Athio" team, invite Derek
- Derek logs in → sees shared domains
- Derek adds own ANTHROPIC_API_KEY → his Reveal runs use his key
- Viewer role cannot edit pages
- RLS prevents cross-team data access