@ttt-productions/q-core 0.1.1 → 0.1.3
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.
- package/dist/constants/business.d.ts +12 -0
- package/dist/constants/business.d.ts.map +1 -1
- package/dist/constants/business.js +24 -0
- package/dist/constants/business.js.map +1 -1
- package/dist/constants/media.d.ts +1 -0
- package/dist/constants/media.d.ts.map +1 -1
- package/dist/constants/media.js +5 -0
- package/dist/constants/media.js.map +1 -1
- package/dist/doc-schemas/admin-notifications.d.ts +1 -0
- package/dist/doc-schemas/admin-notifications.d.ts.map +1 -1
- package/dist/doc-schemas/admin-notifications.js +4 -0
- package/dist/doc-schemas/admin-notifications.js.map +1 -1
- package/dist/doc-schemas/atoms.d.ts +2 -0
- package/dist/doc-schemas/atoms.d.ts.map +1 -1
- package/dist/doc-schemas/audit-event.d.ts +2 -0
- package/dist/doc-schemas/audit-event.d.ts.map +1 -1
- package/dist/doc-schemas/gallery.d.ts +1 -0
- package/dist/doc-schemas/gallery.d.ts.map +1 -1
- package/dist/doc-schemas/gallery.js +3 -0
- package/dist/doc-schemas/gallery.js.map +1 -1
- package/dist/doc-schemas/migration-console.d.ts +2 -0
- package/dist/doc-schemas/migration-console.d.ts.map +1 -1
- package/dist/doc-schemas/migration-console.js +5 -0
- package/dist/doc-schemas/migration-console.js.map +1 -1
- package/dist/doc-schemas/pending-media.d.ts +1 -0
- package/dist/doc-schemas/pending-media.d.ts.map +1 -1
- package/dist/doc-schemas/pending-media.js +8 -0
- package/dist/doc-schemas/pending-media.js.map +1 -1
- package/dist/doc-schemas/registry.d.ts +12 -0
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/doc-schemas/stats-operation.d.ts.map +1 -1
- package/dist/doc-schemas/stats-operation.js +6 -11
- package/dist/doc-schemas/stats-operation.js.map +1 -1
- package/dist/doc-schemas/system.d.ts +7 -0
- package/dist/doc-schemas/system.d.ts.map +1 -1
- package/dist/doc-schemas/system.js +4 -1
- package/dist/doc-schemas/system.js.map +1 -1
- package/dist/doc-schemas/user-profile.d.ts +1 -0
- package/dist/doc-schemas/user-profile.d.ts.map +1 -1
- package/dist/doc-schemas/user-profile.js +5 -0
- package/dist/doc-schemas/user-profile.js.map +1 -1
- package/dist/doc-schemas/waiver-template.d.ts +1 -0
- package/dist/doc-schemas/waiver-template.d.ts.map +1 -1
- package/dist/doc-schemas/waiver-template.js +10 -1
- package/dist/doc-schemas/waiver-template.js.map +1 -1
- package/dist/doc-schemas/waivers-and-hardware.d.ts +1 -0
- package/dist/doc-schemas/waivers-and-hardware.d.ts.map +1 -1
- package/dist/doc-schemas/waivers-and-hardware.js +17 -9
- package/dist/doc-schemas/waivers-and-hardware.js.map +1 -1
- package/dist/ids/minted-ids.d.ts +1 -0
- package/dist/ids/minted-ids.d.ts.map +1 -1
- package/dist/ids/minted-ids.js +6 -0
- package/dist/ids/minted-ids.js.map +1 -1
- package/dist/input-formats/index.d.ts +2 -2
- package/dist/input-formats/index.d.ts.map +1 -1
- package/dist/input-formats/index.js +2 -2
- package/dist/input-formats/index.js.map +1 -1
- package/dist/migration-console/manifest.d.ts.map +1 -1
- package/dist/migration-console/manifest.js +11 -10
- package/dist/migration-console/manifest.js.map +1 -1
- package/dist/notifications/archive-all.d.ts +2 -0
- package/dist/notifications/archive-all.d.ts.map +1 -0
- package/dist/notifications/archive-all.js +6 -0
- package/dist/notifications/archive-all.js.map +1 -0
- package/dist/notifications/index.d.ts +1 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +1 -0
- package/dist/notifications/index.js.map +1 -1
- package/dist/schemas/admin-notifications.d.ts +1 -0
- package/dist/schemas/admin-notifications.d.ts.map +1 -1
- package/dist/schemas/admin-notifications.js +4 -2
- package/dist/schemas/admin-notifications.js.map +1 -1
- package/dist/schemas/app-config.d.ts +2 -2
- package/dist/schemas/app-config.d.ts.map +1 -1
- package/dist/schemas/app-config.js +9 -5
- package/dist/schemas/app-config.js.map +1 -1
- package/dist/schemas/awards.d.ts +16 -4
- package/dist/schemas/awards.d.ts.map +1 -1
- package/dist/schemas/awards.js +10 -6
- package/dist/schemas/awards.js.map +1 -1
- package/dist/schemas/game-locations.d.ts +4 -4
- package/dist/schemas/game-locations.d.ts.map +1 -1
- package/dist/schemas/game-locations.js +11 -3
- package/dist/schemas/game-locations.js.map +1 -1
- package/dist/schemas/migration-console.d.ts +1 -0
- package/dist/schemas/migration-console.d.ts.map +1 -1
- package/dist/schemas/pictures.d.ts +3 -0
- package/dist/schemas/pictures.d.ts.map +1 -1
- package/dist/schemas/stats.d.ts +2 -0
- package/dist/schemas/stats.d.ts.map +1 -1
- package/dist/schemas/teams.d.ts +3 -2
- package/dist/schemas/teams.d.ts.map +1 -1
- package/dist/schemas/teams.js +22 -11
- package/dist/schemas/teams.js.map +1 -1
- package/dist/schemas/users.d.ts +7 -3
- package/dist/schemas/users.d.ts.map +1 -1
- package/dist/schemas/users.js +10 -3
- package/dist/schemas/users.js.map +1 -1
- package/dist/schemas/waiver-templates.d.ts +1 -0
- package/dist/schemas/waiver-templates.d.ts.map +1 -1
- package/dist/schemas/waiver-templates.js +4 -1
- package/dist/schemas/waiver-templates.js.map +1 -1
- package/dist/sports/index.d.ts +1 -0
- package/dist/sports/index.d.ts.map +1 -1
- package/dist/sports/index.js +1 -0
- package/dist/sports/index.js.map +1 -1
- package/dist/sports/ledger-continuity.d.ts +13 -0
- package/dist/sports/ledger-continuity.d.ts.map +1 -0
- package/dist/sports/ledger-continuity.js +19 -0
- package/dist/sports/ledger-continuity.js.map +1 -0
- package/dist/types/audit.d.ts +1 -1
- package/dist/types/audit.d.ts.map +1 -1
- package/dist/types/audit.js +5 -2
- package/dist/types/audit.js.map +1 -1
- package/dist/types/unions.d.ts +4 -2
- package/dist/types/unions.d.ts.map +1 -1
- package/dist/types/unions.js +6 -0
- package/dist/types/unions.js.map +1 -1
- package/dist/upload-variables/index.d.ts +3 -0
- package/dist/upload-variables/index.d.ts.map +1 -0
- package/dist/upload-variables/index.js +3 -0
- package/dist/upload-variables/index.js.map +1 -0
- package/dist/upload-variables/on-progress.d.ts +4 -0
- package/dist/upload-variables/on-progress.d.ts.map +1 -0
- package/dist/upload-variables/on-progress.js +10 -0
- package/dist/upload-variables/on-progress.js.map +1 -0
- package/dist/upload-variables/picture-upload-variables.d.ts +32 -0
- package/dist/upload-variables/picture-upload-variables.d.ts.map +1 -0
- package/dist/upload-variables/picture-upload-variables.js +21 -0
- package/dist/upload-variables/picture-upload-variables.js.map +1 -0
- package/dist/utils/app-config.d.ts +17 -3
- package/dist/utils/app-config.d.ts.map +1 -1
- package/dist/utils/app-config.js +21 -14
- package/dist/utils/app-config.js.map +1 -1
- package/package.json +6 -2
|
@@ -34,6 +34,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
34
34
|
readonly 'userProfiles/{userId}/privateData/{privateDataId}': z.ZodObject<{
|
|
35
35
|
email: z.ZodString;
|
|
36
36
|
registrationStartedAt: z.ZodOptional<z.ZodNumber>;
|
|
37
|
+
orphanDeletionClaimedAt: z.ZodOptional<z.ZodNumber>;
|
|
37
38
|
defaultContactPhone: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
38
39
|
theme: z.ZodOptional<z.ZodEnum<{
|
|
39
40
|
light: "light";
|
|
@@ -1165,6 +1166,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
1165
1166
|
version: z.ZodNumber;
|
|
1166
1167
|
createdAt: z.ZodNumber;
|
|
1167
1168
|
updatedAt: z.ZodNumber;
|
|
1169
|
+
retired: z.ZodBoolean;
|
|
1168
1170
|
retiredAt: z.ZodOptional<z.ZodNumber>;
|
|
1169
1171
|
lastChosenAt: z.ZodOptional<z.ZodNumber>;
|
|
1170
1172
|
}, z.core.$strip>;
|
|
@@ -1196,6 +1198,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
1196
1198
|
coCaptain: "coCaptain";
|
|
1197
1199
|
}>>;
|
|
1198
1200
|
subjectDisplayNameSnapshot: z.ZodOptional<z.ZodString>;
|
|
1201
|
+
witnessDisplayNameSnapshot: z.ZodOptional<z.ZodString>;
|
|
1199
1202
|
}, z.core.$strip>;
|
|
1200
1203
|
readonly 'hardwareLoanContracts/{contractId}': z.ZodObject<{
|
|
1201
1204
|
refereeUserId: z.ZodString;
|
|
@@ -1246,8 +1249,10 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
1246
1249
|
complete: z.ZodBoolean;
|
|
1247
1250
|
discrepancies: z.ZodArray<z.ZodObject<{
|
|
1248
1251
|
kind: z.ZodEnum<{
|
|
1252
|
+
gameUnreadable: "gameUnreadable";
|
|
1249
1253
|
invalidEvent: "invalidEvent";
|
|
1250
1254
|
eventSequenceMismatch: "eventSequenceMismatch";
|
|
1255
|
+
eventSequenceGap: "eventSequenceGap";
|
|
1251
1256
|
rollupMismatch: "rollupMismatch";
|
|
1252
1257
|
scoreMirrorMismatch: "scoreMirrorMismatch";
|
|
1253
1258
|
unrosteredStatLine: "unrosteredStatLine";
|
|
@@ -1269,8 +1274,10 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
1269
1274
|
actual: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString, z.ZodArray<z.ZodNullable<z.ZodNumber>>, z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodNull]>>;
|
|
1270
1275
|
}, z.core.$strict>>;
|
|
1271
1276
|
discrepancyCounts: z.ZodRecord<z.ZodEnum<{
|
|
1277
|
+
gameUnreadable: "gameUnreadable";
|
|
1272
1278
|
invalidEvent: "invalidEvent";
|
|
1273
1279
|
eventSequenceMismatch: "eventSequenceMismatch";
|
|
1280
|
+
eventSequenceGap: "eventSequenceGap";
|
|
1274
1281
|
rollupMismatch: "rollupMismatch";
|
|
1275
1282
|
scoreMirrorMismatch: "scoreMirrorMismatch";
|
|
1276
1283
|
unrosteredStatLine: "unrosteredStatLine";
|
|
@@ -1526,6 +1533,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
1526
1533
|
}>;
|
|
1527
1534
|
ownerId: z.ZodString;
|
|
1528
1535
|
position: z.ZodString;
|
|
1536
|
+
sourceIndex: z.ZodOptional<z.ZodNumber>;
|
|
1529
1537
|
createdAt: z.ZodNumber;
|
|
1530
1538
|
}, z.core.$strip>;
|
|
1531
1539
|
readonly 'pendingMedia/{pendingMediaId}': z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -2574,6 +2582,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
2574
2582
|
"adminNotification.archiveAllRequested": "adminNotification.archiveAllRequested";
|
|
2575
2583
|
"system.manualIntervention": "system.manualIntervention";
|
|
2576
2584
|
"migrationAction.pageRun": "migrationAction.pageRun";
|
|
2585
|
+
"migrationAction.writesCommitted": "migrationAction.writesCommitted";
|
|
2577
2586
|
"migrationAction.controlRecorded": "migrationAction.controlRecorded";
|
|
2578
2587
|
"migrationAction.checkpointRecorded": "migrationAction.checkpointRecorded";
|
|
2579
2588
|
"migrationConsole.cutoverRecorded": "migrationConsole.cutoverRecorded";
|
|
@@ -2718,6 +2727,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
2718
2727
|
}>;
|
|
2719
2728
|
revision: z.ZodNumber;
|
|
2720
2729
|
archived: z.ZodNumber;
|
|
2730
|
+
notArchived: z.ZodOptional<z.ZodNumber>;
|
|
2721
2731
|
error: z.ZodNullable<z.ZodString>;
|
|
2722
2732
|
attemptCount: z.ZodNumber;
|
|
2723
2733
|
nextAttemptAt: z.ZodNumber;
|
|
@@ -2747,6 +2757,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
2747
2757
|
}, z.core.$strip>;
|
|
2748
2758
|
readonly '_appConfig/statsBeacon': z.ZodObject<{
|
|
2749
2759
|
updatedAt: z.ZodNumber;
|
|
2760
|
+
changeId: z.ZodOptional<z.ZodString>;
|
|
2750
2761
|
action: z.ZodEnum<{
|
|
2751
2762
|
finalize: "finalize";
|
|
2752
2763
|
reopen: "reopen";
|
|
@@ -2860,6 +2871,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
2860
2871
|
operationId: z.ZodString;
|
|
2861
2872
|
heldByUserId: z.ZodString;
|
|
2862
2873
|
expiresAt: z.ZodNumber;
|
|
2874
|
+
pageClaimedAt: z.ZodOptional<z.ZodNumber>;
|
|
2863
2875
|
}, z.core.$strict>>;
|
|
2864
2876
|
updatedAt: z.ZodNumber;
|
|
2865
2877
|
}, z.core.$strict>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4C7B,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4C7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAIvE,eAAO,MAAM,wBAAwB;;;;;;;;;;;CAWiC,CAAC;AAGvE,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAO,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats-operation.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/stats-operation.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,0BAA0B;;;;kBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAsB9E,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;kBAK5C,CAAC;AAEH,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;kBAK9C,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;kBAK3C,CAAC;AAGH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;kBAMzC,CAAC;AAEH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;kBAK7C,CAAC;AAEH,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;kBAKhD,CAAC;AAEH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;kBAK/C,CAAC;AAKH,eAAO,MAAM,+BAA+B;;;;kBAI1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAKxF,eAAO,MAAM,qBAAqB;;;;kBAIhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAMpE,eAAO,MAAM,4BAA4B;;;;;kBAKvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAMlF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"stats-operation.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/stats-operation.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB,eAAO,MAAM,0BAA0B;;;;kBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAsB9E,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;kBAK5C,CAAC;AAEH,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;kBAK9C,CAAC;AAEH,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;kBAK3C,CAAC;AAGH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;kBAMzC,CAAC;AAEH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;kBAK7C,CAAC;AAEH,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;kBAKhD,CAAC;AAEH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;kBAK/C,CAAC;AAKH,eAAO,MAAM,+BAA+B;;;;kBAI1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAKxF,eAAO,MAAM,qBAAqB;;;;kBAIhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAMpE,eAAO,MAAM,4BAA4B;;;;;kBAKvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAMlF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkCxC,CAAC;AACL,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAIxF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;kBAItC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAU/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -108,9 +108,9 @@ export const StatsDestinationChangeSchema = z.strictObject({
|
|
|
108
108
|
after: z.record(z.string(), z.number()).nullable(),
|
|
109
109
|
});
|
|
110
110
|
// The ghost's one operation records the account a link chose, or the removal, so a call naming a
|
|
111
|
-
// different account — or a removal against a link — is refused, and the same call resumes.
|
|
112
|
-
//
|
|
113
|
-
//
|
|
111
|
+
// different account — or a removal against a link — is refused, and the same call resumes. Neither
|
|
112
|
+
// takes a reason: a link is chosen and confirmed, and its audit event records who linked which ghost
|
|
113
|
+
// to whom and what moved (BACKEND-212).
|
|
114
114
|
export const GhostPlayerStatsOperationSchema = z
|
|
115
115
|
.strictObject({
|
|
116
116
|
...operationBase,
|
|
@@ -128,7 +128,9 @@ export const GhostPlayerStatsOperationSchema = z
|
|
|
128
128
|
ghostUserId: userIdSchema,
|
|
129
129
|
}),
|
|
130
130
|
]),
|
|
131
|
-
// A
|
|
131
|
+
// A reason stored by a link or a removal recorded while they still took one; no operation
|
|
132
|
+
// writes one now. A removal's is dropped on read; a link's is kept, so its stored operation
|
|
133
|
+
// still resumes.
|
|
132
134
|
reason: repairReasonSchema.optional(),
|
|
133
135
|
// A removal's finished-game entries, in the order it removed them; absent on a link.
|
|
134
136
|
removedFinishedGameEntries: z.array(GhostRemovedFinishedEntrySchema).optional(),
|
|
@@ -139,13 +141,6 @@ export const GhostPlayerStatsOperationSchema = z
|
|
|
139
141
|
// What a completed link did with the team's memberships, so a call after completion answers it.
|
|
140
142
|
membershipOutcome: z.enum(GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS).optional(),
|
|
141
143
|
})
|
|
142
|
-
.superRefine((operation, ctx) => {
|
|
143
|
-
if (operation.scope.action === 'link' && operation.reason === undefined) {
|
|
144
|
-
ctx.addIssue({ code: 'custom', path: ['reason'], message: 'A ghost link records its reason.' });
|
|
145
|
-
}
|
|
146
|
-
})
|
|
147
|
-
// A removal recorded while removals still took a reason keeps it on disk; it is dropped on read
|
|
148
|
-
// rather than failing the document, and no removal writes one now.
|
|
149
144
|
.overwrite((operation) => {
|
|
150
145
|
if (operation.scope.action !== 'removal' || operation.reason === undefined)
|
|
151
146
|
return operation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats-operation.js","sourceRoot":"","sources":["../../src/doc-schemas/stats-operation.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,oGAAoG;AACpG,mGAAmG;AACnG,oGAAoG;AACpG,sDAAsD;AACtD,EAAE;AACF,uFAAuF;AACvF,0FAA0F;AAC1F,EAAE;AACF,oGAAoG;AACpG,oGAAoG;AACpG,yEAAyE;AACzE,+CAA+C;AAE/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,kCAAkC,EAClC,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,WAAW,EACX,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,YAAY,CAAC;IACvD,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,WAAW;IACpB,OAAO,EAAE,WAAW;CACrB,CAAC,CAAC;AAGH,MAAM,aAAa,GAAG;IACpB,eAAe,EAAE,YAAY;IAC7B,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,aAAa;IACxB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC;IAC3C,2EAA2E;IAC3E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,MAAM,EAAE,0BAA0B;CACnC,CAAC;AAEF,oGAAoG;AACpG,uFAAuF;AACvF,MAAM,aAAa,GAAG;IACpB,GAAG,aAAa;IAChB,MAAM,EAAE,kBAAkB;IAC1B,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;CACxC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;AAE3D,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC,YAAY,CAAC;IAC9D,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,oBAAiD,CAAC;IAClE,wBAAwB;IACxB,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,EAAE,CAAC;CAC/D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAC,YAAY,CAAC;IAChE,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,sBAAmD,CAAC;IACpE,sBAAsB;IACtB,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;CAC3D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC,YAAY,CAAC;IAC7D,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAgD,CAAC;IACjE,gCAAgC;IAChC,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;CACrF,CAAC,CAAC;AAEH,sDAAsD;AACtD,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,YAAY,CAAC;IAC3D,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAA8C,CAAC;IAC/D,wDAAwD;IACxD,KAAK,EAAE,0BAA0B;IACjC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC,YAAY,CAAC;IAC/D,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAkD,CAAC;IACnE,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,kBAAkB;CAC3B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,CAAC,YAAY,CAAC;IAClE,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,wBAAqD,CAAC;IACtE,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,kBAAkB;CAC3B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,CAAC,YAAY,CAAC;IACjE,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,uBAAoD,CAAC;IACrE,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;IACzE,MAAM,EAAE,kBAAkB;CAC3B,CAAC,CAAC;AAEH,qGAAqG;AACrG,qGAAqG;AACrG,+FAA+F;AAC/F,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,YAAY,CAAC;IAC5D,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;CAC3B,CAAC,CAAC;AAGH,oGAAoG;AACpG,6FAA6F;AAC7F,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,YAAY,CAAC;IAClD,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;CACpB,CAAC,CAAC;AAGH,oGAAoG;AACpG,kGAAkG;AAClG,mGAAmG;AACnG,oDAAoD;AACpD,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,YAAY,CAAC;IACzD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACnD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAGH,iGAAiG;AACjG,kGAAkG;AAClG,gGAAgG;AAChG,yCAAyC;AACzC,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC7C,YAAY,CAAC;IACZ,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAA+C,CAAC;IAChE,KAAK,EAAE,CAAC,CAAC,kBAAkB,CAAC,QAAQ,EAAE;QACpC,CAAC,CAAC,YAAY,CAAC;YACb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAA0C,CAAC;YAC7D,MAAM,EAAE,YAAY;YACpB,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,YAAY;SACrB,CAAC;QACF,CAAC,CAAC,YAAY,CAAC;YACb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,SAA6C,CAAC;YAChE,MAAM,EAAE,YAAY;YACpB,WAAW,EAAE,YAAY;SAC1B,CAAC;KACH,CAAC;IACF,iGAAiG;IACjG,MAAM,EAAE,kBAAkB,CAAC,QAAQ,EAAE;IACrC,qFAAqF;IACrF,0BAA0B,EAAE,CAAC,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,QAAQ,EAAE;IAC/E,8FAA8F;IAC9F,uBAAuB;IACvB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IACtD,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,QAAQ,EAAE;IACpE,gGAAgG;IAChG,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,QAAQ,EAAE;CACzE,CAAC;KACD,WAAW,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE;IAC9B,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACxE,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC,CAAC;IAClG,CAAC;AACH,CAAC,CAAC;IACF,gGAAgG;IAChG,mEAAmE;KAClE,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE;IACvB,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7F,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,EAAE,GAAG,SAAS,CAAC;IACxD,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC,CAAC;AAGL,6FAA6F;AAC7F,+DAA+D;AAC/D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,YAAY,CAAC;IACxD,GAAG,aAAa;IAChB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAA2C,CAAC;IAC5D,KAAK,EAAE,SAAS;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC/D,iCAAiC;IACjC,mCAAmC;IACnC,gCAAgC;IAChC,8BAA8B;IAC9B,kCAAkC;IAClC,qCAAqC;IACrC,oCAAoC;IACpC,+BAA+B;IAC/B,2BAA2B;CAC5B,CAAC,CAAC","sourcesContent":["// `statsOperations/{operationId}` — one logical run of a stats action: a rebuild, a validation, a\n// game's correction or recalculation, a historical-baseline update, a ghost's stats half, or a game\n// deletion. The stats cores write it in the same commit as each page it records, so an interrupted\n// run resumes the same operation instead of starting a second one, and a retried single-game action\n// finds its operation `complete` and is acknowledged.\n//\n// It is also the hold on a game: while a multi-page operation works a game, the game's\n// `statsOperationId` names this document, and every other writer of that game refuses it.\n//\n// The id is minted by the client when the admin starts the action, except two the server derives: a\n// ghost's, from the team and the ghost, so a ghost has one operation for its links and its removal;\n// and a game deletion's, from the game (`buildGameDeletionOperationId`).\n// Admin read; written only by the stats cores.\n\nimport { z } from 'zod';\nimport {\n GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS,\n STATS_OPERATION_STATUS_KEYS,\n STATS_VALIDATION_PHASE_KEYS,\n} from '../types/stats.js';\nimport type { GhostStatsOperationAction, StatsOperationKind } from '../types/stats.js';\nimport {\n countSchema,\n epochMsSchema,\n gameIdSchema,\n leagueIdSchema,\n repairReasonSchema,\n sportKeySchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\nimport { StatsValidationScopeSchema } from './system.js';\n\nexport const StatsOperationCountsSchema = z.strictObject({\n read: countSchema,\n changed: countSchema,\n skipped: countSchema,\n});\nexport type StatsOperationCounts = z.infer<typeof StatsOperationCountsSchema>;\n\nconst operationBase = {\n startedByUserId: userIdSchema,\n startedAt: epochMsSchema,\n updatedAt: epochMsSchema,\n status: z.enum(STATS_OPERATION_STATUS_KEYS),\n // The last document id a paged run finished; absent before its first page.\n resumeAfter: z.string().min(1).optional(),\n counts: StatsOperationCountsSchema,\n};\n\n// A rebuild replaces a destination whole and never rebuilds from a game whose record disagrees with\n// its rollup; it names each such game and rebuilds everything that game does not feed.\nconst rebuildFields = {\n ...operationBase,\n reason: repairReasonSchema,\n stoppedOnGameIds: z.array(gameIdSchema),\n};\n\nconst gameScope = z.strictObject({ gameId: gameIdSchema });\n\nexport const LeagueStatsRebuildOperationSchema = z.strictObject({\n ...rebuildFields,\n kind: z.literal('leagueStatsRebuild' satisfies StatsOperationKind),\n // Absent: every league.\n scope: z.strictObject({ leagueId: leagueIdSchema.optional() }),\n});\n\nexport const LifetimeStatsRebuildOperationSchema = z.strictObject({\n ...rebuildFields,\n kind: z.literal('lifetimeStatsRebuild' satisfies StatsOperationKind),\n // Absent: every user.\n scope: z.strictObject({ userId: userIdSchema.optional() }),\n});\n\nexport const HallOfFameRebuildOperationSchema = z.strictObject({\n ...rebuildFields,\n kind: z.literal('hallOfFameRebuild' satisfies StatsOperationKind),\n // Absent user: the whole sport.\n scope: z.strictObject({ sportKey: sportKeySchema, userId: userIdSchema.optional() }),\n});\n\n// A validation writes no stat, so it takes no reason.\nexport const StatsValidationOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('statsValidation' satisfies StatsOperationKind),\n // One game, one league, or — with neither — everything.\n scope: StatsValidationScopeSchema,\n phase: z.enum(STATS_VALIDATION_PHASE_KEYS),\n});\n\nexport const GameStatsCorrectionOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('gameStatsCorrection' satisfies StatsOperationKind),\n scope: gameScope,\n reason: repairReasonSchema,\n});\n\nexport const GameStatsRecalculationOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('gameStatsRecalculation' satisfies StatsOperationKind),\n scope: gameScope,\n reason: repairReasonSchema,\n});\n\nexport const HistoricalStatsUpdateOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('historicalStatsUpdate' satisfies StatsOperationKind),\n scope: z.strictObject({ userId: userIdSchema, sportKey: sportKeySchema }),\n reason: repairReasonSchema,\n});\n\n// One completed game a never-played ghost's removal took the ghost's entry off, with what the stored\n// participation decision said of the entry before: absent, and credited no game played. The per-game\n// transaction that removes the entry records it, so the removal's audit event names every one.\nexport const GhostRemovedFinishedEntrySchema = z.strictObject({\n gameId: gameIdSchema,\n wasAbsent: z.boolean(),\n wasNonScoring: z.boolean(),\n});\nexport type GhostRemovedFinishedEntry = z.infer<typeof GhostRemovedFinishedEntrySchema>;\n\n// One game a ghost link moved the ghost's entry on, whether the game was completed when it did, and\n// whether the account already held an entry there that the ghost's merged into. The per-game\n// transaction records it, so the link's audit event names every one.\nexport const GhostLinkedGameSchema = z.strictObject({\n gameId: gameIdSchema,\n completed: z.boolean(),\n merged: z.boolean(),\n});\nexport type GhostLinkedGame = z.infer<typeof GhostLinkedGameSchema>;\n\n// One derived line a stats action moved — a team's standings line, a per-membership row, a lifetime\n// line, or a hall-of-fame entry — with its value before the action's first change to it and after\n// its latest, `null` where there was or is no line. Every repair's audit event records them, and a\n// dry run lists them without writing (BACKEND-212).\nexport const StatsDestinationChangeSchema = z.strictObject({\n ref: z.string().min(1),\n field: z.string().min(1),\n before: z.record(z.string(), z.number()).nullable(),\n after: z.record(z.string(), z.number()).nullable(),\n});\nexport type StatsDestinationChange = z.infer<typeof StatsDestinationChangeSchema>;\n\n// The ghost's one operation records the account a link chose, or the removal, so a call naming a\n// different account — or a removal against a link — is refused, and the same call resumes. A link\n// rewrites completed records, so it carries its reason; a never-played ghost's removal is not a\n// repair and carries none (BACKEND-212).\nexport const GhostPlayerStatsOperationSchema = z\n .strictObject({\n ...operationBase,\n kind: z.literal('ghostPlayerStats' satisfies StatsOperationKind),\n scope: z.discriminatedUnion('action', [\n z.strictObject({\n action: z.literal('link' satisfies GhostStatsOperationAction),\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n userId: userIdSchema,\n }),\n z.strictObject({\n action: z.literal('removal' satisfies GhostStatsOperationAction),\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n }),\n ]),\n // A link's reason; a removal carries none (one stored by an earlier removal is dropped on read).\n reason: repairReasonSchema.optional(),\n // A removal's finished-game entries, in the order it removed them; absent on a link.\n removedFinishedGameEntries: z.array(GhostRemovedFinishedEntrySchema).optional(),\n // A link's games moved so far, in the order it moved them, and every derived line it changed;\n // absent on a removal.\n linkedGames: z.array(GhostLinkedGameSchema).optional(),\n destinationChanges: z.array(StatsDestinationChangeSchema).optional(),\n // What a completed link did with the team's memberships, so a call after completion answers it.\n membershipOutcome: z.enum(GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS).optional(),\n })\n .superRefine((operation, ctx) => {\n if (operation.scope.action === 'link' && operation.reason === undefined) {\n ctx.addIssue({ code: 'custom', path: ['reason'], message: 'A ghost link records its reason.' });\n }\n })\n // A removal recorded while removals still took a reason keeps it on disk; it is dropped on read\n // rather than failing the document, and no removal writes one now.\n .overwrite((operation) => {\n if (operation.scope.action !== 'removal' || operation.reason === undefined) return operation;\n const { reason: _reason, ...withoutReason } = operation;\n return withoutReason;\n });\nexport type GhostPlayerStatsOperation = z.infer<typeof GhostPlayerStatsOperationSchema>;\n\n// A game deletion pages out the game's events and roster under the hold and removes the game\n// document last; running it again on a held game continues it.\nexport const GameDeletionOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('gameDeletion' satisfies StatsOperationKind),\n scope: gameScope,\n});\n\nexport const StatsOperationSchema = z.discriminatedUnion('kind', [\n LeagueStatsRebuildOperationSchema,\n LifetimeStatsRebuildOperationSchema,\n HallOfFameRebuildOperationSchema,\n StatsValidationOperationSchema,\n GameStatsCorrectionOperationSchema,\n GameStatsRecalculationOperationSchema,\n HistoricalStatsUpdateOperationSchema,\n GhostPlayerStatsOperationSchema,\n GameDeletionOperationSchema,\n]);\nexport type StatsOperation = z.infer<typeof StatsOperationSchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"stats-operation.js","sourceRoot":"","sources":["../../src/doc-schemas/stats-operation.ts"],"names":[],"mappings":"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","sourcesContent":["// `statsOperations/{operationId}` — one logical run of a stats action: a rebuild, a validation, a\n// game's correction or recalculation, a historical-baseline update, a ghost's stats half, or a game\n// deletion. The stats cores write it in the same commit as each page it records, so an interrupted\n// run resumes the same operation instead of starting a second one, and a retried single-game action\n// finds its operation `complete` and is acknowledged.\n//\n// It is also the hold on a game: while a multi-page operation works a game, the game's\n// `statsOperationId` names this document, and every other writer of that game refuses it.\n//\n// The id is minted by the client when the admin starts the action, except two the server derives: a\n// ghost's, from the team and the ghost, so a ghost has one operation for its links and its removal;\n// and a game deletion's, from the game (`buildGameDeletionOperationId`).\n// Admin read; written only by the stats cores.\n\nimport { z } from 'zod';\nimport {\n GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS,\n STATS_OPERATION_STATUS_KEYS,\n STATS_VALIDATION_PHASE_KEYS,\n} from '../types/stats.js';\nimport type { GhostStatsOperationAction, StatsOperationKind } from '../types/stats.js';\nimport {\n countSchema,\n epochMsSchema,\n gameIdSchema,\n leagueIdSchema,\n repairReasonSchema,\n sportKeySchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\nimport { StatsValidationScopeSchema } from './system.js';\n\nexport const StatsOperationCountsSchema = z.strictObject({\n read: countSchema,\n changed: countSchema,\n skipped: countSchema,\n});\nexport type StatsOperationCounts = z.infer<typeof StatsOperationCountsSchema>;\n\nconst operationBase = {\n startedByUserId: userIdSchema,\n startedAt: epochMsSchema,\n updatedAt: epochMsSchema,\n status: z.enum(STATS_OPERATION_STATUS_KEYS),\n // The last document id a paged run finished; absent before its first page.\n resumeAfter: z.string().min(1).optional(),\n counts: StatsOperationCountsSchema,\n};\n\n// A rebuild replaces a destination whole and never rebuilds from a game whose record disagrees with\n// its rollup; it names each such game and rebuilds everything that game does not feed.\nconst rebuildFields = {\n ...operationBase,\n reason: repairReasonSchema,\n stoppedOnGameIds: z.array(gameIdSchema),\n};\n\nconst gameScope = z.strictObject({ gameId: gameIdSchema });\n\nexport const LeagueStatsRebuildOperationSchema = z.strictObject({\n ...rebuildFields,\n kind: z.literal('leagueStatsRebuild' satisfies StatsOperationKind),\n // Absent: every league.\n scope: z.strictObject({ leagueId: leagueIdSchema.optional() }),\n});\n\nexport const LifetimeStatsRebuildOperationSchema = z.strictObject({\n ...rebuildFields,\n kind: z.literal('lifetimeStatsRebuild' satisfies StatsOperationKind),\n // Absent: every user.\n scope: z.strictObject({ userId: userIdSchema.optional() }),\n});\n\nexport const HallOfFameRebuildOperationSchema = z.strictObject({\n ...rebuildFields,\n kind: z.literal('hallOfFameRebuild' satisfies StatsOperationKind),\n // Absent user: the whole sport.\n scope: z.strictObject({ sportKey: sportKeySchema, userId: userIdSchema.optional() }),\n});\n\n// A validation writes no stat, so it takes no reason.\nexport const StatsValidationOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('statsValidation' satisfies StatsOperationKind),\n // One game, one league, or — with neither — everything.\n scope: StatsValidationScopeSchema,\n phase: z.enum(STATS_VALIDATION_PHASE_KEYS),\n});\n\nexport const GameStatsCorrectionOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('gameStatsCorrection' satisfies StatsOperationKind),\n scope: gameScope,\n reason: repairReasonSchema,\n});\n\nexport const GameStatsRecalculationOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('gameStatsRecalculation' satisfies StatsOperationKind),\n scope: gameScope,\n reason: repairReasonSchema,\n});\n\nexport const HistoricalStatsUpdateOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('historicalStatsUpdate' satisfies StatsOperationKind),\n scope: z.strictObject({ userId: userIdSchema, sportKey: sportKeySchema }),\n reason: repairReasonSchema,\n});\n\n// One completed game a never-played ghost's removal took the ghost's entry off, with what the stored\n// participation decision said of the entry before: absent, and credited no game played. The per-game\n// transaction that removes the entry records it, so the removal's audit event names every one.\nexport const GhostRemovedFinishedEntrySchema = z.strictObject({\n gameId: gameIdSchema,\n wasAbsent: z.boolean(),\n wasNonScoring: z.boolean(),\n});\nexport type GhostRemovedFinishedEntry = z.infer<typeof GhostRemovedFinishedEntrySchema>;\n\n// One game a ghost link moved the ghost's entry on, whether the game was completed when it did, and\n// whether the account already held an entry there that the ghost's merged into. The per-game\n// transaction records it, so the link's audit event names every one.\nexport const GhostLinkedGameSchema = z.strictObject({\n gameId: gameIdSchema,\n completed: z.boolean(),\n merged: z.boolean(),\n});\nexport type GhostLinkedGame = z.infer<typeof GhostLinkedGameSchema>;\n\n// One derived line a stats action moved — a team's standings line, a per-membership row, a lifetime\n// line, or a hall-of-fame entry — with its value before the action's first change to it and after\n// its latest, `null` where there was or is no line. Every repair's audit event records them, and a\n// dry run lists them without writing (BACKEND-212).\nexport const StatsDestinationChangeSchema = z.strictObject({\n ref: z.string().min(1),\n field: z.string().min(1),\n before: z.record(z.string(), z.number()).nullable(),\n after: z.record(z.string(), z.number()).nullable(),\n});\nexport type StatsDestinationChange = z.infer<typeof StatsDestinationChangeSchema>;\n\n// The ghost's one operation records the account a link chose, or the removal, so a call naming a\n// different account — or a removal against a link — is refused, and the same call resumes. Neither\n// takes a reason: a link is chosen and confirmed, and its audit event records who linked which ghost\n// to whom and what moved (BACKEND-212).\nexport const GhostPlayerStatsOperationSchema = z\n .strictObject({\n ...operationBase,\n kind: z.literal('ghostPlayerStats' satisfies StatsOperationKind),\n scope: z.discriminatedUnion('action', [\n z.strictObject({\n action: z.literal('link' satisfies GhostStatsOperationAction),\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n userId: userIdSchema,\n }),\n z.strictObject({\n action: z.literal('removal' satisfies GhostStatsOperationAction),\n teamId: teamIdSchema,\n ghostUserId: userIdSchema,\n }),\n ]),\n // A reason stored by a link or a removal recorded while they still took one; no operation\n // writes one now. A removal's is dropped on read; a link's is kept, so its stored operation\n // still resumes.\n reason: repairReasonSchema.optional(),\n // A removal's finished-game entries, in the order it removed them; absent on a link.\n removedFinishedGameEntries: z.array(GhostRemovedFinishedEntrySchema).optional(),\n // A link's games moved so far, in the order it moved them, and every derived line it changed;\n // absent on a removal.\n linkedGames: z.array(GhostLinkedGameSchema).optional(),\n destinationChanges: z.array(StatsDestinationChangeSchema).optional(),\n // What a completed link did with the team's memberships, so a call after completion answers it.\n membershipOutcome: z.enum(GHOST_LINK_MEMBERSHIP_OUTCOME_KEYS).optional(),\n })\n .overwrite((operation) => {\n if (operation.scope.action !== 'removal' || operation.reason === undefined) return operation;\n const { reason: _reason, ...withoutReason } = operation;\n return withoutReason;\n });\nexport type GhostPlayerStatsOperation = z.infer<typeof GhostPlayerStatsOperationSchema>;\n\n// A game deletion pages out the game's events and roster under the hold and removes the game\n// document last; running it again on a held game continues it.\nexport const GameDeletionOperationSchema = z.strictObject({\n ...operationBase,\n kind: z.literal('gameDeletion' satisfies StatsOperationKind),\n scope: gameScope,\n});\n\nexport const StatsOperationSchema = z.discriminatedUnion('kind', [\n LeagueStatsRebuildOperationSchema,\n LifetimeStatsRebuildOperationSchema,\n HallOfFameRebuildOperationSchema,\n StatsValidationOperationSchema,\n GameStatsCorrectionOperationSchema,\n GameStatsRecalculationOperationSchema,\n HistoricalStatsUpdateOperationSchema,\n GhostPlayerStatsOperationSchema,\n GameDeletionOperationSchema,\n]);\nexport type StatsOperation = z.infer<typeof StatsOperationSchema>;\n"]}
|
|
@@ -20,6 +20,7 @@ export declare const LandingPageConfigSchema: z.ZodObject<{
|
|
|
20
20
|
export type LandingPageConfig = z.infer<typeof LandingPageConfigSchema>;
|
|
21
21
|
export declare const StatsBeaconSchema: z.ZodObject<{
|
|
22
22
|
updatedAt: z.ZodNumber;
|
|
23
|
+
changeId: z.ZodOptional<z.ZodString>;
|
|
23
24
|
action: z.ZodEnum<{
|
|
24
25
|
finalize: "finalize";
|
|
25
26
|
reopen: "reopen";
|
|
@@ -41,8 +42,10 @@ export type AdminList = z.infer<typeof AdminListSchema>;
|
|
|
41
42
|
export declare const STATS_DISCREPANCY_VALUE_SCHEMA: z.ZodUnion<readonly [z.ZodNumber, z.ZodString, z.ZodArray<z.ZodNullable<z.ZodNumber>>, z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodNull]>;
|
|
42
43
|
export declare const StatsDiscrepancySchema: z.ZodObject<{
|
|
43
44
|
kind: z.ZodEnum<{
|
|
45
|
+
gameUnreadable: "gameUnreadable";
|
|
44
46
|
invalidEvent: "invalidEvent";
|
|
45
47
|
eventSequenceMismatch: "eventSequenceMismatch";
|
|
48
|
+
eventSequenceGap: "eventSequenceGap";
|
|
46
49
|
rollupMismatch: "rollupMismatch";
|
|
47
50
|
scoreMirrorMismatch: "scoreMirrorMismatch";
|
|
48
51
|
unrosteredStatLine: "unrosteredStatLine";
|
|
@@ -89,8 +92,10 @@ export declare const StatsValidationReportSchema: z.ZodObject<{
|
|
|
89
92
|
complete: z.ZodBoolean;
|
|
90
93
|
discrepancies: z.ZodArray<z.ZodObject<{
|
|
91
94
|
kind: z.ZodEnum<{
|
|
95
|
+
gameUnreadable: "gameUnreadable";
|
|
92
96
|
invalidEvent: "invalidEvent";
|
|
93
97
|
eventSequenceMismatch: "eventSequenceMismatch";
|
|
98
|
+
eventSequenceGap: "eventSequenceGap";
|
|
94
99
|
rollupMismatch: "rollupMismatch";
|
|
95
100
|
scoreMirrorMismatch: "scoreMirrorMismatch";
|
|
96
101
|
unrosteredStatLine: "unrosteredStatLine";
|
|
@@ -112,8 +117,10 @@ export declare const StatsValidationReportSchema: z.ZodObject<{
|
|
|
112
117
|
actual: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodString, z.ZodArray<z.ZodNullable<z.ZodNumber>>, z.ZodRecord<z.ZodString, z.ZodNumber>, z.ZodNull]>>;
|
|
113
118
|
}, z.core.$strict>>;
|
|
114
119
|
discrepancyCounts: z.ZodRecord<z.ZodEnum<{
|
|
120
|
+
gameUnreadable: "gameUnreadable";
|
|
115
121
|
invalidEvent: "invalidEvent";
|
|
116
122
|
eventSequenceMismatch: "eventSequenceMismatch";
|
|
123
|
+
eventSequenceGap: "eventSequenceGap";
|
|
117
124
|
rollupMismatch: "rollupMismatch";
|
|
118
125
|
scoreMirrorMismatch: "scoreMirrorMismatch";
|
|
119
126
|
unrosteredStatLine: "unrosteredStatLine";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/system.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/system.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4BxB,eAAO,MAAM,eAAe;;;;;;iBAS1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAIxD,eAAO,MAAM,uBAAuB;;;;;;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAMxE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;iBAS5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAK5D,eAAO,MAAM,eAAe;;;iBAG1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAMxD,eAAO,MAAM,8BAA8B,2IAMzC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;kBAUjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,0BAA0B;;;kBAE8E,CAAC;AACtH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,4BAA4B;;;;;;kBAMvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAYtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { z } from 'zod';
|
|
|
4
4
|
import { MAX_ANNOUNCEMENT_MESSAGE_LENGTH, MAX_APP_VERSION_LENGTH, MAX_LANDING_ABOUT_TEXT_LENGTH, MAX_LANDING_HERO_TITLE_LENGTH, MAX_MAINTENANCE_MESSAGE_LENGTH, } from '../constants/business.js';
|
|
5
5
|
import { MAX_STATS_VALIDATION_DISCREPANCIES } from '../constants/sports.js';
|
|
6
6
|
import { GallerySummarySchema } from './gallery.js';
|
|
7
|
-
import { countSchema, epochMsSchema, gameIdSchema, leagueIdSchema, statsBeaconActionSchema, statsDiscrepancyKindSchema, statsOperationIdSchema, teamIdSchema, userIdSchema, } from './atoms.js';
|
|
7
|
+
import { countSchema, documentIdSegmentSchema, epochMsSchema, gameIdSchema, leagueIdSchema, statsBeaconActionSchema, statsDiscrepancyKindSchema, statsOperationIdSchema, teamIdSchema, userIdSchema, } from './atoms.js';
|
|
8
8
|
// `_appConfig/app` — the app-wide operational levers, set through the audited updateAppConfig
|
|
9
9
|
// callable. `appVersion` is what a live client compares itself against to force a refresh. It is
|
|
10
10
|
// written whole through `mergeAppConfigUpdate` and read one lever at a time through
|
|
@@ -34,6 +34,9 @@ export const LandingPageConfigSchema = z.object({
|
|
|
34
34
|
// earlier write.
|
|
35
35
|
export const StatsBeaconSchema = z.object({
|
|
36
36
|
updatedAt: epochMsSchema,
|
|
37
|
+
// A fresh document id minted by every write, so two commits in the same millisecond still move
|
|
38
|
+
// the beacon. Absent on a beacon stored before writes carried one.
|
|
39
|
+
changeId: documentIdSegmentSchema.optional(),
|
|
37
40
|
action: statsBeaconActionSchema,
|
|
38
41
|
leagueId: leagueIdSchema.optional(),
|
|
39
42
|
gameId: gameIdSchema.optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/doc-schemas/system.ts"],"names":[],"mappings":"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","sourcesContent":["// Fixed-ID system documents in the underscore buckets, plus the derived stat documents. Every one\n// is callable-only for writes.\n\nimport { z } from 'zod';\nimport {\n MAX_ANNOUNCEMENT_MESSAGE_LENGTH,\n MAX_APP_VERSION_LENGTH,\n MAX_LANDING_ABOUT_TEXT_LENGTH,\n MAX_LANDING_HERO_TITLE_LENGTH,\n MAX_MAINTENANCE_MESSAGE_LENGTH,\n} from '../constants/business.js';\nimport { MAX_STATS_VALIDATION_DISCREPANCIES } from '../constants/sports.js';\nimport { GallerySummarySchema } from './gallery.js';\nimport {\n countSchema,\n epochMsSchema,\n gameIdSchema,\n leagueIdSchema,\n statsBeaconActionSchema,\n statsDiscrepancyKindSchema,\n statsOperationIdSchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\n\n// `_appConfig/app` — the app-wide operational levers, set through the audited updateAppConfig\n// callable. `appVersion` is what a live client compares itself against to force a refresh. It is\n// written whole through `mergeAppConfigUpdate` and read one lever at a time through\n// `readAppConfigLever` (../utils/app-config.ts). Every text lever carries the same cap as its\n// updateAppConfig input field, so no writer can store a value the input would refuse.\nexport const AppConfigSchema = z.object({\n // `''` is valid here — no version published yet; only the update input requires a value.\n appVersion: z.string().max(MAX_APP_VERSION_LENGTH),\n maintenanceMode: z.boolean(),\n maintenanceMessage: z.string().max(MAX_MAINTENANCE_MESSAGE_LENGTH).optional(),\n registrationEnabled: z.boolean(),\n // Empty means no banner — there is no separate on/off flag. Non-empty is the band above every\n // page.\n announcementMessage: z.string().max(MAX_ANNOUNCEMENT_MESSAGE_LENGTH).optional(),\n});\nexport type AppConfig = z.infer<typeof AppConfigSchema>;\n\n// `_appConfig/landingPage` — admin-authored landing page copy, written by adminUpdateLandingPage,\n// plus the landing gallery's summary, which only the picture core writes.\nexport const LandingPageConfigSchema = z.object({\n heroTitle: z.string().max(MAX_LANDING_HERO_TITLE_LENGTH),\n aboutCompany: z.string().max(MAX_LANDING_ABOUT_TEXT_LENGTH),\n pictures: GallerySummarySchema.optional(),\n updatedAt: epochMsSchema,\n});\nexport type LandingPageConfig = z.infer<typeof LandingPageConfigSchema>;\n\n// `_appConfig/statsBeacon` — the signal watching clients refresh their stats on, replaced whole by\n// every write. The scope ids say what changed; an action that spans more than one game or league\n// omits them, and because every write replaces the document, an omitted id never survives from an\n// earlier write.\nexport const StatsBeaconSchema = z.object({\n updatedAt: epochMsSchema,\n action: statsBeaconActionSchema,\n leagueId: leagueIdSchema.optional(),\n gameId: gameIdSchema.optional(),\n teamIds: z.array(teamIdSchema).optional(),\n});\nexport type StatsBeacon = z.infer<typeof StatsBeaconSchema>;\n\n// `_systemData/adminList` — the admin and referee rosters. The source of truth the `admin` and\n// `referee` custom claims are minted from, written only by the audited updateAdminList callable;\n// the first admin of a fresh environment is seeded in the console.\nexport const AdminListSchema = z.object({\n admins: z.array(userIdSchema),\n referees: z.array(userIdSchema),\n});\nexport type AdminList = z.infer<typeof AdminListSchema>;\n\n// `statsValidationReports/{reportId}` — one stats check: every place a game's stored numbers, or a\n// derived aggregate, disagree with what the game's events and the completed games say they should\n// be. Its id is the check's operation id, which the admin's browser mints, so two checks never share\n// a report. Written only by the check, page by page; `complete` turns true with its last page.\nexport const STATS_DISCREPANCY_VALUE_SCHEMA = z.union([\n z.number(),\n z.string(),\n z.array(z.number().nullable()),\n z.record(z.string(), z.number()),\n z.null(),\n]);\n\nexport const StatsDiscrepancySchema = z.strictObject({\n kind: statsDiscrepancyKindSchema,\n gameId: gameIdSchema.optional(),\n // The slash path of the document the finding is about.\n path: z.string().min(1),\n // The line or entry within it — a team id, a roster-entry id, a user id — when there is one.\n key: z.string().min(1).optional(),\n field: z.string().min(1).optional(),\n expected: STATS_DISCREPANCY_VALUE_SCHEMA.optional(),\n actual: STATS_DISCREPANCY_VALUE_SCHEMA.optional(),\n});\nexport type StatsDiscrepancy = z.infer<typeof StatsDiscrepancySchema>;\n\nexport const StatsValidationScopeSchema = z\n .strictObject({ gameId: gameIdSchema.optional(), leagueId: leagueIdSchema.optional() })\n .refine((scope) => scope.gameId === undefined || scope.leagueId === undefined, 'One game or one league, not both.');\nexport type StatsValidationScope = z.infer<typeof StatsValidationScopeSchema>;\n\nexport const StatsValidationSummarySchema = z.strictObject({\n totalGamesChecked: countSchema,\n totalUsersChecked: countSchema,\n totalTeamsChecked: countSchema,\n totalLeaguesChecked: countSchema,\n discrepanciesFound: countSchema,\n});\nexport type StatsValidationSummary = z.infer<typeof StatsValidationSummarySchema>;\n\nexport const StatsValidationReportSchema = z.strictObject({\n reportId: z.string().min(1),\n operationId: statsOperationIdSchema,\n ranAt: epochMsSchema,\n ranByUserId: userIdSchema,\n scope: StatsValidationScopeSchema,\n complete: z.boolean(),\n // Game-tier findings first, then aggregate ones, at most MAX_STATS_VALIDATION_DISCREPANCIES.\n discrepancies: z.array(StatsDiscrepancySchema).max(MAX_STATS_VALIDATION_DISCREPANCIES),\n // Every finding, kept or not, counted by kind.\n discrepancyCounts: z.partialRecord(statsDiscrepancyKindSchema, countSchema),\n summary: StatsValidationSummarySchema,\n});\nexport type StatsValidationReport = z.infer<typeof StatsValidationReportSchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/doc-schemas/system.ts"],"names":[],"mappings":"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","sourcesContent":["// Fixed-ID system documents in the underscore buckets, plus the derived stat documents. Every one\n// is callable-only for writes.\n\nimport { z } from 'zod';\nimport {\n MAX_ANNOUNCEMENT_MESSAGE_LENGTH,\n MAX_APP_VERSION_LENGTH,\n MAX_LANDING_ABOUT_TEXT_LENGTH,\n MAX_LANDING_HERO_TITLE_LENGTH,\n MAX_MAINTENANCE_MESSAGE_LENGTH,\n} from '../constants/business.js';\nimport { MAX_STATS_VALIDATION_DISCREPANCIES } from '../constants/sports.js';\nimport { GallerySummarySchema } from './gallery.js';\nimport {\n countSchema,\n documentIdSegmentSchema,\n epochMsSchema,\n gameIdSchema,\n leagueIdSchema,\n statsBeaconActionSchema,\n statsDiscrepancyKindSchema,\n statsOperationIdSchema,\n teamIdSchema,\n userIdSchema,\n} from './atoms.js';\n\n// `_appConfig/app` — the app-wide operational levers, set through the audited updateAppConfig\n// callable. `appVersion` is what a live client compares itself against to force a refresh. It is\n// written whole through `mergeAppConfigUpdate` and read one lever at a time through\n// `readAppConfigLever` (../utils/app-config.ts). Every text lever carries the same cap as its\n// updateAppConfig input field, so no writer can store a value the input would refuse.\nexport const AppConfigSchema = z.object({\n // `''` is valid here — no version published yet; only the update input requires a value.\n appVersion: z.string().max(MAX_APP_VERSION_LENGTH),\n maintenanceMode: z.boolean(),\n maintenanceMessage: z.string().max(MAX_MAINTENANCE_MESSAGE_LENGTH).optional(),\n registrationEnabled: z.boolean(),\n // Empty means no banner — there is no separate on/off flag. Non-empty is the band above every\n // page.\n announcementMessage: z.string().max(MAX_ANNOUNCEMENT_MESSAGE_LENGTH).optional(),\n});\nexport type AppConfig = z.infer<typeof AppConfigSchema>;\n\n// `_appConfig/landingPage` — admin-authored landing page copy, written by adminUpdateLandingPage,\n// plus the landing gallery's summary, which only the picture core writes.\nexport const LandingPageConfigSchema = z.object({\n heroTitle: z.string().max(MAX_LANDING_HERO_TITLE_LENGTH),\n aboutCompany: z.string().max(MAX_LANDING_ABOUT_TEXT_LENGTH),\n pictures: GallerySummarySchema.optional(),\n updatedAt: epochMsSchema,\n});\nexport type LandingPageConfig = z.infer<typeof LandingPageConfigSchema>;\n\n// `_appConfig/statsBeacon` — the signal watching clients refresh their stats on, replaced whole by\n// every write. The scope ids say what changed; an action that spans more than one game or league\n// omits them, and because every write replaces the document, an omitted id never survives from an\n// earlier write.\nexport const StatsBeaconSchema = z.object({\n updatedAt: epochMsSchema,\n // A fresh document id minted by every write, so two commits in the same millisecond still move\n // the beacon. Absent on a beacon stored before writes carried one.\n changeId: documentIdSegmentSchema.optional(),\n action: statsBeaconActionSchema,\n leagueId: leagueIdSchema.optional(),\n gameId: gameIdSchema.optional(),\n teamIds: z.array(teamIdSchema).optional(),\n});\nexport type StatsBeacon = z.infer<typeof StatsBeaconSchema>;\n\n// `_systemData/adminList` — the admin and referee rosters. The source of truth the `admin` and\n// `referee` custom claims are minted from, written only by the audited updateAdminList callable;\n// the first admin of a fresh environment is seeded in the console.\nexport const AdminListSchema = z.object({\n admins: z.array(userIdSchema),\n referees: z.array(userIdSchema),\n});\nexport type AdminList = z.infer<typeof AdminListSchema>;\n\n// `statsValidationReports/{reportId}` — one stats check: every place a game's stored numbers, or a\n// derived aggregate, disagree with what the game's events and the completed games say they should\n// be. Its id is the check's operation id, which the admin's browser mints, so two checks never share\n// a report. Written only by the check, page by page; `complete` turns true with its last page.\nexport const STATS_DISCREPANCY_VALUE_SCHEMA = z.union([\n z.number(),\n z.string(),\n z.array(z.number().nullable()),\n z.record(z.string(), z.number()),\n z.null(),\n]);\n\nexport const StatsDiscrepancySchema = z.strictObject({\n kind: statsDiscrepancyKindSchema,\n gameId: gameIdSchema.optional(),\n // The slash path of the document the finding is about.\n path: z.string().min(1),\n // The line or entry within it — a team id, a roster-entry id, a user id — when there is one.\n key: z.string().min(1).optional(),\n field: z.string().min(1).optional(),\n expected: STATS_DISCREPANCY_VALUE_SCHEMA.optional(),\n actual: STATS_DISCREPANCY_VALUE_SCHEMA.optional(),\n});\nexport type StatsDiscrepancy = z.infer<typeof StatsDiscrepancySchema>;\n\nexport const StatsValidationScopeSchema = z\n .strictObject({ gameId: gameIdSchema.optional(), leagueId: leagueIdSchema.optional() })\n .refine((scope) => scope.gameId === undefined || scope.leagueId === undefined, 'One game or one league, not both.');\nexport type StatsValidationScope = z.infer<typeof StatsValidationScopeSchema>;\n\nexport const StatsValidationSummarySchema = z.strictObject({\n totalGamesChecked: countSchema,\n totalUsersChecked: countSchema,\n totalTeamsChecked: countSchema,\n totalLeaguesChecked: countSchema,\n discrepanciesFound: countSchema,\n});\nexport type StatsValidationSummary = z.infer<typeof StatsValidationSummarySchema>;\n\nexport const StatsValidationReportSchema = z.strictObject({\n reportId: z.string().min(1),\n operationId: statsOperationIdSchema,\n ranAt: epochMsSchema,\n ranByUserId: userIdSchema,\n scope: StatsValidationScopeSchema,\n complete: z.boolean(),\n // Game-tier findings first, then aggregate ones, at most MAX_STATS_VALIDATION_DISCREPANCIES.\n discrepancies: z.array(StatsDiscrepancySchema).max(MAX_STATS_VALIDATION_DISCREPANCIES),\n // Every finding, kept or not, counted by kind.\n discrepancyCounts: z.partialRecord(statsDiscrepancyKindSchema, countSchema),\n summary: StatsValidationSummarySchema,\n});\nexport type StatsValidationReport = z.infer<typeof StatsValidationReportSchema>;\n"]}
|
|
@@ -44,6 +44,7 @@ export type UserProfile = z.infer<typeof UserProfileSchema>;
|
|
|
44
44
|
export declare const UserPrivateDataSchema: z.ZodObject<{
|
|
45
45
|
email: z.ZodString;
|
|
46
46
|
registrationStartedAt: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
orphanDeletionClaimedAt: z.ZodOptional<z.ZodNumber>;
|
|
47
48
|
defaultContactPhone: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
|
|
48
49
|
theme: z.ZodOptional<z.ZodEnum<{
|
|
49
50
|
light: "light";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/user-profile.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,eAAe;;;;EAAsB,CAAC;AAGnD,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAc5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"user-profile.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/user-profile.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,eAAe;;;;EAAsB,CAAC;AAGnD,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAc5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;iBAiBhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAMpE,eAAO,MAAM,qBAAqB;;;;;kBAA6D,CAAC;AAChG,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAWpE,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,EAAyC,SAAS,CAAC,MAAM,eAAe,CAAC,EAAE,CAAC"}
|
|
@@ -37,6 +37,11 @@ export const UserPrivateDataSchema = z.object({
|
|
|
37
37
|
// When this login's registration started (`createRegistrationStart`); `registerUser` refuses
|
|
38
38
|
// without it. Absent on an account copied from V1, which registered before the step existed.
|
|
39
39
|
registrationStartedAt: epochMsSchema.optional(),
|
|
40
|
+
// When the orphan-registration cleanup decided to delete this uid's login. Written in the
|
|
41
|
+
// cleanup's eligibility transaction BEFORE the Auth delete, and both registration steps answer
|
|
42
|
+
// `registrationExpired` in their own transactions while it is present, so no registration
|
|
43
|
+
// completes into a login that is about to be deleted. Backend-only.
|
|
44
|
+
orphanDeletionClaimedAt: epochMsSchema.optional(),
|
|
40
45
|
// Pre-fills the contact phone when this user creates a team.
|
|
41
46
|
defaultContactPhone: textFieldSchema(CONTACT_PHONE_INPUT_FORMAT).optional(),
|
|
42
47
|
// The account's copy of the viewer's settings, synced with the device's. Absent means the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile.js","sourceRoot":"","sources":["../../src/doc-schemas/user-profile.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,6FAA6F;AAC7F,kGAAkG;AAClG,uDAAuD;AAEvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,kGAAkG;AAClG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAEnD,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE;IACjC,oFAAoF;IACpF,UAAU,EAAE,gBAAgB;IAC5B,+FAA+F;IAC/F,yBAAyB;IACzB,aAAa,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IACjD,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IACrD,mEAAmE;IACnE,cAAc,EAAE,aAAa,CAAC,QAAQ,EAAE;IACxC,gBAAgB,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC1C,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,mGAAmG;AACnG,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,6FAA6F;IAC7F,6FAA6F;IAC7F,qBAAqB,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC/C,6DAA6D;IAC7D,mBAAmB,EAAE,eAAe,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE;IAC3E,0FAA0F;IAC1F,gEAAgE;IAChE,KAAK,EAAE,eAAe,CAAC,QAAQ,EAAE;IACjC,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACrC,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,mGAAmG;AACnG,sGAAsG;AACtG,+FAA+F;AAC/F,yCAAyC;AACzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AAGhG,sGAAsG;AACtG,8BAA8B;AAC9B,MAAM,qBAAqB,GAAwC;IACjE,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;CACd,CAAC;AAEF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAuC,CAAC","sourcesContent":["// `userProfiles/{userId}` — the account's profile, one per Firebase Auth uid. Ghosts have none.\n// It is publicly readable (a profile page renders signed out), so it holds nothing personal:\n// email and contact details live in its owner-only `privateData/{userId}` document (BACKEND-105).\n// Plus its `historicalStats/{sportKey}` subcollection.\n\nimport { z } from 'zod';\nimport { THEME_NAMES } from '@ttt-productions/theme-core';\nimport { CONTACT_PHONE_INPUT_FORMAT } from '../input-formats/index.js';\nimport { BasketballPlayerTotalsSchema, UserLifetimeStatsSchema } from './aggregate-stats.js';\nimport { epochMsSchema, textFieldSchema, userStatusSchema } from './atoms.js';\nimport { awardIdSchema } from './catalogs.js';\n\n// A saved theme, typed by theme-core's theme set — the one declaration its provider renders from.\nexport const themeNameSchema = z.enum(THEME_NAMES);\n\n// An award granted to this user. Name and imagery resolve from `awardDefinitions/{awardId}`.\nexport const GrantedAwardSchema = z.object({\n awardId: awardIdSchema,\n grantedAt: epochMsSchema,\n});\nexport type GrantedAward = z.infer<typeof GrantedAwardSchema>;\n\nexport const UserProfileSchema = z.object({\n displayName: z.string(),\n displayName_lowercase: z.string(),\n // Written `active` at registration and by the profile copy; nothing else writes it.\n userStatus: userStatusSchema,\n // Per sport, the career line; career games played is the sum of their games played, derived at\n // read and never stored.\n lifetimeStats: UserLifetimeStatsSchema.optional(),\n grantedAwards: z.array(GrantedAwardSchema).optional(),\n // The awards the account shows beside its name, each one it holds.\n primaryAwardId: awardIdSchema.optional(),\n secondaryAwardId: awardIdSchema.optional(),\n createdAt: epochMsSchema,\n updatedAt: epochMsSchema,\n});\nexport type UserProfile = z.infer<typeof UserProfileSchema>;\n\n// `userProfiles/{userId}/privateData/{userId}` — readable by its owner and by admins; written only\n// by callables.\nexport const UserPrivateDataSchema = z.object({\n email: z.string(),\n // When this login's registration started (`createRegistrationStart`); `registerUser` refuses\n // without it. Absent on an account copied from V1, which registered before the step existed.\n registrationStartedAt: epochMsSchema.optional(),\n // Pre-fills the contact phone when this user creates a team.\n defaultContactPhone: textFieldSchema(CONTACT_PHONE_INPUT_FORMAT).optional(),\n // The account's copy of the viewer's settings, synced with the device's. Absent means the\n // account has saved nothing and the device's own choice stands.\n theme: themeNameSchema.optional(),\n reducedMotion: z.boolean().optional(),\n updatedAt: epochMsSchema,\n});\nexport type UserPrivateData = z.infer<typeof UserPrivateDataSchema>;\n\n// `userProfiles/{userId}/historicalStats/{sportKey}` — pre-Q-Sports career totals an admin enters,\n// folded into lifetime and hall-of-fame recalculation. Absolute totals, not increments. Basketball is\n// the sport with a baseline, so it is the basketball totals line without FP, which the rebuild\n// derives when it folds the baseline in.\nexport const HistoricalStatsSchema = BasketballPlayerTotalsSchema.omit({ fantasyPoints: true });\nexport type HistoricalStats = z.infer<typeof HistoricalStatsSchema>;\n\n// Every field of a baseline, keyed so the record cannot miss one or name one the schema lacks, in the\n// order an admin enters them.\nconst HISTORICAL_STAT_ENTRY: Record<keyof HistoricalStats, true> = {\n gamesPlayed: true,\n points: true,\n rebounds: true,\n assists: true,\n};\n\n/** A baseline's totals, in the order an admin enters them. */\nexport const HISTORICAL_STAT_KEYS = Object.keys(HISTORICAL_STAT_ENTRY) as readonly (keyof HistoricalStats)[];\n"]}
|
|
1
|
+
{"version":3,"file":"user-profile.js","sourceRoot":"","sources":["../../src/doc-schemas/user-profile.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,6FAA6F;AAC7F,kGAAkG;AAClG,uDAAuD;AAEvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,kGAAkG;AAClG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAEnD,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,aAAa;IACtB,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE;IACjC,oFAAoF;IACpF,UAAU,EAAE,gBAAgB;IAC5B,+FAA+F;IAC/F,yBAAyB;IACzB,aAAa,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IACjD,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IACrD,mEAAmE;IACnE,cAAc,EAAE,aAAa,CAAC,QAAQ,EAAE;IACxC,gBAAgB,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC1C,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,mGAAmG;AACnG,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,6FAA6F;IAC7F,6FAA6F;IAC7F,qBAAqB,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC/C,0FAA0F;IAC1F,+FAA+F;IAC/F,0FAA0F;IAC1F,oEAAoE;IACpE,uBAAuB,EAAE,aAAa,CAAC,QAAQ,EAAE;IACjD,6DAA6D;IAC7D,mBAAmB,EAAE,eAAe,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE;IAC3E,0FAA0F;IAC1F,gEAAgE;IAChE,KAAK,EAAE,eAAe,CAAC,QAAQ,EAAE;IACjC,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACrC,SAAS,EAAE,aAAa;CACzB,CAAC,CAAC;AAGH,mGAAmG;AACnG,sGAAsG;AACtG,+FAA+F;AAC/F,yCAAyC;AACzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AAGhG,sGAAsG;AACtG,8BAA8B;AAC9B,MAAM,qBAAqB,GAAwC;IACjE,WAAW,EAAE,IAAI;IACjB,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;CACd,CAAC;AAEF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAuC,CAAC","sourcesContent":["// `userProfiles/{userId}` — the account's profile, one per Firebase Auth uid. Ghosts have none.\n// It is publicly readable (a profile page renders signed out), so it holds nothing personal:\n// email and contact details live in its owner-only `privateData/{userId}` document (BACKEND-105).\n// Plus its `historicalStats/{sportKey}` subcollection.\n\nimport { z } from 'zod';\nimport { THEME_NAMES } from '@ttt-productions/theme-core';\nimport { CONTACT_PHONE_INPUT_FORMAT } from '../input-formats/index.js';\nimport { BasketballPlayerTotalsSchema, UserLifetimeStatsSchema } from './aggregate-stats.js';\nimport { epochMsSchema, textFieldSchema, userStatusSchema } from './atoms.js';\nimport { awardIdSchema } from './catalogs.js';\n\n// A saved theme, typed by theme-core's theme set — the one declaration its provider renders from.\nexport const themeNameSchema = z.enum(THEME_NAMES);\n\n// An award granted to this user. Name and imagery resolve from `awardDefinitions/{awardId}`.\nexport const GrantedAwardSchema = z.object({\n awardId: awardIdSchema,\n grantedAt: epochMsSchema,\n});\nexport type GrantedAward = z.infer<typeof GrantedAwardSchema>;\n\nexport const UserProfileSchema = z.object({\n displayName: z.string(),\n displayName_lowercase: z.string(),\n // Written `active` at registration and by the profile copy; nothing else writes it.\n userStatus: userStatusSchema,\n // Per sport, the career line; career games played is the sum of their games played, derived at\n // read and never stored.\n lifetimeStats: UserLifetimeStatsSchema.optional(),\n grantedAwards: z.array(GrantedAwardSchema).optional(),\n // The awards the account shows beside its name, each one it holds.\n primaryAwardId: awardIdSchema.optional(),\n secondaryAwardId: awardIdSchema.optional(),\n createdAt: epochMsSchema,\n updatedAt: epochMsSchema,\n});\nexport type UserProfile = z.infer<typeof UserProfileSchema>;\n\n// `userProfiles/{userId}/privateData/{userId}` — readable by its owner and by admins; written only\n// by callables.\nexport const UserPrivateDataSchema = z.object({\n email: z.string(),\n // When this login's registration started (`createRegistrationStart`); `registerUser` refuses\n // without it. Absent on an account copied from V1, which registered before the step existed.\n registrationStartedAt: epochMsSchema.optional(),\n // When the orphan-registration cleanup decided to delete this uid's login. Written in the\n // cleanup's eligibility transaction BEFORE the Auth delete, and both registration steps answer\n // `registrationExpired` in their own transactions while it is present, so no registration\n // completes into a login that is about to be deleted. Backend-only.\n orphanDeletionClaimedAt: epochMsSchema.optional(),\n // Pre-fills the contact phone when this user creates a team.\n defaultContactPhone: textFieldSchema(CONTACT_PHONE_INPUT_FORMAT).optional(),\n // The account's copy of the viewer's settings, synced with the device's. Absent means the\n // account has saved nothing and the device's own choice stands.\n theme: themeNameSchema.optional(),\n reducedMotion: z.boolean().optional(),\n updatedAt: epochMsSchema,\n});\nexport type UserPrivateData = z.infer<typeof UserPrivateDataSchema>;\n\n// `userProfiles/{userId}/historicalStats/{sportKey}` — pre-Q-Sports career totals an admin enters,\n// folded into lifetime and hall-of-fame recalculation. Absolute totals, not increments. Basketball is\n// the sport with a baseline, so it is the basketball totals line without FP, which the rebuild\n// derives when it folds the baseline in.\nexport const HistoricalStatsSchema = BasketballPlayerTotalsSchema.omit({ fantasyPoints: true });\nexport type HistoricalStats = z.infer<typeof HistoricalStatsSchema>;\n\n// Every field of a baseline, keyed so the record cannot miss one or name one the schema lacks, in the\n// order an admin enters them.\nconst HISTORICAL_STAT_ENTRY: Record<keyof HistoricalStats, true> = {\n gamesPlayed: true,\n points: true,\n rebounds: true,\n assists: true,\n};\n\n/** A baseline's totals, in the order an admin enters them. */\nexport const HISTORICAL_STAT_KEYS = Object.keys(HISTORICAL_STAT_ENTRY) as readonly (keyof HistoricalStats)[];\n"]}
|
|
@@ -7,6 +7,7 @@ export declare const WaiverTemplateSchema: z.ZodObject<{
|
|
|
7
7
|
version: z.ZodNumber;
|
|
8
8
|
createdAt: z.ZodNumber;
|
|
9
9
|
updatedAt: z.ZodNumber;
|
|
10
|
+
retired: z.ZodBoolean;
|
|
10
11
|
retiredAt: z.ZodOptional<z.ZodNumber>;
|
|
11
12
|
lastChosenAt: z.ZodOptional<z.ZodNumber>;
|
|
12
13
|
}, z.core.$strip>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waiver-template.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/waiver-template.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,sBAAsB,aAA0B,CAAC;AAC9D,eAAO,MAAM,iCAAiC,aAA0B,CAAC;AAIzE,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"waiver-template.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/waiver-template.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,sBAAsB,aAA0B,CAAC;AAC9D,eAAO,MAAM,iCAAiC,aAA0B,CAAC;AAIzE,eAAO,MAAM,oBAAoB;;;;;;;;;iBAuB7B,CAAC;AACL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAIlE,eAAO,MAAM,2BAA2B;;;;;;iBAOtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -10,12 +10,17 @@ export const waiverTemplateIdSchema = documentIdSegmentSchema;
|
|
|
10
10
|
export const waiverTemplateVersionNumberSchema = z.number().int().min(1);
|
|
11
11
|
// `waiverTemplates/{waiverTemplateId}` — the template as it reads now: its latest published
|
|
12
12
|
// version's wording and number.
|
|
13
|
-
export const WaiverTemplateSchema = z
|
|
13
|
+
export const WaiverTemplateSchema = z
|
|
14
|
+
.object({
|
|
14
15
|
title: z.string(),
|
|
15
16
|
waiverText: z.string(),
|
|
16
17
|
version: waiverTemplateVersionNumberSchema,
|
|
17
18
|
createdAt: epochMsSchema,
|
|
18
19
|
updatedAt: epochMsSchema,
|
|
20
|
+
// Whether the template is retired, so the templates offered to a league are one query filter
|
|
21
|
+
// (`retired == false`) rather than a download of every template ever kept. True exactly when
|
|
22
|
+
// `retiredAt` is set.
|
|
23
|
+
retired: z.boolean(),
|
|
19
24
|
// Set when an admin deletes a template a signature or a closed league still names, or one with
|
|
20
25
|
// more versions than a delete removes: it is kept for them and offered to no league again. A
|
|
21
26
|
// template nothing names is deleted outright instead.
|
|
@@ -24,6 +29,10 @@ export const WaiverTemplateSchema = z.object({
|
|
|
24
29
|
// its own transaction so a delete's read of this document conflicts with that save; it is its own
|
|
25
30
|
// field so `updatedAt` keeps meaning the template itself changed.
|
|
26
31
|
lastChosenAt: epochMsSchema.optional(),
|
|
32
|
+
})
|
|
33
|
+
.refine((template) => template.retired === (template.retiredAt !== undefined), {
|
|
34
|
+
message: 'A template is retired exactly when it records when it was retired.',
|
|
35
|
+
path: ['retired'],
|
|
27
36
|
});
|
|
28
37
|
// `waiverTemplates/{waiverTemplateId}/waiverTemplateVersions/{versionId}` — one published version,
|
|
29
38
|
// created once and never changed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waiver-template.js","sourceRoot":"","sources":["../../src/doc-schemas/waiver-template.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,mGAAmG;AACnG,+FAA+F;AAC/F,+FAA+F;AAC/F,sDAAsD;AAEtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAC;AAC9D,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEzE,4FAA4F;AAC5F,gCAAgC;AAChC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"waiver-template.js","sourceRoot":"","sources":["../../src/doc-schemas/waiver-template.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,mGAAmG;AACnG,+FAA+F;AAC/F,+FAA+F;AAC/F,sDAAsD;AAEtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAC;AAC9D,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAEzE,4FAA4F;AAC5F,gCAAgC;AAChC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAClC,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,iCAAiC;IAC1C,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,aAAa;IACxB,6FAA6F;IAC7F,6FAA6F;IAC7F,sBAAsB;IACtB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,+FAA+F;IAC/F,6FAA6F;IAC7F,sDAAsD;IACtD,SAAS,EAAE,aAAa,CAAC,QAAQ,EAAE;IACnC,kGAAkG;IAClG,kGAAkG;IAClG,kEAAkE;IAClE,YAAY,EAAE,aAAa,CAAC,QAAQ,EAAE;CACvC,CAAC;KACD,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,CAAC,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE;IAC7E,OAAO,EAAE,oEAAoE;IAC7E,IAAI,EAAE,CAAC,SAAS,CAAC;CAClB,CAAC,CAAC;AAGL,mGAAmG;AACnG,kCAAkC;AAClC,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,iCAAiC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,uDAAuD;IACvD,iBAAiB,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC1C,WAAW,EAAE,aAAa;CAC3B,CAAC,CAAC","sourcesContent":["// Waiver templates: the wording an admin authors for a league's players to sign.\n//\n// The wording is versioned. Every save that changes it publishes a new version, and each published\n// version is its own immutable document — so the exact wording in force when any signature was\n// captured still exists however the template has changed since. A signature also keeps its own\n// copy of what the signer saw (`SignedWaiverSchema`).\n\nimport { z } from 'zod';\nimport { documentIdSegmentSchema, epochMsSchema, userIdSchema } from './atoms.js';\n\nexport const waiverTemplateIdSchema = documentIdSegmentSchema;\nexport const waiverTemplateVersionNumberSchema = z.number().int().min(1);\n\n// `waiverTemplates/{waiverTemplateId}` — the template as it reads now: its latest published\n// version's wording and number.\nexport const WaiverTemplateSchema = z\n .object({\n title: z.string(),\n waiverText: z.string(),\n version: waiverTemplateVersionNumberSchema,\n createdAt: epochMsSchema,\n updatedAt: epochMsSchema,\n // Whether the template is retired, so the templates offered to a league are one query filter\n // (`retired == false`) rather than a download of every template ever kept. True exactly when\n // `retiredAt` is set.\n retired: z.boolean(),\n // Set when an admin deletes a template a signature or a closed league still names, or one with\n // more versions than a delete removes: it is kept for them and offered to no league again. A\n // template nothing names is deleted outright instead.\n retiredAt: epochMsSchema.optional(),\n // When a league last came to require the template. The league save that chooses it writes this in\n // its own transaction so a delete's read of this document conflicts with that save; it is its own\n // field so `updatedAt` keeps meaning the template itself changed.\n lastChosenAt: epochMsSchema.optional(),\n })\n .refine((template) => template.retired === (template.retiredAt !== undefined), {\n message: 'A template is retired exactly when it records when it was retired.',\n path: ['retired'],\n });\nexport type WaiverTemplate = z.infer<typeof WaiverTemplateSchema>;\n\n// `waiverTemplates/{waiverTemplateId}/waiverTemplateVersions/{versionId}` — one published version,\n// created once and never changed.\nexport const WaiverTemplateVersionSchema = z.object({\n version: waiverTemplateVersionNumberSchema,\n title: z.string(),\n waiverText: z.string(),\n // Absent on a version whose author was never recorded.\n publishedByUserId: userIdSchema.optional(),\n publishedAt: epochMsSchema,\n});\nexport type WaiverTemplateVersion = z.infer<typeof WaiverTemplateVersionSchema>;\n"]}
|
|
@@ -20,6 +20,7 @@ export declare const SignedWaiverSchema: z.ZodObject<{
|
|
|
20
20
|
coCaptain: "coCaptain";
|
|
21
21
|
}>>;
|
|
22
22
|
subjectDisplayNameSnapshot: z.ZodOptional<z.ZodString>;
|
|
23
|
+
witnessDisplayNameSnapshot: z.ZodOptional<z.ZodString>;
|
|
23
24
|
}, z.core.$strip>;
|
|
24
25
|
export type SignedWaiver = z.infer<typeof SignedWaiverSchema>;
|
|
25
26
|
export declare const HardwareItemSchema: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waivers-and-hardware.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/waivers-and-hardware.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"waivers-and-hardware.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/waivers-and-hardware.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;iBA0C5B,CAAC;AACJ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D,eAAO,MAAM,kBAAkB;;;kBAG7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAM9D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;kBAsBpC,CAAC;AACJ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
@@ -28,17 +28,25 @@ export const SignedWaiverSchema = z
|
|
|
28
28
|
witnessUserId: userIdSchema.optional(),
|
|
29
29
|
witnessAuthority: waiverWitnessAuthoritySchema.optional(),
|
|
30
30
|
subjectDisplayNameSnapshot: z.string().optional(),
|
|
31
|
+
// A V1 witnessed waiver recorded the witness's name as it was at signing, and never the authority
|
|
32
|
+
// or the ghost's name; the copy keeps that name as a named snapshot (ARCH-103) and guesses neither.
|
|
33
|
+
witnessDisplayNameSnapshot: z.string().optional(),
|
|
31
34
|
})
|
|
32
35
|
.refine((waiver) => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return present ===
|
|
41
|
-
|
|
36
|
+
const full = [waiver.teamId, waiver.witnessUserId, waiver.witnessAuthority, waiver.subjectDisplayNameSnapshot];
|
|
37
|
+
const legacy = [waiver.teamId, waiver.witnessUserId, waiver.witnessDisplayNameSnapshot];
|
|
38
|
+
const present = (fields) => fields.filter((field) => field !== undefined).length;
|
|
39
|
+
if (present([...full, waiver.witnessDisplayNameSnapshot]) === 0)
|
|
40
|
+
return true;
|
|
41
|
+
if (present(full) === full.length)
|
|
42
|
+
return waiver.witnessDisplayNameSnapshot === undefined;
|
|
43
|
+
return (present(legacy) === legacy.length &&
|
|
44
|
+
waiver.witnessAuthority === undefined &&
|
|
45
|
+
waiver.subjectDisplayNameSnapshot === undefined);
|
|
46
|
+
}, {
|
|
47
|
+
message: "A ghost's waiver carries its team, witness, authority, and name together; or, copied from V1, its team, witness, and the witness's recorded name; or none of them.",
|
|
48
|
+
path: ['witnessUserId'],
|
|
49
|
+
});
|
|
42
50
|
// One loaned item, as the contract was created with it: its catalog id and name. A contract keeps
|
|
43
51
|
// what it loaned even if the catalog later changes.
|
|
44
52
|
export const HardwareItemSchema = z.strictObject({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waivers-and-hardware.js","sourceRoot":"","sources":["../../src/doc-schemas/waivers-and-hardware.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,mGAAmG;AACnG,4BAA4B;AAE5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,aAAa,EACb,gCAAgC,EAChC,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,4BAA4B,GAC7B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qCAAqC,EACrC,sCAAsC,GACvC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,iCAAiC,EAAE,MAAM,sBAAsB,CAAC;AAEjG,iGAAiG;AACjG,gGAAgG;AAChG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,gBAAgB,EAAE,sBAAsB;IACxC,8FAA8F;IAC9F,2DAA2D;IAC3D,qBAAqB,EAAE,iCAAiC,CAAC,QAAQ,EAAE;IACnE,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC/B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,yFAAyF;IACzF,aAAa,EAAE,sBAAsB;IACrC,QAAQ,EAAE,aAAa;IACvB,8FAA8F;IAC9F,8FAA8F;IAC9F,0FAA0F;IAC1F,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC/B,aAAa,EAAE,YAAY,CAAC,QAAQ,EAAE;IACtC,gBAAgB,EAAE,4BAA4B,CAAC,QAAQ,EAAE;IACzD,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClD,CAAC;KACD,MAAM,CACL,CAAC,MAAM,EAAE,EAAE;IACT,MAAM,
|
|
1
|
+
{"version":3,"file":"waivers-and-hardware.js","sourceRoot":"","sources":["../../src/doc-schemas/waivers-and-hardware.ts"],"names":[],"mappings":"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","sourcesContent":["// Signed waivers and referee hardware contracts. Signatures are legal artifacts: a signed waiver\n// carries the exact wording the signer saw, as named snapshots. The templates they are signed from\n// are ./waiver-template.ts.\n\nimport { z } from 'zod';\nimport {\n epochMsSchema,\n hardwareLoanContractStatusSchema,\n leagueIdSchema,\n teamIdSchema,\n userIdSchema,\n waiverWitnessAuthoritySchema,\n} from './atoms.js';\nimport {\n PENDING_HARDWARE_LOAN_CONTRACT_STATUS,\n RETURNED_HARDWARE_LOAN_CONTRACT_STATUS,\n} from '../types/unions.js';\nimport { StorageObjectRefSchema } from './pending-media.js';\nimport { waiverTemplateIdSchema, waiverTemplateVersionNumberSchema } from './waiver-template.js';\n\n// `signedWaivers/{leagueId}_{userId}` — one signed waiver per player per league, never replaced,\n// moved, or deleted: a ghost's stays under the ghost's id after the ghost is removed or linked.\nexport const SignedWaiverSchema = z\n .object({\n leagueId: leagueIdSchema,\n userId: userIdSchema,\n waiverTemplateId: waiverTemplateIdSchema,\n // The published version of the template the signature was captured under. A record that names\n // no version has its wording snapshot as its whole record.\n waiverTemplateVersion: waiverTemplateVersionNumberSchema.optional(),\n waiverTitleSnapshot: z.string(),\n waiverTextSnapshot: z.string(),\n // The kept signature image. Read only through the signature-read callable, never by URL.\n signatureFile: StorageObjectRefSchema,\n signedAt: epochMsSchema,\n // A ghost player's waiver is signed by a witness for the ghost's team: the witness's account,\n // the authority they signed under, and the ghost's name at signing — a named snapshot, so the\n // record still says whom it was for after the ghost's public identity is gone (ARCH-103).\n teamId: teamIdSchema.optional(),\n witnessUserId: userIdSchema.optional(),\n witnessAuthority: waiverWitnessAuthoritySchema.optional(),\n subjectDisplayNameSnapshot: z.string().optional(),\n // A V1 witnessed waiver recorded the witness's name as it was at signing, and never the authority\n // or the ghost's name; the copy keeps that name as a named snapshot (ARCH-103) and guesses neither.\n witnessDisplayNameSnapshot: z.string().optional(),\n })\n .refine(\n (waiver) => {\n const full = [waiver.teamId, waiver.witnessUserId, waiver.witnessAuthority, waiver.subjectDisplayNameSnapshot];\n const legacy = [waiver.teamId, waiver.witnessUserId, waiver.witnessDisplayNameSnapshot];\n const present = (fields: readonly unknown[]) => fields.filter((field) => field !== undefined).length;\n if (present([...full, waiver.witnessDisplayNameSnapshot]) === 0) return true;\n if (present(full) === full.length) return waiver.witnessDisplayNameSnapshot === undefined;\n return (\n present(legacy) === legacy.length &&\n waiver.witnessAuthority === undefined &&\n waiver.subjectDisplayNameSnapshot === undefined\n );\n },\n {\n message:\n \"A ghost's waiver carries its team, witness, authority, and name together; or, copied from V1, its team, witness, and the witness's recorded name; or none of them.\",\n path: ['witnessUserId'],\n },\n );\nexport type SignedWaiver = z.infer<typeof SignedWaiverSchema>;\n\n// One loaned item, as the contract was created with it: its catalog id and name. A contract keeps\n// what it loaned even if the catalog later changes.\nexport const HardwareItemSchema = z.strictObject({\n id: z.string().min(1),\n name: z.string().min(1),\n});\nexport type HardwareItem = z.infer<typeof HardwareItemSchema>;\n\n// `hardwareLoanContracts/{contractId}` — equipment loaned to a referee: who holds it, what they hold,\n// and their signature on the loan agreement, a legal artifact. Names resolve from `publicUsers` at\n// read time (ARCH-103). `pending` until the referee signs; `loaned` from the signing, which keeps the\n// signature for good; `returned` once an admin records the equipment back, the signature retained.\nexport const HardwareLoanContractSchema = z\n .strictObject({\n refereeUserId: userIdSchema,\n createdByUserId: userIdSchema,\n hardware: z.array(HardwareItemSchema).min(1),\n status: hardwareLoanContractStatusSchema,\n // The kept signature image. Read only through the signature-read callables, never by URL.\n signatureFile: StorageObjectRefSchema.optional(),\n createdAt: epochMsSchema,\n loanedAt: epochMsSchema.optional(),\n returnedAt: epochMsSchema.optional(),\n })\n .refine(\n (contract) =>\n contract.status === PENDING_HARDWARE_LOAN_CONTRACT_STATUS\n ? contract.signatureFile === undefined && contract.loanedAt === undefined\n : contract.signatureFile !== undefined && contract.loanedAt !== undefined,\n { message: 'A contract carries its signature and loan date exactly once it is signed.', path: ['signatureFile'] },\n )\n .refine(\n (contract) => (contract.status === RETURNED_HARDWARE_LOAN_CONTRACT_STATUS) === (contract.returnedAt !== undefined),\n { message: 'A contract carries its return date exactly while it is returned.', path: ['returnedAt'] },\n );\nexport type HardwareLoanContract = z.infer<typeof HardwareLoanContractSchema>;\n"]}
|
package/dist/ids/minted-ids.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const GHOST_USER_ID_PREFIX = "ghost_";
|
|
2
2
|
export declare function isGhostUserId(userId: string): boolean;
|
|
3
3
|
export declare function buildGhostUserId(nowMs: number, suffix: string): string;
|
|
4
|
+
export declare function buildGhostUserIdForRequest(requestId: string): string;
|
|
4
5
|
export declare function buildSportGameId(nowMs: number, suffix: string): string;
|
|
5
6
|
export declare function buildScheduleWeekId(nowMs: number, suffix: string): string;
|
|
6
7
|
export declare const BYE_TEAM_ID = "bye";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minted-ids.d.ts","sourceRoot":"","sources":["../../src/ids/minted-ids.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAGD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzE;AAGD,eAAO,MAAM,WAAW,QAAQ,CAAC;AAGjC,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|
|
1
|
+
{"version":3,"file":"minted-ids.d.ts","sourceRoot":"","sources":["../../src/ids/minted-ids.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAKD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpE;AAGD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtE;AAKD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzE;AAGD,eAAO,MAAM,WAAW,QAAQ,CAAC;AAGjC,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|
package/dist/ids/minted-ids.js
CHANGED
|
@@ -10,6 +10,12 @@ export function isGhostUserId(userId) {
|
|
|
10
10
|
export function buildGhostUserId(nowMs, suffix) {
|
|
11
11
|
return `${GHOST_USER_ID_PREFIX}${nowMs}_${suffix}`;
|
|
12
12
|
}
|
|
13
|
+
// The ghost a ghost-add request creates: derived from the request id the client mints once per add
|
|
14
|
+
// and re-sends on every retry, so a retry names the same ghost instead of creating a second one. Its
|
|
15
|
+
// `req_` part never reads as a clock reading, so it cannot collide with a `buildGhostUserId` id.
|
|
16
|
+
export function buildGhostUserIdForRequest(requestId) {
|
|
17
|
+
return `${GHOST_USER_ID_PREFIX}req_${requestId}`;
|
|
18
|
+
}
|
|
13
19
|
// A new game's id, `{timestamp}_{suffix}`. A copied game keeps the id it was stored under.
|
|
14
20
|
export function buildSportGameId(nowMs, suffix) {
|
|
15
21
|
return `${nowMs}_${suffix}`;
|