Skip to main content

Officiating Engine

import { officiatingEngine } from 'tods-competition-factory';

The officiatingEngine is a standalone state engine that manages the lifecycle of official records — certifications, evaluations, assignments, and suspensions for tournament officials (chair umpires, referees, line umpires, etc.). It operates on OfficialRecord documents independently from tournament records.

The engine follows the same patterns as other factory engines (state management, executionQueue with piping and rollback) but manages its own state.


Core Concepts

An OfficialRecord is the aggregate root for a single official. It contains:

  • Certifications — credentials with status tracking (e.g., ITF Gold Badge Chair Umpire)
  • Evaluations — performance reviews with scored criteria and workflow status
  • Assignments — tournament role assignments with status lifecycle
  • Suspensions — periods during which an official is ineligible
  • Certification Requirements — org-defined prerequisites for certification levels
  • Evaluation Policies — structured templates defining evaluation criteria and scoring

State Machines

Certification Status

Terminal state: REVOKED

Evaluation Status

Terminal state: APPROVED

Assignment Status

Terminal states: DECLINED, CANCELLED, COMPLETED


State Management

reset

Clears all official records from engine state.

officiatingEngine.reset();

getState / setState

// Get all records (deep copy)
const { officialRecords } = officiatingEngine.getState();

// Load records into engine
officiatingEngine.setState(officialRecords);

setActiveOfficialRecordId / getActiveOfficialRecordId

When multiple records are loaded, set the active record for method calls that don't specify an officialRecordId.

officiatingEngine.setActiveOfficialRecordId('rec-001');
const activeId = officiatingEngine.getActiveOfficialRecordId();

setOfficialRecord / removeOfficialRecord

// Upsert a single record
officiatingEngine.setOfficialRecord(officialRecord);

// Remove by ID
officiatingEngine.removeOfficialRecord('rec-001');

Mutations

All mutations accept either officialRecordId (resolved from engine state) or officialRecord (passed directly).

createOfficialRecord

Creates a new OfficialRecord, sets it in state, and makes it the active record.

const { officialRecord } = officiatingEngine.createOfficialRecord({
personId: 'person-001', // required
organisationId: 'ITF', // optional
officialRecordId: 'rec-001', // optional — auto-generated if absent
});

Certifications

addCertification

const { certification } = officiatingEngine.addCertification({
organisationId: 'ITF', // required
certificationFamily: 'UMPIRE', // required
certificationLevel: 'GOLD_BADGE', // optional
status: 'ACTIVE', // optional — defaults to ACTIVE
validFrom: '2025-01-01', // optional
validUntil: '2028-12-31', // optional
documentReferences: [], // optional
notes: '', // optional
});

modifyCertification

officiatingEngine.modifyCertification({
certificationId: 'cert-001',
updates: { validUntil: '2029-12-31', notes: 'Renewed' },
});

removeCertification

officiatingEngine.removeCertification({ certificationId: 'cert-001' });

transitionCertificationStatus

Validates the transition against VALID_CERTIFICATION_TRANSITIONS before applying. Records a statusHistory entry with timestamp.

officiatingEngine.transitionCertificationStatus({
certificationId: 'cert-001',
toStatus: 'SUSPENDED',
transitionedBy: 'admin-001', // optional
reason: 'Pending investigation', // optional
});

Evaluations

addEvaluation

const { evaluation } = officiatingEngine.addEvaluation({
evaluatorPersonId: 'person-002', // required — who is evaluating
overallRating: 4.2, // required
subjectPersonId: 'person-001', // optional
tournamentId: 'tourn-001', // optional
matchUpId: 'matchup-001', // optional
evaluationDate: '2026-03-15', // optional — defaults to now
policyName: 'ITF_CHAIR_UMPIRE_EVALUATION', // optional — links to evaluation policy
scores: [
// optional — criterion-level scores
{ criterionId: 'rules_knowledge', sectionId: 'pre_match', value: 4 },
],
comments: 'Strong match management', // optional
});

modifyEvaluation

Only editable in DRAFT or REJECTED status.

officiatingEngine.modifyEvaluation({
evaluationId: 'eval-001',
updates: { overallRating: 4.5, comments: 'Updated assessment' },
});

removeEvaluation

officiatingEngine.removeEvaluation({ evaluationId: 'eval-001' });

transitionEvaluationStatus

When transitioning to SUBMITTED, validates that all required criteria scores are present (if an evaluation policy is attached).

officiatingEngine.transitionEvaluationStatus({
evaluationId: 'eval-001',
toStatus: 'SUBMITTED',
transitionedBy: 'eval-002', // optional
reason: '', // optional
});

