🗺️ Evalium – User Management & Cohorts Roadmap
Owner: Product Engineering
Status: Approved
Related: assignments-backend-roadmap.md, FOUNDATION.md, roles-and-access-control.md
Evalium’s Users & Cohorts system enables SMB-simple onboarding and Enterprise-scale dynamic grouping, while maintaining strict multi-tenant & org-unit isolation via PostgreSQL RLS.
This roadmap provides the backend-first, schema-first plan for Users, Metadata, Groups, Dynamic Cohorts, CSV Imports, and Assignment integration.
Evalium’s goal is to make user management:
- Effortless for SMBs
- Flexible for future Enterprise integrations (SCIM, HRIS, ATS)
- Immutable, auditable, and high-integrity
This roadmap is designed so our backend remains stable even as UX grows in complexity.
Phase 0 — Data Foundation (Schema + RLS)
Goal: Provide a schema capable of supporting all future UX (dynamic cohorts, HRIS sync, metadata rules) without needing further database redesign.
0.1 Schema: Flexible User Metadata (JSONB)
Evalium does not add rigid fields like department, job_title, etc.
Instead, we store all org-specific attributes inside a flexible JSONB object:
ALTER TABLE users
ADD COLUMN metadata JSONB DEFAULT '{}' NOT NULL;
CREATE INDEX idx_users_metadata_gin ON users USING gin (metadata);
Why JSONB?
- Future-proof for HRIS integrations
- Enables Dynamic Groups without schema changes
- Compatible with RLS and query-time performance patterns
- Avoids schema churn when onboarding new customers
0.2 Schema: Groups (Cohort Container)
Groups act as “soft teams” or “logical cohorts” inside an org unit. Groups can be manual OR dynamic (generated by rules).
CREATE TABLE groups (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL,
org_unit_id UUID NOT NULL,
name TEXT NOT NULL,
description TEXT,
-- Dynamic rule-based membership
is_dynamic BOOLEAN DEFAULT false,
membership_rule JSONB,
-- Secure user-join path
join_token TEXT UNIQUE,
allowed_domains TEXT[],
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
0.3 Schema: Group Members (Source of Truth)
Even with dynamic rules, we store members explicitly so that:
- assignment targeting remains fast (no dynamic evaluation at redeem time)
- changes over time are audited
- historical reporting remains accurate
CREATE TABLE group_members (
group_id UUID NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
added_at TIMESTAMPTZ DEFAULT NOW(),
PRIMARY KEY (group_id, user_id)
);
0.4 RLS & Security Invariants
These are non-negotiable architectural constraints:
- Users only visible within their tenant (RLS)
- Groups only exist within a single org-unit
- A user cannot join a group from another org-unit
- Dynamic rules only evaluate user.metadata, never join other tables
- Dynamic rule evaluation must run through TxManager — never bypass RLS
- Code must log/audit all automatic membership additions/removals
Phase 1 — Dynamic Cohorts (“Smart Groups”)
Dynamic groups allow eval admins to manage high volumes of users without manual lists.
1.1 Rule Engine (Evaluator Service)
Runs on:
- User Creation
- User Update
- CSV Import
- SCIM Sync (future)
Evaluation:
- Fetch all
is_dynamic = truegroups in the tenant+org - Apply JSON rule to
user.metadata - If match → insert membership
- If no longer match → remove membership
Supported MVP Operators:
| Operator | Example | Meaning |
|---|---|---|
| equals | {"department": "Sales"} | exact match |
| contains | {"skills": ["Go"]} | metadata array contains any |
| exists | {"employee_id": true} | key present |
1.2 Auditability
All rule-triggered changes must be recorded:
- group_id
- user_id
- rule version
- previous → new state
This supports compliance (especially for HR and regulated industries).
Phase 2 — Safe, Conversational CSV Import (“Dry Run”)
Evalium’s import engine must never let bad data enter the system.
2.1 POST /users/import/preview (Dry Run)
- No writes
- Fuzzy header detection
- Normalize all emails
- Validate metadata structure
- Return a validation report including enriched metadata and rule-trigger results
Example response:
{
"import_id": "tmp_9273",
"valid_count": 45,
"error_count": 2,
"preview": [
{ "email": "alice@co.uk", "metadata": {"dept": "Sales"}, "status": "valid" },
{ "email": "bob", "status": "error", "msg": "Invalid email" }
]
}
2.2 POST /users/import/commit
- Uses sanitized payload (or cached preview)
- Batches inserts in a transaction
- Triggers Dynamic Rule Evaluator upon commit
This eliminates brittle “import failed → no idea why” flows.
Phase 3 — Zero-Touch Onboarding (Join Links)
For product-led growth and small teams.
3.1 Secure Group Join Flow
POST /groups/join/\{token\}
Flow:
- Validate session (magic-link identity)
- Resolve group by join_token
- Validate allowed_domains
- Validate org-unit match
- Add to group_members
This creates:
- easy self-serve enrollment
- Slack/Teams-friendly flows
- enterprise-safe guardrails
Phase 4 — Assignment Integration
Assignments become dramatically more powerful once Groups exist.
4.1 Assignments Target Groups
Extend assignment creation with:
target_type = 'group_id'
target_ref = group_id
4.2 Redeem Logic (Assignments Phase 1)
For group assignments:
exists := repo.CheckGroupMembership(...)
if !exists { return 403 }
This ensures:
- Dynamic groups auto-resolve before redeem
- No expensive rule evaluation at assignment-delivery time
- RLS ensures cross-org spoofing is impossible
RBAC: Required Capabilities
Update roles-and-access-control.md to include:
User & Group Management
users.manage– CRUD usersusers.import– CSV import preview + commitgroups.manage– Create/manage groupsgroups.view– Read group listsgroups.join– User can join via token (session-required)
Assignment Integration
assignments.createassignments.monitorassignments.manageassignments.override
This ensures least-privilege and clean audit trails.
Why This strategy Wins
🎯 1. Maximizes Flexibility
JSONB metadata + rule-based grouping allows Evalium to support:
- HRIS attributes
- ATS attributes
- Custom department structures
- Job grades, levels, cost-centers
- Regional and union compliance
No schema changes required.
🔐 2. Strong Security & RLS Alignment
All tables include:
- tenant_id
- org_unit_id
All access flows through:
- TxManager
- SET LOCAL scopings
- RLS policies
Impossible to leak data cross-tenant/org.
🪢 3. Perfect Fit with Assignments
Assignments can now target:
- users
- emails
- groups
- public links
…and everything flows through:
assignment → delivery_session → submission → snapshot → reporting
with assignment_id frozen into sessions + submissions.
🧠 4. Superior UX for SMBs and Enterprise
SMBs get:
- effortless CSV import
- auto-grouping
- join links
Enterprise gets:
- SCIM-ready metadata
- rule-based cohorts
- assignment integration at scale
🧱 5. Fully Backend-First
All functionality is secure, auditable, and production-safe before any UI is built.
Summary
Evalium’s User & Cohorts system is now:
✔ JSONB metadata–driven ✔ Dynamic group–powered ✔ Fully RLS-secured ✔ Assignment-integrated ✔ Import-safe (“Dry Run”) ✔ Scalable to HRIS + SCIM ✔ Friendly for SMBs and Enterprise
This roadmap is fully aligned with the architecture, foundation, and assignments roadmap — you can now safely implement Users/Groups as a permanent system pillar.