@ttt-productions/q-core 0.1.26 → 0.1.28

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.
@@ -1,3 +1,3 @@
1
- export declare const ADMIN_VIEWS: readonly ["dashboard", "leagues", "people", "stats", "setup", "migration"];
1
+ export declare const ADMIN_VIEWS: readonly ["dashboard", "leagues", "users", "roles", "hardware", "statsReports", "fixStats", "landingPage", "appConfig", "gameLocations", "waiverTemplates", "awards", "capacityLimits", "migration"];
2
2
  export type AdminView = (typeof ADMIN_VIEWS)[number];
3
3
  //# sourceMappingURL=admin-views.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-views.d.ts","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,4EAOd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"admin-views.d.ts","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,sMAed,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -1,11 +1,20 @@
1
1
  // The admin area's views. The admin area is one page, and each view is chosen by its `?view=` slug;
2
- // the dashboard is the bare page. Both roots link into a view, so the slugs are declared here once.
2
+ // the dashboard is the bare page. Every screen is its own view, listed once in the admin sidebar, so
3
+ // both roots link straight to it; the slugs are declared here once.
3
4
  export const ADMIN_VIEWS = [
4
5
  'dashboard',
5
6
  'leagues',
6
- 'people',
7
- 'stats',
8
- 'setup',
7
+ 'users',
8
+ 'roles',
9
+ 'hardware',
10
+ 'statsReports',
11
+ 'fixStats',
12
+ 'landingPage',
13
+ 'appConfig',
14
+ 'gameLocations',
15
+ 'waiverTemplates',
16
+ 'awards',
17
+ 'capacityLimits',
9
18
  'migration',
10
19
  ];
11
20
  //# sourceMappingURL=admin-views.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-views.js","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,oGAAoG;AAEpG,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,SAAS;IACT,QAAQ;IACR,OAAO;IACP,OAAO;IACP,WAAW;CACH,CAAC","sourcesContent":["// The admin area's views. The admin area is one page, and each view is chosen by its `?view=` slug;\n// the dashboard is the bare page. Both roots link into a view, so the slugs are declared here once.\n\nexport const ADMIN_VIEWS = [\n 'dashboard',\n 'leagues',\n 'people',\n 'stats',\n 'setup',\n 'migration',\n] as const;\n\nexport type AdminView = (typeof ADMIN_VIEWS)[number];\n"]}
1
+ {"version":3,"file":"admin-views.js","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,qGAAqG;AACrG,oEAAoE;AAEpE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,SAAS;IACT,OAAO;IACP,OAAO;IACP,UAAU;IACV,cAAc;IACd,UAAU;IACV,aAAa;IACb,WAAW;IACX,eAAe;IACf,iBAAiB;IACjB,QAAQ;IACR,gBAAgB;IAChB,WAAW;CACH,CAAC","sourcesContent":["// The admin area's views. The admin area is one page, and each view is chosen by its `?view=` slug;\n// the dashboard is the bare page. Every screen is its own view, listed once in the admin sidebar, so\n// both roots link straight to it; the slugs are declared here once.\n\nexport const ADMIN_VIEWS = [\n 'dashboard',\n 'leagues',\n 'users',\n 'roles',\n 'hardware',\n 'statsReports',\n 'fixStats',\n 'landingPage',\n 'appConfig',\n 'gameLocations',\n 'waiverTemplates',\n 'awards',\n 'capacityLimits',\n 'migration',\n] as const;\n\nexport type AdminView = (typeof ADMIN_VIEWS)[number];\n"]}
@@ -95,7 +95,7 @@ export declare const AuditActorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
95
95
  actorMode: z.ZodEnum<{
96
96
  user: "user";
97
97
  system: "system";
98
- teamManager: "teamManager";
98
+ teammateUser: "teammateUser";
99
99
  }>;
100
100
  }, z.core.$strict>, z.ZodObject<{
101
101
  uid: z.ZodNullable<z.ZodString>;
@@ -212,7 +212,7 @@ export declare const AuditEventSchema: z.ZodObject<{
212
212
  actorMode: z.ZodEnum<{
213
213
  user: "user";
214
214
  system: "system";
215
- teamManager: "teamManager";
215
+ teammateUser: "teammateUser";
216
216
  }>;
217
217
  }, z.core.$strict>, z.ZodObject<{
218
218
  uid: z.ZodNullable<z.ZodString>;
@@ -2624,7 +2624,7 @@ export declare const COLLECTION_SCHEMAS: {
2624
2624
  actorMode: z.ZodEnum<{
2625
2625
  user: "user";
2626
2626
  system: "system";
2627
- teamManager: "teamManager";
2627
+ teammateUser: "teammateUser";
2628
2628
  }>;
2629
2629
  }, z.core.$strict>, z.ZodObject<{
2630
2630
  uid: z.ZodNullable<z.ZodString>;
@@ -4,7 +4,7 @@ import type { SportKey } from '../types/sports.js';
4
4
  export declare const HALL_OF_FAME_SPORT_PARAM = "sport";
5
5
  /** The query-string key the admin page's views live under. */
6
6
  export declare const ADMIN_VIEW_PARAM = "view";
7
- /** The query-string key a view's sections live under. */
7
+ /** The query-string key a league workspace's sections live under. */
8
8
  export declare const ADMIN_SECTION_PARAM = "section";
9
9
  /** The query-string key the Leagues view names the league whose workspace is open under. */
10
10
  export declare const ADMIN_LEAGUE_PARAM = "league";
@@ -30,8 +30,8 @@ export declare const APP_ROUTES: {
30
30
  readonly sportGame: (leagueId: string, gameId: string) => string;
31
31
  /** A game's scoring page, where a scorer records its stats. */
32
32
  readonly sportGameScoring: (leagueId: string, gameId: string) => string;
33
- /** An admin view, on one of its sections when one is named; the dashboard is the bare page. */
34
- readonly admin: (view?: AdminView, section?: string) => string;
33
+ /** An admin view; the dashboard is the bare page. */
34
+ readonly admin: (view?: AdminView) => string;
35
35
  /** A league's admin workspace, on one of its sections when one is named. */
36
36
  readonly adminLeague: (leagueId: string, section?: AdminLeagueWorkspaceSection) => string;
37
37
  /** One team's admin view, inside its league's workspace on the Teams section. */
@@ -1 +1 @@
1
- {"version":3,"file":"app-routes.d.ts","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAEhD,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAIvC,eAAO,MAAM,mCAAmC,2DAKtC,CAAC;AACX,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,mCAAmC,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/F,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,aAAmD,CAAC;AAExF,8FAA8F;AAC9F,eAAO,MAAM,oBAAoB,UAAgD,CAAC;AAElF,8EAA8E;AAC9E,eAAO,MAAM,0BAA0B,gBAAsD,CAAC;AAoB9F,eAAO,MAAM,UAAU;yBACX,MAAM;kCACK,QAAQ,KAAG,MAAM;8BAEvB,MAAM;6BACP,MAAM;0BACT,MAAM;4BACF,MAAM,KAAG,MAAM;gCACX,MAAM,KAAG,MAAM;oCACX,MAAM,UAAU,MAAM,KAAG,MAAM;mCAEhC,MAAM,UAAU,MAAM,KAAG,MAAM;IAErD,+DAA+D;0CAClC,MAAM,UAAU,MAAM,KAAG,MAAM;IAE5D,+FAA+F;4BAChF,SAAS,YAAY,MAAM,KAAG,MAAM;IAKnD,4EAA4E;qCACpD,MAAM,YAAY,2BAA2B,KAAG,MAAM;IAE9E,iFAAiF;yCACrD,MAAM,UAAU,MAAM,KAAG,MAAM;CAKnD,CAAC"}
1
+ {"version":3,"file":"app-routes.d.ts","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAEhD,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAIvC,eAAO,MAAM,mCAAmC,2DAKtC,CAAC;AACX,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,mCAAmC,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/F,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,aAAmD,CAAC;AAExF,8FAA8F;AAC9F,eAAO,MAAM,oBAAoB,UAAgD,CAAC;AAElF,8EAA8E;AAC9E,eAAO,MAAM,0BAA0B,gBAAsD,CAAC;AAoB9F,eAAO,MAAM,UAAU;yBACX,MAAM;kCACK,QAAQ,KAAG,MAAM;8BAEvB,MAAM;6BACP,MAAM;0BACT,MAAM;4BACF,MAAM,KAAG,MAAM;gCACX,MAAM,KAAG,MAAM;oCACX,MAAM,UAAU,MAAM,KAAG,MAAM;mCAEhC,MAAM,UAAU,MAAM,KAAG,MAAM;IAErD,+DAA+D;0CAClC,MAAM,UAAU,MAAM,KAAG,MAAM;IAE5D,qDAAqD;4BACtC,SAAS,KAAG,MAAM;IAKjC,4EAA4E;qCACpD,MAAM,YAAY,2BAA2B,KAAG,MAAM;IAE9E,iFAAiF;yCACrD,MAAM,UAAU,MAAM,KAAG,MAAM;CAKnD,CAAC"}
@@ -6,7 +6,7 @@
6
6
  export const HALL_OF_FAME_SPORT_PARAM = 'sport';
7
7
  /** The query-string key the admin page's views live under. */
8
8
  export const ADMIN_VIEW_PARAM = 'view';
9
- /** The query-string key a view's sections live under. */
9
+ /** The query-string key a league workspace's sections live under. */
10
10
  export const ADMIN_SECTION_PARAM = 'section';
11
11
  /** The query-string key the Leagues view names the league whose workspace is open under. */
12
12
  export const ADMIN_LEAGUE_PARAM = 'league';
@@ -51,11 +51,8 @@ export const APP_ROUTES = {
51
51
  sportGame: (leagueId, gameId) => `/league/${enc(leagueId)}/game/${enc(gameId)}`,
52
52
  /** A game's scoring page, where a scorer records its stats. */
53
53
  sportGameScoring: (leagueId, gameId) => `/league/${enc(leagueId)}/game/${enc(gameId)}/stats`,
54
- /** An admin view, on one of its sections when one is named; the dashboard is the bare page. */
55
- admin: (view, section) => withQuery('/admin', [
56
- ...(view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view]]),
57
- ...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section]]),
58
- ]),
54
+ /** An admin view; the dashboard is the bare page. */
55
+ admin: (view) => withQuery('/admin', view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view]]),
59
56
  /** A league's admin workspace, on one of its sections when one is named. */
60
57
  adminLeague: (leagueId, section) => withQuery('/admin', adminLeagueEntries(leagueId, section)),
61
58
  /** One team's admin view, inside its league's workspace on the Teams section. */
