@ttt-productions/q-core 0.1.20 → 0.1.22

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.
Files changed (204) hide show
  1. package/dist/constants/business.js +2 -2
  2. package/dist/constants/business.js.map +1 -1
  3. package/dist/constants/deployment.d.ts +2 -0
  4. package/dist/constants/deployment.d.ts.map +1 -0
  5. package/dist/constants/deployment.js +2 -0
  6. package/dist/constants/deployment.js.map +1 -0
  7. package/dist/constants/index.d.ts +1 -0
  8. package/dist/constants/index.d.ts.map +1 -1
  9. package/dist/constants/index.js +1 -0
  10. package/dist/constants/index.js.map +1 -1
  11. package/dist/constants/media.js +1 -1
  12. package/dist/constants/media.js.map +1 -1
  13. package/dist/constants/sports.js +1 -1
  14. package/dist/constants/sports.js.map +1 -1
  15. package/dist/constants/telemetry.js +3 -3
  16. package/dist/constants/telemetry.js.map +1 -1
  17. package/dist/doc-schemas/admin-notifications.js +3 -3
  18. package/dist/doc-schemas/admin-notifications.js.map +1 -1
  19. package/dist/doc-schemas/aggregate-stats.js +3 -3
  20. package/dist/doc-schemas/aggregate-stats.js.map +1 -1
  21. package/dist/doc-schemas/atoms.d.ts +1 -1
  22. package/dist/doc-schemas/atoms.js +3 -3
  23. package/dist/doc-schemas/atoms.js.map +1 -1
  24. package/dist/doc-schemas/audit-event.js +2 -2
  25. package/dist/doc-schemas/audit-event.js.map +1 -1
  26. package/dist/doc-schemas/firestore-primitives.js +1 -1
  27. package/dist/doc-schemas/firestore-primitives.js.map +1 -1
  28. package/dist/doc-schemas/game-location.js +2 -2
  29. package/dist/doc-schemas/game-location.js.map +1 -1
  30. package/dist/doc-schemas/game-stat-history.js +1 -1
  31. package/dist/doc-schemas/game-stat-history.js.map +1 -1
  32. package/dist/doc-schemas/game-stats.js +6 -6
  33. package/dist/doc-schemas/game-stats.js.map +1 -1
  34. package/dist/doc-schemas/league-team.js +4 -4
  35. package/dist/doc-schemas/league-team.js.map +1 -1
  36. package/dist/doc-schemas/membership-roster-sync.js +2 -2
  37. package/dist/doc-schemas/membership-roster-sync.js.map +1 -1
  38. package/dist/doc-schemas/pending-media.d.ts +6 -6
  39. package/dist/doc-schemas/publicUser.js +1 -1
  40. package/dist/doc-schemas/publicUser.js.map +1 -1
  41. package/dist/doc-schemas/registration-start.js +1 -1
  42. package/dist/doc-schemas/registration-start.js.map +1 -1
  43. package/dist/doc-schemas/registry.d.ts +3 -3
  44. package/dist/doc-schemas/sport-game.js +4 -4
  45. package/dist/doc-schemas/sport-game.js.map +1 -1
  46. package/dist/doc-schemas/sport-league.js +1 -1
  47. package/dist/doc-schemas/sport-league.js.map +1 -1
  48. package/dist/doc-schemas/stats-operation.js +2 -2
  49. package/dist/doc-schemas/stats-operation.js.map +1 -1
  50. package/dist/doc-schemas/status-reconcile-queue.js +1 -1
  51. package/dist/doc-schemas/status-reconcile-queue.js.map +1 -1
  52. package/dist/doc-schemas/sweep-state.js +2 -2
  53. package/dist/doc-schemas/sweep-state.js.map +1 -1
  54. package/dist/doc-schemas/team-membership.js +1 -1
  55. package/dist/doc-schemas/team-membership.js.map +1 -1
  56. package/dist/doc-schemas/user-profile.js +1 -1
  57. package/dist/doc-schemas/user-profile.js.map +1 -1
  58. package/dist/doc-schemas/waiver-template.js +1 -1
  59. package/dist/doc-schemas/waiver-template.js.map +1 -1
  60. package/dist/doc-schemas/waivers-and-hardware.js +3 -3
  61. package/dist/doc-schemas/waivers-and-hardware.js.map +1 -1
  62. package/dist/domain-events/domain-events.js +2 -2
  63. package/dist/domain-events/domain-events.js.map +1 -1
  64. package/dist/ids/award-grant-ids.js +1 -1
  65. package/dist/ids/award-grant-ids.js.map +1 -1
  66. package/dist/ids/compound-ids.js +1 -1
  67. package/dist/ids/compound-ids.js.map +1 -1
  68. package/dist/ids/minted-ids.js +1 -1
  69. package/dist/ids/minted-ids.js.map +1 -1
  70. package/dist/ids/notification-ids.js +1 -1
  71. package/dist/ids/notification-ids.js.map +1 -1
  72. package/dist/ids/stat-event-ids.d.ts +1 -1
  73. package/dist/ids/stat-event-ids.js +2 -2
  74. package/dist/ids/stat-event-ids.js.map +1 -1
  75. package/dist/ids/stats-operation-ids.js +1 -1
  76. package/dist/ids/stats-operation-ids.js.map +1 -1
  77. package/dist/index.js +1 -1
  78. package/dist/index.js.map +1 -1
  79. package/dist/input-formats/input-formats.js +1 -1
  80. package/dist/input-formats/input-formats.js.map +1 -1
  81. package/dist/media/file-origins.js +1 -1
  82. package/dist/media/file-origins.js.map +1 -1
  83. package/dist/media/picture-url.js +1 -1
  84. package/dist/media/picture-url.js.map +1 -1
  85. package/dist/migration-console/action-ids.js +1 -1
  86. package/dist/migration-console/action-ids.js.map +1 -1
  87. package/dist/migration-console/manifest.js +1 -1
  88. package/dist/migration-console/manifest.js.map +1 -1
  89. package/dist/notifications/admin-notification-config.js +1 -1
  90. package/dist/notifications/admin-notification-config.js.map +1 -1
  91. package/dist/notifications/occurrences.js +1 -1
  92. package/dist/notifications/occurrences.js.map +1 -1
  93. package/dist/paths/collections.js +3 -3
  94. package/dist/paths/collections.js.map +1 -1
  95. package/dist/paths/picture-owner-paths.js +1 -1
  96. package/dist/paths/picture-owner-paths.js.map +1 -1
  97. package/dist/paths/storage-paths.d.ts +1 -1
  98. package/dist/paths/storage-paths.js +1 -1
  99. package/dist/paths/storage-paths.js.map +1 -1
  100. package/dist/paths/utils.d.ts +1 -1
  101. package/dist/paths/utils.js +1 -1
  102. package/dist/paths/utils.js.map +1 -1
  103. package/dist/schemas/admin-notifications.js +1 -1
  104. package/dist/schemas/admin-notifications.js.map +1 -1
  105. package/dist/schemas/app-config.js +1 -1
  106. package/dist/schemas/app-config.js.map +1 -1
  107. package/dist/schemas/awards.js +1 -1
  108. package/dist/schemas/awards.js.map +1 -1
  109. package/dist/schemas/dead-letters.js +2 -2
  110. package/dist/schemas/dead-letters.js.map +1 -1
  111. package/dist/schemas/leagues.js +1 -1
  112. package/dist/schemas/leagues.js.map +1 -1
  113. package/dist/schemas/migration-console.js +1 -1
  114. package/dist/schemas/migration-console.js.map +1 -1
  115. package/dist/schemas/pictures.js +1 -1
  116. package/dist/schemas/pictures.js.map +1 -1
  117. package/dist/schemas/schedules.js +2 -2
  118. package/dist/schemas/schedules.js.map +1 -1
  119. package/dist/schemas/scoring.js +1 -1
  120. package/dist/schemas/scoring.js.map +1 -1
  121. package/dist/schemas/signed-waivers.js +1 -1
  122. package/dist/schemas/signed-waivers.js.map +1 -1
  123. package/dist/schemas/stats.js +6 -6
  124. package/dist/schemas/stats.js.map +1 -1
  125. package/dist/schemas/team-joining.js +3 -3
  126. package/dist/schemas/team-joining.js.map +1 -1
  127. package/dist/schemas/teams.js +7 -7
  128. package/dist/schemas/teams.js.map +1 -1
  129. package/dist/schemas/users.js +3 -3
  130. package/dist/schemas/users.js.map +1 -1
  131. package/dist/sports/basketball-scoring.js +4 -4
  132. package/dist/sports/basketball-scoring.js.map +1 -1
  133. package/dist/sports/bulk-entry.js +1 -1
  134. package/dist/sports/bulk-entry.js.map +1 -1
  135. package/dist/sports/contribution.d.ts +5 -5
  136. package/dist/sports/contribution.d.ts.map +1 -1
  137. package/dist/sports/contribution.js +4 -4
  138. package/dist/sports/contribution.js.map +1 -1
  139. package/dist/sports/curling-scoring.js +2 -2
  140. package/dist/sports/curling-scoring.js.map +1 -1
  141. package/dist/sports/football-scoring.js +2 -2
  142. package/dist/sports/football-scoring.js.map +1 -1
  143. package/dist/sports/index.js +1 -1
  144. package/dist/sports/index.js.map +1 -1
  145. package/dist/sports/ledger-continuity.js +1 -1
  146. package/dist/sports/ledger-continuity.js.map +1 -1
  147. package/dist/sports/registry.js +2 -2
  148. package/dist/sports/registry.js.map +1 -1
  149. package/dist/sports/replay.js +1 -1
  150. package/dist/sports/replay.js.map +1 -1
  151. package/dist/sports/rollup-check.js +1 -1
  152. package/dist/sports/rollup-check.js.map +1 -1
  153. package/dist/sports/score-mirror.js +1 -1
  154. package/dist/sports/score-mirror.js.map +1 -1
  155. package/dist/sports/scoring-display.d.ts +1 -1
  156. package/dist/sports/scoring-display.js +2 -2
  157. package/dist/sports/scoring-display.js.map +1 -1
  158. package/dist/sports/scoring.d.ts +5 -5
  159. package/dist/sports/scoring.d.ts.map +1 -1
  160. package/dist/sports/scoring.js +2 -2
  161. package/dist/sports/scoring.js.map +1 -1
  162. package/dist/sports/sport-adapter.d.ts +3 -3
  163. package/dist/sports/sport-adapter.d.ts.map +1 -1
  164. package/dist/sports/sport-adapter.js +2 -2
  165. package/dist/sports/sport-adapter.js.map +1 -1
  166. package/dist/sports/store-driver.d.ts +1 -1
  167. package/dist/sports/store-driver.d.ts.map +1 -1
  168. package/dist/sports/store-driver.js +2 -2
  169. package/dist/sports/store-driver.js.map +1 -1
  170. package/dist/types/audit.js +4 -4
  171. package/dist/types/audit.js.map +1 -1
  172. package/dist/types/claims.js +1 -1
  173. package/dist/types/claims.js.map +1 -1
  174. package/dist/types/picture-owners.js +1 -1
  175. package/dist/types/picture-owners.js.map +1 -1
  176. package/dist/types/schedules.js +1 -1
  177. package/dist/types/schedules.js.map +1 -1
  178. package/dist/types/sports.js +2 -2
  179. package/dist/types/sports.js.map +1 -1
  180. package/dist/types/stats.js +5 -5
  181. package/dist/types/stats.js.map +1 -1
  182. package/dist/types/unions.js +2 -2
  183. package/dist/types/unions.js.map +1 -1
  184. package/dist/types/uploads.js +1 -1
  185. package/dist/types/uploads.js.map +1 -1
  186. package/dist/upload-variables/sign-hardware-contract-variables.js +1 -1
  187. package/dist/upload-variables/sign-hardware-contract-variables.js.map +1 -1
  188. package/dist/upload-variables/sign-waiver-variables.js +1 -1
  189. package/dist/upload-variables/sign-waiver-variables.js.map +1 -1
  190. package/dist/utils/account-status.js +1 -1
  191. package/dist/utils/account-status.js.map +1 -1
  192. package/dist/utils/app-routes.js +1 -1
  193. package/dist/utils/app-routes.js.map +1 -1
  194. package/dist/utils/league-join-warning.js +1 -1
  195. package/dist/utils/league-join-warning.js.map +1 -1
  196. package/dist/utils/league-joining.js +1 -1
  197. package/dist/utils/league-joining.js.map +1 -1
  198. package/dist/utils/league-mode.js +1 -1
  199. package/dist/utils/league-mode.js.map +1 -1
  200. package/dist/utils/team-creation.js +1 -1
  201. package/dist/utils/team-creation.js.map +1 -1
  202. package/dist/utils/team-member-actions.js +1 -1
  203. package/dist/utils/team-member-actions.js.map +1 -1
  204. package/package.json +4 -4
