---
title: "Workforce Intelligence"
slug: workforce-capacity
section: Placement & Matching
status: stable
description: "Real-time, skill-level visibility into the balance between host job order demand and applicant supply — with automated operational signals when imbalances are detected"
last-updated: 2026-10-07
---

# Workforce Intelligence

Real-time, skill-level visibility into the balance between host job order demand and applicant supply — with automated operational signals when imbalances are detected

> **Intelligence, Not Control**
>
> This engine does not block intake, throttle recruitment, or alter application flow. It provides structured awareness and automated operational activation so teams can act before imbalances become crises.

> **Related Pages**
>
> Demand originates from approved job orders. The Matching Engine uses workforce capacity signals for its gap analysis scoring dimension. See also: Reservation Concurrency Contract for how the position-level capacity counters this engine reads from are protected against concurrent reservation writes (row lock + 409 RESERVATION_POSITION_TAKEN + nightly integrity scan).

## What It Does

The Workforce Capacity Intelligence Engine provides sponsor leadership and operations teams with forward-looking, skill-level equilibrium analysis. It sits within the Season / Operational Intelligence layer of Globus.

Calculates real-time demand/supply gap per program, season, and skill category / Detects capacity imbalance using configurable, database-driven threshold rules / Automatically publishes structured operational events when thresholds are crossed / Surfaces imbalance signals in dashboards and executive reporting / Maintains a complete audit trail of every imbalance lifecycle
## What It Does Not Do

> **Explicit Boundaries**
>
> The Capacity Intelligence Engine is not a control mechanism. It is an intelligence layer.

Does not throttle application intake / Does not block recruitment pipelines / Does not control marketing spend / Does not track DS-2019 form inventory / Does not automate financial forecasting
For volume controls that do enforce limits, see Quota Model & Capacity Controls .

This engine measures position demand vs. applicant supply. It does not measure on-site supervision load. For the active staff/supervisor-to-participant ratio per host — an observational sibling that flags understaffed sites (and likewise never blocks a placement) — see Staff-to-Participant Ratio Intelligence .

## Core Concepts

### Host Demand

The number of approved, open positions across job orders. Demand is scoped by:

Program / Season / Skill category / Sub-skill (optional) / Location (optional)
Derived from: job_orders (positions_total minus placements not cancelled or withdrawn), via getWorkforceBalance.