Assignments

assignOfficial

const { assignment } = officiatingEngine.assignOfficial({
tournamentId: 'tourn-001', // required
roleSubtype: 'CHAIR_UMPIRE', // required
assignedDate: '2026-03-10', // optional
startDate: '2026-04-01', // optional
endDate: '2026-04-07', // optional
assignedBy: 'admin-001', // optional
notes: '', // optional
});

removeOfficialAssignment

officiatingEngine.removeOfficialAssignment({ assignmentId: 'assign-001' });

transitionAssignmentStatus

officiatingEngine.transitionAssignmentStatus({
assignmentId: 'assign-001',
toStatus: 'CONFIRMED',
transitionedBy: 'admin-001', // optional
reason: '', // optional
});

Suspensions

addSuspension

const { suspension } = officiatingEngine.addSuspension({
organisationId: 'ITF', // optional
suspensionType: 'MISCONDUCT', // optional
suspensionNotes: 'Under review', // optional
suspendedFrom: '2026-03-01', // optional
suspendedUntil: '2026-06-01', // optional
});

removeSuspension

officiatingEngine.removeSuspension({ suspensionId: 'susp-001' });

Certification Requirements

addCertificationRequirement

Defines organisational prerequisites for a certification level. Used by getOfficialEligibility to check readiness.

officiatingEngine.addCertificationRequirement({
certificationFamily: 'UMPIRE',
certificationLevel: 'GOLD_BADGE',
organisationId: 'ITF',
description: 'Requirements for ITF Gold Badge',
requirements: ['Complete advanced course', 'Pass written exam'],
prerequisiteLevels: ['SILVER_BADGE'], // optional
minimumAssignments: 50, // optional
minimumEvaluationScore: 4.0, // optional
validityPeriodMonths: 48, // optional
});

Evaluation Policies

addEvaluationPolicy

Attaches a structured evaluation template to the official record. Two built-in policies are provided as fixtures: POLICY_OFFICIATING_EVALUATION_CHAIR_UMPIRE and POLICY_OFFICIATING_EVALUATION_REFEREE.

import { POLICY_OFFICIATING_EVALUATION_CHAIR_UMPIRE } from 'tods-competition-factory';

officiatingEngine.addEvaluationPolicy({
evaluationPolicy: POLICY_OFFICIATING_EVALUATION_CHAIR_UMPIRE,
});

Policy structure:

{
policyName: string;
policyVersion: string;
organisationId: string;
officialRoleSubtype: string;
scoringMethod: 'WEIGHTED_AVERAGE' | 'SIMPLE_AVERAGE' | 'SUM';
passingThreshold: number;
sections: [{
sectionId: string;
sectionName: string;
weight: number;
criteria: [{
criterionId: string;
criterionName: string;
description: string;
scoringType: 'SCALE' | 'NUMERIC' | 'CHECKLIST' | 'TEXT';
scaleOptions?: [{ value: number; label: string }];
required: boolean;
weight: number;
}]
}]
}

Queries

getOfficialRecord

Returns the full OfficialRecord structure.

const { officialRecord } = officiatingEngine.getOfficialRecord();
// or with explicit ID
const { officialRecord } = officiatingEngine.getOfficialRecord({ officialRecordId: 'rec-001' });

getOfficialCertifications

Returns certifications with optional filtering.

const { certifications } = officiatingEngine.getOfficialCertifications({
certificationFamily: 'UMPIRE', // optional
certificationLevel: 'GOLD_BADGE', // optional
organisationId: 'ITF', // optional
activeOnly: true, // optional — filters to ACTIVE status
});

validateCertification

Checks whether a specific certification is currently valid (status, date range).

const { valid, reasons, certification } = officiatingEngine.validateCertification({
certificationId: 'cert-001',
asOfDate: '2026-06-15', // optional — defaults to today
});
// valid: boolean
// reasons: string[] — empty when valid, populated with failure reasons otherwise

getEvaluations

Returns all evaluations, optionally filtered.

const { evaluations } = officiatingEngine.getEvaluations();

getEvaluationSummary

Computes aggregate statistics from APPROVED evaluations.

const { summary } = officiatingEngine.getEvaluationSummary({
policyName: 'ITF_CHAIR_UMPIRE_EVALUATION', // optional — filter by policy
});
// summary: { evaluationCount: number, averageRating: number }

getEvaluationTemplate

Converts an evaluation policy into a flat array of form fields for UI rendering.

