@ttt-productions/q-core 0.1.28 → 0.1.29

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 (472) hide show
  1. package/dist/constants/admin-views.d.ts.map +1 -1
  2. package/dist/constants/admin-views.js +0 -3
  3. package/dist/constants/admin-views.js.map +1 -1
  4. package/dist/constants/business.d.ts.map +1 -1
  5. package/dist/constants/business.js +0 -52
  6. package/dist/constants/business.js.map +1 -1
  7. package/dist/constants/deployment.d.ts +0 -2
  8. package/dist/constants/deployment.d.ts.map +1 -1
  9. package/dist/constants/deployment.js +0 -2
  10. package/dist/constants/deployment.js.map +1 -1
  11. package/dist/constants/media.d.ts.map +1 -1
  12. package/dist/constants/media.js +4 -30
  13. package/dist/constants/media.js.map +1 -1
  14. package/dist/constants/scheduled-jobs.d.ts +0 -25
  15. package/dist/constants/scheduled-jobs.d.ts.map +1 -1
  16. package/dist/constants/scheduled-jobs.js +0 -26
  17. package/dist/constants/scheduled-jobs.js.map +1 -1
  18. package/dist/constants/sports.d.ts.map +1 -1
  19. package/dist/constants/sports.js +2 -25
  20. package/dist/constants/sports.js.map +1 -1
  21. package/dist/constants/storage-keys.d.ts +0 -38
  22. package/dist/constants/storage-keys.d.ts.map +1 -1
  23. package/dist/constants/storage-keys.js +0 -41
  24. package/dist/constants/storage-keys.js.map +1 -1
  25. package/dist/constants/telemetry.d.ts +0 -3
  26. package/dist/constants/telemetry.d.ts.map +1 -1
  27. package/dist/constants/telemetry.js +2 -11
  28. package/dist/constants/telemetry.js.map +1 -1
  29. package/dist/doc-schemas/admin-notifications.d.ts +0 -1
  30. package/dist/doc-schemas/admin-notifications.d.ts.map +1 -1
  31. package/dist/doc-schemas/admin-notifications.js +0 -41
  32. package/dist/doc-schemas/admin-notifications.js.map +1 -1
  33. package/dist/doc-schemas/aggregate-stats.d.ts.map +1 -1
  34. package/dist/doc-schemas/aggregate-stats.js +0 -35
  35. package/dist/doc-schemas/aggregate-stats.js.map +1 -1
  36. package/dist/doc-schemas/atoms.d.ts +0 -17
  37. package/dist/doc-schemas/atoms.d.ts.map +1 -1
  38. package/dist/doc-schemas/atoms.js +0 -36
  39. package/dist/doc-schemas/atoms.js.map +1 -1
  40. package/dist/doc-schemas/audit-event.d.ts.map +1 -1
  41. package/dist/doc-schemas/audit-event.js +0 -8
  42. package/dist/doc-schemas/audit-event.js.map +1 -1
  43. package/dist/doc-schemas/award-group-grant.d.ts +0 -6
  44. package/dist/doc-schemas/award-group-grant.d.ts.map +1 -1
  45. package/dist/doc-schemas/award-group-grant.js +0 -25
  46. package/dist/doc-schemas/award-group-grant.js.map +1 -1
  47. package/dist/doc-schemas/catalogs.d.ts.map +1 -1
  48. package/dist/doc-schemas/catalogs.js +0 -12
  49. package/dist/doc-schemas/catalogs.js.map +1 -1
  50. package/dist/doc-schemas/firestore-primitives.d.ts.map +1 -1
  51. package/dist/doc-schemas/firestore-primitives.js +0 -5
  52. package/dist/doc-schemas/firestore-primitives.js.map +1 -1
  53. package/dist/doc-schemas/gallery.d.ts.map +1 -1
  54. package/dist/doc-schemas/gallery.js +0 -15
  55. package/dist/doc-schemas/gallery.js.map +1 -1
  56. package/dist/doc-schemas/game-location.d.ts.map +1 -1
  57. package/dist/doc-schemas/game-location.js +2 -11
  58. package/dist/doc-schemas/game-location.js.map +1 -1
  59. package/dist/doc-schemas/game-stat-history.d.ts.map +1 -1
  60. package/dist/doc-schemas/game-stat-history.js +0 -9
  61. package/dist/doc-schemas/game-stat-history.js.map +1 -1
  62. package/dist/doc-schemas/game-stats.d.ts.map +1 -1
  63. package/dist/doc-schemas/game-stats.js +0 -56
  64. package/dist/doc-schemas/game-stats.js.map +1 -1
  65. package/dist/doc-schemas/league-team.d.ts.map +1 -1
  66. package/dist/doc-schemas/league-team.js +6 -29
  67. package/dist/doc-schemas/league-team.js.map +1 -1
  68. package/dist/doc-schemas/membership-roster-sync.d.ts.map +1 -1
  69. package/dist/doc-schemas/membership-roster-sync.js +0 -17
  70. package/dist/doc-schemas/membership-roster-sync.js.map +1 -1
  71. package/dist/doc-schemas/migration-console.d.ts +0 -10
  72. package/dist/doc-schemas/migration-console.d.ts.map +1 -1
  73. package/dist/doc-schemas/migration-console.js +0 -32
  74. package/dist/doc-schemas/migration-console.js.map +1 -1
  75. package/dist/doc-schemas/pending-media.d.ts.map +1 -1
  76. package/dist/doc-schemas/pending-media.js +0 -17
  77. package/dist/doc-schemas/pending-media.js.map +1 -1
  78. package/dist/doc-schemas/picture-retirement.d.ts.map +1 -1
  79. package/dist/doc-schemas/picture-retirement.js +0 -10
  80. package/dist/doc-schemas/picture-retirement.js.map +1 -1
  81. package/dist/doc-schemas/publicUser.d.ts.map +1 -1
  82. package/dist/doc-schemas/publicUser.js +0 -5
  83. package/dist/doc-schemas/publicUser.js.map +1 -1
  84. package/dist/doc-schemas/registration-start.d.ts.map +1 -1
  85. package/dist/doc-schemas/registration-start.js +2 -5
  86. package/dist/doc-schemas/registration-start.js.map +1 -1
  87. package/dist/doc-schemas/registry.d.ts.map +1 -1
  88. package/dist/doc-schemas/registry.js +0 -10
  89. package/dist/doc-schemas/registry.js.map +1 -1
  90. package/dist/doc-schemas/reserved-display-name.d.ts.map +1 -1
  91. package/dist/doc-schemas/reserved-display-name.js +0 -5
  92. package/dist/doc-schemas/reserved-display-name.js.map +1 -1
  93. package/dist/doc-schemas/sport-game.d.ts.map +1 -1
  94. package/dist/doc-schemas/sport-game.js +1 -29
  95. package/dist/doc-schemas/sport-game.js.map +1 -1
  96. package/dist/doc-schemas/sport-league.d.ts +0 -9
  97. package/dist/doc-schemas/sport-league.d.ts.map +1 -1
  98. package/dist/doc-schemas/sport-league.js +4 -26
  99. package/dist/doc-schemas/sport-league.js.map +1 -1
  100. package/dist/doc-schemas/stats-operation.d.ts.map +1 -1
  101. package/dist/doc-schemas/stats-operation.js +2 -44
  102. package/dist/doc-schemas/stats-operation.js.map +1 -1
  103. package/dist/doc-schemas/status-reconcile-queue.d.ts +0 -6
  104. package/dist/doc-schemas/status-reconcile-queue.d.ts.map +1 -1
  105. package/dist/doc-schemas/status-reconcile-queue.js +0 -13
  106. package/dist/doc-schemas/status-reconcile-queue.js.map +1 -1
  107. package/dist/doc-schemas/sweep-state.d.ts.map +1 -1
  108. package/dist/doc-schemas/sweep-state.js +4 -20
  109. package/dist/doc-schemas/sweep-state.js.map +1 -1
  110. package/dist/doc-schemas/system.d.ts.map +1 -1
  111. package/dist/doc-schemas/system.js +1 -27
  112. package/dist/doc-schemas/system.js.map +1 -1
  113. package/dist/doc-schemas/team-membership.d.ts.map +1 -1
  114. package/dist/doc-schemas/team-membership.js +0 -10
  115. package/dist/doc-schemas/team-membership.js.map +1 -1
  116. package/dist/doc-schemas/user-profile.d.ts +0 -1
  117. package/dist/doc-schemas/user-profile.d.ts.map +1 -1
  118. package/dist/doc-schemas/user-profile.js +0 -28
  119. package/dist/doc-schemas/user-profile.js.map +1 -1
  120. package/dist/doc-schemas/waiver-template.d.ts.map +1 -1
  121. package/dist/doc-schemas/waiver-template.js +4 -25
  122. package/dist/doc-schemas/waiver-template.js.map +1 -1
  123. package/dist/doc-schemas/waivers-and-hardware.d.ts.map +1 -1
  124. package/dist/doc-schemas/waivers-and-hardware.js +0 -20
  125. package/dist/doc-schemas/waivers-and-hardware.js.map +1 -1
  126. package/dist/domain-events/domain-events.d.ts.map +1 -1
  127. package/dist/domain-events/domain-events.js +0 -67
  128. package/dist/domain-events/domain-events.js.map +1 -1
  129. package/dist/ids/award-grant-ids.d.ts.map +1 -1
  130. package/dist/ids/award-grant-ids.js +0 -7
  131. package/dist/ids/award-grant-ids.js.map +1 -1
  132. package/dist/ids/compound-ids.d.ts.map +1 -1
  133. package/dist/ids/compound-ids.js +0 -7
  134. package/dist/ids/compound-ids.js.map +1 -1
  135. package/dist/ids/minted-ids.d.ts.map +1 -1
  136. package/dist/ids/minted-ids.js +4 -14
  137. package/dist/ids/minted-ids.js.map +1 -1
  138. package/dist/ids/notification-ids.d.ts.map +1 -1
  139. package/dist/ids/notification-ids.js +0 -15
  140. package/dist/ids/notification-ids.js.map +1 -1
  141. package/dist/ids/picture-ids.d.ts +0 -5
  142. package/dist/ids/picture-ids.d.ts.map +1 -1
  143. package/dist/ids/picture-ids.js +0 -11
  144. package/dist/ids/picture-ids.js.map +1 -1
  145. package/dist/ids/stat-event-ids.d.ts +0 -6
  146. package/dist/ids/stat-event-ids.d.ts.map +1 -1
  147. package/dist/ids/stat-event-ids.js +0 -15
  148. package/dist/ids/stat-event-ids.js.map +1 -1
  149. package/dist/ids/stats-operation-ids.d.ts.map +1 -1
  150. package/dist/ids/stats-operation-ids.js +0 -7
  151. package/dist/ids/stats-operation-ids.js.map +1 -1
  152. package/dist/ids/waiver-template-ids.d.ts +0 -1
  153. package/dist/ids/waiver-template-ids.d.ts.map +1 -1
  154. package/dist/ids/waiver-template-ids.js +0 -2
  155. package/dist/ids/waiver-template-ids.js.map +1 -1
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js +0 -2
  158. package/dist/index.js.map +1 -1
  159. package/dist/input-formats/input-formats.d.ts +0 -80
  160. package/dist/input-formats/input-formats.d.ts.map +1 -1
  161. package/dist/input-formats/input-formats.js +0 -86
  162. package/dist/input-formats/input-formats.js.map +1 -1
  163. package/dist/media/file-origins.d.ts +0 -3
  164. package/dist/media/file-origins.d.ts.map +1 -1
  165. package/dist/media/file-origins.js +0 -26
  166. package/dist/media/file-origins.js.map +1 -1
  167. package/dist/media/picture-aspects.d.ts +0 -2
  168. package/dist/media/picture-aspects.d.ts.map +1 -1
  169. package/dist/media/picture-aspects.js +0 -5
  170. package/dist/media/picture-aspects.js.map +1 -1
  171. package/dist/media/picture-url.d.ts +0 -6
  172. package/dist/media/picture-url.d.ts.map +1 -1
  173. package/dist/media/picture-url.js +0 -9
  174. package/dist/media/picture-url.js.map +1 -1
  175. package/dist/media/upload-tray-display.d.ts +0 -3
  176. package/dist/media/upload-tray-display.d.ts.map +1 -1
  177. package/dist/media/upload-tray-display.js +0 -6
  178. package/dist/media/upload-tray-display.js.map +1 -1
  179. package/dist/migration-console/action-ids.d.ts +0 -1
  180. package/dist/migration-console/action-ids.d.ts.map +1 -1
  181. package/dist/migration-console/action-ids.js +2 -45
  182. package/dist/migration-console/action-ids.js.map +1 -1
  183. package/dist/migration-console/manifest.d.ts +0 -24
  184. package/dist/migration-console/manifest.d.ts.map +1 -1
  185. package/dist/migration-console/manifest.js +1 -56
  186. package/dist/migration-console/manifest.js.map +1 -1
  187. package/dist/migration-console/run-state.d.ts +0 -14
  188. package/dist/migration-console/run-state.d.ts.map +1 -1
  189. package/dist/migration-console/run-state.js +0 -16
  190. package/dist/migration-console/run-state.js.map +1 -1
  191. package/dist/notifications/admin-notification-config.d.ts +0 -11
  192. package/dist/notifications/admin-notification-config.d.ts.map +1 -1
  193. package/dist/notifications/admin-notification-config.js +2 -13
  194. package/dist/notifications/admin-notification-config.js.map +1 -1
  195. package/dist/notifications/archive-all.d.ts.map +1 -1
  196. package/dist/notifications/archive-all.js +0 -2
  197. package/dist/notifications/archive-all.js.map +1 -1
  198. package/dist/notifications/occurrences.d.ts +0 -3
  199. package/dist/notifications/occurrences.d.ts.map +1 -1
  200. package/dist/notifications/occurrences.js +0 -7
  201. package/dist/notifications/occurrences.js.map +1 -1
  202. package/dist/paths/app-routes.d.ts +0 -12
  203. package/dist/paths/app-routes.d.ts.map +1 -1
  204. package/dist/paths/app-routes.js +0 -18
  205. package/dist/paths/app-routes.js.map +1 -1
  206. package/dist/paths/collection-groups.d.ts.map +1 -1
  207. package/dist/paths/collection-groups.js +0 -5
  208. package/dist/paths/collection-groups.js.map +1 -1
  209. package/dist/paths/collection-refs.d.ts.map +1 -1
  210. package/dist/paths/collection-refs.js +0 -4
  211. package/dist/paths/collection-refs.js.map +1 -1
  212. package/dist/paths/collections.d.ts +0 -5
  213. package/dist/paths/collections.d.ts.map +1 -1
  214. package/dist/paths/collections.js +0 -68
  215. package/dist/paths/collections.js.map +1 -1
  216. package/dist/paths/path-builders.d.ts.map +1 -1
  217. package/dist/paths/path-builders.js +0 -16
  218. package/dist/paths/path-builders.js.map +1 -1
  219. package/dist/paths/picture-owner-paths.d.ts +0 -4
  220. package/dist/paths/picture-owner-paths.d.ts.map +1 -1
  221. package/dist/paths/picture-owner-paths.js +0 -10
  222. package/dist/paths/picture-owner-paths.js.map +1 -1
  223. package/dist/paths/storage-paths.d.ts +0 -18
  224. package/dist/paths/storage-paths.d.ts.map +1 -1
  225. package/dist/paths/storage-paths.js +0 -23
  226. package/dist/paths/storage-paths.js.map +1 -1
  227. package/dist/paths/utils.d.ts +0 -6
  228. package/dist/paths/utils.d.ts.map +1 -1
  229. package/dist/paths/utils.js +0 -9
  230. package/dist/paths/utils.js.map +1 -1
  231. package/dist/schemas/account-settings.d.ts.map +1 -1
  232. package/dist/schemas/account-settings.js +0 -7
  233. package/dist/schemas/account-settings.js.map +1 -1
  234. package/dist/schemas/admin-notifications.d.ts.map +1 -1
  235. package/dist/schemas/admin-notifications.js +0 -17
  236. package/dist/schemas/admin-notifications.js.map +1 -1
  237. package/dist/schemas/admin-stats.d.ts.map +1 -1
  238. package/dist/schemas/admin-stats.js +0 -9
  239. package/dist/schemas/admin-stats.js.map +1 -1
  240. package/dist/schemas/app-config.d.ts.map +1 -1
  241. package/dist/schemas/app-config.js +0 -10
  242. package/dist/schemas/app-config.js.map +1 -1
  243. package/dist/schemas/atoms.d.ts.map +1 -1
  244. package/dist/schemas/atoms.js +0 -10
  245. package/dist/schemas/atoms.js.map +1 -1
  246. package/dist/schemas/awards.d.ts.map +1 -1
  247. package/dist/schemas/awards.js +0 -29
  248. package/dist/schemas/awards.js.map +1 -1
  249. package/dist/schemas/dead-letters.d.ts +0 -3
  250. package/dist/schemas/dead-letters.d.ts.map +1 -1
  251. package/dist/schemas/dead-letters.js +0 -15
  252. package/dist/schemas/dead-letters.js.map +1 -1
  253. package/dist/schemas/game-locations.d.ts.map +1 -1
  254. package/dist/schemas/game-locations.js +0 -6
  255. package/dist/schemas/game-locations.js.map +1 -1
  256. package/dist/schemas/hardware-loan-contracts.d.ts.map +1 -1
  257. package/dist/schemas/hardware-loan-contracts.js +0 -13
  258. package/dist/schemas/hardware-loan-contracts.js.map +1 -1
  259. package/dist/schemas/index.d.ts.map +1 -1
  260. package/dist/schemas/index.js +0 -2
  261. package/dist/schemas/index.js.map +1 -1
  262. package/dist/schemas/leagues.d.ts.map +1 -1
  263. package/dist/schemas/leagues.js +0 -24
  264. package/dist/schemas/leagues.js.map +1 -1
  265. package/dist/schemas/migration-console.d.ts +0 -7
  266. package/dist/schemas/migration-console.d.ts.map +1 -1
  267. package/dist/schemas/migration-console.js +0 -34
  268. package/dist/schemas/migration-console.js.map +1 -1
  269. package/dist/schemas/pictures.d.ts.map +1 -1
  270. package/dist/schemas/pictures.js +0 -10
  271. package/dist/schemas/pictures.js.map +1 -1
  272. package/dist/schemas/schedules.d.ts.map +1 -1
  273. package/dist/schemas/schedules.js +0 -26
  274. package/dist/schemas/schedules.js.map +1 -1
  275. package/dist/schemas/scoring.d.ts +0 -6
  276. package/dist/schemas/scoring.d.ts.map +1 -1
  277. package/dist/schemas/scoring.js +0 -33
  278. package/dist/schemas/scoring.js.map +1 -1
  279. package/dist/schemas/signed-waivers.d.ts.map +1 -1
  280. package/dist/schemas/signed-waivers.js +0 -22
  281. package/dist/schemas/signed-waivers.js.map +1 -1
  282. package/dist/schemas/stats.d.ts.map +1 -1
  283. package/dist/schemas/stats.js +0 -60
  284. package/dist/schemas/stats.js.map +1 -1
  285. package/dist/schemas/team-joining.d.ts.map +1 -1
  286. package/dist/schemas/team-joining.js +0 -30
  287. package/dist/schemas/team-joining.js.map +1 -1
  288. package/dist/schemas/teams.d.ts +0 -1
  289. package/dist/schemas/teams.d.ts.map +1 -1
  290. package/dist/schemas/teams.js +0 -83
  291. package/dist/schemas/teams.js.map +1 -1
  292. package/dist/schemas/uploads.d.ts +0 -8
  293. package/dist/schemas/uploads.d.ts.map +1 -1
  294. package/dist/schemas/uploads.js +0 -29
  295. package/dist/schemas/uploads.js.map +1 -1
  296. package/dist/schemas/users.d.ts +0 -1
  297. package/dist/schemas/users.d.ts.map +1 -1
  298. package/dist/schemas/users.js +0 -41
  299. package/dist/schemas/users.js.map +1 -1
  300. package/dist/schemas/waiver-templates.d.ts.map +1 -1
  301. package/dist/schemas/waiver-templates.js +0 -7
  302. package/dist/schemas/waiver-templates.js.map +1 -1
  303. package/dist/sports/basketball-scoring.d.ts +0 -4
  304. package/dist/sports/basketball-scoring.d.ts.map +1 -1
  305. package/dist/sports/basketball-scoring.js +0 -34
  306. package/dist/sports/basketball-scoring.js.map +1 -1
  307. package/dist/sports/basketball.d.ts.map +1 -1
  308. package/dist/sports/basketball.js +0 -5
  309. package/dist/sports/basketball.js.map +1 -1
  310. package/dist/sports/bulk-entry.d.ts +0 -22
  311. package/dist/sports/bulk-entry.d.ts.map +1 -1
  312. package/dist/sports/bulk-entry.js +0 -10
  313. package/dist/sports/bulk-entry.js.map +1 -1
  314. package/dist/sports/column-catalog.d.ts +0 -17
  315. package/dist/sports/column-catalog.d.ts.map +1 -1
  316. package/dist/sports/column-catalog.js +0 -10
  317. package/dist/sports/column-catalog.js.map +1 -1
  318. package/dist/sports/contribution.d.ts +2 -59
  319. package/dist/sports/contribution.d.ts.map +1 -1
  320. package/dist/sports/contribution.js +2 -45
  321. package/dist/sports/contribution.js.map +1 -1
  322. package/dist/sports/curling-scoring.d.ts +0 -1
  323. package/dist/sports/curling-scoring.d.ts.map +1 -1
  324. package/dist/sports/curling-scoring.js +0 -27
  325. package/dist/sports/curling-scoring.js.map +1 -1
  326. package/dist/sports/curling.d.ts.map +1 -1
  327. package/dist/sports/curling.js +0 -4
  328. package/dist/sports/curling.js.map +1 -1
  329. package/dist/sports/finalized-record.d.ts +0 -17
  330. package/dist/sports/finalized-record.d.ts.map +1 -1
  331. package/dist/sports/finalized-record.js +0 -20
  332. package/dist/sports/finalized-record.js.map +1 -1
  333. package/dist/sports/football-scoring.d.ts.map +1 -1
  334. package/dist/sports/football-scoring.js +0 -21
  335. package/dist/sports/football-scoring.js.map +1 -1
  336. package/dist/sports/football.d.ts.map +1 -1
  337. package/dist/sports/football.js +0 -4
  338. package/dist/sports/football.js.map +1 -1
  339. package/dist/sports/index.d.ts.map +1 -1
  340. package/dist/sports/index.js +0 -2
  341. package/dist/sports/index.js.map +1 -1
  342. package/dist/sports/ledger-continuity.d.ts +0 -2
  343. package/dist/sports/ledger-continuity.d.ts.map +1 -1
  344. package/dist/sports/ledger-continuity.js +0 -5
  345. package/dist/sports/ledger-continuity.js.map +1 -1
  346. package/dist/sports/lifetime-summary.d.ts +0 -6
  347. package/dist/sports/lifetime-summary.d.ts.map +1 -1
  348. package/dist/sports/lifetime-summary.js +0 -7
  349. package/dist/sports/lifetime-summary.js.map +1 -1
  350. package/dist/sports/rankings.d.ts +0 -12
  351. package/dist/sports/rankings.d.ts.map +1 -1
  352. package/dist/sports/rankings.js +0 -15
  353. package/dist/sports/rankings.js.map +1 -1
  354. package/dist/sports/registry.d.ts +0 -10
  355. package/dist/sports/registry.d.ts.map +1 -1
  356. package/dist/sports/registry.js +0 -9
  357. package/dist/sports/registry.js.map +1 -1
  358. package/dist/sports/replay.d.ts +0 -11
  359. package/dist/sports/replay.d.ts.map +1 -1
  360. package/dist/sports/replay.js +0 -16
  361. package/dist/sports/replay.js.map +1 -1
  362. package/dist/sports/rollup-check.d.ts +0 -7
  363. package/dist/sports/rollup-check.d.ts.map +1 -1
  364. package/dist/sports/rollup-check.js +0 -14
  365. package/dist/sports/rollup-check.js.map +1 -1
  366. package/dist/sports/score-mirror.d.ts +0 -1
  367. package/dist/sports/score-mirror.d.ts.map +1 -1
  368. package/dist/sports/score-mirror.js +0 -4
  369. package/dist/sports/score-mirror.js.map +1 -1
  370. package/dist/sports/scoring-display.d.ts +0 -30
  371. package/dist/sports/scoring-display.d.ts.map +1 -1
  372. package/dist/sports/scoring-display.js +0 -9
  373. package/dist/sports/scoring-display.js.map +1 -1
  374. package/dist/sports/scoring.d.ts +0 -36
  375. package/dist/sports/scoring.d.ts.map +1 -1
  376. package/dist/sports/scoring.js +0 -10
  377. package/dist/sports/scoring.js.map +1 -1
  378. package/dist/sports/shared-columns.d.ts +0 -1
  379. package/dist/sports/shared-columns.d.ts.map +1 -1
  380. package/dist/sports/shared-columns.js +0 -7
  381. package/dist/sports/shared-columns.js.map +1 -1
  382. package/dist/sports/sport-adapter.d.ts +0 -32
  383. package/dist/sports/sport-adapter.d.ts.map +1 -1
  384. package/dist/sports/sport-adapter.js +0 -7
  385. package/dist/sports/sport-adapter.js.map +1 -1
  386. package/dist/sports/store-driver.d.ts +0 -28
  387. package/dist/sports/store-driver.d.ts.map +1 -1
  388. package/dist/sports/store-driver.js +0 -38
  389. package/dist/sports/store-driver.js.map +1 -1
  390. package/dist/types/audit.d.ts.map +1 -1
  391. package/dist/types/audit.js +0 -67
  392. package/dist/types/audit.js.map +1 -1
  393. package/dist/types/claims.d.ts +0 -10
  394. package/dist/types/claims.d.ts.map +1 -1
  395. package/dist/types/claims.js +0 -16
  396. package/dist/types/claims.js.map +1 -1
  397. package/dist/types/notifications.d.ts.map +1 -1
  398. package/dist/types/notifications.js +7 -25
  399. package/dist/types/notifications.js.map +1 -1
  400. package/dist/types/picture-owners.d.ts +0 -1
  401. package/dist/types/picture-owners.d.ts.map +1 -1
  402. package/dist/types/picture-owners.js +0 -6
  403. package/dist/types/picture-owners.js.map +1 -1
  404. package/dist/types/schedules.d.ts.map +1 -1
  405. package/dist/types/schedules.js +0 -9
  406. package/dist/types/schedules.js.map +1 -1
  407. package/dist/types/sports.d.ts.map +1 -1
  408. package/dist/types/sports.js +0 -24
  409. package/dist/types/sports.js.map +1 -1
  410. package/dist/types/stats.d.ts.map +1 -1
  411. package/dist/types/stats.js +0 -65
  412. package/dist/types/stats.js.map +1 -1
  413. package/dist/types/unions.d.ts +0 -2
  414. package/dist/types/unions.d.ts.map +1 -1
  415. package/dist/types/unions.js +3 -91
  416. package/dist/types/unions.js.map +1 -1
  417. package/dist/types/uploads.d.ts.map +1 -1
  418. package/dist/types/uploads.js +0 -7
  419. package/dist/types/uploads.js.map +1 -1
  420. package/dist/upload-variables/on-progress.d.ts.map +1 -1
  421. package/dist/upload-variables/on-progress.js +2 -5
  422. package/dist/upload-variables/on-progress.js.map +1 -1
  423. package/dist/upload-variables/picture-upload-variables.d.ts +0 -1
  424. package/dist/upload-variables/picture-upload-variables.d.ts.map +1 -1
  425. package/dist/upload-variables/picture-upload-variables.js +0 -4
  426. package/dist/upload-variables/picture-upload-variables.js.map +1 -1
  427. package/dist/upload-variables/sign-hardware-contract-variables.d.ts.map +1 -1
  428. package/dist/upload-variables/sign-hardware-contract-variables.js +0 -2
  429. package/dist/upload-variables/sign-hardware-contract-variables.js.map +1 -1
  430. package/dist/upload-variables/sign-waiver-variables.d.ts.map +1 -1
  431. package/dist/upload-variables/sign-waiver-variables.js +0 -4
  432. package/dist/upload-variables/sign-waiver-variables.js.map +1 -1
  433. package/dist/utils/account-status.d.ts.map +1 -1
  434. package/dist/utils/account-status.js +0 -4
  435. package/dist/utils/account-status.js.map +1 -1
  436. package/dist/utils/app-config.d.ts +0 -53
  437. package/dist/utils/app-config.d.ts.map +1 -1
  438. package/dist/utils/app-config.js +0 -62
  439. package/dist/utils/app-config.js.map +1 -1
  440. package/dist/utils/display-name.d.ts +0 -7
  441. package/dist/utils/display-name.d.ts.map +1 -1
  442. package/dist/utils/display-name.js +0 -8
  443. package/dist/utils/display-name.js.map +1 -1
  444. package/dist/utils/league-calendar.d.ts +0 -11
  445. package/dist/utils/league-calendar.d.ts.map +1 -1
  446. package/dist/utils/league-calendar.js +1 -18
  447. package/dist/utils/league-calendar.js.map +1 -1
  448. package/dist/utils/league-join-warning.d.ts +0 -11
  449. package/dist/utils/league-join-warning.d.ts.map +1 -1
  450. package/dist/utils/league-join-warning.js +0 -28
  451. package/dist/utils/league-join-warning.js.map +1 -1
  452. package/dist/utils/league-joining.d.ts +0 -1
  453. package/dist/utils/league-joining.d.ts.map +1 -1
  454. package/dist/utils/league-joining.js +0 -7
  455. package/dist/utils/league-joining.js.map +1 -1
  456. package/dist/utils/league-mode.d.ts +0 -1
  457. package/dist/utils/league-mode.d.ts.map +1 -1
  458. package/dist/utils/league-mode.js +0 -4
  459. package/dist/utils/league-mode.js.map +1 -1
  460. package/dist/utils/schedules.d.ts +0 -15
  461. package/dist/utils/schedules.d.ts.map +1 -1
  462. package/dist/utils/schedules.js +0 -19
  463. package/dist/utils/schedules.js.map +1 -1
  464. package/dist/utils/team-creation.d.ts +0 -2
  465. package/dist/utils/team-creation.d.ts.map +1 -1
  466. package/dist/utils/team-creation.js +0 -6
  467. package/dist/utils/team-creation.js.map +1 -1
  468. package/dist/utils/team-member-actions.d.ts +0 -6
  469. package/dist/utils/team-member-actions.d.ts.map +1 -1
  470. package/dist/utils/team-member-actions.js +0 -12
  471. package/dist/utils/team-member-actions.js.map +1 -1
  472. package/package.json +1 -1
