--- kind: epic slug: tenant-lifecycle title: Tenant lifecycle — invites, roles, soft-delete, audit, rate-limits plan_slug: multitenant-saas-hardening status: ready priority: P1 tenant_id: global cursor_epic_id: null updated_at: "2026-06-01" --- # Epic objective Cover the operational edges of running a multitenant app: who's in the workspace, what they did, can we recover from a mistake, and can we cap abuse. ## In scope / out of scope **In scope** - Invite + role management (`workspace_members` already exists; add invite flow on top). - Append-only `audit_log` table with write hooks. - Soft-delete on workspaces and core tenant-scoped tables. - Rate-limiting middleware on auth + mutation routes. **Out of scope** - SSO group sync (later). - Per-tenant billing (separate plan). ## Related tasks | Task | Link | |------|------| | Workspace invites and roles | `./Task-workspace-invites-and-roles.md` | | Workspace soft-delete and audit | `./Task-workspace-soft-delete-and-audit.md` | | Rate limit and abuse guardrails | `./Task-rate-limit-and-abuse-guardrails.md` | ## Dependencies - Depends on: `Plan-daily-driver-finish` (don't harden surfaces that are still stubs). - Blocks: charging real money, onboarding non-trusted tenants. ## Acceptance criteria - [ ] An owner can invite an email; the recipient lands in the workspace after sign-in. - [ ] Every tenant-scoped mutation produces an `audit_log` row. - [ ] An archived workspace stops serving its data through tRPC but is restorable for at least 30 days. - [ ] Credentials sign-in is rate-limited at the route handler level. ## Proposed timeline | Phase | Window | Notes | |-------|--------|-------| | Invites | Week 1 | Owner can add a teammate end-to-end. | | Audit + soft-delete | Week 2 | Schema + middleware. | | Guardrails | Week 3 | Rate limits + abuse signals. |