@ttt-productions/ttt-core 0.78.17 → 0.78.19

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.
@@ -27,4 +27,13 @@ export declare const MAX_ARTISAN_LOCATION_LENGTH = 100;
27
27
  export declare const MAX_HISTORY_ITEMS = 10;
28
28
  /** Maximum number of results returned by the search hook. */
29
29
  export declare const SEARCH_RESULT_LIMIT = 6;
30
+ /**
31
+ * Current first-visit site-tour version. The `updateSiteTourPreference` callable stamps
32
+ * this onto `privateData.siteTour.completedVersion` at completion, and the landing
33
+ * eligibility check suppresses the automatic invitation while a member's
34
+ * `completedVersion` equals it. Bump when the permanent-shell-controls tour changes
35
+ * enough to re-invite every member. See
36
+ * docs/design/landing-backstage-guide-and-first-visit-plan.md §10.
37
+ */
38
+ export declare const SITE_TOUR_CURRENT_VERSION = 1;
30
39
  //# sourceMappingURL=business-user.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"business-user.d.ts","sourceRoot":"","sources":["../../src/constants/business-user.ts"],"names":[],"mappings":"AAKA,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,2EAA2E;AAC3E,eAAO,MAAM,cAAc,QAAmB,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAM1D,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,QAAoC,CAAC;AAInE,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,QAA0C,CAAC;AAE/E,0EAA0E;AAC1E,eAAO,MAAM,4BAA4B,QAA+C,CAAC;AAEzF,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,6CAA6C;AAC7C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,yFAAyF;AACzF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAI/C,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAIpC,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,IAAI,CAAC"}
1
+ {"version":3,"file":"business-user.d.ts","sourceRoot":"","sources":["../../src/constants/business-user.ts"],"names":[],"mappings":"AAKA,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,2EAA2E;AAC3E,eAAO,MAAM,cAAc,QAAmB,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAM1D,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,QAAoC,CAAC;AAInE,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,QAA0C,CAAC;AAE/E,0EAA0E;AAC1E,eAAO,MAAM,4BAA4B,QAA+C,CAAC;AAEzF,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,6CAA6C;AAC7C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,yFAAyF;AACzF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAI/C,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAIpC,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAIrC;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC"}
@@ -35,4 +35,14 @@ export const MAX_HISTORY_ITEMS = 10;
35
35
  // --- Search ---
36
36
  /** Maximum number of results returned by the search hook. */
37
37
  export const SEARCH_RESULT_LIMIT = 6;
38
+ // --- First-visit site tour ---
39
+ /**
40
+ * Current first-visit site-tour version. The `updateSiteTourPreference` callable stamps
41
+ * this onto `privateData.siteTour.completedVersion` at completion, and the landing
42
+ * eligibility check suppresses the automatic invitation while a member's
43
+ * `completedVersion` equals it. Bump when the permanent-shell-controls tour changes
44
+ * enough to re-invite every member. See
45
+ * docs/design/landing-backstage-guide-and-first-visit-plan.md §10.
46
+ */
47
+ export const SITE_TOUR_CURRENT_VERSION = 1;
38
48
  //# sourceMappingURL=business-user.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"business-user.js","sourceRoot":"","sources":["../../src/constants/business-user.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+BAA+B;AAE/B,6BAA6B;AAE7B,0DAA0D;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,oCAAoC;AAEpC,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;AAEnE,yEAAyE;AAEzE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC;AAE/E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,4BAA4B,GAAG,aAAa,CAAC,IAAI,CAAC,yBAAyB,CAAC;AAEzF,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C,yFAAyF;AACzF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C,0BAA0B;AAE1B,iFAAiF;AACjF,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,iBAAiB;AAEjB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC","sourcesContent":["// User identity + profile business-rule constants — display names, craft skills,\n// mention history, and search.\n\n// --- User Display Names ---\n\n/** Minimum length for a user display name (inclusive). */\nexport const USERNAME_MIN_LENGTH = 3;\n\n/** Maximum length for a user display name (inclusive). */\nexport const USERNAME_MAX_LENGTH = 20;\n\n/** Allowed characters in a user display name: letters and numbers only. */\nexport const USERNAME_REGEX = /^[a-zA-Z0-9]+$/;\n\n/**\n * Display-name sentinel for an erased account (N3 data-deletion / GDPR erasure).\n * The `publicUsers/{uid}` doc is kept (so uid→name resolvers keep working) with\n * `displayName` set to this and `anonymizedAt` stamped; uid-keyed authorship /\n * share-tombstone records render with this label.\n */\nexport const FORMER_MEMBER_DISPLAY_NAME = 'Former member';\n\nimport { ACTIVE_LIMITS } from './app-mode.js';\n\n// --- User Profile Craft Skills ---\n\n/** Maximum number of craft-skills a user can upload to their profile. Mode-varied. */\nexport const CRAFT_SKILL_LIMIT = ACTIVE_LIMITS.user.maxCraftSkills;\n\n// --- Work-project participation caps (mode-varied, server-enforced) ---\n\n/** Maximum number of work projects an artisan can own (steward) at once. */\nexport const MAX_OWNED_WORK_PROJECTS = ACTIVE_LIMITS.user.maxOwnedWorkProjects;\n\n/** Maximum number of active guild memberships a user can hold at once. */\nexport const MAX_ASSOCIATED_WORK_PROJECTS = ACTIVE_LIMITS.user.maxAssociatedWorkProjects;\n\n/** Maximum number of tags allowed per craftSkill. */\nexport const MAX_CRAFT_SKILL_TAGS = 5;\n\n/** Maximum length for a craft-skill name. */\nexport const MAX_CRAFT_SKILL_NAME_LENGTH = 200;\n\n/** Non-US artisan-interest country/region free-text (input schema + privateData doc). */\nexport const MAX_ARTISAN_LOCATION_LENGTH = 100;\n\n// --- Mention History ---\n\n/** Maximum number of recent mentions kept in the user's mention-history hook. */\nexport const MAX_HISTORY_ITEMS = 10;\n\n// --- Search ---\n\n/** Maximum number of results returned by the search hook. */\nexport const SEARCH_RESULT_LIMIT = 6;\n"]}