@@ -11,9 +11,9 @@ 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
12
  // `finalizeGame` (a captain or co-captain of either team) / `adminFinalizeGame` (an admin or a
13
13
  // referee): make a game's numbers permanent. Everything it writes is derived server-side from the
14
- // game's events; nothing in the input is a number (SPORT-202).
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
- // `alreadyFinalized` when the game was completed before the call: nothing was written (SPORT-203).
16
+ // `alreadyFinalized` when the game was completed before the call: nothing was written (RULE-QS-SPORT-923).
17
17
  export const FinalizeGameResultSchema = z
18
18
  .object({
19
19
  gameId: gameIdSchema,
@@ -23,7 +23,7 @@ export const FinalizeGameResultSchema = z
23
23
  })
24
24
  .strict();
25
25
  // `reopenGame` (an admin): take a finalized game's numbers back out so it can be scored again. It
26
- // changes a completed record, so the admin says why (SPORT-206, BACKEND-212).
26
+ // changes a completed record, so the admin says why (RULE-QS-SPORT-926, RULE-STD-BACKEND-212).
27
27
  export const ReopenGameInputSchema = z
28
28
  .object({ gameId: gameIdSchema, reason: repairReasonSchema })
29
29
  .strict();
@@ -60,8 +60,8 @@ export const AdminResolveUnrosteredStatLineResultSchema = z
60
60
  .strict();
