@ttt-productions/q-core 0.1.27 → 0.1.28

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.
@@ -1,3 +1,3 @@
1
- export declare const ADMIN_VIEWS: readonly ["dashboard", "leagues", "people", "stats", "setup", "migration"];
1
+ export declare const ADMIN_VIEWS: readonly ["dashboard", "leagues", "users", "roles", "hardware", "statsReports", "fixStats", "landingPage", "appConfig", "gameLocations", "waiverTemplates", "awards", "capacityLimits", "migration"];
2
2
  export type AdminView = (typeof ADMIN_VIEWS)[number];
3
3
  //# sourceMappingURL=admin-views.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-views.d.ts","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,4EAOd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"admin-views.d.ts","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,sMAed,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -1,11 +1,20 @@
1
1
  // The admin area's views. The admin area is one page, and each view is chosen by its `?view=` slug;
2
- // the dashboard is the bare page. Both roots link into a view, so the slugs are declared here once.
2
+ // the dashboard is the bare page. Every screen is its own view, listed once in the admin sidebar, so
3
+ // both roots link straight to it; the slugs are declared here once.
3
4
  export const ADMIN_VIEWS = [
4
5
  'dashboard',
5
6
  'leagues',
6
- 'people',
7
- 'stats',
8
- 'setup',
7
+ 'users',
8
+ 'roles',
9
+ 'hardware',
10
+ 'statsReports',
11
+ 'fixStats',
12
+ 'landingPage',
13
+ 'appConfig',
14
+ 'gameLocations',
15
+ 'waiverTemplates',
16
+ 'awards',
17
+ 'capacityLimits',
9
18
  'migration',
10
19
  ];
11
20
  //# sourceMappingURL=admin-views.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin-views.js","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,oGAAoG;AAEpG,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,SAAS;IACT,QAAQ;IACR,OAAO;IACP,OAAO;IACP,WAAW;CACH,CAAC","sourcesContent":["// The admin area's views. The admin area is one page, and each view is chosen by its `?view=` slug;\n// the dashboard is the bare page. Both roots link into a view, so the slugs are declared here once.\n\nexport const ADMIN_VIEWS = [\n 'dashboard',\n 'leagues',\n 'people',\n 'stats',\n 'setup',\n 'migration',\n] as const;\n\nexport type AdminView = (typeof ADMIN_VIEWS)[number];\n"]}
1
+ {"version":3,"file":"admin-views.js","sourceRoot":"","sources":["../../src/constants/admin-views.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,qGAAqG;AACrG,oEAAoE;AAEpE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,SAAS;IACT,OAAO;IACP,OAAO;IACP,UAAU;IACV,cAAc;IACd,UAAU;IACV,aAAa;IACb,WAAW;IACX,eAAe;IACf,iBAAiB;IACjB,QAAQ;IACR,gBAAgB;IAChB,WAAW;CACH,CAAC","sourcesContent":["// The admin area's views. The admin area is one page, and each view is chosen by its `?view=` slug;\n// the dashboard is the bare page. Every screen is its own view, listed once in the admin sidebar, so\n// both roots link straight to it; the slugs are declared here once.\n\nexport const ADMIN_VIEWS = [\n 'dashboard',\n 'leagues',\n 'users',\n 'roles',\n 'hardware',\n 'statsReports',\n 'fixStats',\n 'landingPage',\n 'appConfig',\n 'gameLocations',\n 'waiverTemplates',\n 'awards',\n 'capacityLimits',\n 'migration',\n] as const;\n\nexport type AdminView = (typeof ADMIN_VIEWS)[number];\n"]}
@@ -4,7 +4,7 @@ import type { SportKey } from '../types/sports.js';
4
4
  export declare const HALL_OF_FAME_SPORT_PARAM = "sport";
5
5
  /** The query-string key the admin page's views live under. */
6
6
  export declare const ADMIN_VIEW_PARAM = "view";
7
- /** The query-string key a view's sections live under. */
7
+ /** The query-string key a league workspace's sections live under. */
8
8
  export declare const ADMIN_SECTION_PARAM = "section";
9
9
  /** The query-string key the Leagues view names the league whose workspace is open under. */
10
10
  export declare const ADMIN_LEAGUE_PARAM = "league";
@@ -30,8 +30,8 @@ export declare const APP_ROUTES: {
30
30
  readonly sportGame: (leagueId: string, gameId: string) => string;
31
31
  /** A game's scoring page, where a scorer records its stats. */
32
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;
33
+ /** An admin view; the dashboard is the bare page. */
34
+ readonly admin: (view?: AdminView) => string;
35
35
  /** A league's admin workspace, on one of its sections when one is named. */
36
36
  readonly adminLeague: (leagueId: string, section?: AdminLeagueWorkspaceSection) => string;
37
37
  /** One team's admin view, inside its league's workspace on the Teams section. */
@@ -1 +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"}
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,qEAAqE;AACrE,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,qDAAqD;4BACtC,SAAS,KAAG,MAAM;IAKjC,4EAA4E;qCACpD,MAAM,YAAY,2BAA2B,KAAG,MAAM;IAE9E,iFAAiF;yCACrD,MAAM,UAAU,MAAM,KAAG,MAAM;CAKnD,CAAC"}
@@ -6,7 +6,7 @@
6
6
  export const HALL_OF_FAME_SPORT_PARAM = 'sport';
7
7
  /** The query-string key the admin page's views live under. */
8
8
  export const ADMIN_VIEW_PARAM = 'view';
9
- /** The query-string key a view's sections live under. */
9
+ /** The query-string key a league workspace's sections live under. */
10
10
  export const ADMIN_SECTION_PARAM = 'section';
11
11
  /** The query-string key the Leagues view names the league whose workspace is open under. */
12
12
  export const ADMIN_LEAGUE_PARAM = 'league';
@@ -51,11 +51,8 @@ export const APP_ROUTES = {
51
51
  sportGame: (leagueId, gameId) => `/league/${enc(leagueId)}/game/${enc(gameId)}`,
52
52
  /** A game's scoring page, where a scorer records its stats. */
53
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
- ]),
54
+ /** An admin view; the dashboard is the bare page. */
55
+ admin: (view) => withQuery('/admin', view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view]]),
59
56
  /** A league's admin workspace, on one of its sections when one is named. */