@@ -1,14 +1,3 @@
1
- // The game tier of the stats model: the stat event documents, and the rollup the game document
2
- // carries (RULE-QS-SPORT-901, RULE-QS-SPORT-911, RULE-QS-SPORT-912).
3
- //
4
- // Each stat event is its own document, `sportGames/{gameId}/gameStatEvents/{eventId}`, and the
5
- // event documents are the source of truth: at every commit the game's `stats` equals their replay,
6
- // in `sequence` order, from the sport's empty stats. The store is append-only — an undo appends a
7
- // `STAT_VOID` and a correction a `STAT_CORRECTION`; no event is ever edited.
8
- //
9
- // An event names people by id; names resolve from `publicUsers` at read time (RULE-STD-ARCH-103, RULE-QS-SPORT-914).
10
- // `displayNameSnapshot` and `assistedByDisplayNameSnapshot` are carried only by copied events, as
11
- // the audit record of the name the stat was entered under — never read as identity.
12
1
  import { z } from 'zod';
13
2
  import { CURLING_ROUND_COUNT, MAX_CURLING_ROUND_POINTS } from '../constants/sports.js';
14
3
  import { buildGameRosterPlayerId } from '../ids/compound-ids.js';
@@ -17,25 +6,14 @@ import { BASKETBALL_ASSISTABLE_SHOT_EVENT_TYPE_KEYS, BASKETBALL_BULK_EDIT_EVENT_
17
6
  import { STAT_CORRECTION_EVENT_TYPE, STAT_CORRECTION_SOURCE_KEYS, STAT_EVENT_AUTHORITY_KEYS, STAT_VOID_EVENT_TYPE, } from '../types/stats.js';
18
7
  import { CAPTAIN_TEAM_ROLES } from '../types/unions.js';
19
8
  import { basketballBulkStatKeySchema, countSchema, epochMsSchema, gameRosterPlayerIdSchema, repairReasonSchema, statCounterKeySchema, statEventIdSchema, statsOperationIdSchema, teamIdSchema, userIdSchema, } from './atoms.js';
20
- // ---------------------------------------------------------------------------------------------
21
- // Lines — one per team of the game, one per roster entry holding a non-zero player line
22
- // ---------------------------------------------------------------------------------------------
23
- // A line's counters: one field per key of the sport's declared stat-key set (RULE-QS-SPORT-907), so a key
24
- // added to the set is a field of every line built from it.
25
9
  function counterShape(keys) {
26
10
  return Object.fromEntries(keys.map((key) => [key, countSchema]));
27
11
  }
28
12
  export const BasketballTeamStatsSchema = z.strictObject(counterShape(BASKETBALL_TEAM_STAT_KEYS));
29
- // `fantasyPoints` is `basketballFantasyPoints` of the line's own counters, on every basketball
30
- // player line — this game line and the totals lines built from it — stored so every table and
31
- // aggregate reads it rather than deriving it. FP is linear in the counters, so a totals line's FP
32
- // equals the sum of its games' FP.
33
13
  export const BasketballPlayerStatsSchema = z.strictObject({
34
14
  ...counterShape(BASKETBALL_PLAYER_STAT_KEYS),
35
15
  fantasyPoints: z.number().nonnegative(),
36
16
  });
37
- // `roundScores[n]` is end n + 1: `null` until the end is recorded, `0` on both teams for a blank end.
38
- // `score` is the sum of the recorded ends.
39
17
  export const CurlingTeamStatsSchema = z.strictObject({
40
18
  ...counterShape(CURLING_TEAM_STAT_KEYS),
41
19
  roundScores: z
@@ -43,24 +21,12 @@ export const CurlingTeamStatsSchema = z.strictObject({
43
21
  .length(CURLING_ROUND_COUNT),
44
22
  });
45
23
  export const FootballTeamStatsSchema = z.strictObject(counterShape(FOOTBALL_TEAM_STAT_KEYS));
46
- // ---------------------------------------------------------------------------------------------
47
- // The payload — exactly two keys for every sport (RULE-QS-SPORT-901)
48
- // ---------------------------------------------------------------------------------------------
49
- // The one declaration of the game `stats` payload. Each sport's is built through it from that
50
- // sport's game lines in `SPORT_LINE_SCHEMAS`, as `SPORT_GAME_STATS_SCHEMAS`. `playerStats` is keyed
51
- // by roster entry, never by person, so a person on both teams of a game holds a line on each side. A
52
- // sport with no player lines passes `z.never()`, so its map stays empty.
53
24
  export function gameStatsSchema(teamLine, playerLine) {
54
25
  return z.strictObject({
55
26
  teamStats: z.record(teamIdSchema, teamLine),
56
27
  playerStats: z.record(gameRosterPlayerIdSchema, playerLine),
57
28
  });
58
29
  }
59
- // ---------------------------------------------------------------------------------------------
60
- // Events
61
- // ---------------------------------------------------------------------------------------------
62
- // Every event: its id, its place in the replay, and when it was entered. The recorder facts are
63
- // derived by the writing core, never taken from the payload (RULE-STD-ARCH-106); a copied event has none.
64
30
  const statEventBase = {
65
31
  eventId: statEventIdSchema,
66
32
  sequence: z.number().int().positive(),
@@ -68,22 +34,18 @@ const statEventBase = {
68
34
  acceptedAt: epochMsSchema.optional(),
69
35
  recordedByUserId: userIdSchema.optional(),
70
36
  recordedByAuthority: z.enum(STAT_EVENT_AUTHORITY_KEYS).optional(),
71
- // Only for the two team roles: the team whose authority the event was recorded under.
72
37
  recordedByTeamId: teamIdSchema.optional(),
73
38
  };
74
- // A player-attributed event names the roster entry `{teamId}_{playerUserId}` whose line it changes.
75
39
  const playerEventFields = {
76
40
  teamId: teamIdSchema,
77
41
  playerUserId: userIdSchema,
78
42
  displayNameSnapshot: z.string().optional(),
79
43
  };
80
- // Basketball
81
44
  export const BasketballOnePointEventSchema = z.strictObject({
82
45
  ...statEventBase,
83
46
  ...playerEventFields,
84
47
  type: z.literal(BASKETBALL_ONE_POINT_EVENT_TYPE),
85
48
  });
86
- // An assisted shot names its assister on the same event, which credits both players.
87
49
  export const BasketballAssistableShotEventSchema = z
88
50
  .strictObject({
89
51
  ...statEventBase,
@@ -103,8 +65,6 @@ export const BasketballTimeoutEventSchema = z.strictObject({
103
65
  teamId: teamIdSchema,
104
66
  type: z.literal(BASKETBALL_TIMEOUT_EVENT_TYPE),
105
67
  });
106
- // A scorer's edit: `value` is the signed change to `stat`, entered against `previousValue`, the
107
- // value the form showed. A copied bulk edit has no `previousValue`; nothing validates one again.
108
68
  export const BasketballBulkEditEventSchema = z.strictObject({
109
69
  ...statEventBase,
110
70
  ...playerEventFields,
@@ -113,7 +73,6 @@ export const BasketballBulkEditEventSchema = z.strictObject({
113
73
  value: z.number().int(),
114
74
  previousValue: countSchema.optional(),
115
75
  });
116
- // Curling — an event names the end it records; it names no player.
117
76
  const curlingRoundNumberSchema = z.number().int().min(1).max(CURLING_ROUND_COUNT);
118
77
  export const CurlingRoundScoreEventSchema = z.strictObject({
119
78
  ...statEventBase,
@@ -127,7 +86,6 @@ export const CurlingBlankEndEventSchema = z.strictObject({
127
86
  type: z.literal(CURLING_ROUND_BLANK_EVENT_TYPE),
128
87
  roundNumber: curlingRoundNumberSchema,
129
88
  });
130
- // Football — team-attributed only.
131
89
  export const FootballScoreEventSchema = z.strictObject({
132
90
  ...statEventBase,
133
91
  type: z.enum(FOOTBALL_SCORE_EVENT_TYPE_KEYS),
@@ -140,9 +98,6 @@ export const FootballBulkEditEventSchema = z.strictObject({
140
98
  value: z.number().int(),
141
99
  previousValue: countSchema,
142
100
  });
143
- // The store-level events, members of every sport's union.
144
- // Undoes exactly the event it targets. Its id is derived from the target, so a target has at most
145
- // one void and a second undo of the same event is the same document.
146
101
  export const StatVoidEventSchema = z
147
102
  .strictObject({
148
103
  ...statEventBase,
@@ -153,9 +108,6 @@ export const StatVoidEventSchema = z
153
108
  message: 'A void is stored at the id its target derives.',
154
109
  path: ['eventId'],
155
110
  });
156
- // Adds `value` to one correctable field of one line — the player line `{teamId}_{playerUserId}`
157
- // when it names a player, the team line of `teamId` when it does not. It never cascades: a player
158
- // correction does not move the team's score.
159
111
  export const StatCorrectionEventSchema = z
160
112
  .strictObject({
161
113
  ...statEventBase,
@@ -167,8 +119,6 @@ export const StatCorrectionEventSchema = z
167
119
  correctionSource: z.enum(STAT_CORRECTION_SOURCE_KEYS),
168
120
  operationId: statsOperationIdSchema,
169
121
  reason: repairReasonSchema,
170
- // The ghost a link re-keyed this correction's player line from. The id was derived from the
171
- // ghost's line when the correction was written, and a document id never changes.
172
122
  rekeyedFromGhostUserId: userIdSchema.optional(),
173
123
  })
174
124
  .refine((event) => event.eventId ===
@@ -178,8 +128,6 @@ export const StatCorrectionEventSchema = z
178
128
  message: 'A correction is stored at the id its operation, line, and field derive.',
179
129
  path: ['eventId'],
180
130
  });
181
- // Recorder facts are all present or all absent, and a team is named exactly when the authority is a
182
- // team role.
183
131
  function recorderFactsAgree(event) {
184
132
  const facts = [event.acceptedAt, event.recordedByUserId, event.recordedByAuthority];
185
133
  const present = facts.filter((fact) => fact !== undefined).length;
@@ -188,9 +136,6 @@ function recorderFactsAgree(event) {
188
136
  const teamAuthority = CAPTAIN_TEAM_ROLES.includes(event.recordedByAuthority ?? '');
189
137
  return teamAuthority === (event.recordedByTeamId !== undefined);
190
138
  }
191
- // A name snapshot is the audit record a copied event keeps of the name its stat was entered under.
192
- // Only the writing core stamps recorder facts, and it writes ids only, so an event carrying both a
193
- // snapshot and a recorder fact is refused (RULE-STD-ARCH-103, RULE-QS-SPORT-914).
194
139
  function snapshotsOnlyOnCopiedEvents(event) {
195
140
  const snapshot = event.displayNameSnapshot !== undefined || event.assistedByDisplayNameSnapshot !== undefined;
196
141
  const recorded = [
@@ -201,7 +146,6 @@ function snapshotsOnlyOnCopiedEvents(event) {
201
146
  ].some((fact) => fact !== undefined);
202
147
  return !(snapshot && recorded);
203
148
  }
204
- // Event types are disjoint across sports, so `type` alone discriminates the whole union.
205
149
  export const GameStatEventSchema = z
206
150
  .discriminatedUnion('type', [
207
151
  BasketballOnePointEventSchema,
@@ -1 +1 @@
1
- {"version":3,"file":"game-stats.js","sourceRoot":"","sources":["../../src/doc-schemas/game-stats.ts"],"names":[],"mappings":"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","sourcesContent":["// The game tier of the stats model: the stat event documents, and the rollup the game document\n// carries (RULE-QS-SPORT-901, RULE-QS-SPORT-911, RULE-QS-SPORT-912).\n//\n// Each stat event is its own document, `sportGames/{gameId}/gameStatEvents/{eventId}`, and the\n// event documents are the source of truth: at every commit the game's `stats` equals their replay,\n// in `sequence` order, from the sport's empty stats. The store is append-only — an undo appends a\n// `STAT_VOID` and a correction a `STAT_CORRECTION`; no event is ever edited.\n//\n// An event names people by id; names resolve from `publicUsers` at read time (RULE-STD-ARCH-103, RULE-QS-SPORT-914).\n// `displayNameSnapshot` and `assistedByDisplayNameSnapshot` are carried only by copied events, as\n// the audit record of the name the stat was entered under — never read as identity.\n\nimport { z } from 'zod';\nimport { CURLING_ROUND_COUNT, MAX_CURLING_ROUND_POINTS } from '../constants/sports.js';\nimport { buildGameRosterPlayerId } from '../ids/compound-ids.js';\nimport { buildStatCorrectionId, buildStatVoidId } from '../ids/stat-event-ids.js';\nimport {\n BASKETBALL_ASSISTABLE_SHOT_EVENT_TYPE_KEYS,\n BASKETBALL_BULK_EDIT_EVENT_TYPE,\n BASKETBALL_ONE_POINT_EVENT_TYPE,\n BASKETBALL_PLAYER_STAT_KEYS,\n BASKETBALL_PLAYER_TALLY_EVENT_TYPE_KEYS,\n BASKETBALL_TEAM_STAT_KEYS,\n BASKETBALL_TIMEOUT_EVENT_TYPE,\n CURLING_ROUND_BLANK_EVENT_TYPE,\n CURLING_ROUND_SCORE_EVENT_TYPE,\n CURLING_TEAM_STAT_KEYS,\n FOOTBALL_BULK_EDIT_EVENT_TYPE,\n FOOTBALL_SCORE_EVENT_TYPE_KEYS,\n FOOTBALL_TEAM_STAT_KEYS,\n} from '../types/sports.js';\nimport type {\n BasketballStatEventType,\n CurlingStatEventType,\n FootballStatEventType,\n StatCounterKey,\n} from '../types/sports.js';\nimport {\n STAT_CORRECTION_EVENT_TYPE,\n STAT_CORRECTION_SOURCE_KEYS,\n STAT_EVENT_AUTHORITY_KEYS,\n STAT_VOID_EVENT_TYPE,\n} from '../types/stats.js';\nimport { CAPTAIN_TEAM_ROLES } from '../types/unions.js';\nimport {\n basketballBulkStatKeySchema,\n countSchema,\n epochMsSchema,\n gameRosterPlayerIdSchema,\n repairReasonSchema,\n statCounterKeySchema,\n statEventIdSchema,\n statsOperationIdSchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\n\n// ---------------------------------------------------------------------------------------------\n// Lines — one per team of the game, one per roster entry holding a non-zero player line\n// ---------------------------------------------------------------------------------------------\n\n// A line's counters: one field per key of the sport's declared stat-key set (RULE-QS-SPORT-907), so a key\n// added to the set is a field of every line built from it.\nfunction counterShape<K extends StatCounterKey>(keys: readonly K[]): Record<K, typeof countSchema> {\n return Object.fromEntries(keys.map((key) => [key, countSchema])) as Record<K, typeof countSchema>;\n}\n\nexport const BasketballTeamStatsSchema = z.strictObject(counterShape(BASKETBALL_TEAM_STAT_KEYS));\nexport type BasketballTeamStats = z.infer<typeof BasketballTeamStatsSchema>;\n\n// `fantasyPoints` is `basketballFantasyPoints` of the line's own counters, on every basketball\n// player line — this game line and the totals lines built from it — stored so every table and\n// aggregate reads it rather than deriving it. FP is linear in the counters, so a totals line's FP\n// equals the sum of its games' FP.\nexport const BasketballPlayerStatsSchema = z.strictObject({\n ...counterShape(BASKETBALL_PLAYER_STAT_KEYS),\n fantasyPoints: z.number().nonnegative(),\n});\nexport type BasketballPlayerStats = z.infer<typeof BasketballPlayerStatsSchema>;\n\n// `roundScores[n]` is end n + 1: `null` until the end is recorded, `0` on both teams for a blank end.\n// `score` is the sum of the recorded ends.\nexport const CurlingTeamStatsSchema = z.strictObject({\n ...counterShape(CURLING_TEAM_STAT_KEYS),\n roundScores: z\n .array(z.number().int().min(0).max(MAX_CURLING_ROUND_POINTS).nullable())\n .length(CURLING_ROUND_COUNT),\n});\nexport type CurlingTeamStats = z.infer<typeof CurlingTeamStatsSchema>;\n\nexport const FootballTeamStatsSchema = z.strictObject(counterShape(FOOTBALL_TEAM_STAT_KEYS));\nexport type FootballTeamStats = z.infer<typeof FootballTeamStatsSchema>;\n\n// ---------------------------------------------------------------------------------------------\n// The payload — exactly two keys for every sport (RULE-QS-SPORT-901)\n// ---------------------------------------------------------------------------------------------\n\n// The one declaration of the game `stats` payload. Each sport's is built through it from that\n// sport's game lines in `SPORT_LINE_SCHEMAS`, as `SPORT_GAME_STATS_SCHEMAS`. `playerStats` is keyed\n// by roster entry, never by person, so a person on both teams of a game holds a line on each side. A\n// sport with no player lines passes `z.never()`, so its map stays empty.\nexport function gameStatsSchema<TeamLine extends z.ZodType, PlayerLine extends z.ZodType>(\n teamLine: TeamLine,\n playerLine: PlayerLine,\n) {\n return z.strictObject({\n teamStats: z.record(teamIdSchema, teamLine),\n playerStats: z.record(gameRosterPlayerIdSchema, playerLine),\n });\n}\n\n// ---------------------------------------------------------------------------------------------\n// Events\n// ---------------------------------------------------------------------------------------------\n\n// Every event: its id, its place in the replay, and when it was entered. The recorder facts are\n// derived by the writing core, never taken from the payload (RULE-STD-ARCH-106); a copied event has none.\nconst statEventBase = {\n eventId: statEventIdSchema,\n sequence: z.number().int().positive(),\n recordedAt: epochMsSchema,\n acceptedAt: epochMsSchema.optional(),\n recordedByUserId: userIdSchema.optional(),\n recordedByAuthority: z.enum(STAT_EVENT_AUTHORITY_KEYS).optional(),\n // Only for the two team roles: the team whose authority the event was recorded under.\n recordedByTeamId: teamIdSchema.optional(),\n};\n\n// A player-attributed event names the roster entry `{teamId}_{playerUserId}` whose line it changes.\nconst playerEventFields = {\n teamId: teamIdSchema,\n playerUserId: userIdSchema,\n displayNameSnapshot: z.string().optional(),\n};\n\n// Basketball\n\nexport const BasketballOnePointEventSchema = z.strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.literal(BASKETBALL_ONE_POINT_EVENT_TYPE),\n});\n\n// An assisted shot names its assister on the same event, which credits both players.\nexport const BasketballAssistableShotEventSchema = z\n .strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.enum(BASKETBALL_ASSISTABLE_SHOT_EVENT_TYPE_KEYS),\n assistedByUserId: userIdSchema.optional(),\n assistedByDisplayNameSnapshot: z.string().optional(),\n })\n .refine(\n (event) =>\n event.assistedByDisplayNameSnapshot === undefined || event.assistedByUserId !== undefined,\n 'An assister snapshot needs the assister.',\n );\n\nexport const BasketballPlayerTallyEventSchema = z.strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.enum(BASKETBALL_PLAYER_TALLY_EVENT_TYPE_KEYS),\n});\n\nexport const BasketballTimeoutEventSchema = z.strictObject({\n ...statEventBase,\n teamId: teamIdSchema,\n type: z.literal(BASKETBALL_TIMEOUT_EVENT_TYPE),\n});\n\n// A scorer's edit: `value` is the signed change to `stat`, entered against `previousValue`, the\n// value the form showed. A copied bulk edit has no `previousValue`; nothing validates one again.\nexport const BasketballBulkEditEventSchema = z.strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.literal(BASKETBALL_BULK_EDIT_EVENT_TYPE),\n stat: basketballBulkStatKeySchema,\n value: z.number().int(),\n previousValue: countSchema.optional(),\n});\n\n// Curling — an event names the end it records; it names no player.\n\nconst curlingRoundNumberSchema = z.number().int().min(1).max(CURLING_ROUND_COUNT);\n\nexport const CurlingRoundScoreEventSchema = z.strictObject({\n ...statEventBase,\n type: z.literal(CURLING_ROUND_SCORE_EVENT_TYPE),\n teamId: teamIdSchema,\n roundNumber: curlingRoundNumberSchema,\n points: z.number().int().min(1).max(MAX_CURLING_ROUND_POINTS),\n});\n\nexport const CurlingBlankEndEventSchema = z.strictObject({\n ...statEventBase,\n type: z.literal(CURLING_ROUND_BLANK_EVENT_TYPE),\n roundNumber: curlingRoundNumberSchema,\n});\n\n// Football — team-attributed only.\n\nexport const FootballScoreEventSchema = z.strictObject({\n ...statEventBase,\n type: z.enum(FOOTBALL_SCORE_EVENT_TYPE_KEYS),\n teamId: teamIdSchema,\n});\n\nexport const FootballBulkEditEventSchema = z.strictObject({\n ...statEventBase,\n type: z.literal(FOOTBALL_BULK_EDIT_EVENT_TYPE),\n teamId: teamIdSchema,\n value: z.number().int(),\n previousValue: countSchema,\n});\n\n// The store-level events, members of every sport's union.\n\n// Undoes exactly the event it targets. Its id is derived from the target, so a target has at most\n// one void and a second undo of the same event is the same document.\nexport const StatVoidEventSchema = z\n .strictObject({\n ...statEventBase,\n type: z.literal(STAT_VOID_EVENT_TYPE),\n targetEventId: statEventIdSchema,\n })\n .refine((event) => event.eventId === buildStatVoidId(event.targetEventId), {\n message: 'A void is stored at the id its target derives.',\n path: ['eventId'],\n });\n\n// Adds `value` to one correctable field of one line — the player line `{teamId}_{playerUserId}`\n// when it names a player, the team line of `teamId` when it does not. It never cascades: a player\n// correction does not move the team's score.\nexport const StatCorrectionEventSchema = z\n .strictObject({\n ...statEventBase,\n type: z.literal(STAT_CORRECTION_EVENT_TYPE),\n teamId: teamIdSchema,\n playerUserId: userIdSchema.optional(),\n stat: statCounterKeySchema,\n value: z.number().int(),\n correctionSource: z.enum(STAT_CORRECTION_SOURCE_KEYS),\n operationId: statsOperationIdSchema,\n reason: repairReasonSchema,\n // The ghost a link re-keyed this correction's player line from. The id was derived from the\n // ghost's line when the correction was written, and a document id never changes.\n rekeyedFromGhostUserId: userIdSchema.optional(),\n })\n .refine(\n (event) =>\n event.eventId ===\n buildStatCorrectionId(\n event.operationId,\n event.playerUserId === undefined\n ? event.teamId\n : buildGameRosterPlayerId(\n event.teamId,\n event.rekeyedFromGhostUserId ?? event.playerUserId,\n ),\n event.stat,\n ),\n {\n message: 'A correction is stored at the id its operation, line, and field derive.',\n path: ['eventId'],\n },\n );\n\n// Recorder facts are all present or all absent, and a team is named exactly when the authority is a\n// team role.\nfunction recorderFactsAgree(event: {\n acceptedAt?: number;\n recordedByUserId?: string;\n recordedByAuthority?: (typeof STAT_EVENT_AUTHORITY_KEYS)[number];\n recordedByTeamId?: string;\n}): boolean {\n const facts = [event.acceptedAt, event.recordedByUserId, event.recordedByAuthority];\n const present = facts.filter((fact) => fact !== undefined).length;\n if (present !== 0 && present !== facts.length) return false;\n const teamAuthority = (CAPTAIN_TEAM_ROLES as readonly string[]).includes(\n event.recordedByAuthority ?? '',\n );\n return teamAuthority === (event.recordedByTeamId !== undefined);\n}\n\n// A name snapshot is the audit record a copied event keeps of the name its stat was entered under.\n// Only the writing core stamps recorder facts, and it writes ids only, so an event carrying both a\n// snapshot and a recorder fact is refused (RULE-STD-ARCH-103, RULE-QS-SPORT-914).\nfunction snapshotsOnlyOnCopiedEvents(event: {\n acceptedAt?: number;\n recordedByUserId?: string;\n recordedByAuthority?: string;\n recordedByTeamId?: string;\n displayNameSnapshot?: string;\n assistedByDisplayNameSnapshot?: string;\n}): boolean {\n const snapshot =\n event.displayNameSnapshot !== undefined || event.assistedByDisplayNameSnapshot !== undefined;\n const recorded = [\n event.acceptedAt,\n event.recordedByUserId,\n event.recordedByAuthority,\n event.recordedByTeamId,\n ].some((fact) => fact !== undefined);\n return !(snapshot && recorded);\n}\n\n// Event types are disjoint across sports, so `type` alone discriminates the whole union.\nexport const GameStatEventSchema = z\n .discriminatedUnion('type', [\n BasketballOnePointEventSchema,\n BasketballAssistableShotEventSchema,\n BasketballPlayerTallyEventSchema,\n BasketballTimeoutEventSchema,\n BasketballBulkEditEventSchema,\n CurlingRoundScoreEventSchema,\n CurlingBlankEndEventSchema,\n FootballScoreEventSchema,\n FootballBulkEditEventSchema,\n StatVoidEventSchema,\n StatCorrectionEventSchema,\n ])\n .refine(\n recorderFactsAgree,\n 'Recorder facts are all present, or all absent, with a team only for a team role.',\n )\n .refine(\n snapshotsOnlyOnCopiedEvents,\n 'A name snapshot belongs to a copied event, which carries no recorder facts.',\n );\nexport type GameStatEvent = z.infer<typeof GameStatEventSchema>;\nexport type GameStatEventType = GameStatEvent['type'];\n\nexport type BasketballStatEvent = Extract<GameStatEvent, { type: BasketballStatEventType }>;\nexport type CurlingRoundScoreEvent = z.infer<typeof CurlingRoundScoreEventSchema>;\nexport type CurlingBlankEndEvent = z.infer<typeof CurlingBlankEndEventSchema>;\nexport type CurlingStatEvent = Extract<GameStatEvent, { type: CurlingStatEventType }>;\nexport type FootballStatEvent = Extract<GameStatEvent, { type: FootballStatEventType }>;\nexport type StatVoidEvent = z.infer<typeof StatVoidEventSchema>;\nexport type StatCorrectionEvent = z.infer<typeof StatCorrectionEventSchema>;\n"]}
1
+ {"version":3,"file":"game-stats.js","sourceRoot":"","sources":["../../src/doc-schemas/game-stats.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { CURLING_ROUND_COUNT, MAX_CURLING_ROUND_POINTS } from '../constants/sports.js';\nimport { buildGameRosterPlayerId } from '../ids/compound-ids.js';\nimport { buildStatCorrectionId, buildStatVoidId } from '../ids/stat-event-ids.js';\nimport {\n BASKETBALL_ASSISTABLE_SHOT_EVENT_TYPE_KEYS,\n BASKETBALL_BULK_EDIT_EVENT_TYPE,\n BASKETBALL_ONE_POINT_EVENT_TYPE,\n BASKETBALL_PLAYER_STAT_KEYS,\n BASKETBALL_PLAYER_TALLY_EVENT_TYPE_KEYS,\n BASKETBALL_TEAM_STAT_KEYS,\n BASKETBALL_TIMEOUT_EVENT_TYPE,\n CURLING_ROUND_BLANK_EVENT_TYPE,\n CURLING_ROUND_SCORE_EVENT_TYPE,\n CURLING_TEAM_STAT_KEYS,\n FOOTBALL_BULK_EDIT_EVENT_TYPE,\n FOOTBALL_SCORE_EVENT_TYPE_KEYS,\n FOOTBALL_TEAM_STAT_KEYS,\n} from '../types/sports.js';\nimport type {\n BasketballStatEventType,\n CurlingStatEventType,\n FootballStatEventType,\n StatCounterKey,\n} from '../types/sports.js';\nimport {\n STAT_CORRECTION_EVENT_TYPE,\n STAT_CORRECTION_SOURCE_KEYS,\n STAT_EVENT_AUTHORITY_KEYS,\n STAT_VOID_EVENT_TYPE,\n} from '../types/stats.js';\nimport { CAPTAIN_TEAM_ROLES } from '../types/unions.js';\nimport {\n basketballBulkStatKeySchema,\n countSchema,\n epochMsSchema,\n gameRosterPlayerIdSchema,\n repairReasonSchema,\n statCounterKeySchema,\n statEventIdSchema,\n statsOperationIdSchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\n\nfunction counterShape<K extends StatCounterKey>(keys: readonly K[]): Record<K, typeof countSchema> {\n return Object.fromEntries(keys.map((key) => [key, countSchema])) as Record<K, typeof countSchema>;\n}\n\nexport const BasketballTeamStatsSchema = z.strictObject(counterShape(BASKETBALL_TEAM_STAT_KEYS));\nexport type BasketballTeamStats = z.infer<typeof BasketballTeamStatsSchema>;\n\nexport const BasketballPlayerStatsSchema = z.strictObject({\n ...counterShape(BASKETBALL_PLAYER_STAT_KEYS),\n fantasyPoints: z.number().nonnegative(),\n});\nexport type BasketballPlayerStats = z.infer<typeof BasketballPlayerStatsSchema>;\n\nexport const CurlingTeamStatsSchema = z.strictObject({\n ...counterShape(CURLING_TEAM_STAT_KEYS),\n roundScores: z\n .array(z.number().int().min(0).max(MAX_CURLING_ROUND_POINTS).nullable())\n .length(CURLING_ROUND_COUNT),\n});\nexport type CurlingTeamStats = z.infer<typeof CurlingTeamStatsSchema>;\n\nexport const FootballTeamStatsSchema = z.strictObject(counterShape(FOOTBALL_TEAM_STAT_KEYS));\nexport type FootballTeamStats = z.infer<typeof FootballTeamStatsSchema>;\n\nexport function gameStatsSchema<TeamLine extends z.ZodType, PlayerLine extends z.ZodType>(\n teamLine: TeamLine,\n playerLine: PlayerLine,\n) {\n return z.strictObject({\n teamStats: z.record(teamIdSchema, teamLine),\n playerStats: z.record(gameRosterPlayerIdSchema, playerLine),\n });\n}\n\nconst statEventBase = {\n eventId: statEventIdSchema,\n sequence: z.number().int().positive(),\n recordedAt: epochMsSchema,\n acceptedAt: epochMsSchema.optional(),\n recordedByUserId: userIdSchema.optional(),\n recordedByAuthority: z.enum(STAT_EVENT_AUTHORITY_KEYS).optional(),\n recordedByTeamId: teamIdSchema.optional(),\n};\n\nconst playerEventFields = {\n teamId: teamIdSchema,\n playerUserId: userIdSchema,\n displayNameSnapshot: z.string().optional(),\n};\n\nexport const BasketballOnePointEventSchema = z.strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.literal(BASKETBALL_ONE_POINT_EVENT_TYPE),\n});\n\nexport const BasketballAssistableShotEventSchema = z\n .strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.enum(BASKETBALL_ASSISTABLE_SHOT_EVENT_TYPE_KEYS),\n assistedByUserId: userIdSchema.optional(),\n assistedByDisplayNameSnapshot: z.string().optional(),\n })\n .refine(\n (event) =>\n event.assistedByDisplayNameSnapshot === undefined || event.assistedByUserId !== undefined,\n 'An assister snapshot needs the assister.',\n );\n\nexport const BasketballPlayerTallyEventSchema = z.strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.enum(BASKETBALL_PLAYER_TALLY_EVENT_TYPE_KEYS),\n});\n\nexport const BasketballTimeoutEventSchema = z.strictObject({\n ...statEventBase,\n teamId: teamIdSchema,\n type: z.literal(BASKETBALL_TIMEOUT_EVENT_TYPE),\n});\n\nexport const BasketballBulkEditEventSchema = z.strictObject({\n ...statEventBase,\n ...playerEventFields,\n type: z.literal(BASKETBALL_BULK_EDIT_EVENT_TYPE),\n stat: basketballBulkStatKeySchema,\n value: z.number().int(),\n previousValue: countSchema.optional(),\n});\n\nconst curlingRoundNumberSchema = z.number().int().min(1).max(CURLING_ROUND_COUNT);\n\nexport const CurlingRoundScoreEventSchema = z.strictObject({\n ...statEventBase,\n type: z.literal(CURLING_ROUND_SCORE_EVENT_TYPE),\n teamId: teamIdSchema,\n roundNumber: curlingRoundNumberSchema,\n points: z.number().int().min(1).max(MAX_CURLING_ROUND_POINTS),\n});\n\nexport const CurlingBlankEndEventSchema = z.strictObject({\n ...statEventBase,\n type: z.literal(CURLING_ROUND_BLANK_EVENT_TYPE),\n roundNumber: curlingRoundNumberSchema,\n});\n\nexport const FootballScoreEventSchema = z.strictObject({\n ...statEventBase,\n type: z.enum(FOOTBALL_SCORE_EVENT_TYPE_KEYS),\n teamId: teamIdSchema,\n});\n\nexport const FootballBulkEditEventSchema = z.strictObject({\n ...statEventBase,\n type: z.literal(FOOTBALL_BULK_EDIT_EVENT_TYPE),\n teamId: teamIdSchema,\n value: z.number().int(),\n previousValue: countSchema,\n});\n\nexport const StatVoidEventSchema = z\n .strictObject({\n ...statEventBase,\n type: z.literal(STAT_VOID_EVENT_TYPE),\n targetEventId: statEventIdSchema,\n })\n .refine((event) => event.eventId === buildStatVoidId(event.targetEventId), {\n message: 'A void is stored at the id its target derives.',\n path: ['eventId'],\n });\n\nexport const StatCorrectionEventSchema = z\n .strictObject({\n ...statEventBase,\n type: z.literal(STAT_CORRECTION_EVENT_TYPE),\n teamId: teamIdSchema,\n playerUserId: userIdSchema.optional(),\n stat: statCounterKeySchema,\n value: z.number().int(),\n correctionSource: z.enum(STAT_CORRECTION_SOURCE_KEYS),\n operationId: statsOperationIdSchema,\n reason: repairReasonSchema,\n rekeyedFromGhostUserId: userIdSchema.optional(),\n })\n .refine(\n (event) =>\n event.eventId ===\n buildStatCorrectionId(\n event.operationId,\n event.playerUserId === undefined\n ? event.teamId\n : buildGameRosterPlayerId(\n event.teamId,\n event.rekeyedFromGhostUserId ?? event.playerUserId,\n ),\n event.stat,\n ),\n {\n message: 'A correction is stored at the id its operation, line, and field derive.',\n path: ['eventId'],\n },\n );\n\nfunction recorderFactsAgree(event: {\n acceptedAt?: number;\n recordedByUserId?: string;\n recordedByAuthority?: (typeof STAT_EVENT_AUTHORITY_KEYS)[number];\n recordedByTeamId?: string;\n}): boolean {\n const facts = [event.acceptedAt, event.recordedByUserId, event.recordedByAuthority];\n const present = facts.filter((fact) => fact !== undefined).length;\n if (present !== 0 && present !== facts.length) return false;\n const teamAuthority = (CAPTAIN_TEAM_ROLES as readonly string[]).includes(\n event.recordedByAuthority ?? '',\n );\n return teamAuthority === (event.recordedByTeamId !== undefined);\n}\n\nfunction snapshotsOnlyOnCopiedEvents(event: {\n acceptedAt?: number;\n recordedByUserId?: string;\n recordedByAuthority?: string;\n recordedByTeamId?: string;\n displayNameSnapshot?: string;\n assistedByDisplayNameSnapshot?: string;\n}): boolean {\n const snapshot =\n event.displayNameSnapshot !== undefined || event.assistedByDisplayNameSnapshot !== undefined;\n const recorded = [\n event.acceptedAt,\n event.recordedByUserId,\n event.recordedByAuthority,\n event.recordedByTeamId,\n ].some((fact) => fact !== undefined);\n return !(snapshot && recorded);\n}\n\nexport const GameStatEventSchema = z\n .discriminatedUnion('type', [\n BasketballOnePointEventSchema,\n BasketballAssistableShotEventSchema,\n BasketballPlayerTallyEventSchema,\n BasketballTimeoutEventSchema,\n BasketballBulkEditEventSchema,\n CurlingRoundScoreEventSchema,\n CurlingBlankEndEventSchema,\n FootballScoreEventSchema,\n FootballBulkEditEventSchema,\n StatVoidEventSchema,\n StatCorrectionEventSchema,\n ])\n .refine(\n recorderFactsAgree,\n 'Recorder facts are all present, or all absent, with a team only for a team role.',\n )\n .refine(\n snapshotsOnlyOnCopiedEvents,\n 'A name snapshot belongs to a copied event, which carries no recorder facts.',\n );\nexport type GameStatEvent = z.infer<typeof GameStatEventSchema>;\nexport type GameStatEventType = GameStatEvent['type'];\n\nexport type BasketballStatEvent = Extract<GameStatEvent, { type: BasketballStatEventType }>;\nexport type CurlingRoundScoreEvent = z.infer<typeof CurlingRoundScoreEventSchema>;\nexport type CurlingBlankEndEvent = z.infer<typeof CurlingBlankEndEventSchema>;\nexport type CurlingStatEvent = Extract<GameStatEvent, { type: CurlingStatEventType }>;\nexport type FootballStatEvent = Extract<GameStatEvent, { type: FootballStatEventType }>;\nexport type StatVoidEvent = z.infer<typeof StatVoidEventSchema>;\nexport type StatCorrectionEvent = z.infer<typeof StatCorrectionEventSchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"league-team.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/league-team.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqC3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAK1D,eAAO,MAAM,uBAAuB;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
1
+ {"version":3,"file":"league-team.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/league-team.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoB3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,uBAAuB;;;;iBAIlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -1,5 +1,3 @@
1
- // `leagueTeams/{teamId}` — one team in one league, with its derived season rollups. Who is on the
2
- // team, and who captains it, is `teamMemberships` — never a field here.
3
1
  import { z } from 'zod';
4
2
  import { CONTACT_PHONE_INPUT_FORMAT } from '../input-formats/input-formats.js';
5
3
  import { countSchema, epochMsSchema, leagueIdSchema, teamIconSchema, teamTypeSchema, textFieldSchema, userIdSchema, } from './atoms.js';
@@ -9,46 +7,25 @@ export const LeagueTeamSchema = z.object({
9
7
  name: z.string(),
10
8
  icon: teamIconSchema,
11
9
  leagueId: leagueIdSchema,
12
- // Present only in a Competitive/Recreational league.
13
10
  teamType: teamTypeSchema.optional(),
14
- // The account that created the team — the new captain, or the admin who created it for a ghost
15
- // captain. A creation record, never a membership or an authority.
16
11
  createdByUserId: userIdSchema,
17
- // The team's standings line, absent until its first game is finalized.
18
12
  seasonStats: TeamSeasonStatsSchema.optional(),
19
- // The league player stats: one row per person the team's games credited, keyed by userId (real or
20
- // ghost). The team's league, the team, and the key are the membership the row belongs to.
21
13
  playerSeasonStats: z.record(userIdSchema, PlayerSeasonStatsSchema).optional(),
22
- // The team's picture gallery summary — absent is an empty gallery. Only the picture core writes
23
- // it; the team callables and the copy action never do.
24
14
  pictures: GallerySummarySchema.optional(),
25
- // Advanced by every membership change on the team after its creation; absent until the first.
26
- // Only its changing matters: game creation and a game's team replacement read this document in the
27
- // transaction that seeds a roster from the team's memberships, so a membership change landing at
28
- // the same moment conflicts with them instead of missing the new game (RULE-STD-BACKEND-116).
15
+ // Only its changing matters: the write fence between membership changes and roster seeding
16
+ // (RULE-STD-BACKEND-116).
29
17
  membershipRevision: countSchema.optional(),
30
- // Advanced by every invitation and join request a door creates for the team; absent until the
31
- // first. Only its changing matters: a pending invitation or request between one team and one
32
- // person is unique, and a membership on the team closes both, but a transaction does not lock a
33
- // query against an insert — so each creation writes this document, which every competing
34
- // creation and every membership door also writes, and two racers conflict instead of both passing
35
- // their checks (RULE-STD-BACKEND-116).
18
+ // Only its changing matters: the write fence between competing invitations, join requests, and
19
+ // membership doors (RULE-STD-BACKEND-116).
36
20
  joinRevision: countSchema.optional(),
37
- // Advanced by every game creation and every game edit that brings the team in; absent until the
38
- // first. Only its changing matters: a team's deletion re-reads the team's games in the transaction
39
- // that deletes the team document, and a query does not lock against an insert — so a game created
40
- // for the team writes this document, which the deletion also writes, and the two conflict instead of
41
- // leaving a game naming a deleted team (RULE-STD-BACKEND-116).
21
+ // Only its changing matters: the write fence between game creation and the team's deletion
22
+ // (RULE-STD-BACKEND-116).
42
23
  scheduleRevision: countSchema.optional(),
43
24
  createdAt: epochMsSchema,
44
25
  updatedAt: epochMsSchema,
45
26
  });
46
- // `leagueTeamContacts/{teamId}` — how the league reaches the team. Admin read only: the team
47
- // document is public, so the phone lives here, never on it (RULE-STD-BACKEND-105). `leagueId` is what lists a
48
- // league's contacts in one query. Written with the team by team creation.
49
27
  export const LeagueTeamContactSchema = z.object({
50
28
  leagueId: leagueIdSchema,
51
- // The number as the contact callables kept it, held to the same declaration they parse with.
52
29
  contactPhone: textFieldSchema(CONTACT_PHONE_INPUT_FORMAT),
53
30
  updatedAt: epochMsSchema,
54
31
  });
@@ -1 +1 @@
1
- {"version":3,"file":"league-team.js","sourceRoot":"","sources":["../../src/doc-schemas/league-team.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,wEAAwE;AAExE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EACL,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,cAAc;IACxB,qDAAqD;IACrD,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,+FAA+F;IAC/F,kEAAkE;IAClE,eAAe,EAAE,YAAY;IAC7B,uEAAuE;IACvE,WAAW,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IAC7C,kGAAkG;IAClG,0FAA0F;IAC1F,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC,QAAQ,EAAE;IAC7E,gGAAgG;IAChG,uDAAuD;IACvD,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACzC,8FAA8F;IAC9F,mGAAmG;IACnG,iGAAiG;IACjG,8FAA8F;IAC9F,kBAAkB,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC1C,8FAA8F;IAC9F,6FAA6F;IAC7F,gGAAgG;IAChG,yFAAyF;IACzF,kGAAkG;IAClG,uCAAuC;IACvC,YAAY,EAAE,WAAW,CAAC,QAAQ,EAAE;IACpC,gGAAgG;IAChG,mGAAmG;IACnG,kGAAkG;IAClG,qGAAqG;IACrG,+DAA+D;IAC/D,gBAAgB,EAAE,WAAW,CAAC,QAAQ,EAAE;IACxC,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,6FAA6F;AAC7F,8GAA8G;AAC9G,0EAA0E;AAC1E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,QAAQ,EAAE,cAAc;IACxB,6FAA6F;IAC7F,YAAY,EAAE,eAAe,CAAC,0BAA0B,CAAC;IACzD,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC","sourcesContent":["// `leagueTeams/{teamId}` — one team in one league, with its derived season rollups. Who is on the\n// team, and who captains it, is `teamMemberships` — never a field here.\n\nimport { z } from 'zod';\nimport { CONTACT_PHONE_INPUT_FORMAT } from '../input-formats/input-formats.js';\nimport {\n countSchema,\n epochMsSchema,\n leagueIdSchema,\n teamIconSchema,\n teamTypeSchema,\n textFieldSchema,\n userIdSchema,\n} from './atoms.js';\nimport { PlayerSeasonStatsSchema, TeamSeasonStatsSchema } from './aggregate-stats.js';\nimport { GallerySummarySchema } from './gallery.js';\n\nexport const LeagueTeamSchema = z.object({\n name: z.string(),\n icon: teamIconSchema,\n leagueId: leagueIdSchema,\n // Present only in a Competitive/Recreational league.\n teamType: teamTypeSchema.optional(),\n // The account that created the team — the new captain, or the admin who created it for a ghost\n // captain. A creation record, never a membership or an authority.\n createdByUserId: userIdSchema,\n // The team's standings line, absent until its first game is finalized.\n seasonStats: TeamSeasonStatsSchema.optional(),\n // The league player stats: one row per person the team's games credited, keyed by userId (real or\n // ghost). The team's league, the team, and the key are the membership the row belongs to.\n playerSeasonStats: z.record(userIdSchema, PlayerSeasonStatsSchema).optional(),\n // The team's picture gallery summary — absent is an empty gallery. Only the picture core writes\n // it; the team callables and the copy action never do.\n pictures: GallerySummarySchema.optional(),\n // Advanced by every membership change on the team after its creation; absent until the first.\n // Only its changing matters: game creation and a game's team replacement read this document in the\n // transaction that seeds a roster from the team's memberships, so a membership change landing at\n // the same moment conflicts with them instead of missing the new game (RULE-STD-BACKEND-116).\n membershipRevision: countSchema.optional(),\n // Advanced by every invitation and join request a door creates for the team; absent until the\n // first. Only its changing matters: a pending invitation or request between one team and one\n // person is unique, and a membership on the team closes both, but a transaction does not lock a\n // query against an insert — so each creation writes this document, which every competing\n // creation and every membership door also writes, and two racers conflict instead of both passing\n // their checks (RULE-STD-BACKEND-116).\n joinRevision: countSchema.optional(),\n // Advanced by every game creation and every game edit that brings the team in; absent until the\n // first. Only its changing matters: a team's deletion re-reads the team's games in the transaction\n // that deletes the team document, and a query does not lock against an insert — so a game created\n // for the team writes this document, which the deletion also writes, and the two conflict instead of\n // leaving a game naming a deleted team (RULE-STD-BACKEND-116).\n scheduleRevision: countSchema.optional(),\n createdAt: epochMsSchema,\n updatedAt: epochMsSchema,\n});\nexport type LeagueTeam = z.infer<typeof LeagueTeamSchema>;\n\n// `leagueTeamContacts/{teamId}` — how the league reaches the team. Admin read only: the team\n// document is public, so the phone lives here, never on it (RULE-STD-BACKEND-105). `leagueId` is what lists a\n// league's contacts in one query. Written with the team by team creation.\nexport const LeagueTeamContactSchema = z.object({\n leagueId: leagueIdSchema,\n // The number as the contact callables kept it, held to the same declaration they parse with.\n contactPhone: textFieldSchema(CONTACT_PHONE_INPUT_FORMAT),\n updatedAt: epochMsSchema,\n});\nexport type LeagueTeamContact = z.infer<typeof LeagueTeamContactSchema>;\n"]}
1
+ {"version":3,"file":"league-team.js","sourceRoot":"","sources":["../../src/doc-schemas/league-team.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EACL,WAAW,EACX,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,eAAe,EAAE,YAAY;IAC7B,WAAW,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IAC7C,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC,QAAQ,EAAE;IAC7E,QAAQ,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACzC,2FAA2F;IAC3F,0BAA0B;IAC1B,kBAAkB,EAAE,WAAW,CAAC,QAAQ,EAAE;IAC1C,+FAA+F;IAC/F,2CAA2C;IAC3C,YAAY,EAAE,WAAW,CAAC,QAAQ,EAAE;IACpC,2FAA2F;IAC3F,0BAA0B;IAC1B,gBAAgB,EAAE,WAAW,CAAC,QAAQ,EAAE;IACxC,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,QAAQ,EAAE,cAAc;IACxB,YAAY,EAAE,eAAe,CAAC,0BAA0B,CAAC;IACzD,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport { CONTACT_PHONE_INPUT_FORMAT } from '../input-formats/input-formats.js';\nimport {\n countSchema,\n epochMsSchema,\n leagueIdSchema,\n teamIconSchema,\n teamTypeSchema,\n textFieldSchema,\n userIdSchema,\n} from './atoms.js';\nimport { PlayerSeasonStatsSchema, TeamSeasonStatsSchema } from './aggregate-stats.js';\nimport { GallerySummarySchema } from './gallery.js';\n\nexport const LeagueTeamSchema = z.object({\n name: z.string(),\n icon: teamIconSchema,\n leagueId: leagueIdSchema,\n teamType: teamTypeSchema.optional(),\n createdByUserId: userIdSchema,\n seasonStats: TeamSeasonStatsSchema.optional(),\n playerSeasonStats: z.record(userIdSchema, PlayerSeasonStatsSchema).optional(),\n pictures: GallerySummarySchema.optional(),\n // Only its changing matters: the write fence between membership changes and roster seeding\n // (RULE-STD-BACKEND-116).\n membershipRevision: countSchema.optional(),\n // Only its changing matters: the write fence between competing invitations, join requests, and\n // membership doors (RULE-STD-BACKEND-116).\n joinRevision: countSchema.optional(),\n // Only its changing matters: the write fence between game creation and the team's deletion\n // (RULE-STD-BACKEND-116).\n scheduleRevision: countSchema.optional(),\n createdAt: epochMsSchema,\n updatedAt: epochMsSchema,\n});\nexport type LeagueTeam = z.infer<typeof LeagueTeamSchema>;\n\nexport const LeagueTeamContactSchema = z.object({\n leagueId: leagueIdSchema,\n contactPhone: textFieldSchema(CONTACT_PHONE_INPUT_FORMAT),\n updatedAt: epochMsSchema,\n});\nexport type LeagueTeamContact = z.infer<typeof LeagueTeamContactSchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"membership-roster-sync.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/membership-roster-sync.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,gCAAgC;;;kBAG3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;iBAyCpC,CAAC;AACJ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"membership-roster-sync.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/membership-roster-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,eAAO,MAAM,gCAAgC;;;kBAG3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;iBAkCpC,CAAC;AACJ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -1,17 +1,7 @@
1
- // `membershipRosterSyncs/{teamMembershipId}` — one team membership's durable obligation to bring
2
- // its team's open game rosters in line with it (RULE-STD-QUALITY-104, RULE-STD-BACKEND-302).
3
- //
4
- // Every change to a membership — made, removed, or linked — advances `rosterRevision` in the same
5
- // transaction as the change, so a committed membership can never lose its roster work. The roster
6
- // core raises `reconciledRosterRevision` to the revision it finished; the obligation is outstanding
7
- // while it is lower. The document outlives a deleted membership, so a removal is still reconciled,
8
- // and it is keyed by the membership id, so no second id format exists (RULE-STD-ARCH-109). Backend-only.
9
1
  import { z } from 'zod';
10
2
  import { MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH } from '../constants/business.js';
11
3
  import { FAILED_ROSTER_SYNC_STATUS, RECONCILED_ROSTER_SYNC_STATUS } from '../types/unions.js';
12
4
  import { appliedRevisionSchema, countSchema, epochMsSchema, gameIdSchema, leagueIdSchema, membershipRosterSyncStatusSchema, revisionSchema, teamIdSchema, userIdSchema, } from './atoms.js';
13
- // Where a run that stopped part-way resumes: the last game it finished for this revision. A cursor
14
- // for an older revision is ignored, because a newer change re-reconciles every open game.
15
5
  export const MembershipRosterSyncCursorSchema = z.strictObject({
16
6
  rosterRevision: revisionSchema,
17
7
  afterGameId: gameIdSchema,
@@ -21,20 +11,13 @@ export const MembershipRosterSyncSchema = z
21
11
  leagueId: leagueIdSchema,
22
12
  teamId: teamIdSchema,
23
13
  userId: userIdSchema,
24
- // Advanced by every change to the membership; the first change writes 1.
25
14
  rosterRevision: revisionSchema,
26
- // The revision the roster core last finished; 0 before the first finish.
27
15
  reconciledRosterRevision: appliedRevisionSchema,
28
16
  syncStatus: membershipRosterSyncStatusSchema,
29
- // Runs of the worker at the current revision that ended in a failure.
30
17
  attemptCount: countSchema,
31
- // The earliest moment the worker takes the obligation again.
32
18
  nextAttemptAt: epochMsSchema,
33
19
  cursor: MembershipRosterSyncCursorSchema.optional(),
34
- // When its retries ran out: present exactly while the obligation is failed.
35
20
  failedAt: epochMsSchema.optional(),
36
- // The last failed run's message, kept while it retries and while it is failed; a finished run or
37
- // an admin's retry clears it.
38
21
  lastFailureMessage: z.string().max(MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH).optional(),
39
22
  updatedAt: epochMsSchema,
40
23
  })
@@ -1 +1 @@
1
- {"version":3,"file":"membership-roster-sync.js","sourceRoot":"","sources":["../../src/doc-schemas/membership-roster-sync.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,6FAA6F;AAC7F,EAAE;AACF,kGAAkG;AAClG,kGAAkG;AAClG,oGAAoG;AACpG,mGAAmG;AACnG,yGAAyG;AAEzG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sCAAsC,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,cAAc,EACd,gCAAgC,EAChC,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,mGAAmG;AACnG,0FAA0F;AAC1F,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,YAAY,CAAC;IAC7D,cAAc,EAAE,cAAc;IAC9B,WAAW,EAAE,YAAY;CAC1B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,yEAAyE;IACzE,cAAc,EAAE,cAAc;IAC9B,yEAAyE;IACzE,wBAAwB,EAAE,qBAAqB;IAC/C,UAAU,EAAE,gCAAgC;IAC5C,sEAAsE;IACtE,YAAY,EAAE,WAAW;IACzB,6DAA6D;IAC7D,aAAa,EAAE,aAAa;IAC5B,MAAM,EAAE,gCAAgC,CAAC,QAAQ,EAAE;IACnD,4EAA4E;IAC5E,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE;IAClC,iGAAiG;IACjG,8BAA8B;IAC9B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,QAAQ,EAAE;IACrF,SAAS,EAAE,aAAa;CACzB,CAAC;KACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,IAAI,IAAI,CAAC,cAAc,EAAE;IACtE,OAAO,EAAE,iEAAiE;IAC1E,IAAI,EAAE,CAAC,0BAA0B,CAAC;CACnC,CAAC;KACD,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,IAAI,CAAC,UAAU,KAAK,6BAA6B,CAAC;IACnD,CAAC,IAAI,CAAC,wBAAwB,KAAK,IAAI,CAAC,cAAc,CAAC,EACzD;IACE,OAAO,EAAE,mFAAmF;IAC5F,IAAI,EAAE,CAAC,YAAY,CAAC;CACrB,CACF;KACA,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,yBAAyB,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,EAC3F;IACE,OAAO,EAAE,8DAA8D;IACvE,IAAI,EAAE,CAAC,UAAU,CAAC;CACnB,CACF,CAAC","sourcesContent":["// `membershipRosterSyncs/{teamMembershipId}` — one team membership's durable obligation to bring\n// its team's open game rosters in line with it (RULE-STD-QUALITY-104, RULE-STD-BACKEND-302).\n//\n// Every change to a membership — made, removed, or linked — advances `rosterRevision` in the same\n// transaction as the change, so a committed membership can never lose its roster work. The roster\n// core raises `reconciledRosterRevision` to the revision it finished; the obligation is outstanding\n// while it is lower. The document outlives a deleted membership, so a removal is still reconciled,\n// and it is keyed by the membership id, so no second id format exists (RULE-STD-ARCH-109). Backend-only.\n\nimport { z } from 'zod';\nimport { MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH } from '../constants/business.js';\nimport { FAILED_ROSTER_SYNC_STATUS, RECONCILED_ROSTER_SYNC_STATUS } from '../types/unions.js';\nimport {\n appliedRevisionSchema,\n countSchema,\n epochMsSchema,\n gameIdSchema,\n leagueIdSchema,\n membershipRosterSyncStatusSchema,\n revisionSchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\n\n// Where a run that stopped part-way resumes: the last game it finished for this revision. A cursor\n// for an older revision is ignored, because a newer change re-reconciles every open game.\nexport const MembershipRosterSyncCursorSchema = z.strictObject({\n rosterRevision: revisionSchema,\n afterGameId: gameIdSchema,\n});\nexport type MembershipRosterSyncCursor = z.infer<typeof MembershipRosterSyncCursorSchema>;\n\nexport const MembershipRosterSyncSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n // Advanced by every change to the membership; the first change writes 1.\n rosterRevision: revisionSchema,\n // The revision the roster core last finished; 0 before the first finish.\n reconciledRosterRevision: appliedRevisionSchema,\n syncStatus: membershipRosterSyncStatusSchema,\n // Runs of the worker at the current revision that ended in a failure.\n attemptCount: countSchema,\n // The earliest moment the worker takes the obligation again.\n nextAttemptAt: epochMsSchema,\n cursor: MembershipRosterSyncCursorSchema.optional(),\n // When its retries ran out: present exactly while the obligation is failed.\n failedAt: epochMsSchema.optional(),\n // The last failed run's message, kept while it retries and while it is failed; a finished run or\n // an admin's retry clears it.\n lastFailureMessage: z.string().max(MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH).optional(),\n updatedAt: epochMsSchema,\n })\n .refine((sync) => sync.reconciledRosterRevision <= sync.rosterRevision, {\n message: 'A roster obligation cannot be reconciled past its own revision.',\n path: ['reconciledRosterRevision'],\n })\n .refine(\n (sync) =>\n (sync.syncStatus === RECONCILED_ROSTER_SYNC_STATUS) ===\n (sync.reconciledRosterRevision === sync.rosterRevision),\n {\n message: 'An obligation is reconciled exactly when its reconciled revision is its revision.',\n path: ['syncStatus'],\n },\n )\n .refine(\n (sync) => (sync.syncStatus === FAILED_ROSTER_SYNC_STATUS) === (sync.failedAt !== undefined),\n {\n message: 'An obligation carries `failedAt` exactly while it is failed.',\n path: ['failedAt'],\n },\n );\nexport type MembershipRosterSync = z.infer<typeof MembershipRosterSyncSchema>;\n"]}
1
+ {"version":3,"file":"membership-roster-sync.js","sourceRoot":"","sources":["../../src/doc-schemas/membership-roster-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,sCAAsC,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,cAAc,EACd,gCAAgC,EAChC,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,YAAY,CAAC;IAC7D,cAAc,EAAE,cAAc;IAC9B,WAAW,EAAE,YAAY;CAC1B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,cAAc,EAAE,cAAc;IAC9B,wBAAwB,EAAE,qBAAqB;IAC/C,UAAU,EAAE,gCAAgC;IAC5C,YAAY,EAAE,WAAW;IACzB,aAAa,EAAE,aAAa;IAC5B,MAAM,EAAE,gCAAgC,CAAC,QAAQ,EAAE;IACnD,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE;IAClC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,QAAQ,EAAE;IACrF,SAAS,EAAE,aAAa;CACzB,CAAC;KACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,IAAI,IAAI,CAAC,cAAc,EAAE;IACtE,OAAO,EAAE,iEAAiE;IAC1E,IAAI,EAAE,CAAC,0BAA0B,CAAC;CACnC,CAAC;KACD,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,IAAI,CAAC,UAAU,KAAK,6BAA6B,CAAC;IACnD,CAAC,IAAI,CAAC,wBAAwB,KAAK,IAAI,CAAC,cAAc,CAAC,EACzD;IACE,OAAO,EAAE,mFAAmF;IAC5F,IAAI,EAAE,CAAC,YAAY,CAAC;CACrB,CACF;KACA,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,yBAAyB,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,EAC3F;IACE,OAAO,EAAE,8DAA8D;IACvE,IAAI,EAAE,CAAC,UAAU,CAAC;CACnB,CACF,CAAC","sourcesContent":["import { z } from 'zod';\nimport { MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH } from '../constants/business.js';\nimport { FAILED_ROSTER_SYNC_STATUS, RECONCILED_ROSTER_SYNC_STATUS } from '../types/unions.js';\nimport {\n appliedRevisionSchema,\n countSchema,\n epochMsSchema,\n gameIdSchema,\n leagueIdSchema,\n membershipRosterSyncStatusSchema,\n revisionSchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\n\nexport const MembershipRosterSyncCursorSchema = z.strictObject({\n rosterRevision: revisionSchema,\n afterGameId: gameIdSchema,\n});\nexport type MembershipRosterSyncCursor = z.infer<typeof MembershipRosterSyncCursorSchema>;\n\nexport const MembershipRosterSyncSchema = z\n .object({\n leagueId: leagueIdSchema,\n teamId: teamIdSchema,\n userId: userIdSchema,\n rosterRevision: revisionSchema,\n reconciledRosterRevision: appliedRevisionSchema,\n syncStatus: membershipRosterSyncStatusSchema,\n attemptCount: countSchema,\n nextAttemptAt: epochMsSchema,\n cursor: MembershipRosterSyncCursorSchema.optional(),\n failedAt: epochMsSchema.optional(),\n lastFailureMessage: z.string().max(MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH).optional(),\n updatedAt: epochMsSchema,\n })\n .refine((sync) => sync.reconciledRosterRevision <= sync.rosterRevision, {\n message: 'A roster obligation cannot be reconciled past its own revision.',\n path: ['reconciledRosterRevision'],\n })\n .refine(\n (sync) =>\n (sync.syncStatus === RECONCILED_ROSTER_SYNC_STATUS) ===\n (sync.reconciledRosterRevision === sync.rosterRevision),\n {\n message: 'An obligation is reconciled exactly when its reconciled revision is its revision.',\n path: ['syncStatus'],\n },\n )\n .refine(\n (sync) => (sync.syncStatus === FAILED_ROSTER_SYNC_STATUS) === (sync.failedAt !== undefined),\n {\n message: 'An obligation carries `failedAt` exactly while it is failed.',\n path: ['failedAt'],\n },\n );\nexport type MembershipRosterSync = z.infer<typeof MembershipRosterSyncSchema>;\n"]}
@@ -89,15 +89,8 @@ export declare const migrationDestinationStateSchema: z.ZodEnum<{
89
89
  live: "live";
90
90
  preCutover: "preCutover";
91
91
  }>;
92
- /** One logical run of an action, minted by the admin's browser when the admin starts it. */
93
92
  export declare const migrationOperationIdSchema: z.ZodString;
94
- /** What the operator records as proof of a step the console cannot see done. */
95
93
  export declare const migrationEvidenceSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
96
- /**
97
- * One document an action reported: skipped by a copy, missing or mismatched in a verification, or
98
- * named by one of an action's own report lists (a merged pair, a created roster entry, a ghost's
99
- * disposition) — `category` names which.
100
- */
101
94
  export declare const MigrationFindingSchema: z.ZodObject<{
102
95
  category: z.ZodString;
103
96
  id: z.ZodString;
@@ -105,7 +98,6 @@ export declare const MigrationFindingSchema: z.ZodObject<{
105
98
  reason: z.ZodString;
106
99
  }, z.core.$strict>;
107
100
  export type MigrationFinding = z.infer<typeof MigrationFindingSchema>;
108
- /** A run's totals across its pages. A write action fills the first three, a verification the next three. */
109
101
  export declare const MigrationRunCountsSchema: z.ZodObject<{
110
102
  read: z.ZodNumber;
111
103
  written: z.ZodNumber;
@@ -151,7 +143,6 @@ export declare const MigrationRunRecordSchema: z.ZodObject<{
151
143
  stoppedReason: z.ZodOptional<z.ZodString>;
152
144
  }, z.core.$strict>;
153
145
  export type MigrationRunRecord = z.infer<typeof MigrationRunRecordSchema>;
154
- /** A product control's run, an operator checkpoint, or the cutover, as recorded. */
155
146
  export declare const MigrationStepRecordSchema: z.ZodObject<{
156
147
  recordedAt: z.ZodNumber;
157
148
  recordedByUserId: z.ZodString;
@@ -324,7 +315,6 @@ export declare const MigrationActionRunSchema: z.ZodObject<{
324
315
  }, z.core.$strict>>;
325
316
  }, z.core.$strict>;
326
317
  export type MigrationActionRun = z.infer<typeof MigrationActionRunSchema>;
327
- /** The one action holding the console, until its lease runs out. */
328
318
  export declare const MigrationConsoleLockSchema: z.ZodObject<{
329
319
  actionId: z.ZodEnum<{
330
320
  "copy.userProfiles": "copy.userProfiles";
@@ -1 +1 @@
1
- {"version":3,"file":"migration-console.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/migration-console.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAmC,CAAC;AACxE,eAAO,MAAM,+BAA+B;;;EAA2C,CAAC;AACxF,4FAA4F;AAC5F,eAAO,MAAM,0BAA0B,aAA0B,CAAC;AAClE,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,wDAAmD,CAAC;AAIxF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;kBAKjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,4GAA4G;AAC5G,eAAO,MAAM,wBAAwB;;;;;;;kBAOnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0BnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,oFAAoF;AACpF,eAAO,MAAM,yBAAyB;;;;;kBAOpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAOnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,oEAAoE;AACpE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"migration-console.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/migration-console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAmC,CAAC;AACxE,eAAO,MAAM,+BAA+B;;;EAA2C,CAAC;AACxF,eAAO,MAAM,0BAA0B,aAA0B,CAAC;AAClE,eAAO,MAAM,uBAAuB,wDAAmD,CAAC;AAIxF,eAAO,MAAM,sBAAsB;;;;;kBAKjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,wBAAwB;;;;;;;kBAOnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkBnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,yBAAyB;;;;;kBAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAKnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -1,9 +1,3 @@
1
- // The migration console's recorded state — admin read, written only by the console's callables.
2
- //
3
- // `_serverData/migrationConsole` holds the cutover marker and the lock: one action runs at a time, and
4
- // whether the destinations are still the migration's is recorded here, never taken from the
5
- // operator. `migrationActionRuns/{actionId}` holds each step's latest real run — the one its
6
- // dependents read — its latest preview, and, for a recorded step, what was recorded.
7
1
  import { z } from 'zod';
8
2
  import { MIGRATION_EVIDENCE_INPUT_FORMAT } from '../input-formats/input-formats.js';
9
3
  import { MIGRATION_ACTION_ID_KEYS } from '../migration-console/action-ids.js';
@@ -11,23 +5,15 @@ import { MAX_MIGRATION_FINDING_TEXT_LENGTH, MAX_MIGRATION_RUN_FINDINGS, MIGRATIO
11
5
  import { countSchema, documentIdSegmentSchema, epochMsSchema, repairReasonSchema, statsOperationIdSchema, textFieldSchema, userIdSchema, } from './atoms.js';
12
6
  export const migrationActionIdSchema = z.enum(MIGRATION_ACTION_ID_KEYS);
13
7
  export const migrationDestinationStateSchema = z.enum(MIGRATION_DESTINATION_STATE_KEYS);
14
- /** One logical run of an action, minted by the admin's browser when the admin starts it. */
15
8
  export const migrationOperationIdSchema = documentIdSegmentSchema;
16
- /** What the operator records as proof of a step the console cannot see done. */
17
9
  export const migrationEvidenceSchema = textFieldSchema(MIGRATION_EVIDENCE_INPUT_FORMAT);
18
10
  const findingText = z.string().max(MAX_MIGRATION_FINDING_TEXT_LENGTH);
19
- /**
20
- * One document an action reported: skipped by a copy, missing or mismatched in a verification, or
21
- * named by one of an action's own report lists (a merged pair, a created roster entry, a ghost's
22
- * disposition) — `category` names which.
23
- */
24
11
  export const MigrationFindingSchema = z.strictObject({
25
12
  category: z.string().min(1).max(64),
26
13
  id: findingText,
27
14
  field: findingText,
28
15
  reason: findingText,
29
16
  });
30
- /** A run's totals across its pages. A write action fills the first three, a verification the next three. */
31
17
  export const MigrationRunCountsSchema = z.strictObject({
32
18
  read: countSchema,
33
19
  written: countSchema,
@@ -43,53 +29,35 @@ export const MigrationRunRecordSchema = z.strictObject({
43
29
  startedByUserId: userIdSchema,
44
30
  startedAt: epochMsSchema,
45
31
  updatedAt: epochMsSchema,
46
- // Set with `complete`: the moment the run reached its end.
47
32
  completedAt: epochMsSchema.optional(),
48
33
  status: z.enum(MIGRATION_RUN_STATUS_KEYS),
49
34
  pages: countSchema,
50
- // The resume key of the next page, or null once the run reached its end.
51
35
  nextResumeAfter: z.string().min(1).nullable(),
52
36
  counts: MigrationRunCountsSchema,
53
- // An action's own counters beyond the shared ones — merged pairs, corrections by field, kept
54
- // ghosts by disposition — summed across pages.
55
37
  details: z.record(z.string().min(1), countSchema),
56
38
  findings: z.array(MigrationFindingSchema).max(MAX_MIGRATION_RUN_FINDINGS),
57
- // Findings met past the kept ones; each page's answer carried them in full.
58
39
  findingsNotKept: countSchema,
59
- // A verification run declared, at its start, that its source is empty.
60
40
  expectEmptySource: z.boolean(),
61
- // A `verify.v1Pictures` run acknowledged, at its start, the sources it cannot examine.
62
41
  acknowledgeUnexaminedSources: z.boolean().optional(),
63
- // Why a stopped run stopped: the refusal its core gave.
64
42
  stoppedReason: findingText.optional(),
65
43
  });
66
- /** A product control's run, an operator checkpoint, or the cutover, as recorded. */
67
44
  export const MigrationStepRecordSchema = z.strictObject({
68
45
  recordedAt: epochMsSchema,
69
46
  recordedByUserId: userIdSchema,
70
- // A product control's runs, whose evidence the console checked.
71
47
  operationIds: z.array(statsOperationIdSchema).optional(),
72
- // An operator checkpoint's evidence, or a recorded step's reason.
73
48
  evidence: migrationEvidenceSchema,
74
49
  });
75
50
  export const MigrationActionRunSchema = z.strictObject({
76
51
  actionId: migrationActionIdSchema,
77
- // The latest real run: what every dependent and every gate reads.
78
52
  run: MigrationRunRecordSchema.optional(),
79
- // The latest dry run, kept apart so a preview never stands in for a run.
80
53
  preview: MigrationRunRecordSchema.optional(),
81
54
  recorded: MigrationStepRecordSchema.optional(),
82
55
  });
83
- /** The one action holding the console, until its lease runs out. */
84
56
  export const MigrationConsoleLockSchema = z.strictObject({
85
57
  actionId: migrationActionIdSchema,
86
58
  operationId: migrationOperationIdSchema,
87
59
  heldByUserId: userIdSchema,
88
60
  expiresAt: epochMsSchema,
89
- // Present while one page of the run is in flight: the moment its claim was stamped, and that
90
- // page's fencing token. Only the page holding this exact token records its result or releases the
91
- // lock; any other page, the same run's included, is refused while it stands. A lock stored
92
- // without one has no page in flight.
93
61
  pageClaimedAt: epochMsSchema.optional(),
94
62
  });
95
63
  export const MigrationConsoleSchema = z.strictObject({
@@ -1 +1 @@
1
- {"version":3,"file":"migration-console.js","sourceRoot":"","sources":["../../src/doc-schemas/migration-console.ts"],"names":[],"mappings":"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","sourcesContent":["// The migration console's recorded state — admin read, written only by the console's callables.\n//\n// `_serverData/migrationConsole` holds the cutover marker and the lock: one action runs at a time, and\n// whether the destinations are still the migration's is recorded here, never taken from the\n// operator. `migrationActionRuns/{actionId}` holds each step's latest real run — the one its\n// dependents read — its latest preview, and, for a recorded step, what was recorded.\n\nimport { z } from 'zod';\nimport { MIGRATION_EVIDENCE_INPUT_FORMAT } from '../input-formats/input-formats.js';\nimport { MIGRATION_ACTION_ID_KEYS } from '../migration-console/action-ids.js';\nimport {\n MAX_MIGRATION_FINDING_TEXT_LENGTH,\n MAX_MIGRATION_RUN_FINDINGS,\n MIGRATION_DESTINATION_STATE_KEYS,\n MIGRATION_RUN_STATUS_KEYS,\n} from '../migration-console/run-state.js';\nimport {\n countSchema,\n documentIdSegmentSchema,\n epochMsSchema,\n repairReasonSchema,\n statsOperationIdSchema,\n textFieldSchema,\n userIdSchema,\n} from './atoms.js';\n\nexport const migrationActionIdSchema = z.enum(MIGRATION_ACTION_ID_KEYS);\nexport const migrationDestinationStateSchema = z.enum(MIGRATION_DESTINATION_STATE_KEYS);\n/** One logical run of an action, minted by the admin's browser when the admin starts it. */\nexport const migrationOperationIdSchema = documentIdSegmentSchema;\n/** What the operator records as proof of a step the console cannot see done. */\nexport const migrationEvidenceSchema = textFieldSchema(MIGRATION_EVIDENCE_INPUT_FORMAT);\n\nconst findingText = z.string().max(MAX_MIGRATION_FINDING_TEXT_LENGTH);\n\n/**\n * One document an action reported: skipped by a copy, missing or mismatched in a verification, or\n * named by one of an action's own report lists (a merged pair, a created roster entry, a ghost's\n * disposition) — `category` names which.\n */\nexport const MigrationFindingSchema = z.strictObject({\n category: z.string().min(1).max(64),\n id: findingText,\n field: findingText,\n reason: findingText,\n});\nexport type MigrationFinding = z.infer<typeof MigrationFindingSchema>;\n\n/** A run's totals across its pages. A write action fills the first three, a verification the next three. */\nexport const MigrationRunCountsSchema = z.strictObject({\n read: countSchema,\n written: countSchema,\n skipped: countSchema,\n checked: countSchema,\n missing: countSchema,\n mismatched: countSchema,\n});\nexport type MigrationRunCounts = z.infer<typeof MigrationRunCountsSchema>;\n\nexport const MigrationRunRecordSchema = z.strictObject({\n operationId: migrationOperationIdSchema,\n dryRun: z.boolean(),\n reason: repairReasonSchema,\n startedByUserId: userIdSchema,\n startedAt: epochMsSchema,\n updatedAt: epochMsSchema,\n // Set with `complete`: the moment the run reached its end.\n completedAt: epochMsSchema.optional(),\n status: z.enum(MIGRATION_RUN_STATUS_KEYS),\n pages: countSchema,\n // The resume key of the next page, or null once the run reached its end.\n nextResumeAfter: z.string().min(1).nullable(),\n counts: MigrationRunCountsSchema,\n // An action's own counters beyond the shared ones — merged pairs, corrections by field, kept\n // ghosts by disposition — summed across pages.\n details: z.record(z.string().min(1), countSchema),\n findings: z.array(MigrationFindingSchema).max(MAX_MIGRATION_RUN_FINDINGS),\n // Findings met past the kept ones; each page's answer carried them in full.\n findingsNotKept: countSchema,\n // A verification run declared, at its start, that its source is empty.\n expectEmptySource: z.boolean(),\n // A `verify.v1Pictures` run acknowledged, at its start, the sources it cannot examine.\n acknowledgeUnexaminedSources: z.boolean().optional(),\n // Why a stopped run stopped: the refusal its core gave.\n stoppedReason: findingText.optional(),\n});\nexport type MigrationRunRecord = z.infer<typeof MigrationRunRecordSchema>;\n\n/** A product control's run, an operator checkpoint, or the cutover, as recorded. */\nexport const MigrationStepRecordSchema = z.strictObject({\n recordedAt: epochMsSchema,\n recordedByUserId: userIdSchema,\n // A product control's runs, whose evidence the console checked.\n operationIds: z.array(statsOperationIdSchema).optional(),\n // An operator checkpoint's evidence, or a recorded step's reason.\n evidence: migrationEvidenceSchema,\n});\nexport type MigrationStepRecord = z.infer<typeof MigrationStepRecordSchema>;\n\nexport const MigrationActionRunSchema = z.strictObject({\n actionId: migrationActionIdSchema,\n // The latest real run: what every dependent and every gate reads.\n run: MigrationRunRecordSchema.optional(),\n // The latest dry run, kept apart so a preview never stands in for a run.\n preview: MigrationRunRecordSchema.optional(),\n recorded: MigrationStepRecordSchema.optional(),\n});\nexport type MigrationActionRun = z.infer<typeof MigrationActionRunSchema>;\n\n/** The one action holding the console, until its lease runs out. */\nexport const MigrationConsoleLockSchema = z.strictObject({\n actionId: migrationActionIdSchema,\n operationId: migrationOperationIdSchema,\n heldByUserId: userIdSchema,\n expiresAt: epochMsSchema,\n // Present while one page of the run is in flight: the moment its claim was stamped, and that\n // page's fencing token. Only the page holding this exact token records its result or releases the\n // lock; any other page, the same run's included, is refused while it stands. A lock stored\n // without one has no page in flight.\n pageClaimedAt: epochMsSchema.optional(),\n});\nexport type MigrationConsoleLock = z.infer<typeof MigrationConsoleLockSchema>;\n\nexport const MigrationConsoleSchema = z.strictObject({\n destinationState: migrationDestinationStateSchema,\n cutoverRecordedAt: epochMsSchema.optional(),\n cutoverRecordedByUserId: userIdSchema.optional(),\n lock: MigrationConsoleLockSchema.nullable(),\n updatedAt: epochMsSchema,\n});\nexport type MigrationConsole = z.infer<typeof MigrationConsoleSchema>;\n"]}
1
+ {"version":3,"file":"migration-console.js","sourceRoot":"","sources":["../../src/doc-schemas/migration-console.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { MIGRATION_EVIDENCE_INPUT_FORMAT } from '../input-formats/input-formats.js';\nimport { MIGRATION_ACTION_ID_KEYS } from '../migration-console/action-ids.js';\nimport {\n MAX_MIGRATION_FINDING_TEXT_LENGTH,\n MAX_MIGRATION_RUN_FINDINGS,\n MIGRATION_DESTINATION_STATE_KEYS,\n MIGRATION_RUN_STATUS_KEYS,\n} from '../migration-console/run-state.js';\nimport {\n countSchema,\n documentIdSegmentSchema,\n epochMsSchema,\n repairReasonSchema,\n statsOperationIdSchema,\n textFieldSchema,\n userIdSchema,\n} from './atoms.js';\n\nexport const migrationActionIdSchema = z.enum(MIGRATION_ACTION_ID_KEYS);\nexport const migrationDestinationStateSchema = z.enum(MIGRATION_DESTINATION_STATE_KEYS);\nexport const migrationOperationIdSchema = documentIdSegmentSchema;\nexport const migrationEvidenceSchema = textFieldSchema(MIGRATION_EVIDENCE_INPUT_FORMAT);\n\nconst findingText = z.string().max(MAX_MIGRATION_FINDING_TEXT_LENGTH);\n\nexport const MigrationFindingSchema = z.strictObject({\n category: z.string().min(1).max(64),\n id: findingText,\n field: findingText,\n reason: findingText,\n});\nexport type MigrationFinding = z.infer<typeof MigrationFindingSchema>;\n\nexport const MigrationRunCountsSchema = z.strictObject({\n read: countSchema,\n written: countSchema,\n skipped: countSchema,\n checked: countSchema,\n missing: countSchema,\n mismatched: countSchema,\n});\nexport type MigrationRunCounts = z.infer<typeof MigrationRunCountsSchema>;\n\nexport const MigrationRunRecordSchema = z.strictObject({\n operationId: migrationOperationIdSchema,\n dryRun: z.boolean(),\n reason: repairReasonSchema,\n startedByUserId: userIdSchema,\n startedAt: epochMsSchema,\n updatedAt: epochMsSchema,\n completedAt: epochMsSchema.optional(),\n status: z.enum(MIGRATION_RUN_STATUS_KEYS),\n pages: countSchema,\n nextResumeAfter: z.string().min(1).nullable(),\n counts: MigrationRunCountsSchema,\n details: z.record(z.string().min(1), countSchema),\n findings: z.array(MigrationFindingSchema).max(MAX_MIGRATION_RUN_FINDINGS),\n findingsNotKept: countSchema,\n expectEmptySource: z.boolean(),\n acknowledgeUnexaminedSources: z.boolean().optional(),\n stoppedReason: findingText.optional(),\n});\nexport type MigrationRunRecord = z.infer<typeof MigrationRunRecordSchema>;\n\nexport const MigrationStepRecordSchema = z.strictObject({\n recordedAt: epochMsSchema,\n recordedByUserId: userIdSchema,\n operationIds: z.array(statsOperationIdSchema).optional(),\n evidence: migrationEvidenceSchema,\n});\nexport type MigrationStepRecord = z.infer<typeof MigrationStepRecordSchema>;\n\nexport const MigrationActionRunSchema = z.strictObject({\n actionId: migrationActionIdSchema,\n run: MigrationRunRecordSchema.optional(),\n preview: MigrationRunRecordSchema.optional(),\n recorded: MigrationStepRecordSchema.optional(),\n});\nexport type MigrationActionRun = z.infer<typeof MigrationActionRunSchema>;\n\nexport const MigrationConsoleLockSchema = z.strictObject({\n actionId: migrationActionIdSchema,\n operationId: migrationOperationIdSchema,\n heldByUserId: userIdSchema,\n expiresAt: epochMsSchema,\n pageClaimedAt: epochMsSchema.optional(),\n});\nexport type MigrationConsoleLock = z.infer<typeof MigrationConsoleLockSchema>;\n\nexport const MigrationConsoleSchema = z.strictObject({\n destinationState: migrationDestinationStateSchema,\n cutoverRecordedAt: epochMsSchema.optional(),\n cutoverRecordedByUserId: userIdSchema.optional(),\n lock: MigrationConsoleLockSchema.nullable(),\n updatedAt: epochMsSchema,\n});\nexport type MigrationConsole = z.infer<typeof MigrationConsoleSchema>;\n"]}