Files
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

24 KiB
Raw Permalink Blame History

Feature Research

Domain: Multi-tenancy, user accounts, and role-based access control Researched: 2026-03-18 Confidence: HIGH

Feature Landscape

Table Stakes (Users Expect These)

Features users assume exist. Missing these = product feels incomplete.

Feature Why Expected Complexity Notes
Individual user accounts Standard expectation in any multi-user app; shared passwords are deprecated UX MEDIUM Email/password auth, JWT tokens (already have JWT infrastructure)
Per-user project ownership Users expect "my projects" vs "shared with me" distinction MEDIUM Requires user_id column on projects table, workspace isolation
Invite-only registration Standard pattern for self-hosted tools; prevents open registration abuse LOW Invite codes/tokens in database, validation before signup
Basic role hierarchy (viewer/editor/admin) Industry standard in collaborative tools (GitHub, Notion, Figma all use 3-tier) MEDIUM Role enum on project_user junction table, permission checks
Edit attribution in history Users expect to see "who changed what" in version history LOW Already have history table; add user_id foreign key
Project sharing UI Ability to add collaborators and set their role MEDIUM UI for managing project members, permission checks
Session management Users expect to see active sessions, logout from devices LOW JWT refresh tokens, token revocation list
Password reset flow Expected security hygiene for email/password auth MEDIUM Email service integration, reset tokens, secure workflows

Differentiators (Competitive Advantage)

Features that set the product apart. Not required, but valuable.

Feature Value Proposition Complexity Notes
Granular audit trail with rollback Beyond basic attribution—show full change context and allow per-edit rollback MEDIUM Leverage existing history system; add user context to each snapshot
Workspace-level dashboards Per-user analytics showing activity across all their projects LOW Aggregate existing project stats by user
Inherited permissions on requirement hierarchy Child requirements inherit parent permissions; reduces management overhead HIGH Complex to implement correctly; easy to introduce leaks
Anonymous viewer links Share read-only project views without requiring account MEDIUM Signed tokens with expiry, no-auth view endpoints
Activity feeds "What changed since I last logged in" per project MEDIUM Requires tracking last_seen timestamps and filtering history
Workspace templates Users can save project configurations as templates for reuse LOW Export/import existing project structure
Fine-grained permission customization Beyond viewer/editor/admin—custom permission sets HIGH Significantly increases complexity; likely over-engineering for v2

Anti-Features (Commonly Requested, Often Problematic)

Features that seem good but create problems.

Feature Why Requested Why Problematic Alternative
Real-time collaborative editing "Like Google Docs" — users assume all modern tools have it Massive architectural lift; requires WebSockets, operational transforms, conflict resolution; SQLite poor fit Optimistic locking with "edited by X" warnings; auto-refresh on save
Organization/team hierarchies Enterprises expect nested orgs (company → department → team) Dramatically increases permission model complexity; complicates billing/limits Single workspace per user; flat project sharing model
Social login (OAuth) Convenient for users, reduces friction Adds external dependencies; complicates self-hosted deployments; privacy concerns Email/password sufficient for self-hosted tool; invite-only provides security
Fine-grained field-level permissions "Editor can change description but not acceptance criteria" Explosion of permission checks; confusing UX; high maintenance burden Role-based with clear responsibilities; don't split access within entities
Public project discovery "Browse all public projects like GitHub" Privacy concerns for self-hosted tool; invites spam/abuse Explicit sharing only; anonymous links for specific cases
User-to-user direct messaging "Chat with collaborators in-app" Scope creep; users already have Slack/email/Discord Keep tool focused; collaboration happens in comments/edits

Feature Dependencies

Individual User Accounts (foundational)
    ├──requires──> User Authentication Flow
    │                  ├──requires──> Login/Logout
    │                  ├──requires──> Password Reset
    │                  └──requires──> Session Management
    │
    ├──requires──> Per-User Project Ownership
    │                  ├──requires──> Workspace Isolation (tenant_id pattern)
    │                  └──requires──> "My Projects" vs "Shared With Me" views
    │
    ├──requires──> Edit Attribution
    │                  ├──enhances──> Existing History System
    │                  └──requires──> User Foreign Keys on History Table
    │
    └──requires──> Invite-Only Registration
                       ├──requires──> Invite Token Generation
                       ├──requires──> Invite Validation
                       └──requires──> Admin Controls