60
57
  adminLeague: (leagueId, section) => withQuery('/admin', adminLeagueEntries(leagueId, section)),
61
58
  /** One team's admin view, inside its league's workspace on the Teams section. */
@@ -1 +1 @@
1
- {"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"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","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"]}
1
+ {"version":3,"file":"app-routes.js","sourceRoot":"","sources":["../../src/paths/app-routes.ts"],"names":[],"mappings":"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","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 league workspace'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; the dashboard is the bare page. */\n admin: (view?: AdminView): string =>\n withQuery(\n '/admin',\n view === undefined || view === 'dashboard' ? [] : [[ADMIN_VIEW_PARAM, view]],\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"]}
@@ -153,8 +153,8 @@ export const GHOST_LINK_AUDIT_EVENT_TYPE_KEYS = [
153
153
  // orthogonal to the event type: one event type is produced under several modes, and the mode is what
154
154
  // tells an ordinary action from an admin override.
155
155
  // user a signed-in account acting on its own behalf
156
- // teammateUser a member acting inside a team they belong to: a captain or co-captain through
157
- // their membership, or a player on their own record
156
+ // teammateUser a member acting inside a team they belong to: a captain or co-captain acting
157
+ // through their membership, for the team or a player on it
158
158
  // adminReview an admin or referee doing admin work that no team permission covers
159
159
  // adminOverride an admin or referee acting through their role on a team-scoped action no
160
160
  // membership of theirs admits
@@ -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 // 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// teammateUser a member acting inside a team they belong to: a captain or co-captain through\n// their membership, or a player on their own record\n// adminReview an admin or referee doing admin work that no team permission covers\n// adminOverride an admin or referee acting through their role on a team-scoped action no\n// membership of theirs admits\n// system backend automation with no human caller\nexport const AUDIT_ACTOR_MODE_KEYS = [\n 'user',\n 'teammateUser',\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 'teammateUser',\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// teammateUser a member acting inside a team they belong to: a captain or co-captain acting\n// through their membership, for the team or a player on it\n// adminReview an admin or referee doing admin work that no team permission covers\n// adminOverride an admin or referee acting through their role on a team-scoped action no\n// membership of theirs admits\n// system backend automation with no human caller\nexport const AUDIT_ACTOR_MODE_KEYS = [\n 'user',\n 'teammateUser',\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 'teammateUser',\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/q-core",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "description": "Core types, Firestore path constants, zod schemas, and shared constants for Q-Sports",
5
5
  "repository": {
6
6
  "type": "git",