Sanctioning Governor
import { sanctioningGovernor } from 'tods-competition-factory';
The sanctioningGovernor re-exports all sanctioning mutation and query functions for use outside the sanctioning engine. While the sanctioningEngine provides a complete stateful API, the governor exports individual functions that can be called directly with a sanctioningRecord parameter.
For full engine documentation including state management, executionQueue, and workflow examples, see Sanctioning Engine.
Mutations
createSanctioningRecord
Creates a new SanctioningRecord in DRAFT status.
{
governingBodyId: string;
applicant: Applicant;
proposal: TournamentProposal;
sanctioningTier?: TierClassification;
sanctioningPolicy?: string;
}
Returns: { success, sanctioningRecord }
updateProposal
Updates proposal fields on a record in editable status (DRAFT or MODIFICATION_REQUESTED).
{
sanctioningRecord: SanctioningRecord;
updates: Partial<TournamentProposal>;
}
addEventProposal / removeEventProposal / updateEventProposal
CRUD operations for event proposals within a sanctioning record.
// Add
{
sanctioningRecord;
eventProposal: EventProposal;
}
// Returns: { success, eventProposalId }
// Remove
{
sanctioningRecord;
eventProposalId: string;
}
// Update
{
sanctioningRecord;
eventProposalId: string;
updates: Partial<EventProposal>;
}
submitApplication
Transitions DRAFT → SUBMITTED. Validates endorsement if required by policy. Snapshots the policy version.
{ sanctioningRecord; sanctioningPolicy?: SanctioningPolicy; submittedBy?: string }
reviewApplication
Transitions SUBMITTED → UNDER_REVIEW.
{ sanctioningRecord; reviewer?: Reviewer }
approveApplication
Transitions UNDER_REVIEW or CONDITIONALLY_APPROVED → APPROVED.
{ sanctioningRecord; approvedBy?: string; reason?: string }
conditionallyApprove
Transitions UNDER_REVIEW → CONDITIONALLY_APPROVED with conditions.
{ sanctioningRecord; conditions: Array<{ description: string }>; approvedBy?: string }
meetCondition
Marks a condition as met. Returns { allConditionsMet: boolean }.
{ sanctioningRecord; conditionId: string; metNotes?: string }
rejectApplication
Transitions to REJECTED (terminal).
{ sanctioningRecord; rejectedBy?: string; reason?: string }
withdrawApplication
Transitions to WITHDRAWN (terminal). Available from DRAFT, SUBMITTED, CONDITIONALLY_APPROVED, APPROVED, MODIFICATION_REQUESTED.
{ sanctioningRecord; withdrawnBy?: string; reason?: string }
requestModification
Transitions to MODIFICATION_REQUESTED, making the proposal editable again.
{ sanctioningRecord; requestedBy?: string; note?: string }
requestEndorsement / endorseApplication / declineEndorsement
Endorsement sub-workflow.
// Request
{ sanctioningRecord; endorserId: string; endorserName?: string; endorserContact?: PersonReference }
// Endorse
{ sanctioningRecord; endorserNotes?: string; conditions?: string[] }
// Decline
{ sanctioningRecord; declineReason?: string }
addReviewNote
Adds a review note to the record.
{ sanctioningRecord; note: string; reviewerId?: string; reviewerName?: string }
Returns: { success, noteId }
openProposalRegistration
Opens (or adjusts) public registration on a proposal before a tournamentRecord exists. Assigns a tournamentId to the proposal (minting one if absent) so a public site can render a registration page against a not-yet-activated proposal, and gives each proposed event a stable eventId. Merges any supplied registrationProfile fields and ensures entriesOpen is set (opening now when no explicit value is present). Gated only against terminal statuses (REJECTED, WITHDRAWN, CLOSED); stricter workflow/policy is enforced by the consuming service.
{ sanctioningRecord; tournamentId?: string; registrationProfile?: Partial<RegistrationProfile> }
Returns: { success, tournamentId, registrationProfile }
activateFromSanctioning
Generates a tournamentRecord from an APPROVED sanctioning record and transitions to ACTIVE. Reuses the tournamentId and per-event eventIds already assigned by openProposalRegistration — so registrations collected before activation remain valid — otherwise mints new ids.
{ sanctioningRecord; sanctioningPolicy?: SanctioningPolicy; venues?: Venue[] }
Venues. Pass venues to materialize canonical venues onto the generated tournamentRecord —
typically pulled by the caller from a facility registry for the facility the sanctioning record was
attached to. They are supplied, not resolved: the factory has no runtime dependencies and no
service awareness, so resolution belongs to the caller and materialization to the engine. A canonical
venue carries facilityId and typed courts, so the activated tournament inherits one
cross-tournament identity for the place it is played at instead of a re-entered venue.
When no venues are supplied, proposal.venues (VenueProposal[]) is materialized instead. That is
a fallback: a proposal venue is what an applicant typed, so it has no canonical identity — its
facilityId defaults to its own venueId — and numberOfCourts is deliberately not expanded
into placeholder courts, which would fabricate identities to be reconciled against a registry later.
Supplied venues always win over the proposal description.
Returns: { success, tournamentRecord }
proposeAmendment
Proposes changes to an APPROVED or ACTIVE record. Minor amendments are auto-approved; substantial amendments require review.
{ sanctioningRecord; changes: ProposalChange[]; sanctioningPolicy?: SanctioningPolicy; proposedBy?: string }
Returns: { success, amendmentId, severity, autoApproved }
reviewAmendment
Approves or rejects a proposed amendment. Approved amendments apply their changes to the proposal.
{ sanctioningRecord; amendmentId: string; approved: boolean; reviewerNotes?: string }
transitionToPostEvent
Transitions ACTIVE → POST_EVENT.
{ sanctioningRecord; transitionedBy?: string }
submitComplianceItem / verifyComplianceItem / waiveComplianceItem
Compliance item lifecycle management.
// Submit
{ sanctioningRecord; itemId: string; value?: any }
// Verify
{ sanctioningRecord; itemId: string }
// Returns: { success, allCompliant: boolean }
// Waive
{ sanctioningRecord; itemId: string; reason?: string }
flagComplianceIssues
Transitions POST_EVENT → ISSUES_FLAGGED.
{ sanctioningRecord; transitionedBy?: string; reason?: string }
closeApplication
Transitions to CLOSED (terminal).
{ sanctioningRecord; closedBy?: string; reason?: string }
Queries
querySanctioningRecord
Returns a deep copy of the sanctioning record.
{
sanctioningRecord;
}
getAvailableTransitions
Returns valid status transitions for the record's current status.
{
sanctioningRecord;
}
Returns: { success, availableTransitions: SanctioningStatus[] }
getStatusHistory
Returns the full status transition history.
{
sanctioningRecord;
}
Returns: { success, statusHistory: StatusTransition[] }
getCompleteness
Returns a completeness score (0-100%) with missing fields.
{ sanctioningRecord; sanctioningPolicy?: SanctioningPolicy }
Returns: { success, completeness: { score, totalFields, completedFields, missingFields } }
getEligibleTiers
Returns which policy tiers the proposal qualifies for.
{
proposal: TournamentProposal;
sanctioningPolicy: SanctioningPolicy;
}
Returns: { success, eligibleTiers, tierEligibilities }
getCalendarConflicts
Detects scheduling conflicts using injected calendar context.
{
sanctioningRecord;
calendarContext: CalendarContext;
}
Returns: { success, conflicts, errors, warnings, hasConflicts }
Conflict types: PROXIMITY, SAME_WEEK, BLACKOUT, MAX_EVENTS_PER_WEEK
validateProposal
Validates proposal against policy and optional tier constraints.
{ proposal: TournamentProposal; sanctioningPolicy: SanctioningPolicy; sanctioningTier?: TierClassification }
Returns: { success, valid, issues, errors, warnings }
Checks: insurance, safety plan, medical plan, anti-corruption, safeguarding, lead time, prize money, courts, event types, draw types, draw sizes, match formats, genders, qualifying, personnel.
validateStatusTransition
Validates whether a status transition is allowed.
{
fromStatus: SanctioningStatus;
toStatus: SanctioningStatus;
}
Returns: { success, valid } or { error } with valid targets in context.