@ttt-productions/q-core 0.1.24 → 0.1.26
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/admin-views.d.ts +3 -0
- package/dist/constants/admin-views.d.ts.map +1 -0
- package/dist/constants/admin-views.js +11 -0
- package/dist/constants/admin-views.js.map +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +1 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/constants/scheduled-jobs.d.ts +7 -0
- package/dist/constants/scheduled-jobs.d.ts.map +1 -1
- package/dist/constants/scheduled-jobs.js +7 -0
- package/dist/constants/scheduled-jobs.js.map +1 -1
- package/dist/doc-schemas/audit-event.d.ts +4 -0
- package/dist/doc-schemas/audit-event.d.ts.map +1 -1
- package/dist/doc-schemas/pending-media.d.ts +0 -25
- package/dist/doc-schemas/pending-media.d.ts.map +1 -1
- package/dist/doc-schemas/registry.d.ts +6 -10
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/doc-schemas/sweep-state.d.ts +9 -0
- package/dist/doc-schemas/sweep-state.d.ts.map +1 -1
- package/dist/doc-schemas/sweep-state.js +11 -1
- package/dist/doc-schemas/sweep-state.js.map +1 -1
- package/dist/domain-events/domain-events.d.ts +0 -11
- package/dist/domain-events/domain-events.d.ts.map +1 -1
- package/dist/domain-events/domain-events.js +0 -7
- package/dist/domain-events/domain-events.js.map +1 -1
- package/dist/notifications/admin-notification-config.d.ts.map +1 -1
- package/dist/notifications/admin-notification-config.js +3 -3
- package/dist/notifications/admin-notification-config.js.map +1 -1
- package/dist/paths/app-routes.d.ts +40 -0
- package/dist/paths/app-routes.d.ts.map +1 -0
- package/dist/paths/app-routes.js +67 -0
- package/dist/paths/app-routes.js.map +1 -0
- package/dist/paths/index.d.ts +1 -0
- package/dist/paths/index.d.ts.map +1 -1
- package/dist/paths/index.js +1 -0
- package/dist/paths/index.js.map +1 -1
- package/dist/schemas/pictures.d.ts +0 -15
- package/dist/schemas/pictures.d.ts.map +1 -1
- package/dist/schemas/users.d.ts +1 -0
- package/dist/schemas/users.d.ts.map +1 -1
- package/dist/schemas/users.js +3 -0
- package/dist/schemas/users.js.map +1 -1
- package/dist/types/audit.d.ts +1 -1
- package/dist/types/audit.d.ts.map +1 -1
- package/dist/types/audit.js +4 -0
- package/dist/types/audit.js.map +1 -1
- package/dist/types/claims.d.ts +12 -3
- package/dist/types/claims.d.ts.map +1 -1
- package/dist/types/claims.js +15 -6
- package/dist/types/claims.js.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/utils/app-routes.d.ts +0 -32
- package/dist/utils/app-routes.d.ts.map +0 -1
- package/dist/utils/app-routes.js +0 -59
- package/dist/utils/app-routes.js.map +0 -1
|
@@ -10,7 +10,7 @@ import { COLLECTION_REFS } from '../paths/collection-refs.js';
|
|
|
10
10
|
import { toPath } from '../paths/utils.js';
|
|
11
11
|
import { buildLeagueFreeAgentId } from '../ids/compound-ids.js';
|
|
12
12
|
import { ADMIN_NOTIFICATION_CATEGORY, ADMIN_NOTIFICATION_TYPE_KEYS, } from '../types/notifications.js';
|
|
13
|
-
import {
|
|
13
|
+
import { APP_ROUTES, LEAGUE_FREE_AGENTS_SECTION } from '../paths/app-routes.js';
|
|
14
14
|
export const ADMIN_NOTIFICATION_DEFINITIONS = {
|
|
15
15
|
leagueTeamCreated: {
|
|
16
16
|
// One card per team, so each card links to its own team page.
|
|
@@ -19,7 +19,7 @@ export const ADMIN_NOTIFICATION_DEFINITIONS = {
|
|
|
19
19
|
title: 'New team',
|
|
20
20
|
icon: '👥',
|
|
21
21
|
message: () => 'A new team joined a league.',
|
|
22
|
-
targetPath: ({ leagueId, teamId }) =>
|
|
22
|
+
targetPath: ({ leagueId, teamId }) => APP_ROUTES.leagueTeam(leagueId, teamId),
|
|
23
23
|
countCap: 1,
|
|
24
24
|
},
|
|
25
25
|
leagueFreeAgentSignedUp: {
|
|
@@ -32,7 +32,7 @@ export const ADMIN_NOTIFICATION_DEFINITIONS = {
|
|
|
32
32
|
message: (count) => count === 1
|
|
33
33
|
? 'A player signed up as a free agent.'
|
|
34
34
|
: `A player signed up as a free agent ${count} times.`,
|
|
35
|
-
targetPath: ({ leagueId }) =>
|
|
35
|
+
targetPath: ({ leagueId }) => APP_ROUTES.adminLeague(leagueId, LEAGUE_FREE_AGENTS_SECTION),
|
|
36
36
|
},
|
|
37
37
|
};
|
|
38
38
|
// The package hands every pattern the stored metadata untyped. It is parsed against the type's own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-notification-config.js","sourceRoot":"","sources":["../../src/notifications/admin-notification-config.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,oGAAoG;AACpG,oGAAoG;AACpG,sDAAsD;AACtD,EAAE;AACF,qGAAqG;AACrG,qCAAqC;AAMrC,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAE5F,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,
|
|
1
|
+
{"version":3,"file":"admin-notification-config.js","sourceRoot":"","sources":["../../src/notifications/admin-notification-config.ts"],"names":[],"mappings":"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","sourcesContent":["// The one notification configuration, read by both roots: the Cloud Functions ledger that writes\n// the cards, and the admin area that lists them. notification-core supplies the mechanism and takes\n// Q-Sports' policy here — the shared category, where its documents live, and per type the copy, the\n// icon, the link, and the key its cards aggregate on.\n//\n// The Functions side adds the one field this module cannot carry: `timestampFromMillis`, which needs\n// the Admin SDK (RULE-STD-ARCH-202).\n\nimport type {\n NotificationSystemConfig,\n NotificationTypeConfig,\n} from '@ttt-productions/notification-core';\nimport { ADMIN_NOTIFICATION_METADATA_SCHEMAS } from '../doc-schemas/admin-notifications.js';\nimport type { AdminNotificationMetadataByType } from '../doc-schemas/admin-notifications.js';\nimport { COLLECTION_REFS } from '../paths/collection-refs.js';\nimport { toPath } from '../paths/utils.js';\nimport { buildLeagueFreeAgentId } from '../ids/compound-ids.js';\nimport {\n ADMIN_NOTIFICATION_CATEGORY,\n ADMIN_NOTIFICATION_TYPE_KEYS,\n} from '../types/notifications.js';\nimport type { AdminNotificationType } from '../types/notifications.js';\nimport { APP_ROUTES, LEAGUE_FREE_AGENTS_SECTION } from '../paths/app-routes.js';\n\nexport interface AdminNotificationDefinition<T extends AdminNotificationType> {\n /**\n * The key its cards aggregate on: an occurrence whose key matches an active card lights that card\n * again and counts on it, and any other occurrence opens a new card.\n */\n aggregationKey: (metadata: AdminNotificationMetadataByType[T]) => string;\n /**\n * `realtime`: the owning callable materializes the card right after its commit, and the worker is\n * the fallback. `queued`: the worker alone materializes it.\n */\n delivery: NotificationTypeConfig['delivery'];\n title: string;\n /** The emoji its cards show beside their title. */\n icon: string;\n message: (count: number) => string;\n /** Where the card's link goes. */\n targetPath: (metadata: AdminNotificationMetadataByType[T]) => string;\n /** The highest count a card of this type shows. */\n countCap?: number;\n}\n\nexport const ADMIN_NOTIFICATION_DEFINITIONS: {\n [T in AdminNotificationType]: AdminNotificationDefinition<T>;\n} = {\n leagueTeamCreated: {\n // One card per team, so each card links to its own team page.\n aggregationKey: ({ teamId }) => teamId,\n delivery: 'realtime',\n title: 'New team',\n icon: '👥',\n message: () => 'A new team joined a league.',\n targetPath: ({ leagueId, teamId }) => APP_ROUTES.leagueTeam(leagueId, teamId),\n countCap: 1,\n },\n leagueFreeAgentSignedUp: {\n // One card per player per league: another player's signup is a card of its own, and the same\n // player signing up again lights their card again. Every card links to the league's free agents.\n aggregationKey: ({ leagueId, userId }) => buildLeagueFreeAgentId(leagueId, userId),\n delivery: 'realtime',\n title: 'Free agent signup',\n icon: '🙋',\n message: (count) =>\n count === 1\n ? 'A player signed up as a free agent.'\n : `A player signed up as a free agent ${count} times.`,\n targetPath: ({ leagueId }) => APP_ROUTES.adminLeague(leagueId, LEAGUE_FREE_AGENTS_SECTION),\n },\n};\n\n// The package hands every pattern the stored metadata untyped. It is parsed against the type's own\n// schema, so a row whose metadata is not its type's fails to materialize — and is retried, then\n// dead-lettered — rather than lighting a card with a broken link.\nfunction typeConfig<T extends AdminNotificationType>(type: T): NotificationTypeConfig {\n const definition = ADMIN_NOTIFICATION_DEFINITIONS[type];\n const read = (metadata: Record<string, unknown>) =>\n ADMIN_NOTIFICATION_METADATA_SCHEMAS[type].parse(metadata) as AdminNotificationMetadataByType[T];\n return {\n category: ADMIN_NOTIFICATION_CATEGORY,\n delivery: definition.delivery,\n dedupKeyPattern: (metadata) => definition.aggregationKey(read(metadata)),\n titlePattern: () => definition.title,\n icon: definition.icon,\n messagePattern: (_metadata, count) => definition.message(count),\n defaultTargetPath: (metadata) => definition.targetPath(read(metadata)),\n ...(definition.countCap === undefined ? {} : { countCap: definition.countCap }),\n };\n}\n\nexport const NOTIFICATION_SYSTEM_CONFIG: NotificationSystemConfig = {\n categories: {\n [ADMIN_NOTIFICATION_CATEGORY]: {\n activePath: toPath(COLLECTION_REFS.activeAdminNotifications()),\n historyPath: () => toPath(COLLECTION_REFS.adminNotificationHistory()),\n audienceType: 'shared',\n },\n },\n types: Object.fromEntries(ADMIN_NOTIFICATION_TYPE_KEYS.map((type) => [type, typeConfig(type)])),\n deliveriesCollectionPath: toPath(COLLECTION_REFS.notificationDeliveries()),\n};\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AdminView } from '../constants/admin-views.js';
|
|
2
|
+
import type { SportKey } from '../types/sports.js';
|
|
3
|
+
/** The query-string key the hall of fame names its sport under. */
|
|
4
|
+
export declare const HALL_OF_FAME_SPORT_PARAM = "sport";
|
|
5
|
+
/** The query-string key the admin page's views live under. */
|
|
6
|
+
export declare const ADMIN_VIEW_PARAM = "view";
|
|
7
|
+
/** The query-string key a view's sections live under. */
|
|
8
|
+
export declare const ADMIN_SECTION_PARAM = "section";
|
|
9
|
+
/** The query-string key the Leagues view names the league whose workspace is open under. */
|
|
10
|
+
export declare const ADMIN_LEAGUE_PARAM = "league";
|
|
11
|
+
/** The query-string key the Teams section names the team whose admin view is open under. */
|
|
12
|
+
export declare const ADMIN_TEAM_PARAM = "team";
|
|
13
|
+
export declare const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS: readonly ["settings", "schedule", "teams", "free-agents"];
|
|
14
|
+
export type AdminLeagueWorkspaceSection = (typeof ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS)[number];
|
|
15
|
+
/** The league workspace's section holding the league's weeks and games. */
|
|
16
|
+
export declare const LEAGUE_SCHEDULE_SECTION = "schedule";
|
|
17
|
+
/** The league workspace's section listing the league's teams, each opening its admin view. */
|
|
18
|
+
export declare const LEAGUE_TEAMS_SECTION = "teams";
|
|
19
|
+
/** The league workspace's section listing the league's free-agent signups. */
|
|
20
|
+
export declare const LEAGUE_FREE_AGENTS_SECTION = "free-agents";
|
|
21
|
+
export declare const APP_ROUTES: {
|
|
22
|
+
readonly home: () => string;
|
|
23
|
+
readonly hallOfFame: (sport?: SportKey) => string;
|
|
24
|
+
readonly locations: () => string;
|
|
25
|
+
readonly settings: () => string;
|
|
26
|
+
readonly terms: () => string;
|
|
27
|
+
readonly user: (userId: string) => string;
|
|
28
|
+
readonly league: (leagueId: string) => string;
|
|
29
|
+
readonly leagueTeam: (leagueId: string, teamId: string) => string;
|
|
30
|
+
readonly sportGame: (leagueId: string, gameId: string) => string;
|
|
31
|
+
/** A game's scoring page, where a scorer records its stats. */
|
|
32
|
+
readonly sportGameScoring: (leagueId: string, gameId: string) => string;
|
|
33
|
+
/** An admin view, on one of its sections when one is named; the dashboard is the bare page. */
|
|
34
|
+
readonly admin: (view?: AdminView, section?: string) => string;
|
|
35
|
+
/** A league's admin workspace, on one of its sections when one is named. */
|
|
36
|
+
readonly adminLeague: (leagueId: string, section?: AdminLeagueWorkspaceSection) => string;
|
|
37
|
+
/** One team's admin view, inside its league's workspace on the Teams section. */
|
|
38
|
+
readonly adminLeagueTeam: (leagueId: string, teamId: string) => string;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=app-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-routes.d.ts","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAEhD,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAIvC,eAAO,MAAM,mCAAmC,2DAKtC,CAAC;AACX,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,mCAAmC,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/F,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,aAAmD,CAAC;AAExF,8FAA8F;AAC9F,eAAO,MAAM,oBAAoB,UAAgD,CAAC;AAElF,8EAA8E;AAC9E,eAAO,MAAM,0BAA0B,gBAAsD,CAAC;AAoB9F,eAAO,MAAM,UAAU;yBACX,MAAM;kCACK,QAAQ,KAAG,MAAM;8BAEvB,MAAM;6BACP,MAAM;0BACT,MAAM;4BACF,MAAM,KAAG,MAAM;gCACX,MAAM,KAAG,MAAM;oCACX,MAAM,UAAU,MAAM,KAAG,MAAM;mCAEhC,MAAM,UAAU,MAAM,KAAG,MAAM;IAErD,+DAA+D;0CAClC,MAAM,UAAU,MAAM,KAAG,MAAM;IAE5D,+FAA+F;4BAChF,SAAS,YAAY,MAAM,KAAG,MAAM;IAKnD,4EAA4E;qCACpD,MAAM,YAAY,2BAA2B,KAAG,MAAM;IAE9E,iFAAiF;yCACrD,MAAM,UAAU,MAAM,KAAG,MAAM;CAKnD,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Every app page address, declared once and built through `APP_ROUTES`. Both roots build these
|
|
2
|
+
// links: the server writes one onto an admin notification card, and the app links to every one of
|
|
3
|
+
// them, so each address shape has one change point (RULE-STD-ARCH-101). Every id is encoded, so an id
|
|
4
|
+
// holding a `/` or a space still addresses its own page.
|
|
5
|
+
/** The query-string key the hall of fame names its sport under. */
|
|
6
|
+
export const HALL_OF_FAME_SPORT_PARAM = 'sport';
|
|
7
|
+
/** The query-string key the admin page's views live under. */
|
|
8
|
+
export const ADMIN_VIEW_PARAM = 'view';
|
|
9
|
+
/** The query-string key a view's sections live under. */
|
|
10
|
+
export const ADMIN_SECTION_PARAM = 'section';
|
|
11
|
+
/** The query-string key the Leagues view names the league whose workspace is open under. */
|
|
12
|
+
export const ADMIN_LEAGUE_PARAM = 'league';
|
|
13
|
+
/** The query-string key the Teams section names the team whose admin view is open under. */
|
|
14
|
+
export const ADMIN_TEAM_PARAM = 'team';
|
|
15
|
+
// The sections a league's admin workspace is addressed by. The workspace declares which of them it
|
|
16
|
+
// has built as tabs; a link may name any of them.
|
|
17
|
+
export const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS = [
|
|
18
|
+
'settings',
|
|
19
|
+
'schedule',
|
|
20
|
+
'teams',
|
|
21
|
+
'free-agents',
|
|
22
|
+
];
|
|
23
|
+
/** The league workspace's section holding the league's weeks and games. */
|
|
24
|
+
export const LEAGUE_SCHEDULE_SECTION = 'schedule';
|
|
25
|
+
/** The league workspace's section listing the league's teams, each opening its admin view. */
|
|
26
|
+
export const LEAGUE_TEAMS_SECTION = 'teams';
|
|
27
|
+
/** The league workspace's section listing the league's free-agent signups. */
|
|
28
|
+
export const LEAGUE_FREE_AGENTS_SECTION = 'free-agents';
|
|
29
|
+
const enc = encodeURIComponent;
|
|
30
|
+
function withQuery(path, entries) {
|
|
31
|
+
if (entries.length === 0)
|
|
32
|
+
return path;
|
|
33
|
+
return `${path}?${entries.map(([key, value]) => `${key}=${enc(value)}`).join('&')}`;
|
|
34
|
+
}
|
|
35
|
+
function adminLeagueEntries(leagueId, section) {
|
|
36
|
+
return [
|
|
37
|
+
[ADMIN_VIEW_PARAM, 'leagues'],
|
|
38
|
+
[ADMIN_LEAGUE_PARAM, leagueId],
|
|
39
|
+
...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section]]),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
export const APP_ROUTES = {
|
|
43
|
+
home: () => '/',
|
|
44
|
+
hallOfFame: (sport) => withQuery('/hall-of-fame', sport === undefined ? [] : [[HALL_OF_FAME_SPORT_PARAM, sport]]),
|
|
45
|
+
locations: () => '/locations',
|
|
46
|
+
settings: () => '/settings',
|
|
47
|
+
terms: () => '/terms',
|
|
48
|
+
user: (userId) => `/user/${enc(userId)}`,
|
|
49
|
+
league: (leagueId) => `/league/${enc(leagueId)}`,
|
|
50
|
+
leagueTeam: (leagueId, teamId) => `/league/${enc(leagueId)}/team/${enc(teamId)}`,
|
|
51
|
+
sportGame: (leagueId, gameId) => `/league/${enc(leagueId)}/game/${enc(gameId)}`,
|
|
52
|
+
/** A game's scoring page, where a scorer records its stats. */
|
|
53
|
+
sportGameScoring: (leagueId, gameId) => `/league/${enc(leagueId)}/game/${enc(gameId)}/stats`,
|
|
54
|
+
/** An admin view, on one of its sections when one is named; the dashboard is the bare page. */
|
|
55
|
+
admin: (view, section) => withQuery('/admin', [
|
|
56
|
+
...(view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view]]),
|
|
57
|
+
...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section]]),
|
|
58
|
+
]),
|
|
59
|
+
/** A league's admin workspace, on one of its sections when one is named. */
|
|
60
|
+
adminLeague: (leagueId, section) => withQuery('/admin', adminLeagueEntries(leagueId, section)),
|
|
61
|
+
/** One team's admin view, inside its league's workspace on the Teams section. */
|
|
62
|
+
adminLeagueTeam: (leagueId, teamId) => withQuery('/admin', [
|
|
63
|
+
...adminLeagueEntries(leagueId, LEAGUE_TEAMS_SECTION),
|
|
64
|
+
[ADMIN_TEAM_PARAM, teamId],
|
|
65
|
+
]),
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=app-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,kGAAkG;AAClG,sGAAsG;AACtG,yDAAyD;AAKzD,mEAAmE;AACnE,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEhD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,yDAAyD;AACzD,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,mGAAmG;AACnG,kDAAkD;AAClD,MAAM,CAAC,MAAM,mCAAmC,GAAG;IACjD,UAAU;IACV,UAAU;IACV,OAAO;IACP,aAAa;CACL,CAAC;AAGX,2EAA2E;AAC3E,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAgD,CAAC;AAExF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAA6C,CAAC;AAElF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,0BAA0B,GAAG,aAAmD,CAAC;AAE9F,MAAM,GAAG,GAAG,kBAAkB,CAAC;AAE/B,SAAS,SAAS,CAAC,IAAY,EAAE,OAA+C;IAC9E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,SAAS,kBAAkB,CACzB,QAAgB,EAChB,OAAqC;IAErC,OAAO;QACL,CAAC,gBAAgB,EAAE,SAA6B,CAAC;QACjD,CAAC,kBAAkB,EAAE,QAAQ,CAAC;QAC9B,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,EAAE,OAAO,CAAU,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,GAAW,EAAE,CAAC,GAAG;IACvB,UAAU,EAAE,CAAC,KAAgB,EAAU,EAAE,CACvC,SAAS,CAAC,eAAe,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5F,SAAS,EAAE,GAAW,EAAE,CAAC,YAAY;IACrC,QAAQ,EAAE,GAAW,EAAE,CAAC,WAAW;IACnC,KAAK,EAAE,GAAW,EAAE,CAAC,QAAQ;IAC7B,IAAI,EAAE,CAAC,MAAc,EAAU,EAAE,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,EAAE;IACxD,MAAM,EAAE,CAAC,QAAgB,EAAU,EAAE,CAAC,WAAW,GAAG,CAAC,QAAQ,CAAC,EAAE;IAChE,UAAU,EAAE,CAAC,QAAgB,EAAE,MAAc,EAAU,EAAE,CACvD,WAAW,GAAG,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,EAAE;IAChD,SAAS,EAAE,CAAC,QAAgB,EAAE,MAAc,EAAU,EAAE,CACtD,WAAW,GAAG,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,EAAE;IAChD,+DAA+D;IAC/D,gBAAgB,EAAE,CAAC,QAAgB,EAAE,MAAc,EAAU,EAAE,CAC7D,WAAW,GAAG,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,QAAQ;IACtD,+FAA+F;IAC/F,KAAK,EAAE,CAAC,IAAgB,EAAE,OAAgB,EAAU,EAAE,CACpD,SAAS,CAAC,QAAQ,EAAE;QAClB,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,IAAI,CAAU,CAAC,CAAC;QAC1F,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,EAAE,OAAO,CAAU,CAAC,CAAC;KAC5E,CAAC;IACJ,4EAA4E;IAC5E,WAAW,EAAE,CAAC,QAAgB,EAAE,OAAqC,EAAU,EAAE,CAC/E,SAAS,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5D,iFAAiF;IACjF,eAAe,EAAE,CAAC,QAAgB,EAAE,MAAc,EAAU,EAAE,CAC5D,SAAS,CAAC,QAAQ,EAAE;QAClB,GAAG,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,CAAC;QACrD,CAAC,gBAAgB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACI,CAAC","sourcesContent":["// Every app page address, declared once and built through `APP_ROUTES`. Both roots build these\n// links: the server writes one onto an admin notification card, and the app links to every one of\n// them, so each address shape has one change point (RULE-STD-ARCH-101). Every id is encoded, so an id\n// holding a `/` or a space still addresses its own page.\n\nimport type { AdminView } from '../constants/admin-views.js';\nimport type { SportKey } from '../types/sports.js';\n\n/** The query-string key the hall of fame names its sport under. */\nexport const HALL_OF_FAME_SPORT_PARAM = 'sport';\n\n/** The query-string key the admin page's views live under. */\nexport const ADMIN_VIEW_PARAM = 'view';\n\n/** The query-string key a view's sections live under. */\nexport const ADMIN_SECTION_PARAM = 'section';\n\n/** The query-string key the Leagues view names the league whose workspace is open under. */\nexport const ADMIN_LEAGUE_PARAM = 'league';\n\n/** The query-string key the Teams section names the team whose admin view is open under. */\nexport const ADMIN_TEAM_PARAM = 'team';\n\n// The sections a league's admin workspace is addressed by. The workspace declares which of them it\n// has built as tabs; a link may name any of them.\nexport const ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS = [\n 'settings',\n 'schedule',\n 'teams',\n 'free-agents',\n] as const;\nexport type AdminLeagueWorkspaceSection = (typeof ADMIN_LEAGUE_WORKSPACE_SECTION_KEYS)[number];\n\n/** The league workspace's section holding the league's weeks and games. */\nexport const LEAGUE_SCHEDULE_SECTION = 'schedule' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's teams, each opening its admin view. */\nexport const LEAGUE_TEAMS_SECTION = 'teams' satisfies AdminLeagueWorkspaceSection;\n\n/** The league workspace's section listing the league's free-agent signups. */\nexport const LEAGUE_FREE_AGENTS_SECTION = 'free-agents' satisfies AdminLeagueWorkspaceSection;\n\nconst enc = encodeURIComponent;\n\nfunction withQuery(path: string, entries: readonly (readonly [string, string])[]): string {\n if (entries.length === 0) return path;\n return `${path}?${entries.map(([key, value]) => `${key}=${enc(value)}`).join('&')}`;\n}\n\nfunction adminLeagueEntries(\n leagueId: string,\n section?: AdminLeagueWorkspaceSection,\n): (readonly [string, string])[] {\n return [\n [ADMIN_VIEW_PARAM, 'leagues' satisfies AdminView],\n [ADMIN_LEAGUE_PARAM, leagueId],\n ...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section] as const]),\n ];\n}\n\nexport const APP_ROUTES = {\n home: (): string => '/',\n hallOfFame: (sport?: SportKey): string =>\n withQuery('/hall-of-fame', sport === undefined ? [] : [[HALL_OF_FAME_SPORT_PARAM, sport]]),\n locations: (): string => '/locations',\n settings: (): string => '/settings',\n terms: (): string => '/terms',\n user: (userId: string): string => `/user/${enc(userId)}`,\n league: (leagueId: string): string => `/league/${enc(leagueId)}`,\n leagueTeam: (leagueId: string, teamId: string): string =>\n `/league/${enc(leagueId)}/team/${enc(teamId)}`,\n sportGame: (leagueId: string, gameId: string): string =>\n `/league/${enc(leagueId)}/game/${enc(gameId)}`,\n /** A game's scoring page, where a scorer records its stats. */\n sportGameScoring: (leagueId: string, gameId: string): string =>\n `/league/${enc(leagueId)}/game/${enc(gameId)}/stats`,\n /** An admin view, on one of its sections when one is named; the dashboard is the bare page. */\n admin: (view?: AdminView, section?: string): string =>\n withQuery('/admin', [\n ...(view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view] as const]),\n ...(section === undefined ? [] : [[ADMIN_SECTION_PARAM, section] as const]),\n ]),\n /** A league's admin workspace, on one of its sections when one is named. */\n adminLeague: (leagueId: string, section?: AdminLeagueWorkspaceSection): string =>\n withQuery('/admin', adminLeagueEntries(leagueId, section)),\n /** One team's admin view, inside its league's workspace on the Teams section. */\n adminLeagueTeam: (leagueId: string, teamId: string): string =>\n withQuery('/admin', [\n ...adminLeagueEntries(leagueId, LEAGUE_TEAMS_SECTION),\n [ADMIN_TEAM_PARAM, teamId],\n ]),\n} as const;\n"]}
|
package/dist/paths/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC"}
|
package/dist/paths/index.js
CHANGED
package/dist/paths/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC","sourcesContent":["export * from './collections.js';\nexport * from './path-builders.js';\nexport * from './collection-refs.js';\nexport * from './collection-groups.js';\nexport * from './utils.js';\nexport * from './storage-paths.js';\nexport * from './picture-owner-paths.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/paths/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './collections.js';\nexport * from './path-builders.js';\nexport * from './collection-refs.js';\nexport * from './collection-groups.js';\nexport * from './utils.js';\nexport * from './storage-paths.js';\nexport * from './picture-owner-paths.js';\nexport * from './app-routes.js';\n"]}
|
|
@@ -247,11 +247,6 @@ export declare const AdminMovePictureResultSchema: z.ZodObject<{
|
|
|
247
247
|
contractId: z.ZodString;
|
|
248
248
|
refereeUserId: z.ZodString;
|
|
249
249
|
}, z.core.$strict>;
|
|
250
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
251
|
-
type: z.ZodLiteral<"adminList.changed">;
|
|
252
|
-
ids: z.ZodObject<{
|
|
253
|
-
userId: z.ZodString;
|
|
254
|
-
}, z.core.$strict>;
|
|
255
250
|
}, z.core.$strict>, z.ZodObject<{
|
|
256
251
|
type: z.ZodLiteral<"user.registered">;
|
|
257
252
|
ids: z.ZodObject<{
|
|
@@ -585,11 +580,6 @@ export declare const AdminUpdateFeaturedPictureResultSchema: z.ZodObject<{
|
|
|
585
580
|
contractId: z.ZodString;
|
|
586
581
|
refereeUserId: z.ZodString;
|
|
587
582
|
}, z.core.$strict>;
|
|
588
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
589
|
-
type: z.ZodLiteral<"adminList.changed">;
|
|
590
|
-
ids: z.ZodObject<{
|
|
591
|
-
userId: z.ZodString;
|
|
592
|
-
}, z.core.$strict>;
|
|
593
583
|
}, z.core.$strict>, z.ZodObject<{
|
|
594
584
|
type: z.ZodLiteral<"user.registered">;
|
|
595
585
|
ids: z.ZodObject<{
|
|
@@ -932,11 +922,6 @@ export declare const AdminDeletePictureResultSchema: z.ZodObject<{
|
|
|
932
922
|
contractId: z.ZodString;
|
|
933
923
|
refereeUserId: z.ZodString;
|
|
934
924
|
}, z.core.$strict>;
|
|
935
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
936
|
-
type: z.ZodLiteral<"adminList.changed">;
|
|
937
|
-
ids: z.ZodObject<{
|
|
938
|
-
userId: z.ZodString;
|
|
939
|
-
}, z.core.$strict>;
|
|
940
925
|
}, z.core.$strict>, z.ZodObject<{
|
|
941
926
|
type: z.ZodLiteral<"user.registered">;
|
|
942
927
|
ids: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pictures.d.ts","sourceRoot":"","sources":["../../src/schemas/pictures.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;kBAE3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,2BAA2B;;;kBAM7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,eAAO,MAAM,4BAA4B
|
|
1
|
+
{"version":3,"file":"pictures.d.ts","sourceRoot":"","sources":["../../src/schemas/pictures.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,yBAAyB;;;;;;;;;;;kBAE3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,2BAA2B;;;kBAM7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAChF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAE9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,qCAAqC;;kBAEvC,CAAC;AACZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AACpG,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAExC,CAAC;AACZ,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CACpD,OAAO,sCAAsC,CAC9C,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;;;;;;;;;;kBAO/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AACpF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAEhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
|
package/dist/schemas/users.d.ts
CHANGED
|
@@ -107,6 +107,7 @@ export declare const UpdateAdminListResultSchema: z.ZodObject<{
|
|
|
107
107
|
refereesRevoked: z.ZodNumber;
|
|
108
108
|
}, z.core.$strict>;
|
|
109
109
|
export type UpdateAdminListResult = z.infer<typeof UpdateAdminListResultSchema>;
|
|
110
|
+
export declare const ADMIN_SELF_REVOKE_REFUSAL = "You can't revoke your own admin standing. Ask another admin to do it.";
|
|
110
111
|
export declare const AdminUpdateUserStatusInputSchema: z.ZodObject<{
|
|
111
112
|
userId: z.ZodString;
|
|
112
113
|
userStatus: z.ZodEnum<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,uBAAuB;;;kBAMzB,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,eAAO,MAAM,wBAAwB;;;;;;8BAQnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAM1E,eAAO,MAAM,oCAAoC;;kBAEtC,CAAC;AACZ,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAGlG,eAAO,MAAM,gCAAgC,oBAAqB,CAAC;AACnE,MAAM,MAAM,4BAA4B,GAAG,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7F,eAAO,MAAM,qCAAqC;;;;;kBAEvC,CAAC;AACZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG,gGAAgG;AAChG,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAMhD,eAAO,MAAM,yBAAyB,QAA+B,CAAC;AACtE,eAAO,MAAM,uBAAuB,QAAsB,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AACtD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAKlE;AAID,eAAO,MAAM,iCAAiC;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAC5F,eAAO,MAAM,kBAAkB;;;;;;;;;kBASpB,CAAC;AACZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,kCAAkC;;;;;;;;;;;kBAEpC,CAAC;AACZ,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAI9F,eAAO,MAAM,4BAA4B;;kBAE9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,eAAO,MAAM,4BAA4B;;;;;;;kBAE9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,eAAO,MAAM,6BAA6B;;;;;;;;;kBAE/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAGpF,eAAO,MAAM,4BAA4B;;;kBAE9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAClF,eAAO,MAAM,6BAA6B;;;kBAE/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAKpF,eAAO,MAAM,0BAA0B;;;;;kBAO5B,CAAC;AACZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,eAAO,MAAM,2BAA2B;;;;;kBAO7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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"}
|
package/dist/schemas/users.js
CHANGED
|
@@ -106,6 +106,9 @@ export const UpdateAdminListResultSchema = z
|
|
|
106
106
|
refereesRevoked: countSchema,
|
|
107
107
|
})
|
|
108
108
|
.strict();
|
|
109
|
+
// The one sentence `updateAdminList` refuses an admin's revoke of their own admin role with, and the
|
|
110
|
+
// role screen shows on the control it withholds.
|
|
111
|
+
export const ADMIN_SELF_REVOKE_REFUSAL = "You can't revoke your own admin standing. Ask another admin to do it.";
|
|
109
112
|
// An admin bans an account or lifts its ban. The reason is internal — recorded on the audit event,
|
|
110
113
|
// never shown to the account (RULE-STD-BACKEND-212). Banning or unbanning to the status the account already
|
|
111
114
|
// holds changes nothing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for user accounts and the global role rosters.\n\nimport { z } from 'zod';\nimport { MAX_ADMIN_LIST_CHANGES } from '../constants/business.js';\nimport {\n countSchema,\n repairReasonSchema,\n userIdSchema,\n userStatusSchema,\n} from '../doc-schemas/atoms.js';\nimport { displayNameSchema } from './atoms.js';\n\n// The signed-in caller finishes registration: profile, public identity, and the display-name\n// reservation are created for `request.auth.uid`. Email comes from the token, never the payload.\nexport const RegisterUserInputSchema = z\n .object({\n displayName: displayNameSchema,\n // The terms checkbox, re-checked server-side: only `true` registers.\n acceptedTerms: z.literal(true),\n })\n .strict();\nexport type RegisterUserInput = z.infer<typeof RegisterUserInputSchema>;\nexport const RegisterUserResultSchema = z.discriminatedUnion('status', [\n // The account is registered (or already was — an idempotent replay).\n z\n .object({ status: z.literal('registered'), userId: userIdSchema, displayName: z.string() })\n .strict(),\n // The orphan-registration cleanup claimed this login for deletion, so the registration cannot\n // finish on it; nothing is written and the person signs up again.\n z.object({ status: z.literal('registrationExpired') }).strict(),\n]);\nexport type RegisterUserResult = z.infer<typeof RegisterUserResultSchema>;\n\n// The register form's check before the login is created: is the name free? It runs before any\n// account exists, over the same name rule `registerUser` takes, and is a soft answer — the claim\n// itself is `registerUser`'s transaction, which refuses `already-exists` when two registrations\n// pass this check at once.\nexport const CheckDisplayNameAvailableInputSchema = z\n .object({ displayName: displayNameSchema })\n .strict();\nexport type CheckDisplayNameAvailableInput = z.infer<typeof CheckDisplayNameAvailableInputSchema>;\n// Why a name is not available. Uniqueness is the only rule a Q-Sports name is held to beyond its\n// input format.\nexport const DISPLAY_NAME_UNAVAILABLE_REASONS = ['taken'] as const;\nexport type DisplayNameUnavailableReason = (typeof DISPLAY_NAME_UNAVAILABLE_REASONS)[number];\nexport const CheckDisplayNameAvailableResultSchema = z\n .object({ available: z.boolean(), reason: z.enum(DISPLAY_NAME_UNAVAILABLE_REASONS).optional() })\n .strict();\nexport type CheckDisplayNameAvailableResult = z.infer<typeof CheckDisplayNameAvailableResultSchema>;\n\n/** The longest text an admin's account search takes: a name, a full email address, or a uid. */\nexport const MAX_USER_SEARCH_QUERY_LENGTH = 100;\n\n// Which read an admin's account search routes to: a full email address or a 28-character Firebase\n// Auth uid is an exact lookup (`lookupUserByEmailOrUid`), anything else a name search. Declared once:\n// the search box routes by it and the lookup callable re-derives the same answer, so a mis-routed\n// request never looks an email up as a uid or the other way round.\nexport const USER_LOOKUP_EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nexport const USER_LOOKUP_UID_PATTERN = /^[A-Za-z0-9]{28}$/;\nexport type UserSearchKind = 'email' | 'uid' | 'name';\nexport function detectUserSearchKind(query: string): UserSearchKind {\n const trimmed = query.trim();\n if (USER_LOOKUP_EMAIL_PATTERN.test(trimmed)) return 'email';\n if (USER_LOOKUP_UID_PATTERN.test(trimmed)) return 'uid';\n return 'name';\n}\n\n// An admin finds one account by its exact email address or its uid. The answer carries the\n// owner-only email, so it is admin only.\nexport const LookupUserByEmailOrUidInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type LookupUserByEmailOrUidInput = z.infer<typeof LookupUserByEmailOrUidInputSchema>;\nexport const LookedUpUserSchema = z\n .object({\n uid: userIdSchema,\n displayName: z.string(),\n email: z.string(),\n userStatus: userStatusSchema,\n // Present, and true, only for an account on the admin roster.\n isAdmin: z.literal(true).optional(),\n })\n .strict();\nexport type LookedUpUser = z.infer<typeof LookedUpUserSchema>;\n// The one exact match, or `null` when no account with a profile resolves.\nexport const LookupUserByEmailOrUidResultSchema = z\n .object({ user: LookedUpUserSchema.nullable() })\n .strict();\nexport type LookupUserByEmailOrUidResult = z.infer<typeof LookupUserByEmailOrUidResultSchema>;\n\n// An admin searches accounts by the start of their name, over public display identity. Ghosts are\n// not accounts and are left out; a banned account is found, with its status.\nexport const SearchPublicUsersInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type SearchPublicUsersInput = z.infer<typeof SearchPublicUsersInputSchema>;\nexport const PublicUserSearchResultSchema = z\n .object({ uid: userIdSchema, displayName: z.string(), userStatus: userStatusSchema })\n .strict();\nexport type PublicUserSearchResult = z.infer<typeof PublicUserSearchResultSchema>;\nexport const SearchPublicUsersResultSchema = z\n .object({ users: z.array(PublicUserSearchResultSchema) })\n .strict();\nexport type SearchPublicUsersResult = z.infer<typeof SearchPublicUsersResultSchema>;\n\n// An admin renames a user. Self-service rename is not a Q-Sports feature.\nexport const UpdateDisplayNameInputSchema = z\n .object({ userId: userIdSchema, newDisplayName: displayNameSchema })\n .strict();\nexport type UpdateDisplayNameInput = z.infer<typeof UpdateDisplayNameInputSchema>;\nexport const UpdateDisplayNameResultSchema = z\n .object({ userId: userIdSchema, displayName: z.string() })\n .strict();\nexport type UpdateDisplayNameResult = z.infer<typeof UpdateDisplayNameResultSchema>;\n\n// An admin grants or revokes the two global roles on `_systemData/adminList`. Four named lists —\n// never a role/action discriminator (RULE-STD-BACKEND-002).\nconst adminListChangeSchema = z.array(userIdSchema).max(MAX_ADMIN_LIST_CHANGES).optional();\nexport const UpdateAdminListInputSchema = z\n .object({\n addAdmins: adminListChangeSchema,\n removeAdmins: adminListChangeSchema,\n addReferees: adminListChangeSchema,\n removeReferees: adminListChangeSchema,\n })\n .strict();\nexport type UpdateAdminListInput = z.infer<typeof UpdateAdminListInputSchema>;\nexport const UpdateAdminListResultSchema = z\n .object({\n adminsGranted: countSchema,\n adminsRevoked: countSchema,\n refereesGranted: countSchema,\n refereesRevoked: countSchema,\n })\n .strict();\nexport type UpdateAdminListResult = z.infer<typeof UpdateAdminListResultSchema>;\n\n// An admin bans an account or lifts its ban. The reason is internal — recorded on the audit event,\n// never shown to the account (RULE-STD-BACKEND-212). Banning or unbanning to the status the account already\n// holds changes nothing.\nexport const AdminUpdateUserStatusInputSchema = z\n .object({ userId: userIdSchema, userStatus: userStatusSchema, reason: repairReasonSchema })\n .strict();\nexport type AdminUpdateUserStatusInput = z.infer<typeof AdminUpdateUserStatusInputSchema>;\n\n// `changed` is whether the status moved.\nexport const AdminUpdateUserStatusResultSchema = z\n .object({\n userId: userIdSchema,\n userStatus: userStatusSchema,\n previousStatus: userStatusSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type AdminUpdateUserStatusResult = z.infer<typeof AdminUpdateUserStatusResultSchema>;\n\n// The `details.reason` of the refusal to ban an account that holds admin standing (RULE-STD-BACKEND-210), so\n// a client can tell it from every other refusal.\nexport const ADMIN_STANDING_BAN_REFUSAL_REASON = 'adminStandingTarget';\n\n// A signed-in login with no profile starts its registration, before `registerUser`: the record the\n// orphan-login cleanup finds it by, and the owner-only private record `registerUser` requires. The\n// caller is `request.auth.uid` and the email comes from its token, so it takes no input.\nexport const CreateRegistrationStartInputSchema = z.object({}).strict();\nexport type CreateRegistrationStartInput = z.infer<typeof CreateRegistrationStartInputSchema>;\n// `started` wrote both records; `alreadyStarted` found the registration already started and wrote\n// nothing — a retry, or a resume after a later step failed; `registrationExpired` found the login\n// claimed by the orphan-registration cleanup and wrote nothing — the person signs up again.\nexport const REGISTRATION_START_OUTCOMES = [\n 'started',\n 'alreadyStarted',\n 'registrationExpired',\n] as const;\nexport type RegistrationStartOutcome = (typeof REGISTRATION_START_OUTCOMES)[number];\nexport const CreateRegistrationStartResultSchema = z\n .object({ outcome: z.enum(REGISTRATION_START_OUTCOMES) })\n .strict();\nexport type CreateRegistrationStartResult = z.infer<typeof CreateRegistrationStartResultSchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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","sourcesContent":["// Callable contracts for user accounts and the global role rosters.\n\nimport { z } from 'zod';\nimport { MAX_ADMIN_LIST_CHANGES } from '../constants/business.js';\nimport {\n countSchema,\n repairReasonSchema,\n userIdSchema,\n userStatusSchema,\n} from '../doc-schemas/atoms.js';\nimport { displayNameSchema } from './atoms.js';\n\n// The signed-in caller finishes registration: profile, public identity, and the display-name\n// reservation are created for `request.auth.uid`. Email comes from the token, never the payload.\nexport const RegisterUserInputSchema = z\n .object({\n displayName: displayNameSchema,\n // The terms checkbox, re-checked server-side: only `true` registers.\n acceptedTerms: z.literal(true),\n })\n .strict();\nexport type RegisterUserInput = z.infer<typeof RegisterUserInputSchema>;\nexport const RegisterUserResultSchema = z.discriminatedUnion('status', [\n // The account is registered (or already was — an idempotent replay).\n z\n .object({ status: z.literal('registered'), userId: userIdSchema, displayName: z.string() })\n .strict(),\n // The orphan-registration cleanup claimed this login for deletion, so the registration cannot\n // finish on it; nothing is written and the person signs up again.\n z.object({ status: z.literal('registrationExpired') }).strict(),\n]);\nexport type RegisterUserResult = z.infer<typeof RegisterUserResultSchema>;\n\n// The register form's check before the login is created: is the name free? It runs before any\n// account exists, over the same name rule `registerUser` takes, and is a soft answer — the claim\n// itself is `registerUser`'s transaction, which refuses `already-exists` when two registrations\n// pass this check at once.\nexport const CheckDisplayNameAvailableInputSchema = z\n .object({ displayName: displayNameSchema })\n .strict();\nexport type CheckDisplayNameAvailableInput = z.infer<typeof CheckDisplayNameAvailableInputSchema>;\n// Why a name is not available. Uniqueness is the only rule a Q-Sports name is held to beyond its\n// input format.\nexport const DISPLAY_NAME_UNAVAILABLE_REASONS = ['taken'] as const;\nexport type DisplayNameUnavailableReason = (typeof DISPLAY_NAME_UNAVAILABLE_REASONS)[number];\nexport const CheckDisplayNameAvailableResultSchema = z\n .object({ available: z.boolean(), reason: z.enum(DISPLAY_NAME_UNAVAILABLE_REASONS).optional() })\n .strict();\nexport type CheckDisplayNameAvailableResult = z.infer<typeof CheckDisplayNameAvailableResultSchema>;\n\n/** The longest text an admin's account search takes: a name, a full email address, or a uid. */\nexport const MAX_USER_SEARCH_QUERY_LENGTH = 100;\n\n// Which read an admin's account search routes to: a full email address or a 28-character Firebase\n// Auth uid is an exact lookup (`lookupUserByEmailOrUid`), anything else a name search. Declared once:\n// the search box routes by it and the lookup callable re-derives the same answer, so a mis-routed\n// request never looks an email up as a uid or the other way round.\nexport const USER_LOOKUP_EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nexport const USER_LOOKUP_UID_PATTERN = /^[A-Za-z0-9]{28}$/;\nexport type UserSearchKind = 'email' | 'uid' | 'name';\nexport function detectUserSearchKind(query: string): UserSearchKind {\n const trimmed = query.trim();\n if (USER_LOOKUP_EMAIL_PATTERN.test(trimmed)) return 'email';\n if (USER_LOOKUP_UID_PATTERN.test(trimmed)) return 'uid';\n return 'name';\n}\n\n// An admin finds one account by its exact email address or its uid. The answer carries the\n// owner-only email, so it is admin only.\nexport const LookupUserByEmailOrUidInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type LookupUserByEmailOrUidInput = z.infer<typeof LookupUserByEmailOrUidInputSchema>;\nexport const LookedUpUserSchema = z\n .object({\n uid: userIdSchema,\n displayName: z.string(),\n email: z.string(),\n userStatus: userStatusSchema,\n // Present, and true, only for an account on the admin roster.\n isAdmin: z.literal(true).optional(),\n })\n .strict();\nexport type LookedUpUser = z.infer<typeof LookedUpUserSchema>;\n// The one exact match, or `null` when no account with a profile resolves.\nexport const LookupUserByEmailOrUidResultSchema = z\n .object({ user: LookedUpUserSchema.nullable() })\n .strict();\nexport type LookupUserByEmailOrUidResult = z.infer<typeof LookupUserByEmailOrUidResultSchema>;\n\n// An admin searches accounts by the start of their name, over public display identity. Ghosts are\n// not accounts and are left out; a banned account is found, with its status.\nexport const SearchPublicUsersInputSchema = z\n .object({ query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH) })\n .strict();\nexport type SearchPublicUsersInput = z.infer<typeof SearchPublicUsersInputSchema>;\nexport const PublicUserSearchResultSchema = z\n .object({ uid: userIdSchema, displayName: z.string(), userStatus: userStatusSchema })\n .strict();\nexport type PublicUserSearchResult = z.infer<typeof PublicUserSearchResultSchema>;\nexport const SearchPublicUsersResultSchema = z\n .object({ users: z.array(PublicUserSearchResultSchema) })\n .strict();\nexport type SearchPublicUsersResult = z.infer<typeof SearchPublicUsersResultSchema>;\n\n// An admin renames a user. Self-service rename is not a Q-Sports feature.\nexport const UpdateDisplayNameInputSchema = z\n .object({ userId: userIdSchema, newDisplayName: displayNameSchema })\n .strict();\nexport type UpdateDisplayNameInput = z.infer<typeof UpdateDisplayNameInputSchema>;\nexport const UpdateDisplayNameResultSchema = z\n .object({ userId: userIdSchema, displayName: z.string() })\n .strict();\nexport type UpdateDisplayNameResult = z.infer<typeof UpdateDisplayNameResultSchema>;\n\n// An admin grants or revokes the two global roles on `_systemData/adminList`. Four named lists —\n// never a role/action discriminator (RULE-STD-BACKEND-002).\nconst adminListChangeSchema = z.array(userIdSchema).max(MAX_ADMIN_LIST_CHANGES).optional();\nexport const UpdateAdminListInputSchema = z\n .object({\n addAdmins: adminListChangeSchema,\n removeAdmins: adminListChangeSchema,\n addReferees: adminListChangeSchema,\n removeReferees: adminListChangeSchema,\n })\n .strict();\nexport type UpdateAdminListInput = z.infer<typeof UpdateAdminListInputSchema>;\nexport const UpdateAdminListResultSchema = z\n .object({\n adminsGranted: countSchema,\n adminsRevoked: countSchema,\n refereesGranted: countSchema,\n refereesRevoked: countSchema,\n })\n .strict();\nexport type UpdateAdminListResult = z.infer<typeof UpdateAdminListResultSchema>;\n\n// The one sentence `updateAdminList` refuses an admin's revoke of their own admin role with, and the\n// role screen shows on the control it withholds.\nexport const ADMIN_SELF_REVOKE_REFUSAL =\n \"You can't revoke your own admin standing. Ask another admin to do it.\";\n\n// An admin bans an account or lifts its ban. The reason is internal — recorded on the audit event,\n// never shown to the account (RULE-STD-BACKEND-212). Banning or unbanning to the status the account already\n// holds changes nothing.\nexport const AdminUpdateUserStatusInputSchema = z\n .object({ userId: userIdSchema, userStatus: userStatusSchema, reason: repairReasonSchema })\n .strict();\nexport type AdminUpdateUserStatusInput = z.infer<typeof AdminUpdateUserStatusInputSchema>;\n\n// `changed` is whether the status moved.\nexport const AdminUpdateUserStatusResultSchema = z\n .object({\n userId: userIdSchema,\n userStatus: userStatusSchema,\n previousStatus: userStatusSchema,\n changed: z.boolean(),\n })\n .strict();\nexport type AdminUpdateUserStatusResult = z.infer<typeof AdminUpdateUserStatusResultSchema>;\n\n// The `details.reason` of the refusal to ban an account that holds admin standing (RULE-STD-BACKEND-210), so\n// a client can tell it from every other refusal.\nexport const ADMIN_STANDING_BAN_REFUSAL_REASON = 'adminStandingTarget';\n\n// A signed-in login with no profile starts its registration, before `registerUser`: the record the\n// orphan-login cleanup finds it by, and the owner-only private record `registerUser` requires. The\n// caller is `request.auth.uid` and the email comes from its token, so it takes no input.\nexport const CreateRegistrationStartInputSchema = z.object({}).strict();\nexport type CreateRegistrationStartInput = z.infer<typeof CreateRegistrationStartInputSchema>;\n// `started` wrote both records; `alreadyStarted` found the registration already started and wrote\n// nothing — a retry, or a resume after a later step failed; `registrationExpired` found the login\n// claimed by the orphan-registration cleanup and wrote nothing — the person signs up again.\nexport const REGISTRATION_START_OUTCOMES = [\n 'started',\n 'alreadyStarted',\n 'registrationExpired',\n] as const;\nexport type RegistrationStartOutcome = (typeof REGISTRATION_START_OUTCOMES)[number];\nexport const CreateRegistrationStartResultSchema = z\n .object({ outcome: z.enum(REGISTRATION_START_OUTCOMES) })\n .strict();\nexport type CreateRegistrationStartResult = z.infer<typeof CreateRegistrationStartResultSchema>;\n"]}
|
package/dist/types/audit.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SystemRole } from './unions.js';
|
|
2
2
|
import { CAPTAIN_TEAM_ROLES } from './unions.js';
|
|
3
|
-
export declare const AUDIT_EVENT_TYPE_KEYS: readonly ["user.accountRegistered", "user.displayNameChanged", "user.abandonedRegistrationDeleted", "user.accountBanned", "user.accountUnbanned", "admin.systemRoleGranted", "admin.systemRoleRevoked", "admin.systemRoleClaimSynced", "appConfig.updated", "landingPage.updated", "league.created", "league.updated", "league.statusChanged", "league.modeSwitched", "waiverTemplate.created", "waiverTemplate.versionPublished", "waiverTemplate.retired", "waiverTemplate.deleted", "gameLocation.created", "gameLocation.updated", "gameLocation.deleted", "picture.added", "picture.replaced", "picture.moved", "picture.featuredChanged", "picture.removed", "award.created", "award.badgeReplaced", "award.deleted", "award.granted", "award.revoked", "hardwareLoanContract.created", "hardwareLoanContract.signed", "hardwareLoanContract.returned", "hardwareLoanContract.deleted", "leagueTeam.created", "ghostPlayer.created", "teamRoster.syncRetried", "teamMembership.roleChanged", "leagueTeam.captainChanged", "leagueTeam.updated", "leagueTeamContact.updated", "teamMembership.removed", "ghostPlayer.removed", "ghostPlayer.linked", "ghostPlayer.closedLeagueLinked", "leagueTeam.deleted", "ghostPlayer.removalStopped", "teamInvitation.created", "teamInvitation.cancelled", "teamInvitation.accepted", "teamInvitation.rejected", "teamJoinRequest.created", "teamJoinRequest.cancelled", "teamJoinRequest.accepted", "teamJoinRequest.rejected", "leagueFreeAgent.created", "leagueFreeAgent.deleted", "leagueFreeAgent.assigned", "signedWaiver.created", "scheduleWeek.created", "scheduleWeek.updated", "sportGame.created", "sportGame.updated", "sportGame.deleted", "sportGame.statEventsRejected", "sportGame.absenceChanged", "sportGame.memoUpdated", "sportGame.jumpBallChanged", "sportGame.finalized", "sportGame.reopened", "sportGame.statsCorrected", "sportGame.statsRecalculated", "stats.aggregateRecalculated", "stats.historicalStatsUpdated", "stats.validationRun", "stats.validationReportDeleted", "stats.unrosteredStatLineResolved", "adminNotification.archived", "adminNotification.archiveAllRequested", "system.manualIntervention", "migrationAction.pageRun", "migrationAction.writesCommitted", "migrationAction.controlRecorded", "migrationAction.checkpointRecorded", "migrationConsole.cutoverRecorded"];
|
|
3
|
+
export declare const AUDIT_EVENT_TYPE_KEYS: readonly ["user.accountRegistered", "user.displayNameChanged", "user.abandonedRegistrationDeleted", "user.signedIn", "user.passwordResetCompleted", "user.accountBanned", "user.accountUnbanned", "admin.systemRoleGranted", "admin.systemRoleRevoked", "admin.systemRoleClaimSynced", "appConfig.updated", "landingPage.updated", "league.created", "league.updated", "league.statusChanged", "league.modeSwitched", "waiverTemplate.created", "waiverTemplate.versionPublished", "waiverTemplate.retired", "waiverTemplate.deleted", "gameLocation.created", "gameLocation.updated", "gameLocation.deleted", "picture.added", "picture.replaced", "picture.moved", "picture.featuredChanged", "picture.removed", "award.created", "award.badgeReplaced", "award.deleted", "award.granted", "award.revoked", "hardwareLoanContract.created", "hardwareLoanContract.signed", "hardwareLoanContract.returned", "hardwareLoanContract.deleted", "leagueTeam.created", "ghostPlayer.created", "teamRoster.syncRetried", "teamMembership.roleChanged", "leagueTeam.captainChanged", "leagueTeam.updated", "leagueTeamContact.updated", "teamMembership.removed", "ghostPlayer.removed", "ghostPlayer.linked", "ghostPlayer.closedLeagueLinked", "leagueTeam.deleted", "ghostPlayer.removalStopped", "teamInvitation.created", "teamInvitation.cancelled", "teamInvitation.accepted", "teamInvitation.rejected", "teamJoinRequest.created", "teamJoinRequest.cancelled", "teamJoinRequest.accepted", "teamJoinRequest.rejected", "leagueFreeAgent.created", "leagueFreeAgent.deleted", "leagueFreeAgent.assigned", "signedWaiver.created", "scheduleWeek.created", "scheduleWeek.updated", "sportGame.created", "sportGame.updated", "sportGame.deleted", "sportGame.statEventsRejected", "sportGame.absenceChanged", "sportGame.memoUpdated", "sportGame.jumpBallChanged", "sportGame.finalized", "sportGame.reopened", "sportGame.statsCorrected", "sportGame.statsRecalculated", "stats.aggregateRecalculated", "stats.historicalStatsUpdated", "stats.validationRun", "stats.validationReportDeleted", "stats.unrosteredStatLineResolved", "adminNotification.archived", "adminNotification.archiveAllRequested", "system.manualIntervention", "migrationAction.pageRun", "migrationAction.writesCommitted", "migrationAction.controlRecorded", "migrationAction.checkpointRecorded", "migrationConsole.cutoverRecorded"];
|
|
4
4
|
export type AuditEventType = (typeof AUDIT_EVENT_TYPE_KEYS)[number];
|
|
5
5
|
export declare const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS: readonly ["ghostPlayer.linked", "ghostPlayer.closedLeagueLinked"];
|
|
6
6
|
export type GhostLinkAuditEventType = (typeof GHOST_LINK_AUDIT_EVENT_TYPE_KEYS)[number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,qBAAqB,0xEA2IxB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIpE,eAAO,MAAM,gCAAgC,mEAGC,CAAC;AAC/C,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,gCAAgC,CAAC,CAAC,MAAM,CAAC,CAAC;AAUxF,eAAO,MAAM,qBAAqB,4EAMxB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,2BAA2B,2CAGM,CAAC;AAC/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/E,eAAO,MAAM,+BAA+B,4CAIE,CAAC;AAC/C,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtF,eAAO,MAAM,wBAAwB,mDAAoD,CAAC;AAC1F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAMlE,MAAM,MAAM,UAAU,GAClB;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,sBAAsB,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/F;IACE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,UAAU,CAAC;CACxB,CAAC;AAEN,MAAM,WAAW,WAAW;IAE1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,iCAAkC,CAAC;AACjE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
package/dist/types/audit.js
CHANGED
|
@@ -9,6 +9,10 @@ export const AUDIT_EVENT_TYPE_KEYS = [
|
|
|
9
9
|
'user.displayNameChanged',
|
|
10
10
|
// The scheduled sweep deleted a sign-in account that never finished registering (no profile)
|
|
11
11
|
'user.abandonedRegistrationDeleted',
|
|
12
|
+
// A successful sign-up or sign-in, and a completed password reset, recorded after the fact from
|
|
13
|
+
// Identity Platform's user-activity log
|
|
14
|
+
'user.signedIn',
|
|
15
|
+
'user.passwordResetCompleted',
|
|
12
16
|
// Account status — an admin banned an account or lifted its ban
|
|
13
17
|
'user.accountBanned',
|
|
14
18
|
'user.accountUnbanned',
|
package/dist/types/audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"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","sourcesContent":["// The audit vocabulary: the closed event-type union (RULE-STD-BACKEND-202) and how an actor was acting\n// (RULE-STD-BACKEND-205). The document schema is in ../doc-schemas/audit-event.ts.\n//\n// The union is closed: a new sensitive action adds its event types here, in the same change\n// (RULE-STD-BACKEND-202).\n\nimport type { SystemRole } from './unions.js';\nimport { CAPTAIN_TEAM_ROLES } from './unions.js';\n\nexport const AUDIT_EVENT_TYPE_KEYS = [\n // Accounts\n 'user.accountRegistered',\n 'user.displayNameChanged',\n // The scheduled sweep deleted a sign-in account that never finished registering (no profile)\n 'user.abandonedRegistrationDeleted',\n // Account status — an admin banned an account or lifted its ban\n 'user.accountBanned',\n 'user.accountUnbanned',\n // Global roles — the policy decision (callable) and the claim propagation (trigger)\n 'admin.systemRoleGranted',\n 'admin.systemRoleRevoked',\n 'admin.systemRoleClaimSynced',\n // App configuration — the operational levers on `_appConfig/app`, and the landing page copy\n 'appConfig.updated',\n 'landingPage.updated',\n // Leagues — created, settings edited, status moved, mode switched\n 'league.created',\n 'league.updated',\n 'league.statusChanged',\n 'league.modeSwitched',\n // Waiver templates — created, a new wording published, retired or deleted\n 'waiverTemplate.created',\n 'waiverTemplate.versionPublished',\n 'waiverTemplate.retired',\n 'waiverTemplate.deleted',\n // Game locations\n 'gameLocation.created',\n 'gameLocation.updated',\n 'gameLocation.deleted',\n // Pictures — published to a gallery or a slot by the picture processor (attributed to the admin\n // who uploaded it), and ordered, featured, and removed by the admin picture callables\n 'picture.added',\n 'picture.replaced',\n 'picture.moved',\n 'picture.featuredChanged',\n 'picture.removed',\n // Awards — an award created by its first badge's publication, its badge replaced, the award\n // deleted once nobody holds it, and an award granted to or revoked from one account\n 'award.created',\n 'award.badgeReplaced',\n 'award.deleted',\n 'award.granted',\n 'award.revoked',\n // Hardware contracts — a loan created for a referee, signed by them, its equipment returned, and a\n // contract never signed deleted\n 'hardwareLoanContract.created',\n 'hardwareLoanContract.signed',\n 'hardwareLoanContract.returned',\n 'hardwareLoanContract.deleted',\n // Teams — created with its captain, a ghost player added, a team's failed roster work retried\n 'leagueTeam.created',\n 'ghostPlayer.created',\n 'teamRoster.syncRetried',\n // Team management — a member promoted to co-captain or demoted to player, the captain changed by\n // an admin, the team's name or type edited by an admin, and its contact phone set by an admin\n 'teamMembership.roleChanged',\n 'leagueTeam.captainChanged',\n 'leagueTeam.updated',\n 'leagueTeamContact.updated',\n // Exits — a membership removed, a never-played ghost removed, a ghost linked by either link, and a\n // never-played team deleted; each targets what it deleted, which the migration's live\n // verifications read as proof the product removed it\n 'teamMembership.removed',\n 'ghostPlayer.removed',\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n 'leagueTeam.deleted',\n // A ghost's removal stopped part-way because the ghost came to have played: the games it held are\n // released, and the finished-game entries it had already taken off are named\n 'ghostPlayer.removalStopped',\n // Joining a team — an invitation sent, withdrawn, accepted, or declined; a join request sent,\n // withdrawn, accepted, or rejected; a free-agent signup made, withdrawn, or answered by an admin\n // placing the player on a team\n 'teamInvitation.created',\n 'teamInvitation.cancelled',\n 'teamInvitation.accepted',\n 'teamInvitation.rejected',\n 'teamJoinRequest.created',\n 'teamJoinRequest.cancelled',\n 'teamJoinRequest.accepted',\n 'teamJoinRequest.rejected',\n 'leagueFreeAgent.created',\n 'leagueFreeAgent.deleted',\n 'leagueFreeAgent.assigned',\n // Signed waivers — a legal record, signed by its subject or witnessed for a ghost\n 'signedWaiver.created',\n // Schedules — a week created with its games or its shared fields edited; one game added, edited\n // (moved, rescheduled, or its teams replaced), or deleted with its events and roster\n 'scheduleWeek.created',\n 'scheduleWeek.updated',\n 'sportGame.created',\n 'sportGame.updated',\n 'sportGame.deleted',\n // Live scoring — a scoring write refused its caller's authority (a click writes no success event:\n // the stat event document is its own record), a roster entry marked absent or present, a\n // scorer's note on one person changed, and the jump-ball possession arrow moved\n 'sportGame.statEventsRejected',\n 'sportGame.absenceChanged',\n 'sportGame.memoUpdated',\n 'sportGame.jumpBallChanged',\n // Finalizing — a game finalized, its numbers made permanent in every derived destination, and an\n // admin's reopening of a finalized game, which takes them back out\n 'sportGame.finalized',\n 'sportGame.reopened',\n // Fix stats — a game's numbers corrected (targets, or the stored numbers kept) or restored from\n // its events; a derived aggregate rebuilt; and a person's pre-Q-Sports baseline written\n 'sportGame.statsCorrected',\n 'sportGame.statsRecalculated',\n 'stats.aggregateRecalculated',\n 'stats.historicalStatsUpdated',\n // A stats check ran to its end: its scope, its summary, and its counts by kind.\n 'stats.validationRun',\n // An admin deleted a stats check's report: its id, scope, summary, and counts by kind.\n 'stats.validationReportDeleted',\n // The migration's placement of a recorded stat line no roster entry or play could place: the\n // admin names the team, and the game's copy places the line there\n 'stats.unrosteredStatLineResolved',\n // Admin notifications — a shared card archived, which takes it off every admin's list; and an\n // admin's archive-all decision, recorded once when the job is written, with the request's origin\n 'adminNotification.archived',\n 'adminNotification.archiveAllRequested',\n // An operator's manual intervention in a durable pipeline — a dead-lettered row put back to work,\n // or a refused attempt at one — with the reason the operator gave\n 'system.manualIntervention',\n // The migration console — one page of a cutover action run, with what it read, wrote, and found;\n // the documents an action core wrote and removed, committed in the same batch or transaction as\n // those writes (its action id, operation id, and document ids only — RULE-STD-BACKEND-203); a product\n // control's run recorded once its evidence checked; an operator checkpoint recorded with its\n // evidence; and the cutover, after which the product owns every destination\n 'migrationAction.pageRun',\n 'migrationAction.writesCommitted',\n 'migrationAction.controlRecorded',\n 'migrationAction.checkpointRecorded',\n 'migrationConsole.cutoverRecorded',\n] as const;\nexport type AuditEventType = (typeof AUDIT_EVENT_TYPE_KEYS)[number];\n\n// The two ways a ghost is linked to an account — the normal link and the closed-league link — each\n// committing its own event over the one artifact-moving core.\nexport const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS = [\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n] as const satisfies readonly AuditEventType[];\nexport type GhostLinkAuditEventType = (typeof GHOST_LINK_AUDIT_EVENT_TYPE_KEYS)[number];\n\n// How the actor was acting for the write — never merely which authorities they happen to hold. It is\n// orthogonal to the event type: one event type is produced under several modes, and the mode is what\n// tells an ordinary action from an admin override.\n// user a signed-in account acting on its own behalf\n// teamManager a captain or co-captain acting through their team's membership permissions\n// adminReview an admin or referee doing admin work that no team permission covers\n// adminOverride an admin or referee superseding the team permission a normal entry checks\n// system backend automation with no human caller\nexport const AUDIT_ACTOR_MODE_KEYS = [\n 'user',\n 'teamManager',\n 'adminReview',\n 'adminOverride',\n 'system',\n] as const;\nexport type AuditActorMode = (typeof AUDIT_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_ADMIN_ACTOR_MODE_KEYS = [\n 'adminReview',\n 'adminOverride',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditAdminActorMode = (typeof AUDIT_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS = [\n 'user',\n 'teamManager',\n 'system',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditNonAdminActorMode = (typeof AUDIT_NON_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_SYSTEM_REASON_KEYS = ['trigger', 'scheduledJob', 'migration'] as const;\nexport type AuditSystemReason = (typeof AUDIT_SYSTEM_REASON_KEYS)[number];\n\nexport type CaptainTeamRole = (typeof CAPTAIN_TEAM_ROLES)[number];\n\n// `isAdmin` is metadata only: it records that the caller's token carried a global-role claim (admin\n// or referee) when they acted, and grants nothing. `systemRole` is required on the admin modes and\n// forbidden on the others, so an admin action is never recorded without the authority it used and a\n// non-admin action never carries one.\nexport type AuditActor =\n | { uid: string | null; isAdmin: boolean; actorMode: AuditNonAdminActorMode; systemRole?: never }\n | {\n uid: string | null;\n isAdmin: boolean;\n actorMode: AuditAdminActorMode;\n systemRole: SystemRole;\n };\n\nexport interface AuditTarget {\n // The user the action was performed on, when there is one.\n uid: string | null;\n // The slash path of the document the action changed, when there is one.\n ref: string | null;\n}\n\nexport const AUDIT_RESULT_KEYS = ['success', 'failure'] as const;\nexport type AuditResult = (typeof AUDIT_RESULT_KEYS)[number];\n"]}
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/types/audit.ts"],"names":[],"mappings":"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","sourcesContent":["// The audit vocabulary: the closed event-type union (RULE-STD-BACKEND-202) and how an actor was acting\n// (RULE-STD-BACKEND-205). The document schema is in ../doc-schemas/audit-event.ts.\n//\n// The union is closed: a new sensitive action adds its event types here, in the same change\n// (RULE-STD-BACKEND-202).\n\nimport type { SystemRole } from './unions.js';\nimport { CAPTAIN_TEAM_ROLES } from './unions.js';\n\nexport const AUDIT_EVENT_TYPE_KEYS = [\n // Accounts\n 'user.accountRegistered',\n 'user.displayNameChanged',\n // The scheduled sweep deleted a sign-in account that never finished registering (no profile)\n 'user.abandonedRegistrationDeleted',\n // A successful sign-up or sign-in, and a completed password reset, recorded after the fact from\n // Identity Platform's user-activity log\n 'user.signedIn',\n 'user.passwordResetCompleted',\n // Account status — an admin banned an account or lifted its ban\n 'user.accountBanned',\n 'user.accountUnbanned',\n // Global roles — the policy decision (callable) and the claim propagation (trigger)\n 'admin.systemRoleGranted',\n 'admin.systemRoleRevoked',\n 'admin.systemRoleClaimSynced',\n // App configuration — the operational levers on `_appConfig/app`, and the landing page copy\n 'appConfig.updated',\n 'landingPage.updated',\n // Leagues — created, settings edited, status moved, mode switched\n 'league.created',\n 'league.updated',\n 'league.statusChanged',\n 'league.modeSwitched',\n // Waiver templates — created, a new wording published, retired or deleted\n 'waiverTemplate.created',\n 'waiverTemplate.versionPublished',\n 'waiverTemplate.retired',\n 'waiverTemplate.deleted',\n // Game locations\n 'gameLocation.created',\n 'gameLocation.updated',\n 'gameLocation.deleted',\n // Pictures — published to a gallery or a slot by the picture processor (attributed to the admin\n // who uploaded it), and ordered, featured, and removed by the admin picture callables\n 'picture.added',\n 'picture.replaced',\n 'picture.moved',\n 'picture.featuredChanged',\n 'picture.removed',\n // Awards — an award created by its first badge's publication, its badge replaced, the award\n // deleted once nobody holds it, and an award granted to or revoked from one account\n 'award.created',\n 'award.badgeReplaced',\n 'award.deleted',\n 'award.granted',\n 'award.revoked',\n // Hardware contracts — a loan created for a referee, signed by them, its equipment returned, and a\n // contract never signed deleted\n 'hardwareLoanContract.created',\n 'hardwareLoanContract.signed',\n 'hardwareLoanContract.returned',\n 'hardwareLoanContract.deleted',\n // Teams — created with its captain, a ghost player added, a team's failed roster work retried\n 'leagueTeam.created',\n 'ghostPlayer.created',\n 'teamRoster.syncRetried',\n // Team management — a member promoted to co-captain or demoted to player, the captain changed by\n // an admin, the team's name or type edited by an admin, and its contact phone set by an admin\n 'teamMembership.roleChanged',\n 'leagueTeam.captainChanged',\n 'leagueTeam.updated',\n 'leagueTeamContact.updated',\n // Exits — a membership removed, a never-played ghost removed, a ghost linked by either link, and a\n // never-played team deleted; each targets what it deleted, which the migration's live\n // verifications read as proof the product removed it\n 'teamMembership.removed',\n 'ghostPlayer.removed',\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n 'leagueTeam.deleted',\n // A ghost's removal stopped part-way because the ghost came to have played: the games it held are\n // released, and the finished-game entries it had already taken off are named\n 'ghostPlayer.removalStopped',\n // Joining a team — an invitation sent, withdrawn, accepted, or declined; a join request sent,\n // withdrawn, accepted, or rejected; a free-agent signup made, withdrawn, or answered by an admin\n // placing the player on a team\n 'teamInvitation.created',\n 'teamInvitation.cancelled',\n 'teamInvitation.accepted',\n 'teamInvitation.rejected',\n 'teamJoinRequest.created',\n 'teamJoinRequest.cancelled',\n 'teamJoinRequest.accepted',\n 'teamJoinRequest.rejected',\n 'leagueFreeAgent.created',\n 'leagueFreeAgent.deleted',\n 'leagueFreeAgent.assigned',\n // Signed waivers — a legal record, signed by its subject or witnessed for a ghost\n 'signedWaiver.created',\n // Schedules — a week created with its games or its shared fields edited; one game added, edited\n // (moved, rescheduled, or its teams replaced), or deleted with its events and roster\n 'scheduleWeek.created',\n 'scheduleWeek.updated',\n 'sportGame.created',\n 'sportGame.updated',\n 'sportGame.deleted',\n // Live scoring — a scoring write refused its caller's authority (a click writes no success event:\n // the stat event document is its own record), a roster entry marked absent or present, a\n // scorer's note on one person changed, and the jump-ball possession arrow moved\n 'sportGame.statEventsRejected',\n 'sportGame.absenceChanged',\n 'sportGame.memoUpdated',\n 'sportGame.jumpBallChanged',\n // Finalizing — a game finalized, its numbers made permanent in every derived destination, and an\n // admin's reopening of a finalized game, which takes them back out\n 'sportGame.finalized',\n 'sportGame.reopened',\n // Fix stats — a game's numbers corrected (targets, or the stored numbers kept) or restored from\n // its events; a derived aggregate rebuilt; and a person's pre-Q-Sports baseline written\n 'sportGame.statsCorrected',\n 'sportGame.statsRecalculated',\n 'stats.aggregateRecalculated',\n 'stats.historicalStatsUpdated',\n // A stats check ran to its end: its scope, its summary, and its counts by kind.\n 'stats.validationRun',\n // An admin deleted a stats check's report: its id, scope, summary, and counts by kind.\n 'stats.validationReportDeleted',\n // The migration's placement of a recorded stat line no roster entry or play could place: the\n // admin names the team, and the game's copy places the line there\n 'stats.unrosteredStatLineResolved',\n // Admin notifications — a shared card archived, which takes it off every admin's list; and an\n // admin's archive-all decision, recorded once when the job is written, with the request's origin\n 'adminNotification.archived',\n 'adminNotification.archiveAllRequested',\n // An operator's manual intervention in a durable pipeline — a dead-lettered row put back to work,\n // or a refused attempt at one — with the reason the operator gave\n 'system.manualIntervention',\n // The migration console — one page of a cutover action run, with what it read, wrote, and found;\n // the documents an action core wrote and removed, committed in the same batch or transaction as\n // those writes (its action id, operation id, and document ids only — RULE-STD-BACKEND-203); a product\n // control's run recorded once its evidence checked; an operator checkpoint recorded with its\n // evidence; and the cutover, after which the product owns every destination\n 'migrationAction.pageRun',\n 'migrationAction.writesCommitted',\n 'migrationAction.controlRecorded',\n 'migrationAction.checkpointRecorded',\n 'migrationConsole.cutoverRecorded',\n] as const;\nexport type AuditEventType = (typeof AUDIT_EVENT_TYPE_KEYS)[number];\n\n// The two ways a ghost is linked to an account — the normal link and the closed-league link — each\n// committing its own event over the one artifact-moving core.\nexport const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS = [\n 'ghostPlayer.linked',\n 'ghostPlayer.closedLeagueLinked',\n] as const satisfies readonly AuditEventType[];\nexport type GhostLinkAuditEventType = (typeof GHOST_LINK_AUDIT_EVENT_TYPE_KEYS)[number];\n\n// How the actor was acting for the write — never merely which authorities they happen to hold. It is\n// orthogonal to the event type: one event type is produced under several modes, and the mode is what\n// tells an ordinary action from an admin override.\n// user a signed-in account acting on its own behalf\n// teamManager a captain or co-captain acting through their team's membership permissions\n// adminReview an admin or referee doing admin work that no team permission covers\n// adminOverride an admin or referee superseding the team permission a normal entry checks\n// system backend automation with no human caller\nexport const AUDIT_ACTOR_MODE_KEYS = [\n 'user',\n 'teamManager',\n 'adminReview',\n 'adminOverride',\n 'system',\n] as const;\nexport type AuditActorMode = (typeof AUDIT_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_ADMIN_ACTOR_MODE_KEYS = [\n 'adminReview',\n 'adminOverride',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditAdminActorMode = (typeof AUDIT_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_NON_ADMIN_ACTOR_MODE_KEYS = [\n 'user',\n 'teamManager',\n 'system',\n] as const satisfies readonly AuditActorMode[];\nexport type AuditNonAdminActorMode = (typeof AUDIT_NON_ADMIN_ACTOR_MODE_KEYS)[number];\n\nexport const AUDIT_SYSTEM_REASON_KEYS = ['trigger', 'scheduledJob', 'migration'] as const;\nexport type AuditSystemReason = (typeof AUDIT_SYSTEM_REASON_KEYS)[number];\n\nexport type CaptainTeamRole = (typeof CAPTAIN_TEAM_ROLES)[number];\n\n// `isAdmin` is metadata only: it records that the caller's token carried a global-role claim (admin\n// or referee) when they acted, and grants nothing. `systemRole` is required on the admin modes and\n// forbidden on the others, so an admin action is never recorded without the authority it used and a\n// non-admin action never carries one.\nexport type AuditActor =\n | { uid: string | null; isAdmin: boolean; actorMode: AuditNonAdminActorMode; systemRole?: never }\n | {\n uid: string | null;\n isAdmin: boolean;\n actorMode: AuditAdminActorMode;\n systemRole: SystemRole;\n };\n\nexport interface AuditTarget {\n // The user the action was performed on, when there is one.\n uid: string | null;\n // The slash path of the document the action changed, when there is one.\n ref: string | null;\n}\n\nexport const AUDIT_RESULT_KEYS = ['success', 'failure'] as const;\nexport type AuditResult = (typeof AUDIT_RESULT_KEYS)[number];\n"]}
|
package/dist/types/claims.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import type { UserStatus } from './unions.js';
|
|
2
2
|
export declare const SYSTEM_ROLE_CLAIM_KEYS: {
|
|
3
|
+
readonly admin: "isAdmin";
|
|
4
|
+
readonly referee: "isReferee";
|
|
5
|
+
};
|
|
6
|
+
export declare const USER_STATUS_CLAIM_KEY = "status";
|
|
7
|
+
/**
|
|
8
|
+
* V1's role claim names. Nothing reads them: the roster's claim writer removes them whenever it
|
|
9
|
+
* stamps an account, so the cutover's roster copy re-stamps every live holder under
|
|
10
|
+
* `SYSTEM_ROLE_CLAIM_KEYS` (RULE-STD-ENG-011).
|
|
11
|
+
*/
|
|
12
|
+
export declare const RETIRED_SYSTEM_ROLE_CLAIM_KEYS: {
|
|
3
13
|
readonly admin: "admin";
|
|
4
14
|
readonly referee: "referee";
|
|
5
15
|
};
|
|
6
|
-
export declare const USER_STATUS_CLAIM_KEY = "userStatus";
|
|
7
16
|
export interface QSportsClaims {
|
|
8
|
-
|
|
9
|
-
|
|
17
|
+
isAdmin: boolean;
|
|
18
|
+
isReferee: boolean;
|
|
10
19
|
userStatus: UserStatus;
|
|
11
20
|
}
|
|
12
21
|
export declare const DEFAULT_Q_SPORTS_CLAIMS: QSportsClaims;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../../src/types/claims.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,sBAAsB;;;CAGY,CAAC;AAEhD,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../../src/types/claims.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,eAAO,MAAM,sBAAsB;;;CAGY,CAAC;AAEhD,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;;CAGI,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IAEnB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,eAAO,MAAM,uBAAuB,EAAE,aAIrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAM9E"}
|
package/dist/types/claims.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
// The custom-claim contract — the one declaration both roots parse the ID token against.
|
|
2
2
|
//
|
|
3
|
-
// `
|
|
3
|
+
// `isAdmin` and `isReferee` mirror the `_systemData/adminList` rosters; the `status` claim mirrors the
|
|
4
4
|
// profile's account status so rules and an open client can refuse a banned account that still
|
|
5
5
|
// holds a live token. A claim is a fast hint: a state-changing callable re-reads the roster
|
|
6
6
|
// (RULE-STD-BACKEND-004). Team roles are never claims — they resolve from `teamMemberships` per request.
|
|
7
7
|
export const SYSTEM_ROLE_CLAIM_KEYS = {
|
|
8
|
+
admin: 'isAdmin',
|
|
9
|
+
referee: 'isReferee',
|
|
10
|
+
};
|
|
11
|
+
export const USER_STATUS_CLAIM_KEY = 'status';
|
|
12
|
+
/**
|
|
13
|
+
* V1's role claim names. Nothing reads them: the roster's claim writer removes them whenever it
|
|
14
|
+
* stamps an account, so the cutover's roster copy re-stamps every live holder under
|
|
15
|
+
* `SYSTEM_ROLE_CLAIM_KEYS` (RULE-STD-ENG-011).
|
|
16
|
+
*/
|
|
17
|
+
export const RETIRED_SYSTEM_ROLE_CLAIM_KEYS = {
|
|
8
18
|
admin: 'admin',
|
|
9
19
|
referee: 'referee',
|
|
10
20
|
};
|
|
11
|
-
export const USER_STATUS_CLAIM_KEY = 'userStatus';
|
|
12
21
|
export const DEFAULT_Q_SPORTS_CLAIMS = {
|
|
13
|
-
|
|
14
|
-
|
|
22
|
+
isAdmin: false,
|
|
23
|
+
isReferee: false,
|
|
15
24
|
userStatus: 'active',
|
|
16
25
|
};
|
|
17
26
|
/**
|
|
@@ -21,8 +30,8 @@ export const DEFAULT_Q_SPORTS_CLAIMS = {
|
|
|
21
30
|
*/
|
|
22
31
|
export function parseQSportsClaims(raw) {
|
|
23
32
|
return {
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
isAdmin: raw[SYSTEM_ROLE_CLAIM_KEYS.admin] === true,
|
|
34
|
+
isReferee: raw[SYSTEM_ROLE_CLAIM_KEYS.referee] === true,
|
|
26
35
|
userStatus: raw[USER_STATUS_CLAIM_KEY] === 'banned' ? 'banned' : 'active',
|
|
27
36
|
};
|
|
28
37
|
}
|
package/dist/types/claims.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../../src/types/claims.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../../src/types/claims.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,EAAE;AACF,uGAAuG;AACvG,8FAA8F;AAC9F,4FAA4F;AAC5F,yGAAyG;AAIzG,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,WAAW;CACyB,CAAC;AAEhD,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;CAC2B,CAAC;AAShD,MAAM,CAAC,MAAM,uBAAuB,GAAkB;IACpD,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,QAAQ;CACrB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAA4B;IAC7D,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,KAAK,IAAI;QACnD,SAAS,EAAE,GAAG,CAAC,sBAAsB,CAAC,OAAO,CAAC,KAAK,IAAI;QACvD,UAAU,EAAE,GAAG,CAAC,qBAAqB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;KAC1E,CAAC;AACJ,CAAC","sourcesContent":["// The custom-claim contract — the one declaration both roots parse the ID token against.\n//\n// `isAdmin` and `isReferee` mirror the `_systemData/adminList` rosters; the `status` claim mirrors the\n// profile's account status so rules and an open client can refuse a banned account that still\n// holds a live token. A claim is a fast hint: a state-changing callable re-reads the roster\n// (RULE-STD-BACKEND-004). Team roles are never claims — they resolve from `teamMemberships` per request.\n\nimport type { SystemRole, UserStatus } from './unions.js';\n\nexport const SYSTEM_ROLE_CLAIM_KEYS = {\n admin: 'isAdmin',\n referee: 'isReferee',\n} as const satisfies Record<SystemRole, string>;\n\nexport const USER_STATUS_CLAIM_KEY = 'status';\n\n/**\n * V1's role claim names. Nothing reads them: the roster's claim writer removes them whenever it\n * stamps an account, so the cutover's roster copy re-stamps every live holder under\n * `SYSTEM_ROLE_CLAIM_KEYS` (RULE-STD-ENG-011).\n */\nexport const RETIRED_SYSTEM_ROLE_CLAIM_KEYS = {\n admin: 'admin',\n referee: 'referee',\n} as const satisfies Record<SystemRole, string>;\n\nexport interface QSportsClaims {\n isAdmin: boolean;\n isReferee: boolean;\n // Absent on a token minted before any status was stamped; treated as `active` by the parser.\n userStatus: UserStatus;\n}\n\nexport const DEFAULT_Q_SPORTS_CLAIMS: QSportsClaims = {\n isAdmin: false,\n isReferee: false,\n userStatus: 'active',\n};\n\n/**\n * Parse a raw ID-token claims object into the typed contract. A role is held only on an exact\n * `true`. An absent status claim reads as `active`: the claim only speeds up refusing a banned\n * account, and the server's profile check — which fails closed — is the authority.\n */\nexport function parseQSportsClaims(raw: Record<string, unknown>): QSportsClaims {\n return {\n isAdmin: raw[SYSTEM_ROLE_CLAIM_KEYS.admin] === true,\n isReferee: raw[SYSTEM_ROLE_CLAIM_KEYS.referee] === true,\n userStatus: raw[USER_STATUS_CLAIM_KEY] === 'banned' ? 'banned' : 'active',\n };\n}\n"]}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ export * from './team-creation.js';
|
|
|
5
5
|
export * from './account-status.js';
|
|
6
6
|
export * from './league-join-warning.js';
|
|
7
7
|
export * from './schedules.js';
|
|
8
|
-
export * from './app-routes.js';
|
|
9
8
|
export * from './team-member-actions.js';
|
|
10
9
|
export * from './league-mode.js';
|
|
11
10
|
export * from './league-joining.js';
|