const { fields, evaluationPolicy } = officiatingEngine.getEvaluationTemplate({
policyName: 'ITF_CHAIR_UMPIRE_EVALUATION', // resolves from record's policies
});
// fields: EvaluationFormField[] — flat list with sectionId, criterionId, scoringType, etc.

Can also accept evaluationPolicy directly (without an official record).


getOfficialEligibility

Checks whether an official meets all requirements for a given certification.

const { eligible, reasons } = officiatingEngine.getOfficialEligibility({
certificationFamily: 'UMPIRE',
certificationLevel: 'GOLD_BADGE', // optional
organisationId: 'ITF', // optional
asOfDate: '2026-06-15', // optional
});
// eligible: boolean
// reasons: string[] — e.g., ['Official has active suspension(s)', 'Insufficient completed assignments: 12/50']

getOfficialAssignments

Returns assignments with optional filtering.

const { assignments } = officiatingEngine.getOfficialAssignments({
tournamentId: 'tourn-001', // optional
roleSubtype: 'CHAIR_UMPIRE', // optional
status: 'CONFIRMED', // optional
});

Execution Queue

Batch-execute multiple directives with optional rollback on error and result piping between steps.

const result = officiatingEngine.executionQueue(
[
{
method: 'createOfficialRecord',
params: { personId: 'person-001', organisationId: 'ITF' },
},
{
method: 'addCertification',
params: { organisationId: 'ITF', certificationFamily: 'UMPIRE' },
pipe: { officialRecordId: true }, // pipes officialRecordId from previous result
},
{
method: 'assignOfficial',
params: { tournamentId: 'tourn-001', roleSubtype: 'CHAIR_UMPIRE' },
pipe: { officialRecordId: true },
},
],
true,
); // rollbackOnError = true

// result: { success, results: [{ success, methodName, ... }, ...] }
// On error: { error, rolledBack: true }

Piping: The pipe object maps keys from the previous result into the current directive's params. This enables chaining operations where a later step needs an ID produced by an earlier one.

Rollback: When rollbackOnError is true, the engine snapshots state before execution and restores it if any directive fails.


Constants

All officiating constants are available via the aggregate export:

import { officiatingConstants } from 'tods-competition-factory';

const {
// Certification status
CERT_ACTIVE,
CERT_EXPIRED,
CERT_SUSPENDED,
CERT_REVOKED,
CERT_PENDING_RENEWAL,
// Evaluation status
EVAL_DRAFT,
EVAL_SUBMITTED,
EVAL_REVIEWED,
EVAL_APPROVED,
EVAL_REJECTED,
// Assignment status
ASSIGN_PROPOSED,
ASSIGN_CONFIRMED,
ASSIGN_DECLINED,
ASSIGN_CANCELLED,
ASSIGN_COMPLETED,
// Transition maps
VALID_CERTIFICATION_TRANSITIONS,
VALID_EVALUATION_TRANSITIONS,
VALID_ASSIGNMENT_TRANSITIONS,
// Terminal / editable states
CERTIFICATION_TERMINAL,
EVALUATION_TERMINAL,
ASSIGNMENT_TERMINAL,
EVALUATION_EDITABLE,
// Evaluation scale
EVALUATION_SCALE_OPTIONS,
} = officiatingConstants;

Types

import type {
OfficialRecord,
OfficialRecords,
OfficialCertification,
OfficialEvaluation,
OfficialAssignment,
OfficialSuspension,
CertificationRequirement,
EvaluationPolicy,
EvaluationSection,
EvaluationCriterion,
EvaluationScore,
EvaluationFormField,
CertificationStatus,
EvaluationStatus,
AssignmentStatus,
OfficialRoleSubtype,
CertificationFamily,
CertificationLevel,
ScoringType,
ScoringMethod,
OfficiatingDirective,
OfficiatingDirectives,
} from 'tods-competition-factory';

Key Type Enums

TypeValues
OfficialRoleSubtypeCHAIR_UMPIRE, LINE_UMPIRE, REFEREE, CHIEF_UMPIRE, DEPUTY_REFEREE, REVIEW_OFFICIAL, COURT_SUPERVISOR
CertificationFamilyUMPIRE, REFEREE, CHIEF_UMPIRE, REVIEW_OFFICIAL
CertificationLevelWHITE_BADGE, BRONZE_BADGE, SILVER_BADGE, GOLD_BADGE
ScoringTypeNUMERIC, SCALE, CHECKLIST, TEXT
ScoringMethodWEIGHTED_AVERAGE, SIMPLE_AVERAGE, SUM