Role-Based Access Control
    ├──requires──> Individual User Accounts (above)
    ├──requires──> Project-User Junction Table
    │                  └──stores──> Role (viewer/editor/admin/owner)
    │
    ├──requires──> Permission Enforcement Layer
    │                  ├──frontend──> Route guards, UI element visibility
    │                  └──backend──> Endpoint authorization checks
    │
    └──enhances──> Project Sharing UI
                       └──requires──> Member Management Interface

Project Sharing UI
    ├──requires──> Role-Based Access Control (above)
    └──requires──> Invite Notification System

Audit Trail with User Context
    ├──requires──> Edit Attribution (above)
    └──enhances──> Existing History Visualization

Dependency Notes

  • Individual User Accounts is foundational: All other features depend on this being implemented first
  • Workspace Isolation must be implemented correctly from the start: Retrofitting tenant isolation is high-risk for data leaks
  • Edit Attribution enhances existing history: Already have requirement_history table; adding user_id is low-risk
  • RBAC requires careful sequencing: Must implement permission checks in backend before exposing sharing UI
  • Invite-only registration can be parallel to RBAC: These features are independent after user accounts exist

MVP Definition

Launch With (v2.0)

Minimum viable multi-tenancy — what's needed to validate the concept.

  • Individual user accounts with email/password authentication — Essential foundation
  • Invite-only registration with admin-generated invite codes — Security requirement for self-hosted
  • Per-user project ownership with workspace isolation — Core multi-tenancy feature
  • Three-tier RBAC (owner/editor/viewer) on projects — Table stakes for collaboration
  • Edit attribution in history (user_id on edits) — Minimal audit trail
  • Project sharing UI with role assignment — Required to make RBAC usable
  • Basic permission enforcement (backend + frontend) — Security requirement
  • Password reset flow — Expected security hygiene

Add After Validation (v2.x)

Features to add once core multi-tenancy is working.

  • Activity feeds per project — Add once users report "losing track of changes"
  • Workspace-level dashboard — Add when users manage 5+ projects
  • Anonymous viewer links — Add when users request "share with client" workflows
  • Granular audit trail with per-edit rollback — Add when attribution proves insufficient
  • Session management UI — Add if users report security concerns with active sessions
  • Workspace templates — Add when users request "clone project structure"

Future Consideration (v3+)

Features to defer until product-market fit is established.

  • Fine-grained permission customization — Defer until 3-tier RBAC proves insufficient
  • Inherited permissions on hierarchy — Complex; defer until users report permission management overhead
  • Organization/team hierarchies — Defer until serving enterprise customers
  • OAuth/SSO providers — Defer until serving organizations requiring SSO
  • Real-time collaborative editing — Major architectural change; defer until core collaboration proves valuable

Feature Prioritization Matrix

Feature User Value Implementation Cost Priority
Individual user accounts HIGH MEDIUM P1
Invite-only registration HIGH LOW P1
Per-user project ownership HIGH MEDIUM P1
Three-tier RBAC (owner/editor/viewer) HIGH MEDIUM P1
Edit attribution HIGH LOW P1
Project sharing UI HIGH MEDIUM P1
Permission enforcement layer HIGH HIGH P1
Password reset flow MEDIUM MEDIUM P1
Activity feeds MEDIUM MEDIUM P2
Workspace dashboard MEDIUM LOW P2
Anonymous viewer links MEDIUM MEDIUM P2
Granular audit trail LOW MEDIUM P2
Session management UI LOW LOW P2
Workspace templates LOW LOW P2
Fine-grained permissions LOW HIGH P3
Inherited permissions MEDIUM HIGH P3
Organization hierarchies LOW HIGH P3
OAuth/SSO LOW HIGH P3
Real-time collaboration HIGH VERY HIGH P3

Priority key:

  • P1: Must have for v2.0 launch — core multi-tenancy
  • P2: Should have for v2.x — enhances collaboration
  • P3: Nice to have for v3+ — future consideration

Expected Behavior and UX Patterns

Invite-Only Registration

Standard Flow:

  1. Admin generates invite code/link from admin panel
  2. Invite stored in database with: code (UUID), email (optional), created_by, expires_at, used (boolean)
  3. Registration page requires valid invite code before showing signup form
  4. After successful signup, invite marked as used (single-use) or incremented (multi-use)
  5. Expired/invalid codes show clear error messages

