Venue Governor
addCourt
Add a court to a Venue. See court under venue in Type Defs.
const court = {
altitude, // optional
courtDimensions, // optional
courtId, // generated automatically if not provided
courtName,
dateAvailability, // optional - see below
latitude, // optional
longitude, // optional
onlineResources, // optional
pace, // optional - string; ITF enums
surfaceCategory, // optional - surface constant, e.g. CLAY, HARD, GRASS, CARPET, or ARTIFICIAL
surfaceType, // string; see: https://www.itftennis.com/en/about-us/tennis-tech/recognised-courts/
surfacedDate?: Date;
}
engine.addCourt({ venueId, court });
addCourts
Convenience function to bulk add courts to a Venue. Only adds dataAvailability and courtName. See Scheduling. See examples in Creating Courts.
const dateAvailability = [
{
date: '2020-01-01T00:00', // if no date is provided then this profile will be used as default
startTime: '07:00',
endTime: '19:00',
bookings: [
{ startTime: '07:00', endTime: '08:30', bookingType: 'PRACTICE' },
{ startTime: '08:30', endTime: '09:00', bookingType: 'MAINTENANCE' },
{ startTime: '13:30', endTime: '14:00', bookingType: 'MAINTENANCE' },
],
},
];
engine.addCourts({
venueAbbreviationRoot, // optional boolean; whether to use venue.venueAbbreviation in court naming
dateAvailability, // optional -- see definition in Tournament Engine API
courtNameRoot, // optional; defaults to 'Court'
courtNames: ['Court 1', 'Court 2', 'Court 3'], // optional
courtsCount: 3, // optional, can be added/modified later; also can be derived from courtNames.length
venueId,
});
addVenue
Adds venueId if not provided. See examples in Creating Venues.
engine.addVenue({
venue: {
venueName,
defaultStartTime, // optional - HH:MM format, paired with defaultEndTime
defaultEndTime, // optional - HH:MM format, paired with defaultStartTime
dateAvailability, // optional - venue-level date availability (same structure as court dateAvailability)
isPrimary, // optional boolean - designates this as the tournament's primary venue
},
context, // optional - adds detail in CONTEXT extension
});
Notes:
defaultStartTimeanddefaultEndTimemust be provided together — setting only one returns an errordefaultEndTimemust be afterdefaultStartTime- These defaults are inherited by all courts in the venue. See Venue-Level Scheduling Constraints
- Setting
isPrimary: trueautomatically clearsisPrimaryfrom any previously-primary venue (at most one venue can be primary). See Primary Venue. The venue that loses the flag is announced with amodifyVenuenotice (as withmodifyVenue)
addVenueOtherId
Upserts a UnifiedVenueID entry into a venue's venueOtherIds[] array — the CODES mechanism for recording that the same physical venue is known by a different id at another organisation (a federation, a canonical facility registry, an upstream league site). The venue analog of addPersonOtherId.
engine.addVenueOtherId({
venueId, // required — locates the venue WITHIN this tournamentRecord
organisationId, // required — the issuing organisation (string)
otherVenueId, // required — the venue's id in THAT organisation's namespace
uniqueOrganisationName, // optional — human-readable name for the organisation
});
Two distinct ids. venueId locates the venue inside the current tournamentRecord; otherVenueId is the value stored into the entry's UnifiedVenueID.venueId field — the id in the other organisation's namespace (an ALTA facility number, an ITA institution slug, a courthive-facilities facilityId).
Semantics:
- Upsert by
organisationId: if the venue already has an entry under the givenorganisationId, that entry'svenueId(and optionaluniqueOrganisationName) is replaced. Otherwise a new entry is appended withcreatedAt. - Idempotent: re-applying the same
(organisationId, otherVenueId)is a no-op; the array does not grow. - Organisation-agnostic: the factory neither validates nor interprets
organisationId. Callers choose what it means — a federation id, a canonical-registry id from a downstream service, anything stable within the consuming application. - Dispatches a
MODIFY_VENUEnotice.
Errors:
MISSING_VENUE_ID— standard parameter check.MISSING_VALUE— whenorganisationIdorotherVenueIdis empty.VENUE_NOT_FOUND— when no venue in the resolved records matchesvenueId.
Purpose: give a physical place one identity across providers. A venue entered independently in two tournaments — or held canonically by a facility registry — can be reconciled without the factory taking a position on whose id is authoritative.
deleteCourt
engine.deleteCourt({
courtId,
force, // override warnings about matchUps scheduled on specified court
});
A scheduling policy can allow the change without force: when force is not given, allowModificationWhenMatchUpsScheduled.courts in the applied scheduling policy decides. An explicit force (true or false) always wins; with neither, the call is refused. In 7.21.0 and earlier the flag was read under the wrong key and had no effect.
deleteCourts
Bulk delete multiple courts. If any court has scheduled matchUps, deletion will fail unless force: true, in which case all relevant matchUps will be unscheduled.
engine.deleteCourts({
courtIds: ['court-uuid-1', 'court-uuid-2'],
force, // override warnings about matchUps scheduled on specified courts
});
deleteVenue
If a venue has scheduled matchUps then it will not be deleted unless { force: true } in which case all relevant matchUps will be unscheduled.
A scheduling policy can allow the change without force: when force is not given, allowModificationWhenMatchUpsScheduled.venues in the applied scheduling policy decides. An explicit force (true or false) always wins; with neither, the call is refused. In 7.21.0 and earlier the flag was read under the wrong key and had no effect.
Deleting a primary venue does not auto-promote another venue — the caller must explicitly designate a new primary via modifyVenue.
Deleting a venue also removes every transit pair that names it (see setVenueTransit), in the record where it is deleted.
engine.deleteVenue({ venueId, force });
deleteVenues
If a venue has scheduled matchUps then it will not be deleted unless { force: true } in which case all relevant matchUps will be unscheduled. See examples: Modifying Venues.
engine.deleteVenues({ venueIds, force });
disableCourts
engine.disableCourts({
courtIds,
dates, // optional - if not provided, courts will be disabled for all dates
});
A court disabled for all dates stores disabled: true; one disabled on some dates stores disabled: { dates }. Both
are valid against the CODES schema (Disabled), and disableVenues stores disabled: true on a venue.
disableCourts, enableCourts, disableVenues and enableVenues send a modifyVenue notice for each venue
they changed, and none for a venue already in the requested state.
disableVenues
engine.disableVenues({ venueIds });
enableCourts
engine.enableCourts({
enableAll, // optional boolean
courtIds,
dates, // optional - array of dates to enable (if they have been disabled)
});
enableVenues
engine.enableVenues({ venueIds, enableAll });
findVenue
Returns a complete venue object. Primarily used internally.
const { venue } = engine.findVenue({ venueId });
Returns:
{
venue?: Venue;
error?: ErrorType;
}
generateCourts
Generates multiple courts with sequential naming for a venue. Convenience method for quickly creating courts during testing or initial setup.
const { courts } = engine.generateCourts({
venueId, // required - venue to add courts to
courtsCount: 10, // number of courts to generate
courtNames, // optional - array of custom court names
courtIds, // optional - array of specific courtIds to use
startTime: '08:00', // optional - court availability start
endTime: '20:00', // optional - court availability end
dateAvailability, // optional - full dateAvailability configurations
});
Returns:
{
courts: Court[]; // Array of generated court objects
success: boolean;
}
Notes:
- If
courtNamesnot provided, generates names like "Court 1", "Court 2", etc. - If
courtIdsnot provided, generates UUIDs automatically - Can specify default availability hours via
startTimeandendTime - For complex availability, use full
dateAvailabilityobjects - All courts added to specified venue
getCompetitionVenues
Returns all venues from all tournaments in competition engine state, with optional filtering.
const { venues, courts } = competitionEngine.getCompetitionVenues({
venueIds, // optional - filter to specific venue IDs
dates, // optional - filter courts by availability dates
ignoreDisabled, // optional - exclude disabled venues/courts
convertExtensions, // optional - convert extension objects to arrays
});
Returns:
{
venues: HydratedVenue[]; // Array of venues from all tournaments
courts: HydratedCourt[]; // Array of courts from all venues
}
Use Cases:
- Getting all venues across multi-tournament competition
- Cross-tournament venue scheduling
- Competition-wide court availability analysis
- Building unified venue selection UI
Notes:
- Aggregates venues from all tournament records in competition state
- Removes duplicate venues (same venueId across tournaments)
- Returns hydrated venues with computed properties
- Use
getVenuesAndCourts()for single-tournament queries
getCourts
Returns courts for a specific venue, with optional filtering and hydration. See examples: Retrieving Venue Information.
const { courts } = engine.getCourts({
venueId, // optional - specific venue (omit for all venues)
dates, // optional - filter by date availability
ignoreDisabled, // optional - exclude disabled courts
convertExtensions, // optional - convert extensions format
});
Returns:
{
courts: HydratedCourt[];
}
Hydrated Court Properties:
dateAvailability- Availability schedulescourtName- Display namecourtId- Unique identifier- Computed availability for specified dates
- Disability status
Use Cases:
- Building court selection dropdowns
- Checking court availability
- Getting schedulable courts for specific dates
- Court management interfaces
getVenueTransits
Returns the transit between venues as stored (venueTransits, the pairs each record states), the effective minutes by
direction (transitPairs: a symmetric pair both ways, a one-way pair one way; where linked records state one pair
differently, the greater), and the attached scheduling policy's default (defaultMinutes, absent when no policy states
one). See the scheduling pipeline, § 3.4.
const { venueTransits, transitPairs, defaultMinutes } = engine.getVenueTransits();
getVenuesAndCourts
Returns venues and courts from a tournament record or competition, with optional filtering and hydration.
const { venues, courts } = engine.getVenuesAndCourts({
venueIds, // optional - filter to specific venues
dates, // optional - filter by date
ignoreDisabled, // optional - exclude disabled items
convertExtensions, // optional - convert extension format
});
Returns:
{
venues: HydratedVenue[]; // Array of venue objects with computed properties
courts: HydratedCourt[]; // Array of court objects from all venues
}
Hydrated Venue Properties:
- All standard venue properties
courtsarray with court objects- Disability status from extensions
- Computed availability information
Examples:
// Get all venues and courts
const { venues, courts } = engine.getVenuesAndCourts();
// Get specific venues only
const { venues } = engine.getVenuesAndCourts({
venueIds: ['venue-1', 'venue-2'],
});
// Get courts available on specific dates
const { courts } = engine.getVenuesAndCourts({
dates: ['2024-03-20', '2024-03-21'],
ignoreDisabled: true,
});
// For competition engine (multi-tournament)
const { venues, courts } = competitionEngine.getVenuesAndCourts();
Use Cases:
- Building venue/court selection interfaces
- Scheduling UI data loading
- Availability analysis
- Venue management dashboards
Notes:
- Returns empty arrays if no venues exist
- Hydrated objects include computed properties not in raw data
- Use
ignoreDisabled: trueto exclude administratively disabled venues/courts - Date filtering applies to court availability schedules
modifyCourt
engine.modifyCourt({
courtId,
force, // applies only to dateAvailability, will remove scheduling information from matchUps where court is no longer available
modifications: {
courtName,
dateAvailability,
courtDimensions,
onlineResources,
surfaceCategory,
surfacedDate,
surfaceType,
altitude,
latitude,
longitude,
notes,
pace,
},
});. See examples: [Modifying Courts](../concepts/venues-courts.md#modifying-courts), [Modifying Courts](../concepts/venues-courts.md#modifying-courts).
modifyCourtAvailability
Modifies the dateAvailability attribute of a specified court. Warns if existing scheduled matchUps would be affected. See Scheduling.
const result = engine.modifyCourtAvailability({
dateAvailability,
courtId,
force, // override warning that existing scheduled matchUps exist
});
modifyVenue
Courts present on venue will replaced with courts specified in parameters. If courts are not present in parameters, courts will be unchanged. See examples: Modifying Venues.
See Scheduling for more detail on court dateAvailability and Venue-Level Scheduling Constraints for venue-level defaults.
const modifications = {
venueAbbreviation,
onlineResources,
venueName,
defaultStartTime, // optional - HH:MM format; validated with existing or modified defaultEndTime
defaultEndTime, // optional - HH:MM format; validated with existing or modified defaultStartTime
dateAvailability, // optional - venue-level date availability
isPrimary, // optional boolean - set or clear this venue as the tournament's primary venue
courts: [
{
courtId: 'b9df6177-e430-4a70-ba47-9b9ff60258cb',
courtName: 'Custom Court 1',
dateAvailability: [
{
date: '2020-01-01', // if no date is provided then `startTime` and `endTime` will be considered default values
startTime: '16:30',
endTime: '17:30',
},
],
},
],
};
engine.modifyVenue({ venueId, modifications });
A modification that removes a court with scheduled matchUps is refused unless force: true is passed or, when force is not given, the applied scheduling policy sets allowModificationWhenMatchUpsScheduled.venues. In 7.21.0 and earlier the flag was read under the wrong key and had no effect.
Notes:
- When modifying
defaultStartTimeordefaultEndTime, the engine validates the resulting pair (merging with existing values). For example, if the venue already hasdefaultStartTime: '09:00'and you modify onlydefaultEndTime, the pair('09:00', newEndTime)is validated. dateAvailabilityreplaces the entire venue-level availability array when provided- Setting
isPrimary: trueautomatically clearsisPrimaryfrom any previously-primary venue. SettingisPrimary: falseremoves the property entirely (clean serialization). See Primary Venue
removeVenueTransit
Removes the transit stated for a pair of venues, which then takes the scheduling policy's default. A pair with a sanctioned value cannot be removed.
engine.removeVenueTransit({ venueIds: [venueIdA, venueIdB], oneWay });
setVenueTransit
Sets the minutes to get between two venues: when a participant's consecutive matchUps on a date are at different venues,
the later may not start before the earlier's play ends plus the greater of its recovery and the transit. The pair is
stored once in tournamentRecord.scheduling.venueTransits, in either order; with oneWay: true it runs from
venueIds[0] to venueIds[1] only. Minutes are whole and non-negative. A pair carrying a sanctioned value is never set
below it. Venues sharing a facilityId need no transit; a pair with no stated minutes takes the policy's
defaultTimes.transitMinutes (30 in the default scheduling policy). See
the scheduling pipeline, § 3.4.
engine.setVenueTransit({ venueIds: [venueIdA, venueIdB], minutes: 45 });
engine.setVenueTransit({ venueIds: [venueIdB, venueIdA], minutes: 60, oneWay: true });
setVenueTransits
Sets many pairs at once, as a sanctioning import or a venues page would: each entry is
{ venueIds, minutes, oneWay?, sanctioned? }, validated as in setVenueTransit. A sanctioned value is kept beside the
minutes in effect and is a floor for them. With replace: true, pairs not given are removed, except sanctioned ones.
engine.setVenueTransits({
venueTransits: [{ venueIds: [venueIdA, venueIdB], minutes: 45, sanctioned: { minutes: 40, sanctioningId } }],
replace: false,
});