1
+ {"version":3,"file":"business-user.js","sourceRoot":"","sources":["../../src/constants/business-user.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+BAA+B;AAE/B,6BAA6B;AAE7B,0DAA0D;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,oCAAoC;AAEpC,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC;AAEnE,yEAAyE;AAEzE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAAC,IAAI,CAAC,oBAAoB,CAAC;AAE/E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,4BAA4B,GAAG,aAAa,CAAC,IAAI,CAAC,yBAAyB,CAAC;AAEzF,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C,yFAAyF;AACzF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C,0BAA0B;AAE1B,iFAAiF;AACjF,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,iBAAiB;AAEjB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,gCAAgC;AAEhC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC","sourcesContent":["// User identity + profile business-rule constants — display names, craft skills,\n// mention history, and search.\n\n// --- User Display Names ---\n\n/** Minimum length for a user display name (inclusive). */\nexport const USERNAME_MIN_LENGTH = 3;\n\n/** Maximum length for a user display name (inclusive). */\nexport const USERNAME_MAX_LENGTH = 20;\n\n/** Allowed characters in a user display name: letters and numbers only. */\nexport const USERNAME_REGEX = /^[a-zA-Z0-9]+$/;\n\n/**\n * Display-name sentinel for an erased account (N3 data-deletion / GDPR erasure).\n * The `publicUsers/{uid}` doc is kept (so uid→name resolvers keep working) with\n * `displayName` set to this and `anonymizedAt` stamped; uid-keyed authorship /\n * share-tombstone records render with this label.\n */\nexport const FORMER_MEMBER_DISPLAY_NAME = 'Former member';\n\nimport { ACTIVE_LIMITS } from './app-mode.js';\n\n// --- User Profile Craft Skills ---\n\n/** Maximum number of craft-skills a user can upload to their profile. Mode-varied. */\nexport const CRAFT_SKILL_LIMIT = ACTIVE_LIMITS.user.maxCraftSkills;\n\n// --- Work-project participation caps (mode-varied, server-enforced) ---\n\n/** Maximum number of work projects an artisan can own (steward) at once. */\nexport const MAX_OWNED_WORK_PROJECTS = ACTIVE_LIMITS.user.maxOwnedWorkProjects;\n\n/** Maximum number of active guild memberships a user can hold at once. */\nexport const MAX_ASSOCIATED_WORK_PROJECTS = ACTIVE_LIMITS.user.maxAssociatedWorkProjects;\n\n/** Maximum number of tags allowed per craftSkill. */\nexport const MAX_CRAFT_SKILL_TAGS = 5;\n\n/** Maximum length for a craft-skill name. */\nexport const MAX_CRAFT_SKILL_NAME_LENGTH = 200;\n\n/** Non-US artisan-interest country/region free-text (input schema + privateData doc). */\nexport const MAX_ARTISAN_LOCATION_LENGTH = 100;\n\n// --- Mention History ---\n\n/** Maximum number of recent mentions kept in the user's mention-history hook. */\nexport const MAX_HISTORY_ITEMS = 10;\n\n// --- Search ---\n\n/** Maximum number of results returned by the search hook. */\nexport const SEARCH_RESULT_LIMIT = 6;\n\n// --- First-visit site tour ---\n\n/**\n * Current first-visit site-tour version. The `updateSiteTourPreference` callable stamps\n * this onto `privateData.siteTour.completedVersion` at completion, and the landing\n * eligibility check suppresses the automatic invitation while a member's\n * `completedVersion` equals it. Bump when the permanent-shell-controls tour changes\n * enough to re-invite every member. See\n * docs/design/landing-backstage-guide-and-first-visit-plan.md §10.\n */\nexport const SITE_TOUR_CURRENT_VERSION = 1;\n"]}
@@ -19,4 +19,10 @@ export declare const COMPANION_CHANGE_EVENT = "ttt-company-companion-change";
19
19
  /** Same-tab window event dispatched when the transient dock-puppet pose changes
20
20
  * (in-memory store; never persisted). */
21
21
  export declare const MASCOT_POSE_CHANGE_EVENT = "ttt-bill-pose-change";
22
+ /** localStorage key: 'true' when the member has manually enabled TTT's app-wide
23
+ * reduced-motion preference (the "Motion: Full / Reduced" House control). */
24
+ export declare const REDUCED_MOTION_STORAGE_KEY = "ttt-reduced-motion";
25
+ /** Same-tab window event dispatched when REDUCED_MOTION_STORAGE_KEY changes (localStorage
26
+ * 'storage' events do not fire in the writing tab), mirroring COMPANION_CHANGE_EVENT. */
27
+ export declare const REDUCED_MOTION_CHANGE_EVENT = "ttt-reduced-motion-change";
22
28
  //# sourceMappingURL=storage-keys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage-keys.d.ts","sourceRoot":"","sources":["../../src/constants/storage-keys.ts"],"names":[],"mappings":"AAEA,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,2FAA2F;AAC3F,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AAMtE,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,qFAAqF;AACrF,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D;uCACuC;AACvC,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;AAEnE;sEACsE;AACtE,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AAEjE,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AAErE;0CAC0C;AAC1C,eAAO,MAAM,wBAAwB,yBAAyB,CAAC"}
1
+ {"version":3,"file":"storage-keys.d.ts","sourceRoot":"","sources":["../../src/constants/storage-keys.ts"],"names":[],"mappings":"AAEA,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,2FAA2F;AAC3F,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AAMtE,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,qFAAqF;AACrF,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D;uCACuC;AACvC,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;AAEnE;sEACsE;AACtE,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AAEjE,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AAErE;0CAC0C;AAC1C,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAS/D;8EAC8E;AAC9E,eAAO,MAAM,0BAA0B,uBAAuB,CAAC;AAE/D;0FAC0F;AAC1F,eAAO,MAAM,2BAA2B,8BAA8B,CAAC"}
@@ -23,4 +23,16 @@ export const COMPANION_CHANGE_EVENT = 'ttt-company-companion-change';
23
23
  /** Same-tab window event dispatched when the transient dock-puppet pose changes
24
24
  * (in-memory store; never persisted). */
25
25
  export const MASCOT_POSE_CHANGE_EVENT = 'ttt-bill-pose-change';
26
+ // --- Manual reduced-motion House control (device-local) ---
27
+ // Independent of the companion visibility store above: reducing motion does not hide the
28
+ // companion, and hiding the companion does not change motion. Effective reduced motion is
29
+ // (the device's prefers-reduced-motion request) OR (this manual preference); the device
30
+ // request always wins. Device-local BY DESIGN — never mirrored to Firestore or the private
31
+ // user document (unlike the account-durable site-tour state).
32
+ /** localStorage key: 'true' when the member has manually enabled TTT's app-wide
33
+ * reduced-motion preference (the "Motion: Full / Reduced" House control). */
34
+ export const REDUCED_MOTION_STORAGE_KEY = 'ttt-reduced-motion';
35
+ /** Same-tab window event dispatched when REDUCED_MOTION_STORAGE_KEY changes (localStorage
36
+ * 'storage' events do not fire in the writing tab), mirroring COMPANION_CHANGE_EVENT. */
37
+ export const REDUCED_MOTION_CHANGE_EVENT = 'ttt-reduced-motion-change';
26
38
  //# sourceMappingURL=storage-keys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage-keys.js","sourceRoot":"","sources":["../../src/constants/storage-keys.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEhD,2FAA2F;AAC3F,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEhD,uFAAuF;AACvF,MAAM,CAAC,MAAM,uBAAuB,GAAG,8BAA8B,CAAC;AAEtE,uEAAuE;AACvE,4EAA4E;AAC5E,0DAA0D;AAE1D,qFAAqF;AACrF,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE7D,qFAAqF;AACrF,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;AAE3D;uCACuC;AACvC,MAAM,CAAC,MAAM,6BAA6B,GAAG,qBAAqB,CAAC;AAEnE;sEACsE;AACtE,MAAM,CAAC,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;AAEjE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAG,8BAA8B,CAAC;AAErE;0CAC0C;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC","sourcesContent":["// Well-known keys used in browser sessionStorage / localStorage.\n\n/** sessionStorage key holding the path the user wanted before being redirected to login. */\nexport const REDIRECT_PATH_KEY = 'redirectPath';\n\n/** localStorage key holding the last-seen app version (used by version-gate component). */\nexport const LS_VERSION_KEY = 'ttt-app-version';\n\n/** sessionStorage key marking that a version-mismatch reload was already attempted. */\nexport const SS_RELOAD_ATTEMPTED_KEY = 'ttt-version-reload-attempted';\n\n// --- Company / Green Room dock companion (device-local v1 stores) ---\n// Values are byte-stable for backward compatibility — the historical 'bill'\n// naming predates the Company rename and MUST NOT change.\n\n/** localStorage key holding the user's chosen dock companion id ('bill' | 'kit'). */\nexport const COMPANION_STORAGE_KEY = 'ttt-company-companion';\n\n/** localStorage key: 'true' when the user has hidden the dock companion entirely. */\nexport const MASCOT_HIDDEN_STORAGE_KEY = 'ttt-bill-hidden';\n\n/** localStorage key holding the last-shown dock-bubble line index (avoids an\n * immediate repeat across visits). */\nexport const MASCOT_LINE_INDEX_STORAGE_KEY = 'ttt-bill-line-index';\n\n/** Same-tab window event dispatched when MASCOT_HIDDEN_STORAGE_KEY changes\n * (localStorage 'storage' events do not fire in the writing tab). */\nexport const MASCOT_HIDDEN_CHANGE_EVENT = 'ttt-bill-pref-change';\n\n/** Same-tab window event dispatched when COMPANION_STORAGE_KEY changes. */\nexport const COMPANION_CHANGE_EVENT = 'ttt-company-companion-change';\n\n/** Same-tab window event dispatched when the transient dock-puppet pose changes\n * (in-memory store; never persisted). */\nexport const MASCOT_POSE_CHANGE_EVENT = 'ttt-bill-pose-change';\n"]}
1
+ {"version":3,"file":"storage-keys.js","sourceRoot":"","sources":["../../src/constants/storage-keys.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEhD,2FAA2F;AAC3F,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEhD,uFAAuF;AACvF,MAAM,CAAC,MAAM,uBAAuB,GAAG,8BAA8B,CAAC;AAEtE,uEAAuE;AACvE,4EAA4E;AAC5E,0DAA0D;AAE1D,qFAAqF;AACrF,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE7D,qFAAqF;AACrF,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;AAE3D;uCACuC;AACvC,MAAM,CAAC,MAAM,6BAA6B,GAAG,qBAAqB,CAAC;AAEnE;sEACsE;AACtE,MAAM,CAAC,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;AAEjE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,sBAAsB,GAAG,8BAA8B,CAAC;AAErE;0CAC0C;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAE/D,6DAA6D;AAC7D,yFAAyF;AACzF,0FAA0F;AAC1F,wFAAwF;AACxF,2FAA2F;AAC3F,8DAA8D;AAE9D;8EAC8E;AAC9E,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAE/D;0FAC0F;AAC1F,MAAM,CAAC,MAAM,2BAA2B,GAAG,2BAA2B,CAAC","sourcesContent":["// Well-known keys used in browser sessionStorage / localStorage.\n\n/** sessionStorage key holding the path the user wanted before being redirected to login. */\nexport const REDIRECT_PATH_KEY = 'redirectPath';\n\n/** localStorage key holding the last-seen app version (used by version-gate component). */\nexport const LS_VERSION_KEY = 'ttt-app-version';\n\n/** sessionStorage key marking that a version-mismatch reload was already attempted. */\nexport const SS_RELOAD_ATTEMPTED_KEY = 'ttt-version-reload-attempted';\n\n// --- Company / Green Room dock companion (device-local v1 stores) ---\n// Values are byte-stable for backward compatibility — the historical 'bill'\n// naming predates the Company rename and MUST NOT change.\n\n/** localStorage key holding the user's chosen dock companion id ('bill' | 'kit'). */\nexport const COMPANION_STORAGE_KEY = 'ttt-company-companion';\n\n/** localStorage key: 'true' when the user has hidden the dock companion entirely. */\nexport const MASCOT_HIDDEN_STORAGE_KEY = 'ttt-bill-hidden';\n\n/** localStorage key holding the last-shown dock-bubble line index (avoids an\n * immediate repeat across visits). */\nexport const MASCOT_LINE_INDEX_STORAGE_KEY = 'ttt-bill-line-index';\n\n/** Same-tab window event dispatched when MASCOT_HIDDEN_STORAGE_KEY changes\n * (localStorage 'storage' events do not fire in the writing tab). */\nexport const MASCOT_HIDDEN_CHANGE_EVENT = 'ttt-bill-pref-change';\n\n/** Same-tab window event dispatched when COMPANION_STORAGE_KEY changes. */\nexport const COMPANION_CHANGE_EVENT = 'ttt-company-companion-change';\n\n/** Same-tab window event dispatched when the transient dock-puppet pose changes\n * (in-memory store; never persisted). */\nexport const MASCOT_POSE_CHANGE_EVENT = 'ttt-bill-pose-change';\n\n// --- Manual reduced-motion House control (device-local) ---\n// Independent of the companion visibility store above: reducing motion does not hide the\n// companion, and hiding the companion does not change motion. Effective reduced motion is\n// (the device's prefers-reduced-motion request) OR (this manual preference); the device\n// request always wins. Device-local BY DESIGN — never mirrored to Firestore or the private\n// user document (unlike the account-durable site-tour state).\n\n/** localStorage key: 'true' when the member has manually enabled TTT's app-wide\n * reduced-motion preference (the \"Motion: Full / Reduced\" House control). */\nexport const REDUCED_MOTION_STORAGE_KEY = 'ttt-reduced-motion';\n\n/** Same-tab window event dispatched when REDUCED_MOTION_STORAGE_KEY changes (localStorage\n * 'storage' events do not fire in the writing tab), mirroring COMPANION_CHANGE_EVENT. */\nexport const REDUCED_MOTION_CHANGE_EVENT = 'ttt-reduced-motion-change';\n"]}
@@ -80,6 +80,12 @@ export declare const COLLECTION_SCHEMAS: {
80
80
  terms: z.ZodOptional<z.ZodBoolean>;
81
81
  agreedOn: z.ZodOptional<z.ZodNumber>;
82
82
  }, z.core.$strip>>;
83
+ siteTour: z.ZodOptional<z.ZodObject<{
84
+ completedVersion: z.ZodOptional<z.ZodNumber>;
85
+ completedAt: z.ZodOptional<z.ZodNumber>;
86
+ notTodayDate: z.ZodOptional<z.ZodString>;
87
+ automaticInvitesDisabledAt: z.ZodOptional<z.ZodNumber>;
88
+ }, z.core.$strip>>;
83
89
  statusReason: z.ZodOptional<z.ZodString>;
84
90
  statusReasonAt: z.ZodOptional<z.ZodNumber>;
85
91
  safetyLocked: z.ZodOptional<z.ZodBoolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgM7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqNkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEvE;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;CAmBiC,CAAC;AAEvE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOvC,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgM7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqNkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEvE;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;CAmBiC,CAAC;AAEvE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOvC,CAAC"}
@@ -319,6 +319,28 @@ export declare const UserAgreementsSchema: z.ZodObject<{
319
319
  agreedOn: z.ZodOptional<z.ZodNumber>;
320
320
  }, z.core.$strip>;
321
321
  export type UserAgreements = z.infer<typeof UserAgreementsSchema>;
322
+ /**
323
+ * First-visit site-tour state (account-durable, server-written) stored on
324
+ * `privateData/{uid}.siteTour`. A missing `siteTour` field means the member has never
325
+ * handled the tour. Automatic-invitation eligibility is evaluated in this order:
326
+ * 1. `automaticInvitesDisabledAt` present → never invite automatically ("Don't show
327
+ * this again");
328
+ * 2. `notTodayDate` equals the member's current LOCAL calendar date → do not invite
329
+ * that day ("Not today");
330
+ * 3. `completedVersion` equals `SITE_TOUR_CURRENT_VERSION` → already handled;
331
+ * 4. otherwise → offer the tour.
332
+ * Written ONLY by the `updateSiteTourPreference` callable via the Admin SDK; never
333
+ * client-written. `notTodayDate` is a strict `YYYY-MM-DD` local-date string (same
334
+ * date-string convention as the age cluster's `attestedDateOfBirth`). See
335
+ * docs/design/landing-backstage-guide-and-first-visit-plan.md §10.
336
+ */
337
+ export declare const UserSiteTourStateSchema: z.ZodObject<{
338
+ completedVersion: z.ZodOptional<z.ZodNumber>;
339
+ completedAt: z.ZodOptional<z.ZodNumber>;
340
+ notTodayDate: z.ZodOptional<z.ZodString>;
341
+ automaticInvitesDisabledAt: z.ZodOptional<z.ZodNumber>;
342
+ }, z.core.$strip>;
343
+ export type UserSiteTourState = z.infer<typeof UserSiteTourStateSchema>;
322
344
  /**
323
345
  * Owner-only account state at `userProfiles/{uid}/privateData/{uid}` (readable
324
346
  * only by the owner; never mirrored to publicUsers).
@@ -361,6 +383,12 @@ export declare const UserPrivateDataSchema: z.ZodObject<{
361
383
  terms: z.ZodOptional<z.ZodBoolean>;
362
384
  agreedOn: z.ZodOptional<z.ZodNumber>;
363
385
  }, z.core.$strip>>;
386
+ siteTour: z.ZodOptional<z.ZodObject<{
387
+ completedVersion: z.ZodOptional<z.ZodNumber>;
388
+ completedAt: z.ZodOptional<z.ZodNumber>;
389
+ notTodayDate: z.ZodOptional<z.ZodString>;
390
+ automaticInvitesDisabledAt: z.ZodOptional<z.ZodNumber>;
391
+ }, z.core.$strip>>;
364
392
  statusReason: z.ZodOptional<z.ZodString>;
365
393
  statusReasonAt: z.ZodOptional<z.ZodNumber>;
366
394
  safetyLocked: z.ZodOptional<z.ZodBoolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/user.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB;;yDAEyD;AACzD,eAAO,MAAM,uBAAuB;;;;EAA4C,CAAC;AACjF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAOxE,eAAO,MAAM,oBAAoB;;;;EAAoD,CAAC;AACtF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE,eAAO,MAAM,+BAA+B;;;;;;kBAKjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAKxF,eAAO,MAAM,2BAA2B;;;;;;;;kBAM7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAoBhF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAe3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,uBAAuB;;;;;;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBAOjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,2BAA2B;;;;;;iBAMtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,oBAAoB;;;;;;;iBAO/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0ChC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/user.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB;;yDAEyD;AACzD,eAAO,MAAM,uBAAuB;;;;EAA4C,CAAC;AACjF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAOxE,eAAO,MAAM,oBAAoB;;;;EAAoD,CAAC;AACtF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE,eAAO,MAAM,+BAA+B;;;;;;kBAKjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAKxF,eAAO,MAAM,2BAA2B;;;;;;;;kBAM7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAoBhF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAe3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,uBAAuB;;;;;;;;;iBAKlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBAOjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,2BAA2B;;;;;;iBAMtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,oBAAoB;;;;;;;iBAO/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB;;;;;iBAalC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8ChC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -162,6 +162,35 @@ export const UserAgreementsSchema = z.object({
162
162
  terms: z.boolean().optional(),
163
163
  agreedOn: z.number().optional(),
164
164
  });
165
+ /**
166
+ * First-visit site-tour state (account-durable, server-written) stored on
167
+ * `privateData/{uid}.siteTour`. A missing `siteTour` field means the member has never
168
+ * handled the tour. Automatic-invitation eligibility is evaluated in this order:
169
+ * 1. `automaticInvitesDisabledAt` present → never invite automatically ("Don't show
170
+ * this again");
171
+ * 2. `notTodayDate` equals the member's current LOCAL calendar date → do not invite
172
+ * that day ("Not today");
173
+ * 3. `completedVersion` equals `SITE_TOUR_CURRENT_VERSION` → already handled;
174
+ * 4. otherwise → offer the tour.
175
+ * Written ONLY by the `updateSiteTourPreference` callable via the Admin SDK; never
176
+ * client-written. `notTodayDate` is a strict `YYYY-MM-DD` local-date string (same
177
+ * date-string convention as the age cluster's `attestedDateOfBirth`). See
178
+ * docs/design/landing-backstage-guide-and-first-visit-plan.md §10.
179
+ */
180
+ export const UserSiteTourStateSchema = z.object({
181
+ // The tour version the member completed. The callable stamps SITE_TOUR_CURRENT_VERSION
182
+ // server-side at completion (the version is server-owned, never client-supplied);
183
+ // absent until a completion is recorded.
184
+ completedVersion: z.number().int().optional(),
185
+ // Epoch ms when the tour was completed.
186
+ completedAt: z.number().optional(),
187
+ // The member's LOCAL calendar date (YYYY-MM-DD) recorded by "Not today"; the automatic
188
+ // invitation is suppressed for exactly that date, then offered again on a later date.
189
+ notTodayDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(), // 'YYYY-MM-DD'
190
+ // Epoch ms when the member chose "Don't show this again" (permanent automatic-invite
191
+ // dismissal). Manual replay from Help ignores this without clearing it.
192
+ automaticInvitesDisabledAt: z.number().optional(),
193
+ });
165
194
  /**
166
195
  * Owner-only account state at `userProfiles/{uid}/privateData/{uid}` (readable
167
196
  * only by the owner; never mirrored to publicUsers).
@@ -194,6 +223,10 @@ export const UserPrivateDataSchema = z.object({
194
223
  // acceptHallDownloadAcknowledgement callable; gates the Hall download button.
195
224
  hallDownloadAcknowledgedAt: z.number().optional(),
196
225
  agreements: UserAgreementsSchema.optional(),
226
+ // First-visit site-tour state (account-durable; the SOLE authority for tour
227
+ // eligibility — no local-storage cache/mirror). Absent = never handled. Written only
228
+ // by the updateSiteTourPreference callable. See UserSiteTourStateSchema above.
229
+ siteTour: UserSiteTourStateSchema.optional(),
197
230
  // Moderation: human-readable reason for the current account status (set when an
198
231
  // admin suspends/bans the user). Written by the setUserStatus callable via the
199
232
  // Admin SDK; readable only by the owner (shown in their restricted view).
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/doc-schemas/user.ts"],"names":[],"mappings":"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","sourcesContent":["// User-related Firestore document SCHEMAS — the single source of truth for the\n// `userProfiles/{uid}` doc, its `privateData/{uid}` subdoc, and craft-skill shapes.\n// (The `publicUsers/{uid}` mirror lives in ./publicUser.) TypeScript types are\n// inferred from these schemas via `z.infer`, so a document's shape and its type\n// cannot drift apart. See docs/design/firestore-schema-registry.md (ttt-prod).\n\nimport { z } from 'zod';\nimport { HALL_WING_TYPE_KEYS } from '../types/content.js';\nimport { MAX_ARTISAN_LOCATION_LENGTH } from '../constants/business.js';\nimport { CRAFT_SKILL_TAG_VALUES } from '../constants/options.js';\nimport { userPrivateDataAgeFieldsShape } from './safety/age.js';\nimport { ContentMediaKindSchema } from './media-assets.js';\n\n// The canonical stored media kind — declared once in doc-schemas/media-assets.ts.\nconst mediaKindSchema = ContentMediaKindSchema;\n\n/** The ONE canonical application account status (userProfiles.status is the\n * authoritative value; the chat access projection and the status-reconcile queue\n * derive from the same set). Never re-declare inline. */\nexport const UserAccountStatusSchema = z.enum(['active', 'suspended', 'banned']);\nexport type UserAccountStatus = z.infer<typeof UserAccountStatusSchema>;\n\n// Craft-skill kind — mandatory choice at upload, no default (see\n// CODE_CHANGE_craft_skill_kinds.md). 'original' = the artisan's own original creation;\n// 'mimicOnTtt' = a performance/recreation of work that originated in the TTT community\n// (requires a source reference); 'mimicOffTtt' = a performance/recreation of work from\n// outside TTT (covers covers + public-domain works, no source reference).\nexport const CraftSkillKindSchema = z.enum(['original', 'mimicOnTtt', 'mimicOffTtt']);\nexport type CraftSkillKind = z.infer<typeof CraftSkillKindSchema>;\n\n// Source reference for a 'mimicOnTtt' skill — the original artisan OR the original work,\n// linked mention-style (id only, no name snapshots, resolved at render per the Display\n// Identity Invariant). 'workProject' is the safe framing today; linking a specific hall\n// item is optional future scope.\nexport const CraftSkillSourceReferenceSchema = z\n .object({\n type: z.enum(['user', 'workProject']),\n id: z.string().min(1),\n })\n .strict();\nexport type CraftSkillSourceReference = z.infer<typeof CraftSkillSourceReferenceSchema>;\n\n// The agreed attestation recorded on the doc: which statement (keyed by kind) the\n// uploader agreed to, its version, and when (epoch ms, always a number — never a\n// Firestore Timestamp).\nexport const CraftSkillAttestationSchema = z\n .object({\n statementKind: CraftSkillKindSchema,\n statementVersion: z.number().int().min(1),\n agreedAt: z.number(),\n })\n .strict();\nexport type CraftSkillAttestation = z.infer<typeof CraftSkillAttestationSchema>;\n\n// Base craft-skill fields shared across all kinds. The `kind` + `source` relationship is\n// layered on top as a discriminated union so an invalid combination (e.g. a source on an\n// 'original', or a missing source on a 'mimicOnTtt') fails schema validation.\nconst craftSkillBaseShape = {\n id: z.string(),\n name: z.string(),\n mediaAssetId: z.string(),\n // Canonical discipline-tag allowlist — never open strings (DJ ruling 2026-07-13).\n tags: z.array(z.enum(CRAFT_SKILL_TAG_VALUES)),\n createdAt: z.number(),\n type: mediaKindSchema,\n // Moderation visibility flag. Absent/false = visible; true = hidden by the\n // craft-skill hide cascade (report auto-hide or admin action). Mirrored onto\n // every taggedCraftSkills index doc so discovery surfaces can filter it.\n hidden: z.boolean(),\n attestation: CraftSkillAttestationSchema,\n};\n\nexport const CraftSkillSchema = z.discriminatedUnion('kind', [\n z.object({\n ...craftSkillBaseShape,\n kind: z.literal('original'),\n }),\n z.object({\n ...craftSkillBaseShape,\n kind: z.literal('mimicOnTtt'),\n // REQUIRED for the on-TTT mimic kind: the linked original artisan or work.\n source: CraftSkillSourceReferenceSchema,\n }),\n z.object({\n ...craftSkillBaseShape,\n kind: z.literal('mimicOffTtt'),\n }),\n]);\nexport type CraftSkill = z.infer<typeof CraftSkillSchema>;\n\nexport const CraftSkillReferenceSchema = z.object({\n craftSkillId: z.string(),\n compositeId: z.string(),\n userId: z.string(),\n craftSkillName: z.string(),\n craftSkillAssetId: z.string(),\n craftSkillType: mediaKindSchema,\n tags: z.array(z.enum(CRAFT_SKILL_TAG_VALUES)),\n createdAt: z.number(),\n // Mirror of CraftSkill.hidden; lets the tag-browse filter hidden skills out.\n hidden: z.boolean(),\n // Mirror of CraftSkill.kind so the tag-browse card can render the kind badge without a\n // second read.\n kind: CraftSkillKindSchema,\n // Mirror of CraftSkill.source — present ONLY when kind === 'mimicOnTtt' (the source-doc\n // discriminated union guarantees that invariant on the authoritative side). Lets the\n // browse card render the clickable \"someone performed my work\" source link.\n source: CraftSkillSourceReferenceSchema.optional(),\n});\nexport type CraftSkillReference = z.infer<typeof CraftSkillReferenceSchema>;\n\nexport const MinimalCraftSkillSchema = z.object({\n id: z.string(),\n name: z.string(),\n mediaAssetId: z.string(),\n type: mediaKindSchema,\n});\nexport type MinimalCraftSkill = z.infer<typeof MinimalCraftSkillSchema>;\n\nexport const OwnedWorkProjectSchema = z.object({\n workProjectId: z.string(),\n workingTitle: z.string(),\n workingDescription: z.string(),\n type: z.string(),\n createdOn: z.number(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n});\nexport type OwnedWorkProject = z.infer<typeof OwnedWorkProjectSchema>;\n\nexport const AssociatedWorkProjectSchema = z.object({\n workProjectId: z.string(),\n workingTitle: z.string(),\n workingDescription: z.string(),\n type: z.string(),\n joinedOn: z.number(),\n});\nexport type AssociatedWorkProject = z.infer<typeof AssociatedWorkProjectSchema>;\n\nexport const FullUserSchema = z.object({\n uid: z.string(),\n displayName: z.string(),\n displayName_lowercase: z.string(),\n // One asset, variants full/medium/small in the mediaAssets registry; URLs\n // are built at render time (media-assets-and-protected-serving.md).\n profilePictureAssetId: z.string().nullable().optional(),\n artisanCreator: z.number().optional(),\n // Cosmetic supporter badge. Set true via the Admin SDK inside the Stripe webhook's\n // pledge-record transaction once the user completes a pledge; rendered on the profile\n // page. Lives here (not publicUsers) because userProfiles/{uid} is already readable by\n // any authenticated user, so other viewers see the badge with no mirror. Not PII.\n // Revoked (→ false) on refund once refunds ship.\n hasPledged: z.boolean().optional(),\n // Charter honor stamp: written once at registration by /api/register/complete as\n // byMode(true, false) — true only for accounts created during Charter Season. The\n // flip publish makes new signups false automatically; no backfill, no date math.\n // Backend-only-writable, cosmetic, not PII (docs/charter-season/honor-roll-and-badges.md).\n charterSignupMember: z.boolean().optional(),\n status: UserAccountStatusSchema.optional(),\n // Chat-edge-rebuild account-access domain (Contract B / round-10 blocker 1): the\n // single ban/unban ordering version + state the chat `accountAccess` sync events key\n // on. Backend-only-writable. Deliberate defaults when ABSENT: a never-touched account\n // is `{ accountAccessVersion: 0, accountAccessState: 'active' }` (NOT banned) — bumped\n // atomically on suspend/ban/unban, which enqueue the accountAccessChanged fanout.\n accountAccessVersion: z.number().optional(),\n accountAccessState: UserAccountStatusSchema.optional(),\n // Moderation: set true by the forceDisplayNameReset callable when an admin resets an\n // abusive display name. The app gates the user into a forced \"pick a new name\" flow until\n // they complete it via setMyDisplayName (which clears this). Backend-only-writable (like `status`).\n displayNameResetRequired: z.boolean().optional(),\n ownedWorkProjects: z.array(OwnedWorkProjectSchema).optional(),\n associatedWorkProjects: z.array(AssociatedWorkProjectSchema).optional(),\n createdAt: z.number(),\n // N3 data-deletion / GDPR erasure: epoch ms when the account-deletion scrub\n // anonymized this profile in place. When set, the identity fields have been\n // scrubbed (displayName → the FORMER_MEMBER_DISPLAY_NAME sentinel) and the\n // account is a tombstone. Backend-only-writable.\n anonymizedAt: z.number().optional(),\n});\nexport type FullUser = z.infer<typeof FullUserSchema>;\n\nexport const UserAgreementsSchema = z.object({\n age: z.boolean().optional(),\n nudity: z.boolean().optional(),\n meet: z.boolean().optional(),\n cookies: z.boolean().optional(),\n terms: z.boolean().optional(),\n agreedOn: z.number().optional(),\n});\nexport type UserAgreements = z.infer<typeof UserAgreementsSchema>;\n\n/**\n * Owner-only account state at `userProfiles/{uid}/privateData/{uid}` (readable\n * only by the owner; never mirrored to publicUsers).\n */\nexport const UserPrivateDataSchema = z.object({\n email: z.string(),\n // Epoch ms when the user applied for news/political posting (not a boolean) so the\n // applicant queue can be ordered/triaged by application date. Mirrors the\n // `artisanCreator?: number` grant-timestamp pattern. Truthy when set, so existing\n // truthiness reads keep working; absent until the user applies.\n isWaitingForNewsApproval: z.number().optional(),\n // Epoch ms when the user attested they are a U.S.-based person while becoming an artisan\n // (required at artisan signup for now). Mirrors the ageAttested attestation pattern; written\n // server-side by becomeArtisanCreator.\n usPersonAttestedAt: z.number().optional(),\n // Non-U.S. artisan-interest \"waitlist\" recorded ONLY for adult accounts when a non-U.S. person\n // asks to be notified once creator signups open in their region. Owner-only, backend-written.\n // `requestedAt` is the immutable first-come-first-serve timestamp; `country`/`region` let signups\n // be opened by jurisdiction as each region's laws clear. Mirrors isWaitingForNewsApproval.\n nonUsArtisanInterest: z\n .object({\n country: z.string().min(1).max(MAX_ARTISAN_LOCATION_LENGTH),\n region: z.string().max(MAX_ARTISAN_LOCATION_LENGTH).optional(),\n requestedAt: z.number(),\n })\n .optional(),\n squareStreetzAgreementsDate: z.number().optional(),\n // Epoch ms when the user accepted the one-time Hall download acknowledgement\n // (personal offline use only, no redistribution). Written server-side by the\n // acceptHallDownloadAcknowledgement callable; gates the Hall download button.\n hallDownloadAcknowledgedAt: z.number().optional(),\n agreements: UserAgreementsSchema.optional(),\n // Moderation: human-readable reason for the current account status (set when an\n // admin suspends/bans the user). Written by the setUserStatus callable via the\n // Admin SDK; readable only by the owner (shown in their restricted view).\n // Cleared when the account is reinstated to 'active'.\n statusReason: z.string().optional(),\n statusReasonAt: z.number().optional(),\n // Trust & Safety (§A8): silent interim safety-lock flag. Backend-only-writable,\n // restricted to the owner's view. Set true while a child-safety/NCII action is\n // pending against the account; the app gates the user accordingly.\n safetyLocked: z.boolean().optional(),\n // Trust & Safety (§A7): server-write-only age/registration fields, merged from the\n // standalone age cluster shape (./safety/age.js) so the canonical schema and the\n // age cluster cannot drift.\n ...userPrivateDataAgeFieldsShape,\n});\nexport type UserPrivateData = z.infer<typeof UserPrivateDataSchema>;\n"]}
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/doc-schemas/user.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,oFAAoF;AACpF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAE/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,kFAAkF;AAClF,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAE/C;;yDAEyD;AACzD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGjF,iEAAiE;AACjE,uFAAuF;AACvF,uFAAuF;AACvF,uFAAuF;AACvF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;AAGtF,yFAAyF;AACzF,uFAAuF;AACvF,wFAAwF;AACxF,iCAAiC;AACjC,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC7C,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACtB,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,kFAAkF;AAClF,iFAAiF;AACjF,wBAAwB;AACxB,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC;KACzC,MAAM,CAAC;IACN,aAAa,EAAE,oBAAoB;IACnC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,yFAAyF;AACzF,yFAAyF;AACzF,8EAA8E;AAC9E,MAAM,mBAAmB,GAAG;IAC1B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,kFAAkF;IAClF,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC7C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,IAAI,EAAE,eAAe;IACrB,2EAA2E;IAC3E,6EAA6E;IAC7E,yEAAyE;IACzE,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,WAAW,EAAE,2BAA2B;CACzC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC3D,CAAC,CAAC,MAAM,CAAC;QACP,GAAG,mBAAmB;QACtB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;KAC5B,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,GAAG,mBAAmB;QACtB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;QAC7B,2EAA2E;QAC3E,MAAM,EAAE,+BAA+B;KACxC,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,GAAG,mBAAmB;QACtB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;KAC/B,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC7B,cAAc,EAAE,eAAe;IAC/B,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC7C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,6EAA6E;IAC7E,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,uFAAuF;IACvF,eAAe;IACf,IAAI,EAAE,oBAAoB;IAC1B,wFAAwF;IACxF,qFAAqF;IACrF,4EAA4E;IAC5E,MAAM,EAAE,+BAA+B,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,IAAI,EAAE,eAAe;CACtB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;CAC1C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE;IACjC,0EAA0E;IAC1E,oEAAoE;IACpE,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACvD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,mFAAmF;IACnF,sFAAsF;IACtF,uFAAuF;IACvF,kFAAkF;IAClF,iDAAiD;IACjD,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAClC,iFAAiF;IACjF,kFAAkF;IAClF,iFAAiF;IACjF,2FAA2F;IAC3F,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC3C,MAAM,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IAC1C,iFAAiF;IACjF,qFAAqF;IACrF,sFAAsF;IACtF,uFAAuF;IACvF,kFAAkF;IAClF,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3C,kBAAkB,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IACtD,qFAAqF;IACrF,0FAA0F;IAC1F,oGAAoG;IACpG,wBAAwB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAChD,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,QAAQ,EAAE;IAC7D,sBAAsB,EAAE,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE;IACvE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,iDAAiD;IACjD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC5B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAGH;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,uFAAuF;IACvF,kFAAkF;IAClF,yCAAyC;IACzC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7C,wCAAwC;IACxC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,uFAAuF;IACvF,sFAAsF;IACtF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE,EAAE,eAAe;IACjF,qFAAqF;IACrF,wEAAwE;IACxE,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClD,CAAC,CAAC;AAGH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,mFAAmF;IACnF,0EAA0E;IAC1E,kFAAkF;IAClF,gEAAgE;IAChE,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/C,yFAAyF;IACzF,6FAA6F;IAC7F,uCAAuC;IACvC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,+FAA+F;IAC/F,8FAA8F;IAC9F,kGAAkG;IAClG,2FAA2F;IAC3F,oBAAoB,EAAE,CAAC;SACpB,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,2BAA2B,CAAC;QAC3D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE;QAC9D,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;KACxB,CAAC;SACD,QAAQ,EAAE;IACb,2BAA2B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClD,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjD,UAAU,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IAC3C,4EAA4E;IAC5E,qFAAqF;IACrF,+EAA+E;IAC/E,QAAQ,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IAC5C,gFAAgF;IAChF,+EAA+E;IAC/E,0EAA0E;IAC1E,sDAAsD;IACtD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,gFAAgF;IAChF,+EAA+E;IAC/E,mEAAmE;IACnE,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,mFAAmF;IACnF,iFAAiF;IACjF,4BAA4B;IAC5B,GAAG,6BAA6B;CACjC,CAAC,CAAC","sourcesContent":["// User-related Firestore document SCHEMAS — the single source of truth for the\n// `userProfiles/{uid}` doc, its `privateData/{uid}` subdoc, and craft-skill shapes.\n// (The `publicUsers/{uid}` mirror lives in ./publicUser.) TypeScript types are\n// inferred from these schemas via `z.infer`, so a document's shape and its type\n// cannot drift apart. See docs/design/firestore-schema-registry.md (ttt-prod).\n\nimport { z } from 'zod';\nimport { HALL_WING_TYPE_KEYS } from '../types/content.js';\nimport { MAX_ARTISAN_LOCATION_LENGTH } from '../constants/business.js';\nimport { CRAFT_SKILL_TAG_VALUES } from '../constants/options.js';\nimport { userPrivateDataAgeFieldsShape } from './safety/age.js';\nimport { ContentMediaKindSchema } from './media-assets.js';\n\n// The canonical stored media kind — declared once in doc-schemas/media-assets.ts.\nconst mediaKindSchema = ContentMediaKindSchema;\n\n/** The ONE canonical application account status (userProfiles.status is the\n * authoritative value; the chat access projection and the status-reconcile queue\n * derive from the same set). Never re-declare inline. */\nexport const UserAccountStatusSchema = z.enum(['active', 'suspended', 'banned']);\nexport type UserAccountStatus = z.infer<typeof UserAccountStatusSchema>;\n\n// Craft-skill kind — mandatory choice at upload, no default (see\n// CODE_CHANGE_craft_skill_kinds.md). 'original' = the artisan's own original creation;\n// 'mimicOnTtt' = a performance/recreation of work that originated in the TTT community\n// (requires a source reference); 'mimicOffTtt' = a performance/recreation of work from\n// outside TTT (covers covers + public-domain works, no source reference).\nexport const CraftSkillKindSchema = z.enum(['original', 'mimicOnTtt', 'mimicOffTtt']);\nexport type CraftSkillKind = z.infer<typeof CraftSkillKindSchema>;\n\n// Source reference for a 'mimicOnTtt' skill — the original artisan OR the original work,\n// linked mention-style (id only, no name snapshots, resolved at render per the Display\n// Identity Invariant). 'workProject' is the safe framing today; linking a specific hall\n// item is optional future scope.\nexport const CraftSkillSourceReferenceSchema = z\n .object({\n type: z.enum(['user', 'workProject']),\n id: z.string().min(1),\n })\n .strict();\nexport type CraftSkillSourceReference = z.infer<typeof CraftSkillSourceReferenceSchema>;\n\n// The agreed attestation recorded on the doc: which statement (keyed by kind) the\n// uploader agreed to, its version, and when (epoch ms, always a number — never a\n// Firestore Timestamp).\nexport const CraftSkillAttestationSchema = z\n .object({\n statementKind: CraftSkillKindSchema,\n statementVersion: z.number().int().min(1),\n agreedAt: z.number(),\n })\n .strict();\nexport type CraftSkillAttestation = z.infer<typeof CraftSkillAttestationSchema>;\n\n// Base craft-skill fields shared across all kinds. The `kind` + `source` relationship is\n// layered on top as a discriminated union so an invalid combination (e.g. a source on an\n// 'original', or a missing source on a 'mimicOnTtt') fails schema validation.\nconst craftSkillBaseShape = {\n id: z.string(),\n name: z.string(),\n mediaAssetId: z.string(),\n // Canonical discipline-tag allowlist — never open strings (DJ ruling 2026-07-13).\n tags: z.array(z.enum(CRAFT_SKILL_TAG_VALUES)),\n createdAt: z.number(),\n type: mediaKindSchema,\n // Moderation visibility flag. Absent/false = visible; true = hidden by the\n // craft-skill hide cascade (report auto-hide or admin action). Mirrored onto\n // every taggedCraftSkills index doc so discovery surfaces can filter it.\n hidden: z.boolean(),\n attestation: CraftSkillAttestationSchema,\n};\n\nexport const CraftSkillSchema = z.discriminatedUnion('kind', [\n z.object({\n ...craftSkillBaseShape,\n kind: z.literal('original'),\n }),\n z.object({\n ...craftSkillBaseShape,\n kind: z.literal('mimicOnTtt'),\n // REQUIRED for the on-TTT mimic kind: the linked original artisan or work.\n source: CraftSkillSourceReferenceSchema,\n }),\n z.object({\n ...craftSkillBaseShape,\n kind: z.literal('mimicOffTtt'),\n }),\n]);\nexport type CraftSkill = z.infer<typeof CraftSkillSchema>;\n\nexport const CraftSkillReferenceSchema = z.object({\n craftSkillId: z.string(),\n compositeId: z.string(),\n userId: z.string(),\n craftSkillName: z.string(),\n craftSkillAssetId: z.string(),\n craftSkillType: mediaKindSchema,\n tags: z.array(z.enum(CRAFT_SKILL_TAG_VALUES)),\n createdAt: z.number(),\n // Mirror of CraftSkill.hidden; lets the tag-browse filter hidden skills out.\n hidden: z.boolean(),\n // Mirror of CraftSkill.kind so the tag-browse card can render the kind badge without a\n // second read.\n kind: CraftSkillKindSchema,\n // Mirror of CraftSkill.source — present ONLY when kind === 'mimicOnTtt' (the source-doc\n // discriminated union guarantees that invariant on the authoritative side). Lets the\n // browse card render the clickable \"someone performed my work\" source link.\n source: CraftSkillSourceReferenceSchema.optional(),\n});\nexport type CraftSkillReference = z.infer<typeof CraftSkillReferenceSchema>;\n\nexport const MinimalCraftSkillSchema = z.object({\n id: z.string(),\n name: z.string(),\n mediaAssetId: z.string(),\n type: mediaKindSchema,\n});\nexport type MinimalCraftSkill = z.infer<typeof MinimalCraftSkillSchema>;\n\nexport const OwnedWorkProjectSchema = z.object({\n workProjectId: z.string(),\n workingTitle: z.string(),\n workingDescription: z.string(),\n type: z.string(),\n createdOn: z.number(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n});\nexport type OwnedWorkProject = z.infer<typeof OwnedWorkProjectSchema>;\n\nexport const AssociatedWorkProjectSchema = z.object({\n workProjectId: z.string(),\n workingTitle: z.string(),\n workingDescription: z.string(),\n type: z.string(),\n joinedOn: z.number(),\n});\nexport type AssociatedWorkProject = z.infer<typeof AssociatedWorkProjectSchema>;\n\nexport const FullUserSchema = z.object({\n uid: z.string(),\n displayName: z.string(),\n displayName_lowercase: z.string(),\n // One asset, variants full/medium/small in the mediaAssets registry; URLs\n // are built at render time (media-assets-and-protected-serving.md).\n profilePictureAssetId: z.string().nullable().optional(),\n artisanCreator: z.number().optional(),\n // Cosmetic supporter badge. Set true via the Admin SDK inside the Stripe webhook's\n // pledge-record transaction once the user completes a pledge; rendered on the profile\n // page. Lives here (not publicUsers) because userProfiles/{uid} is already readable by\n // any authenticated user, so other viewers see the badge with no mirror. Not PII.\n // Revoked (→ false) on refund once refunds ship.\n hasPledged: z.boolean().optional(),\n // Charter honor stamp: written once at registration by /api/register/complete as\n // byMode(true, false) — true only for accounts created during Charter Season. The\n // flip publish makes new signups false automatically; no backfill, no date math.\n // Backend-only-writable, cosmetic, not PII (docs/charter-season/honor-roll-and-badges.md).\n charterSignupMember: z.boolean().optional(),\n status: UserAccountStatusSchema.optional(),\n // Chat-edge-rebuild account-access domain (Contract B / round-10 blocker 1): the\n // single ban/unban ordering version + state the chat `accountAccess` sync events key\n // on. Backend-only-writable. Deliberate defaults when ABSENT: a never-touched account\n // is `{ accountAccessVersion: 0, accountAccessState: 'active' }` (NOT banned) — bumped\n // atomically on suspend/ban/unban, which enqueue the accountAccessChanged fanout.\n accountAccessVersion: z.number().optional(),\n accountAccessState: UserAccountStatusSchema.optional(),\n // Moderation: set true by the forceDisplayNameReset callable when an admin resets an\n // abusive display name. The app gates the user into a forced \"pick a new name\" flow until\n // they complete it via setMyDisplayName (which clears this). Backend-only-writable (like `status`).\n displayNameResetRequired: z.boolean().optional(),\n ownedWorkProjects: z.array(OwnedWorkProjectSchema).optional(),\n associatedWorkProjects: z.array(AssociatedWorkProjectSchema).optional(),\n createdAt: z.number(),\n // N3 data-deletion / GDPR erasure: epoch ms when the account-deletion scrub\n // anonymized this profile in place. When set, the identity fields have been\n // scrubbed (displayName → the FORMER_MEMBER_DISPLAY_NAME sentinel) and the\n // account is a tombstone. Backend-only-writable.\n anonymizedAt: z.number().optional(),\n});\nexport type FullUser = z.infer<typeof FullUserSchema>;\n\nexport const UserAgreementsSchema = z.object({\n age: z.boolean().optional(),\n nudity: z.boolean().optional(),\n meet: z.boolean().optional(),\n cookies: z.boolean().optional(),\n terms: z.boolean().optional(),\n agreedOn: z.number().optional(),\n});\nexport type UserAgreements = z.infer<typeof UserAgreementsSchema>;\n\n/**\n * First-visit site-tour state (account-durable, server-written) stored on\n * `privateData/{uid}.siteTour`. A missing `siteTour` field means the member has never\n * handled the tour. Automatic-invitation eligibility is evaluated in this order:\n * 1. `automaticInvitesDisabledAt` present → never invite automatically (\"Don't show\n * this again\");\n * 2. `notTodayDate` equals the member's current LOCAL calendar date → do not invite\n * that day (\"Not today\");\n * 3. `completedVersion` equals `SITE_TOUR_CURRENT_VERSION` → already handled;\n * 4. otherwise → offer the tour.\n * Written ONLY by the `updateSiteTourPreference` callable via the Admin SDK; never\n * client-written. `notTodayDate` is a strict `YYYY-MM-DD` local-date string (same\n * date-string convention as the age cluster's `attestedDateOfBirth`). See\n * docs/design/landing-backstage-guide-and-first-visit-plan.md §10.\n */\nexport const UserSiteTourStateSchema = z.object({\n // The tour version the member completed. The callable stamps SITE_TOUR_CURRENT_VERSION\n // server-side at completion (the version is server-owned, never client-supplied);\n // absent until a completion is recorded.\n completedVersion: z.number().int().optional(),\n // Epoch ms when the tour was completed.\n completedAt: z.number().optional(),\n // The member's LOCAL calendar date (YYYY-MM-DD) recorded by \"Not today\"; the automatic\n // invitation is suppressed for exactly that date, then offered again on a later date.\n notTodayDate: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/).optional(), // 'YYYY-MM-DD'\n // Epoch ms when the member chose \"Don't show this again\" (permanent automatic-invite\n // dismissal). Manual replay from Help ignores this without clearing it.\n automaticInvitesDisabledAt: z.number().optional(),\n});\nexport type UserSiteTourState = z.infer<typeof UserSiteTourStateSchema>;\n\n/**\n * Owner-only account state at `userProfiles/{uid}/privateData/{uid}` (readable\n * only by the owner; never mirrored to publicUsers).\n */\nexport const UserPrivateDataSchema = z.object({\n email: z.string(),\n // Epoch ms when the user applied for news/political posting (not a boolean) so the\n // applicant queue can be ordered/triaged by application date. Mirrors the\n // `artisanCreator?: number` grant-timestamp pattern. Truthy when set, so existing\n // truthiness reads keep working; absent until the user applies.\n isWaitingForNewsApproval: z.number().optional(),\n // Epoch ms when the user attested they are a U.S.-based person while becoming an artisan\n // (required at artisan signup for now). Mirrors the ageAttested attestation pattern; written\n // server-side by becomeArtisanCreator.\n usPersonAttestedAt: z.number().optional(),\n // Non-U.S. artisan-interest \"waitlist\" recorded ONLY for adult accounts when a non-U.S. person\n // asks to be notified once creator signups open in their region. Owner-only, backend-written.\n // `requestedAt` is the immutable first-come-first-serve timestamp; `country`/`region` let signups\n // be opened by jurisdiction as each region's laws clear. Mirrors isWaitingForNewsApproval.\n nonUsArtisanInterest: z\n .object({\n country: z.string().min(1).max(MAX_ARTISAN_LOCATION_LENGTH),\n region: z.string().max(MAX_ARTISAN_LOCATION_LENGTH).optional(),\n requestedAt: z.number(),\n })\n .optional(),\n squareStreetzAgreementsDate: z.number().optional(),\n // Epoch ms when the user accepted the one-time Hall download acknowledgement\n // (personal offline use only, no redistribution). Written server-side by the\n // acceptHallDownloadAcknowledgement callable; gates the Hall download button.\n hallDownloadAcknowledgedAt: z.number().optional(),\n agreements: UserAgreementsSchema.optional(),\n // First-visit site-tour state (account-durable; the SOLE authority for tour\n // eligibility — no local-storage cache/mirror). Absent = never handled. Written only\n // by the updateSiteTourPreference callable. See UserSiteTourStateSchema above.\n siteTour: UserSiteTourStateSchema.optional(),\n // Moderation: human-readable reason for the current account status (set when an\n // admin suspends/bans the user). Written by the setUserStatus callable via the\n // Admin SDK; readable only by the owner (shown in their restricted view).\n // Cleared when the account is reinstated to 'active'.\n statusReason: z.string().optional(),\n statusReasonAt: z.number().optional(),\n // Trust & Safety (§A8): silent interim safety-lock flag. Backend-only-writable,\n // restricted to the owner's view. Set true while a child-safety/NCII action is\n // pending against the account; the app gates the user accordingly.\n safetyLocked: z.boolean().optional(),\n // Trust & Safety (§A7): server-write-only age/registration fields, merged from the\n // standalone age cluster shape (./safety/age.js) so the canonical schema and the\n // age cluster cannot drift.\n ...userPrivateDataAgeFieldsShape,\n});\nexport type UserPrivateData = z.infer<typeof UserPrivateDataSchema>;\n"]}
@@ -18,6 +18,15 @@ export declare const BecomeArtisanCreatorInputSchema: z.ZodObject<{
18
18
  export type BecomeArtisanCreatorInput = z.infer<typeof BecomeArtisanCreatorInputSchema>;
19
19
  export declare const MarkWaitingForNewsApprovalInputSchema: z.ZodObject<{}, z.core.$strict>;
20
20
  export type MarkWaitingForNewsApprovalInput = z.infer<typeof MarkWaitingForNewsApprovalInputSchema>;
21
+ export declare const UpdateSiteTourPreferenceInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
22
+ action: z.ZodLiteral<"deferToday">;
23
+ date: z.ZodString;
24
+ }, z.core.$strict>, z.ZodObject<{
25
+ action: z.ZodLiteral<"dismissAutomaticInvites">;
26
+ }, z.core.$strict>, z.ZodObject<{
27
+ action: z.ZodLiteral<"completeTour">;
28
+ }, z.core.$strict>], "action">;
29
+ export type UpdateSiteTourPreferenceInput = z.infer<typeof UpdateSiteTourPreferenceInputSchema>;
21
30
  export declare const MarkNonUsArtisanInterestInputSchema: z.ZodObject<{
22
31
  country: z.ZodString;
23
32
  region: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB;gFACgF;AAChF,eAAO,MAAM,iBAAiB,aAIN,CAAC;AAEzB,eAAO,MAAM,wCAAwC,iCAAwB,CAAC;AAC9E,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wCAAwC,CAAC,CAAC;AAM1G,eAAO,MAAM,4CAA4C,iCAAwB,CAAC;AAClF,MAAM,MAAM,sCAAsC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4CAA4C,CAAC,CAAC;AAKlH,eAAO,MAAM,+BAA+B;;;;;;;;kBAiBjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,qCAAqC,iCAAwB,CAAC;AAC3E,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAMpG,eAAO,MAAM,mCAAmC;;;kBAGrC,CAAC;AACZ,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAEhG,eAAO,MAAM,uBAAuB;;;;;;;;;kBASzB,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,wBAAwB;;;;;;;;kBAO1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAI1E,eAAO,MAAM,gCAAgC;;;kBAIlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAI1F,eAAO,MAAM,2BAA2B;;kBAE7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAKhF,eAAO,MAAM,oCAAoC;;kBAEtC,CAAC;AACZ,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAKlG,eAAO,MAAM,gCAAgC;;;;;;kBAMlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAK1F,eAAO,MAAM,4BAA4B;;kBAE9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAOlF,eAAO,MAAM,iCAAiC;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC"}
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB;gFACgF;AAChF,eAAO,MAAM,iBAAiB,aAIN,CAAC;AAEzB,eAAO,MAAM,wCAAwC,iCAAwB,CAAC;AAC9E,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wCAAwC,CAAC,CAAC;AAM1G,eAAO,MAAM,4CAA4C,iCAAwB,CAAC;AAClF,MAAM,MAAM,sCAAsC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4CAA4C,CAAC,CAAC;AAKlH,eAAO,MAAM,+BAA+B;;;;;;;;kBAiBjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,qCAAqC,iCAAwB,CAAC;AAC3E,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAapG,eAAO,MAAM,mCAAmC;;;;;;;8BAW9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAMhG,eAAO,MAAM,mCAAmC;;;kBAGrC,CAAC;AACZ,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAEhG,eAAO,MAAM,uBAAuB;;;;;;;;;kBASzB,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,wBAAwB;;;;;;;;kBAO1B,CAAC;AACZ,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAI1E,eAAO,MAAM,gCAAgC;;;kBAIlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAI1F,eAAO,MAAM,2BAA2B;;kBAE7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAKhF,eAAO,MAAM,oCAAoC;;kBAEtC,CAAC;AACZ,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oCAAoC,CAAC,CAAC;AAKlG,eAAO,MAAM,gCAAgC;;;;;;kBAMlC,CAAC;AACZ,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAK1F,eAAO,MAAM,4BAA4B;;kBAE9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAOlF,eAAO,MAAM,iCAAiC;;kBAEnC,CAAC;AACZ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC"}
@@ -37,6 +37,29 @@ export const BecomeArtisanCreatorInputSchema = z.object({
37
37
  }).strict(),
38
38
  }).strict();
