Skip to main content

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:

  • defaultStartTime and defaultEndTime must be provided together — setting only one returns an error
  • defaultEndTime must be after defaultStartTime
  • These defaults are inherited by all courts in the venue. See Venue-Level Scheduling Constraints
  • Setting isPrimary: true automatically clears isPrimary from any previously-primary venue (at most one venue can be primary). See Primary Venue. The venue that loses the flag is announced with a modifyVenue notice (as with modifyVenue)

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 given organisationId, that entry's venueId (and optional uniqueOrganisationName) is replaced. Otherwise a new entry is appended with createdAt.
  • 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_VENUE notice.

Errors:

  • MISSING_VENUE_ID — standard parameter check.
  • MISSING_VALUE — when organisationId or otherVenueId is empty.
  • VENUE_NOT_FOUND — when no venue in the resolved records matches venueId.

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 courtNames not provided, generates names like "Court 1", "Court 2", etc.
  • If courtIds not provided, generates UUIDs automatically
  • Can specify default availability hours via startTime and endTime
  • For complex availability, use full dateAvailability objects
  • 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 schedules
  • courtName - Display name
  • courtId - 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
  • courts array 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: true to 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 defaultStartTime or defaultEndTime, the engine validates the resulting pair (merging with existing values). For example, if the venue already has defaultStartTime: '09:00' and you modify only defaultEndTime, the pair ('09:00', newEndTime) is validated.
  • dateAvailability replaces the entire venue-level availability array when provided
  • Setting isPrimary: true automatically clears isPrimary from any previously-primary venue. Setting isPrimary: false removes 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,
});