Architecture: How should the unified role system be architected to replace...

Documentation for Sessions

🏗️ Architecture: How should the unified role system be architected to replace...

Date: 2026-03-14
Time: 17:56:45 UTC
Session: gspace1-220.2
Agent: angular
Confidence: 95%
Status: ✅ Documented


📋 Decision Context

Question:

How should the unified role system be architected to replace 6 independent role systems?

Task: S220: Unified Role System


🎯 Decision Made

Chosen:

Two orthogonal axes: PlatformRole (executive|developer|admin|builder|user|guest) on User schema + SpaceRole (owner|admin|editor|viewer) on SpaceMember. Single derivePermissions() function in @libs-foundational/core-models computes everything: numeric level, feature flags, config access, tool access, backend roles, legacy userType. Both frontend and backend import from same lib.

Options Considered:

  1. Option A: Single merged role enum (would lose the space-scoped dimension)
  2. Option B: Permission bitmap (too complex for current scale, 4 users)
  3. Option C: Two-axis derivation function (chosen — orthogonal, minimal, backward-compatible)

💭 Reasoning

Root cause: 6 independent systems (SpaceMember role, SystemRole hierarchy, UserHierarchyType, VittoUserType, VittoConfigRole, Dossier roleLevel) grew organically. Each defined its own role vocabulary with different meanings for the same words (e.g. 'admin' meant 4 different things). Every new feature had to guess which system to use. The whistle feature alone needed 3 systems. A single derivation function with two canonical inputs eliminates all ambiguity. PlatformRole is stored on User document (persistent), SpaceRole is per-space (already exists on SpaceMember). Everything else is derived — no more independent mapping tables that can drift out of sync. The derivation function is pure (no side effects, no async) so it's safe for both Angular and NestJS.


📁 Files Involved


🔗 Related


Auto-generated by MCP Smart Consolidation