Files
graph-requirements-planner/.planning/research/SUMMARY.md
ANDREW HOSFORD 0e8978f48c Update project files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 11:59:48 -05:00

23 KiB
Raw Blame History

Project Research Summary

Project: req-planner v2.0 - Multi-Tenancy & User Accounts Domain: Requirements management tool with collaborative features Researched: 2026-03-18 Confidence: HIGH

Executive Summary

The req-planner v2.0 upgrade adds user accounts, invite-only registration, role-based access control, and project sharing to an existing FastAPI + SQLAlchemy + SQLite stack. Research shows this is a well-documented migration pattern with established best practices from 2026. The core architecture requires minimal new dependencies (pwdlib, email-validator) and leverages existing JWT infrastructure. The main risk is tenant isolation failures — forgetting to filter queries by user context is the #1 cause of data leaks in multi-tenant systems. The recommended approach uses shared-schema multi-tenancy with explicit query filtering, three-tier RBAC (owner/editor/viewer), and refresh token rotation for security.

Critical Success Factor: Build tenant-scoped query patterns from day one. Every query must filter by user ownership or project membership. SQLite's limitations (no Row-Level Security) require manual enforcement, making systematic testing essential. The good news: this migration is additive — existing single-user functionality remains intact during the transition, allowing incremental deployment.

Key Recommendation: Structure the roadmap in dependency order: (1) Authentication foundation with user accounts, (2) Tenant isolation with project ownership, (3) RBAC for sharing, (4) Polish with attribution and invites. This sequence minimizes risk by validating tenant isolation before adding sharing complexity.

Key Findings

The existing stack (FastAPI, SQLAlchemy 2.0, SQLite, PyJWT, Angular 17) is optimal for this use case. Only two new dependencies required:

Core additions:

  • pwdlib (Argon2) — Password hashing, replaces deprecated passlib. FastAPI official docs recommend it as of 2026. Argon2 is GPU-resistant and OWASP-approved.
  • email-validator — Required for Pydantic EmailStr validation. Standard for registration forms.
  • secrets (stdlib) — Cryptographically secure invite token generation using token_urlsafe(32) for 256-bit randomness.

