Skip to main content

Introduction to Policies

Policies determine how the various Competition Factory engines function and can shape the way that results are returned. Policies can be attached to the tournamentRecord, events, or to drawDefinitions within an event. They can also be passed directly into some factory methods; e.g. a Participant Policy can be passed into a method which returns particpipants and filter out attributes which are not to be displayed.

The structure of a policyDefinitions object is as follows:

{
[policyType]: { // e.g. 'seeding' or 'avoidance'
policyName: 'name' // for 'seeding' can be the provider of the policy, e.g. 'ITF' or 'USTA'
...attributes // attributes relevant to the policyType
},
[anotherPolicyType]: {
policyName: 'name'
...attributes
},
}

Policy Types

  • Avoidance Policy: Can be attached to drawDefinitions to specify the attriubutes by which participants should be separated
  • Participant Policy Enables participant details to be filtered to respect privacy concerns
  • Position Actions Policy: Determines valid actions for positions in a draw structure
  • MatchUp Actions Policy: Determines valid actions for matchUps (substitutions, penalties, referree, scheduling)
  • Seeding Policy: Sets seeding pattern and thresholds for number of seeds allowed for draw sizes
  • Scheduling Policy: Defines average and rest/recovery times for matchUpFormats, categoryNames, and categoryTypes
  • Round Robin Tally Policy: Configures calculations which determine participant finishing positions
  • Feed-In Policy: Determining the the patterns which direct participants into consolation feed rounds
  • Progression Policy: Configuration related to participant progression, e.g. automatic qualifier placement, double-exit effects
  • Round Naming Policy: Specifies how rounds of draw structures should be named
  • Scoring Policy: Restricts available matchUpFormats, defines a default and conditions for "ready to score"
  • Voluntary Consolation Policy: Specifies { winsLimit, finishingRoundLimit } for voluntary consolation eligibility
  • Competitive Bands: Determines thresholds for ROUTINE and COMPETITIVE matches in getCompetitiveProfile
  • Draws Policy: Configures either global or draw-type-specific drawTypeCoercion
  • Ranking Policy: Defines how points are awarded for tournament performance
  • Print Policy: Opaque extension slot for per-tournament print artifact composition (interpreted by consumers)

When does a policy travel with the record?

Policies divide into two delivery models depending on what they affect:

Attached-to-record (mutation-time)

Any policy whose values shape the output of a mutation must be embedded in the tournamentRecord (or event / drawDefinition / structure) as an APPLIED_POLICIES extension. The standard mutation flow runs each method twice — once on the server, once on the client after server ack — and both runs must consult the same policy bytes. Reading from any other source (process registry, environment, etc.) risks split-brain state.

Mutation-time policies: MATCHUP_ACTIONS, POSITION_ACTIONS, AVOIDANCE, SEEDING, DRAWS, FEED_IN, COMPETITION, PROGRESSION, SCHEDULING, ROUND_ROBIN_TALLY, SANCTIONING, SCORING, AUDIT, VOLUNTARY_CONSOLATION, COMPETITIVE_BANDS, PARTICIPANT.

Registry-served (query-time)

RANKING_POINTS and other display-only policies (ROUND_NAMING, DISPLAY, PRIVACY, PRINT) are read at query time and don't drive mutations. They can be served via the in-process policyRegistry:

import { policyRegistry, scaleEngine } from 'tods-competition-factory';

// Consumer registers — usually at boot from a GET /policies/catalog response
policyRegistry.register({
policyType: 'rankingPoints',
name: 'USTA_JUNIOR_2026',
version: '2026.01',
definition: /* fetched from CFS */,
});

// Engines resolve by name when policyDefinitions isn't passed:
scaleEngine.getTournamentPoints({
tournamentRecord,
policyName: 'USTA_JUNIOR_2026',
level: 1,
});

The registry is a per-process singleton. Each consumer (TMX, CFS, courthive-rankings) hydrates its own. Federations adopt a policy by POSTing their version to CFS; consumers re-hydrate at next boot. See POLICY_DELIVERY for the full architecture.