39
39
  export const MarkWaitingForNewsApprovalInputSchema = z.object({}).strict();
40
+ // First-visit site-tour preference writer (updateSiteTourPreference). This is the ONE
41
+ // server writer for `privateData/{uid}.siteTour`; the client never writes tour state
42
+ // directly. Discriminated on `action`:
43
+ // - deferToday: records the member's LOCAL calendar `date` ("Not today"); the automatic
44
+ // invitation is suppressed for exactly that date.
45
+ // - dismissAutomaticInvites: records the permanent "Don't show this again" time; no payload.
46
+ // - completeTour: records completion; the callable stamps SITE_TOUR_CURRENT_VERSION and
47
+ // completedAt server-side, so no version is accepted from the client (mirrors the
48
+ // acknowledgement callables that record the authoritative value server-side rather than
49
+ // trusting a client-supplied one). Bump SITE_TOUR_CURRENT_VERSION to re-invite everyone.
50
+ // `date` uses the same strict YYYY-MM-DD convention as the age cluster's attestedDateOfBirth.
51
+ export const UpdateSiteTourPreferenceInputSchema = z.discriminatedUnion('action', [
52
+ z.object({
53
+ action: z.literal('deferToday'),
54
+ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/), // 'YYYY-MM-DD' (member's LOCAL calendar date)
55
+ }).strict(),
56
+ z.object({
57
+ action: z.literal('dismissAutomaticInvites'),
58
+ }).strict(),
59
+ z.object({
60
+ action: z.literal('completeTour'),
61
+ }).strict(),
62
+ ]);
40
63
  // Non-U.S. artisan-interest signup (the FCFS "waitlist" fields on privateData). Mirrors