> **How position counters stay accurate under concurrent reservations**
>
> The job_order_capacity counters this engine reads (positionsReserved, positionsPlaced) are protected at the write path by two layered defenses: Position-side row lock. Every reservation insert acquires a SELECT … FOR UPDATE on the job order row inside the same transaction that increments positionsReserved, with a re-read of the placement cap before commit. The losing concurrent caller receives HTTP 409 RESERVATION_POSITION_TAKEN. Applicant-side partial unique index. A partial unique index on active reservations and placements (fix #1894) prevents the same applicant from holding two active rows on the same job order, even if a raw write somehow bypassed the row lock. Anything that slips past both defenses is caught by the nightly reservation-placement-integrity-scan . See Layer 7 &rarr; Reservation Concurrency Contract for the full spec and Error Handling &rarr; Reservation Position Race runbook for response procedures.

### Applicant Supply

The number of qualified, placement-ready applicants per the same scoping dimensions. Supply is determined by readiness status and qualification level.

Derived from: applications whose journey_position is placement, visa_sevis or pre_departure (via getWorkforceBalance).

> **Housing supply is not part of capacity-gap math**
>
> The Workforce Intelligence engine intentionally only models position supply and demand. Housing inventory lives in two separate tables that this page does not aggregate: host_housing — host-managed, on-site units tied to a host org and pre-cleared by compliance during host verification. housing_leads + job_order_housing_leads — third-party housing options sourced for a specific job order; each lead carries its own compliance approval status and only counts as supply once approved on the job order's housing gate. See Job Orders → Housing Vocabulary and Host Portal → Housing Leads vs Host-Managed Inventory for the full vocabulary and approval flow.

### Capacity Gap

Gap = Applicants Ready &minus; Positions

value
## Threshold Rules

Thresholds are database-driven and configurable per program or globally. No hardcoded values. Rules are stored in capacity_gap_rules and evaluated by the Rules Engine . Rules are managed with `POST /api/capacity/gap-rules`, `PATCH /api/capacity/gap-rules/:id` and `DELETE /api/capacity/gap-rules/:id` (all `capacity.rules.manage`; the list read, `GET /api/capacity/gap-rules`, needs `capacity.view`). `POST /api/capacity/recalculate` (`capacity.adjust`, optional `programId`, `seasonId` and `brandId` in the body) re-runs the engine and returns a summary with `totalRows`, `imbalancesDetected`, `eventsPublished`, `resolved` and the per-row `results`.

| Rule | Condition | Severity |
| --- | --- | --- |
| scenario | condition | |

_(row above is a template, repeated for each data row)_

## Auto-Publish Events

When a threshold is crossed, Globus automatically publishes a structured event into the Event Outbox. No human clicking refresh. No manual dashboard monitoring.

> **Auto-Publish Is a Signal, Not an Action**
>
> Auto-publish creates awareness and structured action. It does not block anything, does not alter intake, and does not modify application state. It broadcasts an operational signal into the system.

Example Event Payload

type / CAPACITY_IMBALANCE_DETECTED / program / Teach USA / season / 2026 / skill / English Teacher / positions / applicants / gap / direction / OVERSUPPLY / severity / HIGH
### Event Lifecycle

Imbalance events follow a structured lifecycle. The system avoids duplicate alerts by tracking the state of each imbalance record.

### Event Handling

Because Globus already uses an event outbox + worker pattern, published events are processed cleanly by downstream consumers. The n8n Automation Layer handles most notification routing.

## Processing Flow

The engine recalculates on every relevant data change. The full processing sequence:

> **No Blocking, No Throttling**
>
> This flow is purely observational. It publishes intelligence. It does not gate or delay any applicant or host action.

## Dashboard Signals

### Workforce Balance Panel

Each program displays a skill-level workforce balance panel showing real-time supply and demand:

| Skill | Positions | Applicants | Gap | Status |
| --- | --- | --- | --- | --- |
| skill | positions | applicants | gap | |

_(row above is a template, repeated for each data row)_

### Executive View

Executive dashboards surface aggregated imbalance data across the entire sponsor portfolio:

## Lifecycle Management

Each imbalance record is tracked as a lifecycle entity. The system avoids alert fatigue through structured state management.

Imbalance Record Fields

Avoid duplicate event publishing (idempotent) / Publish escalation only if severity increases / Publish resolution event when gap returns to acceptable range / Version each state change with timestamp
## Data Model

The engine relies on four primary data structures, plus the separate per-season `program_season_capacity` row described below. All skill categories reference the shared system_lookups taxonomy to prevent misclassification.

The capacity and waitlist engine keeps a per-season capacity row in `program_season_capacity`: one row per program and season (unique on the pair) with `max_capacity`, `waitlist_enabled` and an optional `max_waitlist_size`. It is read at `GET /api/admin/programs/:programId/seasons/:seasonId/capacity` (`capacity.view`) and upserted with `PUT` on the same path (`capacity.adjust`); reducing the maximum below the current placed count returns 200 with a `warnings` array and does not promote or reject anyone.

name
## Permissions (RBAC)

Access to workforce capacity intelligence follows the RBAC model .

View Access

Program Managers / Operations / Executive / Compliance
Rule Modification

Requires capacity.rules.manage permission

Capacity Adjustment

Requires `capacity.adjust` permission: `POST /api/capacity/recalculate`, the per-season capacity upsert (`PUT .../seasons/:seasonId/capacity`) and waitlist enqueue and removal. `capacity.view` covers the read routes; the API-key scope `capacity.read` maps to `capacity.view`, `capacity.rules.manage` and `capacity.adjust`.

Job Order Modification

Requires job_orders.create or job_orders.manage permission (staff), or host.positions.manage (host portal)

## Design Principles

## Strategic Impact

The Workforce Capacity Intelligence Engine transforms Globus from a record-keeping ERP into an operational intelligence platform for sponsor workforce equilibrium.

> **Sponsor Intelligence, Not CRM Reporting**
>
> This aligns directly with the layered architecture, event outbox model, zero-hardcode philosophy, season-based program model, and multi-brand sponsor structure. Visibility before imbalance becomes a crisis — not controls that frustrate teams.

> **Where the operator sees this**
>
> The People & Placements dashboard is the surface where workforce gaps and quota burn become operationally visible per camp / job order / season. Live-app build spec: Placements Overview &rarr; Engineering Brief . The KPI landing surface (total / filled / reserved / available / fill rate %) and the spec-only POST /api/placements/recompute action (not built; the live recalculation is the capacity.adjust-gated POST /api/capacity/recalculate) that triggers the Capacity Engine recalculation are specified in the Placement Fill-Rate Dashboard .