UX Patterns (2026):

  • Invite links preferred over codes: Users click link → auto-fills invite code → shows signup form
  • Email pre-fill: If invite includes email, pre-populate signup form (can't be changed)
  • Context in email: Invitation email shows who invited them and to which workspace
  • Clear expiry: Show "This invite expires in X days" prominently
  • Admin controls: Dashboard showing pending/used/expired invites

Sources:

Per-User Project Ownership

Standard Patterns:

  1. Shared database with tenant_id: All users share same tables; user_id column differentiates ownership
  2. Workspace views: "My Projects" (owned), "Shared With Me" (collaborator), optionally "All Projects" (admin)
  3. Default visibility: Projects private by default; owner explicitly shares
  4. Transfer ownership: Admin capability to reassign project owner
  5. Orphaned projects: Handle deleted user accounts (reassign or archive)

Data Model:

projects:
  - owner_id (FK to users)
  - created_by (FK to users)
  - updated_by (FK to users)

project_users (junction):
  - project_id (FK to projects)
  - user_id (FK to users)
  - role (enum: owner, editor, viewer)
  - added_by (FK to users)
  - added_at (timestamp)

Critical Security Pattern:

  • Every query MUST include WHERE user_id = ? OR EXISTS (SELECT 1 FROM project_users WHERE project_id = ? AND user_id = ?)
  • Enforce at ORM level or middleware layer, not per-endpoint (reduces chance of missing checks)

Sources:

Role-Based Access Control (Viewer/Editor/Admin)

Industry Standard Three-Tier Model:

Role Read Create/Edit Delete Manage Members Transfer Ownership
Owner
Editor ✓ (own edits)
Viewer

Implementation Pattern:

# Backend: Permission decorator
@require_project_permission(Permission.EDIT)
def update_requirement(project_id, requirement_id, data):
    # Only called if user has editor+ role
    pass

# Frontend: Structural directives
<button *ngIf="hasPermission('edit')">Edit</button>

UX Expectations:

  • Graceful degradation: Viewers see read-only interface, not error messages
  • Clear role badges: Show user's role in project header ("You are an Editor")
  • Contextual actions: Only show actions user can perform (hide "Delete" for viewers)
  • Permission feedback: If user somehow triggers unauthorized action, show clear explanation

Common Mistakes to Avoid:

  • Authorization only on frontend: Always enforce on backend; frontend is convenience only
  • Inconsistent enforcement: Missing permission checks on some endpoints creates security holes
  • Role explosion: Don't create custom roles too early; three tiers sufficient for most cases
  • Cache-based authorization: Store role in user-controllable location (localStorage) for UI only; always verify on backend

Sources:

Edit Attribution

Expected Behavior:

  1. Every edit records: user_id, timestamp, before/after state
  2. History view shows: "John Doe edited requirement title at 2:34 PM"
  3. Hover/click shows full context: what changed, by whom, when
  4. Filter history: "Show only my edits" or "Show edits by John"

Google Docs Pattern (Gold Standard):

  • Show Editors feature: Right-click text → "Show Editors" → see who edited that specific range
  • Named versions: Users can create named checkpoints ("Before client review")
  • Continuous recording: Every change captured automatically (no manual "save version")
  • Real-time attribution: See colored cursors/highlights showing who's editing what

Adapted for Non-Real-Time:

  • Display "Last edited by X at Y" on each requirement card
  • History panel shows chronological list with user avatars
  • Diff view highlights changes with attribution ("Added by John", "Removed by Jane")
  • Filter/search history by user

Implementation Notes:

  • Already have requirement_history table
  • Add user_id foreign key to requirement_history
  • Add created_by, updated_by to requirement_nodes
  • Frontend displays user info from history records

Sources:

Project Sharing UI

Standard Patterns:

  1. Share button: Prominent in project header
  2. Member list: Shows current collaborators with roles
  3. Add member flow:
    • Input: Email or username
    • Select role: Owner/Editor/Viewer (with tooltips explaining each)
    • Optional: Add message to invitation
    • Send: Generates notification and adds to project
  4. Role modification: Click role dropdown → change role → confirm
  5. Remove member: Click X or "Remove" → confirm dialog → remove access

GitHub Pattern:

  • Settings → Collaborators → "Add people" → username → role → "Add"
  • Shows pending invitations separately from active members
  • Email notification when invited

Notion Pattern:

  • "Share" button → modal with member list
  • Inline role editing (click role → dropdown)
  • "Copy link" for anonymous sharing
  • Shows "X has access via Team Y" (inherited permissions)

Figma Pattern:

  • Share button → modal showing team/project/file hierarchy
  • Link sharing with permission level attached to link
  • "Anyone with link can view/edit"

Recommended Approach:

  • Hybrid: GitHub-style explicit invitations + Notion-style inline role editing
  • No link-based sharing in v2.0 (add in v2.x as anonymous viewer links)
  • Clear visual distinction between owner (1 per project) and collaborators

Sources:

Complexity on Existing Features

Impact on Existing Edit History

Current State:

  • requirement_history table stores snapshots (before/after JSON)
  • No user attribution — assumes single user

Required Changes:

  • Add user_id column (FK to users)
  • Migrate existing records: set user_id to admin or mark as "system"
  • Update create_history_record() to include current_user_id
  • Update history display to show user info

Complexity: LOW — Additive change, doesn't break existing functionality

Impact on Existing Graph Visualization

Current State:

  • Graph shows all requirements in project
  • No permission-based filtering

Required Changes:

  • Filter requirements based on project access (user is owner/editor/viewer)
  • Show read-only indicators for viewers
  • Disable edit actions (drag, delete, create) for viewers
  • Show permission indicators in detail panel

Complexity: MEDIUM — Requires permission checks in graph component, but no architectural changes

Impact on Existing CRUD Operations

Current State:

  • No user context on create/update/delete
  • No ownership checks

Required Changes:

  • Add user_id to CREATE operations (set owner)
  • Add permission checks to UPDATE operations (is editor+?)
  • Add permission checks to DELETE operations (is owner or editor with own edits?)
  • Add created_by, updated_by columns to requirement_nodes
  • Migrate existing records: set created_by to admin or null

Complexity: MEDIUM — Every endpoint needs permission middleware, but follows consistent pattern

Impact on Existing Dashboard

Current State:

  • Shows all projects globally
  • Statistics aggregate all data

Required Changes:

  • Filter projects by ownership + shared access
  • Separate "My Projects" and "Shared With Me" views
  • Per-project statistics respect permissions
  • Add "Collaborators" count to project cards

Complexity: LOW — Mostly UI changes, backend already has project filtering

Impact on Database Schema

New Tables Required:

users (
  id INTEGER PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  password_hash TEXT NOT NULL,
  name TEXT,
  created_at TIMESTAMP,
  last_login TIMESTAMP
)

invite_codes (
  id INTEGER PRIMARY KEY,
  code TEXT UNIQUE NOT NULL,
  email TEXT,  -- optional: pre-assign to email
  created_by INTEGER REFERENCES users(id),
  expires_at TIMESTAMP,
  used BOOLEAN DEFAULT FALSE,
  used_by INTEGER REFERENCES users(id),
  used_at TIMESTAMP
)

project_users (
  id INTEGER PRIMARY KEY,
  project_id INTEGER REFERENCES projects(id) ON DELETE CASCADE,
  user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
  role TEXT CHECK(role IN ('owner', 'editor', 'viewer')),
  added_by INTEGER REFERENCES users(id),
  added_at TIMESTAMP,
  UNIQUE(project_id, user_id)
)

Modified Tables:

projects:
  + owner_id INTEGER REFERENCES users(id)
  + created_by INTEGER REFERENCES users(id)
  + updated_by INTEGER REFERENCES users(id)

requirement_nodes:
  + created_by INTEGER REFERENCES users(id)
  + updated_by INTEGER REFERENCES users(id)

requirement_history:
  + user_id INTEGER REFERENCES users(id)

graph_layouts:
  + user_id INTEGER REFERENCES users(id)  -- per-user layouts

Migration Strategy:

  1. Create users table first
  2. Create admin user (id=1)
  3. Add foreign key columns to existing tables (nullable initially)
  4. Set all existing records to admin user (id=1)
  5. Make columns NOT NULL after backfill
  6. Create invite_codes and project_users tables

Complexity: MEDIUM — Careful sequencing required, but no data loss risk if done correctly

Sources

UX and Design Patterns

RBAC and Authorization

Multi-Tenancy Architecture

Security and Data Isolation

Audit Trails and Attribution

User Onboarding

Collaboration Patterns


Feature research for: req-planner v2.0 Multi-Tenancy & User Accounts Researched: 2026-03-18