41
64
  // MarkWaitingForNewsApproval but carries the applicant's country (+ optional region) so signups
42
65
  // can be opened by jurisdiction as each region's laws clear. The callable records it ONLY for
@@ -1 +1 @@
1
- {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { userIdSchema } from './atoms.js';\nimport {\n USERNAME_MIN_LENGTH,\n USERNAME_MAX_LENGTH,\n USERNAME_REGEX,\n MAX_ARTISAN_LOCATION_LENGTH,\n MAX_INTERNAL_REASON_LENGTH,\n MAX_USER_SEARCH_QUERY_LENGTH,\n} from '../constants/business.js';\nimport { UserAccountStatusSchema } from '../doc-schemas/user.js';\n\n/** The ONE composed display-name field validator (length bounds + charset). Every\n * callable accepting a display name spreads this — never a re-composed copy. */\nexport const displayNameSchema = z\n .string()\n .min(USERNAME_MIN_LENGTH)\n .max(USERNAME_MAX_LENGTH)\n .regex(USERNAME_REGEX);\n\nexport const AcceptSquareStreetzAgreementsInputSchema = z.object({}).strict();\nexport type AcceptSquareStreetzAgreementsInput = z.infer<typeof AcceptSquareStreetzAgreementsInputSchema>;\n\n// One-time acknowledgement gate before a user may download Hall content for personal\n// offline use (final wording owned by the legal-and-content step). No payload — the\n// callable records the timestamp in the caller's privateData. See\n// docs/design/media-assets-and-protected-serving.md (Hall/Library downloads).\nexport const AcceptHallDownloadAcknowledgementInputSchema = z.object({}).strict();\nexport type AcceptHallDownloadAcknowledgementInput = z.infer<typeof AcceptHallDownloadAcknowledgementInputSchema>;\n\n// The become-creator dialog's \"I confirm I am 18 years of age or older\" checkbox must reach the\n// server: the callable rejects when absent and records the attestation on the\n// artisanCreator.grantedToUser audit event (immutable, timestamped, with IP/UA) so it is provable.\nexport const BecomeArtisanCreatorInputSchema = z.object({\n ageAttested: z.literal(true),\n // \"I confirm I am a person located in the United States\" — required for now (only U.S. persons\n // may become artisans). Mirrors ageAttested: the callable rejects when absent and records the\n // attestation timestamp (privateData.usPersonAttestedAt) + the grant audit event.\n usPersonAttested: z.literal(true),\n // [Q21.5 REVISED — DJ 2026-07-06] The artisan's date of birth — the ONLY point in the system\n // where a DOB is collected for persistence (registration/upgrade derive the bracket and store\n // nothing). The dialog copy tells the user this must be THEIR birthday: when the payout system\n // ships, it has to match their payout (KYC) identity. The callable re-derives 18+ server-side\n // from this value; an under-18 derivation rejects (failure audit, nothing stored). Stored as\n // privateData attestedDateOfBirth + attestedDobSource 'artisanOnboarding'.\n dob: z.object({\n year: z.number().int(),\n month: z.number().int().min(1).max(12),\n day: z.number().int().min(1).max(31),\n }).strict(),\n}).strict();\nexport type BecomeArtisanCreatorInput = z.infer<typeof BecomeArtisanCreatorInputSchema>;\n\nexport const MarkWaitingForNewsApprovalInputSchema = z.object({}).strict();\nexport type MarkWaitingForNewsApprovalInput = z.infer<typeof MarkWaitingForNewsApprovalInputSchema>;\n\n// Non-U.S. artisan-interest signup (the FCFS \"waitlist\" fields on privateData). Mirrors\n// MarkWaitingForNewsApproval but carries the applicant's country (+ optional region) so signups\n// can be opened by jurisdiction as each region's laws clear. The callable records it ONLY for\n// adult accounts (never a minor's location).\nexport const MarkNonUsArtisanInterestInputSchema = z.object({\n country: z.string().min(1).max(MAX_ARTISAN_LOCATION_LENGTH),\n region: z.string().max(MAX_ARTISAN_LOCATION_LENGTH).optional(),\n}).strict();\nexport type MarkNonUsArtisanInterestInput = z.infer<typeof MarkNonUsArtisanInterestInputSchema>;\n\nexport const RegisterUserInputSchema = z.object({\n displayName: displayNameSchema,\n agreements: z.object({\n age: z.literal(true),\n nudity: z.literal(true),\n meet: z.literal(true),\n cookies: z.literal(true),\n terms: z.literal(true),\n }).strict(),\n}).strict();\nexport type RegisterUserInput = z.infer<typeof RegisterUserInputSchema>;\n\nexport const SetUserStatusInputSchema = z.object({\n userId: userIdSchema,\n status: UserAccountStatusSchema,\n // Required by the callable when status is 'suspended' or 'banned' (shown to the\n // user in their restricted view and recorded on the audit event). Optional here\n // so reinstating to 'active' can omit it; the callable enforces presence.\n reason: z.string().trim().min(1).max(MAX_INTERNAL_REASON_LENGTH).optional(),\n}).strict();\nexport type SetUserStatusInput = z.infer<typeof SetUserStatusInputSchema>;\n\n// Admin forces an abusive display name off a user: the name is swapped to a neutral\n// placeholder, the old name is blocked from reuse, and the user must pick a new one.\nexport const ForceDisplayNameResetInputSchema = z.object({\n userId: userIdSchema,\n // Optional admin note recorded on the audit event.\n reason: z.string().trim().min(1).max(MAX_INTERNAL_REASON_LENGTH).optional(),\n}).strict();\nexport type ForceDisplayNameResetInput = z.infer<typeof ForceDisplayNameResetInputSchema>;\n\n// User completes a forced display-name reset by choosing a new name. Only honored while\n// the caller's userProfiles doc has `displayNameResetRequired === true`.\nexport const SetMyDisplayNameInputSchema = z.object({\n displayName: displayNameSchema,\n}).strict();\nexport type SetMyDisplayNameInput = z.infer<typeof SetMyDisplayNameInputSchema>;\n\n// Unauthenticated soft-check the register page runs BEFORE creating the Auth user so a\n// taken name never orphans an auth account. Mirrors the RegisterUser displayName contract\n// (same length + regex). The authoritative claim still happens inside registerUser.\nexport const CheckDisplayNameAvailableInputSchema = z.object({\n displayName: displayNameSchema,\n}).strict();\nexport type CheckDisplayNameAvailableInput = z.infer<typeof CheckDisplayNameAvailableInputSchema>;\n\n// Teen→adult upgrade: a transient DOB (never persisted) the callable re-derives adult\n// eligibility from server-side against a fresh attestation. Only the shape is validated\n// here; the age math + attestation binding live in the callable.\nexport const UpgradeAccountToAdultInputSchema = z.object({\n dob: z.object({\n year: z.number().int(),\n month: z.number().int().min(1).max(12),\n day: z.number().int().min(1).max(31),\n }).strict(),\n}).strict();\nexport type UpgradeAccountToAdultInput = z.infer<typeof UpgradeAccountToAdultInputSchema>;\n\n// Admin-only user lookup for the User Management view (prefix search on publicUsers by\n// displayName). Only the trimmed query string is validated here; authz (admin/jr-admin)\n// lives in the callable.\nexport const SearchPublicUsersInputSchema = z.object({\n query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH),\n}).strict();\nexport type SearchPublicUsersInput = z.infer<typeof SearchPublicUsersInputSchema>;\n\n// Admin exact-account lookup (\"look up by email or uid\" in User Management): a solo full\n// admin resolves ONE account by its exact email, uid, or display name. The app detects\n// email-vs-uid-vs-name both client- and server-side, so there is ONE query field (mirrors\n// SearchPublicUsersInput's single trimmed-query shape + bound). Only the trimmed query is\n// validated here; authz (full admin) lives in the callable.\nexport const LookupUserByEmailOrUidInputSchema = z.object({\n query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH),\n}).strict();\nexport type LookupUserByEmailOrUidInput = z.infer<typeof LookupUserByEmailOrUidInputSchema>;\n\n"]}
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/schemas/users.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { userIdSchema } from './atoms.js';\nimport {\n USERNAME_MIN_LENGTH,\n USERNAME_MAX_LENGTH,\n USERNAME_REGEX,\n MAX_ARTISAN_LOCATION_LENGTH,\n MAX_INTERNAL_REASON_LENGTH,\n MAX_USER_SEARCH_QUERY_LENGTH,\n} from '../constants/business.js';\nimport { UserAccountStatusSchema } from '../doc-schemas/user.js';\n\n/** The ONE composed display-name field validator (length bounds + charset). Every\n * callable accepting a display name spreads this — never a re-composed copy. */\nexport const displayNameSchema = z\n .string()\n .min(USERNAME_MIN_LENGTH)\n .max(USERNAME_MAX_LENGTH)\n .regex(USERNAME_REGEX);\n\nexport const AcceptSquareStreetzAgreementsInputSchema = z.object({}).strict();\nexport type AcceptSquareStreetzAgreementsInput = z.infer<typeof AcceptSquareStreetzAgreementsInputSchema>;\n\n// One-time acknowledgement gate before a user may download Hall content for personal\n// offline use (final wording owned by the legal-and-content step). No payload — the\n// callable records the timestamp in the caller's privateData. See\n// docs/design/media-assets-and-protected-serving.md (Hall/Library downloads).\nexport const AcceptHallDownloadAcknowledgementInputSchema = z.object({}).strict();\nexport type AcceptHallDownloadAcknowledgementInput = z.infer<typeof AcceptHallDownloadAcknowledgementInputSchema>;\n\n// The become-creator dialog's \"I confirm I am 18 years of age or older\" checkbox must reach the\n// server: the callable rejects when absent and records the attestation on the\n// artisanCreator.grantedToUser audit event (immutable, timestamped, with IP/UA) so it is provable.\nexport const BecomeArtisanCreatorInputSchema = z.object({\n ageAttested: z.literal(true),\n // \"I confirm I am a person located in the United States\" — required for now (only U.S. persons\n // may become artisans). Mirrors ageAttested: the callable rejects when absent and records the\n // attestation timestamp (privateData.usPersonAttestedAt) + the grant audit event.\n usPersonAttested: z.literal(true),\n // [Q21.5 REVISED — DJ 2026-07-06] The artisan's date of birth — the ONLY point in the system\n // where a DOB is collected for persistence (registration/upgrade derive the bracket and store\n // nothing). The dialog copy tells the user this must be THEIR birthday: when the payout system\n // ships, it has to match their payout (KYC) identity. The callable re-derives 18+ server-side\n // from this value; an under-18 derivation rejects (failure audit, nothing stored). Stored as\n // privateData attestedDateOfBirth + attestedDobSource 'artisanOnboarding'.\n dob: z.object({\n year: z.number().int(),\n month: z.number().int().min(1).max(12),\n day: z.number().int().min(1).max(31),\n }).strict(),\n}).strict();\nexport type BecomeArtisanCreatorInput = z.infer<typeof BecomeArtisanCreatorInputSchema>;\n\nexport const MarkWaitingForNewsApprovalInputSchema = z.object({}).strict();\nexport type MarkWaitingForNewsApprovalInput = z.infer<typeof MarkWaitingForNewsApprovalInputSchema>;\n\n// First-visit site-tour preference writer (updateSiteTourPreference). This is the ONE\n// server writer for `privateData/{uid}.siteTour`; the client never writes tour state\n// directly. Discriminated on `action`:\n// - deferToday: records the member's LOCAL calendar `date` (\"Not today\"); the automatic\n// invitation is suppressed for exactly that date.\n// - dismissAutomaticInvites: records the permanent \"Don't show this again\" time; no payload.\n// - completeTour: records completion; the callable stamps SITE_TOUR_CURRENT_VERSION and\n// completedAt server-side, so no version is accepted from the client (mirrors the\n// acknowledgement callables that record the authoritative value server-side rather than\n// trusting a client-supplied one). Bump SITE_TOUR_CURRENT_VERSION to re-invite everyone.\n// `date` uses the same strict YYYY-MM-DD convention as the age cluster's attestedDateOfBirth.\nexport const UpdateSiteTourPreferenceInputSchema = z.discriminatedUnion('action', [\n z.object({\n action: z.literal('deferToday'),\n date: z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/), // 'YYYY-MM-DD' (member's LOCAL calendar date)\n }).strict(),\n z.object({\n action: z.literal('dismissAutomaticInvites'),\n }).strict(),\n z.object({\n action: z.literal('completeTour'),\n }).strict(),\n]);\nexport type UpdateSiteTourPreferenceInput = z.infer<typeof UpdateSiteTourPreferenceInputSchema>;\n\n// Non-U.S. artisan-interest signup (the FCFS \"waitlist\" fields on privateData). Mirrors\n// MarkWaitingForNewsApproval but carries the applicant's country (+ optional region) so signups\n// can be opened by jurisdiction as each region's laws clear. The callable records it ONLY for\n// adult accounts (never a minor's location).\nexport const MarkNonUsArtisanInterestInputSchema = z.object({\n country: z.string().min(1).max(MAX_ARTISAN_LOCATION_LENGTH),\n region: z.string().max(MAX_ARTISAN_LOCATION_LENGTH).optional(),\n}).strict();\nexport type MarkNonUsArtisanInterestInput = z.infer<typeof MarkNonUsArtisanInterestInputSchema>;\n\nexport const RegisterUserInputSchema = z.object({\n displayName: displayNameSchema,\n agreements: z.object({\n age: z.literal(true),\n nudity: z.literal(true),\n meet: z.literal(true),\n cookies: z.literal(true),\n terms: z.literal(true),\n }).strict(),\n}).strict();\nexport type RegisterUserInput = z.infer<typeof RegisterUserInputSchema>;\n\nexport const SetUserStatusInputSchema = z.object({\n userId: userIdSchema,\n status: UserAccountStatusSchema,\n // Required by the callable when status is 'suspended' or 'banned' (shown to the\n // user in their restricted view and recorded on the audit event). Optional here\n // so reinstating to 'active' can omit it; the callable enforces presence.\n reason: z.string().trim().min(1).max(MAX_INTERNAL_REASON_LENGTH).optional(),\n}).strict();\nexport type SetUserStatusInput = z.infer<typeof SetUserStatusInputSchema>;\n\n// Admin forces an abusive display name off a user: the name is swapped to a neutral\n// placeholder, the old name is blocked from reuse, and the user must pick a new one.\nexport const ForceDisplayNameResetInputSchema = z.object({\n userId: userIdSchema,\n // Optional admin note recorded on the audit event.\n reason: z.string().trim().min(1).max(MAX_INTERNAL_REASON_LENGTH).optional(),\n}).strict();\nexport type ForceDisplayNameResetInput = z.infer<typeof ForceDisplayNameResetInputSchema>;\n\n// User completes a forced display-name reset by choosing a new name. Only honored while\n// the caller's userProfiles doc has `displayNameResetRequired === true`.\nexport const SetMyDisplayNameInputSchema = z.object({\n displayName: displayNameSchema,\n}).strict();\nexport type SetMyDisplayNameInput = z.infer<typeof SetMyDisplayNameInputSchema>;\n\n// Unauthenticated soft-check the register page runs BEFORE creating the Auth user so a\n// taken name never orphans an auth account. Mirrors the RegisterUser displayName contract\n// (same length + regex). The authoritative claim still happens inside registerUser.\nexport const CheckDisplayNameAvailableInputSchema = z.object({\n displayName: displayNameSchema,\n}).strict();\nexport type CheckDisplayNameAvailableInput = z.infer<typeof CheckDisplayNameAvailableInputSchema>;\n\n// Teen→adult upgrade: a transient DOB (never persisted) the callable re-derives adult\n// eligibility from server-side against a fresh attestation. Only the shape is validated\n// here; the age math + attestation binding live in the callable.\nexport const UpgradeAccountToAdultInputSchema = z.object({\n dob: z.object({\n year: z.number().int(),\n month: z.number().int().min(1).max(12),\n day: z.number().int().min(1).max(31),\n }).strict(),\n}).strict();\nexport type UpgradeAccountToAdultInput = z.infer<typeof UpgradeAccountToAdultInputSchema>;\n\n// Admin-only user lookup for the User Management view (prefix search on publicUsers by\n// displayName). Only the trimmed query string is validated here; authz (admin/jr-admin)\n// lives in the callable.\nexport const SearchPublicUsersInputSchema = z.object({\n query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH),\n}).strict();\nexport type SearchPublicUsersInput = z.infer<typeof SearchPublicUsersInputSchema>;\n\n// Admin exact-account lookup (\"look up by email or uid\" in User Management): a solo full\n// admin resolves ONE account by its exact email, uid, or display name. The app detects\n// email-vs-uid-vs-name both client- and server-side, so there is ONE query field (mirrors\n// SearchPublicUsersInput's single trimmed-query shape + bound). Only the trimmed query is\n// validated here; authz (full admin) lives in the callable.\nexport const LookupUserByEmailOrUidInputSchema = z.object({\n query: z.string().trim().min(1).max(MAX_USER_SEARCH_QUERY_LENGTH),\n}).strict();\nexport type LookupUserByEmailOrUidInput = z.infer<typeof LookupUserByEmailOrUidInputSchema>;\n\n"]}
@@ -45,8 +45,6 @@ export declare const CreateWorkProjectInputSchema: z.ZodDiscriminatedUnion<[z.Zo
45
45
  }>;
46
46
  }, z.core.$strict>, z.ZodObject<{
47
47
  realmCreationMode: z.ZodLiteral<"newStandaloneRealm">;
48
- realmWorkingTitle: z.ZodString;
49
- realmWorkingDescription: z.ZodString;
50
48
  workingTitle: z.ZodString;
51
49
  workingDescription: z.ZodString;
52
50
  workProjectType: z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"work-project-management.d.ts","sourceRoot":"","sources":["../../src/schemas/work-project-management.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"work-project-management.d.ts","sourceRoot":"","sources":["../../src/schemas/work-project-management.ts"],"names":[],"mappings":"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"}
@@ -58,11 +58,13 @@ export const CreateWorkProjectInputSchema = z.discriminatedUnion('realmCreationM
58
58
  realmWorkingTitle: realmWorkingTitleSchema,
59
59
  realmWorkingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),
60
60
  }).strict(),
61
+ // Standalone realms are background plumbing (DJ ruling 2026-07-19): the user enters NO
62
+ // realm information — the backend creates the realm shell with a synthetic unique
63
+ // title/description (the generated workRealmId), so nothing user-authored exists on it
64
+ // and no human realm name is consumed from the reservedRealmNames namespace.
61
65
  z.object({
62
66
  ...baseFields,
63
67
  realmCreationMode: z.literal('newStandaloneRealm'),
64
- realmWorkingTitle: realmWorkingTitleSchema,
65
- realmWorkingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),
66
68
  }).strict(),
67
69
  z.object({
68
70
  ...baseFields,
@@ -1 +1 @@
1
- {"version":3,"file":"work-project-management.js","sourceRoot":"","sources":["../../src/schemas/work-project-management.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n workProjectIdSchema,\n userIdSchema,\n addRemoveActionSchema,\n workProjectTypeSchema,\n hallWingTypeSchema,\n commissionListingIdSchema,\n commissionProposalIdSchema,\n auditionIdSchema,\n auditionEntryIdSchema,\n craftSkillIdSchema,\n guildInviteConversationStatusSchema,\n} from './atoms.js';\nimport { TRADE_PROFESSION_OPTIONS, TRADE_PROFESSION_VALUES } from '../constants/options.js';\nimport { GUILD_STANDING_VALUES } from '../permissions/index.js';\nimport {\n MAX_GUILD_INVITE_MESSAGE_LENGTH,\n MAX_WORK_PROJECT_TITLE_LENGTH,\n MAX_WORK_PROJECT_DESCRIPTION_LENGTH,\n MAX_WORK_REALM_TITLE_LENGTH,\n MAX_WORK_REALM_DESCRIPTION_LENGTH,\n MAX_CRAFT_SKILL_NAME_LENGTH,\n MAX_FILE_FOLDER_NAME_LENGTH,\n} from '../constants/business.js';\nimport { RealmFileCanonStatusSchema, ContentMediaKindSchema } from '../doc-schemas/media-assets.js';\n\n// ===========================================================================\n// S7 realm shared-files gallery (ARTISAN-ONLY). `mediaAssets` is client-unreadable, so the gallery\n// reads realm-shared work files via THIS server projection callable (never a client query). The\n// callable is artisan-gated; the whole section is hidden from non-artisans. Serving is the reserved\n// `'artisan'` media tier (mutate-in-place scoped→artisan on promote). V1 = view + download.\n// ===========================================================================\n\nexport const RealmSharedFileProjectionSchema = z.object({\n mediaAssetId: z.string(),\n // The canonical stored media kind — RealmSharedFileProjection is a projection OF a\n // MediaAsset, so it shares the ONE ContentMediaKindSchema.\n mediaKind: ContentMediaKindSchema,\n // 'nonCanon' | 'canon' for a shared file (never 'none' — that means not-shared).\n realmFileCanonStatus: RealmFileCanonStatusSchema,\n creatorUid: z.string(),\n // For the per-file steward canon toggle + download (updateWorkFileRealmCanon takes these).\n workProjectId: z.string(),\n workFileId: z.string(),\n}).strict();\nexport type RealmSharedFileProjection = z.infer<typeof RealmSharedFileProjectionSchema>;\n\nexport const GetRealmSharedFilesInputSchema = z.object({\n realmId: z.string().min(1),\n}).strict();\nexport type GetRealmSharedFilesInput = z.infer<typeof GetRealmSharedFilesInputSchema>;\n\nconst baseFields = {\n workingTitle: z.string().min(1).max(MAX_WORK_PROJECT_TITLE_LENGTH),\n workingDescription: z.string().min(1).max(MAX_WORK_PROJECT_DESCRIPTION_LENGTH),\n workProjectType: workProjectTypeSchema,\n hallWingType: hallWingTypeSchema,\n};\n\n// A Realm working title is reserved under `reservedRealmNames/{UPPER(title)}` — the\n// UPPERCASED title IS the Firestore doc ID (runCreateWorkRealm.reservedRealmNameRef).\n// Firestore doc IDs cannot contain `/` and cannot be exactly `.` or `..`, so a title\n// that would produce an invalid/ambiguous doc ID must be rejected at the callable\n// boundary (both the create transaction and the soft availability check) rather than\n// hard-failing with an opaque `internal` error deep inside ref construction. Length\n// derives from MAX_WORK_REALM_TITLE_LENGTH; only the doc-ID-breaking characters are\n// forbidden. Keep CheckRealmNameAvailableInputSchema in lockstep so a valid-at-create\n// name is never rejected at form time (and vice-versa).\nexport const realmWorkingTitleSchema = z\n .string()\n .min(1)\n .max(MAX_WORK_REALM_TITLE_LENGTH)\n .refine((v) => !v.includes('/'), { message: 'Realm name cannot contain a slash (/).' })\n .refine((v) => v !== '.' && v !== '..', { message: 'Realm name cannot be \".\" or \"..\".' });\n\nexport const RealmCreationModeSchema = z.enum([\n 'newPublicRealm',\n 'newStandaloneRealm',\n 'existingPublicRealm',\n]);\nexport type RealmCreationMode = z.infer<typeof RealmCreationModeSchema>;\n\nexport const CreateWorkProjectInputSchema = z.discriminatedUnion('realmCreationMode', [\n z.object({\n ...baseFields,\n realmCreationMode: z.literal('newPublicRealm'),\n realmWorkingTitle: realmWorkingTitleSchema,\n realmWorkingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),\n }).strict(),\n z.object({\n ...baseFields,\n realmCreationMode: z.literal('newStandaloneRealm'),\n realmWorkingTitle: realmWorkingTitleSchema,\n realmWorkingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),\n }).strict(),\n z.object({\n ...baseFields,\n realmCreationMode: z.literal('existingPublicRealm'),\n workRealmId: z.string().min(1),\n }).strict(),\n]);\nexport type CreateWorkProjectInput = z.infer<typeof CreateWorkProjectInputSchema>;\n\n// Identified by the workAssets subcollection doc id — never by URL parsing\n// (no delete path may depend on a URL; see media-assets-and-protected-serving.md).\nexport const DeleteWorkAssetInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n workAssetId: z.string().min(1),\n}).strict();\nexport type DeleteWorkAssetInput = z.infer<typeof DeleteWorkAssetInputSchema>;\n\nexport const InviteSourceSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('standalone'),\n }).strict(),\n z.object({\n type: z.literal('craftSkill'),\n data: z.object({\n craftSkillId: craftSkillIdSchema,\n craftSkillOwnerUserId: userIdSchema,\n craftSkillName: z.string().min(1).max(MAX_CRAFT_SKILL_NAME_LENGTH),\n }).strict(),\n }).strict(),\n z.object({\n type: z.literal('commission'),\n // Titles are NOT snapshotted here (Display Identity Invariant — client display text\n // must be re-sourced at render by id). `postingStakeSharesOffered` is not display text;\n // the server re-sources it from the posting doc in the invite transaction (never trusts\n // the client copy) — kept so the shape stays server-writable.\n data: z.object({\n commissionListingId: commissionListingIdSchema,\n commissionProposalId: commissionProposalIdSchema,\n proposalArtisanUserId: userIdSchema,\n postingStakeSharesOffered: z.number().int().min(1),\n }).strict(),\n }).strict(),\n z.object({\n type: z.literal('audition'),\n data: z.object({\n auditionId: auditionIdSchema,\n auditionEntryId: auditionEntryIdSchema,\n respondentUserId: userIdSchema,\n postingStakeSharesOffered: z.number().int().min(1),\n }).strict(),\n }).strict(),\n]);\nexport type InviteSource = z.infer<typeof InviteSourceSchema>;\nexport type InviteSourceType = InviteSource['type'];\n\nexport const InviteUserToGuildInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n inviteeUid: userIdSchema,\n message: z.string().min(1).max(MAX_GUILD_INVITE_MESSAGE_LENGTH),\n stakeSharesOffered: z.number().int().min(1),\n source: InviteSourceSchema,\n}).strict();\nexport type InviteUserToGuildInput = z.infer<typeof InviteUserToGuildInputSchema>;\n\n// `finalized` is the terminal SUCCESS state (`accepted` is a transient state a trigger\n// consumes within seconds). Managers must be able to list finalized invites to see the\n// guild's actual recruitment history — not only failures and in-flight items. Derives from\n// the ONE canonical status enum (schemas/atoms.ts), never a re-declared literal.\nexport const ListGuildInvitesInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n statuses: z.array(guildInviteConversationStatusSchema).min(1),\n}).strict();\nexport type ListGuildInvitesInput = z.infer<typeof ListGuildInvitesInputSchema>;\n\nexport const UpdateGuildmateTradeProfessionsInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n userId: userIdSchema,\n tradeProfession: z.enum(TRADE_PROFESSION_VALUES),\n action: addRemoveActionSchema,\n}).strict();\nexport type UpdateGuildmateTradeProfessionsInput = z.infer<typeof UpdateGuildmateTradeProfessionsInputSchema>;\n\nconst GUILD_STANDING_VALUES_ENUM = GUILD_STANDING_VALUES as [typeof GUILD_STANDING_VALUES[number], ...typeof GUILD_STANDING_VALUES[number][]];\n\nexport const UpdateGuildmateStandingInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n userId: userIdSchema,\n guildStanding: z.enum(GUILD_STANDING_VALUES_ENUM),\n action: addRemoveActionSchema,\n}).strict();\nexport type UpdateGuildmateStandingInput = z.infer<typeof UpdateGuildmateStandingInputSchema>;\n\n// Member self-leave (leaveWorkProject). The leaver is ALWAYS request.auth.uid — never a\n// client-supplied uid (invariant 3) — so the input carries only the workProjectId. The\n// callable composes the internal `depart` stake-share operation for ctx.uid.\nexport const LeaveWorkProjectInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n}).strict();\nexport type LeaveWorkProjectInput = z.infer<typeof LeaveWorkProjectInputSchema>;\n\nexport const UpdatePublicWorkProjectDetailsInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n workingTitle: z.string().min(1).max(MAX_WORK_PROJECT_TITLE_LENGTH),\n workingDescription: z.string().min(1).max(MAX_WORK_PROJECT_DESCRIPTION_LENGTH),\n}).strict();\nexport type UpdatePublicWorkProjectDetailsInput = z.infer<typeof UpdatePublicWorkProjectDetailsInputSchema>;\n\nexport const UpdateWorkRealmDetailsInputSchema = z.object({\n workRealmId: z.string().min(1),\n workingTitle: z.string().min(1).max(MAX_WORK_REALM_TITLE_LENGTH),\n workingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),\n}).strict();\nexport type UpdateWorkRealmDetailsInput = z.infer<typeof UpdateWorkRealmDetailsInputSchema>;\n\n// Unauthenticated soft-check for a Realm working title. Must match the authoritative\n// realmWorkingTitle contract in CreateWorkProjectInputSchema (realmWorkingTitleSchema:\n// MAX_WORK_REALM_TITLE_LENGTH, rejecting the doc-ID-breaking `/` and reserved `.`/`..`). Never be\n// stricter than the create transaction or a valid-at-create name would be rejected at\n// form time — reuse the SAME schema so the two can never drift.\nexport const CheckRealmNameAvailableInputSchema = z.object({\n workingTitle: realmWorkingTitleSchema,\n}).strict();\nexport type CheckRealmNameAvailableInput = z.infer<typeof CheckRealmNameAvailableInputSchema>;\n\n// ---- work-project file folders (S7) ---------------------------------------------------\n// The default \"All Guildmates\" folder is immutable; custom-folder access is by trade\n// profession. All four callables require a file-admin standing via assertCanManageFolders.\n\nconst tradeProfessionListSchema = z\n .array(z.enum(TRADE_PROFESSION_VALUES))\n .max(TRADE_PROFESSION_OPTIONS.length);\n\nexport const CreateFileFolderInputSchema = z.object({\n workProjectId: z.string().min(1),\n name: z.string().min(1).max(MAX_FILE_FOLDER_NAME_LENGTH),\n canViewTradeProfessions: tradeProfessionListSchema,\n canUploadTradeProfessions: tradeProfessionListSchema,\n canDeleteTradeProfessions: tradeProfessionListSchema,\n}).strict();\nexport type CreateFileFolderInput = z.infer<typeof CreateFileFolderInputSchema>;\n\nexport const RenameFileFolderInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n name: z.string().min(1).max(MAX_FILE_FOLDER_NAME_LENGTH),\n}).strict();\nexport type RenameFileFolderInput = z.infer<typeof RenameFileFolderInputSchema>;\n\nexport const UpdateFolderProfessionsInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n canViewTradeProfessions: tradeProfessionListSchema,\n canUploadTradeProfessions: tradeProfessionListSchema,\n canDeleteTradeProfessions: tradeProfessionListSchema,\n}).strict();\nexport type UpdateFolderProfessionsInput = z.infer<typeof UpdateFolderProfessionsInputSchema>;\n\nexport const DeleteFileFolderInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n}).strict();\nexport type DeleteFileFolderInput = z.infer<typeof DeleteFileFolderInputSchema>;\n\n// ---- realm shared files ---------------------------------------------------------------\n\n// Delete a single work file (by folder + file id). File-admin authz is enforced in the\n// callable/core transaction.\nexport const DeleteWorkFileInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n workFileId: z.string().min(1),\n}).strict();\nexport type DeleteWorkFileInput = z.infer<typeof DeleteWorkFileInputSchema>;\n\n// Set canon status on a realm shared file. Realm-steward-only authz is enforced inside the\n// core's transaction against workRealms/{workRealmId}.workStewardUid.\nexport const UpdateWorkFileRealmCanonInputSchema = z.object({\n workRealmId: z.string().min(1),\n mediaAssetId: z.string().min(1),\n canon: z.boolean(),\n}).strict();\nexport type UpdateWorkFileRealmCanonInput = z.infer<typeof UpdateWorkFileRealmCanonInputSchema>;\n\n// Share (promote) a work file into its Realm's shared-file pool as non-canon. File-admin\n// authz (`workFile.promoteToRealm`) is enforced inside the core's transaction.\nexport const UpdateWorkFileRealmShareInputSchema = z.object({\n workProjectId: z.string().min(1),\n workFileId: z.string().min(1),\n}).strict();\nexport type UpdateWorkFileRealmShareInput = z.infer<typeof UpdateWorkFileRealmShareInputSchema>;\n\n\n"]}
1
+ {"version":3,"file":"work-project-management.js","sourceRoot":"","sources":["../../src/schemas/work-project-management.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n workProjectIdSchema,\n userIdSchema,\n addRemoveActionSchema,\n workProjectTypeSchema,\n hallWingTypeSchema,\n commissionListingIdSchema,\n commissionProposalIdSchema,\n auditionIdSchema,\n auditionEntryIdSchema,\n craftSkillIdSchema,\n guildInviteConversationStatusSchema,\n} from './atoms.js';\nimport { TRADE_PROFESSION_OPTIONS, TRADE_PROFESSION_VALUES } from '../constants/options.js';\nimport { GUILD_STANDING_VALUES } from '../permissions/index.js';\nimport {\n MAX_GUILD_INVITE_MESSAGE_LENGTH,\n MAX_WORK_PROJECT_TITLE_LENGTH,\n MAX_WORK_PROJECT_DESCRIPTION_LENGTH,\n MAX_WORK_REALM_TITLE_LENGTH,\n MAX_WORK_REALM_DESCRIPTION_LENGTH,\n MAX_CRAFT_SKILL_NAME_LENGTH,\n MAX_FILE_FOLDER_NAME_LENGTH,\n} from '../constants/business.js';\nimport { RealmFileCanonStatusSchema, ContentMediaKindSchema } from '../doc-schemas/media-assets.js';\n\n// ===========================================================================\n// S7 realm shared-files gallery (ARTISAN-ONLY). `mediaAssets` is client-unreadable, so the gallery\n// reads realm-shared work files via THIS server projection callable (never a client query). The\n// callable is artisan-gated; the whole section is hidden from non-artisans. Serving is the reserved\n// `'artisan'` media tier (mutate-in-place scoped→artisan on promote). V1 = view + download.\n// ===========================================================================\n\nexport const RealmSharedFileProjectionSchema = z.object({\n mediaAssetId: z.string(),\n // The canonical stored media kind — RealmSharedFileProjection is a projection OF a\n // MediaAsset, so it shares the ONE ContentMediaKindSchema.\n mediaKind: ContentMediaKindSchema,\n // 'nonCanon' | 'canon' for a shared file (never 'none' — that means not-shared).\n realmFileCanonStatus: RealmFileCanonStatusSchema,\n creatorUid: z.string(),\n // For the per-file steward canon toggle + download (updateWorkFileRealmCanon takes these).\n workProjectId: z.string(),\n workFileId: z.string(),\n}).strict();\nexport type RealmSharedFileProjection = z.infer<typeof RealmSharedFileProjectionSchema>;\n\nexport const GetRealmSharedFilesInputSchema = z.object({\n realmId: z.string().min(1),\n}).strict();\nexport type GetRealmSharedFilesInput = z.infer<typeof GetRealmSharedFilesInputSchema>;\n\nconst baseFields = {\n workingTitle: z.string().min(1).max(MAX_WORK_PROJECT_TITLE_LENGTH),\n workingDescription: z.string().min(1).max(MAX_WORK_PROJECT_DESCRIPTION_LENGTH),\n workProjectType: workProjectTypeSchema,\n hallWingType: hallWingTypeSchema,\n};\n\n// A Realm working title is reserved under `reservedRealmNames/{UPPER(title)}` — the\n// UPPERCASED title IS the Firestore doc ID (runCreateWorkRealm.reservedRealmNameRef).\n// Firestore doc IDs cannot contain `/` and cannot be exactly `.` or `..`, so a title\n// that would produce an invalid/ambiguous doc ID must be rejected at the callable\n// boundary (both the create transaction and the soft availability check) rather than\n// hard-failing with an opaque `internal` error deep inside ref construction. Length\n// derives from MAX_WORK_REALM_TITLE_LENGTH; only the doc-ID-breaking characters are\n// forbidden. Keep CheckRealmNameAvailableInputSchema in lockstep so a valid-at-create\n// name is never rejected at form time (and vice-versa).\nexport const realmWorkingTitleSchema = z\n .string()\n .min(1)\n .max(MAX_WORK_REALM_TITLE_LENGTH)\n .refine((v) => !v.includes('/'), { message: 'Realm name cannot contain a slash (/).' })\n .refine((v) => v !== '.' && v !== '..', { message: 'Realm name cannot be \".\" or \"..\".' });\n\nexport const RealmCreationModeSchema = z.enum([\n 'newPublicRealm',\n 'newStandaloneRealm',\n 'existingPublicRealm',\n]);\nexport type RealmCreationMode = z.infer<typeof RealmCreationModeSchema>;\n\nexport const CreateWorkProjectInputSchema = z.discriminatedUnion('realmCreationMode', [\n z.object({\n ...baseFields,\n realmCreationMode: z.literal('newPublicRealm'),\n realmWorkingTitle: realmWorkingTitleSchema,\n realmWorkingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),\n }).strict(),\n // Standalone realms are background plumbing (DJ ruling 2026-07-19): the user enters NO\n // realm information — the backend creates the realm shell with a synthetic unique\n // title/description (the generated workRealmId), so nothing user-authored exists on it\n // and no human realm name is consumed from the reservedRealmNames namespace.\n z.object({\n ...baseFields,\n realmCreationMode: z.literal('newStandaloneRealm'),\n }).strict(),\n z.object({\n ...baseFields,\n realmCreationMode: z.literal('existingPublicRealm'),\n workRealmId: z.string().min(1),\n }).strict(),\n]);\nexport type CreateWorkProjectInput = z.infer<typeof CreateWorkProjectInputSchema>;\n\n// Identified by the workAssets subcollection doc id — never by URL parsing\n// (no delete path may depend on a URL; see media-assets-and-protected-serving.md).\nexport const DeleteWorkAssetInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n workAssetId: z.string().min(1),\n}).strict();\nexport type DeleteWorkAssetInput = z.infer<typeof DeleteWorkAssetInputSchema>;\n\nexport const InviteSourceSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('standalone'),\n }).strict(),\n z.object({\n type: z.literal('craftSkill'),\n data: z.object({\n craftSkillId: craftSkillIdSchema,\n craftSkillOwnerUserId: userIdSchema,\n craftSkillName: z.string().min(1).max(MAX_CRAFT_SKILL_NAME_LENGTH),\n }).strict(),\n }).strict(),\n z.object({\n type: z.literal('commission'),\n // Titles are NOT snapshotted here (Display Identity Invariant — client display text\n // must be re-sourced at render by id). `postingStakeSharesOffered` is not display text;\n // the server re-sources it from the posting doc in the invite transaction (never trusts\n // the client copy) — kept so the shape stays server-writable.\n data: z.object({\n commissionListingId: commissionListingIdSchema,\n commissionProposalId: commissionProposalIdSchema,\n proposalArtisanUserId: userIdSchema,\n postingStakeSharesOffered: z.number().int().min(1),\n }).strict(),\n }).strict(),\n z.object({\n type: z.literal('audition'),\n data: z.object({\n auditionId: auditionIdSchema,\n auditionEntryId: auditionEntryIdSchema,\n respondentUserId: userIdSchema,\n postingStakeSharesOffered: z.number().int().min(1),\n }).strict(),\n }).strict(),\n]);\nexport type InviteSource = z.infer<typeof InviteSourceSchema>;\nexport type InviteSourceType = InviteSource['type'];\n\nexport const InviteUserToGuildInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n inviteeUid: userIdSchema,\n message: z.string().min(1).max(MAX_GUILD_INVITE_MESSAGE_LENGTH),\n stakeSharesOffered: z.number().int().min(1),\n source: InviteSourceSchema,\n}).strict();\nexport type InviteUserToGuildInput = z.infer<typeof InviteUserToGuildInputSchema>;\n\n// `finalized` is the terminal SUCCESS state (`accepted` is a transient state a trigger\n// consumes within seconds). Managers must be able to list finalized invites to see the\n// guild's actual recruitment history — not only failures and in-flight items. Derives from\n// the ONE canonical status enum (schemas/atoms.ts), never a re-declared literal.\nexport const ListGuildInvitesInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n statuses: z.array(guildInviteConversationStatusSchema).min(1),\n}).strict();\nexport type ListGuildInvitesInput = z.infer<typeof ListGuildInvitesInputSchema>;\n\nexport const UpdateGuildmateTradeProfessionsInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n userId: userIdSchema,\n tradeProfession: z.enum(TRADE_PROFESSION_VALUES),\n action: addRemoveActionSchema,\n}).strict();\nexport type UpdateGuildmateTradeProfessionsInput = z.infer<typeof UpdateGuildmateTradeProfessionsInputSchema>;\n\nconst GUILD_STANDING_VALUES_ENUM = GUILD_STANDING_VALUES as [typeof GUILD_STANDING_VALUES[number], ...typeof GUILD_STANDING_VALUES[number][]];\n\nexport const UpdateGuildmateStandingInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n userId: userIdSchema,\n guildStanding: z.enum(GUILD_STANDING_VALUES_ENUM),\n action: addRemoveActionSchema,\n}).strict();\nexport type UpdateGuildmateStandingInput = z.infer<typeof UpdateGuildmateStandingInputSchema>;\n\n// Member self-leave (leaveWorkProject). The leaver is ALWAYS request.auth.uid — never a\n// client-supplied uid (invariant 3) — so the input carries only the workProjectId. The\n// callable composes the internal `depart` stake-share operation for ctx.uid.\nexport const LeaveWorkProjectInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n}).strict();\nexport type LeaveWorkProjectInput = z.infer<typeof LeaveWorkProjectInputSchema>;\n\nexport const UpdatePublicWorkProjectDetailsInputSchema = z.object({\n workProjectId: workProjectIdSchema,\n workingTitle: z.string().min(1).max(MAX_WORK_PROJECT_TITLE_LENGTH),\n workingDescription: z.string().min(1).max(MAX_WORK_PROJECT_DESCRIPTION_LENGTH),\n}).strict();\nexport type UpdatePublicWorkProjectDetailsInput = z.infer<typeof UpdatePublicWorkProjectDetailsInputSchema>;\n\nexport const UpdateWorkRealmDetailsInputSchema = z.object({\n workRealmId: z.string().min(1),\n workingTitle: z.string().min(1).max(MAX_WORK_REALM_TITLE_LENGTH),\n workingDescription: z.string().min(1).max(MAX_WORK_REALM_DESCRIPTION_LENGTH),\n}).strict();\nexport type UpdateWorkRealmDetailsInput = z.infer<typeof UpdateWorkRealmDetailsInputSchema>;\n\n// Unauthenticated soft-check for a Realm working title. Must match the authoritative\n// realmWorkingTitle contract in CreateWorkProjectInputSchema (realmWorkingTitleSchema:\n// MAX_WORK_REALM_TITLE_LENGTH, rejecting the doc-ID-breaking `/` and reserved `.`/`..`). Never be\n// stricter than the create transaction or a valid-at-create name would be rejected at\n// form time — reuse the SAME schema so the two can never drift.\nexport const CheckRealmNameAvailableInputSchema = z.object({\n workingTitle: realmWorkingTitleSchema,\n}).strict();\nexport type CheckRealmNameAvailableInput = z.infer<typeof CheckRealmNameAvailableInputSchema>;\n\n// ---- work-project file folders (S7) ---------------------------------------------------\n// The default \"All Guildmates\" folder is immutable; custom-folder access is by trade\n// profession. All four callables require a file-admin standing via assertCanManageFolders.\n\nconst tradeProfessionListSchema = z\n .array(z.enum(TRADE_PROFESSION_VALUES))\n .max(TRADE_PROFESSION_OPTIONS.length);\n\nexport const CreateFileFolderInputSchema = z.object({\n workProjectId: z.string().min(1),\n name: z.string().min(1).max(MAX_FILE_FOLDER_NAME_LENGTH),\n canViewTradeProfessions: tradeProfessionListSchema,\n canUploadTradeProfessions: tradeProfessionListSchema,\n canDeleteTradeProfessions: tradeProfessionListSchema,\n}).strict();\nexport type CreateFileFolderInput = z.infer<typeof CreateFileFolderInputSchema>;\n\nexport const RenameFileFolderInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n name: z.string().min(1).max(MAX_FILE_FOLDER_NAME_LENGTH),\n}).strict();\nexport type RenameFileFolderInput = z.infer<typeof RenameFileFolderInputSchema>;\n\nexport const UpdateFolderProfessionsInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n canViewTradeProfessions: tradeProfessionListSchema,\n canUploadTradeProfessions: tradeProfessionListSchema,\n canDeleteTradeProfessions: tradeProfessionListSchema,\n}).strict();\nexport type UpdateFolderProfessionsInput = z.infer<typeof UpdateFolderProfessionsInputSchema>;\n\nexport const DeleteFileFolderInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n}).strict();\nexport type DeleteFileFolderInput = z.infer<typeof DeleteFileFolderInputSchema>;\n\n// ---- realm shared files ---------------------------------------------------------------\n\n// Delete a single work file (by folder + file id). File-admin authz is enforced in the\n// callable/core transaction.\nexport const DeleteWorkFileInputSchema = z.object({\n workProjectId: z.string().min(1),\n folderId: z.string().min(1),\n workFileId: z.string().min(1),\n}).strict();\nexport type DeleteWorkFileInput = z.infer<typeof DeleteWorkFileInputSchema>;\n\n// Set canon status on a realm shared file. Realm-steward-only authz is enforced inside the\n// core's transaction against workRealms/{workRealmId}.workStewardUid.\nexport const UpdateWorkFileRealmCanonInputSchema = z.object({\n workRealmId: z.string().min(1),\n mediaAssetId: z.string().min(1),\n canon: z.boolean(),\n}).strict();\nexport type UpdateWorkFileRealmCanonInput = z.infer<typeof UpdateWorkFileRealmCanonInputSchema>;\n\n// Share (promote) a work file into its Realm's shared-file pool as non-canon. File-admin\n// authz (`workFile.promoteToRealm`) is enforced inside the core's transaction.\nexport const UpdateWorkFileRealmShareInputSchema = z.object({\n workProjectId: z.string().min(1),\n workFileId: z.string().min(1),\n}).strict();\nexport type UpdateWorkFileRealmShareInput = z.infer<typeof UpdateWorkFileRealmShareInputSchema>;\n\n\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/ttt-core",
3
- "version": "0.78.17",
3
+ "version": "0.78.19",
4
4
  "description": "Core types, Firestore path constants, and shared constants for TTT Productions",
5
5
  "repository": {
6
6
  "type": "git",
@@ -118,7 +118,7 @@
118
118
  "@ttt-productions/edge-protocol-core": "^0.1.4",
119
119
  "@ttt-productions/media-schemas": "^0.14.2",
120
120
  "@ttt-productions/notification-core": "^0.15.4",
121
- "@ttt-productions/report-core": "^0.16.5",
121
+ "@ttt-productions/report-core": "^0.16.6",
122
122
  "zod": "^4.4.3"
123
123
  },
124
124
  "devDependencies": {