Skip to main content

WF-109: License Seat Reallocation

Overview

This workflow handles the reallocation of license seats from inactive or departing users to new team members. It manages the seat pool, enforces grace periods for reallocation, handles active session termination, and ensures license compliance.

Trigger: HTTP POST to /api/v1/organizations/{org_id}/licenses/reallocate Duration: ~3-5 seconds Related Workflows: WF-005 (Invitation), WF-008 (Offboarding), WF-002 (Subscription)


Prerequisites

Before reallocating a license seat:

  • Requester must be organization admin or owner
  • Source user must have an assigned license
  • Target user must be organization member without license
  • Organization must have active subscription

Seat States

StateDescriptionCan Reallocate?
AssignedActively used by a userYes (with grace period)
UnassignedIn seat pool, availableImmediate
PendingReserved for invited userCancel invitation first
SuspendedPayment issue, temporarily disabledResolve payment first

Workflow Diagram


Step-by-Step Narrative

Step 1: Validate Request

  • Node: Request Validation
  • Type: API Middleware
  • Actions:
    • Validates required fields: from_user_id, to_user_id, license_id
    • Confirms requester has admin/owner role
    • Verifies both users are organization members
    • Checks license belongs to organization

Step 2: Check License Status

  • Node: License Lookup
  • Type: PostgreSQL Select
  • Table: licenses, license_assignments
  • Actions:
    • Retrieves license details and current assignment
    • Checks license is in active status
    • Verifies source user currently holds this license
    • Confirms target user doesn't already have a license

Step 3: Evaluate Reallocation Path

  • Node: Reallocation Decision
  • Type: Business Logic
  • Actions:
    • Checks source user's last activity date
    • Determines reallocation path:
      • Immediate: User inactive >30 days, or explicitly released
      • Grace Period: User active within 30 days
      • Blocked: User has active sessions in progress
    • Returns reallocation eligibility and path

Step 4a: Immediate Reallocation Path

For inactive users (>30 days) or explicit release:

  • Node: Immediate Transfer
  • Actions:
    1. Terminate any lingering sessions for source user
    2. Update license_assignments to unassign from source
    3. Create new assignment for target user
    4. Set assigned_at to current timestamp
    5. Clear any cached license tokens for source user

Step 4b: Grace Period Reallocation Path

For active users:

  • Node: Scheduled Reallocation
  • Actions:
    1. Create pending_reallocations record:
      • scheduled_at: now + 24 hours
      • status: pending
      • notified: false
    2. Send notification to source user:
      • Email: "Your license will be reassigned in 24 hours"
      • In-app notification
      • Include option to "Save Work" or "Request Extension"
    3. Schedule Celery task to execute after grace period
    4. Return pending status to admin

Step 5: Handle Active Sessions

  • Node: Session Management
  • Type: Session Service
  • Actions:
    • List all active sessions for source user
    • For immediate reallocation:
      • Terminate sessions with "License Reassigned" message
      • Allow 60-second grace for work saving
    • For grace period:
      • Sessions continue until grace period ends
      • Warning banner shown in active sessions

Step 6: Complete Assignment

  • Node: Assign to Target
  • Type: License Service
  • Actions:
    • Creates new license_assignment for target user
    • Generates new license token
    • Sets seat status to assigned
    • Updates seat utilization count

Step 7: Notifications

  • Node: Send Notifications
  • Type: Notification Service
  • Actions:
    • Source User:
      • Email: "Your CODITECT license has been reassigned"
      • Details: New assignment holder (if permitted), effective date
    • Target User:
      • Email: "A CODITECT license has been assigned to you"
      • Details: License type, getting started link
    • Admins:
      • Activity feed entry for reallocation

Step 8: Audit Trail

  • Node: Audit Log
  • Type: PostgreSQL Insert
  • Actions:
    • Records reallocation event:
      • action: license.seat.reallocated
      • from_user_id, to_user_id
      • license_id, reallocation_type
      • initiated_by, completed_at
    • Linked to compliance reporting

Error Handling

ErrorCodeResolution
Unauthorized401Provide valid JWT token
Forbidden403Requires admin/owner role
License Not Found404Verify license ID
Already Assigned409Target user already has license
Active Sessions409User has active work - use grace period
Payment Issue402Resolve subscription payment first

API Endpoints

MethodEndpointDescription
GET/api/v1/organizations/{id}/licensesList all licenses
GET/api/v1/organizations/{id}/licenses/availableList unassigned seats
POST/api/v1/organizations/{id}/licenses/reallocateReallocate seat
POST/api/v1/organizations/{id}/licenses/{id}/releaseRelease seat to pool
DELETE/api/v1/organizations/{id}/licenses/pending/{id}Cancel pending reallocation