61
61
  // Every rebuild and every game repair is a repair of a completed record: it takes a reason, runs
62
62
  // under an operation id the admin's browser mints when the admin starts it, and offers a dry run that
63
- // lists each document it would change, with before and after, and writes nothing (BACKEND-212,
64
- // SPORT-206). A real run resumes from its operation document, so a cursor is taken from the client
63
+ // lists each document it would change, with before and after, and writes nothing (RULE-STD-BACKEND-212,
64
+ // RULE-QS-SPORT-926). A real run resumes from its operation document, so a cursor is taken from the client
65
65
  // only to page a dry run, which keeps no operation.
66
66
  const statsRepairFields = {
67
67
  reason: repairReasonSchema,
@@ -170,7 +170,7 @@ const replacedEntryListSchema = z
170
170
  .object({ stored: z.array(gameRosterPlayerIdSchema), rebuilt: z.array(gameRosterPlayerIdSchema) })
171
171
  .strict();
172
172
  // Every value of the game document a repair changed, each with the value the game stored and the
173
- // value the repair writes — never the whole document (BACKEND-212). `lines` holds each changed field
173
+ // value the repair writes — never the whole document (RULE-STD-BACKEND-212). `lines` holds each changed field
174
174
  // of a team or player line (`lineKey` the team id or the roster entry id), `scores` each team whose
175
175
  // score mirror changed, and the lists, the event counter and `recordRewritten` appear only when the
176
176
  // repair changes them; `recordRewritten` names the finalized record's page counts before and after,
@@ -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 (SPORT-202).\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 (SPORT-203).\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 (SPORT-206, 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 (BACKEND-212,\n// SPORT-206). 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 (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) / `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,9 +1,9 @@
1
1
  // Callable contracts for the ways onto a team: an invitation the team sends, a join request the
2
2
  // player sends, and a free-agent signup an admin answers by placing the player. Every door that
3
3
  // makes a membership ends in the membership core. The acting user is always `request.auth.uid` —
4
- // never an input field (ARCH-106) — and the entry, never a field of the payload, decides the
5
- // authority (BACKEND-004): each action is its own callable, never a choice made by a payload field
6
- // (BACKEND-305).
4
+ // never an input field (RULE-STD-ARCH-106) — and the entry, never a field of the payload, decides the
5
+ // authority (RULE-STD-BACKEND-004): each action is its own callable, never a choice made by a payload field
6
+ // (RULE-STD-BACKEND-305).
7
7
  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';
@@ -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 (ARCH-106) — and the entry, never a field of the payload, decides the\n// authority (BACKEND-004): each action is its own callable, never a choice made by a payload field\n// (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 (`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,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 (ARCH-106). The entry, never a field of the payload, decides the authority
3
- // (BACKEND-004); an admin entry's schema adds only what its authority needs.
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.
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';
@@ -36,7 +36,7 @@ export const CreateLeagueTeamResultSchema = z
36
36
  // `requestId`, which the client mints once when the add starts and re-sends on every retry, so a
37
37
  // retry after an unknown outcome is recognised as the same add (`buildGhostUserIdForRequest`).
38
38
  // ---------------------------------------------------------------------------------------------
39
- // One document-id segment (ARCH-106), short enough that the ghost id derived from it is one too.
39
+ // One document-id segment (RULE-STD-ARCH-106), short enough that the ghost id derived from it is one too.
40
40
  export const ghostCreateRequestIdSchema = documentIdSegmentSchema.refine((requestId) => isDocumentIdSegment(buildGhostUserIdForRequest(requestId)), 'Not a ghost add request id.');
41
41
  export const CreateTeamGhostPlayerInputSchema = z
42
42
  .object({
@@ -106,7 +106,7 @@ export const AdminRetryLeagueTeamRosterSyncResultSchema = z
106
106
  // Linking a ghost to a real account — `linkGhostPlayerToUser` in a league that is not closed, and
107
107
  // `adminLinkClosedLeagueGhostPlayer` in a closed one. Both are admin-only and act on one team. A link
108
108
  // takes no reason: the admin chooses the account and confirms, and the link's audit event records
109
- // who linked which ghost to whom and what moved (BACKEND-212). The ghost and the account are
109
+ // who linked which ghost to whom and what moved (RULE-STD-BACKEND-212). The ghost and the account are
110
110
  // ids the core checks itself, so a ghost id named as the account, or a real id named as the ghost,
111
111
  // is refused with a failure record rather than at the parse. Every name the link records is read
112
112
  // server-side, never sent.
@@ -139,7 +139,7 @@ export const AdminLinkClosedLeagueGhostPlayerResultSchema = LinkGhostPlayerResul
139
139
  // Managing a team's members. A role change and a removal each have a member entry — the team's
140
140
  // captain or a co-captain, read from their membership — and an admin entry; changing the captain,
141
141
  // renaming the team, changing its type, setting its contact phone, and deleting it are admin-only.
142
- // Every target is named by id and read server-side; nothing here names who is acting (ARCH-106).
142
+ // Every target is named by id and read server-side; nothing here names who is acting (RULE-STD-ARCH-106).
143
143
  // ---------------------------------------------------------------------------------------------
144
144
  /** A ghost id, refused for any other id, so a removal input cannot name a real account. */
145
145
  export const ghostUserIdSchema = userIdSchema.refine(isGhostUserId, 'Not a ghost player.');
@@ -183,7 +183,7 @@ export const DeleteTeamMembershipResultSchema = z
183
183
  .strict();
184
184
  // `deleteTeamGhostPlayer` (the captain or a co-captain) / `adminDeleteTeamGhostPlayer`: remove a ghost
185
185
  // that has never played, completely. A never-played ghost holds no stat, so its removal is not a
186
- // repair and takes no reason; its audit event still records who removed what (BACKEND-212).
186
+ // repair and takes no reason; its audit event still records who removed what (RULE-STD-BACKEND-212).
187
187
  export const DeleteTeamGhostPlayerInputSchema = z
188
188
  .object({ teamId: teamIdSchema, ghostUserId: ghostUserIdSchema })
189
189
  .strict();
@@ -243,7 +243,7 @@ export const AdminUpdateLeagueTeamContactInputSchema = z
243
243
  export const AdminUpdateLeagueTeamContactResultSchema = AdminUpdateLeagueTeamResultSchema;
244
244
  // `adminDeleteLeagueTeam`: delete a team that has never played, with everything that is only its.
245
245
  // A never-played team holds no stat, so its deletion is not a repair and takes no reason; its audit
246
- // event still records who deleted what (BACKEND-212).
246
+ // event still records who deleted what (RULE-STD-BACKEND-212).
247
247
  export const AdminDeleteLeagueTeamInputSchema = z.object({ teamId: teamIdSchema }).strict();
248
248
  // `complete` is false when the call ran out of time part-way: what is left stays, the team still
249
249
  // stands, and the same call finishes the deletion. `remainingGameCount` is the team's games still to
@@ -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 (ARCH-106). The entry, never a field of the payload, decides the authority\n// (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 (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 (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 (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 (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 (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":"AAAA,mGAAmG;AACnG,2GAA2G;AAC3G,sFAAsF;AAEtF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,YAAY,EACZ,cAAc,EACd,gCAAgC,EAChC,cAAc,EACd,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,GACb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,kCAAkC,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnF,gGAAgG;AAChG,+FAA+F;AAC/F,+FAA+F;AAC/F,0FAA0F;AAC1F,gGAAgG;AAEhG,MAAM,kBAAkB,GAAG;IACzB,QAAQ,EAAE,cAAc;IACxB,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,YAAY,EAAE,kBAAkB;CACjC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;AAGjF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC,EAAE,GAAG,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;KACxE,MAAM,EAAE,CAAC;AAGZ,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC;KAC1C,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;KACvF,MAAM,EAAE,CAAC;AAGZ,gGAAgG;AAChG,uFAAuF;AACvF,kFAAkF;AAClF,iGAAiG;AACjG,yFAAyF;AACzF,iGAAiG;AACjG,+FAA+F;AAC/F,gGAAgG;AAEhG,0GAA0G;AAC1G,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAC,MAAM,CACtE,CAAC,SAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAC,EACzE,6BAA6B,CAC9B,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,WAAW,EAAE,iBAAiB;IAC9B,SAAS,EAAE,0BAA0B;CACtC,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,WAAW,EAAE,iBAAiB;IAC9B,SAAS,EAAE,0BAA0B;CACtC,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,iGAAiG;AACjG,gFAAgF;AAChF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC;KAC3C,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,WAAW,EAAE,YAAY;IACzB,gBAAgB,EAAE,gCAAgC;CACnD,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,gGAAgG;AAChG,kGAAkG;AAClG,kEAAkE;AAClE,gGAAgG;AAEhG,kGAAkG;AAClG,8EAA8E;AAC9E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC7C,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,YAAY,EAAE,YAAY,CAAC,QAAQ,EAAE;IACrC,OAAO,EAAE,8BAA8B,CAAC,QAAQ,EAAE;CACnD,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,8BAA8B,CAAC;CAClD,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,gGAAgG;AAChG,kGAAkG;AAClG,gGAAgG;AAEhG,MAAM,CAAC,MAAM,yCAAyC,GAAG,CAAC;KACvD,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;KAChC,MAAM,EAAE,CAAC;AAKZ,MAAM,CAAC,MAAM,0CAA0C,GAAG,CAAC;KACxD,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,0CAA0C;IAC1C,OAAO,EAAE,WAAW;IACpB,uEAAuE;IACvE,UAAU,EAAE,WAAW;IACvB,wFAAwF;IACxF,8FAA8F;IAC9F,wBAAwB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,gGAAgG;AAChG,kGAAkG;AAClG,sGAAsG;AACtG,kGAAkG;AAClG,sGAAsG;AACtG,mGAAmG;AACnG,iGAAiG;AACjG,2BAA2B;AAC3B,gGAAgG;AAEhG,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,WAAW,EAAE,YAAY;IACzB,MAAM,EAAE,YAAY;CACrB,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,qGAAqG;AACrG,6FAA6F;AAC7F,0EAA0E;AAC1E,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,WAAW,EAAE,YAAY;IACzB,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,UAAU,EAAE,WAAW;IACvB,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,QAAQ,EAAE;IACxE,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE;CAC/B,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,MAAM,CAAC,MAAM,2CAA2C,GAAG,0BAA0B,CAAC;AAEtF,MAAM,CAAC,MAAM,4CAA4C,GAAG,2BAA2B,CAAC;AAGxF,gGAAgG;AAChG,+FAA+F;AAC/F,kGAAkG;AAClG,mGAAmG;AACnG,0GAA0G;AAC1G,gGAAgG;AAEhG,2FAA2F;AAC3F,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAE3F,kGAAkG;AAClG,gDAAgD;AAChD,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC;CAC3C,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,6FAA6F;AAC7F,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC;KAClD,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;CACrB,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,oGAAoG;AACpG,0EAA0E;AAC1E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC7C,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY,CAAC,MAAM,CACzB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,EAClC,8CAA8C,CAC/C;CACF,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,8FAA8F;AAC9F,8FAA8F;AAC9F,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,gBAAgB,EAAE,gCAAgC;CACnD,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,uGAAuG;AACvG,iGAAiG;AACjG,qGAAqG;AACrG,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;KAChE,MAAM,EAAE,CAAC;AAGZ,kGAAkG;AAClG,oGAAoG;AACpG,oGAAoG;AACpG,0FAA0F;AAC1F,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAC/C,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,WAAW,EAAE,YAAY;IACzB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,0BAA0B,EAAE,WAAW;IACvC,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE;CAC/B,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,kGAAkG;AAClG,sGAAsG;AACtG,yCAAyC;AACzC,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC;IAC1C,0BAA0B,EAAE,WAAW,CAAC,QAAQ,EAAE;CACnD,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,sGAAsG;AACtG,0BAA0B;AAC1B,MAAM,CAAC,MAAM,uCAAuC,GAAG,CAAC;KACrD,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;KAC7D,MAAM,EAAE,CAAC;AAKZ,MAAM,CAAC,MAAM,wCAAwC,GAAG,CAAC;KACtD,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,aAAa,EAAE,YAAY;IAC3B,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;CACrB,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,mGAAmG;AACnG,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC;KAClD,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;KACtD,MAAM,EAAE,CAAC;AAGZ,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC;KAClD,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;KAC1D,MAAM,EAAE,CAAC;AAGZ,sFAAsF;AACtF,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAC/C,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;KAChF,MAAM,EAAE,CAAC;AAGZ,mGAAmG;AACnG,MAAM,CAAC,MAAM,uCAAuC,GAAG,CAAC;KACrD,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC;KAClE,MAAM,EAAE,CAAC;AAKZ,MAAM,CAAC,MAAM,wCAAwC,GAAG,iCAAiC,CAAC;AAG1F,kGAAkG;AAClG,oGAAoG;AACpG,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAG5F,iGAAiG;AACjG,qGAAqG;AACrG,0BAA0B;AAC1B,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAC/C,MAAM,CAAC;IACN,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;IACrB,kBAAkB,EAAE,WAAW;CAChC,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,iGAAiG;AACjG,sGAAsG;AACtG,mGAAmG;AACnG,8EAA8E;AAC9E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,eAAe,CAAU,CAAC;AAE1E,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC;KAClD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;KAC1F,MAAM,EAAE,CAAC","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"]}
@@ -88,7 +88,7 @@ export const UpdateDisplayNameResultSchema = z
88
88
  .object({ userId: userIdSchema, displayName: z.string() })
89
89
  .strict();
90
90
  // An admin grants or revokes the two global roles on `_systemData/adminList`. Four named lists —
91
- // never a role/action discriminator (BACKEND-002).
91
+ // never a role/action discriminator (RULE-STD-BACKEND-002).
92
92
  const adminListChangeSchema = z.array(userIdSchema).max(MAX_ADMIN_LIST_CHANGES).optional();
93
93
  export const UpdateAdminListInputSchema = z
94
94
  .object({
@@ -107,7 +107,7 @@ export const UpdateAdminListResultSchema = z
107
107
  })
108
108
  .strict();
109
109
  // An admin bans an account or lifts its ban. The reason is internal — recorded on the audit event,
110
- // never shown to the account (BACKEND-212). Banning or unbanning to the status the account already
110
+ // never shown to the account (RULE-STD-BACKEND-212). Banning or unbanning to the status the account already
111
111
  // holds changes nothing.
112
112
  export const AdminUpdateUserStatusInputSchema = z
113
113
  .object({ userId: userIdSchema, userStatus: userStatusSchema, reason: repairReasonSchema })
@@ -121,7 +121,7 @@ export const AdminUpdateUserStatusResultSchema = z
121
121
  changed: z.boolean(),
122
122
  })
123
123
  .strict();
124
- // The `details.reason` of the refusal to ban an account that holds admin standing (BACKEND-210), so
124
+ // The `details.reason` of the refusal to ban an account that holds admin standing (RULE-STD-BACKEND-210), so
125
125
  // a client can tell it from every other refusal.
126
126
  export const ADMIN_STANDING_BAN_REFUSAL_REASON = 'adminStandingTarget';
127
127
  // A signed-in login with no profile starts its registration, before `registerUser`: the record the
@@ -1 +1 @@
1
- {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for user accounts and the global role rosters.\n\nimport { z } from 'zod';\nimport { MAX_ADMIN_LIST_CHANGES } from '../constants/business.js';\nimport {\n countSchema,\n repairReasonSchema,\n userIdSchema,\n userStatusSchema,\n} from '../doc-schemas/atoms.js';\nimport { displayNameSchema } from './atoms.js';\n\n// The signed-in caller finishes registration: profile, public identity, and the display-name\n// reservation are created for `request.auth.uid`. Email comes from the token, never the payload.\nexport const RegisterUserInputSchema = z\n .object({\n displayName: displayNameSchema,\n // The terms checkbox, re-checked server-side: only `true` registers.\n acceptedTerms: z.literal(true),\n })\n .strict();\nexport type RegisterUserInput = z.infer<typeof RegisterUserInputSchema>;\nexport const RegisterUserResultSchema = z.discriminatedUnion('status', [\n // The account is registered (or already was — an idempotent replay).\n z\n .object({ status: z.literal('registered'), userId: userIdSchema, displayName: z.string() })\n .strict(),\n // The orphan-registration cleanup claimed this login for deletion, so the registration cannot\n // finish on it; nothing is written and the person signs up again.\n z.object({ status: z.literal('registrationExpired') }).strict(),\n]);\nexport type RegisterUserResult = z.infer<typeof RegisterUserResultSchema>;\n\n// The register form's check before the login is created: is the name free? It runs before any\n// account exists, over the same name rule `registerUser` takes, and is a soft answer — the claim\n// itself is `registerUser`'s transaction, which refuses `already-exists` when two registrations\n// pass this check at once.\nexport const CheckDisplayNameAvailableInputSchema = z\n .object({ displayName: displayNameSchema })\n .strict();\nexport type CheckDisplayNameAvailableInput = z.infer<typeof CheckDisplayNameAvailableInputSchema>;\n// Why a name is not available. Uniqueness is the only rule a Q-Sports name is held to beyond its\n// input format.\nexport const DISPLAY_NAME_UNAVAILABLE_REASONS = ['taken'] as const;\nexport type DisplayNameUnavailableReason = (typeof DISPLAY_NAME_UNAVAILABLE_REASONS)[number];\nexport const CheckDisplayNameAvailableResultSchema = z\n .object({ available: z.boolean(), reason: z.enum(DISPLAY_NAME_UNAVAILABLE_REASONS).optional() })\n .strict();\nexport type CheckDisplayNameAvailableResult = z.infer<typeof CheckDisplayNameAvailableResultSchema>;\n\n/** The longest text an admin's account search takes: a name, a full email address, or a uid. */\nexport const MAX_USER_SEARCH_QUERY_LENGTH = 100;\n\n// Which read an admin's account search routes to: a full email address or a 28-character Firebase\n// Auth uid is an exact lookup (`lookupUserByEmailOrUid`), anything else a name search. Declared once:\n// the search box routes by it and the lookup callable re-derives the same answer, so a mis-routed\n// request never looks an email up as a uid or the other way round.\nexport const USER_LOOKUP_EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nexport const USER_LOOKUP_UID_PATTERN = /^[A-Za-z0-9]{28}$/;\nexport type UserSearchKind = 'email' | 'uid' | 'name';\nexport function detectUserSearchKind(query: string): UserSearchKind {\n const trimmed = query.trim();\n if (USER_LOOKUP_EMAIL_PATTERN.test(trimmed)) return 'email';\n if (USER_LOOKUP_UID_PATTERN.test(trimmed)) return 'uid';\n return 'name';\n}\n\n// An admin finds one account by its exact email address or its uid. The answer carries the\n// owner-only email, so it is admin only.\nexport const LookupUserByEmailOrUidInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type LookupUserByEmailOrUidInput = z.infer<typeof LookupUserByEmailOrUidInputSchema>;\nexport const LookedUpUserSchema = z\n .object({\n uid: userIdSchema,\n displayName: z.string(),\n email: z.string(),\n userStatus: userStatusSchema,\n // Present, and true, only for an account on the admin roster.\n isAdmin: z.literal(true).optional(),\n })\n .strict();\nexport type LookedUpUser = z.infer<typeof LookedUpUserSchema>;\n// The one exact match, or `null` when no account with a profile resolves.\nexport const LookupUserByEmailOrUidResultSchema = z\n .object({ user: LookedUpUserSchema.nullable() })\n .strict();\nexport type LookupUserByEmailOrUidResult = z.infer<typeof LookupUserByEmailOrUidResultSchema>;\n\n// An admin searches accounts by the start of their name, over public display identity. Ghosts are\n// not accounts and are left out; a banned account is found, with its status.\nexport const SearchPublicUsersInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type SearchPublicUsersInput = z.infer<typeof SearchPublicUsersInputSchema>;\nexport const PublicUserSearchResultSchema = z\n .object({ uid: userIdSchema, displayName: z.string(), userStatus: userStatusSchema })\n .strict();\nexport type PublicUserSearchResult = z.infer<typeof PublicUserSearchResultSchema>;\nexport const SearchPublicUsersResultSchema = z\n .object({ users: z.array(PublicUserSearchResultSchema) })\n .strict();\nexport type SearchPublicUsersResult = z.infer<typeof SearchPublicUsersResultSchema>;\n\n// An admin renames a user. Self-service rename is not a Q-Sports feature.\nexport const UpdateDisplayNameInputSchema = z\n .object({ userId: userIdSchema, newDisplayName: displayNameSchema })\n .strict();\nexport type UpdateDisplayNameInput = z.infer<typeof UpdateDisplayNameInputSchema>;\nexport const UpdateDisplayNameResultSchema = z\n .object({ userId: userIdSchema, displayName: z.string() })\n .strict();\nexport type UpdateDisplayNameResult = z.infer<typeof UpdateDisplayNameResultSchema>;\n\n// An admin grants or revokes the two global roles on `_systemData/adminList`. Four named lists —\n// never a role/action discriminator (BACKEND-002).\nconst adminListChangeSchema = z.array(userIdSchema).max(MAX_ADMIN_LIST_CHANGES).optional();\nexport const UpdateAdminListInputSchema = z\n .object({\n addAdmins: adminListChangeSchema,\n removeAdmins: adminListChangeSchema,\n addReferees: adminListChangeSchema,\n removeReferees: adminListChangeSchema,\n })\n .strict();\nexport type UpdateAdminListInput = z.infer<typeof UpdateAdminListInputSchema>;\nexport const UpdateAdminListResultSchema = z\n .object({\n adminsGranted: countSchema,\n adminsRevoked: countSchema,\n refereesGranted: countSchema,\n refereesRevoked: countSchema,\n })\n .strict();\nexport type UpdateAdminListResult = z.infer<typeof UpdateAdminListResultSchema>;\n\n// An admin bans an account or lifts its ban. The reason is internal — recorded on the audit event,\n// never shown to the account (BACKEND-212). Banning or unbanning to the status the account already\n// holds changes nothing.\nexport const AdminUpdateUserStatusInputSchema = z\n .object({ userId: userIdSchema, userStatus: userStatusSchema, reason: repairReasonSchema })\n .strict();\nexport type AdminUpdateUserStatusInput = z.infer<typeof AdminUpdateUserStatusInputSchema>;\n\n// `changed` is whether the status moved.\nexport const AdminUpdateUserStatusResultSchema = z\n .object({\n userId: userIdSchema,\n userStatus: userStatusSchema,\n previousStatus: userStatusSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type AdminUpdateUserStatusResult = z.infer<typeof AdminUpdateUserStatusResultSchema>;\n\n// The `details.reason` of the refusal to ban an account that holds admin standing (BACKEND-210), so\n// a client can tell it from every other refusal.\nexport const ADMIN_STANDING_BAN_REFUSAL_REASON = 'adminStandingTarget';\n\n// A signed-in login with no profile starts its registration, before `registerUser`: the record the\n// orphan-login cleanup finds it by, and the owner-only private record `registerUser` requires. The\n// caller is `request.auth.uid` and the email comes from its token, so it takes no input.\nexport const CreateRegistrationStartInputSchema = z.object({}).strict();\nexport type CreateRegistrationStartInput = z.infer<typeof CreateRegistrationStartInputSchema>;\n// `started` wrote both records; `alreadyStarted` found the registration already started and wrote\n// nothing — a retry, or a resume after a later step failed; `registrationExpired` found the login\n// claimed by the orphan-registration cleanup and wrote nothing — the person signs up again.\nexport const REGISTRATION_START_OUTCOMES = [\n 'started',\n 'alreadyStarted',\n 'registrationExpired',\n] as const;\nexport type RegistrationStartOutcome = (typeof REGISTRATION_START_OUTCOMES)[number];\nexport const CreateRegistrationStartResultSchema = z\n .object({ outcome: z.enum(REGISTRATION_START_OUTCOMES) })\n .strict();\nexport type CreateRegistrationStartResult = z.infer<typeof CreateRegistrationStartResultSchema>;\n"]}
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for user accounts and the global role rosters.\n\nimport { z } from 'zod';\nimport { MAX_ADMIN_LIST_CHANGES } from '../constants/business.js';\nimport {\n countSchema,\n repairReasonSchema,\n userIdSchema,\n userStatusSchema,\n} from '../doc-schemas/atoms.js';\nimport { displayNameSchema } from './atoms.js';\n\n// The signed-in caller finishes registration: profile, public identity, and the display-name\n// reservation are created for `request.auth.uid`. Email comes from the token, never the payload.\nexport const RegisterUserInputSchema = z\n .object({\n displayName: displayNameSchema,\n // The terms checkbox, re-checked server-side: only `true` registers.\n acceptedTerms: z.literal(true),\n })\n .strict();\nexport type RegisterUserInput = z.infer<typeof RegisterUserInputSchema>;\nexport const RegisterUserResultSchema = z.discriminatedUnion('status', [\n // The account is registered (or already was — an idempotent replay).\n z\n .object({ status: z.literal('registered'), userId: userIdSchema, displayName: z.string() })\n .strict(),\n // The orphan-registration cleanup claimed this login for deletion, so the registration cannot\n // finish on it; nothing is written and the person signs up again.\n z.object({ status: z.literal('registrationExpired') }).strict(),\n]);\nexport type RegisterUserResult = z.infer<typeof RegisterUserResultSchema>;\n\n// The register form's check before the login is created: is the name free? It runs before any\n// account exists, over the same name rule `registerUser` takes, and is a soft answer — the claim\n// itself is `registerUser`'s transaction, which refuses `already-exists` when two registrations\n// pass this check at once.\nexport const CheckDisplayNameAvailableInputSchema = z\n .object({ displayName: displayNameSchema })\n .strict();\nexport type CheckDisplayNameAvailableInput = z.infer<typeof CheckDisplayNameAvailableInputSchema>;\n// Why a name is not available. Uniqueness is the only rule a Q-Sports name is held to beyond its\n// input format.\nexport const DISPLAY_NAME_UNAVAILABLE_REASONS = ['taken'] as const;\nexport type DisplayNameUnavailableReason = (typeof DISPLAY_NAME_UNAVAILABLE_REASONS)[number];\nexport const CheckDisplayNameAvailableResultSchema = z\n .object({ available: z.boolean(), reason: z.enum(DISPLAY_NAME_UNAVAILABLE_REASONS).optional() })\n .strict();\nexport type CheckDisplayNameAvailableResult = z.infer<typeof CheckDisplayNameAvailableResultSchema>;\n\n/** The longest text an admin's account search takes: a name, a full email address, or a uid. */\nexport const MAX_USER_SEARCH_QUERY_LENGTH = 100;\n\n// Which read an admin's account search routes to: a full email address or a 28-character Firebase\n// Auth uid is an exact lookup (`lookupUserByEmailOrUid`), anything else a name search. Declared once:\n// the search box routes by it and the lookup callable re-derives the same answer, so a mis-routed\n// request never looks an email up as a uid or the other way round.\nexport const USER_LOOKUP_EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nexport const USER_LOOKUP_UID_PATTERN = /^[A-Za-z0-9]{28}$/;\nexport type UserSearchKind = 'email' | 'uid' | 'name';\nexport function detectUserSearchKind(query: string): UserSearchKind {\n const trimmed = query.trim();\n if (USER_LOOKUP_EMAIL_PATTERN.test(trimmed)) return 'email';\n if (USER_LOOKUP_UID_PATTERN.test(trimmed)) return 'uid';\n return 'name';\n}\n\n// An admin finds one account by its exact email address or its uid. The answer carries the\n// owner-only email, so it is admin only.\nexport const LookupUserByEmailOrUidInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type LookupUserByEmailOrUidInput = z.infer<typeof LookupUserByEmailOrUidInputSchema>;\nexport const LookedUpUserSchema = z\n .object({\n uid: userIdSchema,\n displayName: z.string(),\n email: z.string(),\n userStatus: userStatusSchema,\n // Present, and true, only for an account on the admin roster.\n isAdmin: z.literal(true).optional(),\n })\n .strict();\nexport type LookedUpUser = z.infer<typeof LookedUpUserSchema>;\n// The one exact match, or `null` when no account with a profile resolves.\nexport const LookupUserByEmailOrUidResultSchema = z\n .object({ user: LookedUpUserSchema.nullable() })\n .strict();\nexport type LookupUserByEmailOrUidResult = z.infer<typeof LookupUserByEmailOrUidResultSchema>;\n\n// An admin searches accounts by the start of their name, over public display identity. Ghosts are\n// not accounts and are left out; a banned account is found, with its status.\nexport const SearchPublicUsersInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type SearchPublicUsersInput = z.infer<typeof SearchPublicUsersInputSchema>;\nexport const PublicUserSearchResultSchema = z\n .object({ uid: userIdSchema, displayName: z.string(), userStatus: userStatusSchema })\n .strict();\nexport type PublicUserSearchResult = z.infer<typeof PublicUserSearchResultSchema>;\nexport const SearchPublicUsersResultSchema = z\n .object({ users: z.array(PublicUserSearchResultSchema) })\n .strict();\nexport type SearchPublicUsersResult = z.infer<typeof SearchPublicUsersResultSchema>;\n\n// An admin renames a user. Self-service rename is not a Q-Sports feature.\nexport const UpdateDisplayNameInputSchema = z\n .object({ userId: userIdSchema, newDisplayName: displayNameSchema })\n .strict();\nexport type UpdateDisplayNameInput = z.infer<typeof UpdateDisplayNameInputSchema>;\nexport const UpdateDisplayNameResultSchema = z\n .object({ userId: userIdSchema, displayName: z.string() })\n .strict();\nexport type UpdateDisplayNameResult = z.infer<typeof UpdateDisplayNameResultSchema>;\n\n// An admin grants or revokes the two global roles on `_systemData/adminList`. Four named lists —\n// never a role/action discriminator (RULE-STD-BACKEND-002).\nconst adminListChangeSchema = z.array(userIdSchema).max(MAX_ADMIN_LIST_CHANGES).optional();\nexport const UpdateAdminListInputSchema = z\n .object({\n addAdmins: adminListChangeSchema,\n removeAdmins: adminListChangeSchema,\n addReferees: adminListChangeSchema,\n removeReferees: adminListChangeSchema,\n })\n .strict();\nexport type UpdateAdminListInput = z.infer<typeof UpdateAdminListInputSchema>;\nexport const UpdateAdminListResultSchema = z\n .object({\n adminsGranted: countSchema,\n adminsRevoked: countSchema,\n refereesGranted: countSchema,\n refereesRevoked: countSchema,\n })\n .strict();\nexport type UpdateAdminListResult = z.infer<typeof UpdateAdminListResultSchema>;\n\n// An admin bans an account or lifts its ban. The reason is internal — recorded on the audit event,\n// never shown to the account (RULE-STD-BACKEND-212). Banning or unbanning to the status the account already\n// holds changes nothing.\nexport const AdminUpdateUserStatusInputSchema = z\n .object({ userId: userIdSchema, userStatus: userStatusSchema, reason: repairReasonSchema })\n .strict();\nexport type AdminUpdateUserStatusInput = z.infer<typeof AdminUpdateUserStatusInputSchema>;\n\n// `changed` is whether the status moved.\nexport const AdminUpdateUserStatusResultSchema = z\n .object({\n userId: userIdSchema,\n userStatus: userStatusSchema,\n previousStatus: userStatusSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type AdminUpdateUserStatusResult = z.infer<typeof AdminUpdateUserStatusResultSchema>;\n\n// The `details.reason` of the refusal to ban an account that holds admin standing (RULE-STD-BACKEND-210), so\n// a client can tell it from every other refusal.\nexport const ADMIN_STANDING_BAN_REFUSAL_REASON = 'adminStandingTarget';\n\n// A signed-in login with no profile starts its registration, before `registerUser`: the record the\n// orphan-login cleanup finds it by, and the owner-only private record `registerUser` requires. The\n// caller is `request.auth.uid` and the email comes from its token, so it takes no input.\nexport const CreateRegistrationStartInputSchema = z.object({}).strict();\nexport type CreateRegistrationStartInput = z.infer<typeof CreateRegistrationStartInputSchema>;\n// `started` wrote both records; `alreadyStarted` found the registration already started and wrote\n// nothing — a retry, or a resume after a later step failed; `registrationExpired` found the login\n// claimed by the orphan-registration cleanup and wrote nothing — the person signs up again.\nexport const REGISTRATION_START_OUTCOMES = [\n 'started',\n 'alreadyStarted',\n 'registrationExpired',\n] as const;\nexport type RegistrationStartOutcome = (typeof REGISTRATION_START_OUTCOMES)[number];\nexport const CreateRegistrationStartResultSchema = z\n .object({ outcome: z.enum(REGISTRATION_START_OUTCOMES) })\n .strict();\nexport type CreateRegistrationStartResult = z.infer<typeof CreateRegistrationStartResultSchema>;\n"]}
@@ -1,9 +1,9 @@
1
1
  // The basketball adapter's scoring, display, and bulk-entry members. Basketball is player-scored: a
2
2
  // shot credits its scorer's points and its team's score, and — when it names one — its assister's
3
- // assists, all on the one event (SPORT-003).
3
+ // assists, all on the one event (RULE-QS-SPORT-903).
4
4
  //
5
5
  // `apply` and `undo` are one function over an event's effects with opposite signs, so they are exact
6
- // inverses by construction (SPORT-103).
6
+ // inverses by construction (RULE-QS-SPORT-913).
7
7
  import { z } from 'zod';
8
8
  import { BASKETBALL_FANTASY_POINT_WEIGHTS, BASKETBALL_POINTS_BY_EVENT_TYPE, MAX_STAT_EVENTS_PER_WRITE, NOT_ON_GAME_ROSTER_MESSAGE, } from '../constants/sports.js';
9
9
  import { buildGameRosterPlayerId, parseGameRosterPlayerId } from '../ids/compound-ids.js';
@@ -17,7 +17,7 @@ function isBasketballEvent(event) {
17
17
  return isSportStatEventIn(BASKETBALL_STAT_EVENT_TYPE_KEYS, event);
18
18
  }
19
19
  // The registry chose this adapter by the game's `leagueType`, so the rollup it is handed is a
20
- // basketball game's (SPORT-002).
20
+ // basketball game's (RULE-QS-SPORT-902).
21
21
  function ownStats(state) {
22
22
  return state;
23
23
  }
@@ -162,7 +162,7 @@ function applyEffects(state, effects, sign) {
162
162
  return { teamStats, playerStats };
163
163
  }
164
164
  // ---------------------------------------------------------------------------------------------
165
- // Validation — the same rules the bulk form holds, re-checked on the server (SPORT-006)
165
+ // Validation — the same rules the bulk form holds, re-checked on the server (RULE-QS-SPORT-906)
166
166
  // ---------------------------------------------------------------------------------------------
167
167
  function isAssistableShot(type) {
168
168
  return BASKETBALL_ASSISTABLE_SHOT_EVENT_TYPE_KEYS.includes(type);