No library needed (use patterns instead):

  • Multi-tenancy via SQLAlchemy query filters with user_id FK (SQLite doesn't support PostgreSQL Row-Level Security)
  • RBAC via Enum + FastAPI dependency injection (three roles don't justify a library like Casbin)
  • Edit attribution via modified_by_user_id column on existing requirement_history table
  • Email sending via stdlib smtplib + FastAPI BackgroundTasks (Celery is overkill)

Critical decision: Stick with SQLite until 100+ concurrent users or 10GB+ database. WAL mode supports unlimited concurrent readers + 1 writer, sufficient for small team collaboration. Migration to PostgreSQL adds operational complexity — delay until necessary.

Expected Features

Must have for v2.0 launch (table stakes):

  • Individual user accounts with email/password authentication
  • Invite-only registration with admin-generated tokens (security requirement for self-hosted)
  • Per-user project ownership with workspace isolation (core multi-tenancy)
  • Three-tier RBAC (owner/editor/viewer) on projects
  • Edit attribution in history showing who made each change
  • Project sharing UI with role assignment
  • Password reset flow (expected security hygiene)
  • Permission enforcement on both backend and frontend

Should have for v2.x (competitive differentiators):

  • Activity feeds per project ("what changed since I last logged in")
  • Workspace-level dashboard aggregating user's projects
  • Anonymous viewer links for sharing with clients without accounts
  • Granular audit trail with per-edit rollback capabilities

Defer to v3+ (future consideration):

  • Fine-grained permission customization beyond three tiers
  • Inherited permissions on requirement hierarchy (complex to implement correctly)
  • Organization/team hierarchies for enterprise customers
  • OAuth/SSO providers
  • Real-time collaborative editing (major architectural change)

Anti-features (commonly requested but problematic):

  • Real-time collaborative editing: Massive architectural lift, requires WebSockets and operational transforms
  • Organization hierarchies: Dramatically increases permission complexity
  • Social login (OAuth): Complicates self-hosted deployments
  • Field-level permissions: Explosion of permission checks, confusing UX

Architecture Approach

The recommended architecture uses four layers: Authentication (user identity via JWT with refresh tokens), Authorization (RBAC via junction tables), Tenant Isolation (explicit query filtering by user context), and Migration Strategy (backwards-compatible schema changes). The key pattern is shared-schema multi-tenancy — single database with user_id columns and explicit filters, rather than database-per-tenant (which performs worse on SQLite's single-writer model).

Major components:

  1. Authentication Layer — Extends existing JWT system with user accounts, adds refresh tokens (15min access, 30-day refresh), invite token validation, password reset flow. Uses pwdlib for Argon2 hashing.

  2. User Context Injection — FastAPI dependency get_current_user() extracts user_id from JWT, verifies user active, returns immutable UserContext(user_id, email, is_admin). All routes receive current_user as dependency.

  3. Tenant-Scoped Queries — Manual filtering pattern: query(Project).filter((Project.owner_id == user_id) | (Project.members.any(user_id))). Explicit over implicit (no hidden session middleware). SQLite lacks Row-Level Security.

  4. RBAC LayerProjectMember junction table with role enum (owner/editor/viewer). Permission checks via require_project_access(project_id, required_role) dependency. Role hierarchy encoded: owner > editor > viewer.

  5. Migration Layer — Add nullable user_id columns, seed default admin user, backfill existing data to admin, make columns NOT NULL. Dual auth during transition (old password endpoint + new email/password endpoint).

Critical pattern: Never trust client-provided user_id. Always extract from server-verified JWT. Never use global query filters in middleware (breaks admin operations, hard to debug). Never store refresh tokens in localStorage (XSS risk).

Critical Pitfalls

  1. Forgetting tenant filters in queries — #1 cause of data leaks. Every SQLAlchemy query needs .filter(user_id == current_user.id) or project membership check. Missing a single filter exposes another user's data. Mitigation: Create base query functions enforcing tenant scoping, use integration tests with multiple users, code review checklist: "Does this query filter by tenant?"

  2. SQLite foreign key constraint failures during migration — Adding user_id FKs to existing tables causes migration failures or silent data loss. SQLite's ALTER TABLE limitations force table recreation with CASCADE risks. Mitigation: Use Alembic batch mode, test migration on production data copy, have rollback plan, consider enforcing constraints at application level initially.

  3. Existing JWT tokens become invalid — Deploying new auth invalidates all current sessions. Token payload structure changes (adding user_id) breaks old token format. Mitigation: Version tokens (version: 2), handle both formats during transition, communicate forced re-login window, consider token migration endpoint.

  4. Orphaned data without clear ownership — Existing projects/requirements have no owner_id. Assigning all to admin is wrong, leaving NULL breaks constraints. Mitigation: Decide ownership strategy before migration (assign to admin, create shared workspace, copy to all users, or delete legacy data), document rationale, make reversible.

  5. Role explosion and privilege creep — Starting with 3 roles (viewer/editor/owner) becomes dozens of overly-specific roles. Users accumulate permissions. Mitigation: Resist adding roles, use project-level assignments not feature-level, implement permission inheritance, audit roles quarterly, track role changes in audit log.

Implications for Roadmap

Based on research, the roadmap should follow a dependency-ordered sequence that validates tenant isolation before adding sharing complexity. The architecture naturally divides into four milestones that can be developed incrementally with clear validation gates.

Phase 1: Authentication Foundation

Rationale: User accounts are the prerequisite for all multi-tenancy features. Build the identity layer before touching data isolation.

Delivers: Users can register with invite tokens, login with email/password, receive JWT access + refresh tokens, and maintain sessions across browser sessions.

Addresses (from FEATURES.md):

  • Individual user accounts with email/password authentication
  • Invite-only registration (security requirement)
  • Session management with refresh tokens
  • Password reset flow

Avoids (from PITFALLS.md):

  • Pitfall #3: JWT token invalidation (handle old token format gracefully)
  • Pitfall #6: Invite system security weaknesses (cryptographically secure tokens, single-use, expiration)

Implementation notes:

  • Create users, invite_tokens, refresh_tokens tables
  • Implement pwdlib password hashing
  • Add /auth/register, /auth/login, /auth/refresh, /auth/logout endpoints
  • Update get_current_user() dependency to extract from JWT
  • Seed default admin user in migration

Research flag: No additional research needed — well-documented pattern in FastAPI ecosystem.

Phase 2: Tenant Isolation & Project Ownership

Rationale: Establish data separation before adding collaboration. Validate users can only see their own data before allowing sharing.

Delivers: Projects belong to specific users. Users see only projects they own. All queries filtered by user context. Existing data migrated to admin user.

Addresses (from FEATURES.md):

  • Per-user project ownership with workspace isolation
  • Basic permission enforcement (backend + frontend)

Avoids (from PITFALLS.md):

  • Pitfall #1: Forgetting tenant filters (THE critical pitfall)
  • Pitfall #4: Orphaned data without ownership
  • Pitfall #10: Dependency injection scope leaks

Implementation notes:

  • Add owner_id column to projects (nullable initially)
  • Add created_by_id, updated_by_id to requirement_nodes
  • Update all queries to filter by ownership
  • Migration: Assign existing projects to admin (id=1)
  • Make owner_id NOT NULL after backfill
  • Integration tests: User A cannot access User B's projects

Research flag: No additional research needed — standard SQLAlchemy patterns.

Phase 3: RBAC & Project Sharing

Rationale: Now that tenant isolation is validated, enable controlled sharing with role-based permissions.

Delivers: Project owners can invite collaborators with viewer/editor/owner roles. Permission checks enforce RBAC on all operations. UI shows user's role per project.

Addresses (from FEATURES.md):

  • Three-tier RBAC (owner/editor/viewer)
  • Project sharing UI with role assignment
  • Edit attribution in history (who made each change)

Avoids (from PITFALLS.md):

  • Pitfall #5: Role explosion (stick to 3 roles)
  • Pitfall #8: Cascading deletes destroying shared data
  • Pitfall #9: Missing edit attribution

Implementation notes:

  • Create project_members junction table with role enum
  • Add POST /projects/{id}/members, GET /projects/{id}/members, DELETE /projects/{id}/members/{user_id}
  • Implement require_project_access(project_id, required_role) dependency
  • Update all requirement routes to check RBAC
  • Add user_id to requirement_history for attribution
  • Update UI to display editor names and role badges

Research flag: RBAC patterns well-documented. May need phase-specific research for permission UI patterns if complex interactions emerge.

Phase 4: Polish & User Management

Rationale: With core multi-tenancy working, add user-facing features that improve collaboration experience.

Delivers: Users can invite others to the platform. Admins can manage invites. History shows detailed edit attribution. Enhanced security with rate limiting.

Addresses (from FEATURES.md):

  • Enhanced invite system (user-driven invites, not just admin)
  • Improved edit attribution in history UI
  • User profile management
  • Security hardening (rate limiting, token cleanup)

Avoids (from PITFALLS.md):

  • Pitfall #7: Frontend state management assumes single user
  • Performance traps (N+1 queries, pagination)

Implementation notes:

  • Add POST /auth/invites (users can invite others)
  • Add GET /auth/invites (list sent invites)
  • Integrate email sending (SMTP + BackgroundTasks)
  • Add rate limiting to auth endpoints (slowapi)
  • Scheduled task for token cleanup
  • Update history UI with user avatars and "edited by" attribution

Research flag: Email integration may need focused research on SMTP providers, deliverability, and template design if building production-grade invite emails.

Phase Ordering Rationale

Why this order:

  1. Authentication before isolation — Can't isolate data without user identity
  2. Isolation before sharing — Must prove single-user works before adding multi-user
  3. RBAC after ownership — Roles are meaningless without established ownership model
  4. Polish last — User-facing improvements after core functionality validated

How this avoids pitfalls:

  • Validates tenant isolation (Pitfall #1) in Phase 2 before sharing in Phase 3
  • Addresses data migration (Pitfall #4) early in Phase 2 when schema is simple
  • Prevents role explosion (Pitfall #5) by defining minimal roles in Phase 3
  • Frontend state management (Pitfall #7) addressed progressively across phases

Dependency chain:

  • Phase 2 depends on Phase 1 (needs user_id from auth)
  • Phase 3 depends on Phase 2 (needs project ownership to share)
  • Phase 4 depends on Phase 3 (invites need roles to assign)

Incremental deployment: Each phase is independently deployable. Phase 1 can launch without breaking existing single-user mode. Phase 2 migrates data but doesn't force collaboration. Phase 3 adds sharing as opt-in. Phase 4 enhances without breaking.

Research Flags

Phases with standard patterns (skip /gsd:research-phase):

  • Phase 1 (Authentication): FastAPI JWT auth is well-documented, official examples exist, pwdlib docs comprehensive
  • Phase 2 (Tenant Isolation): SQLAlchemy query filtering is standard ORM practice, multi-tenancy patterns mature
  • Phase 3 (RBAC): Three-role model is trivial, junction table pattern universal, permission checks straightforward

Phases likely needing deeper research:

  • Phase 4 (Email Integration): If building production-grade invite emails, may need research on:

    • SMTP provider selection (SendGrid vs Mailgun vs AWS SES)
    • Email deliverability (SPF, DKIM, DMARC configuration)
    • Template design and testing frameworks
    • Invite link generation security (signed URLs, token rotation)

    However, for MVP, stdlib smtplib is sufficient — defer detailed research until email features become critical path.

Overall assessment: This is a low-research-intensity roadmap. All core patterns are well-established. Only Phase 4 email features might warrant focused research if expanding beyond basic SMTP.

Confidence Assessment

Area Confidence Notes
Stack HIGH Recommendations verified against FastAPI official docs (2026), pwdlib is official replacement for passlib, SQLAlchemy 2.0 patterns stable. No experimental dependencies.
Features HIGH Feature categorization based on industry-standard collaboration tools (GitHub, Notion, Figma). Table stakes vs differentiators validated across multiple UX sources. Anti-features identified from documented failures.
Architecture HIGH Multi-tenancy patterns sourced from official guides, 2026 FastAPI tutorials, SQLAlchemy events documented. Dependency injection is core FastAPI feature. Refresh token rotation is OAuth 2.0 standard.
Pitfalls MEDIUM-HIGH Top pitfalls (#1 tenant filters, #2 SQLite migrations, #3 JWT invalidation) extensively documented across sources. Some pitfalls (#7 frontend state, #10 context scope) inferred from general patterns rather than domain-specific sources.

Overall confidence: HIGH

The research is built on official documentation (FastAPI, SQLAlchemy, SQLite, Pydantic), authoritative 2026 guides, and multiple corroborating sources. Stack recommendations align with maintainer guidance. Architecture patterns are production-proven. Pitfalls are sourced from documented post-mortems and security analyses.

Gaps to Address

Minor gaps that need attention during implementation:

  1. Email deliverability details: Research covered email sending (smtplib) but not email deliverability (SPF/DKIM/DMARC setup). If invite emails must reach inbox (not spam), Phase 4 may need focused research on email infrastructure.

    • How to handle: Start with simple SMTP in development, use established email service (SendGrid/Mailgun) in production, defer deliverability research until user reports spam issues.
  2. SQLite concurrency limits: Research confirms WAL mode supports multiple readers + 1 writer, but exact concurrency threshold (when to migrate to PostgreSQL) is deployment-specific.

    • How to handle: Monitor write contention in production (SQLITE_BUSY errors), plan PostgreSQL migration at 50+ concurrent writers or 10GB database, not earlier.
  3. Cascading delete policy: Research identifies the risk (Pitfall #8) but ownership transfer strategy is product decision, not technical.

    • How to handle: Decide in Phase 3 planning: transfer to co-owner, mark as archived, or require explicit reassignment before user deletion.
  4. Frontend state management details: Research identifies risk (Pitfall #7) but Angular 17 specifics (Signals vs Services for user context) are implementation details.

    • How to handle: Validate during Phase 2 frontend work, test user switching scenarios, follow Angular 17 best practices for auth guards.
  5. Password strength requirements: Research recommends enforcement but exact policy (length, complexity) is security policy decision.

    • How to handle: Implement OWASP-recommended baseline (8 chars, mixed case, numbers) in Phase 1, allow customization in Phase 4 if self-hosted users request it.

No critical blockers identified. All gaps are solvable during implementation without requiring additional research phases.

Sources

Primary (HIGH confidence)

Official Documentation:

2026 Technical Guides:

Secondary (MEDIUM confidence)

Multi-Tenancy & Architecture:

RBAC & Authorization:

Security & Data Isolation:

UX & Collaboration Patterns:

Tertiary (LOW confidence, needs validation)

SQLite Limitations:


Research completed: 2026-03-18 Ready for roadmap creation: YES

All four research files synthesized. Recommended phase structure validated against dependencies, pitfalls, and architecture patterns. No critical blockers identified. Roadmap can proceed with high confidence.