Skip to content

Multi-Tenant Profile & Branding Architecture Implementation #23

@mjunaidca

Description

@mjunaidca

Overview

Implement the multi-tenant profile and branding architecture as outlined in auth-server/docs/proposals/001-multi-tenant-profile-branding.md.

This transforms the auth server from a RoboLearn-specific service into a production-ready multi-tenant identity platform with:

  • OIDC-compliant user profiles
  • Dynamic branding per OAuth client
  • Clerk-style profile management UI
  • Up to 3 tenant-defined custom fields per organization

Prerequisites (Must Complete First)

Before starting this implementation, complete all documentation issues:

Rationale: Documentation clarifies current architecture before major refactoring.


Implementation Phases

Phase 1: Schema Migration

  • Add OIDC standard claims columns to user table
  • Add branding columns to oauth2_client table
  • Add custom_fields JSONB to organization table
  • Add metadata JSONB to member table
  • Update Drizzle schema
  • Run migration (keep user_profile table temporarily)

Phase 2: Profile System Update

  • Configure Better Auth additionalFields for OIDC claims
  • Update userinfo endpoint to return OIDC claims + tenant_profile
  • Create /account/profile page with standard claims form
  • Add organization switcher dropdown for multi-org users
  • Implement dynamic custom field renderer
  • Add API endpoints: GET/PATCH /api/account/profile
  • Add API endpoints: GET/PATCH /api/account/member-profile
  • Enable Better Auth phone plugin for phone verification

Phase 3: Dynamic Branding

  • Create branding lookup API (GET /api/branding?client_id=xxx)
  • Update auth page layout to accept branding props
  • Update sign-in/sign-up pages to use dynamic branding
  • Add branding configuration to client registration
  • Implement fallback for direct access (no client_id)

Phase 4: Tenant Custom Fields

  • Add custom field configuration UI for organization admins
  • Create dynamic form renderer for tenant fields (select/text/number/checkbox)
  • Update member join flow to collect custom fields
  • Add tenant_profile to userinfo response
  • Implement field validation (max 3 fields, type constraints)

Phase 5: Cross-Tenant Flows

  • Implement "Join Organization" flow for existing users
  • Add membership check after authentication
  • Handle custom field collection for new tenants
  • Update redirect logic for multi-tenant scenarios
  • Add organization switcher in profile UI

Phase 6: Cleanup & Migration

  • Migrate user_profile data to member.metadata
  • Drop user_profile table
  • Update RoboLearn client to use new custom fields system
  • Update all documentation to reflect new architecture
  • Remove hardcoded RoboLearn branding

Success Criteria

  • No RoboLearn-specific code in auth server (all tenant-configurable)
  • OIDC-compliant userinfo response (passes conformance tests)
  • Dynamic branding based on client_id
  • Profile management UI at /account/profile functional
  • OIDC standard claims editable (name, email, picture, phone, locale, timezone)
  • Dynamic custom field rendering per organization
  • Organization switcher works for multi-org users
  • Tenant custom fields (max 3) working end-to-end
  • Clean migration from user_profile table (no data loss)
  • All existing tests pass + new tests for multi-tenant features

Testing Requirements

Unit Tests:

  • OIDC claims correctly populated in userinfo
  • Custom fields saved to member.metadata
  • Branding lookup returns correct data
  • Cross-tenant membership flow works

Integration Tests:

  • Full OAuth flow with new userinfo structure
  • Dynamic branding renders correctly
  • Custom field collection during sign-up
  • Existing user joining new tenant

Visual Tests:

  • Branded sign-in page renders correctly
  • Custom field forms display properly during sign-up
  • Profile management page works
  • OIDC standard claims editable
  • Custom fields dynamically render per organization
  • Organization switcher works for multi-org users
  • Phone verification flow works
  • Form validation displays errors correctly

Related Issues

Closes:

Depends On:

Supersedes:


Documentation

Full proposal: auth-server/docs/proposals/001-multi-tenant-profile-branding.md

Key References:

  • OIDC Standard Claims: OpenID Connect Core 1.0, Section 5.1
  • Better Auth additionalFields: https://www.better-auth.com/docs
  • Industry Patterns: Clerk, Auth0, Keycloak profile management

Estimated Effort

  • Phase 1 (Schema): 2-3 hours
  • Phase 2 (Profile UI): 8-10 hours
  • Phase 3 (Branding): 4-6 hours
  • Phase 4 (Custom Fields): 6-8 hours
  • Phase 5 (Cross-Tenant): 4-6 hours
  • Phase 6 (Cleanup): 2-3 hours

Total: ~26-36 hours (3-5 days of focused work)


Implementation Approach

Recommended: Use /sp.orchestrate with proposal document as input for structured SDD-RI workflow:

  1. Create feature branch: feature/multi-tenant-profile-branding
  2. Run /sp.orchestrate to generate spec.md, plan.md, tasks.md
  3. Execute phases incrementally with tests at each step
  4. Create PR when all success criteria met

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions