@ttt-productions/q-core 0.1.4 → 0.1.6
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 +40 -9
- package/dist/constants/business.d.ts.map +1 -1
- package/dist/constants/business.js +41 -20
- package/dist/constants/business.js.map +1 -1
- package/dist/doc-schemas/admin-notifications.d.ts +1 -1
- package/dist/doc-schemas/award-group-grant.d.ts +60 -0
- package/dist/doc-schemas/award-group-grant.d.ts.map +1 -0
- package/dist/doc-schemas/award-group-grant.js +72 -0
- package/dist/doc-schemas/award-group-grant.js.map +1 -0
- package/dist/doc-schemas/index.d.ts +1 -0
- package/dist/doc-schemas/index.d.ts.map +1 -1
- package/dist/doc-schemas/index.js +1 -0
- package/dist/doc-schemas/index.js.map +1 -1
- package/dist/doc-schemas/migration-console.d.ts +3 -3
- package/dist/doc-schemas/registry.d.ts +50 -12
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/doc-schemas/registry.js +5 -0
- package/dist/doc-schemas/registry.js.map +1 -1
- package/dist/doc-schemas/stats-operation.d.ts +18 -18
- package/dist/ids/award-grant-ids.d.ts +9 -0
- package/dist/ids/award-grant-ids.d.ts.map +1 -0
- package/dist/ids/award-grant-ids.js +17 -0
- package/dist/ids/award-grant-ids.js.map +1 -0
- package/dist/ids/index.d.ts +1 -0
- package/dist/ids/index.d.ts.map +1 -1
- package/dist/ids/index.js +1 -0
- package/dist/ids/index.js.map +1 -1
- package/dist/paths/collection-groups.d.ts +1 -0
- package/dist/paths/collection-groups.d.ts.map +1 -1
- package/dist/paths/collection-groups.js +3 -1
- package/dist/paths/collection-groups.js.map +1 -1
- package/dist/paths/collection-refs.d.ts +1 -0
- package/dist/paths/collection-refs.d.ts.map +1 -1
- package/dist/paths/collection-refs.js +1 -0
- package/dist/paths/collection-refs.js.map +1 -1
- package/dist/paths/collections.d.ts +5 -0
- package/dist/paths/collections.d.ts.map +1 -1
- package/dist/paths/collections.js +8 -0
- package/dist/paths/collections.js.map +1 -1
- package/dist/paths/path-builders.d.ts +3 -0
- package/dist/paths/path-builders.d.ts.map +1 -1
- package/dist/paths/path-builders.js +13 -1
- package/dist/paths/path-builders.js.map +1 -1
- package/dist/schemas/admin-notifications.d.ts +1 -1
- package/dist/schemas/awards.d.ts +94 -2
- package/dist/schemas/awards.d.ts.map +1 -1
- package/dist/schemas/awards.js +49 -9
- package/dist/schemas/awards.js.map +1 -1
- package/dist/schemas/leagues.d.ts +2 -2
- package/dist/schemas/migration-console.d.ts +7 -7
- package/dist/types/unions.d.ts +8 -0
- package/dist/types/unions.d.ts.map +1 -1
- package/dist/types/unions.js +12 -2
- package/dist/types/unions.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,7 +10,6 @@ export declare const MIN_LEAGUE_TITLE_LENGTH = 3;
|
|
|
10
10
|
export declare const MAX_LEAGUE_TITLE_LENGTH = 100;
|
|
11
11
|
export declare const MIN_LEAGUE_DESCRIPTION_LENGTH = 10;
|
|
12
12
|
export declare const MAX_LEAGUE_DESCRIPTION_LENGTH = 5000;
|
|
13
|
-
export declare const MAX_PLAYOFF_CUTOFF = 100;
|
|
14
13
|
export declare const HARDWARE_CATALOG: readonly [{
|
|
15
14
|
readonly id: "ipad";
|
|
16
15
|
readonly name: "iPad";
|
|
@@ -22,8 +21,8 @@ export type HardwareCatalogItemId = (typeof HARDWARE_CATALOG)[number]['id'];
|
|
|
22
21
|
export declare const HARDWARE_CATALOG_ITEM_IDS: [HardwareCatalogItemId, ...HardwareCatalogItemId[]];
|
|
23
22
|
export declare const MIN_AWARD_NAME_LENGTH = 3;
|
|
24
23
|
export declare const MAX_AWARD_NAME_LENGTH = 60;
|
|
25
|
-
export declare const MAX_AWARD_GRANT_RECIPIENTS = 200;
|
|
26
24
|
export declare const MAX_AWARD_GRANT_TARGETS = 20;
|
|
25
|
+
export declare const AWARD_GROUP_GRANT_PAGE_SIZE = 100;
|
|
27
26
|
export declare const MIN_REPAIR_REASON_LENGTH = 3;
|
|
28
27
|
export declare const MAX_REPAIR_REASON_LENGTH = 500;
|
|
29
28
|
export declare const MAX_ADMIN_LIST_CHANGES = 20;
|
|
@@ -43,19 +42,51 @@ export declare const MAX_GAME_LOCATION_SUB_LOCATIONS = 50;
|
|
|
43
42
|
export declare const MAX_GAME_LOCATION_SUB_LOCATION_LENGTH = 60;
|
|
44
43
|
export declare const MAX_GAME_LOCATION_MEMO_LENGTH = 500;
|
|
45
44
|
export declare const MAX_SCHEDULE_WEEK_TITLE_LENGTH = 100;
|
|
46
|
-
export declare const MAX_SCHEDULE_WEEK_GAMES = 20;
|
|
47
45
|
export declare const LEAGUE_TIME_ZONE = "America/New_York";
|
|
48
46
|
export declare const MAX_GAME_MEMO_LENGTH = 30;
|
|
49
47
|
export declare const countCapReachedMessage: (subject: string, limit: number, noun: string) => string;
|
|
50
|
-
export declare const MAX_ACTIVE_TEAM_MEMBERS =
|
|
48
|
+
export declare const MAX_ACTIVE_TEAM_MEMBERS = 30;
|
|
51
49
|
export declare const TEAM_FULL_MESSAGE: string;
|
|
52
|
-
export declare const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM =
|
|
53
|
-
export declare const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM =
|
|
50
|
+
export declare const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = 30;
|
|
51
|
+
export declare const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 10;
|
|
54
52
|
export declare const MAX_ROSTER_ENTRIES_PER_TEAM: number;
|
|
55
|
-
export declare const MAX_TEAMS_PER_LEAGUE =
|
|
56
|
-
export declare const MAX_GAMES_PER_LEAGUE =
|
|
53
|
+
export declare const MAX_TEAMS_PER_LEAGUE = 40;
|
|
54
|
+
export declare const MAX_GAMES_PER_LEAGUE = 250;
|
|
57
55
|
export declare const LEAGUE_TEAMS_FULL_MESSAGE: string;
|
|
58
56
|
export declare const LEAGUE_GAMES_FULL_MESSAGE: string;
|
|
59
|
-
export declare const
|
|
57
|
+
export declare const MAX_SCHEDULE_WEEK_GAMES = 20;
|
|
58
|
+
export declare const SCHEDULE_WEEK_FULL_MESSAGE: string;
|
|
59
|
+
export declare const MAX_PLAYOFF_CUTOFF = 40;
|
|
60
|
+
export declare const MAX_STAT_EVENTS_PER_GAME = 1000;
|
|
60
61
|
export declare const GAME_STAT_LOG_FULL_MESSAGE: string;
|
|
62
|
+
export declare const CAPACITY_LIMITS: readonly [{
|
|
63
|
+
readonly key: "teamPlayers";
|
|
64
|
+
readonly label: "Players on a team, ghost players included";
|
|
65
|
+
readonly limit: 30;
|
|
66
|
+
}, {
|
|
67
|
+
readonly key: "gameSidePeople";
|
|
68
|
+
readonly label: "People on one side of one game: 30 players plus 10 who left the team after recording stats in it";
|
|
69
|
+
readonly limit: number;
|
|
70
|
+
}, {
|
|
71
|
+
readonly key: "leagueTeams";
|
|
72
|
+
readonly label: "Teams in a league";
|
|
73
|
+
readonly limit: 40;
|
|
74
|
+
}, {
|
|
75
|
+
readonly key: "leagueGames";
|
|
76
|
+
readonly label: "Games in a league, so also a team's games";
|
|
77
|
+
readonly limit: 250;
|
|
78
|
+
}, {
|
|
79
|
+
readonly key: "weekGames";
|
|
80
|
+
readonly label: "Games in one week of the schedule";
|
|
81
|
+
readonly limit: 20;
|
|
82
|
+
}, {
|
|
83
|
+
readonly key: "gameStats";
|
|
84
|
+
readonly label: "Stats recorded in one game";
|
|
85
|
+
readonly limit: 1000;
|
|
86
|
+
}, {
|
|
87
|
+
readonly key: "playoffCutoff";
|
|
88
|
+
readonly label: "Teams reaching the playoffs, at most the league's team limit";
|
|
89
|
+
readonly limit: 40;
|
|
90
|
+
}];
|
|
91
|
+
export type CapacityLimitKey = (typeof CAPACITY_LIMITS)[number]['key'];
|
|
61
92
|
//# sourceMappingURL=business.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"business.d.ts","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,oCAAoC,KAAK,CAAC;AACvD,eAAO,MAAM,oCAAoC,MAAM,CAAC;AACxD,eAAO,MAAM,kCAAkC,MAAM,CAAC;AAEtD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAGlD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"business.d.ts","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,9 +14,6 @@ export const MIN_LEAGUE_TITLE_LENGTH = 3;
|
|
|
14
14
|
export const MAX_LEAGUE_TITLE_LENGTH = 100;
|
|
15
15
|
export const MIN_LEAGUE_DESCRIPTION_LENGTH = 10;
|
|
16
16
|
export const MAX_LEAGUE_DESCRIPTION_LENGTH = 5000;
|
|
17
|
-
// How many teams in a pool reach the playoffs. The cap only bounds the input: no league comes near
|
|
18
|
-
// it, and a cutoff above a pool's team count simply admits every team.
|
|
19
|
-
export const MAX_PLAYOFF_CUTOFF = 100;
|
|
20
17
|
// The equipment a referee can be loaned. The catalog is this constant: adding an item is a code
|
|
21
18
|
// change, and a contract records each item's id and name as it was loaned.
|
|
22
19
|
export const HARDWARE_CATALOG = [
|
|
@@ -27,11 +24,12 @@ export const HARDWARE_CATALOG_ITEM_IDS = HARDWARE_CATALOG.map((item) => item.id)
|
|
|
27
24
|
// An award's name in the catalog.
|
|
28
25
|
export const MIN_AWARD_NAME_LENGTH = 3;
|
|
29
26
|
export const MAX_AWARD_NAME_LENGTH = 60;
|
|
30
|
-
// The most
|
|
31
|
-
// members: every grant of one call commits in one transaction, beside its audit events.
|
|
32
|
-
export const MAX_AWARD_GRANT_RECIPIENTS = 200;
|
|
33
|
-
// The most users, teams, or leagues one award grant call may name in each list.
|
|
27
|
+
// The most accounts one award grant call may name in each list.
|
|
34
28
|
export const MAX_AWARD_GRANT_TARGETS = 20;
|
|
29
|
+
// The people one page of a team's or league's award grant reaches. A group grant has no limit on
|
|
30
|
+
// people; each page commits on its own, and a person takes at most four writes in it — the profile,
|
|
31
|
+
// its public mirror, the person's record on the grant, and the audit event — beside the grant record.
|
|
32
|
+
export const AWARD_GROUP_GRANT_PAGE_SIZE = 100;
|
|
35
33
|
// The reason an admin gives for a repair action — a backfill, a recalculation, a reopen — recorded on
|
|
36
34
|
// its audit event (BACKEND-212).
|
|
37
35
|
export const MIN_REPAIR_REASON_LENGTH = 3;
|
|
@@ -62,36 +60,59 @@ export const MAX_GAME_LOCATION_STREET_ADDRESS_LENGTH = 200;
|
|
|
62
60
|
export const MAX_GAME_LOCATION_SUB_LOCATIONS = 50;
|
|
63
61
|
export const MAX_GAME_LOCATION_SUB_LOCATION_LENGTH = 60;
|
|
64
62
|
export const MAX_GAME_LOCATION_MEMO_LENGTH = 500;
|
|
65
|
-
// A week of the schedule
|
|
66
|
-
// teams' rosters in the same transaction, so a larger week is saved in parts.
|
|
63
|
+
// A week of the schedule's title.
|
|
67
64
|
export const MAX_SCHEDULE_WEEK_TITLE_LENGTH = 100;
|
|
68
|
-
export const MAX_SCHEDULE_WEEK_GAMES = 20;
|
|
69
65
|
// The timezone a game's `dayKey` (its local calendar date) is computed in.
|
|
70
66
|
export const LEAGUE_TIME_ZONE = 'America/New_York';
|
|
71
67
|
// A scorer's note on one person in a game ("red shirt", "#9").
|
|
72
68
|
export const MAX_GAME_MEMO_LENGTH = 30;
|
|
73
69
|
// How a refusal at a count cap reads: the thing that is full, its limit, and what it holds.
|
|
74
70
|
export const countCapReachedMessage = (subject, limit, noun) => `${subject} already has the maximum of ${limit} ${noun}.`;
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
// The capacity limits: how many players, teams, games and stats Q-Sports holds. Each is enforced
|
|
72
|
+
// where the thing is created, inside that creation's transaction, so every read of a whole set fits
|
|
73
|
+
// one bound and every internal bound sized from one derives from it here.
|
|
74
|
+
// A team's size, ghost players included. Every way onto a team is refused at this many active
|
|
75
|
+
// members, so a game's roster can always be seeded and checked in one read.
|
|
76
|
+
export const MAX_ACTIVE_TEAM_MEMBERS = 30;
|
|
77
|
+
export const TEAM_FULL_MESSAGE = countCapReachedMessage('This team', MAX_ACTIVE_TEAM_MEMBERS, 'players');
|
|
79
78
|
// The memberships one game-roster seed reads for a team: every membership is active, so the cap.
|
|
80
79
|
export const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;
|
|
81
80
|
// Departed players a team's side of an open game may keep beside its members: a player who recorded
|
|
82
81
|
// stats in the game keeps their entry after leaving the team.
|
|
83
|
-
export const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM =
|
|
82
|
+
export const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 10;
|
|
84
83
|
// The entries one team's side of a game may hold, so a reconcile or finalize reads them in one page.
|
|
85
84
|
export const MAX_ROSTER_ENTRIES_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS + MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM;
|
|
86
85
|
// A league's size. Standings, schedules, and rankings need a league's complete set of teams and
|
|
87
|
-
// games, so creation is refused at these caps rather than any read being cut short.
|
|
88
|
-
//
|
|
89
|
-
export const MAX_TEAMS_PER_LEAGUE =
|
|
90
|
-
export const MAX_GAMES_PER_LEAGUE =
|
|
86
|
+
// games, so creation is refused at these caps rather than any read being cut short. A team's games
|
|
87
|
+
// are its league's, so the game cap bounds them too.
|
|
88
|
+
export const MAX_TEAMS_PER_LEAGUE = 40;
|
|
89
|
+
export const MAX_GAMES_PER_LEAGUE = 250;
|
|
91
90
|
export const LEAGUE_TEAMS_FULL_MESSAGE = countCapReachedMessage('This league', MAX_TEAMS_PER_LEAGUE, 'teams');
|
|
92
91
|
export const LEAGUE_GAMES_FULL_MESSAGE = countCapReachedMessage('This league', MAX_GAMES_PER_LEAGUE, 'games');
|
|
92
|
+
// The most games one week of the schedule holds, counting the games it already has: creating a week
|
|
93
|
+
// or adding a game to one is refused past it.
|
|
94
|
+
export const MAX_SCHEDULE_WEEK_GAMES = 20;
|
|
95
|
+
export const SCHEDULE_WEEK_FULL_MESSAGE = countCapReachedMessage('This week', MAX_SCHEDULE_WEEK_GAMES, 'games');
|
|
96
|
+
// How many teams in a pool reach the playoffs: at most every team a league can hold. A cutoff above a
|
|
97
|
+
// pool's team count simply admits every team.
|
|
98
|
+
export const MAX_PLAYOFF_CUTOFF = MAX_TEAMS_PER_LEAGUE;
|
|
93
99
|
// A game's stat log. A write that would take a game's `statEventSequence` past it is refused with
|
|
94
100
|
// nothing written, which also bounds the game's live play-by-play.
|
|
95
|
-
export const MAX_STAT_EVENTS_PER_GAME =
|
|
101
|
+
export const MAX_STAT_EVENTS_PER_GAME = 1000;
|
|
96
102
|
export const GAME_STAT_LOG_FULL_MESSAGE = countCapReachedMessage('This game', MAX_STAT_EVENTS_PER_GAME, 'recorded stats');
|
|
103
|
+
// Every capacity limit as an admin reads it, in the order the Limits card lists them. Each value is
|
|
104
|
+
// the constant the server enforces, so the card and every refusal name the same number.
|
|
105
|
+
export const CAPACITY_LIMITS = [
|
|
106
|
+
{ key: 'teamPlayers', label: 'Players on a team, ghost players included', limit: MAX_ACTIVE_TEAM_MEMBERS },
|
|
107
|
+
{
|
|
108
|
+
key: 'gameSidePeople',
|
|
109
|
+
label: `People on one side of one game: ${MAX_ACTIVE_TEAM_MEMBERS} players plus ${MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM} who left the team after recording stats in it`,
|
|
110
|
+
limit: MAX_ROSTER_ENTRIES_PER_TEAM,
|
|
111
|
+
},
|
|
112
|
+
{ key: 'leagueTeams', label: 'Teams in a league', limit: MAX_TEAMS_PER_LEAGUE },
|
|
113
|
+
{ key: 'leagueGames', label: "Games in a league, so also a team's games", limit: MAX_GAMES_PER_LEAGUE },
|
|
114
|
+
{ key: 'weekGames', label: 'Games in one week of the schedule', limit: MAX_SCHEDULE_WEEK_GAMES },
|
|
115
|
+
{ key: 'gameStats', label: 'Stats recorded in one game', limit: MAX_STAT_EVENTS_PER_GAME },
|
|
116
|
+
{ key: 'playoffCutoff', label: "Teams reaching the playoffs, at most the league's team limit", limit: MAX_PLAYOFF_CUTOFF },
|
|
117
|
+
];
|
|
97
118
|
//# sourceMappingURL=business.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"business.js","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"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","sourcesContent":["// Business limits and policy values both app roots enforce. A form reads these for its\n// `maxLength` / zod bound and the callable's input schema reads the same constant (ENG-005).\n\n// Display names, team names, and ghost player names share one length policy.\nexport const MIN_DISPLAY_NAME_LENGTH = 3;\nexport const MAX_DISPLAY_NAME_LENGTH = 50;\n// The shortest password an account takes: Firebase Auth's own floor.\nexport const PASSWORD_MIN_LENGTH = 6;\nexport const MIN_TEAM_NAME_LENGTH = 3;\nexport const MAX_TEAM_NAME_LENGTH = 50;\n\nexport const MIN_TEAM_JOIN_REQUEST_MESSAGE_LENGTH = 10;\nexport const MAX_TEAM_JOIN_REQUEST_MESSAGE_LENGTH = 500;\nexport const MAX_TEAM_INVITATION_MESSAGE_LENGTH = 500;\n\nexport const MIN_LEAGUE_TITLE_LENGTH = 3;\nexport const MAX_LEAGUE_TITLE_LENGTH = 100;\nexport const MIN_LEAGUE_DESCRIPTION_LENGTH = 10;\nexport const MAX_LEAGUE_DESCRIPTION_LENGTH = 5000;\n// How many teams in a pool reach the playoffs. The cap only bounds the input: no league comes near\n// it, and a cutoff above a pool's team count simply admits every team.\nexport const MAX_PLAYOFF_CUTOFF = 100;\n// The equipment a referee can be loaned. The catalog is this constant: adding an item is a code\n// change, and a contract records each item's id and name as it was loaned.\nexport const HARDWARE_CATALOG = [\n { id: 'ipad', name: 'iPad' },\n { id: 'ipad-charger', name: 'iPad Charger' },\n] as const;\nexport type HardwareCatalogItemId = (typeof HARDWARE_CATALOG)[number]['id'];\nexport const HARDWARE_CATALOG_ITEM_IDS = HARDWARE_CATALOG.map((item) => item.id) as [\n HardwareCatalogItemId,\n ...HardwareCatalogItemId[],\n];\n\n// An award's name in the catalog.\nexport const MIN_AWARD_NAME_LENGTH = 3;\nexport const MAX_AWARD_NAME_LENGTH = 60;\n\n// The most people one award grant may reach once its teams and leagues are resolved to their active\n// members: every grant of one call commits in one transaction, beside its audit events.\nexport const MAX_AWARD_GRANT_RECIPIENTS = 200;\n// The most users, teams, or leagues one award grant call may name in each list.\nexport const MAX_AWARD_GRANT_TARGETS = 20;\n\n// The reason an admin gives for a repair action — a backfill, a recalculation, a reopen — recorded on\n// its audit event (BACKEND-212).\nexport const MIN_REPAIR_REASON_LENGTH = 3;\nexport const MAX_REPAIR_REASON_LENGTH = 500;\n\n// The most uids one `updateAdminList` call may grant or revoke per list.\nexport const MAX_ADMIN_LIST_CHANGES = 20;\n\n// A team may be created in a league until this many days after the league's start date.\nexport const TEAM_CREATION_CUTOFF_DAYS = 14;\n\n// Contact phone numbers are stored as typed, bounded only in length.\nexport const MAX_CONTACT_PHONE_LENGTH = 30;\n\n// The failure a roster obligation records when a reconciliation run fails, cut to this length.\nexport const MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH = 500;\n\n// `_appConfig/app` operator messages.\nexport const MAX_MAINTENANCE_MESSAGE_LENGTH = 2000;\nexport const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;\n// `_appConfig/app.appVersion` — the version a live client compares itself against.\nexport const MAX_APP_VERSION_LENGTH = 64;\n\n// `_appConfig/landingPage` copy.\nexport const MAX_LANDING_HERO_TITLE_LENGTH = 200;\nexport const MAX_LANDING_ABOUT_TEXT_LENGTH = 5000;\n\n// Waiver template wording. A signed waiver carries its own copy of the title and text, so the text\n// cap also bounds every signature document.\nexport const MAX_WAIVER_TEMPLATE_TITLE_LENGTH = 120;\nexport const MAX_WAIVER_TEMPLATE_TEXT_LENGTH = 20000;\n\n// Game locations: the venue, its address, the courts or sheets inside it, and the directions memo.\nexport const MAX_GAME_LOCATION_NAME_LENGTH = 100;\nexport const MAX_GAME_LOCATION_STREET_ADDRESS_LENGTH = 200;\nexport const MAX_GAME_LOCATION_SUB_LOCATIONS = 50;\nexport const MAX_GAME_LOCATION_SUB_LOCATION_LENGTH = 60;\nexport const MAX_GAME_LOCATION_MEMO_LENGTH = 500;\n\n// A week of the schedule: its title, and the games one save creates with it — each seeded with its\n// teams' rosters in the same transaction, so a larger week is saved in parts.\nexport const MAX_SCHEDULE_WEEK_TITLE_LENGTH = 100;\nexport const MAX_SCHEDULE_WEEK_GAMES = 20;\n\n// The timezone a game's `dayKey` (its local calendar date) is computed in.\nexport const LEAGUE_TIME_ZONE = 'America/New_York';\n\n// A scorer's note on one person in a game (\"red shirt\", \"#9\").\nexport const MAX_GAME_MEMO_LENGTH = 30;\n\n\n// How a refusal at a count cap reads: the thing that is full, its limit, and what it holds.\nexport const countCapReachedMessage = (subject: string, limit: number, noun: string): string =>\n `${subject} already has the maximum of ${limit} ${noun}.`;\n\n// A team's size. Every way onto a team is refused at this many active members, inside the\n// admission's transaction, so a game's roster can always be seeded and checked in one read.\nexport const MAX_ACTIVE_TEAM_MEMBERS = 100;\nexport const TEAM_FULL_MESSAGE = countCapReachedMessage('This team', MAX_ACTIVE_TEAM_MEMBERS, 'members');\n// The memberships one game-roster seed reads for a team: every membership is active, so the cap.\nexport const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;\n// Departed players a team's side of an open game may keep beside its members: a player who recorded\n// stats in the game keeps their entry after leaving the team.\nexport const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 20;\n// The entries one team's side of a game may hold, so a reconcile or finalize reads them in one page.\nexport const MAX_ROSTER_ENTRIES_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS + MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM;\n\n// A league's size. Standings, schedules, and rankings need a league's complete set of teams and\n// games, so creation is refused at these caps rather than any read being cut short. The team cap is\n// also the most teams one mode switch rewrites in its one transaction.\nexport const MAX_TEAMS_PER_LEAGUE = 498;\nexport const MAX_GAMES_PER_LEAGUE = 1000;\nexport const LEAGUE_TEAMS_FULL_MESSAGE = countCapReachedMessage('This league', MAX_TEAMS_PER_LEAGUE, 'teams');\nexport const LEAGUE_GAMES_FULL_MESSAGE = countCapReachedMessage('This league', MAX_GAMES_PER_LEAGUE, 'games');\n\n// A game's stat log. A write that would take a game's `statEventSequence` past it is refused with\n// nothing written, which also bounds the game's live play-by-play.\nexport const MAX_STAT_EVENTS_PER_GAME = 5000;\nexport const GAME_STAT_LOG_FULL_MESSAGE = countCapReachedMessage('This game', MAX_STAT_EVENTS_PER_GAME, 'recorded stats');\n"]}
|
|
1
|
+
{"version":3,"file":"business.js","sourceRoot":"","sources":["../../src/constants/business.ts"],"names":[],"mappings":"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","sourcesContent":["// Business limits and policy values both app roots enforce. A form reads these for its\n// `maxLength` / zod bound and the callable's input schema reads the same constant (ENG-005).\n\n// Display names, team names, and ghost player names share one length policy.\nexport const MIN_DISPLAY_NAME_LENGTH = 3;\nexport const MAX_DISPLAY_NAME_LENGTH = 50;\n// The shortest password an account takes: Firebase Auth's own floor.\nexport const PASSWORD_MIN_LENGTH = 6;\nexport const MIN_TEAM_NAME_LENGTH = 3;\nexport const MAX_TEAM_NAME_LENGTH = 50;\n\nexport const MIN_TEAM_JOIN_REQUEST_MESSAGE_LENGTH = 10;\nexport const MAX_TEAM_JOIN_REQUEST_MESSAGE_LENGTH = 500;\nexport const MAX_TEAM_INVITATION_MESSAGE_LENGTH = 500;\n\nexport const MIN_LEAGUE_TITLE_LENGTH = 3;\nexport const MAX_LEAGUE_TITLE_LENGTH = 100;\nexport const MIN_LEAGUE_DESCRIPTION_LENGTH = 10;\nexport const MAX_LEAGUE_DESCRIPTION_LENGTH = 5000;\n// The equipment a referee can be loaned. The catalog is this constant: adding an item is a code\n// change, and a contract records each item's id and name as it was loaned.\nexport const HARDWARE_CATALOG = [\n { id: 'ipad', name: 'iPad' },\n { id: 'ipad-charger', name: 'iPad Charger' },\n] as const;\nexport type HardwareCatalogItemId = (typeof HARDWARE_CATALOG)[number]['id'];\nexport const HARDWARE_CATALOG_ITEM_IDS = HARDWARE_CATALOG.map((item) => item.id) as [\n HardwareCatalogItemId,\n ...HardwareCatalogItemId[],\n];\n\n// An award's name in the catalog.\nexport const MIN_AWARD_NAME_LENGTH = 3;\nexport const MAX_AWARD_NAME_LENGTH = 60;\n\n// The most accounts one award grant call may name in each list.\nexport const MAX_AWARD_GRANT_TARGETS = 20;\n// The people one page of a team's or league's award grant reaches. A group grant has no limit on\n// people; each page commits on its own, and a person takes at most four writes in it — the profile,\n// its public mirror, the person's record on the grant, and the audit event — beside the grant record.\nexport const AWARD_GROUP_GRANT_PAGE_SIZE = 100;\n\n// The reason an admin gives for a repair action — a backfill, a recalculation, a reopen — recorded on\n// its audit event (BACKEND-212).\nexport const MIN_REPAIR_REASON_LENGTH = 3;\nexport const MAX_REPAIR_REASON_LENGTH = 500;\n\n// The most uids one `updateAdminList` call may grant or revoke per list.\nexport const MAX_ADMIN_LIST_CHANGES = 20;\n\n// A team may be created in a league until this many days after the league's start date.\nexport const TEAM_CREATION_CUTOFF_DAYS = 14;\n\n// Contact phone numbers are stored as typed, bounded only in length.\nexport const MAX_CONTACT_PHONE_LENGTH = 30;\n\n// The failure a roster obligation records when a reconciliation run fails, cut to this length.\nexport const MAX_ROSTER_SYNC_FAILURE_MESSAGE_LENGTH = 500;\n\n// `_appConfig/app` operator messages.\nexport const MAX_MAINTENANCE_MESSAGE_LENGTH = 2000;\nexport const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;\n// `_appConfig/app.appVersion` — the version a live client compares itself against.\nexport const MAX_APP_VERSION_LENGTH = 64;\n\n// `_appConfig/landingPage` copy.\nexport const MAX_LANDING_HERO_TITLE_LENGTH = 200;\nexport const MAX_LANDING_ABOUT_TEXT_LENGTH = 5000;\n\n// Waiver template wording. A signed waiver carries its own copy of the title and text, so the text\n// cap also bounds every signature document.\nexport const MAX_WAIVER_TEMPLATE_TITLE_LENGTH = 120;\nexport const MAX_WAIVER_TEMPLATE_TEXT_LENGTH = 20000;\n\n// Game locations: the venue, its address, the courts or sheets inside it, and the directions memo.\nexport const MAX_GAME_LOCATION_NAME_LENGTH = 100;\nexport const MAX_GAME_LOCATION_STREET_ADDRESS_LENGTH = 200;\nexport const MAX_GAME_LOCATION_SUB_LOCATIONS = 50;\nexport const MAX_GAME_LOCATION_SUB_LOCATION_LENGTH = 60;\nexport const MAX_GAME_LOCATION_MEMO_LENGTH = 500;\n\n// A week of the schedule's title.\nexport const MAX_SCHEDULE_WEEK_TITLE_LENGTH = 100;\n\n// The timezone a game's `dayKey` (its local calendar date) is computed in.\nexport const LEAGUE_TIME_ZONE = 'America/New_York';\n\n// A scorer's note on one person in a game (\"red shirt\", \"#9\").\nexport const MAX_GAME_MEMO_LENGTH = 30;\n\n\n// How a refusal at a count cap reads: the thing that is full, its limit, and what it holds.\nexport const countCapReachedMessage = (subject: string, limit: number, noun: string): string =>\n `${subject} already has the maximum of ${limit} ${noun}.`;\n\n// The capacity limits: how many players, teams, games and stats Q-Sports holds. Each is enforced\n// where the thing is created, inside that creation's transaction, so every read of a whole set fits\n// one bound and every internal bound sized from one derives from it here.\n\n// A team's size, ghost players included. Every way onto a team is refused at this many active\n// members, so a game's roster can always be seeded and checked in one read.\nexport const MAX_ACTIVE_TEAM_MEMBERS = 30;\nexport const TEAM_FULL_MESSAGE = countCapReachedMessage('This team', MAX_ACTIVE_TEAM_MEMBERS, 'players');\n// The memberships one game-roster seed reads for a team: every membership is active, so the cap.\nexport const MAX_ROSTER_SEED_MEMBERSHIPS_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS;\n// Departed players a team's side of an open game may keep beside its members: a player who recorded\n// stats in the game keeps their entry after leaving the team.\nexport const MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM = 10;\n// The entries one team's side of a game may hold, so a reconcile or finalize reads them in one page.\nexport const MAX_ROSTER_ENTRIES_PER_TEAM = MAX_ACTIVE_TEAM_MEMBERS + MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM;\n\n// A league's size. Standings, schedules, and rankings need a league's complete set of teams and\n// games, so creation is refused at these caps rather than any read being cut short. A team's games\n// are its league's, so the game cap bounds them too.\nexport const MAX_TEAMS_PER_LEAGUE = 40;\nexport const MAX_GAMES_PER_LEAGUE = 250;\nexport const LEAGUE_TEAMS_FULL_MESSAGE = countCapReachedMessage('This league', MAX_TEAMS_PER_LEAGUE, 'teams');\nexport const LEAGUE_GAMES_FULL_MESSAGE = countCapReachedMessage('This league', MAX_GAMES_PER_LEAGUE, 'games');\n\n// The most games one week of the schedule holds, counting the games it already has: creating a week\n// or adding a game to one is refused past it.\nexport const MAX_SCHEDULE_WEEK_GAMES = 20;\nexport const SCHEDULE_WEEK_FULL_MESSAGE = countCapReachedMessage('This week', MAX_SCHEDULE_WEEK_GAMES, 'games');\n\n// How many teams in a pool reach the playoffs: at most every team a league can hold. A cutoff above a\n// pool's team count simply admits every team.\nexport const MAX_PLAYOFF_CUTOFF = MAX_TEAMS_PER_LEAGUE;\n\n// A game's stat log. A write that would take a game's `statEventSequence` past it is refused with\n// nothing written, which also bounds the game's live play-by-play.\nexport const MAX_STAT_EVENTS_PER_GAME = 1000;\nexport const GAME_STAT_LOG_FULL_MESSAGE = countCapReachedMessage('This game', MAX_STAT_EVENTS_PER_GAME, 'recorded stats');\n\n// Every capacity limit as an admin reads it, in the order the Limits card lists them. Each value is\n// the constant the server enforces, so the card and every refusal name the same number.\nexport const CAPACITY_LIMITS = [\n { key: 'teamPlayers', label: 'Players on a team, ghost players included', limit: MAX_ACTIVE_TEAM_MEMBERS },\n {\n key: 'gameSidePeople',\n label: `People on one side of one game: ${MAX_ACTIVE_TEAM_MEMBERS} players plus ${MAX_DEPARTED_ROSTER_ENTRIES_PER_TEAM} who left the team after recording stats in it`,\n limit: MAX_ROSTER_ENTRIES_PER_TEAM,\n },\n { key: 'leagueTeams', label: 'Teams in a league', limit: MAX_TEAMS_PER_LEAGUE },\n { key: 'leagueGames', label: \"Games in a league, so also a team's games\", limit: MAX_GAMES_PER_LEAGUE },\n { key: 'weekGames', label: 'Games in one week of the schedule', limit: MAX_SCHEDULE_WEEK_GAMES },\n { key: 'gameStats', label: 'Stats recorded in one game', limit: MAX_STAT_EVENTS_PER_GAME },\n { key: 'playoffCutoff', label: \"Teams reaching the playoffs, at most the league's team limit\", limit: MAX_PLAYOFF_CUTOFF },\n] as const satisfies readonly { key: string; label: string; limit: number }[];\nexport type CapacityLimitKey = (typeof CAPACITY_LIMITS)[number]['key'];\n"]}
|
|
@@ -134,8 +134,8 @@ export declare const NotificationArchiveAllJobSchema: z.ZodObject<{
|
|
|
134
134
|
userId: z.ZodString;
|
|
135
135
|
category: z.ZodLiteral<"admin">;
|
|
136
136
|
state: z.ZodEnum<{
|
|
137
|
-
failed: "failed";
|
|
138
137
|
complete: "complete";
|
|
138
|
+
failed: "failed";
|
|
139
139
|
"in-progress": "in-progress";
|
|
140
140
|
incomplete: "incomplete";
|
|
141
141
|
}>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const awardGroupTypeSchema: z.ZodEnum<{
|
|
3
|
+
team: "team";
|
|
4
|
+
league: "league";
|
|
5
|
+
}>;
|
|
6
|
+
export declare const awardGroupGrantActionSchema: z.ZodEnum<{
|
|
7
|
+
grant: "grant";
|
|
8
|
+
revoke: "revoke";
|
|
9
|
+
}>;
|
|
10
|
+
export declare const awardGroupGrantStatusSchema: z.ZodEnum<{
|
|
11
|
+
pending: "pending";
|
|
12
|
+
complete: "complete";
|
|
13
|
+
}>;
|
|
14
|
+
export declare const awardGroupGrantDecisionSchema: z.ZodNumber;
|
|
15
|
+
export declare const AwardGroupGrantSchema: z.ZodObject<{
|
|
16
|
+
grantId: z.ZodString;
|
|
17
|
+
action: z.ZodEnum<{
|
|
18
|
+
grant: "grant";
|
|
19
|
+
revoke: "revoke";
|
|
20
|
+
}>;
|
|
21
|
+
awardId: z.ZodString;
|
|
22
|
+
groupType: z.ZodEnum<{
|
|
23
|
+
team: "team";
|
|
24
|
+
league: "league";
|
|
25
|
+
}>;
|
|
26
|
+
groupId: z.ZodString;
|
|
27
|
+
targetKey: z.ZodString;
|
|
28
|
+
decision: z.ZodNumber;
|
|
29
|
+
actorUid: z.ZodString;
|
|
30
|
+
status: z.ZodEnum<{
|
|
31
|
+
pending: "pending";
|
|
32
|
+
complete: "complete";
|
|
33
|
+
}>;
|
|
34
|
+
createdAt: z.ZodNumber;
|
|
35
|
+
completedAt: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
attemptCount: z.ZodNumber;
|
|
37
|
+
nextAttemptAt: z.ZodNumber;
|
|
38
|
+
lastError: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
export type AwardGroupGrant = z.infer<typeof AwardGroupGrantSchema>;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a request opens a new decision on an award for a group, given the group's latest decision
|
|
43
|
+
* (`null` when it has none): a grant opens unless the latest is a grant, and a take-back opens only
|
|
44
|
+
* when it is. A request the latest decision already settles opens nothing. The server applies it in
|
|
45
|
+
* the transaction that opens the decision; the admin surface offers only the request it opens.
|
|
46
|
+
*/
|
|
47
|
+
export declare function awardGroupGrantOpens(latest: Pick<AwardGroupGrant, 'action'> | null, action: AwardGroupGrant['action']): boolean;
|
|
48
|
+
export declare const AwardGroupGrantPersonSchema: z.ZodObject<{
|
|
49
|
+
userId: z.ZodString;
|
|
50
|
+
heldBefore: z.ZodBoolean;
|
|
51
|
+
recordedAt: z.ZodNumber;
|
|
52
|
+
revoked: z.ZodBoolean;
|
|
53
|
+
revokedAt: z.ZodOptional<z.ZodNumber>;
|
|
54
|
+
revokeSkipped: z.ZodOptional<z.ZodEnum<{
|
|
55
|
+
heldBefore: "heldBefore";
|
|
56
|
+
heldByAnotherGrant: "heldByAnotherGrant";
|
|
57
|
+
}>>;
|
|
58
|
+
}, z.core.$strict>;
|
|
59
|
+
export type AwardGroupGrantPerson = z.infer<typeof AwardGroupGrantPersonSchema>;
|
|
60
|
+
//# sourceMappingURL=award-group-grant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"award-group-grant.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/award-group-grant.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,oBAAoB;;;EAAgC,CAAC;AAClE,eAAO,MAAM,2BAA2B;;;EAAwC,CAAC;AACjF,eAAO,MAAM,2BAA2B;;;EAAwC,CAAC;AAGjF,eAAO,MAAM,6BAA6B,aAAiB,CAAC;AAE5D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;kBA6B9B,CAAC;AACL,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,GAAG,IAAI,EAC9C,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,GAChC,OAAO,CAET;AAMD,eAAO,MAAM,2BAA2B;;;;;;;;;;kBAOtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// `awardGroupGrants/{grantId}` — one decision on one award for one group (a team, or a whole league):
|
|
2
|
+
// grant the award to the group's active members, or take back what the group's grants gave. The
|
|
3
|
+
// people are reached a page at a time, after the decision opens in its own small transaction. Written
|
|
4
|
+
// only by Cloud Functions; an admin reads a decision through the status callable.
|
|
5
|
+
//
|
|
6
|
+
// A grant records each person in `awardGroupGrantPeople` before it changes their profile, so a re-run
|
|
7
|
+
// after any interruption finds every recorded person and finishes them, and its revoke reverses exactly
|
|
8
|
+
// the people it gave the award to. Someone who already held the award is recorded as holding it before,
|
|
9
|
+
// and a revoke leaves them holding it. `status` stays `pending` until every page is done; the retry
|
|
10
|
+
// ledger lets a decision that keeps failing back off instead of holding the resume's window.
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { buildAwardGroupGrantId, buildAwardGroupGrantTargetKey } from '../ids/award-grant-ids.js';
|
|
13
|
+
import { AWARD_GROUP_GRANT_ACTION_KEYS, AWARD_GROUP_GRANT_STATUS_KEYS, AWARD_GROUP_REVOKE_SKIP_KEYS, AWARD_GROUP_TYPE_KEYS, } from '../types/unions.js';
|
|
14
|
+
import { countSchema, documentIdSegmentSchema, epochMsSchema, revisionSchema, userIdSchema } from './atoms.js';
|
|
15
|
+
import { awardIdSchema } from './catalogs.js';
|
|
16
|
+
export const awardGroupTypeSchema = z.enum(AWARD_GROUP_TYPE_KEYS);
|
|
17
|
+
export const awardGroupGrantActionSchema = z.enum(AWARD_GROUP_GRANT_ACTION_KEYS);
|
|
18
|
+
export const awardGroupGrantStatusSchema = z.enum(AWARD_GROUP_GRANT_STATUS_KEYS);
|
|
19
|
+
// A decision's number among every decision on its award and group: the first is 1.
|
|
20
|
+
export const awardGroupGrantDecisionSchema = revisionSchema;
|
|
21
|
+
export const AwardGroupGrantSchema = z
|
|
22
|
+
.strictObject({
|
|
23
|
+
grantId: z.string().min(1),
|
|
24
|
+
action: awardGroupGrantActionSchema,
|
|
25
|
+
awardId: awardIdSchema,
|
|
26
|
+
groupType: awardGroupTypeSchema,
|
|
27
|
+
// The team id or the league id, as `groupType` says.
|
|
28
|
+
groupId: documentIdSegmentSchema,
|
|
29
|
+
targetKey: z.string().min(1),
|
|
30
|
+
decision: awardGroupGrantDecisionSchema,
|
|
31
|
+
// The admin who decided. Each person's audit event is recorded as their action.
|
|
32
|
+
actorUid: userIdSchema,
|
|
33
|
+
status: awardGroupGrantStatusSchema,
|
|
34
|
+
createdAt: epochMsSchema,
|
|
35
|
+
completedAt: epochMsSchema.optional(),
|
|
36
|
+
attemptCount: countSchema,
|
|
37
|
+
nextAttemptAt: epochMsSchema,
|
|
38
|
+
lastError: z.string().optional(),
|
|
39
|
+
})
|
|
40
|
+
.superRefine((grant, ctx) => {
|
|
41
|
+
// The key and the id are derived fields: a decision whose stored key or id disagrees with its
|
|
42
|
+
// award, group, and number would sit outside that pair's decision sequence.
|
|
43
|
+
const targetKey = buildAwardGroupGrantTargetKey(grant);
|
|
44
|
+
if (grant.targetKey !== targetKey) {
|
|
45
|
+
ctx.addIssue({ code: 'custom', path: ['targetKey'], message: 'targetKey must be the award and group target key.' });
|
|
46
|
+
}
|
|
47
|
+
if (grant.grantId !== buildAwardGroupGrantId(targetKey, grant.decision)) {
|
|
48
|
+
ctx.addIssue({ code: 'custom', path: ['grantId'], message: 'grantId must be the target key and the decision.' });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Whether a request opens a new decision on an award for a group, given the group's latest decision
|
|
53
|
+
* (`null` when it has none): a grant opens unless the latest is a grant, and a take-back opens only
|
|
54
|
+
* when it is. A request the latest decision already settles opens nothing. The server applies it in
|
|
55
|
+
* the transaction that opens the decision; the admin surface offers only the request it opens.
|
|
56
|
+
*/
|
|
57
|
+
export function awardGroupGrantOpens(latest, action) {
|
|
58
|
+
return action === 'grant' ? latest?.action !== 'grant' : latest?.action === 'grant';
|
|
59
|
+
}
|
|
60
|
+
// `awardGroupGrants/{grantId}/awardGroupGrantPeople/{userId}` — one person a grant decision reached,
|
|
61
|
+
// recorded before their profile changed. `heldBefore` says they already held the award, so the grant
|
|
62
|
+
// gave them nothing. `revoked` turns true once a revoke has dealt with them; `revokeSkipped` says why
|
|
63
|
+
// that revoke left them holding the award.
|
|
64
|
+
export const AwardGroupGrantPersonSchema = z.strictObject({
|
|
65
|
+
userId: userIdSchema,
|
|
66
|
+
heldBefore: z.boolean(),
|
|
67
|
+
recordedAt: epochMsSchema,
|
|
68
|
+
revoked: z.boolean(),
|
|
69
|
+
revokedAt: epochMsSchema.optional(),
|
|
70
|
+
revokeSkipped: z.enum(AWARD_GROUP_REVOKE_SKIP_KEYS).optional(),
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=award-group-grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"award-group-grant.js","sourceRoot":"","sources":["../../src/doc-schemas/award-group-grant.ts"],"names":[],"mappings":"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","sourcesContent":["// `awardGroupGrants/{grantId}` — one decision on one award for one group (a team, or a whole league):\n// grant the award to the group's active members, or take back what the group's grants gave. The\n// people are reached a page at a time, after the decision opens in its own small transaction. Written\n// only by Cloud Functions; an admin reads a decision through the status callable.\n//\n// A grant records each person in `awardGroupGrantPeople` before it changes their profile, so a re-run\n// after any interruption finds every recorded person and finishes them, and its revoke reverses exactly\n// the people it gave the award to. Someone who already held the award is recorded as holding it before,\n// and a revoke leaves them holding it. `status` stays `pending` until every page is done; the retry\n// ledger lets a decision that keeps failing back off instead of holding the resume's window.\n\nimport { z } from 'zod';\nimport { buildAwardGroupGrantId, buildAwardGroupGrantTargetKey } from '../ids/award-grant-ids.js';\nimport {\n AWARD_GROUP_GRANT_ACTION_KEYS,\n AWARD_GROUP_GRANT_STATUS_KEYS,\n AWARD_GROUP_REVOKE_SKIP_KEYS,\n AWARD_GROUP_TYPE_KEYS,\n} from '../types/unions.js';\nimport { countSchema, documentIdSegmentSchema, epochMsSchema, revisionSchema, userIdSchema } from './atoms.js';\nimport { awardIdSchema } from './catalogs.js';\n\nexport const awardGroupTypeSchema = z.enum(AWARD_GROUP_TYPE_KEYS);\nexport const awardGroupGrantActionSchema = z.enum(AWARD_GROUP_GRANT_ACTION_KEYS);\nexport const awardGroupGrantStatusSchema = z.enum(AWARD_GROUP_GRANT_STATUS_KEYS);\n\n// A decision's number among every decision on its award and group: the first is 1.\nexport const awardGroupGrantDecisionSchema = revisionSchema;\n\nexport const AwardGroupGrantSchema = z\n .strictObject({\n grantId: z.string().min(1),\n action: awardGroupGrantActionSchema,\n awardId: awardIdSchema,\n groupType: awardGroupTypeSchema,\n // The team id or the league id, as `groupType` says.\n groupId: documentIdSegmentSchema,\n targetKey: z.string().min(1),\n decision: awardGroupGrantDecisionSchema,\n // The admin who decided. Each person's audit event is recorded as their action.\n actorUid: userIdSchema,\n status: awardGroupGrantStatusSchema,\n createdAt: epochMsSchema,\n completedAt: epochMsSchema.optional(),\n attemptCount: countSchema,\n nextAttemptAt: epochMsSchema,\n lastError: z.string().optional(),\n })\n .superRefine((grant, ctx) => {\n // The key and the id are derived fields: a decision whose stored key or id disagrees with its\n // award, group, and number would sit outside that pair's decision sequence.\n const targetKey = buildAwardGroupGrantTargetKey(grant);\n if (grant.targetKey !== targetKey) {\n ctx.addIssue({ code: 'custom', path: ['targetKey'], message: 'targetKey must be the award and group target key.' });\n }\n if (grant.grantId !== buildAwardGroupGrantId(targetKey, grant.decision)) {\n ctx.addIssue({ code: 'custom', path: ['grantId'], message: 'grantId must be the target key and the decision.' });\n }\n });\nexport type AwardGroupGrant = z.infer<typeof AwardGroupGrantSchema>;\n\n/**\n * Whether a request opens a new decision on an award for a group, given the group's latest decision\n * (`null` when it has none): a grant opens unless the latest is a grant, and a take-back opens only\n * when it is. A request the latest decision already settles opens nothing. The server applies it in\n * the transaction that opens the decision; the admin surface offers only the request it opens.\n */\nexport function awardGroupGrantOpens(\n latest: Pick<AwardGroupGrant, 'action'> | null,\n action: AwardGroupGrant['action'],\n): boolean {\n return action === 'grant' ? latest?.action !== 'grant' : latest?.action === 'grant';\n}\n\n// `awardGroupGrants/{grantId}/awardGroupGrantPeople/{userId}` — one person a grant decision reached,\n// recorded before their profile changed. `heldBefore` says they already held the award, so the grant\n// gave them nothing. `revoked` turns true once a revoke has dealt with them; `revokeSkipped` says why\n// that revoke left them holding the award.\nexport const AwardGroupGrantPersonSchema = z.strictObject({\n userId: userIdSchema,\n heldBefore: z.boolean(),\n recordedAt: epochMsSchema,\n revoked: z.boolean(),\n revokedAt: epochMsSchema.optional(),\n revokeSkipped: z.enum(AWARD_GROUP_REVOKE_SKIP_KEYS).optional(),\n});\nexport type AwardGroupGrantPerson = z.infer<typeof AwardGroupGrantPersonSchema>;\n"]}
|
|
@@ -22,6 +22,7 @@ export * from './waiver-template.js';
|
|
|
22
22
|
export * from './waivers-and-hardware.js';
|
|
23
23
|
export * from './game-location.js';
|
|
24
24
|
export * from './catalogs.js';
|
|
25
|
+
export * from './award-group-grant.js';
|
|
25
26
|
export * from './system.js';
|
|
26
27
|
export * from './admin-notifications.js';
|
|
27
28
|
export * from './migration-console.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
|
|
@@ -22,6 +22,7 @@ export * from './waiver-template.js';
|
|
|
22
22
|
export * from './waivers-and-hardware.js';
|
|
23
23
|
export * from './game-location.js';
|
|
24
24
|
export * from './catalogs.js';
|
|
25
|
+
export * from './award-group-grant.js';
|
|
25
26
|
export * from './system.js';
|
|
26
27
|
export * from './admin-notifications.js';
|
|
27
28
|
export * from './migration-console.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/doc-schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC","sourcesContent":["export * from './atoms.js';\nexport * from './firestore-primitives.js';\nexport * from './user-profile.js';\nexport * from './publicUser.js';\nexport * from './reserved-display-name.js';\nexport * from './status-reconcile-queue.js';\nexport * from './registration-start.js';\nexport * from './audit-event.js';\nexport * from './gallery.js';\nexport * from './pending-media.js';\nexport * from './picture-retirement.js';\nexport * from './sport-league.js';\nexport * from './league-team.js';\nexport * from './team-membership.js';\nexport * from './membership-roster-sync.js';\nexport * from './game-stats.js';\nexport * from './sport-game.js';\nexport * from './game-stat-history.js';\nexport * from './aggregate-stats.js';\nexport * from './stats-operation.js';\nexport * from './waiver-template.js';\nexport * from './waivers-and-hardware.js';\nexport * from './game-location.js';\nexport * from './catalogs.js';\nexport * from './system.js';\nexport * from './admin-notifications.js';\nexport * from './migration-console.js';\nexport * from './sweep-state.js';\nexport * from './registry.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/doc-schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC","sourcesContent":["export * from './atoms.js';\nexport * from './firestore-primitives.js';\nexport * from './user-profile.js';\nexport * from './publicUser.js';\nexport * from './reserved-display-name.js';\nexport * from './status-reconcile-queue.js';\nexport * from './registration-start.js';\nexport * from './audit-event.js';\nexport * from './gallery.js';\nexport * from './pending-media.js';\nexport * from './picture-retirement.js';\nexport * from './sport-league.js';\nexport * from './league-team.js';\nexport * from './team-membership.js';\nexport * from './membership-roster-sync.js';\nexport * from './game-stats.js';\nexport * from './sport-game.js';\nexport * from './game-stat-history.js';\nexport * from './aggregate-stats.js';\nexport * from './stats-operation.js';\nexport * from './waiver-template.js';\nexport * from './waivers-and-hardware.js';\nexport * from './game-location.js';\nexport * from './catalogs.js';\nexport * from './award-group-grant.js';\nexport * from './system.js';\nexport * from './admin-notifications.js';\nexport * from './migration-console.js';\nexport * from './sweep-state.js';\nexport * from './registry.js';\n"]}
|
|
@@ -124,8 +124,8 @@ export declare const MigrationRunRecordSchema: z.ZodObject<{
|
|
|
124
124
|
updatedAt: z.ZodNumber;
|
|
125
125
|
completedAt: z.ZodOptional<z.ZodNumber>;
|
|
126
126
|
status: z.ZodEnum<{
|
|
127
|
-
running: "running";
|
|
128
127
|
complete: "complete";
|
|
128
|
+
running: "running";
|
|
129
129
|
stopped: "stopped";
|
|
130
130
|
}>;
|
|
131
131
|
pages: z.ZodNumber;
|
|
@@ -255,8 +255,8 @@ export declare const MigrationActionRunSchema: z.ZodObject<{
|
|
|
255
255
|
updatedAt: z.ZodNumber;
|
|
256
256
|
completedAt: z.ZodOptional<z.ZodNumber>;
|
|
257
257
|
status: z.ZodEnum<{
|
|
258
|
-
running: "running";
|
|
259
258
|
complete: "complete";
|
|
259
|
+
running: "running";
|
|
260
260
|
stopped: "stopped";
|
|
261
261
|
}>;
|
|
262
262
|
pages: z.ZodNumber;
|
|
@@ -290,8 +290,8 @@ export declare const MigrationActionRunSchema: z.ZodObject<{
|
|
|
290
290
|
updatedAt: z.ZodNumber;
|
|
291
291
|
completedAt: z.ZodOptional<z.ZodNumber>;
|
|
292
292
|
status: z.ZodEnum<{
|
|
293
|
-
running: "running";
|
|
294
293
|
complete: "complete";
|
|
294
|
+
running: "running";
|
|
295
295
|
stopped: "stopped";
|
|
296
296
|
}>;
|
|
297
297
|
pages: z.ZodNumber;
|