Update project files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
ANDREW HOSFORD
2026-04-07 11:59:48 -05:00
parent dd227be9b0
commit 0e8978f48c
50 changed files with 5878 additions and 241 deletions

View File

@@ -0,0 +1,492 @@
# 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.
- [x] Individual user accounts with email/password authentication — Essential foundation
- [x] Invite-only registration with admin-generated invite codes — Security requirement for self-hosted
- [x] Per-user project ownership with workspace isolation — Core multi-tenancy feature
- [x] Three-tier RBAC (owner/editor/viewer) on projects — Table stakes for collaboration
- [x] Edit attribution in history (user_id on edits) — Minimal audit trail
- [x] Project sharing UI with role assignment — Required to make RBAC usable
- [x] Basic permission enforcement (backend + frontend) — Security requirement
- [x] 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:**
- [User Onboarding Strategies in a B2B SaaS Application](https://auth0.com/blog/user-onboarding-strategies-b2b-saas/)
- [How to onboard invited users and fast-track user engagement](https://www.appcues.com/blog/user-onboarding-strategies-invited-users)
### 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:**
```sql
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:**
- [The developer's guide to SaaS multi-tenant architecture — WorkOS](https://workos.com/blog/developers-guide-saas-multi-tenant-architecture)
- [Tenant Data Isolation: 5 Patterns That Actually Work](https://propelius.tech/blogs/tenant-data-isolation-patterns-and-anti-patterns/)
### 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:**
```python
# 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:**
- [How to Build a Role-Based Access Control Layer](https://www.osohq.com/learn/rbac-role-based-access-control)
- [Role-Based Access Control Best Practices for 2026](https://www.techprescient.com/blogs/role-based-access-control-best-practices/)
- [Guide to sharing and permissions Figma Learn](https://help.figma.com/hc/en-us/articles/1500007609322-Guide-to-sharing-and-permissions)
### 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:**
- [Google Workspace Updates: "Show Editors" provides more context on changes made in Google Docs](https://workspaceupdates.googleblog.com/2021/05/view-more-context-on-google-docs-edits-with-show-editors.html)
- [How to See Version History in Google Docs](https://www.geeksforgeeks.org/websites-apps/how-to-see-version-history-in-google-docs/)
### 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:**
- [Guide to sharing and permissions Figma Learn](https://help.figma.com/hc/en-us/articles/1500007609322-Guide-to-sharing-and-permissions)
- [How to Add Collaborators in GitHub](https://www.rapidnative.com/blogs/how-to-add-collaborators-in-github)
## 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:**
```sql
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:**
```sql
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
- [Best Sign Up Flows (2026): 15 UX Examples That Convert](https://www.eleken.co/blog-posts/sign-up-flow)
- [Login & Signup UX: The 2025 Guide to Best Practices](https://www.authgear.com/post/login-signup-ux-guide)
- [Designing an intuitive user flow for inviting teammates](https://pageflows.com/resources/invite-teammates-user-flow/)
### RBAC and Authorization
- [How to Build a Role-Based Access Control Layer](https://www.osohq.com/learn/rbac-role-based-access-control)
- [Role-Based Access Control Best Practices for 2026](https://www.techprescient.com/blogs/role-based-access-control-best-practices/)
- [Role-based Access Control: Five Common Authorization Patterns](https://thenewstack.io/role-based-access-control-five-common-authorization-patterns/)
- [Best Practices for Multi-Tenant Authorization](https://www.permit.io/blog/best-practices-for-multi-tenant-authorization)
### Multi-Tenancy Architecture
- [The developer's guide to SaaS multi-tenant architecture — WorkOS](https://workos.com/blog/developers-guide-saas-multi-tenant-architecture)
- [Multi-Tenant SaaS Architecture: Complete Guide](https://codeboxr.com/multi-tenant-saas-architecture-complete-guide-models-design-patterns-and-scaling-strategy/)
- [Data Isolation in Multi-Tenant SaaS](https://redis.io/blog/data-isolation-multi-tenant-saas/)
- [Tenant Data Isolation: 5 Patterns That Actually Work](https://propelius.tech/blogs/tenant-data-isolation-patterns-and-anti-patterns/)
### Security and Data Isolation
- [Preventing Cross-Tenant Data Leakage in Multi-Tenant SaaS Systems](https://agnitestudio.com/blog/preventing-cross-tenant-leakage/)
- [Multi-Tenant Leakage: When "Row-Level Security" Fails in SaaS](https://medium.com/@instatunnel/multi-tenant-leakage-when-row-level-security-fails-in-saas-da25f40c788c)
- [Tenant Isolation in Multi-Tenant Systems](https://securityboulevard.com/2025/12/tenant-isolation-in-multi-tenant-systems-architecture-identity-and-security/)
- [Access control vulnerabilities and privilege escalation](https://portswigger.net/web-security/access-control)
### Audit Trails and Attribution
- [What Is an Audit Trail? Definition and Best Practices](https://trullion.com/blog/audit-trail-guide/)
- [10 Essential Audit Trail Best Practices for 2026](https://signal.opshub.me/audit-trail-best-practices/)
- [Google Workspace Updates: "Show Editors" in Google Docs](https://workspaceupdates.googleblog.com/2021/05/view-more-context-on-google-docs-edits-with-show-editors.html)
- [How to See Version History in Google Docs](https://www.geeksforgeeks.org/websites-apps/how-to-see-version-history-in-google-docs/)
### User Onboarding
- [User Onboarding Strategies in a B2B SaaS Application](https://auth0.com/blog/user-onboarding-strategies-b2b-saas/)
- [How to onboard invited users and fast-track user engagement](https://www.appcues.com/blog/user-onboarding-strategies-invited-users)
- [SaaS Onboarding Flows That Actually Convert in 2026](https://www.saasui.design/blog/saas-onboarding-flows-that-actually-convert-2026)
### Collaboration Patterns
- [Guide to sharing and permissions Figma Learn](https://help.figma.com/hc/en-us/articles/1500007609322-Guide-to-sharing-and-permissions)
- [How to Add Collaborators in GitHub](https://www.rapidnative.com/blogs/how-to-add-collaborators-in-github)
---
*Feature research for: req-planner v2.0 Multi-Tenancy & User Accounts*
*Researched: 2026-03-18*