@ttt-productions/q-core 0.1.61 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,6 +33,8 @@ export declare const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;
33
33
  export declare const MAX_APP_VERSION_LENGTH = 64;
34
34
  export declare const MAX_LANDING_HERO_TITLE_LENGTH = 200;
35
35
  export declare const MAX_LANDING_ABOUT_TEXT_LENGTH = 5000;
36
+ export declare const LANDING_OWNER_NAME = "Q-Sports League";
37
+ export declare const HERO_ROTATION_INTERVAL_MS = 6000;
36
38
  export declare const MAX_WAIVER_TEMPLATE_TITLE_LENGTH = 120;
37
39
  export declare const MAX_WAIVER_TEMPLATE_TEXT_LENGTH = 20000;
38
40
  export declare const MAX_GAME_LOCATION_NAME_LENGTH = 100;
@@ -47,12 +49,10 @@ export declare const countCapReachedMessage: (subject: string, limit: number, no
47
49
  export declare const MAX_ACTIVE_TEAM_MEMBERS = 30;
48
50
  export declare const TEAM_FULL_MESSAGE: string;
49
51
  export declare const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = 30;
50
- export declare const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 10;
51
- export declare const MAX_ROSTER_ENTRIES_PER_TEAM: number;
52
+ export declare const MAX_ROSTER_ENTRIES_PER_TEAM = 30;
52
53
  export declare const gameRosterBound: (teamIds: readonly string[]) => number;
53
54
  export declare const scheduledGameLabel: (weekTitle: string, dayKey: string) => string;
54
55
  export declare const gameSideFullMessage: (gameLabel: string) => string;
55
- export declare const gameSideDepartedFullMessage: (gameLabel: string) => string;
56
56
  export declare const GAME_COMPLETED_DELETE_MESSAGE = "This game is completed, so it cannot be deleted.";
57
57
  export declare const WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD = "This week has completed games, which cannot be deleted:";
58
58
  export declare const weekHasCompletedGamesDeleteMessage: (games: readonly string[]) => string;
@@ -76,8 +76,8 @@ export declare const CAPACITY_LIMITS: readonly [{
76
76
  readonly limit: 30;
77
77
  }, {
78
78
  readonly key: "gameSidePeople";
79
- readonly label: "People on one side of one game: 30 players plus 10 who left the team after recording stats in it";
80
- readonly limit: number;
79
+ readonly label: "People on one side of one game";
80
+ readonly limit: 30;
81
81
  }, {
82
82
  readonly key: "leagueTeams";
83
83
  readonly label: "Teams in a league";
@@ -1 +1 @@
1
- {"version":3,"file":"business.d.ts","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAGrC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,oCAAoC,MAAM,CAAC;AACxD,eAAO,MAAM,kCAAkC,MAAM,CAAC;AAEtD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAClD,eAAO,MAAM,gBAAgB;;;;;;EAGnB,CAAC;AACX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5E,eAAO,MAAM,yBAAyB,EAA8C,CAClF,qBAAqB,EACrB,GAAG,qBAAqB,EAAE,CAC3B,CAAC;AAEF,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,+BAA+B,QAAQ,CAAC;AAErD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,uCAAuC,MAAM,CAAC;AAC3D,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAClD,eAAO,MAAM,qCAAqC,KAAK,CAAC;AACxD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AAEnD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,EAAE,OAAO,MAAM,EAAE,MAAM,MAAM,KAAG,MAC3B,CAAC;AAE5D,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,iBAAiB,QAI7B,CAAC;AACF,eAAO,MAAM,oCAAoC,KAA0B,CAAC;AAC5E,eAAO,MAAM,oCAAoC,KAAK,CAAC;AACvD,eAAO,MAAM,2BAA2B,QACwB,CAAC;AACjE,eAAO,MAAM,eAAe,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,MACf,CAAC;AAC/C,eAAO,MAAM,kBAAkB,GAAI,WAAW,MAAM,EAAE,QAAQ,MAAM,KAAG,MACjC,CAAC;AACvC,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,KAAG,MACsC,CAAC;AAC/F,eAAO,MAAM,2BAA2B,GAAI,WAAW,MAAM,KAAG,MAC6I,CAAC;AAC9M,eAAO,MAAM,6BAA6B,qDAAqD,CAAC;AAChG,eAAO,MAAM,oCAAoC,4DACU,CAAC;AAC5D,eAAO,MAAM,kCAAkC,GAAI,OAAO,SAAS,MAAM,EAAE,KAAG,MACd,CAAC;AAEjE,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,yBAAyB,QAIrC,CAAC;AACF,eAAO,MAAM,yBAAyB,QAIrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,0BAA0B,QAItC,CAAC;AAEF,eAAO,MAAM,kBAAkB,KAAuB,CAAC;AAEvD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,0BAA0B,QAItC,CAAC;AAEF,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,2BAA2B,QAIvC,CAAC;AAEF,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,6BAA6B,QAIzC,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCiD,CAAC;AAC9E,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"business.d.ts","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,8 @@ export const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;
31
31
  export const MAX_APP_VERSION_LENGTH = 64;
32
32
  export const MAX_LANDING_HERO_TITLE_LENGTH = 200;
33
33
  export const MAX_LANDING_ABOUT_TEXT_LENGTH = 5000;
34
+ export const LANDING_OWNER_NAME = 'Q-Sports League';
35
+ export const HERO_ROTATION_INTERVAL_MS = 6000;
34
36
  export const MAX_WAIVER_TEMPLATE_TITLE_LENGTH = 120;
35
37
  export const MAX_WAIVER_TEMPLATE_TEXT_LENGTH = 20000;
36
38
  export const MAX_GAME_LOCATION_NAME_LENGTH = 100;
@@ -45,12 +47,10 @@ export const countCapReachedMessage = (subject, limit, noun) => `${subject} alre
45
47
  export const MAX_ACTIVE_TEAM_MEMBERS = 30;
46
48
  export const TEAM_FULL_MESSAGE = countCapReachedMessage('This team', MAX_ACTIVE_TEAM_MEMBERS, 'players');
47
49
  export const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;
48
- export const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 10;
49
- export const MAX_ROSTER_ENTRIES_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS + MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM;
50
+ export const MAX_ROSTER_ENTRIES_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;
50
51
  export const gameRosterBound = (teamIds) => MAX_ROSTER_ENTRIES_PER_TEAM * teamIds.length;
51
52
  export const scheduledGameLabel = (weekTitle, dayKey) => `The ${weekTitle} game on ${dayKey}`;
52
53
  export const gameSideFullMessage = (gameLabel) => countCapReachedMessage(gameLabel, MAX_ROSTER_ENTRIES_PER_TEAM, "people on this team's side");
53
- export const gameSideDepartedFullMessage = (gameLabel) => `${gameLabel} already keeps the ${MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM} players a side may hold after they leave the team with stats in it. Finalize that game, or take this player's stats off it, first.`;
54
54
  export const GAME_COMPLETED_DELETE_MESSAGE = 'This game is completed, so it cannot be deleted.';
55
55
  export const WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD = 'This week has completed games, which cannot be deleted:';
56
56
  export const weekHasCompletedGamesDeleteMessage = (games) => `${WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD} ${games.join('; ')}.`;
@@ -76,7 +76,7 @@ export const CAPACITY_LIMITS = [
76
76
  },
77
77
  {
78
78
  key: 'gameSidePeople',
79
- label: `People on one side of one game: ${MAX_ACTIVE_TEAM_MEMBERS} players plus ${MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM} who left the team after recording stats in it`,
79
+ label: 'People on one side of one game',
80
80
  limit: MAX_ROSTER_ENTRIES_PER_TEAM,
81
81
  },
82
82
  { key: 'leagueTeams', label: 'Teams in a league', limit: MAX_TEAMS_PER_LEAGUE },
@@ -1 +1 @@
1
- {"version":3,"file":"business.js","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"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","sourcesContent":["export const MIN_DISPLAY_NAME_LENGTH = 3;\nexport const MAX_DISPLAY_NAME_LENGTH = 50;\n// The shortest password an account takes: Firebase Auth's own floor.\nexport const PASSWORD_MIN_LENGTH = 6;\n\n// The RFC 5321 ceiling on an email address.\nexport const EMAIL_MAX_LENGTH = 320;\n\nexport const MAX_SEARCH_QUERY_LENGTH = 100;\nexport const MIN_TEAM_NAME_LENGTH = 3;\nexport const MAX_TEAM_NAME_LENGTH = 50;\n\nexport const MAX_TEAM_JOIN_REQUEST_MESSAGE_LENGTH = 500;\nexport const MAX_TEAM_INVITATION_MESSAGE_LENGTH = 500;\n\nexport const MIN_LEAGUE_TITLE_LENGTH = 3;\nexport const MAX_LEAGUE_TITLE_LENGTH = 100;\nexport const MIN_LEAGUE_DESCRIPTION_LENGTH = 10;\nexport const MAX_LEAGUE_DESCRIPTION_LENGTH = 5000;\nexport const HARDWARE_CATALOG = [\n { id: 'ipad', name: 'iPad' },\n { id: 'ipad-charger', name: 'iPad Charger' },\n] as const;\nexport type HardwareCatalogItemId = (typeof HARDWARE_CATALOG)[number]['id'];\nexport const HARDWARE_CATALOG_ITEM_IDS = HARDWARE_CATALOG.map((item) => item.id) as [\n HardwareCatalogItemId,\n ...HardwareCatalogItemId[],\n];\n\nexport const MIN_AWARD_NAME_LENGTH = 3;\nexport const MAX_AWARD_NAME_LENGTH = 60;\n\nexport const MAX_AWARD_GRANT_TARGETS = 20;\n\nexport const MIN_REPAIR_REASON_LENGTH = 3;\nexport const MAX_REPAIR_REASON_LENGTH = 500;\n\nexport const MAX_ADMIN_LIST_CHANGES = 20;\n\nexport const TEAM_CREATION_CUTOFF_DAYS = 14;\n\nexport const MAX_CONTACT_PHONE_LENGTH = 30;\n\nexport const MAX_MAINTENANCE_MESSAGE_LENGTH = 2000;\nexport const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;\nexport const MAX_APP_VERSION_LENGTH = 64;\n\nexport const MAX_LANDING_HERO_TITLE_LENGTH = 200;\nexport const MAX_LANDING_ABOUT_TEXT_LENGTH = 5000;\n\nexport const MAX_WAIVER_TEMPLATE_TITLE_LENGTH = 120;\nexport const MAX_WAIVER_TEMPLATE_TEXT_LENGTH = 20000;\n\nexport const MAX_GAME_LOCATION_NAME_LENGTH = 100;\nexport const MAX_GAME_LOCATION_STREET_ADDRESS_LENGTH = 200;\nexport const MAX_GAME_LOCATION_SUB_LOCATIONS = 50;\nexport const MAX_GAME_LOCATION_SUB_LOCATION_LENGTH = 60;\nexport const MAX_GAME_LOCATION_MEMO_LENGTH = 500;\n\nexport const MAX_SCHEDULE_WEEK_TITLE_LENGTH = 100;\n\nexport const LEAGUE_TIME_ZONE = 'America/New_York';\n\nexport const MAX_GAME_MEMO_LENGTH = 30;\n\nexport const countCapReachedMessage = (subject: string, limit: number, noun: string): string =>\n `${subject} already has the maximum of ${limit} ${noun}.`;\n\nexport const MAX_ACTIVE_TEAM_MEMBERS = 30;\nexport const TEAM_FULL_MESSAGE = countCapReachedMessage(\n 'This team',\n MAX_ACTIVE_TEAM_MEMBERS,\n 'players',\n);\nexport const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;\nexport const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 10;\nexport const MAX_ROSTER_ENTRIES_PER_TEAM =\n MAX_ACTIVE_TEAM_MEMBERS + MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM;\nexport const gameRosterBound = (teamIds: readonly string[]): number =>\n MAX_ROSTER_ENTRIES_PER_TEAM * teamIds.length;\nexport const scheduledGameLabel = (weekTitle: string, dayKey: string): string =>\n `The ${weekTitle} game on ${dayKey}`;\nexport const gameSideFullMessage = (gameLabel: string): string =>\n countCapReachedMessage(gameLabel, MAX_ROSTER_ENTRIES_PER_TEAM, \"people on this team's side\");\nexport const gameSideDepartedFullMessage = (gameLabel: string): string =>\n `${gameLabel} already keeps the ${MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM} players a side may hold after they leave the team with stats in it. Finalize that game, or take this player's stats off it, first.`;\nexport const GAME_COMPLETED_DELETE_MESSAGE = 'This game is completed, so it cannot be deleted.';\nexport const WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD =\n 'This week has completed games, which cannot be deleted:';\nexport const weekHasCompletedGamesDeleteMessage = (games: readonly string[]): string =>\n `${WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD} ${games.join('; ')}.`;\n\nexport const MAX_TEAMS_PER_GAME = 2;\nexport const MAX_TEAMS_PER_LEAGUE = 40;\nexport const MAX_GAMES_PER_LEAGUE = 250;\nexport const LEAGUE_TEAMS_FULL_MESSAGE = countCapReachedMessage(\n 'This league',\n MAX_TEAMS_PER_LEAGUE,\n 'teams',\n);\nexport const LEAGUE_GAMES_FULL_MESSAGE = countCapReachedMessage(\n 'This league',\n MAX_GAMES_PER_LEAGUE,\n 'games',\n);\n\nexport const MAX_SCHEDULE_WEEK_GAMES = 20;\nexport const SCHEDULE_WEEK_FULL_MESSAGE = countCapReachedMessage(\n 'This week',\n MAX_SCHEDULE_WEEK_GAMES,\n 'games',\n);\n\nexport const MAX_PLAYOFF_CUTOFF = MAX_TEAMS_PER_LEAGUE;\n\nexport const MAX_STAT_EVENTS_PER_GAME = 1000;\nexport const GAME_STAT_LOG_FULL_MESSAGE = countCapReachedMessage(\n 'This game',\n MAX_STAT_EVENTS_PER_GAME,\n 'recorded stats',\n);\n\nexport const MAX_GAME_LOCATIONS = 30;\nexport const GAME_LOCATIONS_FULL_MESSAGE = countCapReachedMessage(\n 'Q-Sports',\n MAX_GAME_LOCATIONS,\n 'locations',\n);\n\nexport const MAX_OFFERED_WAIVER_TEMPLATES = 30;\nexport const WAIVER_TEMPLATES_FULL_MESSAGE = countCapReachedMessage(\n 'Q-Sports',\n MAX_OFFERED_WAIVER_TEMPLATES,\n 'waiver templates offered to leagues',\n);\n\nexport const CAPACITY_LIMITS = [\n {\n key: 'teamPlayers',\n label: 'Players on a team, ghost players included',\n limit: MAX_ACTIVE_TEAM_MEMBERS,\n },\n {\n key: 'gameSidePeople',\n label: `People on one side of one game: ${MAX_ACTIVE_TEAM_MEMBERS} players plus ${MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM} who left the team after recording stats in it`,\n limit: MAX_ROSTER_ENTRIES_PER_TEAM,\n },\n { key: 'leagueTeams', label: 'Teams in a league', limit: MAX_TEAMS_PER_LEAGUE },\n {\n key: 'leagueGames',\n label: \"Games in a league, so also a team's games\",\n limit: MAX_GAMES_PER_LEAGUE,\n },\n { key: 'weekGames', label: 'Games in one week of the schedule', limit: MAX_SCHEDULE_WEEK_GAMES },\n { key: 'gameStats', label: 'Stats recorded in one game', limit: MAX_STAT_EVENTS_PER_GAME },\n {\n key: 'playoffCutoff',\n label: \"Teams reaching the playoffs, at most the league's team limit\",\n limit: MAX_PLAYOFF_CUTOFF,\n },\n {\n key: 'gameLocations',\n label: \"Game locations, each venue's courts or sheets counted as part of it\",\n limit: MAX_GAME_LOCATIONS,\n },\n {\n key: 'offeredWaiverTemplates',\n label: 'Waiver templates offered to leagues, retired ones not counted',\n limit: MAX_OFFERED_WAIVER_TEMPLATES,\n },\n] as const satisfies readonly { key: string; label: string; limit: number }[];\nexport type CapacityLimitKey = (typeof CAPACITY_LIMITS)[number]['key'];\n"]}
1
+ {"version":3,"file":"business.js","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"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","sourcesContent":["export const MIN_DISPLAY_NAME_LENGTH = 3;\nexport const MAX_DISPLAY_NAME_LENGTH = 50;\n// The shortest password an account takes: Firebase Auth's own floor.\nexport const PASSWORD_MIN_LENGTH = 6;\n\n// The RFC 5321 ceiling on an email address.\nexport const EMAIL_MAX_LENGTH = 320;\n\nexport const MAX_SEARCH_QUERY_LENGTH = 100;\nexport const MIN_TEAM_NAME_LENGTH = 3;\nexport const MAX_TEAM_NAME_LENGTH = 50;\n\nexport const MAX_TEAM_JOIN_REQUEST_MESSAGE_LENGTH = 500;\nexport const MAX_TEAM_INVITATION_MESSAGE_LENGTH = 500;\n\nexport const MIN_LEAGUE_TITLE_LENGTH = 3;\nexport const MAX_LEAGUE_TITLE_LENGTH = 100;\nexport const MIN_LEAGUE_DESCRIPTION_LENGTH = 10;\nexport const MAX_LEAGUE_DESCRIPTION_LENGTH = 5000;\nexport const HARDWARE_CATALOG = [\n { id: 'ipad', name: 'iPad' },\n { id: 'ipad-charger', name: 'iPad Charger' },\n] as const;\nexport type HardwareCatalogItemId = (typeof HARDWARE_CATALOG)[number]['id'];\nexport const HARDWARE_CATALOG_ITEM_IDS = HARDWARE_CATALOG.map((item) => item.id) as [\n HardwareCatalogItemId,\n ...HardwareCatalogItemId[],\n];\n\nexport const MIN_AWARD_NAME_LENGTH = 3;\nexport const MAX_AWARD_NAME_LENGTH = 60;\n\nexport const MAX_AWARD_GRANT_TARGETS = 20;\n\nexport const MIN_REPAIR_REASON_LENGTH = 3;\nexport const MAX_REPAIR_REASON_LENGTH = 500;\n\nexport const MAX_ADMIN_LIST_CHANGES = 20;\n\nexport const TEAM_CREATION_CUTOFF_DAYS = 14;\n\nexport const MAX_CONTACT_PHONE_LENGTH = 30;\n\nexport const MAX_MAINTENANCE_MESSAGE_LENGTH = 2000;\nexport const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;\nexport const MAX_APP_VERSION_LENGTH = 64;\n\nexport const MAX_LANDING_HERO_TITLE_LENGTH = 200;\nexport const MAX_LANDING_ABOUT_TEXT_LENGTH = 5000;\nexport const LANDING_OWNER_NAME = 'Q-Sports League';\nexport const HERO_ROTATION_INTERVAL_MS = 6000;\n\nexport const MAX_WAIVER_TEMPLATE_TITLE_LENGTH = 120;\nexport const MAX_WAIVER_TEMPLATE_TEXT_LENGTH = 20000;\n\nexport const MAX_GAME_LOCATION_NAME_LENGTH = 100;\nexport const MAX_GAME_LOCATION_STREET_ADDRESS_LENGTH = 200;\nexport const MAX_GAME_LOCATION_SUB_LOCATIONS = 50;\nexport const MAX_GAME_LOCATION_SUB_LOCATION_LENGTH = 60;\nexport const MAX_GAME_LOCATION_MEMO_LENGTH = 500;\n\nexport const MAX_SCHEDULE_WEEK_TITLE_LENGTH = 100;\n\nexport const LEAGUE_TIME_ZONE = 'America/New_York';\n\nexport const MAX_GAME_MEMO_LENGTH = 30;\n\nexport const countCapReachedMessage = (subject: string, limit: number, noun: string): string =>\n `${subject} already has the maximum of ${limit} ${noun}.`;\n\nexport const MAX_ACTIVE_TEAM_MEMBERS = 30;\nexport const TEAM_FULL_MESSAGE = countCapReachedMessage(\n 'This team',\n MAX_ACTIVE_TEAM_MEMBERS,\n 'players',\n);\nexport const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;\nexport const MAX_ROSTER_ENTRIES_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;\nexport const gameRosterBound = (teamIds: readonly string[]): number =>\n MAX_ROSTER_ENTRIES_PER_TEAM * teamIds.length;\nexport const scheduledGameLabel = (weekTitle: string, dayKey: string): string =>\n `The ${weekTitle} game on ${dayKey}`;\nexport const gameSideFullMessage = (gameLabel: string): string =>\n countCapReachedMessage(gameLabel, MAX_ROSTER_ENTRIES_PER_TEAM, \"people on this team's side\");\nexport const GAME_COMPLETED_DELETE_MESSAGE = 'This game is completed, so it cannot be deleted.';\nexport const WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD =\n 'This week has completed games, which cannot be deleted:';\nexport const weekHasCompletedGamesDeleteMessage = (games: readonly string[]): string =>\n `${WEEK_HAS_COMPLETED_GAMES_DELETE_LEAD} ${games.join('; ')}.`;\n\nexport const MAX_TEAMS_PER_GAME = 2;\nexport const MAX_TEAMS_PER_LEAGUE = 40;\nexport const MAX_GAMES_PER_LEAGUE = 250;\nexport const LEAGUE_TEAMS_FULL_MESSAGE = countCapReachedMessage(\n 'This league',\n MAX_TEAMS_PER_LEAGUE,\n 'teams',\n);\nexport const LEAGUE_GAMES_FULL_MESSAGE = countCapReachedMessage(\n 'This league',\n MAX_GAMES_PER_LEAGUE,\n 'games',\n);\n\nexport const MAX_SCHEDULE_WEEK_GAMES = 20;\nexport const SCHEDULE_WEEK_FULL_MESSAGE = countCapReachedMessage(\n 'This week',\n MAX_SCHEDULE_WEEK_GAMES,\n 'games',\n);\n\nexport const MAX_PLAYOFF_CUTOFF = MAX_TEAMS_PER_LEAGUE;\n\nexport const MAX_STAT_EVENTS_PER_GAME = 1000;\nexport const GAME_STAT_LOG_FULL_MESSAGE = countCapReachedMessage(\n 'This game',\n MAX_STAT_EVENTS_PER_GAME,\n 'recorded stats',\n);\n\nexport const MAX_GAME_LOCATIONS = 30;\nexport const GAME_LOCATIONS_FULL_MESSAGE = countCapReachedMessage(\n 'Q-Sports',\n MAX_GAME_LOCATIONS,\n 'locations',\n);\n\nexport const MAX_OFFERED_WAIVER_TEMPLATES = 30;\nexport const WAIVER_TEMPLATES_FULL_MESSAGE = countCapReachedMessage(\n 'Q-Sports',\n MAX_OFFERED_WAIVER_TEMPLATES,\n 'waiver templates offered to leagues',\n);\n\nexport const CAPACITY_LIMITS = [\n {\n key: 'teamPlayers',\n label: 'Players on a team, ghost players included',\n limit: MAX_ACTIVE_TEAM_MEMBERS,\n },\n {\n key: 'gameSidePeople',\n label: 'People on one side of one game',\n limit: MAX_ROSTER_ENTRIES_PER_TEAM,\n },\n { key: 'leagueTeams', label: 'Teams in a league', limit: MAX_TEAMS_PER_LEAGUE },\n {\n key: 'leagueGames',\n label: \"Games in a league, so also a team's games\",\n limit: MAX_GAMES_PER_LEAGUE,\n },\n { key: 'weekGames', label: 'Games in one week of the schedule', limit: MAX_SCHEDULE_WEEK_GAMES },\n { key: 'gameStats', label: 'Stats recorded in one game', limit: MAX_STAT_EVENTS_PER_GAME },\n {\n key: 'playoffCutoff',\n label: \"Teams reaching the playoffs, at most the league's team limit\",\n limit: MAX_PLAYOFF_CUTOFF,\n },\n {\n key: 'gameLocations',\n label: \"Game locations, each venue's courts or sheets counted as part of it\",\n limit: MAX_GAME_LOCATIONS,\n },\n {\n key: 'offeredWaiverTemplates',\n label: 'Waiver templates offered to leagues, retired ones not counted',\n limit: MAX_OFFERED_WAIVER_TEMPLATES,\n },\n] as const satisfies readonly { key: string; label: string; limit: number }[];\nexport type CapacityLimitKey = (typeof CAPACITY_LIMITS)[number]['key'];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/migration-console/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/migration-console/manifest.ts"],"names":[],"mappings":"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"}
@@ -166,8 +166,8 @@ export const MIGRATION_CUTOVER_MANIFEST = [
166
166
  owningStep: 'migration-console',
167
167
  }),
168
168
  v1CheckStep(A.verifyV1LeagueCapacity, {
169
- title: 'Check no V1 league is over capacity',
170
- summary: 'Lists every V1 league holding more games or teams than a league may. The leagues, teams, and games are copied only once it finds none.',
169
+ title: 'Check no V1 league or game is over capacity',
170
+ summary: 'Lists every V1 league holding more games or teams than a league may; every V1 game side holding more people than a side may, counting the people its plays name off its roster; and every open V1 game holding stats for someone no longer on the team. The leagues, teams, game rosters, and games are copied only once it finds none.',
171
171
  owningStep: 'migration-console',
172
172
  }),
173
173
  v1CheckStep(A.verifyV1HardwareContractIdsUnique, {
@@ -439,6 +439,7 @@ export const MIGRATION_CUTOVER_MANIFEST = [
439
439
  title: 'Copy the game rosters',
440
440
  summary: 'One entry per team per person in each game, from each V1 roster document’s own team and user.',
441
441
  owningStep: 'high-risk-callables',
442
+ dependsOn: [A.verifyV1LeagueCapacity],
442
443
  resumeKey: 'The V1 games by document id; the resume key is the last game id.',
443
444
  defaultPageSize: 50,
444
445
  maxPageSize: 50,
@@ -704,7 +705,7 @@ export const MIGRATION_CUTOVER_MANIFEST = [
704
705
  summary: 'The `teamMembers` collection.',
705
706
  owningStep: 'q-core',
706
707
  dependsOn: [A.verifyTeamMemberships],
707
- consumes: [A.copyTeamMemberships, A.verifyTeamMemberships],
708
+ consumes: [A.copyTeamMemberships, A.verifyTeamMemberships, A.verifyV1LeagueCapacity],
708
709
  }),
709
710
  deleteStep(A.deleteV1Teams, {
710
711
  title: 'Delete the V1 teams',
@@ -775,6 +776,7 @@ export const MIGRATION_CUTOVER_MANIFEST = [
775
776
  A.copySportGames,
776
777
  A.verifySportGames,
777
778
  A.verifyGameStats,
779
+ A.verifyV1LeagueCapacity,
778
780
  ],
779
781
  }),
780
782
  deleteStep(A.deleteV1LeagueGames, {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/migration-console/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { MIGRATION_ACTION_IDS as A } from './action-ids.js';\nimport type { MigrationActionId } from './action-ids.js';\nimport type { RegisteredCollectionPath } from '../doc-schemas/registry.js';\nimport { MAX_MIGRATION_PAGE_SIZE } from './run-state.js';\n\nexport const MIGRATION_STEP_KIND_KEYS = [\n 'executable',\n 'productControl',\n 'operatorCheckpoint',\n 'cutoverMarker',\n] as const;\nexport type MigrationStepKind = (typeof MIGRATION_STEP_KIND_KEYS)[number];\n\nexport const MIGRATION_RESULT_KIND_KEYS = ['write', 'verification'] as const;\nexport type MigrationResultKind = (typeof MIGRATION_RESULT_KIND_KEYS)[number];\n\nexport const MIGRATION_CONTROL_EVIDENCE_KEYS = ['statsJob', 'statsValidationReport'] as const;\nexport type MigrationControlEvidence = (typeof MIGRATION_CONTROL_EVIDENCE_KEYS)[number];\n\nexport const MIGRATION_OWNING_STEP_KEYS = [\n 'auth',\n 'q-core',\n 'stat-data-model',\n 'high-risk-callables',\n 'uploads-and-media',\n 'query-and-invalidation',\n 'secret-management',\n 'migration-console',\n] as const;\nexport type MigrationOwningStep = (typeof MIGRATION_OWNING_STEP_KEYS)[number];\n\ninterface MigrationStepBase {\n readonly id: MigrationActionId;\n readonly title: string;\n readonly summary: string;\n readonly owningStep: MigrationOwningStep;\n readonly dependsOn: readonly MigrationActionId[];\n readonly orderedAfter: readonly MigrationActionId[];\n}\n\nexport interface ExecutableMigrationStep extends MigrationStepBase {\n readonly kind: 'executable';\n readonly callable: string;\n readonly resultKind: MigrationResultKind;\n readonly destructive: boolean;\n readonly paged: boolean;\n readonly defaultPageSize: number;\n readonly maxPageSize: number;\n readonly informational: boolean;\n readonly idempotency: string;\n readonly resumeKey: string;\n readonly recovery: string;\n // The steps whose V1 source this destructive step removes; a non-destructive step consumes none.\n readonly consumes: readonly MigrationActionId[];\n}\n\nexport interface ProductControlMigrationStep extends MigrationStepBase {\n readonly kind: 'productControl';\n readonly callable: string;\n readonly instructions: string;\n readonly evidence: MigrationControlEvidence;\n readonly destinations: readonly RegisteredCollectionPath[];\n}\n\nexport interface OperatorCheckpointMigrationStep extends MigrationStepBase {\n readonly kind: 'operatorCheckpoint';\n readonly instructions: string;\n readonly noReturnBoundary: string | null;\n}\n\nexport interface CutoverMarkerMigrationStep extends MigrationStepBase {\n readonly kind: 'cutoverMarker';\n readonly callable: string;\n readonly noReturnBoundary: string;\n}\n\nexport type MigrationStep =\n | ExecutableMigrationStep\n | ProductControlMigrationStep\n | OperatorCheckpointMigrationStep\n | CutoverMarkerMigrationStep;\n\nexport const RECORD_MIGRATION_CONTROL_RUN_CALLABLE = 'adminUpdateMigrationActionRunControl';\nexport const RECORD_MIGRATION_CHECKPOINT_CALLABLE = 'adminUpdateMigrationActionRunCheckpoint';\nexport const RECORD_MIGRATION_CUTOVER_CALLABLE = 'adminUpdateMigrationConsoleCutover';\nexport const GET_MIGRATION_CONSOLE_CALLABLE = 'adminGetMigrationConsole';\nexport const RESOLVE_UNROSTERED_STAT_LINE_CALLABLE = 'adminCreateGameRosterPlayer';\n\nexport function migrationActionCallableName(id: MigrationActionId): string {\n const [verb = '', object = ''] = id.split('.');\n const capitalize = (word: string) => word.charAt(0).toUpperCase() + word.slice(1);\n return `adminUpdateMigrationActionRun${capitalize(verb)}${capitalize(object)}`;\n}\n\nconst COPY_IDEMPOTENCY =\n 'Deterministic destination ids written whole, so a re-run rewrites the same documents with the same content.';\nconst VERIFY_IDEMPOTENCY = 'Reads only; a re-run compares again.';\nconst DELETE_IDEMPOTENCY =\n 'Deletes by id; a document already gone is skipped, so a re-run removes only what is left.';\nconst BY_DOCUMENT_ID =\n 'Source documents in document-id order; the resume key is the last id consumed.';\nconst SINGLE_DOCUMENT = 'One source document; it is never paged.';\nconst COPY_RECOVERY = 'Fix the transform and run the copy again; it refuses a live destination.';\nconst VERIFY_RECOVERY =\n 'Repair what it reports, through its copy or its resolution, and verify again.';\nconst DELETE_RECOVERY =\n 'Forward repair only: the retained V1 Firestore export holds what was deleted.';\nconst V1_CHECK_RECOVERY = 'Fix what it reports in V1, then run the check again.';\n\ninterface ExecutableOptions {\n title: string;\n summary: string;\n owningStep: MigrationOwningStep;\n dependsOn?: readonly MigrationActionId[];\n orderedAfter?: readonly MigrationActionId[];\n resumeKey?: string;\n defaultPageSize?: number;\n maxPageSize?: number;\n}\n\nfunction copyStep(id: MigrationActionId, options: ExecutableOptions): ExecutableMigrationStep {\n return {\n kind: 'executable',\n id,\n callable: migrationActionCallableName(id),\n resultKind: 'write',\n destructive: false,\n paged: true,\n defaultPageSize: options.defaultPageSize ?? 100,\n maxPageSize: options.maxPageSize ?? MAX_MIGRATION_PAGE_SIZE,\n informational: false,\n idempotency: COPY_IDEMPOTENCY,\n resumeKey: options.resumeKey ?? BY_DOCUMENT_ID,\n recovery: COPY_RECOVERY,\n consumes: [],\n title: options.title,\n summary: options.summary,\n owningStep: options.owningStep,\n dependsOn: options.dependsOn ?? [A.checkpointV1FirestoreExport],\n orderedAfter: options.orderedAfter ?? [],\n };\n}\n\nfunction verifyStep(\n id: MigrationActionId,\n options: ExecutableOptions & { informational?: boolean; recovery?: string },\n): ExecutableMigrationStep {\n return {\n kind: 'executable',\n id,\n callable: migrationActionCallableName(id),\n resultKind: 'verification',\n destructive: false,\n paged: true,\n defaultPageSize: options.defaultPageSize ?? 100,\n maxPageSize: options.maxPageSize ?? MAX_MIGRATION_PAGE_SIZE,\n informational: options.informational ?? false,\n idempotency: VERIFY_IDEMPOTENCY,\n resumeKey: options.resumeKey ?? BY_DOCUMENT_ID,\n recovery: options.recovery ?? VERIFY_RECOVERY,\n consumes: [],\n title: options.title,\n summary: options.summary,\n owningStep: options.owningStep,\n dependsOn: options.dependsOn ?? [],\n orderedAfter: options.orderedAfter ?? [],\n };\n}\n\nfunction v1CheckStep(id: MigrationActionId, options: ExecutableOptions): ExecutableMigrationStep {\n return verifyStep(id, {\n dependsOn: [A.checkpointV1FirestoreExport],\n ...options,\n recovery: V1_CHECK_RECOVERY,\n });\n}\n\nfunction deleteStep(\n id: MigrationActionId,\n options: ExecutableOptions & { consumes: readonly MigrationActionId[] },\n): ExecutableMigrationStep {\n return {\n kind: 'executable',\n id,\n callable: migrationActionCallableName(id),\n resultKind: 'write',\n destructive: true,\n paged: true,\n defaultPageSize: options.defaultPageSize ?? 100,\n maxPageSize: options.maxPageSize ?? MAX_MIGRATION_PAGE_SIZE,\n informational: false,\n idempotency: DELETE_IDEMPOTENCY,\n resumeKey: options.resumeKey ?? BY_DOCUMENT_ID,\n recovery: DELETE_RECOVERY,\n consumes: options.consumes,\n title: options.title,\n summary: options.summary,\n owningStep: options.owningStep,\n dependsOn: options.dependsOn ?? [],\n orderedAfter: options.orderedAfter ?? [],\n };\n}\n\nconst SOURCE_VERIFICATIONS_FOR_REBUILD = [\n A.verifySportLeagues,\n A.verifyLeagueTeams,\n A.verifyTeamMemberships,\n A.verifyGameRosterPlayers,\n A.verifySportGames,\n A.verifyGameStats,\n] as const satisfies readonly MigrationActionId[];\n\nconst COPY_VERIFICATIONS = [\n A.verifyAdminList,\n A.verifyAppConfig,\n A.verifyLandingPageConfig,\n A.verifyStatsBeacon,\n A.verifyWaiverTemplates,\n A.verifyGameLocations,\n A.verifyUserProfiles,\n A.verifyHistoricalStats,\n A.verifyReservedDisplayNames,\n A.verifyPublicUsers,\n A.verifyAwardDefinitions,\n A.verifySportLeagues,\n A.verifyLeagueTeams,\n A.verifyTeamMemberships,\n A.verifyTeamInvitations,\n A.verifyTeamJoinRequests,\n A.verifyLeagueFreeAgents,\n A.verifySignedWaivers,\n A.verifyHardwareLoanContracts,\n A.verifySportGames,\n A.verifyGameStats,\n A.verifyGameRosterPlayers,\n A.verifyV1Pictures,\n] as const satisfies readonly MigrationActionId[];\n\nexport const MIGRATION_CUTOVER_MANIFEST: readonly MigrationStep[] = [\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointV1FirestoreExport,\n title: 'Keep a managed export of the V1 database',\n summary:\n 'The managed Firestore export is the record of V1 and the only recovery after a delete.',\n owningStep: 'migration-console',\n dependsOn: [],\n orderedAfter: [],\n instructions:\n 'In production, with V1 stopped, take a managed Firestore export of the whole database to a Cloud Storage bucket and keep it. In a rehearsal, name the production export the dev copy was imported from.',\n noReturnBoundary: null,\n },\n\n v1CheckStep(A.verifyV1DisplayNamesUnique, {\n title: 'Check no two V1 display names collide',\n summary:\n 'Lists every group of V1 accounts whose display names normalize to one reservation key. The profiles are copied only once it finds none.',\n owningStep: 'migration-console',\n }),\n v1CheckStep(A.verifyV1TextFitsLimits, {\n title: 'Check every V1 text fits its V2 field',\n summary:\n 'Lists every V1 text a copy carries into a capped V2 field that is over the field’s limit or that its schema would change. The copies it covers run only once it finds none.',\n owningStep: 'migration-console',\n }),\n v1CheckStep(A.verifyV1LeagueCapacity, {\n title: 'Check no V1 league is over capacity',\n summary:\n 'Lists every V1 league holding more games or teams than a league may. The leagues, teams, and games are copied only once it finds none.',\n owningStep: 'migration-console',\n }),\n v1CheckStep(A.verifyV1HardwareContractIdsUnique, {\n title: 'Check no hardware contract id is in both V1 collections',\n summary:\n 'Lists every contract id found in both V1 hardware collections. The contracts are copied only once it finds none.',\n owningStep: 'migration-console',\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n }),\n\n copyStep(A.copyAdminList, {\n title: 'Copy the admin and referee rosters',\n summary:\n 'The `landing/admin` role maps become `_systemData/adminList`, the roster every role check reads.',\n owningStep: 'auth',\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyAdminList, {\n title: 'Verify the rosters',\n summary: 'Every V1 admin and referee is on the copied roster, and nobody else is.',\n owningStep: 'auth',\n dependsOn: [A.copyAdminList],\n resumeKey: SINGLE_DOCUMENT,\n }),\n\n copyStep(A.copyAppConfig, {\n title: 'Copy the app configuration',\n summary:\n 'The version and the banner from `landing/base` become `_appConfig/app`, its switches at their open defaults.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1TextFitsLimits],\n resumeKey: SINGLE_DOCUMENT,\n }),\n copyStep(A.copyLandingPageConfig, {\n title: 'Copy the landing page copy',\n summary:\n 'The hero title and the about text become `_appConfig/landingPage`; its picture arrives with the picture carry.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1TextFitsLimits],\n resumeKey: SINGLE_DOCUMENT,\n }),\n copyStep(A.copyStatsBeacon, {\n title: 'Copy the stats beacon',\n summary:\n 'The last stats change V1 announced becomes `_appConfig/statsBeacon`, or nothing when V1 never fired one.',\n owningStep: 'query-and-invalidation',\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyAppConfig, {\n title: 'Verify the app configuration',\n summary:\n 'The version and the banner match V1 before the cutover, and the document satisfies its schema after it.',\n owningStep: 'q-core',\n dependsOn: [A.copyAppConfig],\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyLandingPageConfig, {\n title: 'Verify the landing page copy',\n summary: 'The landing copy matches V1 before the cutover, and satisfies its schema after it.',\n owningStep: 'q-core',\n dependsOn: [A.copyLandingPageConfig],\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyStatsBeacon, {\n title: 'Verify the stats beacon',\n summary: 'A beacon at least as recent as V1’s exists, or V1 never fired one.',\n owningStep: 'query-and-invalidation',\n dependsOn: [A.copyStatsBeacon],\n resumeKey: SINGLE_DOCUMENT,\n }),\n\n copyStep(A.copyWaiverTemplates, {\n title: 'Copy the waiver templates',\n summary: 'Each template under its id, its wording as version 1.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1TextFitsLimits],\n maxPageSize: 200,\n }),\n verifyStep(A.verifyWaiverTemplates, {\n title: 'Verify the waiver templates',\n summary: 'Every V1 template copied with its first version.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyWaiverTemplates],\n }),\n copyStep(A.copyGameLocations, {\n title: 'Copy the game locations',\n summary:\n 'Each venue on `landing/admin` becomes a `gameLocations` document under its id; its picture arrives with the picture carry.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1TextFitsLimits],\n resumeKey: 'The venues in array order; the resume key is the last venue id.',\n }),\n verifyStep(A.verifyGameLocations, {\n title: 'Verify the game locations',\n summary: 'Every V1 venue copied and equal.',\n owningStep: 'q-core',\n dependsOn: [A.copyGameLocations],\n resumeKey: 'The venues in array order; the resume key is the last venue id.',\n }),\n\n copyStep(A.copyUserProfiles, {\n title: 'Copy the profiles',\n summary:\n 'Each `users` document becomes its profile and its owner-only private document, every account active.',\n owningStep: 'auth',\n dependsOn: [A.verifyV1DisplayNamesUnique, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyUserProfiles, {\n title: 'Verify the profiles',\n summary: 'Every V1 profile copied with its private document.',\n owningStep: 'auth',\n dependsOn: [A.copyUserProfiles],\n }),\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointAbandonedRegistrationSweepEnabled,\n title: 'Enable the abandoned-registration sweep',\n summary:\n 'The scheduled sweep that deletes a sign-in account still holding no profile after its grace window does nothing until this is recorded, and stops again whenever the profile verification is run anew.',\n owningStep: 'auth',\n dependsOn: [A.verifyUserProfiles],\n orderedAfter: [],\n instructions:\n 'Once the profile verification has passed, confirm every account that should keep its sign-in holds a copied profile, then record this step to let the scheduled sweep delete the sign-in accounts that hold none past their grace window.',\n noReturnBoundary: 'The sweep’s first deletion of a sign-in account that holds no profile.',\n },\n copyStep(A.copyHistoricalStats, {\n title: 'Copy the historical baselines',\n summary: 'Each pre-Q-Sports career total becomes its sport’s `historicalStats` document.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyUserProfiles],\n }),\n verifyStep(A.verifyHistoricalStats, {\n title: 'Verify the historical baselines',\n summary: 'Every V1 baseline copied and equal; a database with none is declared empty.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyHistoricalStats],\n }),\n copyStep(A.deriveReservedDisplayNames, {\n title: 'Reserve the display names',\n summary: 'One reservation per copied profile.',\n owningStep: 'auth',\n dependsOn: [A.copyUserProfiles, A.verifyV1DisplayNamesUnique],\n }),\n verifyStep(A.verifyReservedDisplayNames, {\n title: 'Verify the display-name reservations',\n summary: 'Every profile holds the reservation of its name.',\n owningStep: 'auth',\n dependsOn: [A.deriveReservedDisplayNames],\n }),\n copyStep(A.migratePublicUsers, {\n title: 'Migrate the public identities in place',\n summary:\n \"Each `publicUsers` document is rewritten where it sits: an account's card from its copied profile, a ghost's from its own name.\",\n owningStep: 'q-core',\n dependsOn: [A.copyUserProfiles],\n }),\n verifyStep(A.verifyPublicUsers, {\n title: 'Verify the public identities',\n summary:\n 'Each document holds its own uid, ghost flag, and lowercase name, and shows the featured badges its profile holds.',\n owningStep: 'q-core',\n dependsOn: [A.migratePublicUsers, A.copyUserProfiles],\n }),\n copyStep(A.copyAwardDefinitions, {\n title: 'Copy the award catalog',\n summary:\n 'Each award on `landing/admin` becomes an `awardDefinitions` document with its holder count; its badge arrives with the picture carry.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copyUserProfiles, A.verifyV1TextFitsLimits],\n resumeKey: 'The awards in array order; the resume key is the last award id.',\n }),\n verifyStep(A.verifyAwardDefinitions, {\n title: 'Verify the award catalog',\n summary:\n 'Every award copied, every holder count equal to the profiles holding it, every grant, profile award pick, and shown badge naming an award that exists.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copyAwardDefinitions, A.migratePublicUsers],\n resumeKey: SINGLE_DOCUMENT,\n }),\n\n copyStep(A.copySportLeagues, {\n title: 'Copy the leagues',\n summary:\n 'Each league under its id — closed leagues included; its pictures arrive with the picture carry.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1LeagueCapacity, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifySportLeagues, {\n title: 'Verify the leagues',\n summary: 'Every V1 league copied and equal, every waiver template it names existing.',\n owningStep: 'q-core',\n dependsOn: [A.copySportLeagues, A.copyWaiverTemplates],\n }),\n copyStep(A.copyLeagueTeams, {\n title: 'Copy the teams',\n summary: 'Each team under its id, its season lines in its sport’s shape.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1LeagueCapacity, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyLeagueTeams, {\n title: 'Verify the teams',\n summary:\n 'Every V1 team copied; the season lines are held to their schema, since the rebuild replaces them.',\n owningStep: 'q-core',\n dependsOn: [A.copyLeagueTeams],\n }),\n copyStep(A.copyTeamMemberships, {\n title: 'Copy the memberships',\n summary:\n 'Each membership under its compound id, `member` becoming `player`; one whose team was not copied into its league is left behind and reported.',\n owningStep: 'q-core',\n dependsOn: [A.copyLeagueTeams],\n }),\n verifyStep(A.verifyTeamMemberships, {\n title: 'Verify the memberships',\n summary:\n 'Every V1 membership copied, or absent because its team is gone; a team with two captains and a ghost on two memberships are reported.',\n owningStep: 'q-core',\n dependsOn: [A.copyTeamMemberships],\n }),\n copyStep(A.copyTeamInvitations, {\n title: 'Copy the invitations',\n summary:\n 'Each invitation by id; a pending one whose invitee is already on the team is written approved, and a pending one whose team was not copied into its league is left behind and reported.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyLeagueTeams, A.copyTeamMemberships, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyTeamInvitations, {\n title: 'Verify the invitations',\n summary:\n 'Every V1 invitation copied as the transform makes it, or absent because its team is gone.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyTeamInvitations],\n }),\n copyStep(A.copyTeamJoinRequests, {\n title: 'Copy the join requests',\n summary:\n 'Each request by id; a pending one whose requester is already on the team is written approved, and a pending one whose team was not copied into its league is left behind and reported.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyLeagueTeams, A.copyTeamMemberships, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyTeamJoinRequests, {\n title: 'Verify the join requests',\n summary:\n 'Every V1 request copied as the transform makes it, or absent because its team is gone.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyTeamJoinRequests],\n }),\n copyStep(A.copyLeagueFreeAgents, {\n title: 'Copy the free-agent signups',\n summary:\n 'Each signup under its built id; a signup whose player already joined a team in the league is left behind and reported.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyTeamMemberships],\n }),\n verifyStep(A.verifyLeagueFreeAgents, {\n title: 'Verify the free-agent signups',\n summary: 'Every V1 signup copied, or absent because joining left it behind.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyLeagueFreeAgents],\n }),\n\n copyStep(A.copySignedWaivers, {\n title: 'Copy the signed waivers',\n summary:\n 'Every signed waiver, a ghost’s included, under its id; its signature file stays where it is.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copyWaiverTemplates],\n }),\n verifyStep(A.verifySignedWaivers, {\n title: 'Verify the signed waivers',\n summary: 'Every V1 record copied and equal, each template it names existing.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copySignedWaivers],\n }),\n copyStep(A.copyHardwareLoanContracts, {\n title: 'Copy the hardware loan contracts',\n summary:\n 'Each contract from both V1 collections under its id; its signature file stays where it is.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1HardwareContractIdsUnique],\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n }),\n verifyStep(A.verifyHardwareLoanContracts, {\n title: 'Verify the hardware loan contracts',\n summary: 'Every V1 contract copied and equal.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyHardwareLoanContracts],\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n }),\n verifyStep(A.verifySignatureFilesResolvable, {\n title: 'Verify the signature files resolve',\n summary:\n 'Each kept signature file is in this project’s bucket and exists. A rehearsal reports every file as another environment’s, which is expected.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.verifySignedWaivers, A.verifyHardwareLoanContracts],\n resumeKey: 'The signed waivers by id, then the contracts; the resume key is the record path.',\n }),\n\n copyStep(A.copyGameRosterPlayers, {\n title: 'Copy the game rosters',\n summary:\n 'One entry per team per person in each game, from each V1 roster document’s own team and user.',\n owningStep: 'high-risk-callables',\n resumeKey: 'The V1 games by document id; the resume key is the last game id.',\n defaultPageSize: 50,\n maxPageSize: 50,\n }),\n {\n kind: 'executable',\n id: A.resolveUnrosteredStatLine,\n callable: RESOLVE_UNROSTERED_STAT_LINE_CALLABLE,\n resultKind: 'write',\n destructive: false,\n paged: false,\n defaultPageSize: 1,\n maxPageSize: MAX_MIGRATION_PAGE_SIZE,\n informational: false,\n idempotency: 'A second resolution of the same line is acknowledged and writes nothing.',\n resumeKey: 'One game, one line; it is never paged.',\n recovery: 'Resolve the line again with the right team, then copy the game again.',\n consumes: [],\n title: 'Resolve a stat line no roster places',\n summary:\n 'For a line the game copy stops on, the admin names its team: the missing roster entry is written with its reason, and the game copied again.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyGameRosterPlayers],\n orderedAfter: [],\n },\n copyStep(A.copySportGames, {\n title: 'Copy the games',\n summary:\n 'Each V1 game with its stats: the event documents, the rollup, the participation lists by roster entry, and a completed game’s finalized record.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyGameRosterPlayers, A.verifyV1LeagueCapacity, A.verifyV1TextFitsLimits],\n orderedAfter: [A.resolveUnrosteredStatLine],\n resumeKey:\n 'The V1 games by document id; a game’s documents commit before its id becomes the resume key.',\n defaultPageSize: 20,\n maxPageSize: 25,\n }),\n verifyStep(A.verifySportGames, {\n title: 'Verify the game schedules',\n summary: 'Every V1 game’s schedule fields as the copy converts them.',\n owningStep: 'q-core',\n dependsOn: [A.copySportGames],\n }),\n verifyStep(A.verifyGameStats, {\n title: 'Verify the game stats',\n summary:\n 'Per game: the events replay to the rollup and to V1’s recorded lines, the finalized record matches, and every line and list names a roster entry.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copySportGames],\n defaultPageSize: 20,\n maxPageSize: 25,\n }),\n {\n kind: 'executable',\n id: A.reconcileOpenGameRosters,\n callable: migrationActionCallableName(A.reconcileOpenGameRosters),\n resultKind: 'write',\n destructive: false,\n paged: true,\n defaultPageSize: 20,\n maxPageSize: 25,\n informational: false,\n idempotency:\n 'Each open game is reconciled through the roster core against the copied memberships; a reconciled game changes nothing on a re-run.',\n resumeKey: 'The open games by document id; the resume key is the last game id.',\n recovery:\n 'Run it again: a game held by another operation is reported and reconciled on the next run.',\n consumes: [],\n title: 'Reconcile the open games’ rosters',\n summary:\n 'Each game open at the cutover: stale stat-free entries removed, missing members added.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyTeamMemberships, A.verifyGameStats],\n orderedAfter: [],\n },\n verifyStep(A.verifyGameRosterPlayers, {\n title: 'Verify the game rosters',\n summary: 'Every V1 roster entry copied; before the cutover, no open game keeps a stale entry.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyGameRosterPlayers, A.reconcileOpenGameRosters],\n resumeKey: 'The V1 games by document id; the resume key is the last game id.',\n }),\n\n copyStep(A.carryV1Pictures, {\n title: 'Carry the V1 pictures onto the pipeline',\n summary:\n 'Each league, landing, venue, and award image is staged and accepted through the upload pipeline, which processes and publishes it. A rehearsal reports every source unavailable.',\n owningStep: 'uploads-and-media',\n dependsOn: [\n A.copySportLeagues,\n A.copyLandingPageConfig,\n A.copyGameLocations,\n A.copyAwardDefinitions,\n ],\n resumeKey: 'By owner kind, then owner id; the resume key is `{ownerKind}:{ownerId}`.',\n }),\n verifyStep(A.verifyV1Pictures, {\n title: 'Verify the carried pictures',\n summary:\n 'Every V1 reference attached with its three sizes, or reported for a reason no re-run changes; nothing still pending. A source in another bucket, or a page it could examine none of, fails it unless the run acknowledges unexamined sources, as a rehearsal does.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.carryV1Pictures],\n resumeKey: 'By owner kind, then owner id; the resume key is `{ownerKind}:{ownerId}`.',\n }),\n\n {\n kind: 'executable',\n id: A.cleanupOrphanGhostPublicUsers,\n callable: migrationActionCallableName(A.cleanupOrphanGhostPublicUsers),\n resultKind: 'write',\n destructive: true,\n paged: true,\n defaultPageSize: 100,\n maxPageSize: 100,\n informational: false,\n idempotency:\n 'A ghost document is deleted only when nothing references it; a re-run finds nothing further.',\n resumeKey: BY_DOCUMENT_ID,\n recovery: DELETE_RECOVERY,\n consumes: [],\n title: 'Remove the ghost names nothing references',\n summary:\n 'Each ghost `publicUsers` document no membership, roster entry, or unvoided stat event names, reported by disposition first. No signed waiver is touched.',\n owningStep: 'high-risk-callables',\n dependsOn: [\n A.verifyPublicUsers,\n A.verifyTeamMemberships,\n A.verifyGameRosterPlayers,\n A.verifyGameStats,\n ],\n orderedAfter: [],\n },\n\n {\n kind: 'productControl',\n id: A.rebuildStats,\n title: 'Rebuild every stat',\n summary:\n 'Every team’s season line and per-membership rows, closed leagues included, every account’s lifetime lines and the hall of fame of every sport that keeps one, rebuilt from the copied games and historical baselines.',\n owningStep: 'stat-data-model',\n dependsOn: [...SOURCE_VERIFICATIONS_FOR_REBUILD, A.verifyUserProfiles, A.verifyHistoricalStats],\n orderedAfter: [],\n callable: 'adminCreateStatsJob',\n destinations: ['leagueTeams/{teamId}', 'userProfiles/{userId}', 'sportHallOfFame/{sportKey}'],\n instructions: 'Run “Rebuild › Everything” from Stats › Fix stats and let it finish.',\n evidence: 'statsJob',\n },\n {\n kind: 'productControl',\n id: A.validateStats,\n title: 'Validate the stats',\n summary: 'Check stats over everything; it must report no finding.',\n owningStep: 'stat-data-model',\n dependsOn: [A.rebuildStats],\n orderedAfter: [],\n callable: 'adminCreateStatsValidationReport',\n destinations: ['statsValidationReports/{reportId}'],\n instructions: 'Run “Check stats” over everything from Stats › Fix stats and let it finish.',\n evidence: 'statsValidationReport',\n },\n verifyStep(A.verifyLeaguePlayerStats, {\n title: 'Compare the league player totals with V1',\n summary:\n 'Lists each player whose V1 league total differs from the sum of their rebuilt rows in that league. It informs the rehearsal and gates nothing.',\n owningStep: 'stat-data-model',\n dependsOn: [A.rebuildStats],\n informational: true,\n }),\n verifyStep(A.verifySportHallOfFame, {\n title: 'Verify the rebuilt hall of fame',\n summary:\n 'Every V1 hall of fame of a sport that keeps one has its rebuilt document, which satisfies its schema and holds an entry for every V1 player with a non-zero total.',\n owningStep: 'stat-data-model',\n dependsOn: [A.rebuildStats],\n }),\n\n {\n kind: 'cutoverMarker',\n id: A.recordCutoverLive,\n callable: RECORD_MIGRATION_CUTOVER_CALLABLE,\n title: 'Record the cutover',\n summary:\n 'From here on the product owns every destination: no copy runs again, and each verification holds what the product edits to its schema only.',\n owningStep: 'migration-console',\n dependsOn: [...COPY_VERIFICATIONS, A.validateStats],\n orderedAfter: [A.verifySportHallOfFame, A.verifySignatureFilesResolvable],\n noReturnBoundary:\n 'Recording the cutover. It is never undone: every copy refuses a live destination after it.',\n },\n\n deleteStep(A.deleteV1LandingBase, {\n title: 'Delete `landing/base`',\n summary:\n 'The V1 configuration document, once its three documents and its picture are verified.',\n owningStep: 'q-core',\n dependsOn: [\n A.verifyAppConfig,\n A.verifyLandingPageConfig,\n A.verifyStatsBeacon,\n A.verifyV1Pictures,\n ],\n resumeKey: SINGLE_DOCUMENT,\n consumes: [\n A.copyAppConfig,\n A.copyLandingPageConfig,\n A.copyStatsBeacon,\n A.verifyAppConfig,\n A.verifyLandingPageConfig,\n A.verifyStatsBeacon,\n A.carryV1Pictures,\n A.verifyV1Pictures,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1LandingAdmin, {\n title: 'Delete `landing/admin`',\n summary:\n 'The V1 admin document — its role maps, venues and award catalog — once the rosters, the venues, the awards and their pictures are verified.',\n owningStep: 'q-core',\n dependsOn: [\n A.verifyAdminList,\n A.verifyGameLocations,\n A.verifyAwardDefinitions,\n A.verifyUserProfiles,\n A.verifyPublicUsers,\n A.verifyV1Pictures,\n ],\n resumeKey: SINGLE_DOCUMENT,\n consumes: [\n A.copyAdminList,\n A.verifyAdminList,\n A.copyGameLocations,\n A.verifyGameLocations,\n A.copyAwardDefinitions,\n A.verifyAwardDefinitions,\n A.carryV1Pictures,\n A.verifyV1Pictures,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1Waivers, {\n title: 'Delete the V1 waiver templates',\n summary: 'The `waivers` collection.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyWaiverTemplates],\n consumes: [A.copyWaiverTemplates, A.verifyWaiverTemplates, A.verifyV1TextFitsLimits],\n }),\n deleteStep(A.deleteV1Users, {\n title: 'Delete the V1 user documents',\n summary: 'Each `users` document with its historical baselines.',\n owningStep: 'auth',\n dependsOn: [A.verifyUserProfiles, A.verifyHistoricalStats, A.verifyReservedDisplayNames],\n maxPageSize: 200,\n consumes: [\n A.copyUserProfiles,\n A.verifyUserProfiles,\n A.copyHistoricalStats,\n A.verifyHistoricalStats,\n A.verifyV1DisplayNamesUnique,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1TeamInvites, {\n title: 'Delete the V1 invitations',\n summary: 'The `teamInvites` collection.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyTeamInvitations],\n consumes: [A.copyTeamInvitations, A.verifyTeamInvitations, A.verifyV1TextFitsLimits],\n }),\n deleteStep(A.deleteV1JoinRequests, {\n title: 'Delete the V1 join requests',\n summary: 'The `joinRequests` collection.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyTeamJoinRequests],\n consumes: [A.copyTeamJoinRequests, A.verifyTeamJoinRequests, A.verifyV1TextFitsLimits],\n }),\n deleteStep(A.deleteV1FreeAgentSignups, {\n title: 'Delete the V1 free-agent signups',\n summary: 'The `freeAgentSignups` collection, left-behind signups included.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyLeagueFreeAgents],\n consumes: [A.copyLeagueFreeAgents, A.verifyLeagueFreeAgents],\n }),\n deleteStep(A.deleteV1TeamMembers, {\n title: 'Delete the V1 memberships',\n summary: 'The `teamMembers` collection.',\n owningStep: 'q-core',\n dependsOn: [A.verifyTeamMemberships],\n consumes: [A.copyTeamMemberships, A.verifyTeamMemberships],\n }),\n deleteStep(A.deleteV1Teams, {\n title: 'Delete the V1 teams',\n summary: 'The `teams` collection; a team still holding a subcollection is reported and kept.',\n owningStep: 'q-core',\n dependsOn: [A.verifyLeagueTeams],\n consumes: [\n A.copyLeagueTeams,\n A.verifyLeagueTeams,\n A.verifyV1LeagueCapacity,\n A.verifyV1TextFitsLimits,\n ],\n }),\n {\n kind: 'executable',\n id: A.revokeV1SignatureDownloadTokens,\n callable: migrationActionCallableName(A.revokeV1SignatureDownloadTokens),\n resultKind: 'write',\n destructive: true,\n paged: true,\n defaultPageSize: 100,\n maxPageSize: 200,\n informational: false,\n idempotency:\n 'Removes a kept file’s download token; a file holding none is skipped. No file is moved or deleted.',\n resumeKey: 'The signed waivers by id, then the contracts; the resume key is the record path.',\n recovery: 'Run it again; a file whose token went is skipped.',\n consumes: [],\n title: 'Revoke the V1 signature download links',\n summary:\n 'Each kept signature file loses the download token V1’s stored links carry, so those links stop resolving.',\n owningStep: 'uploads-and-media',\n dependsOn: [\n A.verifySignedWaivers,\n A.verifyHardwareLoanContracts,\n A.verifySignatureFilesResolvable,\n ],\n orderedAfter: [],\n },\n deleteStep(A.deleteV1WaiverSignatures, {\n title: 'Delete the V1 signed-waiver records',\n summary: 'The `waiverSignatures` records; the files stay, named by the copied records.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.verifySignedWaivers],\n consumes: [A.copySignedWaivers, A.verifySignedWaivers],\n }),\n deleteStep(A.deleteV1HardwareContracts, {\n title: 'Delete the V1 hardware contracts',\n summary:\n 'Both V1 contract collections; the signature files stay, named by the copied contracts.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyHardwareLoanContracts],\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n consumes: [\n A.copyHardwareLoanContracts,\n A.verifyHardwareLoanContracts,\n A.verifyV1HardwareContractIdsUnique,\n ],\n }),\n deleteStep(A.deleteV1GameRosters, {\n title: 'Delete the V1 game rosters',\n summary: 'Each V1 game’s `roster` subcollection — never the game document.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyGameRosterPlayers, A.validateStats],\n resumeKey: 'The V1 games by document id; the resume key is the last game id.',\n defaultPageSize: 50,\n maxPageSize: 50,\n consumes: [\n A.copyGameRosterPlayers,\n A.verifyGameRosterPlayers,\n A.copySportGames,\n A.verifySportGames,\n A.verifyGameStats,\n ],\n }),\n deleteStep(A.deleteV1LeagueGames, {\n title: 'Delete the V1 games',\n summary: 'The `leagueGames` documents; a game still holding its roster is reported and kept.',\n owningStep: 'stat-data-model',\n dependsOn: [\n A.verifySportGames,\n A.verifyGameStats,\n A.verifyGameRosterPlayers,\n A.validateStats,\n A.deleteV1GameRosters,\n ],\n consumes: [\n A.copySportGames,\n A.verifySportGames,\n A.verifyGameStats,\n A.copyGameRosterPlayers,\n A.verifyGameRosterPlayers,\n A.verifyV1LeagueCapacity,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1LeagueChats, {\n title: 'Delete the V1 league chats',\n summary:\n 'The parked chat documents under each V1 league and its team paths. Any other document found under a league is reported and kept.',\n owningStep: 'migration-console',\n dependsOn: [A.checkpointV1FirestoreExport],\n resumeKey:\n 'The V1 leagues by document id; the resume key is the last league id, or, while a league holds more chat than one page examines or deletes, `{leagueId}/unfinished` inside its own chat and `{leagueId}/unfinished/{teamParentId}` from that team path on.',\n defaultPageSize: 50,\n maxPageSize: 50,\n consumes: [],\n }),\n deleteStep(A.deleteV1Leagues, {\n title: 'Delete the V1 leagues',\n summary:\n 'The `leagues` collection; a league still holding a subcollection is reported and kept.',\n owningStep: 'q-core',\n dependsOn: [A.verifySportLeagues, A.verifyV1Pictures],\n orderedAfter: [A.verifyLeaguePlayerStats, A.deleteV1LeagueChats],\n consumes: [\n A.copySportLeagues,\n A.verifySportLeagues,\n A.verifyLeaguePlayerStats,\n A.carryV1Pictures,\n A.verifyV1Pictures,\n A.verifyV1LeagueCapacity,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1HallOfFame, {\n title: 'Delete the V1 hall of fame',\n summary:\n 'The `hallOfFame` collection, once every sport that keeps a hall of fame has its rebuilt document.',\n owningStep: 'stat-data-model',\n dependsOn: [A.verifySportHallOfFame],\n consumes: [A.verifySportHallOfFame],\n }),\n deleteStep(A.deleteV1ValidationReports, {\n title: 'Delete the V1 validation reports',\n summary:\n 'The `validationReports` collection. Nothing is copied: each report describes V1 aggregates at a past moment.',\n owningStep: 'stat-data-model',\n dependsOn: [A.checkpointV1FirestoreExport],\n orderedAfter: [A.validateStats],\n consumes: [],\n }),\n deleteStep(A.deleteV1AdminStats, {\n title: 'Delete the V1 dashboard counts',\n summary:\n 'The `adminStats` collection. Nothing is copied: the dashboard counts are counted live.',\n owningStep: 'q-core',\n dependsOn: [A.checkpointV1FirestoreExport],\n consumes: [],\n }),\n verifyStep(A.verifyV1CommerceDiscardable, {\n title: 'Check the V1 store holds no purchase',\n summary:\n 'Fails on an order that is not cancelled, a completed checkout, or a product holding inventory — any would be a real purchase, and goes to the owner.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.checkpointV1FirestoreExport],\n resumeKey: 'The six store collections in turn, each by document id.',\n }),\n deleteStep(A.deleteV1Commerce, {\n title: 'Delete the V1 store and payments',\n summary: 'The six store collections, nothing copied.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1CommerceDiscardable],\n resumeKey: 'The six store collections in turn, each by document id.',\n consumes: [A.verifyV1CommerceDiscardable],\n }),\n\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointUnattachedPicturesReuploaded,\n title: 'Re-upload the pictures the carry could not attach',\n summary: 'Any V1 image still unattached in production goes back on through its own control.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.verifyV1Pictures, A.recordCutoverLive],\n orderedAfter: [],\n instructions:\n 'For each source the picture verification reported, re-upload the image through its control — Reupload badge for an award, the picture managers for a league, the landing page, or a venue. In a rehearsal, record that this is production-only.',\n noReturnBoundary: null,\n },\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointPaymentCredentialsRetired,\n title: 'Retire the payment-service credentials',\n summary:\n 'V2 binds no payment-service credential, so once it is live the three V1 binds are live credentials with no reader.',\n owningStep: 'secret-management',\n dependsOn: [A.recordCutoverLive],\n orderedAfter: [],\n instructions:\n 'Production only, once V2 is live there: revoke the payment service’s secret key and disable its webhook endpoint in its dashboard, then destroy the three secrets V1 binds for it — its secret key, its webhook secret, and APP_URL — in Secret Manager in both Firebase projects. In a rehearsal, record that this is production-only.',\n noReturnBoundary: 'The secret key revocation.',\n },\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointServiceAccountKeyRevoked,\n title: 'Revoke the obsolete production service-account key',\n summary:\n 'No script reads the local production key once the export script runs on the signed-in CLI credentials; revoking it makes every copy of it worthless.',\n owningStep: 'secret-management',\n dependsOn: [A.checkpointV1FirestoreExport],\n orderedAfter: [A.recordCutoverLive],\n instructions:\n 'Run the export script on Application Default Credentials against the production project named explicitly, then revoke the q-sports-prod service-account key in the Google Cloud console and delete serviceAccount.json from the machine. No replacement key is minted. In a rehearsal, record that this is production-only.',\n noReturnBoundary: 'The key revocation.',\n },\n];\n\nexport const MIGRATION_STEP_BY_ID: ReadonlyMap<MigrationActionId, MigrationStep> = new Map(\n MIGRATION_CUTOVER_MANIFEST.map((step) => [step.id, step]),\n);\n\nexport function migrationStepsOfKind<K extends MigrationStepKind>(\n kind: K,\n): Extract<MigrationStep, { kind: K }>[] {\n return MIGRATION_CUTOVER_MANIFEST.filter(\n (step): step is Extract<MigrationStep, { kind: K }> => step.kind === kind,\n );\n}\n"]}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/migration-console/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { MIGRATION_ACTION_IDS as A } from './action-ids.js';\nimport type { MigrationActionId } from './action-ids.js';\nimport type { RegisteredCollectionPath } from '../doc-schemas/registry.js';\nimport { MAX_MIGRATION_PAGE_SIZE } from './run-state.js';\n\nexport const MIGRATION_STEP_KIND_KEYS = [\n 'executable',\n 'productControl',\n 'operatorCheckpoint',\n 'cutoverMarker',\n] as const;\nexport type MigrationStepKind = (typeof MIGRATION_STEP_KIND_KEYS)[number];\n\nexport const MIGRATION_RESULT_KIND_KEYS = ['write', 'verification'] as const;\nexport type MigrationResultKind = (typeof MIGRATION_RESULT_KIND_KEYS)[number];\n\nexport const MIGRATION_CONTROL_EVIDENCE_KEYS = ['statsJob', 'statsValidationReport'] as const;\nexport type MigrationControlEvidence = (typeof MIGRATION_CONTROL_EVIDENCE_KEYS)[number];\n\nexport const MIGRATION_OWNING_STEP_KEYS = [\n 'auth',\n 'q-core',\n 'stat-data-model',\n 'high-risk-callables',\n 'uploads-and-media',\n 'query-and-invalidation',\n 'secret-management',\n 'migration-console',\n] as const;\nexport type MigrationOwningStep = (typeof MIGRATION_OWNING_STEP_KEYS)[number];\n\ninterface MigrationStepBase {\n readonly id: MigrationActionId;\n readonly title: string;\n readonly summary: string;\n readonly owningStep: MigrationOwningStep;\n readonly dependsOn: readonly MigrationActionId[];\n readonly orderedAfter: readonly MigrationActionId[];\n}\n\nexport interface ExecutableMigrationStep extends MigrationStepBase {\n readonly kind: 'executable';\n readonly callable: string;\n readonly resultKind: MigrationResultKind;\n readonly destructive: boolean;\n readonly paged: boolean;\n readonly defaultPageSize: number;\n readonly maxPageSize: number;\n readonly informational: boolean;\n readonly idempotency: string;\n readonly resumeKey: string;\n readonly recovery: string;\n // The steps whose V1 source this destructive step removes; a non-destructive step consumes none.\n readonly consumes: readonly MigrationActionId[];\n}\n\nexport interface ProductControlMigrationStep extends MigrationStepBase {\n readonly kind: 'productControl';\n readonly callable: string;\n readonly instructions: string;\n readonly evidence: MigrationControlEvidence;\n readonly destinations: readonly RegisteredCollectionPath[];\n}\n\nexport interface OperatorCheckpointMigrationStep extends MigrationStepBase {\n readonly kind: 'operatorCheckpoint';\n readonly instructions: string;\n readonly noReturnBoundary: string | null;\n}\n\nexport interface CutoverMarkerMigrationStep extends MigrationStepBase {\n readonly kind: 'cutoverMarker';\n readonly callable: string;\n readonly noReturnBoundary: string;\n}\n\nexport type MigrationStep =\n | ExecutableMigrationStep\n | ProductControlMigrationStep\n | OperatorCheckpointMigrationStep\n | CutoverMarkerMigrationStep;\n\nexport const RECORD_MIGRATION_CONTROL_RUN_CALLABLE = 'adminUpdateMigrationActionRunControl';\nexport const RECORD_MIGRATION_CHECKPOINT_CALLABLE = 'adminUpdateMigrationActionRunCheckpoint';\nexport const RECORD_MIGRATION_CUTOVER_CALLABLE = 'adminUpdateMigrationConsoleCutover';\nexport const GET_MIGRATION_CONSOLE_CALLABLE = 'adminGetMigrationConsole';\nexport const RESOLVE_UNROSTERED_STAT_LINE_CALLABLE = 'adminCreateGameRosterPlayer';\n\nexport function migrationActionCallableName(id: MigrationActionId): string {\n const [verb = '', object = ''] = id.split('.');\n const capitalize = (word: string) => word.charAt(0).toUpperCase() + word.slice(1);\n return `adminUpdateMigrationActionRun${capitalize(verb)}${capitalize(object)}`;\n}\n\nconst COPY_IDEMPOTENCY =\n 'Deterministic destination ids written whole, so a re-run rewrites the same documents with the same content.';\nconst VERIFY_IDEMPOTENCY = 'Reads only; a re-run compares again.';\nconst DELETE_IDEMPOTENCY =\n 'Deletes by id; a document already gone is skipped, so a re-run removes only what is left.';\nconst BY_DOCUMENT_ID =\n 'Source documents in document-id order; the resume key is the last id consumed.';\nconst SINGLE_DOCUMENT = 'One source document; it is never paged.';\nconst COPY_RECOVERY = 'Fix the transform and run the copy again; it refuses a live destination.';\nconst VERIFY_RECOVERY =\n 'Repair what it reports, through its copy or its resolution, and verify again.';\nconst DELETE_RECOVERY =\n 'Forward repair only: the retained V1 Firestore export holds what was deleted.';\nconst V1_CHECK_RECOVERY = 'Fix what it reports in V1, then run the check again.';\n\ninterface ExecutableOptions {\n title: string;\n summary: string;\n owningStep: MigrationOwningStep;\n dependsOn?: readonly MigrationActionId[];\n orderedAfter?: readonly MigrationActionId[];\n resumeKey?: string;\n defaultPageSize?: number;\n maxPageSize?: number;\n}\n\nfunction copyStep(id: MigrationActionId, options: ExecutableOptions): ExecutableMigrationStep {\n return {\n kind: 'executable',\n id,\n callable: migrationActionCallableName(id),\n resultKind: 'write',\n destructive: false,\n paged: true,\n defaultPageSize: options.defaultPageSize ?? 100,\n maxPageSize: options.maxPageSize ?? MAX_MIGRATION_PAGE_SIZE,\n informational: false,\n idempotency: COPY_IDEMPOTENCY,\n resumeKey: options.resumeKey ?? BY_DOCUMENT_ID,\n recovery: COPY_RECOVERY,\n consumes: [],\n title: options.title,\n summary: options.summary,\n owningStep: options.owningStep,\n dependsOn: options.dependsOn ?? [A.checkpointV1FirestoreExport],\n orderedAfter: options.orderedAfter ?? [],\n };\n}\n\nfunction verifyStep(\n id: MigrationActionId,\n options: ExecutableOptions & { informational?: boolean; recovery?: string },\n): ExecutableMigrationStep {\n return {\n kind: 'executable',\n id,\n callable: migrationActionCallableName(id),\n resultKind: 'verification',\n destructive: false,\n paged: true,\n defaultPageSize: options.defaultPageSize ?? 100,\n maxPageSize: options.maxPageSize ?? MAX_MIGRATION_PAGE_SIZE,\n informational: options.informational ?? false,\n idempotency: VERIFY_IDEMPOTENCY,\n resumeKey: options.resumeKey ?? BY_DOCUMENT_ID,\n recovery: options.recovery ?? VERIFY_RECOVERY,\n consumes: [],\n title: options.title,\n summary: options.summary,\n owningStep: options.owningStep,\n dependsOn: options.dependsOn ?? [],\n orderedAfter: options.orderedAfter ?? [],\n };\n}\n\nfunction v1CheckStep(id: MigrationActionId, options: ExecutableOptions): ExecutableMigrationStep {\n return verifyStep(id, {\n dependsOn: [A.checkpointV1FirestoreExport],\n ...options,\n recovery: V1_CHECK_RECOVERY,\n });\n}\n\nfunction deleteStep(\n id: MigrationActionId,\n options: ExecutableOptions & { consumes: readonly MigrationActionId[] },\n): ExecutableMigrationStep {\n return {\n kind: 'executable',\n id,\n callable: migrationActionCallableName(id),\n resultKind: 'write',\n destructive: true,\n paged: true,\n defaultPageSize: options.defaultPageSize ?? 100,\n maxPageSize: options.maxPageSize ?? MAX_MIGRATION_PAGE_SIZE,\n informational: false,\n idempotency: DELETE_IDEMPOTENCY,\n resumeKey: options.resumeKey ?? BY_DOCUMENT_ID,\n recovery: DELETE_RECOVERY,\n consumes: options.consumes,\n title: options.title,\n summary: options.summary,\n owningStep: options.owningStep,\n dependsOn: options.dependsOn ?? [],\n orderedAfter: options.orderedAfter ?? [],\n };\n}\n\nconst SOURCE_VERIFICATIONS_FOR_REBUILD = [\n A.verifySportLeagues,\n A.verifyLeagueTeams,\n A.verifyTeamMemberships,\n A.verifyGameRosterPlayers,\n A.verifySportGames,\n A.verifyGameStats,\n] as const satisfies readonly MigrationActionId[];\n\nconst COPY_VERIFICATIONS = [\n A.verifyAdminList,\n A.verifyAppConfig,\n A.verifyLandingPageConfig,\n A.verifyStatsBeacon,\n A.verifyWaiverTemplates,\n A.verifyGameLocations,\n A.verifyUserProfiles,\n A.verifyHistoricalStats,\n A.verifyReservedDisplayNames,\n A.verifyPublicUsers,\n A.verifyAwardDefinitions,\n A.verifySportLeagues,\n A.verifyLeagueTeams,\n A.verifyTeamMemberships,\n A.verifyTeamInvitations,\n A.verifyTeamJoinRequests,\n A.verifyLeagueFreeAgents,\n A.verifySignedWaivers,\n A.verifyHardwareLoanContracts,\n A.verifySportGames,\n A.verifyGameStats,\n A.verifyGameRosterPlayers,\n A.verifyV1Pictures,\n] as const satisfies readonly MigrationActionId[];\n\nexport const MIGRATION_CUTOVER_MANIFEST: readonly MigrationStep[] = [\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointV1FirestoreExport,\n title: 'Keep a managed export of the V1 database',\n summary:\n 'The managed Firestore export is the record of V1 and the only recovery after a delete.',\n owningStep: 'migration-console',\n dependsOn: [],\n orderedAfter: [],\n instructions:\n 'In production, with V1 stopped, take a managed Firestore export of the whole database to a Cloud Storage bucket and keep it. In a rehearsal, name the production export the dev copy was imported from.',\n noReturnBoundary: null,\n },\n\n v1CheckStep(A.verifyV1DisplayNamesUnique, {\n title: 'Check no two V1 display names collide',\n summary:\n 'Lists every group of V1 accounts whose display names normalize to one reservation key. The profiles are copied only once it finds none.',\n owningStep: 'migration-console',\n }),\n v1CheckStep(A.verifyV1TextFitsLimits, {\n title: 'Check every V1 text fits its V2 field',\n summary:\n 'Lists every V1 text a copy carries into a capped V2 field that is over the field’s limit or that its schema would change. The copies it covers run only once it finds none.',\n owningStep: 'migration-console',\n }),\n v1CheckStep(A.verifyV1LeagueCapacity, {\n title: 'Check no V1 league or game is over capacity',\n summary:\n 'Lists every V1 league holding more games or teams than a league may; every V1 game side holding more people than a side may, counting the people its plays name off its roster; and every open V1 game holding stats for someone no longer on the team. The leagues, teams, game rosters, and games are copied only once it finds none.',\n owningStep: 'migration-console',\n }),\n v1CheckStep(A.verifyV1HardwareContractIdsUnique, {\n title: 'Check no hardware contract id is in both V1 collections',\n summary:\n 'Lists every contract id found in both V1 hardware collections. The contracts are copied only once it finds none.',\n owningStep: 'migration-console',\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n }),\n\n copyStep(A.copyAdminList, {\n title: 'Copy the admin and referee rosters',\n summary:\n 'The `landing/admin` role maps become `_systemData/adminList`, the roster every role check reads.',\n owningStep: 'auth',\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyAdminList, {\n title: 'Verify the rosters',\n summary: 'Every V1 admin and referee is on the copied roster, and nobody else is.',\n owningStep: 'auth',\n dependsOn: [A.copyAdminList],\n resumeKey: SINGLE_DOCUMENT,\n }),\n\n copyStep(A.copyAppConfig, {\n title: 'Copy the app configuration',\n summary:\n 'The version and the banner from `landing/base` become `_appConfig/app`, its switches at their open defaults.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1TextFitsLimits],\n resumeKey: SINGLE_DOCUMENT,\n }),\n copyStep(A.copyLandingPageConfig, {\n title: 'Copy the landing page copy',\n summary:\n 'The hero title and the about text become `_appConfig/landingPage`; its picture arrives with the picture carry.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1TextFitsLimits],\n resumeKey: SINGLE_DOCUMENT,\n }),\n copyStep(A.copyStatsBeacon, {\n title: 'Copy the stats beacon',\n summary:\n 'The last stats change V1 announced becomes `_appConfig/statsBeacon`, or nothing when V1 never fired one.',\n owningStep: 'query-and-invalidation',\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyAppConfig, {\n title: 'Verify the app configuration',\n summary:\n 'The version and the banner match V1 before the cutover, and the document satisfies its schema after it.',\n owningStep: 'q-core',\n dependsOn: [A.copyAppConfig],\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyLandingPageConfig, {\n title: 'Verify the landing page copy',\n summary: 'The landing copy matches V1 before the cutover, and satisfies its schema after it.',\n owningStep: 'q-core',\n dependsOn: [A.copyLandingPageConfig],\n resumeKey: SINGLE_DOCUMENT,\n }),\n verifyStep(A.verifyStatsBeacon, {\n title: 'Verify the stats beacon',\n summary: 'A beacon at least as recent as V1’s exists, or V1 never fired one.',\n owningStep: 'query-and-invalidation',\n dependsOn: [A.copyStatsBeacon],\n resumeKey: SINGLE_DOCUMENT,\n }),\n\n copyStep(A.copyWaiverTemplates, {\n title: 'Copy the waiver templates',\n summary: 'Each template under its id, its wording as version 1.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1TextFitsLimits],\n maxPageSize: 200,\n }),\n verifyStep(A.verifyWaiverTemplates, {\n title: 'Verify the waiver templates',\n summary: 'Every V1 template copied with its first version.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyWaiverTemplates],\n }),\n copyStep(A.copyGameLocations, {\n title: 'Copy the game locations',\n summary:\n 'Each venue on `landing/admin` becomes a `gameLocations` document under its id; its picture arrives with the picture carry.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1TextFitsLimits],\n resumeKey: 'The venues in array order; the resume key is the last venue id.',\n }),\n verifyStep(A.verifyGameLocations, {\n title: 'Verify the game locations',\n summary: 'Every V1 venue copied and equal.',\n owningStep: 'q-core',\n dependsOn: [A.copyGameLocations],\n resumeKey: 'The venues in array order; the resume key is the last venue id.',\n }),\n\n copyStep(A.copyUserProfiles, {\n title: 'Copy the profiles',\n summary:\n 'Each `users` document becomes its profile and its owner-only private document, every account active.',\n owningStep: 'auth',\n dependsOn: [A.verifyV1DisplayNamesUnique, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyUserProfiles, {\n title: 'Verify the profiles',\n summary: 'Every V1 profile copied with its private document.',\n owningStep: 'auth',\n dependsOn: [A.copyUserProfiles],\n }),\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointAbandonedRegistrationSweepEnabled,\n title: 'Enable the abandoned-registration sweep',\n summary:\n 'The scheduled sweep that deletes a sign-in account still holding no profile after its grace window does nothing until this is recorded, and stops again whenever the profile verification is run anew.',\n owningStep: 'auth',\n dependsOn: [A.verifyUserProfiles],\n orderedAfter: [],\n instructions:\n 'Once the profile verification has passed, confirm every account that should keep its sign-in holds a copied profile, then record this step to let the scheduled sweep delete the sign-in accounts that hold none past their grace window.',\n noReturnBoundary: 'The sweep’s first deletion of a sign-in account that holds no profile.',\n },\n copyStep(A.copyHistoricalStats, {\n title: 'Copy the historical baselines',\n summary: 'Each pre-Q-Sports career total becomes its sport’s `historicalStats` document.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyUserProfiles],\n }),\n verifyStep(A.verifyHistoricalStats, {\n title: 'Verify the historical baselines',\n summary: 'Every V1 baseline copied and equal; a database with none is declared empty.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyHistoricalStats],\n }),\n copyStep(A.deriveReservedDisplayNames, {\n title: 'Reserve the display names',\n summary: 'One reservation per copied profile.',\n owningStep: 'auth',\n dependsOn: [A.copyUserProfiles, A.verifyV1DisplayNamesUnique],\n }),\n verifyStep(A.verifyReservedDisplayNames, {\n title: 'Verify the display-name reservations',\n summary: 'Every profile holds the reservation of its name.',\n owningStep: 'auth',\n dependsOn: [A.deriveReservedDisplayNames],\n }),\n copyStep(A.migratePublicUsers, {\n title: 'Migrate the public identities in place',\n summary:\n \"Each `publicUsers` document is rewritten where it sits: an account's card from its copied profile, a ghost's from its own name.\",\n owningStep: 'q-core',\n dependsOn: [A.copyUserProfiles],\n }),\n verifyStep(A.verifyPublicUsers, {\n title: 'Verify the public identities',\n summary:\n 'Each document holds its own uid, ghost flag, and lowercase name, and shows the featured badges its profile holds.',\n owningStep: 'q-core',\n dependsOn: [A.migratePublicUsers, A.copyUserProfiles],\n }),\n copyStep(A.copyAwardDefinitions, {\n title: 'Copy the award catalog',\n summary:\n 'Each award on `landing/admin` becomes an `awardDefinitions` document with its holder count; its badge arrives with the picture carry.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copyUserProfiles, A.verifyV1TextFitsLimits],\n resumeKey: 'The awards in array order; the resume key is the last award id.',\n }),\n verifyStep(A.verifyAwardDefinitions, {\n title: 'Verify the award catalog',\n summary:\n 'Every award copied, every holder count equal to the profiles holding it, every grant, profile award pick, and shown badge naming an award that exists.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copyAwardDefinitions, A.migratePublicUsers],\n resumeKey: SINGLE_DOCUMENT,\n }),\n\n copyStep(A.copySportLeagues, {\n title: 'Copy the leagues',\n summary:\n 'Each league under its id — closed leagues included; its pictures arrive with the picture carry.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1LeagueCapacity, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifySportLeagues, {\n title: 'Verify the leagues',\n summary: 'Every V1 league copied and equal, every waiver template it names existing.',\n owningStep: 'q-core',\n dependsOn: [A.copySportLeagues, A.copyWaiverTemplates],\n }),\n copyStep(A.copyLeagueTeams, {\n title: 'Copy the teams',\n summary: 'Each team under its id, its season lines in its sport’s shape.',\n owningStep: 'q-core',\n dependsOn: [A.verifyV1LeagueCapacity, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyLeagueTeams, {\n title: 'Verify the teams',\n summary:\n 'Every V1 team copied; the season lines are held to their schema, since the rebuild replaces them.',\n owningStep: 'q-core',\n dependsOn: [A.copyLeagueTeams],\n }),\n copyStep(A.copyTeamMemberships, {\n title: 'Copy the memberships',\n summary:\n 'Each membership under its compound id, `member` becoming `player`; one whose team was not copied into its league is left behind and reported.',\n owningStep: 'q-core',\n dependsOn: [A.copyLeagueTeams],\n }),\n verifyStep(A.verifyTeamMemberships, {\n title: 'Verify the memberships',\n summary:\n 'Every V1 membership copied, or absent because its team is gone; a team with two captains and a ghost on two memberships are reported.',\n owningStep: 'q-core',\n dependsOn: [A.copyTeamMemberships],\n }),\n copyStep(A.copyTeamInvitations, {\n title: 'Copy the invitations',\n summary:\n 'Each invitation by id; a pending one whose invitee is already on the team is written approved, and a pending one whose team was not copied into its league is left behind and reported.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyLeagueTeams, A.copyTeamMemberships, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyTeamInvitations, {\n title: 'Verify the invitations',\n summary:\n 'Every V1 invitation copied as the transform makes it, or absent because its team is gone.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyTeamInvitations],\n }),\n copyStep(A.copyTeamJoinRequests, {\n title: 'Copy the join requests',\n summary:\n 'Each request by id; a pending one whose requester is already on the team is written approved, and a pending one whose team was not copied into its league is left behind and reported.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyLeagueTeams, A.copyTeamMemberships, A.verifyV1TextFitsLimits],\n }),\n verifyStep(A.verifyTeamJoinRequests, {\n title: 'Verify the join requests',\n summary:\n 'Every V1 request copied as the transform makes it, or absent because its team is gone.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyTeamJoinRequests],\n }),\n copyStep(A.copyLeagueFreeAgents, {\n title: 'Copy the free-agent signups',\n summary:\n 'Each signup under its built id; a signup whose player already joined a team in the league is left behind and reported.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyTeamMemberships],\n }),\n verifyStep(A.verifyLeagueFreeAgents, {\n title: 'Verify the free-agent signups',\n summary: 'Every V1 signup copied, or absent because joining left it behind.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyLeagueFreeAgents],\n }),\n\n copyStep(A.copySignedWaivers, {\n title: 'Copy the signed waivers',\n summary:\n 'Every signed waiver, a ghost’s included, under its id; its signature file stays where it is.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copyWaiverTemplates],\n }),\n verifyStep(A.verifySignedWaivers, {\n title: 'Verify the signed waivers',\n summary: 'Every V1 record copied and equal, each template it names existing.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.copySignedWaivers],\n }),\n copyStep(A.copyHardwareLoanContracts, {\n title: 'Copy the hardware loan contracts',\n summary:\n 'Each contract from both V1 collections under its id; its signature file stays where it is.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1HardwareContractIdsUnique],\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n }),\n verifyStep(A.verifyHardwareLoanContracts, {\n title: 'Verify the hardware loan contracts',\n summary: 'Every V1 contract copied and equal.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyHardwareLoanContracts],\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n }),\n verifyStep(A.verifySignatureFilesResolvable, {\n title: 'Verify the signature files resolve',\n summary:\n 'Each kept signature file is in this project’s bucket and exists. A rehearsal reports every file as another environment’s, which is expected.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.verifySignedWaivers, A.verifyHardwareLoanContracts],\n resumeKey: 'The signed waivers by id, then the contracts; the resume key is the record path.',\n }),\n\n copyStep(A.copyGameRosterPlayers, {\n title: 'Copy the game rosters',\n summary:\n 'One entry per team per person in each game, from each V1 roster document’s own team and user.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1LeagueCapacity],\n resumeKey: 'The V1 games by document id; the resume key is the last game id.',\n defaultPageSize: 50,\n maxPageSize: 50,\n }),\n {\n kind: 'executable',\n id: A.resolveUnrosteredStatLine,\n callable: RESOLVE_UNROSTERED_STAT_LINE_CALLABLE,\n resultKind: 'write',\n destructive: false,\n paged: false,\n defaultPageSize: 1,\n maxPageSize: MAX_MIGRATION_PAGE_SIZE,\n informational: false,\n idempotency: 'A second resolution of the same line is acknowledged and writes nothing.',\n resumeKey: 'One game, one line; it is never paged.',\n recovery: 'Resolve the line again with the right team, then copy the game again.',\n consumes: [],\n title: 'Resolve a stat line no roster places',\n summary:\n 'For a line the game copy stops on, the admin names its team: the missing roster entry is written with its reason, and the game copied again.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyGameRosterPlayers],\n orderedAfter: [],\n },\n copyStep(A.copySportGames, {\n title: 'Copy the games',\n summary:\n 'Each V1 game with its stats: the event documents, the rollup, the participation lists by roster entry, and a completed game’s finalized record.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copyGameRosterPlayers, A.verifyV1LeagueCapacity, A.verifyV1TextFitsLimits],\n orderedAfter: [A.resolveUnrosteredStatLine],\n resumeKey:\n 'The V1 games by document id; a game’s documents commit before its id becomes the resume key.',\n defaultPageSize: 20,\n maxPageSize: 25,\n }),\n verifyStep(A.verifySportGames, {\n title: 'Verify the game schedules',\n summary: 'Every V1 game’s schedule fields as the copy converts them.',\n owningStep: 'q-core',\n dependsOn: [A.copySportGames],\n }),\n verifyStep(A.verifyGameStats, {\n title: 'Verify the game stats',\n summary:\n 'Per game: the events replay to the rollup and to V1’s recorded lines, the finalized record matches, and every line and list names a roster entry.',\n owningStep: 'stat-data-model',\n dependsOn: [A.copySportGames],\n defaultPageSize: 20,\n maxPageSize: 25,\n }),\n {\n kind: 'executable',\n id: A.reconcileOpenGameRosters,\n callable: migrationActionCallableName(A.reconcileOpenGameRosters),\n resultKind: 'write',\n destructive: false,\n paged: true,\n defaultPageSize: 20,\n maxPageSize: 25,\n informational: false,\n idempotency:\n 'Each open game is reconciled through the roster core against the copied memberships; a reconciled game changes nothing on a re-run.',\n resumeKey: 'The open games by document id; the resume key is the last game id.',\n recovery:\n 'Run it again: a game held by another operation is reported and reconciled on the next run.',\n consumes: [],\n title: 'Reconcile the open games’ rosters',\n summary:\n 'Each game open at the cutover: stale stat-free entries removed, missing members added.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyTeamMemberships, A.verifyGameStats],\n orderedAfter: [],\n },\n verifyStep(A.verifyGameRosterPlayers, {\n title: 'Verify the game rosters',\n summary: 'Every V1 roster entry copied; before the cutover, no open game keeps a stale entry.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.copyGameRosterPlayers, A.reconcileOpenGameRosters],\n resumeKey: 'The V1 games by document id; the resume key is the last game id.',\n }),\n\n copyStep(A.carryV1Pictures, {\n title: 'Carry the V1 pictures onto the pipeline',\n summary:\n 'Each league, landing, venue, and award image is staged and accepted through the upload pipeline, which processes and publishes it. A rehearsal reports every source unavailable.',\n owningStep: 'uploads-and-media',\n dependsOn: [\n A.copySportLeagues,\n A.copyLandingPageConfig,\n A.copyGameLocations,\n A.copyAwardDefinitions,\n ],\n resumeKey: 'By owner kind, then owner id; the resume key is `{ownerKind}:{ownerId}`.',\n }),\n verifyStep(A.verifyV1Pictures, {\n title: 'Verify the carried pictures',\n summary:\n 'Every V1 reference attached with its three sizes, or reported for a reason no re-run changes; nothing still pending. A source in another bucket, or a page it could examine none of, fails it unless the run acknowledges unexamined sources, as a rehearsal does.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.carryV1Pictures],\n resumeKey: 'By owner kind, then owner id; the resume key is `{ownerKind}:{ownerId}`.',\n }),\n\n {\n kind: 'executable',\n id: A.cleanupOrphanGhostPublicUsers,\n callable: migrationActionCallableName(A.cleanupOrphanGhostPublicUsers),\n resultKind: 'write',\n destructive: true,\n paged: true,\n defaultPageSize: 100,\n maxPageSize: 100,\n informational: false,\n idempotency:\n 'A ghost document is deleted only when nothing references it; a re-run finds nothing further.',\n resumeKey: BY_DOCUMENT_ID,\n recovery: DELETE_RECOVERY,\n consumes: [],\n title: 'Remove the ghost names nothing references',\n summary:\n 'Each ghost `publicUsers` document no membership, roster entry, or unvoided stat event names, reported by disposition first. No signed waiver is touched.',\n owningStep: 'high-risk-callables',\n dependsOn: [\n A.verifyPublicUsers,\n A.verifyTeamMemberships,\n A.verifyGameRosterPlayers,\n A.verifyGameStats,\n ],\n orderedAfter: [],\n },\n\n {\n kind: 'productControl',\n id: A.rebuildStats,\n title: 'Rebuild every stat',\n summary:\n 'Every team’s season line and per-membership rows, closed leagues included, every account’s lifetime lines and the hall of fame of every sport that keeps one, rebuilt from the copied games and historical baselines.',\n owningStep: 'stat-data-model',\n dependsOn: [...SOURCE_VERIFICATIONS_FOR_REBUILD, A.verifyUserProfiles, A.verifyHistoricalStats],\n orderedAfter: [],\n callable: 'adminCreateStatsJob',\n destinations: ['leagueTeams/{teamId}', 'userProfiles/{userId}', 'sportHallOfFame/{sportKey}'],\n instructions: 'Run “Rebuild › Everything” from Stats › Fix stats and let it finish.',\n evidence: 'statsJob',\n },\n {\n kind: 'productControl',\n id: A.validateStats,\n title: 'Validate the stats',\n summary: 'Check stats over everything; it must report no finding.',\n owningStep: 'stat-data-model',\n dependsOn: [A.rebuildStats],\n orderedAfter: [],\n callable: 'adminCreateStatsValidationReport',\n destinations: ['statsValidationReports/{reportId}'],\n instructions: 'Run “Check stats” over everything from Stats › Fix stats and let it finish.',\n evidence: 'statsValidationReport',\n },\n verifyStep(A.verifyLeaguePlayerStats, {\n title: 'Compare the league player totals with V1',\n summary:\n 'Lists each player whose V1 league total differs from the sum of their rebuilt rows in that league. It informs the rehearsal and gates nothing.',\n owningStep: 'stat-data-model',\n dependsOn: [A.rebuildStats],\n informational: true,\n }),\n verifyStep(A.verifySportHallOfFame, {\n title: 'Verify the rebuilt hall of fame',\n summary:\n 'Every V1 hall of fame of a sport that keeps one has its rebuilt document, which satisfies its schema and holds an entry for every V1 player with a non-zero total.',\n owningStep: 'stat-data-model',\n dependsOn: [A.rebuildStats],\n }),\n\n {\n kind: 'cutoverMarker',\n id: A.recordCutoverLive,\n callable: RECORD_MIGRATION_CUTOVER_CALLABLE,\n title: 'Record the cutover',\n summary:\n 'From here on the product owns every destination: no copy runs again, and each verification holds what the product edits to its schema only.',\n owningStep: 'migration-console',\n dependsOn: [...COPY_VERIFICATIONS, A.validateStats],\n orderedAfter: [A.verifySportHallOfFame, A.verifySignatureFilesResolvable],\n noReturnBoundary:\n 'Recording the cutover. It is never undone: every copy refuses a live destination after it.',\n },\n\n deleteStep(A.deleteV1LandingBase, {\n title: 'Delete `landing/base`',\n summary:\n 'The V1 configuration document, once its three documents and its picture are verified.',\n owningStep: 'q-core',\n dependsOn: [\n A.verifyAppConfig,\n A.verifyLandingPageConfig,\n A.verifyStatsBeacon,\n A.verifyV1Pictures,\n ],\n resumeKey: SINGLE_DOCUMENT,\n consumes: [\n A.copyAppConfig,\n A.copyLandingPageConfig,\n A.copyStatsBeacon,\n A.verifyAppConfig,\n A.verifyLandingPageConfig,\n A.verifyStatsBeacon,\n A.carryV1Pictures,\n A.verifyV1Pictures,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1LandingAdmin, {\n title: 'Delete `landing/admin`',\n summary:\n 'The V1 admin document — its role maps, venues and award catalog — once the rosters, the venues, the awards and their pictures are verified.',\n owningStep: 'q-core',\n dependsOn: [\n A.verifyAdminList,\n A.verifyGameLocations,\n A.verifyAwardDefinitions,\n A.verifyUserProfiles,\n A.verifyPublicUsers,\n A.verifyV1Pictures,\n ],\n resumeKey: SINGLE_DOCUMENT,\n consumes: [\n A.copyAdminList,\n A.verifyAdminList,\n A.copyGameLocations,\n A.verifyGameLocations,\n A.copyAwardDefinitions,\n A.verifyAwardDefinitions,\n A.carryV1Pictures,\n A.verifyV1Pictures,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1Waivers, {\n title: 'Delete the V1 waiver templates',\n summary: 'The `waivers` collection.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyWaiverTemplates],\n consumes: [A.copyWaiverTemplates, A.verifyWaiverTemplates, A.verifyV1TextFitsLimits],\n }),\n deleteStep(A.deleteV1Users, {\n title: 'Delete the V1 user documents',\n summary: 'Each `users` document with its historical baselines.',\n owningStep: 'auth',\n dependsOn: [A.verifyUserProfiles, A.verifyHistoricalStats, A.verifyReservedDisplayNames],\n maxPageSize: 200,\n consumes: [\n A.copyUserProfiles,\n A.verifyUserProfiles,\n A.copyHistoricalStats,\n A.verifyHistoricalStats,\n A.verifyV1DisplayNamesUnique,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1TeamInvites, {\n title: 'Delete the V1 invitations',\n summary: 'The `teamInvites` collection.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyTeamInvitations],\n consumes: [A.copyTeamInvitations, A.verifyTeamInvitations, A.verifyV1TextFitsLimits],\n }),\n deleteStep(A.deleteV1JoinRequests, {\n title: 'Delete the V1 join requests',\n summary: 'The `joinRequests` collection.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyTeamJoinRequests],\n consumes: [A.copyTeamJoinRequests, A.verifyTeamJoinRequests, A.verifyV1TextFitsLimits],\n }),\n deleteStep(A.deleteV1FreeAgentSignups, {\n title: 'Delete the V1 free-agent signups',\n summary: 'The `freeAgentSignups` collection, left-behind signups included.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyLeagueFreeAgents],\n consumes: [A.copyLeagueFreeAgents, A.verifyLeagueFreeAgents],\n }),\n deleteStep(A.deleteV1TeamMembers, {\n title: 'Delete the V1 memberships',\n summary: 'The `teamMembers` collection.',\n owningStep: 'q-core',\n dependsOn: [A.verifyTeamMemberships],\n consumes: [A.copyTeamMemberships, A.verifyTeamMemberships, A.verifyV1LeagueCapacity],\n }),\n deleteStep(A.deleteV1Teams, {\n title: 'Delete the V1 teams',\n summary: 'The `teams` collection; a team still holding a subcollection is reported and kept.',\n owningStep: 'q-core',\n dependsOn: [A.verifyLeagueTeams],\n consumes: [\n A.copyLeagueTeams,\n A.verifyLeagueTeams,\n A.verifyV1LeagueCapacity,\n A.verifyV1TextFitsLimits,\n ],\n }),\n {\n kind: 'executable',\n id: A.revokeV1SignatureDownloadTokens,\n callable: migrationActionCallableName(A.revokeV1SignatureDownloadTokens),\n resultKind: 'write',\n destructive: true,\n paged: true,\n defaultPageSize: 100,\n maxPageSize: 200,\n informational: false,\n idempotency:\n 'Removes a kept file’s download token; a file holding none is skipped. No file is moved or deleted.',\n resumeKey: 'The signed waivers by id, then the contracts; the resume key is the record path.',\n recovery: 'Run it again; a file whose token went is skipped.',\n consumes: [],\n title: 'Revoke the V1 signature download links',\n summary:\n 'Each kept signature file loses the download token V1’s stored links carry, so those links stop resolving.',\n owningStep: 'uploads-and-media',\n dependsOn: [\n A.verifySignedWaivers,\n A.verifyHardwareLoanContracts,\n A.verifySignatureFilesResolvable,\n ],\n orderedAfter: [],\n },\n deleteStep(A.deleteV1WaiverSignatures, {\n title: 'Delete the V1 signed-waiver records',\n summary: 'The `waiverSignatures` records; the files stay, named by the copied records.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.verifySignedWaivers],\n consumes: [A.copySignedWaivers, A.verifySignedWaivers],\n }),\n deleteStep(A.deleteV1HardwareContracts, {\n title: 'Delete the V1 hardware contracts',\n summary:\n 'Both V1 contract collections; the signature files stay, named by the copied contracts.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyHardwareLoanContracts],\n resumeKey:\n 'The V1 collections in turn, each by document id; the resume key is `{collection}/{id}`.',\n consumes: [\n A.copyHardwareLoanContracts,\n A.verifyHardwareLoanContracts,\n A.verifyV1HardwareContractIdsUnique,\n ],\n }),\n deleteStep(A.deleteV1GameRosters, {\n title: 'Delete the V1 game rosters',\n summary: 'Each V1 game’s `roster` subcollection — never the game document.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyGameRosterPlayers, A.validateStats],\n resumeKey: 'The V1 games by document id; the resume key is the last game id.',\n defaultPageSize: 50,\n maxPageSize: 50,\n consumes: [\n A.copyGameRosterPlayers,\n A.verifyGameRosterPlayers,\n A.copySportGames,\n A.verifySportGames,\n A.verifyGameStats,\n A.verifyV1LeagueCapacity,\n ],\n }),\n deleteStep(A.deleteV1LeagueGames, {\n title: 'Delete the V1 games',\n summary: 'The `leagueGames` documents; a game still holding its roster is reported and kept.',\n owningStep: 'stat-data-model',\n dependsOn: [\n A.verifySportGames,\n A.verifyGameStats,\n A.verifyGameRosterPlayers,\n A.validateStats,\n A.deleteV1GameRosters,\n ],\n consumes: [\n A.copySportGames,\n A.verifySportGames,\n A.verifyGameStats,\n A.copyGameRosterPlayers,\n A.verifyGameRosterPlayers,\n A.verifyV1LeagueCapacity,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1LeagueChats, {\n title: 'Delete the V1 league chats',\n summary:\n 'The parked chat documents under each V1 league and its team paths. Any other document found under a league is reported and kept.',\n owningStep: 'migration-console',\n dependsOn: [A.checkpointV1FirestoreExport],\n resumeKey:\n 'The V1 leagues by document id; the resume key is the last league id, or, while a league holds more chat than one page examines or deletes, `{leagueId}/unfinished` inside its own chat and `{leagueId}/unfinished/{teamParentId}` from that team path on.',\n defaultPageSize: 50,\n maxPageSize: 50,\n consumes: [],\n }),\n deleteStep(A.deleteV1Leagues, {\n title: 'Delete the V1 leagues',\n summary:\n 'The `leagues` collection; a league still holding a subcollection is reported and kept.',\n owningStep: 'q-core',\n dependsOn: [A.verifySportLeagues, A.verifyV1Pictures],\n orderedAfter: [A.verifyLeaguePlayerStats, A.deleteV1LeagueChats],\n consumes: [\n A.copySportLeagues,\n A.verifySportLeagues,\n A.verifyLeaguePlayerStats,\n A.carryV1Pictures,\n A.verifyV1Pictures,\n A.verifyV1LeagueCapacity,\n A.verifyV1TextFitsLimits,\n ],\n }),\n deleteStep(A.deleteV1HallOfFame, {\n title: 'Delete the V1 hall of fame',\n summary:\n 'The `hallOfFame` collection, once every sport that keeps a hall of fame has its rebuilt document.',\n owningStep: 'stat-data-model',\n dependsOn: [A.verifySportHallOfFame],\n consumes: [A.verifySportHallOfFame],\n }),\n deleteStep(A.deleteV1ValidationReports, {\n title: 'Delete the V1 validation reports',\n summary:\n 'The `validationReports` collection. Nothing is copied: each report describes V1 aggregates at a past moment.',\n owningStep: 'stat-data-model',\n dependsOn: [A.checkpointV1FirestoreExport],\n orderedAfter: [A.validateStats],\n consumes: [],\n }),\n deleteStep(A.deleteV1AdminStats, {\n title: 'Delete the V1 dashboard counts',\n summary:\n 'The `adminStats` collection. Nothing is copied: the dashboard counts are counted live.',\n owningStep: 'q-core',\n dependsOn: [A.checkpointV1FirestoreExport],\n consumes: [],\n }),\n verifyStep(A.verifyV1CommerceDiscardable, {\n title: 'Check the V1 store holds no purchase',\n summary:\n 'Fails on an order that is not cancelled, a completed checkout, or a product holding inventory — any would be a real purchase, and goes to the owner.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.checkpointV1FirestoreExport],\n resumeKey: 'The six store collections in turn, each by document id.',\n }),\n deleteStep(A.deleteV1Commerce, {\n title: 'Delete the V1 store and payments',\n summary: 'The six store collections, nothing copied.',\n owningStep: 'high-risk-callables',\n dependsOn: [A.verifyV1CommerceDiscardable],\n resumeKey: 'The six store collections in turn, each by document id.',\n consumes: [A.verifyV1CommerceDiscardable],\n }),\n\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointUnattachedPicturesReuploaded,\n title: 'Re-upload the pictures the carry could not attach',\n summary: 'Any V1 image still unattached in production goes back on through its own control.',\n owningStep: 'uploads-and-media',\n dependsOn: [A.verifyV1Pictures, A.recordCutoverLive],\n orderedAfter: [],\n instructions:\n 'For each source the picture verification reported, re-upload the image through its control — Reupload badge for an award, the picture managers for a league, the landing page, or a venue. In a rehearsal, record that this is production-only.',\n noReturnBoundary: null,\n },\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointPaymentCredentialsRetired,\n title: 'Retire the payment-service credentials',\n summary:\n 'V2 binds no payment-service credential, so once it is live the three V1 binds are live credentials with no reader.',\n owningStep: 'secret-management',\n dependsOn: [A.recordCutoverLive],\n orderedAfter: [],\n instructions:\n 'Production only, once V2 is live there: revoke the payment service’s secret key and disable its webhook endpoint in its dashboard, then destroy the three secrets V1 binds for it — its secret key, its webhook secret, and APP_URL — in Secret Manager in both Firebase projects. In a rehearsal, record that this is production-only.',\n noReturnBoundary: 'The secret key revocation.',\n },\n {\n kind: 'operatorCheckpoint',\n id: A.checkpointServiceAccountKeyRevoked,\n title: 'Revoke the obsolete production service-account key',\n summary:\n 'No script reads the local production key once the export script runs on the signed-in CLI credentials; revoking it makes every copy of it worthless.',\n owningStep: 'secret-management',\n dependsOn: [A.checkpointV1FirestoreExport],\n orderedAfter: [A.recordCutoverLive],\n instructions:\n 'Run the export script on Application Default Credentials against the production project named explicitly, then revoke the q-sports-prod service-account key in the Google Cloud console and delete serviceAccount.json from the machine. No replacement key is minted. In a rehearsal, record that this is production-only.',\n noReturnBoundary: 'The key revocation.',\n },\n];\n\nexport const MIGRATION_STEP_BY_ID: ReadonlyMap<MigrationActionId, MigrationStep> = new Map(\n MIGRATION_CUTOVER_MANIFEST.map((step) => [step.id, step]),\n);\n\nexport function migrationStepsOfKind<K extends MigrationStepKind>(\n kind: K,\n): Extract<MigrationStep, { kind: K }>[] {\n return MIGRATION_CUTOVER_MANIFEST.filter(\n (step): step is Extract<MigrationStep, { kind: K }> => step.kind === kind,\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"football-scoring.d.ts","sourceRoot":"","sources":["../../src/sports/football-scoring.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAYrF,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EAOL,KAAK,YAAY,EAIlB,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,KAAK,UAAU,EAEf,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,qBAAqB,IAAI,iBAAiB,CAEzD;AAoED,eAAO,MAAM,gBAAgB,EAAE,YAqB9B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;CAKgC,CAAC;AAEnE,eAAO,MAAM,qBAAqB;;;;;CAG8B,CAAC;AAEjE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,qBAAqB,GAC7B,MAAM,CASR;AAED,eAAO,MAAM,mBAAmB,EAAE,UAGjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,sBAGpC,CAAC;AAaF,eAAO,MAAM,mBAAmB,EAAE,mBAuBjC,CAAC"}
1
+ {"version":3,"file":"football-scoring.d.ts","sourceRoot":"","sources":["../../src/sports/football-scoring.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAYrF,OAAO,EAIL,KAAK,mBAAmB,EAEzB,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EAOL,KAAK,YAAY,EAIlB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,KAAK,UAAU,EAEf,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,qBAAqB,IAAI,iBAAiB,CAEzD;AAoED,eAAO,MAAM,gBAAgB,EAAE,YAqB9B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;CAKgC,CAAC;AAEnE,eAAO,MAAM,qBAAqB;;;;;CAG8B,CAAC;AAEjE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,qBAAqB,GAC7B,MAAM,CASR;AAED,eAAO,MAAM,mBAAmB,EAAE,UAGjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,sBAGpC,CAAC;AAaF,eAAO,MAAM,mBAAmB,EAAE,mBAuBjC,CAAC"}
@@ -4,7 +4,7 @@ import { FOOTBALL_BULK_EDIT_EVENT_TYPE, FOOTBALL_ONE_POINT_EVENT_TYPE, FOOTBALL_
4
4
  import { bulkEntryCountField, } from './bulk-entry.js';
5
5
  import { buildGameContribution, decideParticipation, } from './contribution.js';
6
6
  import { FINALIZATION_READY, STAT_EVENT_ACCEPTED, isSportStatEventIn, isStatCorrection, refuseStatEvent, } from './scoring.js';
7
- import { describeStoreEvent, formatSignedValue, } from './scoring-display.js';
7
+ import { describeStoreEvent, } from './scoring-display.js';
8
8
  function isFootballEvent(event) {
9
9
  return isSportStatEventIn(FOOTBALL_STAT_EVENT_TYPE_KEYS, event);
10
10
  }
@@ -113,7 +113,7 @@ export function describeFootballEvent(event, resolve) {
113
113
  return event.type;
114
114
  const team = resolve.team(event.teamId);
115
115
  if (event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE) {
116
- return `${team}: ${formatSignedValue(event.value)} points (${FOOTBALL_EVENT_LABELS[event.type].play.toLowerCase()})`;
116
+ return `${FOOTBALL_EVENT_LABELS[event.type].play}: ${team} ${event.previousValue + event.value}`;
117
117
  }
118
118
  return `${team}: ${FOOTBALL_EVENT_LABELS[event.type].play}`;
119
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"football-scoring.js","sourceRoot":"","sources":["../../src/sports/football-scoring.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { FOOTBALL_POINTS_BY_EVENT_TYPE, TEAM_NOT_IN_GAME_MESSAGE } from '../constants/sports.js';\nimport type { FootballTeamStats, GameStatEvent } from '../doc-schemas/game-stats.js';\nimport type { FootballGameStats, GameStats } from '../doc-schemas/sport-game.js';\nimport {\n FOOTBALL_BULK_EDIT_EVENT_TYPE,\n FOOTBALL_ONE_POINT_EVENT_TYPE,\n FOOTBALL_SCORE_EVENT_TYPE_KEYS,\n FOOTBALL_SIX_POINT_EVENT_TYPE,\n FOOTBALL_STAT_EVENT_TYPE_KEYS,\n FOOTBALL_TEAM_STAT_KEYS,\n FOOTBALL_TWO_POINT_EVENT_TYPE,\n} from '../types/sports.js';\nimport type { FootballStatEventType, FootballTeamStatKey } from '../types/sports.js';\nimport {\n bulkEntryCountField,\n type BulkEntryContext,\n type StatEventDraft,\n type TeamScoresBulkEntry,\n type TeamScoresValues,\n} from './bulk-entry.js';\nimport {\n buildGameContribution,\n decideParticipation,\n type ContributionSpec,\n} from './contribution.js';\nimport {\n FINALIZATION_READY,\n STAT_EVENT_ACCEPTED,\n isSportStatEventIn,\n isStatCorrection,\n refuseStatEvent,\n type CorrectableFields,\n type SportScoring,\n type SportStatEventBody,\n type StatCorrectionBody,\n type StatEventBody,\n} from './scoring.js';\nimport {\n describeStoreEvent,\n formatSignedValue,\n type Scoreboard,\n type StatEventLabel,\n type StatEventNameResolver,\n type StatFieldLabels,\n type TeamPointsScoringPanel,\n} from './scoring-display.js';\n\ntype FootballEvent = Extract<SportStatEventBody, { type: FootballStatEventType }>;\n\nfunction isFootballEvent(event: StatEventBody | undefined): event is FootballEvent {\n return isSportStatEventIn(FOOTBALL_STAT_EVENT_TYPE_KEYS, event);\n}\n\nfunction ownStats(state: GameStats): FootballGameStats {\n return state as FootballGameStats;\n}\n\nexport function emptyFootballTeamLine(): FootballTeamStats {\n return Object.fromEntries(FOOTBALL_TEAM_STAT_KEYS.map((key) => [key, 0])) as FootballTeamStats;\n}\n\nfunction teamScoreOf(state: FootballGameStats, teamId: string): number {\n return (state.teamStats[teamId] ?? emptyFootballTeamLine()).score;\n}\n\nfunction pointsOf(event: FootballEvent): number {\n return event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE\n ? event.value\n : FOOTBALL_POINTS_BY_EVENT_TYPE[event.type];\n}\n\nfunction addToScore(stateIn: GameStats, teamId: string, amount: number): FootballGameStats {\n const state = ownStats(stateIn);\n const line = state.teamStats[teamId] ?? emptyFootballTeamLine();\n return {\n teamStats: { ...state.teamStats, [teamId]: { ...line, score: line.score + amount } },\n playerStats: state.playerStats,\n };\n}\n\nconst CORRECTABLE_FIELDS: CorrectableFields = { team: FOOTBALL_TEAM_STAT_KEYS, player: [] };\n\nfunction correctionAmount(event: StatCorrectionBody): number {\n const fields =\n event.playerUserId === undefined ? CORRECTABLE_FIELDS.team : CORRECTABLE_FIELDS.player;\n if (!fields.includes(event.stat)) {\n throw new Error(\n `A football correction cannot change ${event.stat} on a ${event.playerUserId === undefined ? 'team' : 'player'} line.`,\n );\n }\n return event.value;\n}\n\nfunction namesPlayer(event: StatEventBody): boolean {\n return 'playerUserId' in event && event.playerUserId !== undefined;\n}\n\nconst validate: SportScoring['validate'] = (stateIn, event, roster) => {\n if (!isFootballEvent(event)) return refuseStatEvent('eventTypeNotInSport');\n if (!roster.teamIds.includes(event.teamId)) return refuseStatEvent('teamNotInGame');\n if (namesPlayer(event)) return refuseStatEvent('playerNotAllowed');\n if (event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE) {\n if (!Number.isInteger(event.value) || event.value === 0)\n return refuseStatEvent('bulkValueInvalid');\n const score = teamScoreOf(ownStats(stateIn), event.teamId);\n if (score + event.value < 0) return refuseStatEvent('bulkValueInvalid');\n }\n return STAT_EVENT_ACCEPTED;\n};\n\nconst FOOTBALL_CONTRIBUTION: ContributionSpec = {\n playerStatKeys: [],\n teamSeasonPlayerSums: [],\n zeroLineIsNonScoring: false,\n deriveLine: (_kind, line) => line,\n};\n\nconst resolveBulkEntry: NonNullable<SportScoring['resolveBulkEntry']> = (state, submission) => {\n if (submission.type !== FOOTBALL_BULK_EDIT_EVENT_TYPE) return null;\n const { target, ...event } = submission;\n const previousValue = teamScoreOf(ownStats(state), event.teamId);\n const value = target - previousValue;\n return value === 0\n ? { kind: 'unchanged' }\n : { kind: 'change', event: { ...event, value, previousValue } };\n};\n\nexport const FOOTBALL_SCORING: SportScoring = {\n validate,\n resolveBulkEntry,\n apply: (state, event) => {\n if (isStatCorrection(event)) return addToScore(state, event.teamId, correctionAmount(event));\n if (!isFootballEvent(event))\n throw new Error(`The football adapter does not apply ${event.type}.`);\n return addToScore(state, event.teamId, pointsOf(event));\n },\n undo: (state, target) => {\n if (!isFootballEvent(target))\n throw new Error(`The football adapter does not undo ${target.type}.`);\n return addToScore(state, target.teamId, -pointsOf(target));\n },\n deriveLine: FOOTBALL_CONTRIBUTION.deriveLine,\n correctableFields: CORRECTABLE_FIELDS,\n nextRound: () => null,\n finalizationReadiness: () => FINALIZATION_READY,\n participation: (state, rosterPlayerIds, absentRosterPlayerIds) =>\n decideParticipation(FOOTBALL_CONTRIBUTION, state, rosterPlayerIds, absentRosterPlayerIds),\n contribution: (game) => buildGameContribution(FOOTBALL_CONTRIBUTION, game),\n};\n\nexport const FOOTBALL_EVENT_LABELS = {\n [FOOTBALL_SIX_POINT_EVENT_TYPE]: { button: '+6', play: '6 points' },\n [FOOTBALL_TWO_POINT_EVENT_TYPE]: { button: '+2', play: '2 points' },\n [FOOTBALL_ONE_POINT_EVENT_TYPE]: { button: '+1', play: '1 point' },\n [FOOTBALL_BULK_EDIT_EVENT_TYPE]: { button: 'Final scores', play: 'Final score entry' },\n} as const satisfies Record<FootballStatEventType, StatEventLabel>;\n\nexport const FOOTBALL_FIELD_LABELS = {\n team: { score: 'Score' },\n player: {},\n} as const satisfies StatFieldLabels<FootballTeamStatKey, never>;\n\nexport function describeFootballEvent(\n event: GameStatEvent,\n resolve: StatEventNameResolver,\n): string {\n const storeEvent = describeStoreEvent(event, resolve, FOOTBALL_FIELD_LABELS);\n if (storeEvent !== null) return storeEvent;\n if (!isFootballEvent(event)) return event.type;\n const team = resolve.team(event.teamId);\n if (event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE) {\n return `${team}: ${formatSignedValue(event.value)} points (${FOOTBALL_EVENT_LABELS[event.type].play.toLowerCase()})`;\n }\n return `${team}: ${FOOTBALL_EVENT_LABELS[event.type].play}`;\n}\n\nexport const FOOTBALL_SCOREBOARD: Scoreboard = {\n figures: [{ id: 'points', label: 'Points', value: (teamLine) => teamLine.score }],\n jumpBall: false,\n};\n\nexport const FOOTBALL_SCORING_PANEL: TeamPointsScoringPanel = {\n kind: 'teamPoints',\n eventTypes: FOOTBALL_SCORE_EVENT_TYPE_KEYS,\n};\n\nfunction scoreDrafts(values: TeamScoresValues, context: BulkEntryContext): StatEventDraft[] {\n const state = ownStats(context.state);\n const drafts: StatEventDraft[] = [];\n for (const teamId of context.game.teamIds) {\n const entered = values.scores[teamId];\n if (entered === undefined || entered === teamScoreOf(state, teamId)) continue;\n drafts.push({ type: FOOTBALL_BULK_EDIT_EVENT_TYPE, teamId, target: entered });\n }\n return drafts;\n}\n\nexport const FOOTBALL_BULK_ENTRY: TeamScoresBulkEntry = {\n kind: 'teamScores',\n formDefaults: (context) => ({\n scores: Object.fromEntries(\n context.game.teamIds.map((teamId) => [teamId, teamScoreOf(ownStats(context.state), teamId)]),\n ),\n }),\n formSchema: (context) => {\n const teams = new Set(context.game.teamIds);\n return z\n .object({ scores: z.record(z.string(), bulkEntryCountField) })\n .superRefine((values, issues) => {\n for (const teamId of Object.keys(values.scores)) {\n if (!teams.has(teamId))\n issues.addIssue({\n code: 'custom',\n path: ['scores', teamId],\n message: TEAM_NOT_IN_GAME_MESSAGE,\n });\n }\n });\n },\n toEvents: scoreDrafts,\n};\n"]}
1
+ {"version":3,"file":"football-scoring.js","sourceRoot":"","sources":["../../src/sports/football-scoring.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { FOOTBALL_POINTS_BY_EVENT_TYPE, TEAM_NOT_IN_GAME_MESSAGE } from '../constants/sports.js';\nimport type { FootballTeamStats, GameStatEvent } from '../doc-schemas/game-stats.js';\nimport type { FootballGameStats, GameStats } from '../doc-schemas/sport-game.js';\nimport {\n FOOTBALL_BULK_EDIT_EVENT_TYPE,\n FOOTBALL_ONE_POINT_EVENT_TYPE,\n FOOTBALL_SCORE_EVENT_TYPE_KEYS,\n FOOTBALL_SIX_POINT_EVENT_TYPE,\n FOOTBALL_STAT_EVENT_TYPE_KEYS,\n FOOTBALL_TEAM_STAT_KEYS,\n FOOTBALL_TWO_POINT_EVENT_TYPE,\n} from '../types/sports.js';\nimport type { FootballStatEventType, FootballTeamStatKey } from '../types/sports.js';\nimport {\n bulkEntryCountField,\n type BulkEntryContext,\n type StatEventDraft,\n type TeamScoresBulkEntry,\n type TeamScoresValues,\n} from './bulk-entry.js';\nimport {\n buildGameContribution,\n decideParticipation,\n type ContributionSpec,\n} from './contribution.js';\nimport {\n FINALIZATION_READY,\n STAT_EVENT_ACCEPTED,\n isSportStatEventIn,\n isStatCorrection,\n refuseStatEvent,\n type CorrectableFields,\n type SportScoring,\n type SportStatEventBody,\n type StatCorrectionBody,\n type StatEventBody,\n} from './scoring.js';\nimport {\n describeStoreEvent,\n type Scoreboard,\n type StatEventLabel,\n type StatEventNameResolver,\n type StatFieldLabels,\n type TeamPointsScoringPanel,\n} from './scoring-display.js';\n\ntype FootballEvent = Extract<SportStatEventBody, { type: FootballStatEventType }>;\n\nfunction isFootballEvent(event: StatEventBody | undefined): event is FootballEvent {\n return isSportStatEventIn(FOOTBALL_STAT_EVENT_TYPE_KEYS, event);\n}\n\nfunction ownStats(state: GameStats): FootballGameStats {\n return state as FootballGameStats;\n}\n\nexport function emptyFootballTeamLine(): FootballTeamStats {\n return Object.fromEntries(FOOTBALL_TEAM_STAT_KEYS.map((key) => [key, 0])) as FootballTeamStats;\n}\n\nfunction teamScoreOf(state: FootballGameStats, teamId: string): number {\n return (state.teamStats[teamId] ?? emptyFootballTeamLine()).score;\n}\n\nfunction pointsOf(event: FootballEvent): number {\n return event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE\n ? event.value\n : FOOTBALL_POINTS_BY_EVENT_TYPE[event.type];\n}\n\nfunction addToScore(stateIn: GameStats, teamId: string, amount: number): FootballGameStats {\n const state = ownStats(stateIn);\n const line = state.teamStats[teamId] ?? emptyFootballTeamLine();\n return {\n teamStats: { ...state.teamStats, [teamId]: { ...line, score: line.score + amount } },\n playerStats: state.playerStats,\n };\n}\n\nconst CORRECTABLE_FIELDS: CorrectableFields = { team: FOOTBALL_TEAM_STAT_KEYS, player: [] };\n\nfunction correctionAmount(event: StatCorrectionBody): number {\n const fields =\n event.playerUserId === undefined ? CORRECTABLE_FIELDS.team : CORRECTABLE_FIELDS.player;\n if (!fields.includes(event.stat)) {\n throw new Error(\n `A football correction cannot change ${event.stat} on a ${event.playerUserId === undefined ? 'team' : 'player'} line.`,\n );\n }\n return event.value;\n}\n\nfunction namesPlayer(event: StatEventBody): boolean {\n return 'playerUserId' in event && event.playerUserId !== undefined;\n}\n\nconst validate: SportScoring['validate'] = (stateIn, event, roster) => {\n if (!isFootballEvent(event)) return refuseStatEvent('eventTypeNotInSport');\n if (!roster.teamIds.includes(event.teamId)) return refuseStatEvent('teamNotInGame');\n if (namesPlayer(event)) return refuseStatEvent('playerNotAllowed');\n if (event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE) {\n if (!Number.isInteger(event.value) || event.value === 0)\n return refuseStatEvent('bulkValueInvalid');\n const score = teamScoreOf(ownStats(stateIn), event.teamId);\n if (score + event.value < 0) return refuseStatEvent('bulkValueInvalid');\n }\n return STAT_EVENT_ACCEPTED;\n};\n\nconst FOOTBALL_CONTRIBUTION: ContributionSpec = {\n playerStatKeys: [],\n teamSeasonPlayerSums: [],\n zeroLineIsNonScoring: false,\n deriveLine: (_kind, line) => line,\n};\n\nconst resolveBulkEntry: NonNullable<SportScoring['resolveBulkEntry']> = (state, submission) => {\n if (submission.type !== FOOTBALL_BULK_EDIT_EVENT_TYPE) return null;\n const { target, ...event } = submission;\n const previousValue = teamScoreOf(ownStats(state), event.teamId);\n const value = target - previousValue;\n return value === 0\n ? { kind: 'unchanged' }\n : { kind: 'change', event: { ...event, value, previousValue } };\n};\n\nexport const FOOTBALL_SCORING: SportScoring = {\n validate,\n resolveBulkEntry,\n apply: (state, event) => {\n if (isStatCorrection(event)) return addToScore(state, event.teamId, correctionAmount(event));\n if (!isFootballEvent(event))\n throw new Error(`The football adapter does not apply ${event.type}.`);\n return addToScore(state, event.teamId, pointsOf(event));\n },\n undo: (state, target) => {\n if (!isFootballEvent(target))\n throw new Error(`The football adapter does not undo ${target.type}.`);\n return addToScore(state, target.teamId, -pointsOf(target));\n },\n deriveLine: FOOTBALL_CONTRIBUTION.deriveLine,\n correctableFields: CORRECTABLE_FIELDS,\n nextRound: () => null,\n finalizationReadiness: () => FINALIZATION_READY,\n participation: (state, rosterPlayerIds, absentRosterPlayerIds) =>\n decideParticipation(FOOTBALL_CONTRIBUTION, state, rosterPlayerIds, absentRosterPlayerIds),\n contribution: (game) => buildGameContribution(FOOTBALL_CONTRIBUTION, game),\n};\n\nexport const FOOTBALL_EVENT_LABELS = {\n [FOOTBALL_SIX_POINT_EVENT_TYPE]: { button: '+6', play: '6 points' },\n [FOOTBALL_TWO_POINT_EVENT_TYPE]: { button: '+2', play: '2 points' },\n [FOOTBALL_ONE_POINT_EVENT_TYPE]: { button: '+1', play: '1 point' },\n [FOOTBALL_BULK_EDIT_EVENT_TYPE]: { button: 'Final scores', play: 'Final score entry' },\n} as const satisfies Record<FootballStatEventType, StatEventLabel>;\n\nexport const FOOTBALL_FIELD_LABELS = {\n team: { score: 'Score' },\n player: {},\n} as const satisfies StatFieldLabels<FootballTeamStatKey, never>;\n\nexport function describeFootballEvent(\n event: GameStatEvent,\n resolve: StatEventNameResolver,\n): string {\n const storeEvent = describeStoreEvent(event, resolve, FOOTBALL_FIELD_LABELS);\n if (storeEvent !== null) return storeEvent;\n if (!isFootballEvent(event)) return event.type;\n const team = resolve.team(event.teamId);\n if (event.type === FOOTBALL_BULK_EDIT_EVENT_TYPE) {\n return `${FOOTBALL_EVENT_LABELS[event.type].play}: ${team} ${event.previousValue + event.value}`;\n }\n return `${team}: ${FOOTBALL_EVENT_LABELS[event.type].play}`;\n}\n\nexport const FOOTBALL_SCOREBOARD: Scoreboard = {\n figures: [{ id: 'points', label: 'Points', value: (teamLine) => teamLine.score }],\n jumpBall: false,\n};\n\nexport const FOOTBALL_SCORING_PANEL: TeamPointsScoringPanel = {\n kind: 'teamPoints',\n eventTypes: FOOTBALL_SCORE_EVENT_TYPE_KEYS,\n};\n\nfunction scoreDrafts(values: TeamScoresValues, context: BulkEntryContext): StatEventDraft[] {\n const state = ownStats(context.state);\n const drafts: StatEventDraft[] = [];\n for (const teamId of context.game.teamIds) {\n const entered = values.scores[teamId];\n if (entered === undefined || entered === teamScoreOf(state, teamId)) continue;\n drafts.push({ type: FOOTBALL_BULK_EDIT_EVENT_TYPE, teamId, target: entered });\n }\n return drafts;\n}\n\nexport const FOOTBALL_BULK_ENTRY: TeamScoresBulkEntry = {\n kind: 'teamScores',\n formDefaults: (context) => ({\n scores: Object.fromEntries(\n context.game.teamIds.map((teamId) => [teamId, teamScoreOf(ownStats(context.state), teamId)]),\n ),\n }),\n formSchema: (context) => {\n const teams = new Set(context.game.teamIds);\n return z\n .object({ scores: z.record(z.string(), bulkEntryCountField) })\n .superRefine((values, issues) => {\n for (const teamId of Object.keys(values.scores)) {\n if (!teams.has(teamId))\n issues.addIssue({\n code: 'custom',\n path: ['scores', teamId],\n message: TEAM_NOT_IN_GAME_MESSAGE,\n });\n }\n });\n },\n toEvents: scoreDrafts,\n};\n"]}
@@ -1,5 +1,7 @@
1
1
  export declare function toLeagueDayKey(epochMs: number): string;
2
+ export declare function calendarDayDate(dayKey: string): Date | null;
2
3
  export declare function addCalendarDays(dayKey: string, days: number): string;
4
+ export declare function formatGameDay(dayKey: string): string;
3
5
  export declare function toLeagueTimeOfDay(epochMs: number): string;
4
6
  export declare function leagueInstantOf(dayKey: string, timeOfDay: string): number;
5
7
  //# sourceMappingURL=league-calendar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"league-calendar.d.ts","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"AAYA,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpE;AAkCD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAwBzE"}
1
+ {"version":3,"file":"league-calendar.d.ts","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"AAYA,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAGD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAG3D;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpE;AAYD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGpD;AAkCD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAwBzE"}
@@ -10,13 +10,31 @@ const DAY_MS = 24 * 60 * 60 * 1000;
10
10
  export function toLeagueDayKey(epochMs) {
11
11
  return LEAGUE_DAY_FORMAT.format(new Date(epochMs));
12
12
  }
13
- export function addCalendarDays(dayKey, days) {
13
+ // A stored calendar day read as its midnight in UTC, or null when it is not a day.
14
+ export function calendarDayDate(dayKey) {
14
15
  const day = new Date(`${dayKey}T00:00:00.000Z`);
15
- if (Number.isNaN(day.getTime())) {
16
+ return Number.isNaN(day.getTime()) ? null : day;
17
+ }
18
+ export function addCalendarDays(dayKey, days) {
19
+ const day = calendarDayDate(dayKey);
20
+ if (day === null) {
16
21
  throw new RangeError(`Not a calendar date: '${dayKey}'.`);
17
22
  }
18
23
  return new Date(day.getTime() + days * DAY_MS).toISOString().slice(0, 10);
19
24
  }
25
+ // In UTC, the zone `calendarDayDate` reads a calendar day in.
26
+ const GAME_DAY_FORMAT = new Intl.DateTimeFormat('en-US', {
27
+ timeZone: 'UTC',
28
+ weekday: 'short',
29
+ month: 'short',
30
+ day: 'numeric',
31
+ });
32
+ // A game's calendar day as every schedule shows it ("Mon, Jan 5"); a value that is not a day
33
+ // shows as stored.
34
+ export function formatGameDay(dayKey) {
35
+ const day = calendarDayDate(dayKey);
36
+ return day ? GAME_DAY_FORMAT.format(day) : dayKey;
37
+ }
20
38
  // `h23` keeps midnight at hour 0.
21
39
  const LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {
22
40
  timeZone: LEAGUE_TIME_ZONE,
@@ -1 +1 @@
1
- {"version":3,"file":"league-calendar.js","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { LEAGUE_TIME_ZONE } from '../constants/business.js';\n\n// `en-CA` formats a date as `YYYY-MM-DD`, the stored calendar-date shape.\nconst LEAGUE_DAY_FORMAT = new Intl.DateTimeFormat('en-CA', {\n timeZone: LEAGUE_TIME_ZONE,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n});\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport function toLeagueDayKey(epochMs: number): string {\n return LEAGUE_DAY_FORMAT.format(new Date(epochMs));\n}\n\nexport function addCalendarDays(dayKey: string, days: number): string {\n const day = new Date(`${dayKey}T00:00:00.000Z`);\n if (Number.isNaN(day.getTime())) {\n throw new RangeError(`Not a calendar date: '${dayKey}'.`);\n }\n return new Date(day.getTime() + days * DAY_MS).toISOString().slice(0, 10);\n}\n\n// `h23` keeps midnight at hour 0.\nconst LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {\n timeZone: LEAGUE_TIME_ZONE,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n});\n\nconst CALENDAR_DAY_SHAPE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst TIME_OF_DAY_SHAPE = /^([01]\\d|2[0-3]):([0-5]\\d)$/;\n\nfunction leagueWallClockAsUtc(epochMs: number): number {\n const parts = Object.fromEntries(\n LEAGUE_WALL_CLOCK_FORMAT.formatToParts(new Date(epochMs)).map((part) => [\n part.type,\n part.value,\n ]),\n );\n return Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n );\n}\n\nexport function toLeagueTimeOfDay(epochMs: number): string {\n const wallClock = new Date(leagueWallClockAsUtc(epochMs));\n const hours = String(wallClock.getUTCHours()).padStart(2, '0');\n const minutes = String(wallClock.getUTCMinutes()).padStart(2, '0');\n return `${hours}:${minutes}`;\n}\n\nexport function leagueInstantOf(dayKey: string, timeOfDay: string): number {\n const day = CALENDAR_DAY_SHAPE.exec(dayKey);\n const time = TIME_OF_DAY_SHAPE.exec(timeOfDay);\n if (!day || !time)\n throw new RangeError(`Not a calendar day and time of day: '${dayKey}' '${timeOfDay}'.`);\n const wallClock = Date.UTC(\n Number(day[1]),\n Number(day[2]) - 1,\n Number(day[3]),\n Number(time[1]),\n Number(time[2]),\n );\n if (new Date(wallClock).toISOString().slice(0, 10) !== dayKey) {\n throw new RangeError(`Not a calendar day: '${dayKey}'.`);\n }\n // The offset at the wall-clock reading taken as UTC is within a day of the right one; read again at\n // the instant that offset gives, so a reading on the other side of a change settles on its own.\n const firstGuess = wallClock - (leagueWallClockAsUtc(wallClock) - wallClock);\n const instant = wallClock - (leagueWallClockAsUtc(firstGuess) - firstGuess);\n // A reading the clocks skip forward over settles on another hour; only a real one reads back.\n if (toLeagueDayKey(instant) !== dayKey || toLeagueTimeOfDay(instant) !== timeOfDay) {\n throw new RangeError(`Not a time the league's clocks show: '${dayKey}' '${timeOfDay}'.`);\n }\n return instant;\n}\n"]}
1
+ {"version":3,"file":"league-calendar.js","sourceRoot":"","sources":["../../src/utils/league-calendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { LEAGUE_TIME_ZONE } from '../constants/business.js';\n\n// `en-CA` formats a date as `YYYY-MM-DD`, the stored calendar-date shape.\nconst LEAGUE_DAY_FORMAT = new Intl.DateTimeFormat('en-CA', {\n timeZone: LEAGUE_TIME_ZONE,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n});\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport function toLeagueDayKey(epochMs: number): string {\n return LEAGUE_DAY_FORMAT.format(new Date(epochMs));\n}\n\n// A stored calendar day read as its midnight in UTC, or null when it is not a day.\nexport function calendarDayDate(dayKey: string): Date | null {\n const day = new Date(`${dayKey}T00:00:00.000Z`);\n return Number.isNaN(day.getTime()) ? null : day;\n}\n\nexport function addCalendarDays(dayKey: string, days: number): string {\n const day = calendarDayDate(dayKey);\n if (day === null) {\n throw new RangeError(`Not a calendar date: '${dayKey}'.`);\n }\n return new Date(day.getTime() + days * DAY_MS).toISOString().slice(0, 10);\n}\n\n// In UTC, the zone `calendarDayDate` reads a calendar day in.\nconst GAME_DAY_FORMAT = new Intl.DateTimeFormat('en-US', {\n timeZone: 'UTC',\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n});\n\n// A game's calendar day as every schedule shows it (\"Mon, Jan 5\"); a value that is not a day\n// shows as stored.\nexport function formatGameDay(dayKey: string): string {\n const day = calendarDayDate(dayKey);\n return day ? GAME_DAY_FORMAT.format(day) : dayKey;\n}\n\n// `h23` keeps midnight at hour 0.\nconst LEAGUE_WALL_CLOCK_FORMAT = new Intl.DateTimeFormat('en-US', {\n timeZone: LEAGUE_TIME_ZONE,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n});\n\nconst CALENDAR_DAY_SHAPE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst TIME_OF_DAY_SHAPE = /^([01]\\d|2[0-3]):([0-5]\\d)$/;\n\nfunction leagueWallClockAsUtc(epochMs: number): number {\n const parts = Object.fromEntries(\n LEAGUE_WALL_CLOCK_FORMAT.formatToParts(new Date(epochMs)).map((part) => [\n part.type,\n part.value,\n ]),\n );\n return Date.UTC(\n Number(parts.year),\n Number(parts.month) - 1,\n Number(parts.day),\n Number(parts.hour),\n Number(parts.minute),\n Number(parts.second),\n );\n}\n\nexport function toLeagueTimeOfDay(epochMs: number): string {\n const wallClock = new Date(leagueWallClockAsUtc(epochMs));\n const hours = String(wallClock.getUTCHours()).padStart(2, '0');\n const minutes = String(wallClock.getUTCMinutes()).padStart(2, '0');\n return `${hours}:${minutes}`;\n}\n\nexport function leagueInstantOf(dayKey: string, timeOfDay: string): number {\n const day = CALENDAR_DAY_SHAPE.exec(dayKey);\n const time = TIME_OF_DAY_SHAPE.exec(timeOfDay);\n if (!day || !time)\n throw new RangeError(`Not a calendar day and time of day: '${dayKey}' '${timeOfDay}'.`);\n const wallClock = Date.UTC(\n Number(day[1]),\n Number(day[2]) - 1,\n Number(day[3]),\n Number(time[1]),\n Number(time[2]),\n );\n if (new Date(wallClock).toISOString().slice(0, 10) !== dayKey) {\n throw new RangeError(`Not a calendar day: '${dayKey}'.`);\n }\n // The offset at the wall-clock reading taken as UTC is within a day of the right one; read again at\n // the instant that offset gives, so a reading on the other side of a change settles on its own.\n const firstGuess = wallClock - (leagueWallClockAsUtc(wallClock) - wallClock);\n const instant = wallClock - (leagueWallClockAsUtc(firstGuess) - firstGuess);\n // A reading the clocks skip forward over settles on another hour; only a real one reads back.\n if (toLeagueDayKey(instant) !== dayKey || toLeagueTimeOfDay(instant) !== timeOfDay) {\n throw new RangeError(`Not a time the league's clocks show: '${dayKey}' '${timeOfDay}'.`);\n }\n return instant;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/q-core",
3
- "version": "0.1.61",
3
+ "version": "0.1.63",
4
4
  "description": "Core types, Firestore path constants, zod schemas, and shared constants for Q-Sports",
5
5
  "repository": {
6
6
  "type": "git",