MatchUps Overview
Overview
MatchUps are the fundamental competitive units in TODS, representing individual contests between participants. A matchUp can be a singles match, doubles match, or team match, and contains all information about the competition: participants, scores, schedule, officials, and outcome.
Key Concepts
Match Types: SINGLES, DOUBLES, TEAM
Match Status: TO_BE_PLAYED, IN_PROGRESS, COMPLETED, WALKOVER, DEFAULTED, etc.
Sides: The two competing participants (side1 and side2)
Position Assignments: How participants are placed in matchUps
Hydration: Adding contextual information from draw/event/tournament
Collection MatchUps: Individual matches within TEAM matchUps
MatchUp Types
SINGLES
A matchUp between two INDIVIDUAL participants:
type SinglesMatchUp = {
matchUpId: string;
matchUpType: 'SINGLES';
matchUpFormat: string; // e.g., 'SET3-S:6/TB7'
matchUpStatus: MatchUpStatus;
sides: [
{
sideNumber: 1,
participantId: string, // INDIVIDUAL participant
participant?: Participant
},
{
sideNumber: 2,
participantId: string,
participant?: Participant
}
];
score?: Score;
winningSide?: 1 | 2;
// ... additional attributes
};
DOUBLES
A matchUp between two PAIR participants:
type DoublesMatchUp = {
matchUpId: string;
matchUpType: 'DOUBLES';
matchUpFormat: string;
matchUpStatus: MatchUpStatus;
sides: [
{
sideNumber: 1,
participantId: string, // PAIR participant
participant?: PairParticipant
},
{
sideNumber: 2,
participantId: string,
participant?: PairParticipant
}
];
score?: Score;
winningSide?: 1 | 2;
};
TEAM
A matchUp between two TEAM participants, containing multiple collection matchUps:
type TeamMatchUp = {
matchUpId: string;
matchUpType: 'TEAM';
matchUpStatus: MatchUpStatus;
tieFormat: TieFormat; // Defines structure of team match
sides: [
{
sideNumber: 1,
participantId: string, // TEAM participant
lineUp?: IndividualParticipant[]
},
{
sideNumber: 2,
participantId: string,
lineUp?: IndividualParticipant[]
}
];
tieMatchUps?: CollectionMatchUp[]; // Individual matches within team match
score?: TeamScore;
winningSide?: 1 | 2;
};
See: Tie Format and Tie MatchUp for team match details.
MatchUp Status
MatchUps progress through various states:
Pre-Match Statuses
- TO_BE_PLAYED - Match is scheduled but not started
- BYE - One participant received a bye
- WALKOVER - Opponent did not appear
- DEFAULTED - Participant disqualified before starting
During Match
- IN_PROGRESS - Match currently being played
- SUSPENDED - Match temporarily halted
- INTERRUPTED - Match paused (rain delay, etc.)
Post-Match
- COMPLETED - Match finished with score
- RETIRED - Participant withdrew during match
- ABANDONED - Match canceled/voided
- CANCELLED - Match will not be played
- DEAD_RUBBER - Match outcome irrelevant to progression
Example Usage
const { matchUps } = tournamentEngine.allTournamentMatchUps({
matchUpFilters: {
matchUpStatuses: ['COMPLETED', 'RETIRED', 'DEFAULTED']
}
});
console.log(`${matchUps.length} finished matches`);
Retrieving MatchUps
Tournament-Wide
Get all matchUps across entire tournament:
const { matchUps } = tournamentEngine.allTournamentMatchUps({
inContext: true, // Add tournament/event/draw context (default)
nextMatchUps: true // Include winnerTo/loserTo information
});
// MatchUps are automatically returned with context
matchUps.forEach(matchUp => {
console.log(`${matchUp.tournamentName} - ${matchUp.eventName}`);
console.log(` ${matchUp.drawName} - Round ${matchUp.roundNumber}`);
});
Event-Specific
Get matchUps for a specific event:
const { matchUps } = tournamentEngine.allEventMatchUps({
eventId: 'singles-main',
inContext: true
});
Draw-Specific
Get matchUps from a specific draw:
const { matchUps } = tournamentEngine.allDrawMatchUps({
drawId: 'draw-123',
inContext: true
});
With Filters
Filter matchUps by various criteria:
const { matchUps } = tournamentEngine.allTournamentMatchUps({
matchUpFilters: {
matchUpStatuses: ['COMPLETED'],
matchUpTypes: ['SINGLES', 'DOUBLES'],
roundNumbers: [1, 2],
hasWinningSide: true
},
contextFilters: {
scheduledDate: '2024-06-15',
venueIds: ['venue-123'],
courtIds: ['court-1', 'court-2']
}
});
See: MatchUp Filtering for comprehensive filtering options.
MatchUp Sides
Each matchUp has two sides representing the competing participants:
{
matchUpId: 'match-123',
sides: [
{
sideNumber: 1,
participantId: 'player-1',
participant: { // Added when inContext: true
participantType: 'INDIVIDUAL',
person: { standardFamilyName: 'Federer' }
}
},
{
sideNumber: 2,
participantId: 'player-2',
participant: {
participantType: 'INDIVIDUAL',
person: { standardFamilyName: 'Nadal' }
}
}
]
}
Winning Side
After completion, winningSide indicates the victor:
if (matchUp.matchUpStatus === 'COMPLETED') {
const winner = matchUp.sides.find(s => s.sideNumber === matchUp.winningSide);
const loser = matchUp.sides.find(s => s.sideNumber !== matchUp.winningSide);
console.log(`Winner: ${winner.participant.person.standardFamilyName}`);
}
Scores
MatchUp scores follow TODS score structure:
{
matchUpId: 'match-123',
score: {
sets: [
{
setNumber: 1,
side1Score: 6,
side2Score: 4,
winningSide: 1
},
{
setNumber: 2,
side1Score: 7,
side2Score: 6,
side1TiebreakScore: 7,
side2TiebreakScore: 5,
winningSide: 1
}
],
scoreStringSide1: '6-4 7-6(7)',
scoreStringSide2: '4-6 6-7(5)'
},
winningSide: 1
}
Setting Scores
tournamentEngine.setMatchUpStatus({
matchUpId: 'match-123',
drawId: 'draw-456',
outcome: {
score: {
sets: [
{ side1Score: 6, side2Score: 4, winningSide: 1 },
{ side1Score: 6, side2Score: 3, winningSide: 1 }
]
},
winningSide: 1
}
});
Scheduling Information
MatchUps include comprehensive scheduling details:
{
matchUpId: 'match-123',
schedule: {
scheduledDate: '2024-06-15',
scheduledTime: '14:00',
venueId: 'venue-123',
courtId: 'court-5',
courtName: 'Court 5',
startTime: '2024-06-15T14:05:00Z',
endTime: '2024-06-15T15:45:00Z'
},
// Additional context when inContext: true
venueName: 'Stadium',
courtOrder: 2 // Order of play on this court
}
Scheduling MatchUps
tournamentEngine.addMatchUpScheduleItems({
matchUpId: 'match-123',
drawId: 'draw-456',
schedule: {
scheduledDate: '2024-06-15',
scheduledTime: '14:00',
venueId: 'venue-123',
courtId: 'court-5'
}
});
See: Scheduling Overview for detailed scheduling workflows.
Officials and Check-In
Assigning Officials
// Assign referee
tournamentEngine.addMatchUpOfficial({
matchUpId: 'match-123',
drawId: 'draw-456',
participantId: 'official-789',
officialType: 'REFEREE'
});
Participant Check-In
Track participant availability:
// Check in participants
tournamentEngine.checkInParticipant({
matchUpId: 'match-123',
participantId: 'player-1'
});
// Both participants checked in?
if (matchUp.sides.every(side => side.checkInState === 'CHECKED_IN')) {
console.log('Match ready to start');
}
Next MatchUps (Winner/Loser Progression)
When nextMatchUps: true, each matchUp includes progression information:
const { matchUps } = tournamentEngine.allDrawMatchUps({
drawId: 'draw-123',
nextMatchUps: true
});
matchUps.forEach(matchUp => {
if (matchUp.winnerTo) {
console.log(`Winner advances to matchUp ${matchUp.winnerTo.matchUpId}`);
console.log(` Round ${matchUp.winnerTo.roundNumber}`);
}
if (matchUp.loserTo) {
console.log(`Loser feeds to matchUp ${matchUp.loserTo.matchUpId}`);
console.log(` Consolation Round ${matchUp.loserTo.roundNumber}`);
}
});
Collection MatchUps (TEAM Matches)
TEAM matchUps contain collection matchUps (individual matches):
const teamMatchUp = {
matchUpId: 'team-match-123',
matchUpType: 'TEAM',
tieMatchUps: [
{
matchUpId: 'singles-1',
matchUpType: 'SINGLES',
collectionId: 'singles-collection',
collectionPosition: 1
},
{
matchUpId: 'singles-2',
matchUpType: 'SINGLES',
collectionId: 'singles-collection',
collectionPosition: 2
},
{
matchUpId: 'doubles-1',
matchUpType: 'DOUBLES',
collectionId: 'doubles-collection',
collectionPosition: 1
}
]
};
// Access individual matches
teamMatchUp.tieMatchUps.forEach(tieMatchUp => {
console.log(`${tieMatchUp.matchUpType} Match ${tieMatchUp.collectionPosition}`);
});
MatchUp Actions
Get available actions for a matchUp:
const { validActions } = tournamentEngine.matchUpActions({
matchUpId: 'match-123',
drawId: 'draw-456'
});
validActions.forEach(action => {
console.log(`Available: ${action.type}`);
// - SCORE: Can enter score
// - SCHEDULE: Can set schedule
// - ASSIGN_OFFICIAL: Can assign referee
// - etc.
});
See: Actions for complete action documentation.
Common Use Cases
Display Order of Play
const { matchUps } = tournamentEngine.allTournamentMatchUps({
contextFilters: {
scheduledDate: '2024-06-15',
venueIds: ['main-stadium']
},
matchUpFilters: {
matchUpStatuses: ['TO_BE_PLAYED', 'IN_PROGRESS']
}
});
// Group by court
const byCourt = matchUps.reduce((acc, matchUp) => {
const courtId = matchUp.schedule?.courtId || 'unscheduled';
if (!acc[courtId]) acc[courtId] = [];
acc[courtId].push(matchUp);
return acc;
}, {});
// Display
Object.entries(byCourt).forEach(([courtId, matches]) => {
console.log(`\n${matches[0]?.courtName || 'Unscheduled'}:`);
matches.forEach(m => {
console.log(` ${m.schedule.scheduledTime} - ${m.roundName}`);
});
});
Results Feed
const { matchUps } = tournamentEngine.allTournamentMatchUps({
matchUpFilters: {
matchUpStatuses: ['COMPLETED']
}
});
// Sort by completion time
matchUps
.sort((a, b) =>
new Date(b.schedule?.endTime || 0) - new Date(a.schedule?.endTime || 0)
)
.slice(0, 10) // Latest 10 results
.forEach(matchUp => {
const winner = matchUp.sides.find(s => s.sideNumber === matchUp.winningSide);
const loser = matchUp.sides.find(s => s.sideNumber !== matchUp.winningSide);
console.log(`${winner.participant.person.standardFamilyName} d. ${loser.participant.person.standardFamilyName}`);
console.log(` ${matchUp.score.scoreStringSide1}`);
});
Live Matches
const { matchUps } = tournamentEngine.allTournamentMatchUps({
matchUpFilters: {
matchUpStatuses: ['IN_PROGRESS']
}
});
console.log(`${matchUps.length} matches in progress`);
matchUps.forEach(matchUp => {
console.log(`${matchUp.courtName}: ${matchUp.roundName}`);
matchUp.sides.forEach(side => {
console.log(` ${side.participant.person.standardFamilyName}`);
});
});
Related Documentation
- MatchUp Context - Understanding hydration and contextual data
- MatchUp Filtering - Comprehensive filtering options
- Actions - Available matchUp actions
- Tie Format - Team match structure
- Scheduling Overview - Match scheduling workflows
- Query Governor - Complete API reference