Ir al contenido

ADR-024 — Employee Bar Semantics and Contract Matching

ADR-024 — Employee Bar Semantics and Contract Matching

Sección titulada «ADR-024 — Employee Bar Semantics and Contract Matching»

Accepted

The org-chart detail view displays coverage bars per employee. The original implementation calculated effective_hours / position.required_weekly_hours, producing percentages like “12h / 36h = 33%”. This is conceptually incorrect for two reasons:

  1. An employee with a 12h contract cannot be assigned to a 36h position. Contract hours must match the position’s required hours for regular assignments (not reinforcements).
  2. The employee bar should represent the employee’s fulfillment of their own contractual obligation, not the fraction they cover of the position.

Showing the utilization percentage of the employee’s weekly pool (assigned hours vs total pool) was considered, but discarded because it requires an additional fetch to the balance API per employee and adds complexity without clear benefit in this view.

Rule 1 — mandatory contract matching. For regular assignments (not reinforcement), assignment.effective_hours must equal position.required_weekly_hours. An employee can only fill a position whose required hours match their contract hours. This rule is enforced in the assignment logic and reflected in the UI.

Rule 2 — employee bar = own fulfillment. The worker row coverage bar shows the employee’s fulfillment percentage relative to their own obligation. With Rule 1, regular assignments always produce 100% (green). The display format is Xh / Xh where both values are the assignment’s effective_hours.

Rule 3 — reinforcements without a denominator. Reinforcements (is_reinforcement = true) contribute additional hours without filling a position slot (see [[adr-001-c-hour-color-vocabulary|ADR-001-c]] Rule 3). Their bar is always blue and shows only the contributed hours (Xh) without a denominator, since they have no position requirement of their own to fulfill.

Rule 4 — unit bar unchanged. The unit-level coverage bar ([[adr-001-c-hour-color-vocabulary|ADR-001-c]]) is not affected. It continues to calculate total_assigned_hours / total_required_hours * 100 from position data aggregated by the API.

  • The worker row always shows 100% green for regular assignments with well-formed data. The differentiating information lives at the position level (vacant vs covered) and unit level (aggregate coverage).
  • Reinforcements are visually distinguished with a blue bar and no hour denominator.
  • If for any reason the data contains a mismatch (effective_hours != required_weekly_hours for a regular assignment), the bar still shows 100% of the employee’s contract, not the fraction of the position.
  • The kdx-worker-row showcase is updated to reflect these semantics: examples with matching hours and a blue reinforcement example.
  • Complements [[adr-001-c-hour-color-vocabulary|ADR-001-c]] (unit-level colors) with employee-level semantics.