@@ -1 +1 @@
1
- {"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"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","sourcesContent":["// Every app page address, declared once and built through `APP_ROUTES`. Both roots build these\n// links: the server writes one onto an admin notification card, and the app links to every one of\n// them, so each address shape has one change point (RULE-STD-ARCH-101). Every id is encoded, so an id\n// holding a `/` or a space still addresses its own page.\n\nimport type { AdminView } from '../constants/admin-views.js';\nimport type { SportKey } from '../types/sports.js';\n\n/** The query-string key the hall of fame names its sport under. */\nexport const HALL_OF_FAME_SPORT_PARAM = 'sport';\n\n/** The query-string key the admin page's views live under. */\nexport const ADMIN_VIEW_PARAM = 'view';\n\n/** The query-string key a view's sections live under. */\nexport const ADMIN_SECTION_PARAM = 'section';\n\n/** The query-string key the Leagues view names the league whose workspace is open under. */\nexport const ADMIN_LEAGUE_PARAM = 'league';\n\n/** The query-string key the Teams section names the team whose admin view is open under. */\nexport const ADMIN_TEAM_PARAM = 'team';\n\n// The sections a league's admin workspace is addressed by. The workspace declares which of them it\n// has built as tabs; a link may name any of them.\nexport const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS = [\n 'settings',\n 'schedule',\n 'teams',\n 'free-agents',\n] as const;\nexport type AdminLeagueWorkspaceSection = (typeof ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS)[number];\n\n/** The league workspace's section holding the league's weeks and games. */\nexport const LEAGUE_SCHEDULE_SECTION = 'schedule' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's teams, each opening its admin view. */\nexport const LEAGUE_TEAMS_SECTION = 'teams' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's free-agent signups. */\nexport const LEAGUE_FREE_AGENTS_SECTION = 'free-agents' satisfies AdminLeagueWorkspaceSection;\n\nconst enc = encodeURIComponent;\n\nfunction withQuery(path: string, entries: readonly (readonly [string, string])[]): string {\n if (entries.length === 0) return path;\n return `${path}?${entries.map(([key, value]) => `${key}=${enc(value)}`).join('&')}`;\n}\n\nfunction adminLeagueEntries(\n leagueId: string,\n section?: AdminLeagueWorkspaceSection,\n): (readonly [string, string])[] {\n return [\n [ADMIN_VIEW_PARAM, 'leagues' satisfies AdminView],\n [ADMIN_LEAGUE_PARAM, leagueId],\n ...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section] as const]),\n ];\n}\n\nexport const APP_ROUTES = {\n home: (): string => '/',\n hallOfFame: (sport?: SportKey): string =>\n withQuery('/hall-of-fame', sport === undefined ? [] : [[HALL_OF_FAME_SPORT_PARAM, sport]]),\n locations: (): string => '/locations',\n settings: (): string => '/settings',\n terms: (): string => '/terms',\n user: (userId: string): string => `/user/${enc(userId)}`,\n league: (leagueId: string): string => `/league/${enc(leagueId)}`,\n leagueTeam: (leagueId: string, teamId: string): string =>\n `/league/${enc(leagueId)}/team/${enc(teamId)}`,\n sportGame: (leagueId: string, gameId: string): string =>\n `/league/${enc(leagueId)}/game/${enc(gameId)}`,\n /** A game's scoring page, where a scorer records its stats. */\n sportGameScoring: (leagueId: string, gameId: string): string =>\n `/league/${enc(leagueId)}/game/${enc(gameId)}/stats`,\n /** An admin view, on one of its sections when one is named; the dashboard is the bare page. */\n admin: (view?: AdminView, section?: string): string =>\n withQuery('/admin', [\n ...(view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view] as const]),\n ...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section] as const]),\n ]),\n /** A league's admin workspace, on one of its sections when one is named. */\n adminLeague: (leagueId: string, section?: AdminLeagueWorkspaceSection): string =>\n withQuery('/admin', adminLeagueEntries(leagueId, section)),\n /** One team's admin view, inside its league's workspace on the Teams section. */\n adminLeagueTeam: (leagueId: string, teamId: string): string =>\n withQuery('/admin', [\n ...adminLeagueEntries(leagueId, LEAGUE_TEAMS_SECTION),\n [ADMIN_TEAM_PARAM, teamId],\n ]),\n} as const;\n"]}
1
+ {"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"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","sourcesContent":["// Every app page address, declared once and built through `APP_ROUTES`. Both roots build these\n// links: the server writes one onto an admin notification card, and the app links to every one of\n// them, so each address shape has one change point (RULE-STD-ARCH-101). Every id is encoded, so an id\n// holding a `/` or a space still addresses its own page.\n\nimport type { AdminView } from '../constants/admin-views.js';\nimport type { SportKey } from '../types/sports.js';\n\n/** The query-string key the hall of fame names its sport under. */\nexport const HALL_OF_FAME_SPORT_PARAM = 'sport';\n\n/** The query-string key the admin page's views live under. */\nexport const ADMIN_VIEW_PARAM = 'view';\n\n/** The query-string key a league workspace's sections live under. */\nexport const ADMIN_SECTION_PARAM = 'section';\n\n/** The query-string key the Leagues view names the league whose workspace is open under. */\nexport const ADMIN_LEAGUE_PARAM = 'league';\n\n/** The query-string key the Teams section names the team whose admin view is open under. */\nexport const ADMIN_TEAM_PARAM = 'team';\n\n// The sections a league's admin workspace is addressed by. The workspace declares which of them it\n// has built as tabs; a link may name any of them.\nexport const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS = [\n 'settings',\n 'schedule',\n 'teams',\n 'free-agents',\n] as const;\nexport type AdminLeagueWorkspaceSection = (typeof ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS)[number];\n\n/** The league workspace's section holding the league's weeks and games. */\nexport const LEAGUE_SCHEDULE_SECTION = 'schedule' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's teams, each opening its admin view. */\nexport const LEAGUE_TEAMS_SECTION = 'teams' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's free-agent signups. */\nexport const LEAGUE_FREE_AGENTS_SECTION = 'free-agents' satisfies AdminLeagueWorkspaceSection;\n\nconst enc = encodeURIComponent;\n\nfunction withQuery(path: string, entries: readonly (readonly [string, string])[]): string {\n if (entries.length === 0) return path;\n return `${path}?${entries.map(([key, value]) => `${key}=${enc(value)}`).join('&')}`;\n}\n\nfunction adminLeagueEntries(\n leagueId: string,\n section?: AdminLeagueWorkspaceSection,\n): (readonly [string, string])[] {\n return [\n [ADMIN_VIEW_PARAM, 'leagues' satisfies AdminView],\n [ADMIN_LEAGUE_PARAM, leagueId],\n ...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section] as const]),\n ];\n}\n\nexport const APP_ROUTES = {\n home: (): string => '/',\n hallOfFame: (sport?: SportKey): string =>\n withQuery('/hall-of-fame', sport === undefined ? [] : [[HALL_OF_FAME_SPORT_PARAM, sport]]),\n locations: (): string => '/locations',\n settings: (): string => '/settings',\n terms: (): string => '/terms',\n user: (userId: string): string => `/user/${enc(userId)}`,\n league: (leagueId: string): string => `/league/${enc(leagueId)}`,\n leagueTeam: (leagueId: string, teamId: string): string =>\n `/league/${enc(leagueId)}/team/${enc(teamId)}`,\n sportGame: (leagueId: string, gameId: string): string =>\n `/league/${enc(leagueId)}/game/${enc(gameId)}`,\n /** A game's scoring page, where a scorer records its stats. */\n sportGameScoring: (leagueId: string, gameId: string): string =>\n `/league/${enc(leagueId)}/game/${enc(gameId)}/stats`,\n /** An admin view; the dashboard is the bare page. */\n admin: (view?: AdminView): string =>\n withQuery(\n '/admin',\n view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view]],\n ),\n /** A league's admin workspace, on one of its sections when one is named. */\n adminLeague: (leagueId: string, section?: AdminLeagueWorkspaceSection): string =>\n withQuery('/admin', adminLeagueEntries(leagueId, section)),\n /** One team's admin view, inside its league's workspace on the Teams section. */\n adminLeagueTeam: (leagueId: string, teamId: string): string =>\n withQuery('/admin', [\n ...adminLeagueEntries(leagueId, LEAGUE_TEAMS_SECTION),\n [ADMIN_TEAM_PARAM, teamId],\n ]),\n} as const;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/schemas/scoring.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8DxB,eAAO,MAAM,sBAAsB,aAGlC,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAmBpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAG5E,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAKjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAGxF,eAAO,MAAM,uBAAuB;;;;;;;kBAMzB,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,gCAAgC;;;;;;;;;;kBAKlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAK1F,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;kBAK/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAMpF,eAAO,MAAM,kCAAkC;;;;kBAMpC,CAAC;AACZ,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAG9F,eAAO,MAAM,mCAAmC;;;;;kBAOrC,CAAC;AACZ,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAQhG,eAAO,MAAM,cAAc,wDAA0C,CAAC;AAEtE,eAAO,MAAM,yBAAyB;;;;kBAM3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,0BAA0B;;;;;kBAO5B,CAAC;AACZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAM9E,eAAO,MAAM,6BAA6B;;;kBAK/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,8BAA8B;;;;kBAMhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
1
+ {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../src/schemas/scoring.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8DxB,eAAO,MAAM,sBAAsB,aAGlC,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAmBpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAG5E,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAKjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAGxF,eAAO,MAAM,uBAAuB;;;;;;;kBAMzB,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,gCAAgC;;;;;;;;;;kBAKlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAK1F,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;kBAK/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAMpF,eAAO,MAAM,kCAAkC;;;;kBAMpC,CAAC;AACZ,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAG9F,eAAO,MAAM,mCAAmC;;;;;kBAOrC,CAAC;AACZ,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAQhG,eAAO,MAAM,cAAc,wDAA0C,CAAC;AAEtE,eAAO,MAAM,yBAAyB;;;;kBAM3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,0BAA0B;;;;;kBAO5B,CAAC;AACZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAM9E,eAAO,MAAM,6BAA6B;;;kBAK/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,8BAA8B;;;;kBAMhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
@@ -1,7 +1,6 @@
1
1
  // Callable contracts for live scoring: recording stat events, marking a roster entry absent, a
2
- // scorer's memo, and the jump-ball possession arrow. Each action is two entries over one core — the
3
- // member entry for a captain or co-captain of one of the game's two teams, and the admin entry for
4
- // an admin or referee — which share one input and one result.
2
+ // scorer's memo, and the jump-ball possession arrow. Each action is one callable for everyone who
3
+ // scores the game: a captain or co-captain of one of its two teams, a referee, or an admin.
5
4
  import { z } from 'zod';
6
5
  import { MAX_STAT_EVENTS_PER_WRITE } from '../constants/sports.js';
7
6
  import { isSportStatEventId } from '../ids/stat-event-ids.js';
@@ -1 +1 @@
1
- {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/schemas/scoring.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for live scoring: recording stat events, marking a roster entry absent, a\n// scorer's memo, and the jump-ball possession arrow. Each action is two entries over one core — the\n// member entry for a captain or co-captain of one of the game's two teams, and the admin entry for\n// an admin or referee — which share one input and one result.\n\nimport { z } from 'zod';\nimport { MAX_STAT_EVENTS_PER_WRITE } from '../constants/sports.js';\nimport { isSportStatEventId } from '../ids/stat-event-ids.js';\nimport { GAME_MEMO_INPUT_FORMAT } from '../input-formats/input-formats.js';\nimport {\n BasketballAssistableShotEventSchema,\n BasketballBulkEditEventSchema,\n BasketballOnePointEventSchema,\n BasketballPlayerTallyEventSchema,\n BasketballTimeoutEventSchema,\n CurlingBlankEndEventSchema,\n CurlingRoundScoreEventSchema,\n FootballBulkEditEventSchema,\n FootballScoreEventSchema,\n StatCorrectionEventSchema,\n StatVoidEventSchema,\n} from '../doc-schemas/game-stats.js';\nimport {\n RECORDED_STAT_EVENT_OUTCOME_KEYS,\n STAT_EVENT_RECORDER_FIELD_KEYS,\n STAT_EVENT_REFUSAL_KEYS,\n STAT_EVENT_SNAPSHOT_FIELD_KEYS,\n} from '../types/stats.js';\nimport type { StatEventRecorderField, StatEventSnapshotField } from '../types/stats.js';\nimport {\n countSchema,\n gameIdSchema,\n gameRosterPlayerIdSchema,\n statEventIdSchema,\n teamIdSchema,\n textFieldSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Recording stat events\n// ---------------------------------------------------------------------------------------------\n\ntype ServerDerivedField = StatEventRecorderField | StatEventSnapshotField;\nconst SERVER_DERIVED_FIELDS: ReadonlySet<string> = new Set([\n ...STAT_EVENT_RECORDER_FIELD_KEYS,\n ...STAT_EVENT_SNAPSHOT_FIELD_KEYS,\n]);\n\n/**\n * A stored event's fields as its caller sends them: without the sequence and recorder facts the\n * writing core derives (RULE-STD-ARCH-106), and without a name snapshot, which only a copied event carries.\n * Built from the stored event's own declaration, so the wire and the document cannot drift.\n */\nfunction callerShape<Shape extends z.ZodRawShape, Omitted extends keyof Shape = never>(\n shape: Shape,\n omitted: readonly Omitted[] = [],\n): Omit<Shape, ServerDerivedField | Omitted> {\n const dropped = new Set<PropertyKey>([...SERVER_DERIVED_FIELDS, ...omitted]);\n return Object.fromEntries(Object.entries(shape).filter(([field]) => !dropped.has(field))) as Omit<\n Shape,\n ServerDerivedField | Omitted\n >;\n}\n\n// A sport event's id as its caller sends it — the id minted at the tap, or, as a void's target, one a\n// copied event kept. It becomes a document path, so it is held to the shape a sport event id has.\nexport const sportStatEventIdSchema = statEventIdSchema.refine(\n isSportStatEventId,\n 'Not a stat event id.',\n);\n\nconst sportEventId = { eventId: sportStatEventIdSchema };\n\n/**\n * One event of a scoring write, as the tap minted it: a sport event with its id and `recordedAt`, or\n * a void naming its target, whose own id the core derives. A bulk edit carries `previousValue`, the\n * value the form showed, so a stale form is refused. A correction parses so the core can answer it\n * with its refusal: only the game-reconcile core appends one.\n */\nexport const StatEventSubmissionSchema = z.discriminatedUnion('type', [\n z.strictObject({ ...callerShape(BasketballOnePointEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(BasketballAssistableShotEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(BasketballPlayerTallyEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(BasketballTimeoutEventSchema.shape), ...sportEventId }),\n z.strictObject({\n ...callerShape(BasketballBulkEditEventSchema.shape),\n ...sportEventId,\n previousValue: countSchema,\n }),\n z.strictObject({ ...callerShape(CurlingRoundScoreEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(CurlingBlankEndEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(FootballScoreEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(FootballBulkEditEventSchema.shape), ...sportEventId }),\n z.strictObject({\n ...callerShape(StatVoidEventSchema.shape, ['eventId']),\n targetEventId: sportStatEventIdSchema,\n }),\n z.strictObject(callerShape(StatCorrectionEventSchema.shape)),\n]);\nexport type StatEventSubmission = z.infer<typeof StatEventSubmissionSchema>;\n\n// A queue drain, a bulk-entry submission, or an undo: one ordered batch, applied whole or not at all.\nexport const RecordGameStatEventsInputSchema = z\n .object({\n gameId: gameIdSchema,\n events: z.array(StatEventSubmissionSchema).min(1).max(MAX_STAT_EVENTS_PER_WRITE),\n })\n .strict();\nexport type RecordGameStatEventsInput = z.infer<typeof RecordGameStatEventsInputSchema>;\n\n// Each event sent, in order: stored now, or found already stored by an earlier send.\nexport const RecordedStatEventSchema = z\n .object({\n eventId: statEventIdSchema,\n outcome: z.enum(RECORDED_STAT_EVENT_OUTCOME_KEYS),\n sequence: z.number().int().positive(),\n })\n .strict();\nexport type RecordedStatEvent = z.infer<typeof RecordedStatEventSchema>;\n\nexport const RecordGameStatEventsResultSchema = z\n .object({\n gameId: gameIdSchema,\n events: z.array(RecordedStatEventSchema),\n })\n .strict();\nexport type RecordGameStatEventsResult = z.infer<typeof RecordGameStatEventsResultSchema>;\n\n// What a refused scoring write names in its error details: why, and the first event it refused. No\n// event of the batch was stored, and the scorekeeper's failed list shows the refusal's copy beside\n// that event.\nexport const StatEventRefusalDetailsSchema = z\n .object({\n refusal: z.enum(STAT_EVENT_REFUSAL_KEYS),\n eventId: statEventIdSchema,\n })\n .strict();\nexport type StatEventRefusalDetails = z.infer<typeof StatEventRefusalDetailsSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Absence — per roster entry, so a person on both teams can be absent on one side only\n// ---------------------------------------------------------------------------------------------\n\nexport const UpdateGameAbsentPlayersInputSchema = z\n .object({\n gameId: gameIdSchema,\n gameRosterPlayerId: gameRosterPlayerIdSchema,\n absent: z.boolean(),\n })\n .strict();\nexport type UpdateGameAbsentPlayersInput = z.infer<typeof UpdateGameAbsentPlayersInputSchema>;\n\n// `changed` is false when the entry was already marked that way; nothing was written.\nexport const UpdateGameAbsentPlayersResultSchema = z\n .object({\n gameId: gameIdSchema,\n gameRosterPlayerId: gameRosterPlayerIdSchema,\n absent: z.boolean(),\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateGameAbsentPlayersResult = z.infer<typeof UpdateGameAbsentPlayersResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The memo — a scorer's note on one person in a live game (\"red shirt\", \"#9\")\n// ---------------------------------------------------------------------------------------------\n\n// Built from the memo's one declaration, so the memo form and the callable accept exactly the same\n// text: trimmed, one line, empty allowed — an empty memo clears the person's note.\nexport const gameMemoSchema = textFieldSchema(GAME_MEMO_INPUT_FORMAT);\n\nexport const UpdateGameMemoInputSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n memo: gameMemoSchema,\n })\n .strict();\nexport type UpdateGameMemoInput = z.infer<typeof UpdateGameMemoInputSchema>;\n\nexport const UpdateGameMemoResultSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n memo: z.string(),\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateGameMemoResult = z.infer<typeof UpdateGameMemoResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The jump-ball possession arrow — set to a team, so a retried call lands where the first did\n// ---------------------------------------------------------------------------------------------\n\nexport const UpdateGameJumpBallInputSchema = z\n .object({\n gameId: gameIdSchema,\n teamId: teamIdSchema,\n })\n .strict();\nexport type UpdateGameJumpBallInput = z.infer<typeof UpdateGameJumpBallInputSchema>;\n\nexport const UpdateGameJumpBallResultSchema = z\n .object({\n gameId: gameIdSchema,\n teamId: teamIdSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateGameJumpBallResult = z.infer<typeof UpdateGameJumpBallResultSchema>;\n"]}
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/schemas/scoring.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for live scoring: recording stat events, marking a roster entry absent, a\n// scorer's memo, and the jump-ball possession arrow. Each action is one callable for everyone who\n// scores the game: a captain or co-captain of one of its two teams, a referee, or an admin.\n\nimport { z } from 'zod';\nimport { MAX_STAT_EVENTS_PER_WRITE } from '../constants/sports.js';\nimport { isSportStatEventId } from '../ids/stat-event-ids.js';\nimport { GAME_MEMO_INPUT_FORMAT } from '../input-formats/input-formats.js';\nimport {\n BasketballAssistableShotEventSchema,\n BasketballBulkEditEventSchema,\n BasketballOnePointEventSchema,\n BasketballPlayerTallyEventSchema,\n BasketballTimeoutEventSchema,\n CurlingBlankEndEventSchema,\n CurlingRoundScoreEventSchema,\n FootballBulkEditEventSchema,\n FootballScoreEventSchema,\n StatCorrectionEventSchema,\n StatVoidEventSchema,\n} from '../doc-schemas/game-stats.js';\nimport {\n RECORDED_STAT_EVENT_OUTCOME_KEYS,\n STAT_EVENT_RECORDER_FIELD_KEYS,\n STAT_EVENT_REFUSAL_KEYS,\n STAT_EVENT_SNAPSHOT_FIELD_KEYS,\n} from '../types/stats.js';\nimport type { StatEventRecorderField, StatEventSnapshotField } from '../types/stats.js';\nimport {\n countSchema,\n gameIdSchema,\n gameRosterPlayerIdSchema,\n statEventIdSchema,\n teamIdSchema,\n textFieldSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Recording stat events\n// ---------------------------------------------------------------------------------------------\n\ntype ServerDerivedField = StatEventRecorderField | StatEventSnapshotField;\nconst SERVER_DERIVED_FIELDS: ReadonlySet<string> = new Set([\n ...STAT_EVENT_RECORDER_FIELD_KEYS,\n ...STAT_EVENT_SNAPSHOT_FIELD_KEYS,\n]);\n\n/**\n * A stored event's fields as its caller sends them: without the sequence and recorder facts the\n * writing core derives (RULE-STD-ARCH-106), and without a name snapshot, which only a copied event carries.\n * Built from the stored event's own declaration, so the wire and the document cannot drift.\n */\nfunction callerShape<Shape extends z.ZodRawShape, Omitted extends keyof Shape = never>(\n shape: Shape,\n omitted: readonly Omitted[] = [],\n): Omit<Shape, ServerDerivedField | Omitted> {\n const dropped = new Set<PropertyKey>([...SERVER_DERIVED_FIELDS, ...omitted]);\n return Object.fromEntries(Object.entries(shape).filter(([field]) => !dropped.has(field))) as Omit<\n Shape,\n ServerDerivedField | Omitted\n >;\n}\n\n// A sport event's id as its caller sends it — the id minted at the tap, or, as a void's target, one a\n// copied event kept. It becomes a document path, so it is held to the shape a sport event id has.\nexport const sportStatEventIdSchema = statEventIdSchema.refine(\n isSportStatEventId,\n 'Not a stat event id.',\n);\n\nconst sportEventId = { eventId: sportStatEventIdSchema };\n\n/**\n * One event of a scoring write, as the tap minted it: a sport event with its id and `recordedAt`, or\n * a void naming its target, whose own id the core derives. A bulk edit carries `previousValue`, the\n * value the form showed, so a stale form is refused. A correction parses so the core can answer it\n * with its refusal: only the game-reconcile core appends one.\n */\nexport const StatEventSubmissionSchema = z.discriminatedUnion('type', [\n z.strictObject({ ...callerShape(BasketballOnePointEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(BasketballAssistableShotEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(BasketballPlayerTallyEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(BasketballTimeoutEventSchema.shape), ...sportEventId }),\n z.strictObject({\n ...callerShape(BasketballBulkEditEventSchema.shape),\n ...sportEventId,\n previousValue: countSchema,\n }),\n z.strictObject({ ...callerShape(CurlingRoundScoreEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(CurlingBlankEndEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(FootballScoreEventSchema.shape), ...sportEventId }),\n z.strictObject({ ...callerShape(FootballBulkEditEventSchema.shape), ...sportEventId }),\n z.strictObject({\n ...callerShape(StatVoidEventSchema.shape, ['eventId']),\n targetEventId: sportStatEventIdSchema,\n }),\n z.strictObject(callerShape(StatCorrectionEventSchema.shape)),\n]);\nexport type StatEventSubmission = z.infer<typeof StatEventSubmissionSchema>;\n\n// A queue drain, a bulk-entry submission, or an undo: one ordered batch, applied whole or not at all.\nexport const RecordGameStatEventsInputSchema = z\n .object({\n gameId: gameIdSchema,\n events: z.array(StatEventSubmissionSchema).min(1).max(MAX_STAT_EVENTS_PER_WRITE),\n })\n .strict();\nexport type RecordGameStatEventsInput = z.infer<typeof RecordGameStatEventsInputSchema>;\n\n// Each event sent, in order: stored now, or found already stored by an earlier send.\nexport const RecordedStatEventSchema = z\n .object({\n eventId: statEventIdSchema,\n outcome: z.enum(RECORDED_STAT_EVENT_OUTCOME_KEYS),\n sequence: z.number().int().positive(),\n })\n .strict();\nexport type RecordedStatEvent = z.infer<typeof RecordedStatEventSchema>;\n\nexport const RecordGameStatEventsResultSchema = z\n .object({\n gameId: gameIdSchema,\n events: z.array(RecordedStatEventSchema),\n })\n .strict();\nexport type RecordGameStatEventsResult = z.infer<typeof RecordGameStatEventsResultSchema>;\n\n// What a refused scoring write names in its error details: why, and the first event it refused. No\n// event of the batch was stored, and the scorekeeper's failed list shows the refusal's copy beside\n// that event.\nexport const StatEventRefusalDetailsSchema = z\n .object({\n refusal: z.enum(STAT_EVENT_REFUSAL_KEYS),\n eventId: statEventIdSchema,\n })\n .strict();\nexport type StatEventRefusalDetails = z.infer<typeof StatEventRefusalDetailsSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Absence — per roster entry, so a person on both teams can be absent on one side only\n// ---------------------------------------------------------------------------------------------\n\nexport const UpdateGameAbsentPlayersInputSchema = z\n .object({\n gameId: gameIdSchema,\n gameRosterPlayerId: gameRosterPlayerIdSchema,\n absent: z.boolean(),\n })\n .strict();\nexport type UpdateGameAbsentPlayersInput = z.infer<typeof UpdateGameAbsentPlayersInputSchema>;\n\n// `changed` is false when the entry was already marked that way; nothing was written.\nexport const UpdateGameAbsentPlayersResultSchema = z\n .object({\n gameId: gameIdSchema,\n gameRosterPlayerId: gameRosterPlayerIdSchema,\n absent: z.boolean(),\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateGameAbsentPlayersResult = z.infer<typeof UpdateGameAbsentPlayersResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The memo — a scorer's note on one person in a live game (\"red shirt\", \"#9\")\n// ---------------------------------------------------------------------------------------------\n\n// Built from the memo's one declaration, so the memo form and the callable accept exactly the same\n// text: trimmed, one line, empty allowed — an empty memo clears the person's note.\nexport const gameMemoSchema = textFieldSchema(GAME_MEMO_INPUT_FORMAT);\n\nexport const UpdateGameMemoInputSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n memo: gameMemoSchema,\n })\n .strict();\nexport type UpdateGameMemoInput = z.infer<typeof UpdateGameMemoInputSchema>;\n\nexport const UpdateGameMemoResultSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n memo: z.string(),\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateGameMemoResult = z.infer<typeof UpdateGameMemoResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The jump-ball possession arrow — set to a team, so a retried call lands where the first did\n// ---------------------------------------------------------------------------------------------\n\nexport const UpdateGameJumpBallInputSchema = z\n .object({\n gameId: gameIdSchema,\n teamId: teamIdSchema,\n })\n .strict();\nexport type UpdateGameJumpBallInput = z.infer<typeof UpdateGameJumpBallInputSchema>;\n\nexport const UpdateGameJumpBallResultSchema = z\n .object({\n gameId: gameIdSchema,\n teamId: teamIdSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateGameJumpBallResult = z.infer<typeof UpdateGameJumpBallResultSchema>;\n"]}
@@ -9,8 +9,8 @@ import { StatsDestinationChangeSchema, StatsOperationCountsSchema, } from '../do
9
9
  import { StatsValidationReportSchema, StatsValidationScopeSchema, StatsValidationSummarySchema, } from '../doc-schemas/system.js';
10
10
  import { HistoricalStatsSchema } from '../doc-schemas/user-profile.js';
11
11
  import { GAME_FINALIZE_OUTCOME_KEYS, GAME_REOPEN_OUTCOME_KEYS, GAME_STATS_REPAIR_OUTCOME_KEYS, UNROSTERED_STAT_LINE_RESOLUTION_OUTCOME_KEYS, } from '../types/stats.js';
12
- // `finalizeGame` (a captain or co-captain of either team) / `adminFinalizeGame` (an admin or a
13
- // referee): make a game's numbers permanent. Everything it writes is derived server-side from the
12
+ // `finalizeGame` (a captain or co-captain of either team, a referee, or an admin): make a game's
13
+ // numbers permanent. Everything it writes is derived server-side from the
14
14
  // game's events; nothing in the input is a number (RULE-QS-SPORT-922).
15
15
  export const FinalizeGameInputSchema = z.object({ gameId: gameIdSchema }).strict();
16
16
  // `alreadyFinalized` when the game was completed before the call: nothing was written (RULE-QS-SPORT-923).
@@ -1 +1 @@
1
- {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/schemas/stats.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for the stats pipeline: finalize, reopen, the Fix stats actions — the rebuilds,\n// the game repairs, the historical baseline, the stats check, and deleting a check's report — and the\n// migration's placement of\n// an unplaceable stat line.\n\nimport { z } from 'zod';\nimport { MAX_GAME_STATS_CORRECTION_TARGETS } from '../constants/sports.js';\nimport {\n countSchema,\n gameIdSchema,\n gameRosterPlayerIdSchema,\n leagueIdSchema,\n repairReasonSchema,\n sportKeySchema,\n statCounterKeySchema,\n statsOperationIdSchema,\n statsValidationReportIdSchema,\n teamIdSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\nimport {\n StatsDestinationChangeSchema,\n StatsOperationCountsSchema,\n} from '../doc-schemas/stats-operation.js';\nimport {\n StatsValidationReportSchema,\n StatsValidationScopeSchema,\n StatsValidationSummarySchema,\n} from '../doc-schemas/system.js';\nimport { HistoricalStatsSchema } from '../doc-schemas/user-profile.js';\nimport {\n GAME_FINALIZE_OUTCOME_KEYS,\n GAME_REOPEN_OUTCOME_KEYS,\n GAME_STATS_REPAIR_OUTCOME_KEYS,\n UNROSTERED_STAT_LINE_RESOLUTION_OUTCOME_KEYS,\n} from '../types/stats.js';\n\n// `finalizeGame` (a captain or co-captain of either team) / `adminFinalizeGame` (an admin or a\n// referee): make a game's numbers permanent. Everything it writes is derived server-side from the\n// game's events; nothing in the input is a number (RULE-QS-SPORT-922).\nexport const FinalizeGameInputSchema = z.object({ gameId: gameIdSchema }).strict();\nexport type FinalizeGameInput = z.infer<typeof FinalizeGameInputSchema>;\n\n// `alreadyFinalized` when the game was completed before the call: nothing was written (RULE-QS-SPORT-923).\nexport const FinalizeGameResultSchema = z\n .object({\n gameId: gameIdSchema,\n leagueId: leagueIdSchema,\n outcome: z.enum(GAME_FINALIZE_OUTCOME_KEYS),\n nonScoringRosterPlayerIds: z.array(gameRosterPlayerIdSchema),\n })\n .strict();\nexport type FinalizeGameResult = z.infer<typeof FinalizeGameResultSchema>;\n\n// `reopenGame` (an admin): take a finalized game's numbers back out so it can be scored again. It\n// changes a completed record, so the admin says why (RULE-QS-SPORT-926, RULE-STD-BACKEND-212).\nexport const ReopenGameInputSchema = z\n .object({ gameId: gameIdSchema, reason: repairReasonSchema })\n .strict();\nexport type ReopenGameInput = z.infer<typeof ReopenGameInputSchema>;\n\n// `alreadyOpen` when the game was not completed: nothing was written.\nexport const ReopenGameResultSchema = z\n .object({\n gameId: gameIdSchema,\n leagueId: leagueIdSchema,\n outcome: z.enum(GAME_REOPEN_OUTCOME_KEYS),\n })\n .strict();\nexport type ReopenGameResult = z.infer<typeof ReopenGameResultSchema>;\n\n// `resolve.unrosteredStatLine` (an admin, at the cutover console, before the cutover): a recorded V1\n// stat line that no roster entry and no play of the game can place is placed on the team the admin\n// names, as the game's missing roster entry; the game's copy is then run again. The admin says why.\n// `dryRun` previews the placement — whether the game would then convert — and writes nothing.\nexport const AdminResolveUnrosteredStatLineInputSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n teamId: teamIdSchema,\n reason: repairReasonSchema,\n dryRun: z.boolean().optional(),\n })\n .strict();\nexport type AdminResolveUnrosteredStatLineInput = z.infer<\n typeof AdminResolveUnrosteredStatLineInputSchema\n>;\n\n// `gameConverts` says whether the game's stats now convert, so the operator knows the copy can run.\nexport const AdminResolveUnrosteredStatLineResultSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n teamId: teamIdSchema,\n outcome: z.enum(UNROSTERED_STAT_LINE_RESOLUTION_OUTCOME_KEYS),\n gameConverts: z.boolean(),\n })\n .strict();\nexport type AdminResolveUnrosteredStatLineResult = z.infer<\n typeof AdminResolveUnrosteredStatLineResultSchema\n>;\n\n// Every rebuild and every game repair is a repair of a completed record: it takes a reason, runs\n// under an operation id the admin's browser mints when the admin starts it, and offers a dry run that\n// lists each document it would change, with before and after, and writes nothing (RULE-STD-BACKEND-212,\n// RULE-QS-SPORT-926). A real run resumes from its operation document, so a cursor is taken from the client\n// only to page a dry run, which keeps no operation.\nconst statsRepairFields = {\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n resumeAfter: z.string().min(1).optional(),\n};\n\nconst cursorOnlyOnDryRun = (input: { dryRun: boolean; resumeAfter?: string }): boolean =>\n input.dryRun || input.resumeAfter === undefined;\nconst CURSOR_ONLY_ON_DRY_RUN = {\n message: 'A real run resumes from its operation; only a dry run takes a cursor.',\n path: ['resumeAfter'],\n};\n\n// `recalculateLeagueStats`: every team of one league — its standings line and its per-membership rows.\nexport const RecalculateLeagueStatsInputSchema = z\n .object({ leagueId: leagueIdSchema, ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateLeagueStatsInput = z.infer<typeof RecalculateLeagueStatsInputSchema>;\n\n// `recalculateAllLeagueStats`: every league, closed ones included, a page of leagues per call.\nexport const RecalculateAllLeagueStatsInputSchema = z\n .object({ ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateAllLeagueStatsInput = z.infer<typeof RecalculateAllLeagueStatsInputSchema>;\n\n// `recalculateUserStats`: one person's career line in every sport.\nexport const RecalculateUserStatsInputSchema = z\n .object({ userId: userIdSchema, ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateUserStatsInput = z.infer<typeof RecalculateUserStatsInputSchema>;\n\n// `recalculateAllUserStats`: every profile's career lines, a page of profiles per call.\nexport const RecalculateAllUserStatsInputSchema = z\n .object({ ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateAllUserStatsInput = z.infer<typeof RecalculateAllUserStatsInputSchema>;\n\n// `recalculateHallOfFame`: one sport's hall of fame — one person's entry, or the whole sport a page\n// of profiles per call. Refused for a sport that keeps none.\nexport const RecalculateHallOfFameInputSchema = z\n .object({ sportKey: sportKeySchema, userId: userIdSchema.optional(), ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateHallOfFameInput = z.infer<typeof RecalculateHallOfFameInputSchema>;\n\n// What one call of a rebuild did. `complete` is false while a paged rebuild has pages left: the\n// admin calls again with the same operation id — or, for a dry run, with `resumeAfter` set to\n// `nextResumeAfter`. `changes` is every document this call changed or, on a dry run, would change,\n// up to MAX_STATS_REPAIR_LISTED_CHANGES (`changesTruncated` says more were left out). A game whose\n// stored numbers disagree with its record is named in `stoppedOnGameIds`, and what it feeds is left\n// untouched. `scopeChanged` says a game was finalized or reopened in the scope while it ran, so the\n// admin runs it again.\nexport const StatsRebuildResultSchema = z\n .object({\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n complete: z.boolean(),\n nextResumeAfter: z.string().min(1).nullable(),\n counts: StatsOperationCountsSchema,\n stoppedOnGameIds: z.array(gameIdSchema),\n changes: z.array(StatsDestinationChangeSchema),\n changesTruncated: z.boolean(),\n scopeChanged: z.boolean(),\n })\n .strict();\nexport type StatsRebuildResult = z.infer<typeof StatsRebuildResultSchema>;\n\n// A line a correction sets, by its absolute value: the team line of `teamId`, or the player line\n// `{teamId}_{playerUserId}` when a player is named. Only a field the sport's adapter lists in\n// `correctableFields` may be set.\nexport const GameStatsCorrectionTargetSchema = z\n .object({\n teamId: teamIdSchema,\n playerUserId: userIdSchema.optional(),\n stat: statCounterKeySchema,\n value: countSchema,\n })\n .strict();\nexport type GameStatsCorrectionTarget = z.infer<typeof GameStatsCorrectionTargetSchema>;\n\n// `adminCorrectGameStats`: set named fields of a game's lines to the values given, or keep the\n// numbers the game stores now — a hand edit made outside the app — as corrections. Exactly one of the\n// two.\nexport const AdminCorrectGameStatsInputSchema = z\n .object({\n gameId: gameIdSchema,\n targets: z\n .array(GameStatsCorrectionTargetSchema)\n .min(1)\n .max(MAX_GAME_STATS_CORRECTION_TARGETS)\n .optional(),\n keepStored: z.literal(true).optional(),\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n })\n .strict()\n .refine((input) => (input.targets === undefined) !== (input.keepStored === undefined), {\n message: 'Give the values to set, or keep the stored numbers — one of the two.',\n path: ['targets'],\n });\nexport type AdminCorrectGameStatsInput = z.infer<typeof AdminCorrectGameStatsInputSchema>;\n\n// `recalculateGameStats`: restore a game's numbers from its events, discarding a hand edit.\nexport const RecalculateGameStatsInputSchema = z\n .object({\n gameId: gameIdSchema,\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n })\n .strict();\nexport type RecalculateGameStatsInput = z.infer<typeof RecalculateGameStatsInputSchema>;\n\n// One correction a repair appended, or on a dry run would append.\nexport const GameStatsCorrectionSchema = z\n .object({ lineKey: z.string().min(1), field: statCounterKeySchema, value: z.number().int() })\n .strict();\nexport type GameStatsCorrection = z.infer<typeof GameStatsCorrectionSchema>;\n\n// A list of roster entries a repair replaced, as the game stored it and as the repair rebuilds it.\nconst replacedEntryListSchema = z\n .object({ stored: z.array(gameRosterPlayerIdSchema), rebuilt: z.array(gameRosterPlayerIdSchema) })\n .strict();\n\n// Every value of the game document a repair changed, each with the value the game stored and the\n// value the repair writes — never the whole document (RULE-STD-BACKEND-212). `lines` holds each changed field\n// of a team or player line (`lineKey` the team id or the roster entry id), `scores` each team whose\n// score mirror changed, and the lists, the event counter and `recordRewritten` appear only when the\n// repair changes them; `recordRewritten` names the finalized record's page counts before and after,\n// without copying the record.\nexport const GameRepairChangesSchema = z\n .object({\n lines: z.array(\n z\n .object({\n lineKey: z.string().min(1),\n field: z.string().min(1),\n stored: z.number(),\n rebuilt: z.number(),\n })\n .strict(),\n ),\n scores: z.array(\n z.object({ teamId: teamIdSchema, stored: z.number(), rebuilt: z.number() }).strict(),\n ),\n absentRosterPlayerIds: replacedEntryListSchema.optional(),\n nonScoringRosterPlayerIds: replacedEntryListSchema.optional(),\n statEventSequence: z.object({ stored: countSchema, rebuilt: countSchema }).strict().optional(),\n recordRewritten: z\n .object({ pagesBefore: countSchema, pagesAfter: countSchema })\n .strict()\n .optional(),\n })\n .strict();\nexport type GameRepairChanges = z.infer<typeof GameRepairChangesSchema>;\n\n// What a game repair did: `reconciled` it changed the game; `unchanged` there was nothing to change;\n// `alreadyApplied` the operation had already committed and this call is its acknowledged retry.\n// `gameChanges` is what it changed on the game document, or on a dry run would change; empty lists\n// for any other outcome.\nexport const GameStatsRepairResultSchema = z\n .object({\n gameId: gameIdSchema,\n leagueId: leagueIdSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n outcome: z.enum(GAME_STATS_REPAIR_OUTCOME_KEYS),\n corrections: z.array(GameStatsCorrectionSchema),\n gameChanged: z.boolean(),\n gameChanges: GameRepairChangesSchema,\n destinationChanges: z.array(StatsDestinationChangeSchema),\n })\n .strict();\nexport type GameStatsRepairResult = z.infer<typeof GameStatsRepairResultSchema>;\n\n// `adminUpdateHistoricalStats`: a person's pre-Q-Sports career totals for a sport that takes them,\n// written whole, and their career line and hall-of-fame entry rebuilt with them.\nexport const AdminUpdateHistoricalStatsInputSchema = z\n .object({\n userId: userIdSchema,\n sportKey: sportKeySchema,\n stats: HistoricalStatsSchema,\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n })\n .strict();\nexport type AdminUpdateHistoricalStatsInput = z.infer<typeof AdminUpdateHistoricalStatsInputSchema>;\n\nexport const AdminUpdateHistoricalStatsResultSchema = z\n .object({\n userId: userIdSchema,\n sportKey: sportKeySchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n outcome: z.enum(GAME_STATS_REPAIR_OUTCOME_KEYS),\n baselineBefore: HistoricalStatsSchema.nullable(),\n stoppedOnGameIds: z.array(gameIdSchema),\n changes: z.array(StatsDestinationChangeSchema),\n })\n .strict();\nexport type AdminUpdateHistoricalStatsResult = z.infer<\n typeof AdminUpdateHistoricalStatsResultSchema\n>;\n\n// `runStatsValidation`: check one game, one league, or — with neither — everything. A check that\n// reaches its time budget saves its place on its operation and answers `complete: false`; calling\n// again with the same operation id resumes it. It writes no stat, so it takes no reason.\nexport const RunStatsValidationInputSchema = z\n .object({ operationId: statsOperationIdSchema, scope: StatsValidationScopeSchema })\n .strict();\nexport type RunStatsValidationInput = z.infer<typeof RunStatsValidationInputSchema>;\n\nexport const RunStatsValidationResultSchema = z\n .object({\n reportId: z.string().min(1),\n complete: z.boolean(),\n summary: StatsValidationSummarySchema,\n discrepancyCounts: StatsValidationReportSchema.shape.discrepancyCounts,\n })\n .strict();\nexport type RunStatsValidationResult = z.infer<typeof RunStatsValidationResultSchema>;\n\n// `adminDeleteStatsValidationReport`: delete one stats check's report. It writes no stat, so it takes\n// no reason; a report that is not there is refused as not found.\nexport const AdminDeleteStatsValidationReportInputSchema = z\n .object({ reportId: statsValidationReportIdSchema })\n .strict();\nexport type AdminDeleteStatsValidationReportInput = z.infer<\n typeof AdminDeleteStatsValidationReportInputSchema\n>;\n\nexport const AdminDeleteStatsValidationReportResultSchema = z\n .object({ reportId: statsValidationReportIdSchema })\n .strict();\nexport type AdminDeleteStatsValidationReportResult = z.infer<\n typeof AdminDeleteStatsValidationReportResultSchema\n>;\n"]}
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/schemas/stats.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for the stats pipeline: finalize, reopen, the Fix stats actions — the rebuilds,\n// the game repairs, the historical baseline, the stats check, and deleting a check's report — and the\n// migration's placement of\n// an unplaceable stat line.\n\nimport { z } from 'zod';\nimport { MAX_GAME_STATS_CORRECTION_TARGETS } from '../constants/sports.js';\nimport {\n countSchema,\n gameIdSchema,\n gameRosterPlayerIdSchema,\n leagueIdSchema,\n repairReasonSchema,\n sportKeySchema,\n statCounterKeySchema,\n statsOperationIdSchema,\n statsValidationReportIdSchema,\n teamIdSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\nimport {\n StatsDestinationChangeSchema,\n StatsOperationCountsSchema,\n} from '../doc-schemas/stats-operation.js';\nimport {\n StatsValidationReportSchema,\n StatsValidationScopeSchema,\n StatsValidationSummarySchema,\n} from '../doc-schemas/system.js';\nimport { HistoricalStatsSchema } from '../doc-schemas/user-profile.js';\nimport {\n GAME_FINALIZE_OUTCOME_KEYS,\n GAME_REOPEN_OUTCOME_KEYS,\n GAME_STATS_REPAIR_OUTCOME_KEYS,\n UNROSTERED_STAT_LINE_RESOLUTION_OUTCOME_KEYS,\n} from '../types/stats.js';\n\n// `finalizeGame` (a captain or co-captain of either team, a referee, or an admin): make a game's\n// numbers permanent. Everything it writes is derived server-side from the\n// game's events; nothing in the input is a number (RULE-QS-SPORT-922).\nexport const FinalizeGameInputSchema = z.object({ gameId: gameIdSchema }).strict();\nexport type FinalizeGameInput = z.infer<typeof FinalizeGameInputSchema>;\n\n// `alreadyFinalized` when the game was completed before the call: nothing was written (RULE-QS-SPORT-923).\nexport const FinalizeGameResultSchema = z\n .object({\n gameId: gameIdSchema,\n leagueId: leagueIdSchema,\n outcome: z.enum(GAME_FINALIZE_OUTCOME_KEYS),\n nonScoringRosterPlayerIds: z.array(gameRosterPlayerIdSchema),\n })\n .strict();\nexport type FinalizeGameResult = z.infer<typeof FinalizeGameResultSchema>;\n\n// `reopenGame` (an admin): take a finalized game's numbers back out so it can be scored again. It\n// changes a completed record, so the admin says why (RULE-QS-SPORT-926, RULE-STD-BACKEND-212).\nexport const ReopenGameInputSchema = z\n .object({ gameId: gameIdSchema, reason: repairReasonSchema })\n .strict();\nexport type ReopenGameInput = z.infer<typeof ReopenGameInputSchema>;\n\n// `alreadyOpen` when the game was not completed: nothing was written.\nexport const ReopenGameResultSchema = z\n .object({\n gameId: gameIdSchema,\n leagueId: leagueIdSchema,\n outcome: z.enum(GAME_REOPEN_OUTCOME_KEYS),\n })\n .strict();\nexport type ReopenGameResult = z.infer<typeof ReopenGameResultSchema>;\n\n// `resolve.unrosteredStatLine` (an admin, at the cutover console, before the cutover): a recorded V1\n// stat line that no roster entry and no play of the game can place is placed on the team the admin\n// names, as the game's missing roster entry; the game's copy is then run again. The admin says why.\n// `dryRun` previews the placement — whether the game would then convert — and writes nothing.\nexport const AdminResolveUnrosteredStatLineInputSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n teamId: teamIdSchema,\n reason: repairReasonSchema,\n dryRun: z.boolean().optional(),\n })\n .strict();\nexport type AdminResolveUnrosteredStatLineInput = z.infer<\n typeof AdminResolveUnrosteredStatLineInputSchema\n>;\n\n// `gameConverts` says whether the game's stats now convert, so the operator knows the copy can run.\nexport const AdminResolveUnrosteredStatLineResultSchema = z\n .object({\n gameId: gameIdSchema,\n userId: userIdSchema,\n teamId: teamIdSchema,\n outcome: z.enum(UNROSTERED_STAT_LINE_RESOLUTION_OUTCOME_KEYS),\n gameConverts: z.boolean(),\n })\n .strict();\nexport type AdminResolveUnrosteredStatLineResult = z.infer<\n typeof AdminResolveUnrosteredStatLineResultSchema\n>;\n\n// Every rebuild and every game repair is a repair of a completed record: it takes a reason, runs\n// under an operation id the admin's browser mints when the admin starts it, and offers a dry run that\n// lists each document it would change, with before and after, and writes nothing (RULE-STD-BACKEND-212,\n// RULE-QS-SPORT-926). A real run resumes from its operation document, so a cursor is taken from the client\n// only to page a dry run, which keeps no operation.\nconst statsRepairFields = {\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n resumeAfter: z.string().min(1).optional(),\n};\n\nconst cursorOnlyOnDryRun = (input: { dryRun: boolean; resumeAfter?: string }): boolean =>\n input.dryRun || input.resumeAfter === undefined;\nconst CURSOR_ONLY_ON_DRY_RUN = {\n message: 'A real run resumes from its operation; only a dry run takes a cursor.',\n path: ['resumeAfter'],\n};\n\n// `recalculateLeagueStats`: every team of one league — its standings line and its per-membership rows.\nexport const RecalculateLeagueStatsInputSchema = z\n .object({ leagueId: leagueIdSchema, ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateLeagueStatsInput = z.infer<typeof RecalculateLeagueStatsInputSchema>;\n\n// `recalculateAllLeagueStats`: every league, closed ones included, a page of leagues per call.\nexport const RecalculateAllLeagueStatsInputSchema = z\n .object({ ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateAllLeagueStatsInput = z.infer<typeof RecalculateAllLeagueStatsInputSchema>;\n\n// `recalculateUserStats`: one person's career line in every sport.\nexport const RecalculateUserStatsInputSchema = z\n .object({ userId: userIdSchema, ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateUserStatsInput = z.infer<typeof RecalculateUserStatsInputSchema>;\n\n// `recalculateAllUserStats`: every profile's career lines, a page of profiles per call.\nexport const RecalculateAllUserStatsInputSchema = z\n .object({ ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateAllUserStatsInput = z.infer<typeof RecalculateAllUserStatsInputSchema>;\n\n// `recalculateHallOfFame`: one sport's hall of fame — one person's entry, or the whole sport a page\n// of profiles per call. Refused for a sport that keeps none.\nexport const RecalculateHallOfFameInputSchema = z\n .object({ sportKey: sportKeySchema, userId: userIdSchema.optional(), ...statsRepairFields })\n .strict()\n .refine(cursorOnlyOnDryRun, CURSOR_ONLY_ON_DRY_RUN);\nexport type RecalculateHallOfFameInput = z.infer<typeof RecalculateHallOfFameInputSchema>;\n\n// What one call of a rebuild did. `complete` is false while a paged rebuild has pages left: the\n// admin calls again with the same operation id — or, for a dry run, with `resumeAfter` set to\n// `nextResumeAfter`. `changes` is every document this call changed or, on a dry run, would change,\n// up to MAX_STATS_REPAIR_LISTED_CHANGES (`changesTruncated` says more were left out). A game whose\n// stored numbers disagree with its record is named in `stoppedOnGameIds`, and what it feeds is left\n// untouched. `scopeChanged` says a game was finalized or reopened in the scope while it ran, so the\n// admin runs it again.\nexport const StatsRebuildResultSchema = z\n .object({\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n complete: z.boolean(),\n nextResumeAfter: z.string().min(1).nullable(),\n counts: StatsOperationCountsSchema,\n stoppedOnGameIds: z.array(gameIdSchema),\n changes: z.array(StatsDestinationChangeSchema),\n changesTruncated: z.boolean(),\n scopeChanged: z.boolean(),\n })\n .strict();\nexport type StatsRebuildResult = z.infer<typeof StatsRebuildResultSchema>;\n\n// A line a correction sets, by its absolute value: the team line of `teamId`, or the player line\n// `{teamId}_{playerUserId}` when a player is named. Only a field the sport's adapter lists in\n// `correctableFields` may be set.\nexport const GameStatsCorrectionTargetSchema = z\n .object({\n teamId: teamIdSchema,\n playerUserId: userIdSchema.optional(),\n stat: statCounterKeySchema,\n value: countSchema,\n })\n .strict();\nexport type GameStatsCorrectionTarget = z.infer<typeof GameStatsCorrectionTargetSchema>;\n\n// `adminCorrectGameStats`: set named fields of a game's lines to the values given, or keep the\n// numbers the game stores now — a hand edit made outside the app — as corrections. Exactly one of the\n// two.\nexport const AdminCorrectGameStatsInputSchema = z\n .object({\n gameId: gameIdSchema,\n targets: z\n .array(GameStatsCorrectionTargetSchema)\n .min(1)\n .max(MAX_GAME_STATS_CORRECTION_TARGETS)\n .optional(),\n keepStored: z.literal(true).optional(),\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n })\n .strict()\n .refine((input) => (input.targets === undefined) !== (input.keepStored === undefined), {\n message: 'Give the values to set, or keep the stored numbers — one of the two.',\n path: ['targets'],\n });\nexport type AdminCorrectGameStatsInput = z.infer<typeof AdminCorrectGameStatsInputSchema>;\n\n// `recalculateGameStats`: restore a game's numbers from its events, discarding a hand edit.\nexport const RecalculateGameStatsInputSchema = z\n .object({\n gameId: gameIdSchema,\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n })\n .strict();\nexport type RecalculateGameStatsInput = z.infer<typeof RecalculateGameStatsInputSchema>;\n\n// One correction a repair appended, or on a dry run would append.\nexport const GameStatsCorrectionSchema = z\n .object({ lineKey: z.string().min(1), field: statCounterKeySchema, value: z.number().int() })\n .strict();\nexport type GameStatsCorrection = z.infer<typeof GameStatsCorrectionSchema>;\n\n// A list of roster entries a repair replaced, as the game stored it and as the repair rebuilds it.\nconst replacedEntryListSchema = z\n .object({ stored: z.array(gameRosterPlayerIdSchema), rebuilt: z.array(gameRosterPlayerIdSchema) })\n .strict();\n\n// Every value of the game document a repair changed, each with the value the game stored and the\n// value the repair writes — never the whole document (RULE-STD-BACKEND-212). `lines` holds each changed field\n// of a team or player line (`lineKey` the team id or the roster entry id), `scores` each team whose\n// score mirror changed, and the lists, the event counter and `recordRewritten` appear only when the\n// repair changes them; `recordRewritten` names the finalized record's page counts before and after,\n// without copying the record.\nexport const GameRepairChangesSchema = z\n .object({\n lines: z.array(\n z\n .object({\n lineKey: z.string().min(1),\n field: z.string().min(1),\n stored: z.number(),\n rebuilt: z.number(),\n })\n .strict(),\n ),\n scores: z.array(\n z.object({ teamId: teamIdSchema, stored: z.number(), rebuilt: z.number() }).strict(),\n ),\n absentRosterPlayerIds: replacedEntryListSchema.optional(),\n nonScoringRosterPlayerIds: replacedEntryListSchema.optional(),\n statEventSequence: z.object({ stored: countSchema, rebuilt: countSchema }).strict().optional(),\n recordRewritten: z\n .object({ pagesBefore: countSchema, pagesAfter: countSchema })\n .strict()\n .optional(),\n })\n .strict();\nexport type GameRepairChanges = z.infer<typeof GameRepairChangesSchema>;\n\n// What a game repair did: `reconciled` it changed the game; `unchanged` there was nothing to change;\n// `alreadyApplied` the operation had already committed and this call is its acknowledged retry.\n// `gameChanges` is what it changed on the game document, or on a dry run would change; empty lists\n// for any other outcome.\nexport const GameStatsRepairResultSchema = z\n .object({\n gameId: gameIdSchema,\n leagueId: leagueIdSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n outcome: z.enum(GAME_STATS_REPAIR_OUTCOME_KEYS),\n corrections: z.array(GameStatsCorrectionSchema),\n gameChanged: z.boolean(),\n gameChanges: GameRepairChangesSchema,\n destinationChanges: z.array(StatsDestinationChangeSchema),\n })\n .strict();\nexport type GameStatsRepairResult = z.infer<typeof GameStatsRepairResultSchema>;\n\n// `adminUpdateHistoricalStats`: a person's pre-Q-Sports career totals for a sport that takes them,\n// written whole, and their career line and hall-of-fame entry rebuilt with them.\nexport const AdminUpdateHistoricalStatsInputSchema = z\n .object({\n userId: userIdSchema,\n sportKey: sportKeySchema,\n stats: HistoricalStatsSchema,\n reason: repairReasonSchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n })\n .strict();\nexport type AdminUpdateHistoricalStatsInput = z.infer<typeof AdminUpdateHistoricalStatsInputSchema>;\n\nexport const AdminUpdateHistoricalStatsResultSchema = z\n .object({\n userId: userIdSchema,\n sportKey: sportKeySchema,\n operationId: statsOperationIdSchema,\n dryRun: z.boolean(),\n outcome: z.enum(GAME_STATS_REPAIR_OUTCOME_KEYS),\n baselineBefore: HistoricalStatsSchema.nullable(),\n stoppedOnGameIds: z.array(gameIdSchema),\n changes: z.array(StatsDestinationChangeSchema),\n })\n .strict();\nexport type AdminUpdateHistoricalStatsResult = z.infer<\n typeof AdminUpdateHistoricalStatsResultSchema\n>;\n\n// `runStatsValidation`: check one game, one league, or — with neither — everything. A check that\n// reaches its time budget saves its place on its operation and answers `complete: false`; calling\n// again with the same operation id resumes it. It writes no stat, so it takes no reason.\nexport const RunStatsValidationInputSchema = z\n .object({ operationId: statsOperationIdSchema, scope: StatsValidationScopeSchema })\n .strict();\nexport type RunStatsValidationInput = z.infer<typeof RunStatsValidationInputSchema>;\n\nexport const RunStatsValidationResultSchema = z\n .object({\n reportId: z.string().min(1),\n complete: z.boolean(),\n summary: StatsValidationSummarySchema,\n discrepancyCounts: StatsValidationReportSchema.shape.discrepancyCounts,\n })\n .strict();\nexport type RunStatsValidationResult = z.infer<typeof RunStatsValidationResultSchema>;\n\n// `adminDeleteStatsValidationReport`: delete one stats check's report. It writes no stat, so it takes\n// no reason; a report that is not there is refused as not found.\nexport const AdminDeleteStatsValidationReportInputSchema = z\n .object({ reportId: statsValidationReportIdSchema })\n .strict();\nexport type AdminDeleteStatsValidationReportInput = z.infer<\n typeof AdminDeleteStatsValidationReportInputSchema\n>;\n\nexport const AdminDeleteStatsValidationReportResultSchema = z\n .object({ reportId: statsValidationReportIdSchema })\n .strict();\nexport type AdminDeleteStatsValidationReportResult = z.infer<\n typeof AdminDeleteStatsValidationReportResultSchema\n>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"team-joining.d.ts","sourceRoot":"","sources":["../../src/schemas/team-joining.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB,eAAO,MAAM,+BAA+B;;;;kBAMjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAGxF,eAAO,MAAM,+BAA+B;;kBAEjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAIxF,eAAO,MAAM,0BAA0B;;;;;kBAO5B,CAAC;AACZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAI9E,eAAO,MAAM,gCAAgC;;;;;;;;;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAS1F,eAAO,MAAM,gCAAgC;;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAG1F,eAAO,MAAM,gCAAgC;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,2BAA2B;;;;;kBAO7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,iCAAiC;;;;;;;;;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAS5F,eAAO,MAAM,0BAA0B;;kBAAkD,CAAC;AAC1F,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAG9E,eAAO,MAAM,iCAAiC;;;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAG5F,eAAO,MAAM,iCAAiC;;;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F,eAAO,MAAM,qCAAqC;;;;kBAEvC,CAAC;AACZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG,eAAO,MAAM,sCAAsC;;;;;;;;;kBAOxC,CAAC;AACZ,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CACpD,OAAO,sCAAsC,CAC9C,CAAC"}
1
+ {"version":3,"file":"team-joining.d.ts","sourceRoot":"","sources":["../../src/schemas/team-joining.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB,eAAO,MAAM,+BAA+B;;;;kBAMjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAGxF,eAAO,MAAM,+BAA+B;;kBAEjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAIxF,eAAO,MAAM,0BAA0B;;;;;kBAO5B,CAAC;AACZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAI9E,eAAO,MAAM,gCAAgC;;;;;;;;;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAQ1F,eAAO,MAAM,gCAAgC;;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAG1F,eAAO,MAAM,gCAAgC;;kBAElC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,2BAA2B;;;;;kBAO7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,iCAAiC;;;;;;;;;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAS5F,eAAO,MAAM,0BAA0B;;kBAAkD,CAAC;AAC1F,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAG9E,eAAO,MAAM,iCAAiC;;;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAG5F,eAAO,MAAM,iCAAiC;;;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F,eAAO,MAAM,qCAAqC;;;;kBAEvC,CAAC;AACZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG,eAAO,MAAM,sCAAsC;;;;;;;;;kBAOxC,CAAC;AACZ,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CACpD,OAAO,sCAAsC,CAC9C,CAAC"}
@@ -8,9 +8,9 @@ import { z } from 'zod';
8
8
  import { epochMsSchema, leagueIdSchema, membershipRosterSyncStatusSchema, teamIdSchema, userIdSchema, } from '../doc-schemas/atoms.js';
9
9
  import { teamInvitationIdSchema, teamInvitationMessageSchema, teamJoinRequestIdSchema, teamJoinRequestMessageSchema, } from './atoms.js';
10
10
  // ---------------------------------------------------------------------------------------------
11
- // Invitations — sent and withdrawn by the team's captain or a co-captain (`createTeamInvitation`,
12
- // `cancelTeamInvitation`) or by an admin (`adminCreateTeamInvitation`, `adminCancelTeamInvitation`);
13
- // accepted or declined by the invitee alone (`acceptTeamInvitation`, `rejectTeamInvitation`).
11
+ // Invitations — sent and withdrawn by the team's captain or a co-captain, or an admin
12
+ // (`createTeamInvitation`, `cancelTeamInvitation`); accepted or declined by the invitee alone
13
+ // (`acceptTeamInvitation`, `rejectTeamInvitation`).
14
14
  // ---------------------------------------------------------------------------------------------
15
15
  export const CreateTeamInvitationInputSchema = z
16
16
  .object({
@@ -40,9 +40,8 @@ export const AcceptTeamInvitationResultSchema = TeamInvitationResultSchema.exten
40
40
  }).strict();
41
41
  // ---------------------------------------------------------------------------------------------
42
42
  // Join requests — sent and withdrawn by the player (`createTeamJoinRequest`,
43
- // `cancelTeamJoinRequest`); accepted or rejected by the team's captain or a co-captain
44
- // (`acceptTeamJoinRequest`, `rejectTeamJoinRequest`) or by an admin (`adminAcceptTeamJoinRequest`,
45
- // `adminRejectTeamJoinRequest`).
43
+ // `cancelTeamJoinRequest`); accepted or rejected by the team's captain or a co-captain, or an admin
44
+ // (`acceptTeamJoinRequest`, `rejectTeamJoinRequest`).
46
45
  // ---------------------------------------------------------------------------------------------
47
46
  export const CreateTeamJoinRequestInputSchema = z
48
47
  .object({ teamId: teamIdSchema, message: teamJoinRequestMessageSchema })
@@ -1 +1 @@
1
- {"version":3,"file":"team-joining.js","sourceRoot":"","sources":["../../src/schemas/team-joining.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for the ways onto a team: an invitation the team sends, a join request the\n// player sends, and a free-agent signup an admin answers by placing the player. Every door that\n// makes a membership ends in the membership core. The acting user is always `request.auth.uid` —\n// never an input field (RULE-STD-ARCH-106) — and the entry, never a field of the payload, decides the\n// authority (RULE-STD-BACKEND-004): each action is its own callable, never a choice made by a payload field\n// (RULE-STD-BACKEND-305).\n\nimport { z } from 'zod';\nimport {\n epochMsSchema,\n leagueIdSchema,\n membershipRosterSyncStatusSchema,\n teamIdSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\nimport {\n teamInvitationIdSchema,\n teamInvitationMessageSchema,\n teamJoinRequestIdSchema,\n teamJoinRequestMessageSchema,\n} from './atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Invitations — sent and withdrawn by the team's captain or a co-captain (`createTeamInvitation`,\n// `cancelTeamInvitation`) or by an admin (`adminCreateTeamInvitation`, `adminCancelTeamInvitation`);\n// accepted or declined by the invitee alone (`acceptTeamInvitation`, `rejectTeamInvitation`).\n// ---------------------------------------------------------------------------------------------\n\nexport const CreateTeamInvitationInputSchema = z\n .object({\n teamId: teamIdSchema,\n invitedUserId: userIdSchema,\n message: teamInvitationMessageSchema,\n })\n .strict();\nexport type CreateTeamInvitationInput = z.infer<typeof CreateTeamInvitationInputSchema>;\n\n// Names the invitation a cancel, an acceptance, or a decline acts on.\nexport const TeamInvitationTargetInputSchema = z\n .object({ teamInvitationId: teamInvitationIdSchema })\n .strict();\nexport type TeamInvitationTargetInput = z.infer<typeof TeamInvitationTargetInputSchema>;\n\n// What sending, cancelling, and declining answer with: the invitation and the ids a client names in\n// its domain event.\nexport const TeamInvitationResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n teamInvitationId: teamInvitationIdSchema,\n invitedUserId: userIdSchema,\n })\n .strict();\nexport type TeamInvitationResult = z.infer<typeof TeamInvitationResultSchema>;\n\n// `rosterSyncStatus` is where the new membership's roster work stood when the call returned: the\n// membership is committed either way, and `pending` finishes in the background.\nexport const AcceptTeamInvitationResultSchema = TeamInvitationResultSchema.extend({\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n}).strict();\nexport type AcceptTeamInvitationResult = z.infer<typeof AcceptTeamInvitationResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Join requests — sent and withdrawn by the player (`createTeamJoinRequest`,\n// `cancelTeamJoinRequest`); accepted or rejected by the team's captain or a co-captain\n// (`acceptTeamJoinRequest`, `rejectTeamJoinRequest`) or by an admin (`adminAcceptTeamJoinRequest`,\n// `adminRejectTeamJoinRequest`).\n// ---------------------------------------------------------------------------------------------\n\nexport const CreateTeamJoinRequestInputSchema = z\n .object({ teamId: teamIdSchema, message: teamJoinRequestMessageSchema })\n .strict();\nexport type CreateTeamJoinRequestInput = z.infer<typeof CreateTeamJoinRequestInputSchema>;\n\n// Names the join request a cancel, an acceptance, or a rejection acts on.\nexport const TeamJoinRequestTargetInputSchema = z\n .object({ teamJoinRequestId: teamJoinRequestIdSchema })\n .strict();\nexport type TeamJoinRequestTargetInput = z.infer<typeof TeamJoinRequestTargetInputSchema>;\n\nexport const TeamJoinRequestResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n teamJoinRequestId: teamJoinRequestIdSchema,\n userId: userIdSchema,\n })\n .strict();\nexport type TeamJoinRequestResult = z.infer<typeof TeamJoinRequestResultSchema>;\n\nexport const AcceptTeamJoinRequestResultSchema = TeamJoinRequestResultSchema.extend({\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n}).strict();\nexport type AcceptTeamJoinRequestResult = z.infer<typeof AcceptTeamJoinRequestResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Free agents — a player signs up in a league (`createLeagueFreeAgent`) or withdraws\n// (`deleteLeagueFreeAgent`); an admin places a signed-up player on a team\n// (`adminAssignLeagueFreeAgent`).\n// ---------------------------------------------------------------------------------------------\n\n// The league a player signs up in, or withdraws from. The player is the caller.\nexport const LeagueFreeAgentInputSchema = z.object({ leagueId: leagueIdSchema }).strict();\nexport type LeagueFreeAgentInput = z.infer<typeof LeagueFreeAgentInputSchema>;\n\n// `createdAt` is the signup's own moment: a repeated signup answers the one already on record.\nexport const CreateLeagueFreeAgentResultSchema = z\n .object({ leagueId: leagueIdSchema, userId: userIdSchema, createdAt: epochMsSchema })\n .strict();\nexport type CreateLeagueFreeAgentResult = z.infer<typeof CreateLeagueFreeAgentResultSchema>;\n\n// `deleted` is false when no signup was on record — a repeated withdrawal changes nothing.\nexport const DeleteLeagueFreeAgentResultSchema = z\n .object({ leagueId: leagueIdSchema, userId: userIdSchema, deleted: z.boolean() })\n .strict();\nexport type DeleteLeagueFreeAgentResult = z.infer<typeof DeleteLeagueFreeAgentResultSchema>;\n\nexport const AdminAssignLeagueFreeAgentInputSchema = z\n .object({ leagueId: leagueIdSchema, userId: userIdSchema, teamId: teamIdSchema })\n .strict();\nexport type AdminAssignLeagueFreeAgentInput = z.infer<typeof AdminAssignLeagueFreeAgentInputSchema>;\n\nexport const AdminAssignLeagueFreeAgentResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n })\n .strict();\nexport type AdminAssignLeagueFreeAgentResult = z.infer<\n typeof AdminAssignLeagueFreeAgentResultSchema\n>;\n"]}
1
+ {"version":3,"file":"team-joining.js","sourceRoot":"","sources":["../../src/schemas/team-joining.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for the ways onto a team: an invitation the team sends, a join request the\n// player sends, and a free-agent signup an admin answers by placing the player. Every door that\n// makes a membership ends in the membership core. The acting user is always `request.auth.uid` —\n// never an input field (RULE-STD-ARCH-106) — and the entry, never a field of the payload, decides the\n// authority (RULE-STD-BACKEND-004): each action is its own callable, never a choice made by a payload field\n// (RULE-STD-BACKEND-305).\n\nimport { z } from 'zod';\nimport {\n epochMsSchema,\n leagueIdSchema,\n membershipRosterSyncStatusSchema,\n teamIdSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\nimport {\n teamInvitationIdSchema,\n teamInvitationMessageSchema,\n teamJoinRequestIdSchema,\n teamJoinRequestMessageSchema,\n} from './atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Invitations — sent and withdrawn by the team's captain or a co-captain, or an admin\n// (`createTeamInvitation`, `cancelTeamInvitation`); accepted or declined by the invitee alone\n// (`acceptTeamInvitation`, `rejectTeamInvitation`).\n// ---------------------------------------------------------------------------------------------\n\nexport const CreateTeamInvitationInputSchema = z\n .object({\n teamId: teamIdSchema,\n invitedUserId: userIdSchema,\n message: teamInvitationMessageSchema,\n })\n .strict();\nexport type CreateTeamInvitationInput = z.infer<typeof CreateTeamInvitationInputSchema>;\n\n// Names the invitation a cancel, an acceptance, or a decline acts on.\nexport const TeamInvitationTargetInputSchema = z\n .object({ teamInvitationId: teamInvitationIdSchema })\n .strict();\nexport type TeamInvitationTargetInput = z.infer<typeof TeamInvitationTargetInputSchema>;\n\n// What sending, cancelling, and declining answer with: the invitation and the ids a client names in\n// its domain event.\nexport const TeamInvitationResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n teamInvitationId: teamInvitationIdSchema,\n invitedUserId: userIdSchema,\n })\n .strict();\nexport type TeamInvitationResult = z.infer<typeof TeamInvitationResultSchema>;\n\n// `rosterSyncStatus` is where the new membership's roster work stood when the call returned: the\n// membership is committed either way, and `pending` finishes in the background.\nexport const AcceptTeamInvitationResultSchema = TeamInvitationResultSchema.extend({\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n}).strict();\nexport type AcceptTeamInvitationResult = z.infer<typeof AcceptTeamInvitationResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Join requests — sent and withdrawn by the player (`createTeamJoinRequest`,\n// `cancelTeamJoinRequest`); accepted or rejected by the team's captain or a co-captain, or an admin\n// (`acceptTeamJoinRequest`, `rejectTeamJoinRequest`).\n// ---------------------------------------------------------------------------------------------\n\nexport const CreateTeamJoinRequestInputSchema = z\n .object({ teamId: teamIdSchema, message: teamJoinRequestMessageSchema })\n .strict();\nexport type CreateTeamJoinRequestInput = z.infer<typeof CreateTeamJoinRequestInputSchema>;\n\n// Names the join request a cancel, an acceptance, or a rejection acts on.\nexport const TeamJoinRequestTargetInputSchema = z\n .object({ teamJoinRequestId: teamJoinRequestIdSchema })\n .strict();\nexport type TeamJoinRequestTargetInput = z.infer<typeof TeamJoinRequestTargetInputSchema>;\n\nexport const TeamJoinRequestResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n teamJoinRequestId: teamJoinRequestIdSchema,\n userId: userIdSchema,\n })\n .strict();\nexport type TeamJoinRequestResult = z.infer<typeof TeamJoinRequestResultSchema>;\n\nexport const AcceptTeamJoinRequestResultSchema = TeamJoinRequestResultSchema.extend({\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n}).strict();\nexport type AcceptTeamJoinRequestResult = z.infer<typeof AcceptTeamJoinRequestResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Free agents — a player signs up in a league (`createLeagueFreeAgent`) or withdraws\n// (`deleteLeagueFreeAgent`); an admin places a signed-up player on a team\n// (`adminAssignLeagueFreeAgent`).\n// ---------------------------------------------------------------------------------------------\n\n// The league a player signs up in, or withdraws from. The player is the caller.\nexport const LeagueFreeAgentInputSchema = z.object({ leagueId: leagueIdSchema }).strict();\nexport type LeagueFreeAgentInput = z.infer<typeof LeagueFreeAgentInputSchema>;\n\n// `createdAt` is the signup's own moment: a repeated signup answers the one already on record.\nexport const CreateLeagueFreeAgentResultSchema = z\n .object({ leagueId: leagueIdSchema, userId: userIdSchema, createdAt: epochMsSchema })\n .strict();\nexport type CreateLeagueFreeAgentResult = z.infer<typeof CreateLeagueFreeAgentResultSchema>;\n\n// `deleted` is false when no signup was on record — a repeated withdrawal changes nothing.\nexport const DeleteLeagueFreeAgentResultSchema = z\n .object({ leagueId: leagueIdSchema, userId: userIdSchema, deleted: z.boolean() })\n .strict();\nexport type DeleteLeagueFreeAgentResult = z.infer<typeof DeleteLeagueFreeAgentResultSchema>;\n\nexport const AdminAssignLeagueFreeAgentInputSchema = z\n .object({ leagueId: leagueIdSchema, userId: userIdSchema, teamId: teamIdSchema })\n .strict();\nexport type AdminAssignLeagueFreeAgentInput = z.infer<typeof AdminAssignLeagueFreeAgentInputSchema>;\n\nexport const AdminAssignLeagueFreeAgentResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n })\n .strict();\nexport type AdminAssignLeagueFreeAgentResult = z.infer<\n typeof AdminAssignLeagueFreeAgentResultSchema\n>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/schemas/teams.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/schemas/teams.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  // Callable contracts for teams and team membership. The acting user is always `request.auth.uid` —
2
- // never an input field (RULE-STD-ARCH-106). The entry, never a field of the payload, decides the authority
3
- // (RULE-STD-BACKEND-004); an admin entry's schema adds only what its authority needs.
2
+ // never an input field (RULE-STD-ARCH-106). The server, never a field of the payload, decides the
3
+ // authority (RULE-STD-BACKEND-004); an admin-only action's schema adds only what its authority needs.
4
4
  import { z } from 'zod';
5
5
  import { leagueJoinWarningActedOnSchema, leagueJoinWarningFindingSchema, } from '../utils/league-join-warning.js';
6
6
  import { countSchema, documentIdSegmentSchema, gameIdSchema, leagueIdSchema, membershipRosterSyncStatusSchema, teamIconSchema, teamIdSchema, teamRoleSchema, teamTypeSchema, userIdSchema, } from '../doc-schemas/atoms.js';
@@ -29,10 +29,9 @@ export const CreateLeagueTeamResultSchema = z
29
29
  .object({ leagueId: leagueIdSchema, teamId: teamIdSchema, captainUserId: userIdSchema })
30
30
  .strict();
31
31
  // ---------------------------------------------------------------------------------------------
32
- // Ghost add — one core behind two doors. The team page door (`createTeamGhostPlayer` /
33
- // `adminCreateTeamGhostPlayer`) needs authority over the team; the game page door
34
- // (`createGameGhostPlayer` / `adminCreateGameGhostPlayer`) needs scoring authority over the game
35
- // and adds to one of its two teams. The ghost id is derived by the server from the add's
32
+ // Ghost add — one core behind two doors. The team page door (`createTeamGhostPlayer`) needs
33
+ // authority over the team; the game page door (`createGameGhostPlayer`) needs scoring authority over
34
+ // the game and adds to one of its two teams. The ghost id is derived by the server from the add's
36
35
  // `requestId`, which the client mints once when the add starts and re-sends on every retry, so a
37
36
  // retry after an unknown outcome is recognised as the same add (`buildGhostUserIdForRequest`).
38
37
  // ---------------------------------------------------------------------------------------------
@@ -136,15 +135,15 @@ export const LinkGhostPlayerResultSchema = z
136
135
  export const AdminLinkClosedLeagueGhostPlayerInputSchema = LinkGhostPlayerInputSchema;
137
136
  export const AdminLinkClosedLeagueGhostPlayerResultSchema = LinkGhostPlayerResultSchema;
138
137
  // ---------------------------------------------------------------------------------------------
139
- // Managing a team's members. A role change and a removal each have a member entry — the team's
140
- // captain or a co-captain, read from their membership — and an admin entry; changing the captain,
138
+ // Managing a team's members. A role change and a removal are each one callable for the team's
139
+ // captain or a co-captain, read from their membership, and for an admin; changing the captain,
141
140
  // renaming the team, changing its type, setting its contact phone, and deleting it are admin-only.
142
141
  // Every target is named by id and read server-side; nothing here names who is acting (RULE-STD-ARCH-106).
143
142
  // ---------------------------------------------------------------------------------------------
144
143
  /** A ghost id, refused for any other id, so a removal input cannot name a real account. */
145
144
  export const ghostUserIdSchema = userIdSchema.refine(isGhostUserId, 'Not a ghost player.');
146
- // `updateTeamMembershipRole` (the captain) / `adminUpdateTeamMembershipRole`: promote a player to
147
- // co-captain, or demote a co-captain to player.
145
+ // `updateTeamMembershipRole` (the captain or an admin): promote a player to co-captain, or demote a
146
+ // co-captain to player.
148
147
  export const UpdateTeamMembershipRoleInputSchema = z
149
148
  .object({
150
149
  teamId: teamIdSchema,
@@ -162,8 +161,8 @@ export const UpdateTeamMembershipRoleResultSchema = z
162
161
  changed: z.boolean(),
163
162
  })
164
163
  .strict();
165
- // `deleteTeamMembership` (the captain or a co-captain) / `adminDeleteTeamMembership`: remove a real
166
- // player from the team. A ghost is removed through its own action, below.
164
+ // `deleteTeamMembership` (the captain, a co-captain, or an admin): remove a real player from the
165
+ // team. A ghost is removed through its own action, below.
167
166
  export const DeleteTeamMembershipInputSchema = z
168
167
  .object({
169
168
  teamId: teamIdSchema,
@@ -181,8 +180,8 @@ export const DeleteTeamMembershipResultSchema = z
181
180
  rosterSyncStatus: membershipRosterSyncStatusSchema,
182
181
  })
183
182
  .strict();
184
- // `deleteTeamGhostPlayer` (the captain or a co-captain) / `adminDeleteTeamGhostPlayer`: remove a ghost
185
- // that has never played, completely. A never-played ghost holds no stat, so its removal is not a
183
+ // `deleteTeamGhostPlayer` (the captain, a co-captain, or an admin): remove a ghost that has never
184
+ // played, completely. A never-played ghost holds no stat, so its removal is not a
186
185
  // repair and takes no reason; its audit event still records who removed what (RULE-STD-BACKEND-212).
187
186
  export const DeleteTeamGhostPlayerInputSchema = z
188
187
  .object({ teamId: teamIdSchema, ghostUserId: ghostUserIdSchema })
@@ -1 +1 @@
1
- {"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/schemas/teams.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for teams and team membership. The acting user is always `request.auth.uid` —\n// never an input field (RULE-STD-ARCH-106). The entry, never a field of the payload, decides the authority\n// (RULE-STD-BACKEND-004); an admin entry's schema adds only what its authority needs.\n\nimport { z } from 'zod';\nimport {\n leagueJoinWarningActedOnSchema,\n leagueJoinWarningFindingSchema,\n} from '../utils/league-join-warning.js';\nimport {\n countSchema,\n documentIdSegmentSchema,\n gameIdSchema,\n leagueIdSchema,\n membershipRosterSyncStatusSchema,\n teamIconSchema,\n teamIdSchema,\n teamRoleSchema,\n teamTypeSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\nimport { buildGhostUserIdForRequest, isGhostUserId } from '../ids/minted-ids.js';\nimport { isDocumentIdSegment } from '../paths/utils.js';\nimport { GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS, GHOST_REMOVAL_REFUSAL_KEYS } from '../types/stats.js';\nimport { MEMBER_ASSIGNABLE_TEAM_ROLES } from '../types/unions.js';\nimport { contactPhoneSchema, displayNameSchema, teamNameSchema } from './atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Team creation — `createLeagueTeam` (the creator becomes captain) and `adminCreateLeagueTeam`\n// (an admin creates the team with a newly minted ghost captain). Both write the team's contact\n// phone; `teamType` is read only in a Competitive/Recreational league, which requires it.\n// ---------------------------------------------------------------------------------------------\n\nconst teamCreationFields = {\n leagueId: leagueIdSchema,\n name: teamNameSchema,\n icon: teamIconSchema,\n teamType: teamTypeSchema.optional(),\n contactPhone: contactPhoneSchema,\n};\n\nexport const CreateLeagueTeamInputSchema = z.object(teamCreationFields).strict();\nexport type CreateLeagueTeamInput = z.infer<typeof CreateLeagueTeamInputSchema>;\n\nexport const AdminCreateLeagueTeamInputSchema = z\n .object({ ...teamCreationFields, captainDisplayName: displayNameSchema })\n .strict();\nexport type AdminCreateLeagueTeamInput = z.infer<typeof AdminCreateLeagueTeamInputSchema>;\n\nexport const CreateLeagueTeamResultSchema = z\n .object({ leagueId: leagueIdSchema, teamId: teamIdSchema, captainUserId: userIdSchema })\n .strict();\nexport type CreateLeagueTeamResult = z.infer<typeof CreateLeagueTeamResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Ghost add — one core behind two doors. The team page door (`createTeamGhostPlayer` /\n// `adminCreateTeamGhostPlayer`) needs authority over the team; the game page door\n// (`createGameGhostPlayer` / `adminCreateGameGhostPlayer`) needs scoring authority over the game\n// and adds to one of its two teams. The ghost id is derived by the server from the add's\n// `requestId`, which the client mints once when the add starts and re-sends on every retry, so a\n// retry after an unknown outcome is recognised as the same add (`buildGhostUserIdForRequest`).\n// ---------------------------------------------------------------------------------------------\n\n// One document-id segment (RULE-STD-ARCH-106), short enough that the ghost id derived from it is one too.\nexport const ghostCreateRequestIdSchema = documentIdSegmentSchema.refine(\n (requestId) => isDocumentIdSegment(buildGhostUserIdForRequest(requestId)),\n 'Not a ghost add request id.',\n);\n\nexport const CreateTeamGhostPlayerInputSchema = z\n .object({\n teamId: teamIdSchema,\n displayName: displayNameSchema,\n requestId: ghostCreateRequestIdSchema,\n })\n .strict();\nexport type CreateTeamGhostPlayerInput = z.infer<typeof CreateTeamGhostPlayerInputSchema>;\n\nexport const CreateGameGhostPlayerInputSchema = z\n .object({\n gameId: gameIdSchema,\n teamId: teamIdSchema,\n displayName: displayNameSchema,\n requestId: ghostCreateRequestIdSchema,\n })\n .strict();\nexport type CreateGameGhostPlayerInput = z.infer<typeof CreateGameGhostPlayerInputSchema>;\n\n// `rosterSyncStatus` is where the new membership's roster work stood when the call returned: the\n// membership is committed either way, and `pending` finishes in the background.\nexport const CreateGhostPlayerResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n })\n .strict();\nexport type CreateGhostPlayerResult = z.infer<typeof CreateGhostPlayerResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The join warning — `getLeagueJoinWarning` (the person, or a captain or co-captain of the target\n// team) and `adminGetLeagueJoinWarning` (an admin, about anyone).\n// ---------------------------------------------------------------------------------------------\n\n// `targetTeamId` is the team the door acts for; a free-agent signup and a team being created have\n// none. `actedOn` is the item the door answers, which the warning leaves out.\nexport const GetLeagueJoinWarningInputSchema = z\n .object({\n leagueId: leagueIdSchema,\n userId: userIdSchema,\n targetTeamId: teamIdSchema.optional(),\n actedOn: leagueJoinWarningActedOnSchema.optional(),\n })\n .strict();\nexport type GetLeagueJoinWarningInput = z.infer<typeof GetLeagueJoinWarningInputSchema>;\n\nexport const GetLeagueJoinWarningResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n userId: userIdSchema,\n findings: z.array(leagueJoinWarningFindingSchema),\n })\n .strict();\nexport type GetLeagueJoinWarningResult = z.infer<typeof GetLeagueJoinWarningResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Roster reconciliation recovery — an admin puts a team's failed roster obligations back to work.\n// ---------------------------------------------------------------------------------------------\n\nexport const AdminRetryLeagueTeamRosterSyncInputSchema = z\n .object({ teamId: teamIdSchema })\n .strict();\nexport type AdminRetryLeagueTeamRosterSyncInput = z.infer<\n typeof AdminRetryLeagueTeamRosterSyncInputSchema\n>;\n\nexport const AdminRetryLeagueTeamRosterSyncResultSchema = z\n .object({\n teamId: teamIdSchema,\n // Failed obligations put back to pending.\n retried: countSchema,\n // Of those and any already pending, how many the call itself finished.\n reconciled: countSchema,\n // Failed obligations left as they are because they fail their schema, by document id; a\n // damaged document's id is reported as stored, so it is not held to the membership id format.\n damagedTeamMembershipIds: z.array(z.string().min(1)),\n })\n .strict();\nexport type AdminRetryLeagueTeamRosterSyncResult = z.infer<\n typeof AdminRetryLeagueTeamRosterSyncResultSchema\n>;\n\n// ---------------------------------------------------------------------------------------------\n// Linking a ghost to a real account — `linkGhostPlayerToUser` in a league that is not closed, and\n// `adminLinkClosedLeagueGhostPlayer` in a closed one. Both are admin-only and act on one team. A link\n// takes no reason: the admin chooses the account and confirms, and the link's audit event records\n// who linked which ghost to whom and what moved (RULE-STD-BACKEND-212). The ghost and the account are\n// ids the core checks itself, so a ghost id named as the account, or a real id named as the ghost,\n// is refused with a failure record rather than at the parse. Every name the link records is read\n// server-side, never sent.\n// ---------------------------------------------------------------------------------------------\n\nexport const LinkGhostPlayerInputSchema = z\n .object({\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n userId: userIdSchema,\n })\n .strict();\nexport type LinkGhostPlayerInput = z.infer<typeof LinkGhostPlayerInputSchema>;\n\n// `complete` is false when the call ran out of time part-way: the link stays under way, and the same\n// call by the same account continues it. `membershipOutcome` is present once it is complete.\n// `publicUserDeleted` is false when something else still names the ghost.\nexport const LinkGhostPlayerResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n userId: userIdSchema,\n complete: z.boolean(),\n gamesMoved: countSchema,\n membershipOutcome: z.enum(GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS).optional(),\n publicUserDeleted: z.boolean(),\n })\n .strict();\nexport type LinkGhostPlayerResult = z.infer<typeof LinkGhostPlayerResultSchema>;\n\nexport const AdminLinkClosedLeagueGhostPlayerInputSchema = LinkGhostPlayerInputSchema;\nexport type AdminLinkClosedLeagueGhostPlayerInput = LinkGhostPlayerInput;\nexport const AdminLinkClosedLeagueGhostPlayerResultSchema = LinkGhostPlayerResultSchema;\nexport type AdminLinkClosedLeagueGhostPlayerResult = LinkGhostPlayerResult;\n\n// ---------------------------------------------------------------------------------------------\n// Managing a team's members. A role change and a removal each have a member entry — the team's\n// captain or a co-captain, read from their membership — and an admin entry; changing the captain,\n// renaming the team, changing its type, setting its contact phone, and deleting it are admin-only.\n// Every target is named by id and read server-side; nothing here names who is acting (RULE-STD-ARCH-106).\n// ---------------------------------------------------------------------------------------------\n\n/** A ghost id, refused for any other id, so a removal input cannot name a real account. */\nexport const ghostUserIdSchema = userIdSchema.refine(isGhostUserId, 'Not a ghost player.');\n\n// `updateTeamMembershipRole` (the captain) / `adminUpdateTeamMembershipRole`: promote a player to\n// co-captain, or demote a co-captain to player.\nexport const UpdateTeamMembershipRoleInputSchema = z\n .object({\n teamId: teamIdSchema,\n userId: userIdSchema,\n role: z.enum(MEMBER_ASSIGNABLE_TEAM_ROLES),\n })\n .strict();\nexport type UpdateTeamMembershipRoleInput = z.infer<typeof UpdateTeamMembershipRoleInputSchema>;\n\n// `changed` is false when the member already held the role: nothing was written or recorded.\nexport const UpdateTeamMembershipRoleResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n role: teamRoleSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateTeamMembershipRoleResult = z.infer<typeof UpdateTeamMembershipRoleResultSchema>;\n\n// `deleteTeamMembership` (the captain or a co-captain) / `adminDeleteTeamMembership`: remove a real\n// player from the team. A ghost is removed through its own action, below.\nexport const DeleteTeamMembershipInputSchema = z\n .object({\n teamId: teamIdSchema,\n userId: userIdSchema.refine(\n (userId) => !isGhostUserId(userId),\n 'A ghost player is removed as a ghost player.',\n ),\n })\n .strict();\nexport type DeleteTeamMembershipInput = z.infer<typeof DeleteTeamMembershipInputSchema>;\n\n// `deleted` is false when the person held no membership on the team: nothing was written. The\n// membership is gone either way; `rosterSyncStatus` is where its roster work stood on return.\nexport const DeleteTeamMembershipResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n deleted: z.boolean(),\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n })\n .strict();\nexport type DeleteTeamMembershipResult = z.infer<typeof DeleteTeamMembershipResultSchema>;\n\n// `deleteTeamGhostPlayer` (the captain or a co-captain) / `adminDeleteTeamGhostPlayer`: remove a ghost\n// that has never played, completely. A never-played ghost holds no stat, so its removal is not a\n// repair and takes no reason; its audit event still records who removed what (RULE-STD-BACKEND-212).\nexport const DeleteTeamGhostPlayerInputSchema = z\n .object({ teamId: teamIdSchema, ghostUserId: ghostUserIdSchema })\n .strict();\nexport type DeleteTeamGhostPlayerInput = z.infer<typeof DeleteTeamGhostPlayerInputSchema>;\n\n// `complete` is false when the call ran out of time part-way: the ghost's games stay held and the\n// same call finishes the removal. `finishedGameEntriesRemoved` is the whole removal's count so far,\n// never one call's share, so a later response replaces an earlier one. `publicUserDeleted` is false\n// when something else still names the ghost, so its name stays until that reference goes.\nexport const DeleteTeamGhostPlayerResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n complete: z.boolean(),\n finishedGameEntriesRemoved: countSchema,\n publicUserDeleted: z.boolean(),\n })\n .strict();\nexport type DeleteTeamGhostPlayerResult = z.infer<typeof DeleteTeamGhostPlayerResultSchema>;\n\n// The details of a ghost removal's designed refusal: its reason, and — for a refusal that stops a\n// removal already under way — `finishedGameEntriesRemoved`, the removal's count so far, as the result\n// counts it. Those entries stay removed.\nexport const GhostRemovalRefusalDetailsSchema = z\n .object({\n reason: z.enum(GHOST_REMOVAL_REFUSAL_KEYS),\n finishedGameEntriesRemoved: countSchema.optional(),\n })\n .strict();\nexport type GhostRemovalRefusalDetails = z.infer<typeof GhostRemovalRefusalDetailsSchema>;\n\n// `adminUpdateLeagueTeamCaptain`: make a member of the team its captain. Every other captain the team\n// holds becomes a player.\nexport const AdminUpdateLeagueTeamCaptainInputSchema = z\n .object({ teamId: teamIdSchema, captainUserId: userIdSchema })\n .strict();\nexport type AdminUpdateLeagueTeamCaptainInput = z.infer<\n typeof AdminUpdateLeagueTeamCaptainInputSchema\n>;\n\nexport const AdminUpdateLeagueTeamCaptainResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n captainUserId: userIdSchema,\n demotedUserIds: z.array(userIdSchema),\n changed: z.boolean(),\n })\n .strict();\nexport type AdminUpdateLeagueTeamCaptainResult = z.infer<\n typeof AdminUpdateLeagueTeamCaptainResultSchema\n>;\n\n// `adminUpdateLeagueTeamName`: rename a team. The name lives on the team alone; nothing copies it.\nexport const AdminUpdateLeagueTeamNameInputSchema = z\n .object({ teamId: teamIdSchema, name: teamNameSchema })\n .strict();\nexport type AdminUpdateLeagueTeamNameInput = z.infer<typeof AdminUpdateLeagueTeamNameInputSchema>;\n\n// `adminUpdateLeagueTeamType`: change a team's type in a league that sorts its teams by type.\nexport const AdminUpdateLeagueTeamTypeInputSchema = z\n .object({ teamId: teamIdSchema, teamType: teamTypeSchema })\n .strict();\nexport type AdminUpdateLeagueTeamTypeInput = z.infer<typeof AdminUpdateLeagueTeamTypeInputSchema>;\n\n// The answer to either edit: `changed` is false when the team already held the value.\nexport const AdminUpdateLeagueTeamResultSchema = z\n .object({ leagueId: leagueIdSchema, teamId: teamIdSchema, changed: z.boolean() })\n .strict();\nexport type AdminUpdateLeagueTeamResult = z.infer<typeof AdminUpdateLeagueTeamResultSchema>;\n\n// `adminUpdateLeagueTeamContact`: set the team's contact phone on its admin-only contact document.\nexport const AdminUpdateLeagueTeamContactInputSchema = z\n .object({ teamId: teamIdSchema, contactPhone: contactPhoneSchema })\n .strict();\nexport type AdminUpdateLeagueTeamContactInput = z.infer<\n typeof AdminUpdateLeagueTeamContactInputSchema\n>;\n\nexport const AdminUpdateLeagueTeamContactResultSchema = AdminUpdateLeagueTeamResultSchema;\nexport type AdminUpdateLeagueTeamContactResult = AdminUpdateLeagueTeamResult;\n\n// `adminDeleteLeagueTeam`: delete a team that has never played, with everything that is only its.\n// A never-played team holds no stat, so its deletion is not a repair and takes no reason; its audit\n// event still records who deleted what (RULE-STD-BACKEND-212).\nexport const AdminDeleteLeagueTeamInputSchema = z.object({ teamId: teamIdSchema }).strict();\nexport type AdminDeleteLeagueTeamInput = z.infer<typeof AdminDeleteLeagueTeamInputSchema>;\n\n// `complete` is false when the call ran out of time part-way: what is left stays, the team still\n// stands, and the same call finishes the deletion. `remainingGameCount` is the team's games still to\n// delete when it stopped.\nexport const AdminDeleteLeagueTeamResultSchema = z\n .object({\n teamId: teamIdSchema,\n complete: z.boolean(),\n remainingGameCount: countSchema,\n })\n .strict();\nexport type AdminDeleteLeagueTeamResult = z.infer<typeof AdminDeleteLeagueTeamResultSchema>;\n\n// Why a team's deletion was refused, in the refusal's details: the team has played — a completed\n// game, or a stat in one of its games — whether that is found before anything is deleted or only as a\n// later game is reached. `deletedGameCount` is the unplayed games this request had already deleted\n// when it found the play, 0 when it found it first; those games stay deleted.\nexport const LEAGUE_TEAM_DELETE_REFUSAL_KEYS = ['teamHasPlayed'] as const;\nexport type LeagueTeamDeleteRefusal = (typeof LEAGUE_TEAM_DELETE_REFUSAL_KEYS)[number];\nexport const LeagueTeamDeleteRefusalDetailsSchema = z\n .object({ reason: z.enum(LEAGUE_TEAM_DELETE_REFUSAL_KEYS), deletedGameCount: countSchema })\n .strict();\nexport type LeagueTeamDeleteRefusalDetails = z.infer<typeof LeagueTeamDeleteRefusalDetailsSchema>;\n"]}
1
+ {"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/schemas/teams.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for teams and team membership. The acting user is always `request.auth.uid` —\n// never an input field (RULE-STD-ARCH-106). The server, never a field of the payload, decides the\n// authority (RULE-STD-BACKEND-004); an admin-only action's schema adds only what its authority needs.\n\nimport { z } from 'zod';\nimport {\n leagueJoinWarningActedOnSchema,\n leagueJoinWarningFindingSchema,\n} from '../utils/league-join-warning.js';\nimport {\n countSchema,\n documentIdSegmentSchema,\n gameIdSchema,\n leagueIdSchema,\n membershipRosterSyncStatusSchema,\n teamIconSchema,\n teamIdSchema,\n teamRoleSchema,\n teamTypeSchema,\n userIdSchema,\n} from '../doc-schemas/atoms.js';\nimport { buildGhostUserIdForRequest, isGhostUserId } from '../ids/minted-ids.js';\nimport { isDocumentIdSegment } from '../paths/utils.js';\nimport { GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS, GHOST_REMOVAL_REFUSAL_KEYS } from '../types/stats.js';\nimport { MEMBER_ASSIGNABLE_TEAM_ROLES } from '../types/unions.js';\nimport { contactPhoneSchema, displayNameSchema, teamNameSchema } from './atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Team creation — `createLeagueTeam` (the creator becomes captain) and `adminCreateLeagueTeam`\n// (an admin creates the team with a newly minted ghost captain). Both write the team's contact\n// phone; `teamType` is read only in a Competitive/Recreational league, which requires it.\n// ---------------------------------------------------------------------------------------------\n\nconst teamCreationFields = {\n leagueId: leagueIdSchema,\n name: teamNameSchema,\n icon: teamIconSchema,\n teamType: teamTypeSchema.optional(),\n contactPhone: contactPhoneSchema,\n};\n\nexport const CreateLeagueTeamInputSchema = z.object(teamCreationFields).strict();\nexport type CreateLeagueTeamInput = z.infer<typeof CreateLeagueTeamInputSchema>;\n\nexport const AdminCreateLeagueTeamInputSchema = z\n .object({ ...teamCreationFields, captainDisplayName: displayNameSchema })\n .strict();\nexport type AdminCreateLeagueTeamInput = z.infer<typeof AdminCreateLeagueTeamInputSchema>;\n\nexport const CreateLeagueTeamResultSchema = z\n .object({ leagueId: leagueIdSchema, teamId: teamIdSchema, captainUserId: userIdSchema })\n .strict();\nexport type CreateLeagueTeamResult = z.infer<typeof CreateLeagueTeamResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Ghost add — one core behind two doors. The team page door (`createTeamGhostPlayer`) needs\n// authority over the team; the game page door (`createGameGhostPlayer`) needs scoring authority over\n// the game and adds to one of its two teams. The ghost id is derived by the server from the add's\n// `requestId`, which the client mints once when the add starts and re-sends on every retry, so a\n// retry after an unknown outcome is recognised as the same add (`buildGhostUserIdForRequest`).\n// ---------------------------------------------------------------------------------------------\n\n// One document-id segment (RULE-STD-ARCH-106), short enough that the ghost id derived from it is one too.\nexport const ghostCreateRequestIdSchema = documentIdSegmentSchema.refine(\n (requestId) => isDocumentIdSegment(buildGhostUserIdForRequest(requestId)),\n 'Not a ghost add request id.',\n);\n\nexport const CreateTeamGhostPlayerInputSchema = z\n .object({\n teamId: teamIdSchema,\n displayName: displayNameSchema,\n requestId: ghostCreateRequestIdSchema,\n })\n .strict();\nexport type CreateTeamGhostPlayerInput = z.infer<typeof CreateTeamGhostPlayerInputSchema>;\n\nexport const CreateGameGhostPlayerInputSchema = z\n .object({\n gameId: gameIdSchema,\n teamId: teamIdSchema,\n displayName: displayNameSchema,\n requestId: ghostCreateRequestIdSchema,\n })\n .strict();\nexport type CreateGameGhostPlayerInput = z.infer<typeof CreateGameGhostPlayerInputSchema>;\n\n// `rosterSyncStatus` is where the new membership's roster work stood when the call returned: the\n// membership is committed either way, and `pending` finishes in the background.\nexport const CreateGhostPlayerResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n })\n .strict();\nexport type CreateGhostPlayerResult = z.infer<typeof CreateGhostPlayerResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The join warning — `getLeagueJoinWarning` (the person, or a captain or co-captain of the target\n// team) and `adminGetLeagueJoinWarning` (an admin, about anyone).\n// ---------------------------------------------------------------------------------------------\n\n// `targetTeamId` is the team the door acts for; a free-agent signup and a team being created have\n// none. `actedOn` is the item the door answers, which the warning leaves out.\nexport const GetLeagueJoinWarningInputSchema = z\n .object({\n leagueId: leagueIdSchema,\n userId: userIdSchema,\n targetTeamId: teamIdSchema.optional(),\n actedOn: leagueJoinWarningActedOnSchema.optional(),\n })\n .strict();\nexport type GetLeagueJoinWarningInput = z.infer<typeof GetLeagueJoinWarningInputSchema>;\n\nexport const GetLeagueJoinWarningResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n userId: userIdSchema,\n findings: z.array(leagueJoinWarningFindingSchema),\n })\n .strict();\nexport type GetLeagueJoinWarningResult = z.infer<typeof GetLeagueJoinWarningResultSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// Roster reconciliation recovery — an admin puts a team's failed roster obligations back to work.\n// ---------------------------------------------------------------------------------------------\n\nexport const AdminRetryLeagueTeamRosterSyncInputSchema = z\n .object({ teamId: teamIdSchema })\n .strict();\nexport type AdminRetryLeagueTeamRosterSyncInput = z.infer<\n typeof AdminRetryLeagueTeamRosterSyncInputSchema\n>;\n\nexport const AdminRetryLeagueTeamRosterSyncResultSchema = z\n .object({\n teamId: teamIdSchema,\n // Failed obligations put back to pending.\n retried: countSchema,\n // Of those and any already pending, how many the call itself finished.\n reconciled: countSchema,\n // Failed obligations left as they are because they fail their schema, by document id; a\n // damaged document's id is reported as stored, so it is not held to the membership id format.\n damagedTeamMembershipIds: z.array(z.string().min(1)),\n })\n .strict();\nexport type AdminRetryLeagueTeamRosterSyncResult = z.infer<\n typeof AdminRetryLeagueTeamRosterSyncResultSchema\n>;\n\n// ---------------------------------------------------------------------------------------------\n// Linking a ghost to a real account — `linkGhostPlayerToUser` in a league that is not closed, and\n// `adminLinkClosedLeagueGhostPlayer` in a closed one. Both are admin-only and act on one team. A link\n// takes no reason: the admin chooses the account and confirms, and the link's audit event records\n// who linked which ghost to whom and what moved (RULE-STD-BACKEND-212). The ghost and the account are\n// ids the core checks itself, so a ghost id named as the account, or a real id named as the ghost,\n// is refused with a failure record rather than at the parse. Every name the link records is read\n// server-side, never sent.\n// ---------------------------------------------------------------------------------------------\n\nexport const LinkGhostPlayerInputSchema = z\n .object({\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n userId: userIdSchema,\n })\n .strict();\nexport type LinkGhostPlayerInput = z.infer<typeof LinkGhostPlayerInputSchema>;\n\n// `complete` is false when the call ran out of time part-way: the link stays under way, and the same\n// call by the same account continues it. `membershipOutcome` is present once it is complete.\n// `publicUserDeleted` is false when something else still names the ghost.\nexport const LinkGhostPlayerResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n userId: userIdSchema,\n complete: z.boolean(),\n gamesMoved: countSchema,\n membershipOutcome: z.enum(GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS).optional(),\n publicUserDeleted: z.boolean(),\n })\n .strict();\nexport type LinkGhostPlayerResult = z.infer<typeof LinkGhostPlayerResultSchema>;\n\nexport const AdminLinkClosedLeagueGhostPlayerInputSchema = LinkGhostPlayerInputSchema;\nexport type AdminLinkClosedLeagueGhostPlayerInput = LinkGhostPlayerInput;\nexport const AdminLinkClosedLeagueGhostPlayerResultSchema = LinkGhostPlayerResultSchema;\nexport type AdminLinkClosedLeagueGhostPlayerResult = LinkGhostPlayerResult;\n\n// ---------------------------------------------------------------------------------------------\n// Managing a team's members. A role change and a removal are each one callable for the team's\n// captain or a co-captain, read from their membership, and for an admin; changing the captain,\n// renaming the team, changing its type, setting its contact phone, and deleting it are admin-only.\n// Every target is named by id and read server-side; nothing here names who is acting (RULE-STD-ARCH-106).\n// ---------------------------------------------------------------------------------------------\n\n/** A ghost id, refused for any other id, so a removal input cannot name a real account. */\nexport const ghostUserIdSchema = userIdSchema.refine(isGhostUserId, 'Not a ghost player.');\n\n// `updateTeamMembershipRole` (the captain or an admin): promote a player to co-captain, or demote a\n// co-captain to player.\nexport const UpdateTeamMembershipRoleInputSchema = z\n .object({\n teamId: teamIdSchema,\n userId: userIdSchema,\n role: z.enum(MEMBER_ASSIGNABLE_TEAM_ROLES),\n })\n .strict();\nexport type UpdateTeamMembershipRoleInput = z.infer<typeof UpdateTeamMembershipRoleInputSchema>;\n\n// `changed` is false when the member already held the role: nothing was written or recorded.\nexport const UpdateTeamMembershipRoleResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n role: teamRoleSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type UpdateTeamMembershipRoleResult = z.infer<typeof UpdateTeamMembershipRoleResultSchema>;\n\n// `deleteTeamMembership` (the captain, a co-captain, or an admin): remove a real player from the\n// team. A ghost is removed through its own action, below.\nexport const DeleteTeamMembershipInputSchema = z\n .object({\n teamId: teamIdSchema,\n userId: userIdSchema.refine(\n (userId) => !isGhostUserId(userId),\n 'A ghost player is removed as a ghost player.',\n ),\n })\n .strict();\nexport type DeleteTeamMembershipInput = z.infer<typeof DeleteTeamMembershipInputSchema>;\n\n// `deleted` is false when the person held no membership on the team: nothing was written. The\n// membership is gone either way; `rosterSyncStatus` is where its roster work stood on return.\nexport const DeleteTeamMembershipResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n deleted: z.boolean(),\n rosterSyncStatus: membershipRosterSyncStatusSchema,\n })\n .strict();\nexport type DeleteTeamMembershipResult = z.infer<typeof DeleteTeamMembershipResultSchema>;\n\n// `deleteTeamGhostPlayer` (the captain, a co-captain, or an admin): remove a ghost that has never\n// played, completely. A never-played ghost holds no stat, so its removal is not a\n// repair and takes no reason; its audit event still records who removed what (RULE-STD-BACKEND-212).\nexport const DeleteTeamGhostPlayerInputSchema = z\n .object({ teamId: teamIdSchema, ghostUserId: ghostUserIdSchema })\n .strict();\nexport type DeleteTeamGhostPlayerInput = z.infer<typeof DeleteTeamGhostPlayerInputSchema>;\n\n// `complete` is false when the call ran out of time part-way: the ghost's games stay held and the\n// same call finishes the removal. `finishedGameEntriesRemoved` is the whole removal's count so far,\n// never one call's share, so a later response replaces an earlier one. `publicUserDeleted` is false\n// when something else still names the ghost, so its name stays until that reference goes.\nexport const DeleteTeamGhostPlayerResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n complete: z.boolean(),\n finishedGameEntriesRemoved: countSchema,\n publicUserDeleted: z.boolean(),\n })\n .strict();\nexport type DeleteTeamGhostPlayerResult = z.infer<typeof DeleteTeamGhostPlayerResultSchema>;\n\n// The details of a ghost removal's designed refusal: its reason, and — for a refusal that stops a\n// removal already under way — `finishedGameEntriesRemoved`, the removal's count so far, as the result\n// counts it. Those entries stay removed.\nexport const GhostRemovalRefusalDetailsSchema = z\n .object({\n reason: z.enum(GHOST_REMOVAL_REFUSAL_KEYS),\n finishedGameEntriesRemoved: countSchema.optional(),\n })\n .strict();\nexport type GhostRemovalRefusalDetails = z.infer<typeof GhostRemovalRefusalDetailsSchema>;\n\n// `adminUpdateLeagueTeamCaptain`: make a member of the team its captain. Every other captain the team\n// holds becomes a player.\nexport const AdminUpdateLeagueTeamCaptainInputSchema = z\n .object({ teamId: teamIdSchema, captainUserId: userIdSchema })\n .strict();\nexport type AdminUpdateLeagueTeamCaptainInput = z.infer<\n typeof AdminUpdateLeagueTeamCaptainInputSchema\n>;\n\nexport const AdminUpdateLeagueTeamCaptainResultSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n captainUserId: userIdSchema,\n demotedUserIds: z.array(userIdSchema),\n changed: z.boolean(),\n })\n .strict();\nexport type AdminUpdateLeagueTeamCaptainResult = z.infer<\n typeof AdminUpdateLeagueTeamCaptainResultSchema\n>;\n\n// `adminUpdateLeagueTeamName`: rename a team. The name lives on the team alone; nothing copies it.\nexport const AdminUpdateLeagueTeamNameInputSchema = z\n .object({ teamId: teamIdSchema, name: teamNameSchema })\n .strict();\nexport type AdminUpdateLeagueTeamNameInput = z.infer<typeof AdminUpdateLeagueTeamNameInputSchema>;\n\n// `adminUpdateLeagueTeamType`: change a team's type in a league that sorts its teams by type.\nexport const AdminUpdateLeagueTeamTypeInputSchema = z\n .object({ teamId: teamIdSchema, teamType: teamTypeSchema })\n .strict();\nexport type AdminUpdateLeagueTeamTypeInput = z.infer<typeof AdminUpdateLeagueTeamTypeInputSchema>;\n\n// The answer to either edit: `changed` is false when the team already held the value.\nexport const AdminUpdateLeagueTeamResultSchema = z\n .object({ leagueId: leagueIdSchema, teamId: teamIdSchema, changed: z.boolean() })\n .strict();\nexport type AdminUpdateLeagueTeamResult = z.infer<typeof AdminUpdateLeagueTeamResultSchema>;\n\n// `adminUpdateLeagueTeamContact`: set the team's contact phone on its admin-only contact document.\nexport const AdminUpdateLeagueTeamContactInputSchema = z\n .object({ teamId: teamIdSchema, contactPhone: contactPhoneSchema })\n .strict();\nexport type AdminUpdateLeagueTeamContactInput = z.infer<\n typeof AdminUpdateLeagueTeamContactInputSchema\n>;\n\nexport const AdminUpdateLeagueTeamContactResultSchema = AdminUpdateLeagueTeamResultSchema;\nexport type AdminUpdateLeagueTeamContactResult = AdminUpdateLeagueTeamResult;\n\n// `adminDeleteLeagueTeam`: delete a team that has never played, with everything that is only its.\n// A never-played team holds no stat, so its deletion is not a repair and takes no reason; its audit\n// event still records who deleted what (RULE-STD-BACKEND-212).\nexport const AdminDeleteLeagueTeamInputSchema = z.object({ teamId: teamIdSchema }).strict();\nexport type AdminDeleteLeagueTeamInput = z.infer<typeof AdminDeleteLeagueTeamInputSchema>;\n\n// `complete` is false when the call ran out of time part-way: what is left stays, the team still\n// stands, and the same call finishes the deletion. `remainingGameCount` is the team's games still to\n// delete when it stopped.\nexport const AdminDeleteLeagueTeamResultSchema = z\n .object({\n teamId: teamIdSchema,\n complete: z.boolean(),\n remainingGameCount: countSchema,\n })\n .strict();\nexport type AdminDeleteLeagueTeamResult = z.infer<typeof AdminDeleteLeagueTeamResultSchema>;\n\n// Why a team's deletion was refused, in the refusal's details: the team has played — a completed\n// game, or a stat in one of its games — whether that is found before anything is deleted or only as a\n// later game is reached. `deletedGameCount` is the unplayed games this request had already deleted\n// when it found the play, 0 when it found it first; those games stay deleted.\nexport const LEAGUE_TEAM_DELETE_REFUSAL_KEYS = ['teamHasPlayed'] as const;\nexport type LeagueTeamDeleteRefusal = (typeof LEAGUE_TEAM_DELETE_REFUSAL_KEYS)[number];\nexport const LeagueTeamDeleteRefusalDetailsSchema = z\n .object({ reason: z.enum(LEAGUE_TEAM_DELETE_REFUSAL_KEYS), deletedGameCount: countSchema })\n .strict();\nexport type LeagueTeamDeleteRefusalDetails = z.infer<typeof LeagueTeamDeleteRefusalDetailsSchema>;\n"]}
@@ -4,11 +4,11 @@ export declare const AUDIT_EVENT_TYPE_KEYS: readonly ["user.accountRegistered",
4
4
  export type AuditEventType = (typeof AUDIT_EVENT_TYPE_KEYS)[number];
5
5
  export declare const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS: readonly ["ghostPlayer.linked", "ghostPlayer.closedLeagueLinked"];
6
6
  export type GhostLinkAuditEventType = (typeof GHOST_LINK_AUDIT_EVENT_TYPE_KEYS)[number];
7
- export declare const AUDIT_ACTOR_MODE_KEYS: readonly ["user", "teamManager", "adminReview", "adminOverride", "system"];
7
+ export declare const AUDIT_ACTOR_MODE_KEYS: readonly ["user", "teammateUser", "adminReview", "adminOverride", "system"];
8
8
  export type AuditActorMode = (typeof AUDIT_ACTOR_MODE_KEYS)[number];
9
9
  export declare const AUDIT_ADMIN_ACTOR_MODE_KEYS: readonly ["adminReview", "adminOverride"];
10
10
  export type AuditAdminActorMode = (typeof AUDIT_ADMIN_ACTOR_MODE_KEYS)[number];
11
- export declare const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS: readonly ["user", "teamManager", "system"];
11
+ export declare const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS: readonly ["user", "teammateUser", "system"];
12
12
  export type AuditNonAdminActorMode = (typeof AUDIT_NON_ADMIN_ACTOR_MODE_KEYS)[number];
13
13
  export declare const AUDIT_SYSTEM_REASON_KEYS: readonly ["trigger", "scheduledJob", "migration"];
14
14
  export type AuditSystemReason = (typeof AUDIT_SYSTEM_REASON_KEYS)[number];
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,qBAAqB,0xEA2IxB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIpE,eAAO,MAAM,gCAAgC,mEAGC,CAAC;AAC/C,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC;AAUxF,eAAO,MAAM,qBAAqB,4EAMxB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,2BAA2B,2CAGM,CAAC;AAC/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/E,eAAO,MAAM,+BAA+B,4CAIE,CAAC;AAC/C,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtF,eAAO,MAAM,wBAAwB,mDAAoD,CAAC;AAC1F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAMlE,MAAM,MAAM,UAAU,GAClB;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,sBAAsB,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/F;IACE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEN,MAAM,WAAW,WAAW;IAE1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,iCAAkC,CAAC;AACjE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,qBAAqB,0xEA2IxB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIpE,eAAO,MAAM,gCAAgC,mEAGC,CAAC;AAC/C,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC;AAYxF,eAAO,MAAM,qBAAqB,6EAMxB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,2BAA2B,2CAGM,CAAC;AAC/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/E,eAAO,MAAM,+BAA+B,6CAIE,CAAC;AAC/C,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtF,eAAO,MAAM,wBAAwB,mDAAoD,CAAC;AAC1F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAMlE,MAAM,MAAM,UAAU,GAClB;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,sBAAsB,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/F;IACE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEN,MAAM,WAAW,WAAW;IAE1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,iCAAkC,CAAC;AACjE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -153,13 +153,15 @@ export const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS = [
153
153
  // orthogonal to the event type: one event type is produced under several modes, and the mode is what
154
154
  // tells an ordinary action from an admin override.
155
155
  // user a signed-in account acting on its own behalf
156
- // teamManager a captain or co-captain acting through their team's membership permissions
156
+ // teammateUser a member acting inside a team they belong to: a captain or co-captain acting
157
+ // through their membership, for the team or a player on it
157
158
  // adminReview an admin or referee doing admin work that no team permission covers
158
- // adminOverride an admin or referee superseding the team permission a normal entry checks
159
+ // adminOverride an admin or referee acting through their role on a team-scoped action no
160
+ // membership of theirs admits
159
161
  // system backend automation with no human caller
160
162
  export const AUDIT_ACTOR_MODE_KEYS = [
161
163
  'user',
162
- 'teamManager',
164
+ 'teammateUser',
163
165
  'adminReview',
164
166
  'adminOverride',
165
167
  'system',
@@ -170,7 +172,7 @@ export const AUDIT_ADMIN_ACTOR_MODE_KEYS = [
170
172
  ];
171
173
  export const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS = [
172
174
  'user',
173
- 'teamManager',
175
+ 'teammateUser',
174
176
  'system',
175
177
  ];
176
178
  export const AUDIT_SYSTEM_REASON_KEYS = ['trigger', 'scheduledJob', 'migration'];
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"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","sourcesContent":["// The audit vocabulary: the closed event-type union (RULE-STD-BACKEND-202) and how an actor was acting\n// (RULE-STD-BACKEND-205). The document schema is in ../doc-schemas/audit-event.ts.\n//\n// The union is closed: a new sensitive action adds its event types here, in the same change\n// (RULE-STD-BACKEND-202).\n\nimport type { SystemRole } from './unions.js';\nimport { CAPTAIN_TEAM_ROLES } from './unions.js';\n\nexport const AUDIT_EVENT_TYPE_KEYS = [\n // Accounts\n 'user.accountRegistered',\n 'user.displayNameChanged',\n // The scheduled sweep deleted a sign-in account that never finished registering (no profile)\n 'user.abandonedRegistrationDeleted',\n // A successful sign-up or sign-in, and a completed password reset, recorded after the fact from\n // Identity Platform's user-activity log\n 'user.signedIn',\n 'user.passwordResetCompleted',\n // Account status — an admin banned an account or lifted its ban\n 'user.accountBanned',\n 'user.accountUnbanned',\n // Global roles — the policy decision (callable) and the claim propagation (trigger)\n 'admin.systemRoleGranted',\n 'admin.systemRoleRevoked',\n 'admin.systemRoleClaimSynced',\n // App configuration — the operational levers on `_appConfig/app`, and the landing page copy\n 'appConfig.updated',\n 'landingPage.updated',\n // Leagues — created, settings edited, status moved, mode switched\n 'league.created',\n 'league.updated',\n 'league.statusChanged',\n 'league.modeSwitched',\n // Waiver templates — created, a new wording published, retired or deleted\n 'waiverTemplate.created',\n 'waiverTemplate.versionPublished',\n 'waiverTemplate.retired',\n 'waiverTemplate.deleted',\n // Game locations\n 'gameLocation.created',\n 'gameLocation.updated',\n 'gameLocation.deleted',\n // Pictures — published to a gallery or a slot by the picture processor (attributed to the admin\n // who uploaded it), and ordered, featured, and removed by the admin picture callables\n 'picture.added',\n 'picture.replaced',\n 'picture.moved',\n 'picture.featuredChanged',\n 'picture.removed',\n // Awards — an award created by its first badge's publication, its badge replaced, the award\n // deleted once nobody holds it, and an award granted to or revoked from one account\n 'award.created',\n 'award.badgeReplaced',\n 'award.deleted',\n 'award.granted',\n 'award.revoked',\n // Hardware contracts — a loan created for a referee, signed by them, its equipment returned, and a\n // contract never signed deleted\n 'hardwareLoanContract.created',\n 'hardwareLoanContract.signed',\n 'hardwareLoanContract.returned',\n 'hardwareLoanContract.deleted',\n // Teams — created with its captain, a ghost player added, a team's failed roster work retried\n 'leagueTeam.created',\n 'ghostPlayer.created',\n 'teamRoster.syncRetried',\n // Team management — a member promoted to co-captain or demoted to player, the captain changed by\n // an admin, the team's name or type edited by an admin, and its contact phone set by an admin\n 'teamMembership.roleChanged',\n 'leagueTeam.captainChanged',\n 'leagueTeam.updated',\n 'leagueTeamContact.updated',\n // Exits — a membership removed, a never-played ghost removed, a ghost linked by either link, and a\n // never-played team deleted; each targets what it deleted, which the migration's live\n // verifications read as proof the product removed it\n 'teamMembership.removed',\n 'ghostPlayer.removed',\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n 'leagueTeam.deleted',\n // A ghost's removal stopped part-way because the ghost came to have played: the games it held are\n // released, and the finished-game entries it had already taken off are named\n 'ghostPlayer.removalStopped',\n // Joining a team — an invitation sent, withdrawn, accepted, or declined; a join request sent,\n // withdrawn, accepted, or rejected; a free-agent signup made, withdrawn, or answered by an admin\n // placing the player on a team\n 'teamInvitation.created',\n 'teamInvitation.cancelled',\n 'teamInvitation.accepted',\n 'teamInvitation.rejected',\n 'teamJoinRequest.created',\n 'teamJoinRequest.cancelled',\n 'teamJoinRequest.accepted',\n 'teamJoinRequest.rejected',\n 'leagueFreeAgent.created',\n 'leagueFreeAgent.deleted',\n 'leagueFreeAgent.assigned',\n // Signed waivers — a legal record, signed by its subject or witnessed for a ghost\n 'signedWaiver.created',\n // Schedules — a week created with its games or its shared fields edited; one game added, edited\n // (moved, rescheduled, or its teams replaced), or deleted with its events and roster\n 'scheduleWeek.created',\n 'scheduleWeek.updated',\n 'sportGame.created',\n 'sportGame.updated',\n 'sportGame.deleted',\n // Live scoring — a scoring write refused its caller's authority (a click writes no success event:\n // the stat event document is its own record), a roster entry marked absent or present, a\n // scorer's note on one person changed, and the jump-ball possession arrow moved\n 'sportGame.statEventsRejected',\n 'sportGame.absenceChanged',\n 'sportGame.memoUpdated',\n 'sportGame.jumpBallChanged',\n // Finalizing — a game finalized, its numbers made permanent in every derived destination, and an\n // admin's reopening of a finalized game, which takes them back out\n 'sportGame.finalized',\n 'sportGame.reopened',\n // Fix stats — a game's numbers corrected (targets, or the stored numbers kept) or restored from\n // its events; a derived aggregate rebuilt; and a person's pre-Q-Sports baseline written\n 'sportGame.statsCorrected',\n 'sportGame.statsRecalculated',\n 'stats.aggregateRecalculated',\n 'stats.historicalStatsUpdated',\n // A stats check ran to its end: its scope, its summary, and its counts by kind.\n 'stats.validationRun',\n // An admin deleted a stats check's report: its id, scope, summary, and counts by kind.\n 'stats.validationReportDeleted',\n // The migration's placement of a recorded stat line no roster entry or play could place: the\n // admin names the team, and the game's copy places the line there\n 'stats.unrosteredStatLineResolved',\n // Admin notifications — a shared card archived, which takes it off every admin's list; and an\n // admin's archive-all decision, recorded once when the job is written, with the request's origin\n 'adminNotification.archived',\n 'adminNotification.archiveAllRequested',\n // An operator's manual intervention in a durable pipeline — a dead-lettered row put back to work,\n // or a refused attempt at one — with the reason the operator gave\n 'system.manualIntervention',\n // The migration console — one page of a cutover action run, with what it read, wrote, and found;\n // the documents an action core wrote and removed, committed in the same batch or transaction as\n // those writes (its action id, operation id, and document ids only — RULE-STD-BACKEND-203); a product\n // control's run recorded once its evidence checked; an operator checkpoint recorded with its\n // evidence; and the cutover, after which the product owns every destination\n 'migrationAction.pageRun',\n 'migrationAction.writesCommitted',\n 'migrationAction.controlRecorded',\n 'migrationAction.checkpointRecorded',\n 'migrationConsole.cutoverRecorded',\n] as const;\nexport type AuditEventType = (typeof AUDIT_EVENT_TYPE_KEYS)[number];\n\n// The two ways a ghost is linked to an account — the normal link and the closed-league link — each\n// committing its own event over the one artifact-moving core.\nexport const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS = [\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n] as const satisfies readonly AuditEventType[];\nexport type GhostLinkAuditEventType = (typeof GHOST_LINK_AUDIT_EVENT_TYPE_KEYS)[number];\n\n// How the actor was acting for the write — never merely which authorities they happen to hold. It is\n// orthogonal to the event type: one event type is produced under several modes, and the mode is what\n// tells an ordinary action from an admin override.\n// user a signed-in account acting on its own behalf\n// teamManager a captain or co-captain acting through their team's membership permissions\n// adminReview an admin or referee doing admin work that no team permission covers\n// adminOverride an admin or referee superseding the team permission a normal entry checks\n// system backend automation with no human caller\nexport const AUDIT_ACTOR_MODE_KEYS = [\n 'user',\n 'teamManager',\n 'adminReview',\n 'adminOverride',\n 'system',\n] as const;\nexport type AuditActorMode = (typeof AUDIT_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_ADMIN_ACTOR_MODE_KEYS = [\n 'adminReview',\n 'adminOverride',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditAdminActorMode = (typeof AUDIT_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS = [\n 'user',\n 'teamManager',\n 'system',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditNonAdminActorMode = (typeof AUDIT_NON_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_SYSTEM_REASON_KEYS = ['trigger', 'scheduledJob', 'migration'] as const;\nexport type AuditSystemReason = (typeof AUDIT_SYSTEM_REASON_KEYS)[number];\n\nexport type CaptainTeamRole = (typeof CAPTAIN_TEAM_ROLES)[number];\n\n// `isAdmin` is metadata only: it records that the caller's token carried a global-role claim (admin\n// or referee) when they acted, and grants nothing. `systemRole` is required on the admin modes and\n// forbidden on the others, so an admin action is never recorded without the authority it used and a\n// non-admin action never carries one.\nexport type AuditActor =\n | { uid: string | null; isAdmin: boolean; actorMode: AuditNonAdminActorMode; systemRole?: never }\n | {\n uid: string | null;\n isAdmin: boolean;\n actorMode: AuditAdminActorMode;\n systemRole: SystemRole;\n };\n\nexport interface AuditTarget {\n // The user the action was performed on, when there is one.\n uid: string | null;\n // The slash path of the document the action changed, when there is one.\n ref: string | null;\n}\n\nexport const AUDIT_RESULT_KEYS = ['success', 'failure'] as const;\nexport type AuditResult = (typeof AUDIT_RESULT_KEYS)[number];\n"]}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,mFAAmF;AACnF,EAAE;AACF,4FAA4F;AAC5F,0BAA0B;AAK1B,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,WAAW;IACX,wBAAwB;IACxB,yBAAyB;IACzB,6FAA6F;IAC7F,mCAAmC;IACnC,gGAAgG;IAChG,wCAAwC;IACxC,eAAe;IACf,6BAA6B;IAC7B,gEAAgE;IAChE,oBAAoB;IACpB,sBAAsB;IACtB,oFAAoF;IACpF,yBAAyB;IACzB,yBAAyB;IACzB,6BAA6B;IAC7B,4FAA4F;IAC5F,mBAAmB;IACnB,qBAAqB;IACrB,kEAAkE;IAClE,gBAAgB;IAChB,gBAAgB;IAChB,sBAAsB;IACtB,qBAAqB;IACrB,0EAA0E;IAC1E,wBAAwB;IACxB,iCAAiC;IACjC,wBAAwB;IACxB,wBAAwB;IACxB,iBAAiB;IACjB,sBAAsB;IACtB,sBAAsB;IACtB,sBAAsB;IACtB,gGAAgG;IAChG,sFAAsF;IACtF,eAAe;IACf,kBAAkB;IAClB,eAAe;IACf,yBAAyB;IACzB,iBAAiB;IACjB,4FAA4F;IAC5F,oFAAoF;IACpF,eAAe;IACf,qBAAqB;IACrB,eAAe;IACf,eAAe;IACf,eAAe;IACf,mGAAmG;IACnG,gCAAgC;IAChC,8BAA8B;IAC9B,6BAA6B;IAC7B,+BAA+B;IAC/B,8BAA8B;IAC9B,8FAA8F;IAC9F,oBAAoB;IACpB,qBAAqB;IACrB,wBAAwB;IACxB,iGAAiG;IACjG,8FAA8F;IAC9F,4BAA4B;IAC5B,2BAA2B;IAC3B,oBAAoB;IACpB,2BAA2B;IAC3B,mGAAmG;IACnG,sFAAsF;IACtF,qDAAqD;IACrD,wBAAwB;IACxB,qBAAqB;IACrB,oBAAoB;IACpB,gCAAgC;IAChC,oBAAoB;IACpB,kGAAkG;IAClG,6EAA6E;IAC7E,4BAA4B;IAC5B,8FAA8F;IAC9F,iGAAiG;IACjG,+BAA+B;IAC/B,wBAAwB;IACxB,0BAA0B;IAC1B,yBAAyB;IACzB,yBAAyB;IACzB,yBAAyB;IACzB,2BAA2B;IAC3B,0BAA0B;IAC1B,0BAA0B;IAC1B,yBAAyB;IACzB,yBAAyB;IACzB,0BAA0B;IAC1B,kFAAkF;IAClF,sBAAsB;IACtB,gGAAgG;IAChG,qFAAqF;IACrF,sBAAsB;IACtB,sBAAsB;IACtB,mBAAmB;IACnB,mBAAmB;IACnB,mBAAmB;IACnB,kGAAkG;IAClG,yFAAyF;IACzF,gFAAgF;IAChF,8BAA8B;IAC9B,0BAA0B;IAC1B,uBAAuB;IACvB,2BAA2B;IAC3B,iGAAiG;IACjG,mEAAmE;IACnE,qBAAqB;IACrB,oBAAoB;IACpB,gGAAgG;IAChG,wFAAwF;IACxF,0BAA0B;IAC1B,6BAA6B;IAC7B,6BAA6B;IAC7B,8BAA8B;IAC9B,gFAAgF;IAChF,qBAAqB;IACrB,uFAAuF;IACvF,+BAA+B;IAC/B,6FAA6F;IAC7F,kEAAkE;IAClE,kCAAkC;IAClC,8FAA8F;IAC9F,iGAAiG;IACjG,4BAA4B;IAC5B,uCAAuC;IACvC,kGAAkG;IAClG,kEAAkE;IAClE,2BAA2B;IAC3B,iGAAiG;IACjG,gGAAgG;IAChG,sGAAsG;IACtG,6FAA6F;IAC7F,4EAA4E;IAC5E,yBAAyB;IACzB,iCAAiC;IACjC,iCAAiC;IACjC,oCAAoC;IACpC,kCAAkC;CAC1B,CAAC;AAGX,mGAAmG;AACnG,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,oBAAoB;IACpB,gCAAgC;CACY,CAAC;AAG/C,qGAAqG;AACrG,qGAAqG;AACrG,mDAAmD;AACnD,+DAA+D;AAC/D,+FAA+F;AAC/F,2EAA2E;AAC3E,sFAAsF;AACtF,2FAA2F;AAC3F,8CAA8C;AAC9C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,MAAM;IACN,cAAc;IACd,aAAa;IACb,eAAe;IACf,QAAQ;CACA,CAAC;AAGX,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,aAAa;IACb,eAAe;CAC6B,CAAC;AAG/C,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,MAAM;IACN,cAAc;IACd,QAAQ;CACoC,CAAC;AAG/C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,WAAW,CAAU,CAAC;AAyB1F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,SAAS,CAAU,CAAC","sourcesContent":["// The audit vocabulary: the closed event-type union (RULE-STD-BACKEND-202) and how an actor was acting\n// (RULE-STD-BACKEND-205). The document schema is in ../doc-schemas/audit-event.ts.\n//\n// The union is closed: a new sensitive action adds its event types here, in the same change\n// (RULE-STD-BACKEND-202).\n\nimport type { SystemRole } from './unions.js';\nimport { CAPTAIN_TEAM_ROLES } from './unions.js';\n\nexport const AUDIT_EVENT_TYPE_KEYS = [\n // Accounts\n 'user.accountRegistered',\n 'user.displayNameChanged',\n // The scheduled sweep deleted a sign-in account that never finished registering (no profile)\n 'user.abandonedRegistrationDeleted',\n // A successful sign-up or sign-in, and a completed password reset, recorded after the fact from\n // Identity Platform's user-activity log\n 'user.signedIn',\n 'user.passwordResetCompleted',\n // Account status — an admin banned an account or lifted its ban\n 'user.accountBanned',\n 'user.accountUnbanned',\n // Global roles — the policy decision (callable) and the claim propagation (trigger)\n 'admin.systemRoleGranted',\n 'admin.systemRoleRevoked',\n 'admin.systemRoleClaimSynced',\n // App configuration — the operational levers on `_appConfig/app`, and the landing page copy\n 'appConfig.updated',\n 'landingPage.updated',\n // Leagues — created, settings edited, status moved, mode switched\n 'league.created',\n 'league.updated',\n 'league.statusChanged',\n 'league.modeSwitched',\n // Waiver templates — created, a new wording published, retired or deleted\n 'waiverTemplate.created',\n 'waiverTemplate.versionPublished',\n 'waiverTemplate.retired',\n 'waiverTemplate.deleted',\n // Game locations\n 'gameLocation.created',\n 'gameLocation.updated',\n 'gameLocation.deleted',\n // Pictures — published to a gallery or a slot by the picture processor (attributed to the admin\n // who uploaded it), and ordered, featured, and removed by the admin picture callables\n 'picture.added',\n 'picture.replaced',\n 'picture.moved',\n 'picture.featuredChanged',\n 'picture.removed',\n // Awards — an award created by its first badge's publication, its badge replaced, the award\n // deleted once nobody holds it, and an award granted to or revoked from one account\n 'award.created',\n 'award.badgeReplaced',\n 'award.deleted',\n 'award.granted',\n 'award.revoked',\n // Hardware contracts — a loan created for a referee, signed by them, its equipment returned, and a\n // contract never signed deleted\n 'hardwareLoanContract.created',\n 'hardwareLoanContract.signed',\n 'hardwareLoanContract.returned',\n 'hardwareLoanContract.deleted',\n // Teams — created with its captain, a ghost player added, a team's failed roster work retried\n 'leagueTeam.created',\n 'ghostPlayer.created',\n 'teamRoster.syncRetried',\n // Team management — a member promoted to co-captain or demoted to player, the captain changed by\n // an admin, the team's name or type edited by an admin, and its contact phone set by an admin\n 'teamMembership.roleChanged',\n 'leagueTeam.captainChanged',\n 'leagueTeam.updated',\n 'leagueTeamContact.updated',\n // Exits — a membership removed, a never-played ghost removed, a ghost linked by either link, and a\n // never-played team deleted; each targets what it deleted, which the migration's live\n // verifications read as proof the product removed it\n 'teamMembership.removed',\n 'ghostPlayer.removed',\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n 'leagueTeam.deleted',\n // A ghost's removal stopped part-way because the ghost came to have played: the games it held are\n // released, and the finished-game entries it had already taken off are named\n 'ghostPlayer.removalStopped',\n // Joining a team — an invitation sent, withdrawn, accepted, or declined; a join request sent,\n // withdrawn, accepted, or rejected; a free-agent signup made, withdrawn, or answered by an admin\n // placing the player on a team\n 'teamInvitation.created',\n 'teamInvitation.cancelled',\n 'teamInvitation.accepted',\n 'teamInvitation.rejected',\n 'teamJoinRequest.created',\n 'teamJoinRequest.cancelled',\n 'teamJoinRequest.accepted',\n 'teamJoinRequest.rejected',\n 'leagueFreeAgent.created',\n 'leagueFreeAgent.deleted',\n 'leagueFreeAgent.assigned',\n // Signed waivers — a legal record, signed by its subject or witnessed for a ghost\n 'signedWaiver.created',\n // Schedules — a week created with its games or its shared fields edited; one game added, edited\n // (moved, rescheduled, or its teams replaced), or deleted with its events and roster\n 'scheduleWeek.created',\n 'scheduleWeek.updated',\n 'sportGame.created',\n 'sportGame.updated',\n 'sportGame.deleted',\n // Live scoring — a scoring write refused its caller's authority (a click writes no success event:\n // the stat event document is its own record), a roster entry marked absent or present, a\n // scorer's note on one person changed, and the jump-ball possession arrow moved\n 'sportGame.statEventsRejected',\n 'sportGame.absenceChanged',\n 'sportGame.memoUpdated',\n 'sportGame.jumpBallChanged',\n // Finalizing — a game finalized, its numbers made permanent in every derived destination, and an\n // admin's reopening of a finalized game, which takes them back out\n 'sportGame.finalized',\n 'sportGame.reopened',\n // Fix stats — a game's numbers corrected (targets, or the stored numbers kept) or restored from\n // its events; a derived aggregate rebuilt; and a person's pre-Q-Sports baseline written\n 'sportGame.statsCorrected',\n 'sportGame.statsRecalculated',\n 'stats.aggregateRecalculated',\n 'stats.historicalStatsUpdated',\n // A stats check ran to its end: its scope, its summary, and its counts by kind.\n 'stats.validationRun',\n // An admin deleted a stats check's report: its id, scope, summary, and counts by kind.\n 'stats.validationReportDeleted',\n // The migration's placement of a recorded stat line no roster entry or play could place: the\n // admin names the team, and the game's copy places the line there\n 'stats.unrosteredStatLineResolved',\n // Admin notifications — a shared card archived, which takes it off every admin's list; and an\n // admin's archive-all decision, recorded once when the job is written, with the request's origin\n 'adminNotification.archived',\n 'adminNotification.archiveAllRequested',\n // An operator's manual intervention in a durable pipeline — a dead-lettered row put back to work,\n // or a refused attempt at one — with the reason the operator gave\n 'system.manualIntervention',\n // The migration console — one page of a cutover action run, with what it read, wrote, and found;\n // the documents an action core wrote and removed, committed in the same batch or transaction as\n // those writes (its action id, operation id, and document ids only — RULE-STD-BACKEND-203); a product\n // control's run recorded once its evidence checked; an operator checkpoint recorded with its\n // evidence; and the cutover, after which the product owns every destination\n 'migrationAction.pageRun',\n 'migrationAction.writesCommitted',\n 'migrationAction.controlRecorded',\n 'migrationAction.checkpointRecorded',\n 'migrationConsole.cutoverRecorded',\n] as const;\nexport type AuditEventType = (typeof AUDIT_EVENT_TYPE_KEYS)[number];\n\n// The two ways a ghost is linked to an account — the normal link and the closed-league link — each\n// committing its own event over the one artifact-moving core.\nexport const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS = [\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n] as const satisfies readonly AuditEventType[];\nexport type GhostLinkAuditEventType = (typeof GHOST_LINK_AUDIT_EVENT_TYPE_KEYS)[number];\n\n// How the actor was acting for the write — never merely which authorities they happen to hold. It is\n// orthogonal to the event type: one event type is produced under several modes, and the mode is what\n// tells an ordinary action from an admin override.\n// user a signed-in account acting on its own behalf\n// teammateUser a member acting inside a team they belong to: a captain or co-captain acting\n// through their membership, for the team or a player on it\n// adminReview an admin or referee doing admin work that no team permission covers\n// adminOverride an admin or referee acting through their role on a team-scoped action no\n// membership of theirs admits\n// system backend automation with no human caller\nexport const AUDIT_ACTOR_MODE_KEYS = [\n 'user',\n 'teammateUser',\n 'adminReview',\n 'adminOverride',\n 'system',\n] as const;\nexport type AuditActorMode = (typeof AUDIT_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_ADMIN_ACTOR_MODE_KEYS = [\n 'adminReview',\n 'adminOverride',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditAdminActorMode = (typeof AUDIT_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS = [\n 'user',\n 'teammateUser',\n 'system',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditNonAdminActorMode = (typeof AUDIT_NON_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_SYSTEM_REASON_KEYS = ['trigger', 'scheduledJob', 'migration'] as const;\nexport type AuditSystemReason = (typeof AUDIT_SYSTEM_REASON_KEYS)[number];\n\nexport type CaptainTeamRole = (typeof CAPTAIN_TEAM_ROLES)[number];\n\n// `isAdmin` is metadata only: it records that the caller's token carried a global-role claim (admin\n// or referee) when they acted, and grants nothing. `systemRole` is required on the admin modes and\n// forbidden on the others, so an admin action is never recorded without the authority it used and a\n// non-admin action never carries one.\nexport type AuditActor =\n | { uid: string | null; isAdmin: boolean; actorMode: AuditNonAdminActorMode; systemRole?: never }\n | {\n uid: string | null;\n isAdmin: boolean;\n actorMode: AuditAdminActorMode;\n systemRole: SystemRole;\n };\n\nexport interface AuditTarget {\n // The user the action was performed on, when there is one.\n uid: string | null;\n // The slash path of the document the action changed, when there is one.\n ref: string | null;\n}\n\nexport const AUDIT_RESULT_KEYS = ['success', 'failure'] as const;\nexport type AuditResult = (typeof AUDIT_RESULT_KEYS)[number];\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { CaptainTeamRole } from '../types/audit.js';
2
2
  import { type TeamRole } from '../types/unions.js';
3
- /** An action on a member taken through its admin entry, under the admin role. */
3
+ /** An action on a member taken under the admin role, where no captaincy on the team admits the caller. */
4
4
  export declare const TEAM_MEMBER_ADMIN_ACTOR: "admin";
5
5
  /** The authority an action on a member is taken under: an admin, or the caller's role on the team. */
6
6
  export type TeamMemberActor = typeof TEAM_MEMBER_ADMIN_ACTOR | CaptainTeamRole;
@@ -1 +1 @@
1
- {"version":3,"file":"team-member-actions.d.ts","sourceRoot":"","sources":["../../src/utils/team-member-actions.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAE5B,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,SAAwC,CAAC;AAE7E,sGAAsG;AACtG,MAAM,MAAM,eAAe,GAAG,OAAO,uBAAuB,GAAG,eAAe,CAAC;AAE/E,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAC;CACjB;AAID,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,gBAAgB,GACvB,iBAAiB,CAQnB"}
1
+ {"version":3,"file":"team-member-actions.d.ts","sourceRoot":"","sources":["../../src/utils/team-member-actions.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAE5B,0GAA0G;AAC1G,eAAO,MAAM,uBAAuB,SAAwC,CAAC;AAE7E,sGAAsG;AACtG,MAAM,MAAM,eAAe,GAAG,OAAO,uBAAuB,GAAG,eAAe,CAAC;AAE/E,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAC;CACjB;AAID,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,gBAAgB,GACvB,iBAAiB,CAQnB"}
@@ -10,7 +10,7 @@
10
10
  // A ghost leaves through its own removal, which decides whether it has played; that is still a
11
11
  // removal here.
12
12
  import { TEAM_CAPTAIN_ROLE, TEAM_CO_CAPTAIN_ROLE, TEAM_PLAYER_ROLE, } from '../types/unions.js';
13
- /** An action on a member taken through its admin entry, under the admin role. */
13
+ /** An action on a member taken under the admin role, where no captaincy on the team admits the caller. */
14
14
  export const TEAM_MEMBER_ADMIN_ACTOR = 'admin';
15
15
  const NONE = { promote: false, demote: false, remove: false };
16
16
  export function teamMemberActions(actor, target) {
@@ -1 +1 @@
1
- {"version":3,"file":"team-member-actions.js","sourceRoot":"","sources":["../../src/utils/team-member-actions.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,kGAAkG;AAClG,8GAA8G;AAC9G,EAAE;AACF,4FAA4F;AAC5F,sGAAsG;AACtG,uCAAuC;AACvC,2FAA2F;AAC3F,EAAE;AACF,+FAA+F;AAC/F,gBAAgB;AAGhB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GAGjB,MAAM,oBAAoB,CAAC;AAE5B,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAqC,CAAC;AAoB7E,MAAM,IAAI,GAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAEjF,MAAM,UAAU,iBAAiB,CAC/B,KAAsB,EACtB,MAAwB;IAExB,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,iBAAiB,GAAG,KAAK,KAAK,uBAAuB,IAAI,KAAK,KAAK,iBAAiB,CAAC;IAC3F,OAAO;QACL,OAAO,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,OAAO;QACjF,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB;QACjE,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;KAC9D,CAAC;AACJ,CAAC","sourcesContent":["// What a team leader or an admin may do to one member of a team: promote a player to co-captain,\n// demote a co-captain to player, or remove them. The team's management callables refuse what this\n// leaves out, and the team page and the admin Teams tab offer exactly what it allows (RULE-STD-FRONTEND-110):\n//\n// - the captain is never moved or removed here — an admin changes the team's captain first;\n// - only the captain and an admin promote or demote, and a ghost is never made a co-captain, since no\n// one could act with that authority;\n// - a co-captain removes plain players only — never another co-captain, never the captain.\n//\n// A ghost leaves through its own removal, which decides whether it has played; that is still a\n// removal here.\n\nimport type { CaptainTeamRole } from '../types/audit.js';\nimport {\n TEAM_CAPTAIN_ROLE,\n TEAM_CO_CAPTAIN_ROLE,\n TEAM_PLAYER_ROLE,\n type SystemRole,\n type TeamRole,\n} from '../types/unions.js';\n\n/** An action on a member taken through its admin entry, under the admin role. */\nexport const TEAM_MEMBER_ADMIN_ACTOR = 'admin' as const satisfies SystemRole;\n\n/** The authority an action on a member is taken under: an admin, or the caller's role on the team. */\nexport type TeamMemberActor = typeof TEAM_MEMBER_ADMIN_ACTOR | CaptainTeamRole;\n\n/** The member acted on: their role on the team, and whether they are a ghost. */\nexport interface TeamMemberTarget {\n role: TeamRole;\n isGhost: boolean;\n}\n\nexport interface TeamMemberActions {\n /** Make the player a co-captain. */\n promote: boolean;\n /** Make the co-captain a player. */\n demote: boolean;\n /** Take them off the team — a ghost through the ghost removal. */\n remove: boolean;\n}\n\nconst NONE: TeamMemberActions = { promote: false, demote: false, remove: false };\n\nexport function teamMemberActions(\n actor: TeamMemberActor,\n target: TeamMemberTarget,\n): TeamMemberActions {\n if (target.role === TEAM_CAPTAIN_ROLE) return NONE;\n const managesCoCaptains = actor === TEAM_MEMBER_ADMIN_ACTOR || actor === TEAM_CAPTAIN_ROLE;\n return {\n promote: managesCoCaptains && target.role === TEAM_PLAYER_ROLE && !target.isGhost,\n demote: managesCoCaptains && target.role === TEAM_CO_CAPTAIN_ROLE,\n remove: managesCoCaptains || target.role === TEAM_PLAYER_ROLE,\n };\n}\n"]}
1
+ {"version":3,"file":"team-member-actions.js","sourceRoot":"","sources":["../../src/utils/team-member-actions.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,kGAAkG;AAClG,8GAA8G;AAC9G,EAAE;AACF,4FAA4F;AAC5F,sGAAsG;AACtG,uCAAuC;AACvC,2FAA2F;AAC3F,EAAE;AACF,+FAA+F;AAC/F,gBAAgB;AAGhB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GAGjB,MAAM,oBAAoB,CAAC;AAE5B,0GAA0G;AAC1G,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAqC,CAAC;AAoB7E,MAAM,IAAI,GAAsB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAEjF,MAAM,UAAU,iBAAiB,CAC/B,KAAsB,EACtB,MAAwB;IAExB,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,iBAAiB,GAAG,KAAK,KAAK,uBAAuB,IAAI,KAAK,KAAK,iBAAiB,CAAC;IAC3F,OAAO;QACL,OAAO,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,MAAM,CAAC,OAAO;QACjF,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB;QACjE,MAAM,EAAE,iBAAiB,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;KAC9D,CAAC;AACJ,CAAC","sourcesContent":["// What a team leader or an admin may do to one member of a team: promote a player to co-captain,\n// demote a co-captain to player, or remove them. The team's management callables refuse what this\n// leaves out, and the team page and the admin Teams tab offer exactly what it allows (RULE-STD-FRONTEND-110):\n//\n// - the captain is never moved or removed here — an admin changes the team's captain first;\n// - only the captain and an admin promote or demote, and a ghost is never made a co-captain, since no\n// one could act with that authority;\n// - a co-captain removes plain players only — never another co-captain, never the captain.\n//\n// A ghost leaves through its own removal, which decides whether it has played; that is still a\n// removal here.\n\nimport type { CaptainTeamRole } from '../types/audit.js';\nimport {\n TEAM_CAPTAIN_ROLE,\n TEAM_CO_CAPTAIN_ROLE,\n TEAM_PLAYER_ROLE,\n type SystemRole,\n type TeamRole,\n} from '../types/unions.js';\n\n/** An action on a member taken under the admin role, where no captaincy on the team admits the caller. */\nexport const TEAM_MEMBER_ADMIN_ACTOR = 'admin' as const satisfies SystemRole;\n\n/** The authority an action on a member is taken under: an admin, or the caller's role on the team. */\nexport type TeamMemberActor = typeof TEAM_MEMBER_ADMIN_ACTOR | CaptainTeamRole;\n\n/** The member acted on: their role on the team, and whether they are a ghost. */\nexport interface TeamMemberTarget {\n role: TeamRole;\n isGhost: boolean;\n}\n\nexport interface TeamMemberActions {\n /** Make the player a co-captain. */\n promote: boolean;\n /** Make the co-captain a player. */\n demote: boolean;\n /** Take them off the team — a ghost through the ghost removal. */\n remove: boolean;\n}\n\nconst NONE: TeamMemberActions = { promote: false, demote: false, remove: false };\n\nexport function teamMemberActions(\n actor: TeamMemberActor,\n target: TeamMemberTarget,\n): TeamMemberActions {\n if (target.role === TEAM_CAPTAIN_ROLE) return NONE;\n const managesCoCaptains = actor === TEAM_MEMBER_ADMIN_ACTOR || actor === TEAM_CAPTAIN_ROLE;\n return {\n promote: managesCoCaptains && target.role === TEAM_PLAYER_ROLE && !target.isGhost,\n demote: managesCoCaptains && target.role === TEAM_CO_CAPTAIN_ROLE,\n remove: managesCoCaptains || target.role === TEAM_PLAYER_ROLE,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/q-core",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "Core types, Firestore path constants, zod schemas, and shared constants for Q-Sports",
5
5
  "repository": {
6
6
  "type": "git",