@ttt-productions/ttt-core 0.79.11 → 0.79.13

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.
Files changed (50) hide show
  1. package/dist/constants/business-content.d.ts +7 -0
  2. package/dist/constants/business-content.d.ts.map +1 -1
  3. package/dist/constants/business-content.js +7 -0
  4. package/dist/constants/business-content.js.map +1 -1
  5. package/dist/constants/business-user.d.ts +8 -0
  6. package/dist/constants/business-user.d.ts.map +1 -1
  7. package/dist/constants/business-user.js +8 -0
  8. package/dist/constants/business-user.js.map +1 -1
  9. package/dist/constants/chat.d.ts +9 -0
  10. package/dist/constants/chat.d.ts.map +1 -1
  11. package/dist/constants/chat.js +9 -0
  12. package/dist/constants/chat.js.map +1 -1
  13. package/dist/doc-schemas/account-deletion.d.ts +1 -0
  14. package/dist/doc-schemas/account-deletion.d.ts.map +1 -1
  15. package/dist/doc-schemas/account-deletion.js +7 -0
  16. package/dist/doc-schemas/account-deletion.js.map +1 -1
  17. package/dist/doc-schemas/registry.d.ts +13 -4
  18. package/dist/doc-schemas/registry.d.ts.map +1 -1
  19. package/dist/doc-schemas/report-docs.d.ts +21 -0
  20. package/dist/doc-schemas/report-docs.d.ts.map +1 -1
  21. package/dist/doc-schemas/report-docs.js +31 -1
  22. package/dist/doc-schemas/report-docs.js.map +1 -1
  23. package/dist/media/domain-events-work.d.ts +2 -2
  24. package/dist/media/domain-events-work.d.ts.map +1 -1
  25. package/dist/media/domain-events-work.js +5 -2
  26. package/dist/media/domain-events-work.js.map +1 -1
  27. package/dist/media/domain-events.d.ts +1 -1
  28. package/dist/media/domain-events.js +2 -2
  29. package/dist/media/domain-events.js.map +1 -1
  30. package/dist/media/pending-media.d.ts +11 -11
  31. package/dist/permissions/work-project-permissions-data.d.ts +1 -6
  32. package/dist/permissions/work-project-permissions-data.d.ts.map +1 -1
  33. package/dist/permissions/work-project-permissions-data.js +1 -6
  34. package/dist/permissions/work-project-permissions-data.js.map +1 -1
  35. package/dist/schemas/chat.d.ts +5 -0
  36. package/dist/schemas/chat.d.ts.map +1 -1
  37. package/dist/schemas/chat.js +10 -0
  38. package/dist/schemas/chat.js.map +1 -1
  39. package/dist/schemas/commissions.d.ts +0 -4
  40. package/dist/schemas/commissions.d.ts.map +1 -1
  41. package/dist/schemas/commissions.js +0 -3
  42. package/dist/schemas/commissions.js.map +1 -1
  43. package/dist/schemas/users.d.ts +11 -0
  44. package/dist/schemas/users.d.ts.map +1 -1
  45. package/dist/schemas/users.js +15 -0
  46. package/dist/schemas/users.js.map +1 -1
  47. package/dist/types/audit.d.ts +1 -1
  48. package/dist/types/audit.d.ts.map +1 -1
  49. package/dist/types/audit.js.map +1 -1
  50. package/package.json +2 -2
@@ -187,6 +187,13 @@ export declare const MAX_AUDITION_DESCRIPTION_LENGTH = 1000;
187
187
  * downstream processing.
188
188
  */
189
189
  export declare const MAX_SPONSORED_AUDITION_AMOUNT_USD = 500000;
190
+ /**
191
+ * The one user-facing rejection sentence when a Work's own active guildmate tries to enter
192
+ * that Work's open audition (entries exist to recruit OUTSIDERS; a member can't be
193
+ * recruited). Shared by both backend enforcement points (upload-accept and publish) — it is
194
+ * the `failed-precondition` answer text the entry UI renders verbatim.
195
+ */
196
+ export declare const GUILDMATE_AUDITION_ENTRY_REJECTION = "You are already a guildmate of this Work \u2014 its audition is for recruiting new collaborators.";
190
197
  /** Maximum length for a SquareStreetz post. */
191
198
  export declare const MAX_POST_LENGTH = 500;
192
199
  /** Maximum number of mentions allowed in a single SquareStreetz post. */
@@ -1 +1 @@
1
- {"version":3,"file":"business-content.d.ts","sourceRoot":"","sources":["../../src/constants/business-content.ts"],"names":[],"mappings":"AAYA,gGAAgG;AAChG,eAAO,MAAM,qCAAqC,MAAM,CAAC;AAIzD,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,QAAkD,CAAC;AAEvF,iEAAiE;AACjE,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,6CAA6C;AAC7C,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AAEzE,kEAAkE;AAClE,eAAO,MAAM,iCAAiC,MAAM,CAAC;AAIrD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,oEACqB,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,2BAA2B,CAAC;AAC1E,eAAO,MAAM,iCAAiC,6CAA6C,CAAC;AAE5F;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC;;;;;;;;;CAYS,CAAC;AAEvD,8EAA8E;AAC9E,MAAM,MAAM,0BAA0B,GAAG,MAAM,OAAO,gCAAgC,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,gCAAgC,CAAC,CAAC,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,8CAIlC,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;CASiB,CAAC;AAEvD;;;;;oBAKoB;AACpB,eAAO,MAAM,2BAA2B;;;;;;CAMmB,CAAC;AAE5D;;4BAE4B;AAC5B,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,aAAa,EAAE,0BAA0B,CAAC;IAC1C,kDAAkD;IAClD,YAAY,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAChD,kFAAkF;IAClF,cAAc,EAAE,0BAA0B,CAAC;IAC3C;iEAC6D;IAC7D,aAAa,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAClD;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;CAmBwB,CAAC;AAExE;2FAC2F;AAC3F,eAAO,MAAM,qCAAqC,OAAO,CAAC;AAI1D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,QAEiC,CAAC;AAE5E,eAAO,MAAM,8BAA8B,QAMO,CAAC;AAInD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB;;;;;CAKO,CAAC;AAI5C,4CAA4C;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C;;4EAE4E;AAC5E,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,kDAAkD;AAClD,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,SAAU,CAAC;AAIzD,+CAA+C;AAC/C,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,yEAAyE;AACzE,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,8EAA8E;AAC9E,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAI7C,iDAAiD;AACjD,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,kDAAkD;AAClD,eAAO,MAAM,iCAAiC,MAAM,CAAC"}
1
+ {"version":3,"file":"business-content.d.ts","sourceRoot":"","sources":["../../src/constants/business-content.ts"],"names":[],"mappings":"AAYA,gGAAgG;AAChG,eAAO,MAAM,qCAAqC,MAAM,CAAC;AAIzD,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,QAAkD,CAAC;AAEvF,iEAAiE;AACjE,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,6CAA6C;AAC7C,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AAEzE,kEAAkE;AAClE,eAAO,MAAM,iCAAiC,MAAM,CAAC;AAIrD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,oEACqB,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,2BAA2B,CAAC;AAC1E,eAAO,MAAM,iCAAiC,6CAA6C,CAAC;AAE5F;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC;;;;;;;;;CAYS,CAAC;AAEvD,8EAA8E;AAC9E,MAAM,MAAM,0BAA0B,GAAG,MAAM,OAAO,gCAAgC,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,gCAAgC,CAAC,CAAC,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,8CAIlC,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;CASiB,CAAC;AAEvD;;;;;oBAKoB;AACpB,eAAO,MAAM,2BAA2B;;;;;;CAMmB,CAAC;AAE5D;;4BAE4B;AAC5B,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,aAAa,EAAE,0BAA0B,CAAC;IAC1C,kDAAkD;IAClD,YAAY,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAChD,kFAAkF;IAClF,cAAc,EAAE,0BAA0B,CAAC;IAC3C;iEAC6D;IAC7D,aAAa,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAClD;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;CAmBwB,CAAC;AAExE;2FAC2F;AAC3F,eAAO,MAAM,qCAAqC,OAAO,CAAC;AAI1D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,QAEiC,CAAC;AAE5E,eAAO,MAAM,8BAA8B,QAMO,CAAC;AAInD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB;;;;;CAKO,CAAC;AAI5C,4CAA4C;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C;;4EAE4E;AAC5E,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,kDAAkD;AAClD,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,SAAU,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,sGACiD,CAAC;AAIjG,+CAA+C;AAC/C,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,yEAAyE;AACzE,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,8EAA8E;AAC9E,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAI7C,iDAAiD;AACjD,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,kDAAkD;AAClD,eAAO,MAAM,iCAAiC,MAAM,CAAC"}
@@ -187,6 +187,13 @@ export const MAX_AUDITION_DESCRIPTION_LENGTH = 1000;
187
187
  * downstream processing.
188
188
  */
189
189
  export const MAX_SPONSORED_AUDITION_AMOUNT_USD = 500_000;
190
+ /**
191
+ * The one user-facing rejection sentence when a Work's own active guildmate tries to enter
192
+ * that Work's open audition (entries exist to recruit OUTSIDERS; a member can't be
193
+ * recruited). Shared by both backend enforcement points (upload-accept and publish) — it is
194
+ * the `failed-precondition` answer text the entry UI renders verbatim.
195
+ */
196
+ export const GUILDMATE_AUDITION_ENTRY_REJECTION = 'You are already a guildmate of this Work — its audition is for recruiting new collaborators.';
190
197
  // --- SquareStreetz (Social Feed) ---
191
198
  /** Maximum length for a SquareStreetz post. */
192
199
  export const MAX_POST_LENGTH = 500;
@@ -1 +1 @@
1
- {"version":3,"file":"business-content.js","sourceRoot":"","sources":["../../src/constants/business-content.ts"],"names":[],"mappings":"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","sourcesContent":["// Content-surface business-rule constants — commissions, auditions, the social\n// feed, and messaging.\nimport {\n MAX_WORK_PROJECT_TITLE_LENGTH,\n MAX_WORK_PROJECT_DESCRIPTION_LENGTH,\n MAX_CHAPTER_CONTENT_LENGTH,\n MAX_WORK_REALM_TITLE_LENGTH,\n MAX_WORK_REALM_DESCRIPTION_LENGTH,\n} from \"./business-work-project.js\";\nimport { ACTIVE_LIMITS } from './app-mode.js';\nimport type { WorkProjectType } from '../types/content.js';\n\n/** The maximum character length for a SquareStreetz post created on behalf of a workProject. */\nexport const MAX_SQUARE_STREETZ_DESCRIPTION_LENGTH = 150;\n\n// --- Commission Board & Proposals ---\n\n/** Maximum number of open commissions a workProject can have. Mode-varied. */\nexport const MAX_COMMISSION_LISTINGS = ACTIVE_LIMITS.workProject.maxCommissionListings;\n\n/** Maximum number of proposal artisans saved to a commission. */\nexport const MAX_SAVED_PROPOSAL_ARTISANS = 5;\n\n/** Maximum length for a commission title. */\nexport const MAX_COMMISSION_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;\n\n/** Maximum length for a commission description / cover letter. */\nexport const MAX_COMMISSION_DESCRIPTION_LENGTH = 400;\n\n// --- Moderation text-clear + published hall-content text fields ---\n\n/**\n * Neutral placeholder written into a single cleared text field by the moderation\n * text-clear remedy. Canonical wording — the backend `runModerationClearText`\n * core writes exactly this string; a wording change is a single edit here.\n */\nexport const MODERATION_CLEAR_PLACEHOLDER =\n 'Removed by moderation — awaiting an update by the steward.';\n\n/**\n * Default REASON strings recorded on a moderation action when the admin supplies no\n * user-facing reason. Distinct from MODERATION_CLEAR_PLACEHOLDER (which is written INTO\n * cleared content fields) — these are the recorded justification text. Canonical wording;\n * consumers (resolveAdminTask's forceRetitle / chat-delete actions) never inline them.\n */\nexport const MODERATION_DEFAULT_REMOVAL_REASON = 'Removed by moderation.';\nexport const MODERATION_DEFAULT_RETITLE_REASON = 'Title/description removed by moderation.';\n\n/**\n * CANONICAL clearable text-field map for the per-field moderation TEXT-CLEAR remedy.\n * Cross-boundary single owner: the admin field-picker offers this set per surface and\n * the backend clear runner validates + normalizes caller-supplied fields against it.\n * Keys are surfaces; values are the exact document field names (NOT display labels)\n * recorded verbatim in `moderationClearedFields`. Covers every clearable surface —\n * workProject/workRealm shell metadata, hall parent details (tale/tune/television),\n * and hall sub-items (chapter/track/episode).\n */\nexport const MODERATION_CLEARABLE_TEXT_FIELDS = {\n // workProject + workRealm shell metadata\n workProject: ['workingTitle', 'workingDescription'],\n workRealm: ['workingTitle', 'workingDescription'],\n // hall content parent details\n tale: ['title', 'description'],\n tune: ['title', 'description'],\n television: ['title', 'description'],\n // hall content sub-items\n chapter: ['title', 'content'],\n tuneTrack: ['title', 'description'],\n televisionEpisode: ['title', 'description'],\n} as const satisfies Record<string, readonly string[]>;\n\n/** A surface whose text fields the moderation clear remedy can neutralize. */\nexport type ModerationClearableSurface = keyof typeof MODERATION_CLEARABLE_TEXT_FIELDS;\n\n/**\n * Every DISTINCT clearable/changeable text-field NAME, DERIVED from the canonical\n * MODERATION_CLEARABLE_TEXT_FIELDS map (the union of every surface's tuple). Label maps and\n * per-field cap maps key on this instead of `string`, so adding a field to a surface is a\n * compile error until its label and cap exist.\n */\nexport type ClearableTextFieldName =\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS)[ModerationClearableSurface][number];\n\n/**\n * The DISTINCT clearable text-field NAMES across the whole hall content family (tale/tune/\n * television detail → title/description; chapter → title/content; track/episode →\n * title/description). DERIVED from the canonical MODERATION_CLEARABLE_TEXT_FIELDS map — the\n * union of every hall surface's fields — so the `clearHallContentText` callable's field-enum\n * (`HallClearFieldSchema`) never restates the `title`/`description`/`content` literals. Index\n * access on the map's readonly tuples preserves the literal types, so this stays a typed\n * `readonly ['title','description','content']` a `z.enum(...)` can consume directly.\n */\nexport const HALL_CLEARABLE_TEXT_FIELD_NAMES = [\n MODERATION_CLEARABLE_TEXT_FIELDS.tale[0], // title\n MODERATION_CLEARABLE_TEXT_FIELDS.tale[1], // description\n MODERATION_CLEARABLE_TEXT_FIELDS.chapter[1], // content\n] as const;\n\n/**\n * The raw doc field names each published hall-content surface exposes as changeable TEXT.\n * Cross-boundary: the member \"Update details\" field picker offers this set per surface and\n * the change-request submit runner validates against it. Detail surfaces (tale/tune/\n * television) live on the hall parent doc; sub-item surfaces on the published chapter/\n * track/episode doc. This is the HALL-SURFACE SUBSET of the canonical\n * MODERATION_CLEARABLE_TEXT_FIELDS above (it excludes the `workProject` shell) — every\n * tuple is projected from that one owner, so the two can never drift.\n */\nexport const HALL_CONTENT_TEXT_FIELDS = {\n tale: MODERATION_CLEARABLE_TEXT_FIELDS.tale,\n tune: MODERATION_CLEARABLE_TEXT_FIELDS.tune,\n television: MODERATION_CLEARABLE_TEXT_FIELDS.television,\n chapter: MODERATION_CLEARABLE_TEXT_FIELDS.chapter,\n tuneTrack: MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack,\n televisionEpisode: MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode,\n // Realm grain (R1, 2026-07-12): targets the `workRealms/{id}` doc directly.\n workRealm: MODERATION_CLEARABLE_TEXT_FIELDS.workRealm,\n} as const satisfies Record<string, readonly string[]>;\n\n/** Per-field max lengths for proposed hall-content text. DERIVED from the owning\n * constants — never independent numbers — so the change-request pipeline can never\n * drift from the authoring limits again (the pre-2026-07-13 copy carried its own\n * 200/5000/100000 set while authoring enforced 150/300/2500). Keyed on the derived\n * ClearableTextFieldName union, so a new clearable field fails the build here until\n * it has a cap. */\nexport const HALL_CONTENT_TEXT_FIELD_MAX = {\n title: MAX_WORK_PROJECT_TITLE_LENGTH,\n description: MAX_WORK_PROJECT_DESCRIPTION_LENGTH,\n content: MAX_CHAPTER_CONTENT_LENGTH,\n workingTitle: MAX_WORK_REALM_TITLE_LENGTH,\n workingDescription: MAX_WORK_REALM_DESCRIPTION_LENGTH,\n} as const satisfies Record<ClearableTextFieldName, number>;\n\n/** One work-project type's two hall text surfaces — the published DETAIL on the hall parent\n * and its chapter/track/episode SUB-ITEM — each with the clearable/changeable field tuple\n * that surface exposes. */\nexport interface HallContentSurfaceRouting {\n /** Surface identity of the hall parent DETAIL (tale / tune / television). */\n detailSurface: ModerationClearableSurface;\n /** The DETAIL surface's clearable text fields. */\n detailFields: readonly ClearableTextFieldName[];\n /** Surface identity of the SUB-ITEM (chapter / tuneTrack / televisionEpisode). */\n subItemSurface: ModerationClearableSurface;\n /** The SUB-ITEM surface's clearable text fields — a Tale chapter carries title/content, a\n * Tune track and a Television episode title/description. */\n subItemFields: readonly ClearableTextFieldName[];\n}\n\n/**\n * CANONICAL WorkProjectType → hall text-surface routing. The ONE owner of \"a Tale's sub-item is\n * a chapter, a Tune's is a tuneTrack, a Television's is a televisionEpisode\" and of which fields\n * each of those surfaces exposes. Cross-boundary: the backend text-clear and change-request\n * runners resolve `surface` from (workProjectType, is-sub-item?) through this map, and the admin\n * field pickers project their checkbox options from the same entry — three sites that each\n * hand-rolled the routing before (a ternary that fell through to the tuneTrack tuple for\n * Television, silently correct only because the two tuples happen to match today).\n *\n * Every field tuple is PROJECTED from MODERATION_CLEARABLE_TEXT_FIELDS above — no field literal\n * is restated here — and the `satisfies Record<WorkProjectType, …>` makes adding a work-project\n * type a compile error until its surfaces are routed.\n */\nexport const HALL_CONTENT_SURFACES_BY_WORK_TYPE = {\n Tales: {\n detailSurface: 'tale',\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tale,\n subItemSurface: 'chapter',\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.chapter,\n },\n Tunes: {\n detailSurface: 'tune',\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tune,\n subItemSurface: 'tuneTrack',\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack,\n },\n Television: {\n detailSurface: 'television',\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.television,\n subItemSurface: 'televisionEpisode',\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode,\n },\n} as const satisfies Record<WorkProjectType, HallContentSurfaceRouting>;\n\n/** Admin decision reason on a published change request (required on a deny; shown to\n * the member). One owner for the review callable schema AND the admin work-view input. */\nexport const MAX_HALL_CHANGE_REQUEST_REASON_LENGTH = 2000;\n\n// --- Real-people / parody disclaimer (R3, 2026-07-12) ---\n\n/**\n * The ONE standard platform disclaimer rendered on every published work whose\n * author attested it depicts real people (parody / satire / commentary). Two\n * layers, always shown together (DJ, 2026-07-12): the themed playbill HEADER\n * on top, the plain legal MESSAGE underneath. There is no free-text disclaimer\n * anywhere — these constants are the only wording, so a wording change is a\n * single edit here (display surfaces and any backend consumer read these; the\n * text is never persisted on docs). The MESSAGE deliberately never ADMITS the\n * work depicts real people — it hedges (\"even those based on real people\",\n * the standard film-boilerplate move) so the disclaimer never hands over the\n * depiction element of a claim. Legal wording pending counsel confirmation\n * (tracked in docs/ttt-prod-legal/).\n */\nexport const REAL_PEOPLE_DISCLAIMER_HEADER =\n 'A Notice from the Management: the faces may be familiar, but the players are pure ' +\n 'invention — parody and satire, in the grand old tradition of the stage.';\n\nexport const REAL_PEOPLE_DISCLAIMER_MESSAGE =\n 'All characters, statements, and events in this work, even those based on real people, ' +\n 'are entirely fictional and are presented as parody, satire, or commentary. Any voices, ' +\n 'likenesses, or portrayals of real people are impersonated or fictionalized, and nothing ' +\n 'in this work should be understood as a statement of fact about, or as speech by, any ' +\n 'real person. This work is not created by, affiliated with, sponsored by, or endorsed by ' +\n 'any real person portrayed or referenced in it.';\n\n// --- Hall library per-user viewing-state doc (hall-viewing-experience Area 2, ruled 2026-07-04) ---\n\n/**\n * Caps for the per-user Hall viewing-state doc (`HallLibraryPreferencesSchema`,\n * `userProfiles/{uid}/privateData/hallLibraryPreferences`). Every list on that doc is\n * capped for launch — no unbounded per-user lists. `hiddenWorkIds`/`inkedWorkIds` are\n * oldest-pruned (or the write is rejected with a friendly message once full);\n * `inProgress` is LRU-pruned by `updatedAt`; `recentlyViewed` is capped, newest-kept.\n * Enforcement lives in the backend core (`runX`) that owns this doc — this is the\n * shared source of truth for the cap values themselves.\n */\nexport const HALL_LIBRARY_PREFS_CAPS = {\n hiddenWorkIds: 200,\n inkedWorkIds: 200,\n inProgress: 50,\n recentlyViewed: 20,\n} as const satisfies Record<string, number>;\n\n// --- Auditions ---\n\n/** Maximum length for an audition title. */\nexport const MAX_AUDITION_TITLE_LENGTH = 150;\n\n/** Curated-audition option-video batch bounds (the fixed 2..8 option count carried\n * from the Create click through targetInfo/upload-variables to the create core's\n * re-check). ONE declaration — every `.min()/.max()` derives from these. */\nexport const MIN_CURATED_AUDITION_OPTIONS = 2;\nexport const MAX_CURATED_AUDITION_OPTIONS = 8;\n\n/** Maximum length for an audition description. */\nexport const MAX_AUDITION_DESCRIPTION_LENGTH = 1000;\n\n/**\n * Maximum sponsored-audition payout amount in whole USD accepted at the upload\n * trust boundary. Mirrors MAX_PLEDGE_PAYMENT_AMOUNT_CENTS ($500,000) expressed\n * in dollars — a finite ceiling that rejects absurd/garbage amounts before any\n * downstream processing.\n */\nexport const MAX_SPONSORED_AUDITION_AMOUNT_USD = 500_000;\n\n// --- SquareStreetz (Social Feed) ---\n\n/** Maximum length for a SquareStreetz post. */\nexport const MAX_POST_LENGTH = 500;\n\n/** Maximum number of mentions allowed in a single SquareStreetz post. */\nexport const MAX_MENTIONS = 3;\n\n/** Maximum characters of a mention's display name shown before truncation. */\nexport const MAX_MENTION_DISPLAY_LENGTH = 30;\n\n// --- Messages & Invites ---\n\n/** Maximum length for a guild-invite message. */\nexport const MAX_GUILD_INVITE_MESSAGE_LENGTH = 500;\n\n/** Maximum length for a pledgePayment message. */\nexport const MAX_PLEDGE_PAYMENT_MESSAGE_LENGTH = 500;\n"]}
1
+ {"version":3,"file":"business-content.js","sourceRoot":"","sources":["../../src/constants/business-content.ts"],"names":[],"mappings":"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","sourcesContent":["// Content-surface business-rule constants — commissions, auditions, the social\n// feed, and messaging.\nimport {\n MAX_WORK_PROJECT_TITLE_LENGTH,\n MAX_WORK_PROJECT_DESCRIPTION_LENGTH,\n MAX_CHAPTER_CONTENT_LENGTH,\n MAX_WORK_REALM_TITLE_LENGTH,\n MAX_WORK_REALM_DESCRIPTION_LENGTH,\n} from \"./business-work-project.js\";\nimport { ACTIVE_LIMITS } from './app-mode.js';\nimport type { WorkProjectType } from '../types/content.js';\n\n/** The maximum character length for a SquareStreetz post created on behalf of a workProject. */\nexport const MAX_SQUARE_STREETZ_DESCRIPTION_LENGTH = 150;\n\n// --- Commission Board & Proposals ---\n\n/** Maximum number of open commissions a workProject can have. Mode-varied. */\nexport const MAX_COMMISSION_LISTINGS = ACTIVE_LIMITS.workProject.maxCommissionListings;\n\n/** Maximum number of proposal artisans saved to a commission. */\nexport const MAX_SAVED_PROPOSAL_ARTISANS = 5;\n\n/** Maximum length for a commission title. */\nexport const MAX_COMMISSION_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;\n\n/** Maximum length for a commission description / cover letter. */\nexport const MAX_COMMISSION_DESCRIPTION_LENGTH = 400;\n\n// --- Moderation text-clear + published hall-content text fields ---\n\n/**\n * Neutral placeholder written into a single cleared text field by the moderation\n * text-clear remedy. Canonical wording — the backend `runModerationClearText`\n * core writes exactly this string; a wording change is a single edit here.\n */\nexport const MODERATION_CLEAR_PLACEHOLDER =\n 'Removed by moderation — awaiting an update by the steward.';\n\n/**\n * Default REASON strings recorded on a moderation action when the admin supplies no\n * user-facing reason. Distinct from MODERATION_CLEAR_PLACEHOLDER (which is written INTO\n * cleared content fields) — these are the recorded justification text. Canonical wording;\n * consumers (resolveAdminTask's forceRetitle / chat-delete actions) never inline them.\n */\nexport const MODERATION_DEFAULT_REMOVAL_REASON = 'Removed by moderation.';\nexport const MODERATION_DEFAULT_RETITLE_REASON = 'Title/description removed by moderation.';\n\n/**\n * CANONICAL clearable text-field map for the per-field moderation TEXT-CLEAR remedy.\n * Cross-boundary single owner: the admin field-picker offers this set per surface and\n * the backend clear runner validates + normalizes caller-supplied fields against it.\n * Keys are surfaces; values are the exact document field names (NOT display labels)\n * recorded verbatim in `moderationClearedFields`. Covers every clearable surface —\n * workProject/workRealm shell metadata, hall parent details (tale/tune/television),\n * and hall sub-items (chapter/track/episode).\n */\nexport const MODERATION_CLEARABLE_TEXT_FIELDS = {\n // workProject + workRealm shell metadata\n workProject: ['workingTitle', 'workingDescription'],\n workRealm: ['workingTitle', 'workingDescription'],\n // hall content parent details\n tale: ['title', 'description'],\n tune: ['title', 'description'],\n television: ['title', 'description'],\n // hall content sub-items\n chapter: ['title', 'content'],\n tuneTrack: ['title', 'description'],\n televisionEpisode: ['title', 'description'],\n} as const satisfies Record<string, readonly string[]>;\n\n/** A surface whose text fields the moderation clear remedy can neutralize. */\nexport type ModerationClearableSurface = keyof typeof MODERATION_CLEARABLE_TEXT_FIELDS;\n\n/**\n * Every DISTINCT clearable/changeable text-field NAME, DERIVED from the canonical\n * MODERATION_CLEARABLE_TEXT_FIELDS map (the union of every surface's tuple). Label maps and\n * per-field cap maps key on this instead of `string`, so adding a field to a surface is a\n * compile error until its label and cap exist.\n */\nexport type ClearableTextFieldName =\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS)[ModerationClearableSurface][number];\n\n/**\n * The DISTINCT clearable text-field NAMES across the whole hall content family (tale/tune/\n * television detail → title/description; chapter → title/content; track/episode →\n * title/description). DERIVED from the canonical MODERATION_CLEARABLE_TEXT_FIELDS map — the\n * union of every hall surface's fields — so the `clearHallContentText` callable's field-enum\n * (`HallClearFieldSchema`) never restates the `title`/`description`/`content` literals. Index\n * access on the map's readonly tuples preserves the literal types, so this stays a typed\n * `readonly ['title','description','content']` a `z.enum(...)` can consume directly.\n */\nexport const HALL_CLEARABLE_TEXT_FIELD_NAMES = [\n MODERATION_CLEARABLE_TEXT_FIELDS.tale[0], // title\n MODERATION_CLEARABLE_TEXT_FIELDS.tale[1], // description\n MODERATION_CLEARABLE_TEXT_FIELDS.chapter[1], // content\n] as const;\n\n/**\n * The raw doc field names each published hall-content surface exposes as changeable TEXT.\n * Cross-boundary: the member \"Update details\" field picker offers this set per surface and\n * the change-request submit runner validates against it. Detail surfaces (tale/tune/\n * television) live on the hall parent doc; sub-item surfaces on the published chapter/\n * track/episode doc. This is the HALL-SURFACE SUBSET of the canonical\n * MODERATION_CLEARABLE_TEXT_FIELDS above (it excludes the `workProject` shell) — every\n * tuple is projected from that one owner, so the two can never drift.\n */\nexport const HALL_CONTENT_TEXT_FIELDS = {\n tale: MODERATION_CLEARABLE_TEXT_FIELDS.tale,\n tune: MODERATION_CLEARABLE_TEXT_FIELDS.tune,\n television: MODERATION_CLEARABLE_TEXT_FIELDS.television,\n chapter: MODERATION_CLEARABLE_TEXT_FIELDS.chapter,\n tuneTrack: MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack,\n televisionEpisode: MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode,\n // Realm grain (R1, 2026-07-12): targets the `workRealms/{id}` doc directly.\n workRealm: MODERATION_CLEARABLE_TEXT_FIELDS.workRealm,\n} as const satisfies Record<string, readonly string[]>;\n\n/** Per-field max lengths for proposed hall-content text. DERIVED from the owning\n * constants — never independent numbers — so the change-request pipeline can never\n * drift from the authoring limits again (the pre-2026-07-13 copy carried its own\n * 200/5000/100000 set while authoring enforced 150/300/2500). Keyed on the derived\n * ClearableTextFieldName union, so a new clearable field fails the build here until\n * it has a cap. */\nexport const HALL_CONTENT_TEXT_FIELD_MAX = {\n title: MAX_WORK_PROJECT_TITLE_LENGTH,\n description: MAX_WORK_PROJECT_DESCRIPTION_LENGTH,\n content: MAX_CHAPTER_CONTENT_LENGTH,\n workingTitle: MAX_WORK_REALM_TITLE_LENGTH,\n workingDescription: MAX_WORK_REALM_DESCRIPTION_LENGTH,\n} as const satisfies Record<ClearableTextFieldName, number>;\n\n/** One work-project type's two hall text surfaces — the published DETAIL on the hall parent\n * and its chapter/track/episode SUB-ITEM — each with the clearable/changeable field tuple\n * that surface exposes. */\nexport interface HallContentSurfaceRouting {\n /** Surface identity of the hall parent DETAIL (tale / tune / television). */\n detailSurface: ModerationClearableSurface;\n /** The DETAIL surface's clearable text fields. */\n detailFields: readonly ClearableTextFieldName[];\n /** Surface identity of the SUB-ITEM (chapter / tuneTrack / televisionEpisode). */\n subItemSurface: ModerationClearableSurface;\n /** The SUB-ITEM surface's clearable text fields — a Tale chapter carries title/content, a\n * Tune track and a Television episode title/description. */\n subItemFields: readonly ClearableTextFieldName[];\n}\n\n/**\n * CANONICAL WorkProjectType → hall text-surface routing. The ONE owner of \"a Tale's sub-item is\n * a chapter, a Tune's is a tuneTrack, a Television's is a televisionEpisode\" and of which fields\n * each of those surfaces exposes. Cross-boundary: the backend text-clear and change-request\n * runners resolve `surface` from (workProjectType, is-sub-item?) through this map, and the admin\n * field pickers project their checkbox options from the same entry — three sites that each\n * hand-rolled the routing before (a ternary that fell through to the tuneTrack tuple for\n * Television, silently correct only because the two tuples happen to match today).\n *\n * Every field tuple is PROJECTED from MODERATION_CLEARABLE_TEXT_FIELDS above — no field literal\n * is restated here — and the `satisfies Record<WorkProjectType, …>` makes adding a work-project\n * type a compile error until its surfaces are routed.\n */\nexport const HALL_CONTENT_SURFACES_BY_WORK_TYPE = {\n Tales: {\n detailSurface: 'tale',\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tale,\n subItemSurface: 'chapter',\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.chapter,\n },\n Tunes: {\n detailSurface: 'tune',\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tune,\n subItemSurface: 'tuneTrack',\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack,\n },\n Television: {\n detailSurface: 'television',\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.television,\n subItemSurface: 'televisionEpisode',\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode,\n },\n} as const satisfies Record<WorkProjectType, HallContentSurfaceRouting>;\n\n/** Admin decision reason on a published change request (required on a deny; shown to\n * the member). One owner for the review callable schema AND the admin work-view input. */\nexport const MAX_HALL_CHANGE_REQUEST_REASON_LENGTH = 2000;\n\n// --- Real-people / parody disclaimer (R3, 2026-07-12) ---\n\n/**\n * The ONE standard platform disclaimer rendered on every published work whose\n * author attested it depicts real people (parody / satire / commentary). Two\n * layers, always shown together (DJ, 2026-07-12): the themed playbill HEADER\n * on top, the plain legal MESSAGE underneath. There is no free-text disclaimer\n * anywhere — these constants are the only wording, so a wording change is a\n * single edit here (display surfaces and any backend consumer read these; the\n * text is never persisted on docs). The MESSAGE deliberately never ADMITS the\n * work depicts real people — it hedges (\"even those based on real people\",\n * the standard film-boilerplate move) so the disclaimer never hands over the\n * depiction element of a claim. Legal wording pending counsel confirmation\n * (tracked in docs/ttt-prod-legal/).\n */\nexport const REAL_PEOPLE_DISCLAIMER_HEADER =\n 'A Notice from the Management: the faces may be familiar, but the players are pure ' +\n 'invention — parody and satire, in the grand old tradition of the stage.';\n\nexport const REAL_PEOPLE_DISCLAIMER_MESSAGE =\n 'All characters, statements, and events in this work, even those based on real people, ' +\n 'are entirely fictional and are presented as parody, satire, or commentary. Any voices, ' +\n 'likenesses, or portrayals of real people are impersonated or fictionalized, and nothing ' +\n 'in this work should be understood as a statement of fact about, or as speech by, any ' +\n 'real person. This work is not created by, affiliated with, sponsored by, or endorsed by ' +\n 'any real person portrayed or referenced in it.';\n\n// --- Hall library per-user viewing-state doc (hall-viewing-experience Area 2, ruled 2026-07-04) ---\n\n/**\n * Caps for the per-user Hall viewing-state doc (`HallLibraryPreferencesSchema`,\n * `userProfiles/{uid}/privateData/hallLibraryPreferences`). Every list on that doc is\n * capped for launch — no unbounded per-user lists. `hiddenWorkIds`/`inkedWorkIds` are\n * oldest-pruned (or the write is rejected with a friendly message once full);\n * `inProgress` is LRU-pruned by `updatedAt`; `recentlyViewed` is capped, newest-kept.\n * Enforcement lives in the backend core (`runX`) that owns this doc — this is the\n * shared source of truth for the cap values themselves.\n */\nexport const HALL_LIBRARY_PREFS_CAPS = {\n hiddenWorkIds: 200,\n inkedWorkIds: 200,\n inProgress: 50,\n recentlyViewed: 20,\n} as const satisfies Record<string, number>;\n\n// --- Auditions ---\n\n/** Maximum length for an audition title. */\nexport const MAX_AUDITION_TITLE_LENGTH = 150;\n\n/** Curated-audition option-video batch bounds (the fixed 2..8 option count carried\n * from the Create click through targetInfo/upload-variables to the create core's\n * re-check). ONE declaration — every `.min()/.max()` derives from these. */\nexport const MIN_CURATED_AUDITION_OPTIONS = 2;\nexport const MAX_CURATED_AUDITION_OPTIONS = 8;\n\n/** Maximum length for an audition description. */\nexport const MAX_AUDITION_DESCRIPTION_LENGTH = 1000;\n\n/**\n * Maximum sponsored-audition payout amount in whole USD accepted at the upload\n * trust boundary. Mirrors MAX_PLEDGE_PAYMENT_AMOUNT_CENTS ($500,000) expressed\n * in dollars — a finite ceiling that rejects absurd/garbage amounts before any\n * downstream processing.\n */\nexport const MAX_SPONSORED_AUDITION_AMOUNT_USD = 500_000;\n\n/**\n * The one user-facing rejection sentence when a Work's own active guildmate tries to enter\n * that Work's open audition (entries exist to recruit OUTSIDERS; a member can't be\n * recruited). Shared by both backend enforcement points (upload-accept and publish) — it is\n * the `failed-precondition` answer text the entry UI renders verbatim.\n */\nexport const GUILDMATE_AUDITION_ENTRY_REJECTION =\n 'You are already a guildmate of this Work — its audition is for recruiting new collaborators.';\n\n// --- SquareStreetz (Social Feed) ---\n\n/** Maximum length for a SquareStreetz post. */\nexport const MAX_POST_LENGTH = 500;\n\n/** Maximum number of mentions allowed in a single SquareStreetz post. */\nexport const MAX_MENTIONS = 3;\n\n/** Maximum characters of a mention's display name shown before truncation. */\nexport const MAX_MENTION_DISPLAY_LENGTH = 30;\n\n// --- Messages & Invites ---\n\n/** Maximum length for a guild-invite message. */\nexport const MAX_GUILD_INVITE_MESSAGE_LENGTH = 500;\n\n/** Maximum length for a pledgePayment message. */\nexport const MAX_PLEDGE_PAYMENT_MESSAGE_LENGTH = 500;\n"]}
@@ -11,6 +11,14 @@ export declare const USERNAME_REGEX: RegExp;
11
11
  * share-tombstone records render with this label.
12
12
  */
13
13
  export declare const FORMER_MEMBER_DISPLAY_NAME = "Former member";
14
+ /**
15
+ * N3 account deletion / GDPR erasure — the grace window (days) between the deletion
16
+ * request and the destructive scrub. Logging back in during the window is the one cancel.
17
+ * Persisted on each request as `graceDays` (compliance trail) and stated as product policy
18
+ * in the user-facing data-deletion documents — ONE declaration; the callable and the copy
19
+ * both derive from it.
20
+ */
21
+ export declare const ACCOUNT_DELETION_GRACE_DAYS = 30;
14
22
  /** Maximum number of craft-skills a user can upload to their profile. Mode-varied. */
15
23
  export declare const CRAFT_SKILL_LIMIT: number;
16
24
  /** Maximum number of work projects an artisan can own (steward) at once. */
@@ -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;AAIrC;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,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;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAM9C,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"}
@@ -14,6 +14,14 @@ export const USERNAME_REGEX = /^[a-zA-Z0-9]+$/;
14
14
  * share-tombstone records render with this label.
15
15
  */
16
16
  export const FORMER_MEMBER_DISPLAY_NAME = 'Former member';
17
+ /**
18
+ * N3 account deletion / GDPR erasure — the grace window (days) between the deletion
19
+ * request and the destructive scrub. Logging back in during the window is the one cancel.
20
+ * Persisted on each request as `graceDays` (compliance trail) and stated as product policy
21
+ * in the user-facing data-deletion documents — ONE declaration; the callable and the copy
22
+ * both derive from it.
23
+ */
24
+ export const ACCOUNT_DELETION_GRACE_DAYS = 30;
17
25
  import { ACTIVE_LIMITS } from './app-mode.js';
18
26
  // --- User Profile Craft Skills ---
19
27
  /** Maximum number of craft-skills a user can upload to their profile. Mode-varied. */
@@ -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;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 * ttt-prod docs/design/landing-backstage-guide-and-first-visit-plan.md §10.\n */\nexport const SITE_TOUR_CURRENT_VERSION = 1;\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;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,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\n/**\n * N3 account deletion / GDPR erasure — the grace window (days) between the deletion\n * request and the destructive scrub. Logging back in during the window is the one cancel.\n * Persisted on each request as `graceDays` (compliance trail) and stated as product policy\n * in the user-facing data-deletion documents — ONE declaration; the callable and the copy\n * both derive from it.\n */\nexport const ACCOUNT_DELETION_GRACE_DAYS = 30;\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 * ttt-prod docs/design/landing-backstage-guide-and-first-visit-plan.md §10.\n */\nexport const SITE_TOUR_CURRENT_VERSION = 1;\n"]}
@@ -14,4 +14,13 @@ export declare const MAX_CHAT_MESSAGE_LENGTH = 4000;
14
14
  export declare const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;
15
15
  /** Guild chat channel description — same single-owner rule as the name. */
16
16
  export declare const MAX_GUILD_CHAT_CHANNEL_DESCRIPTION_LENGTH = 150;
17
+ /**
18
+ * The ONE user-facing sentence for "the chat service itself is down right now"
19
+ * (DJ ruling 2026-07-30). A chat callable that cannot reach the Cloudflare chat Worker
20
+ * answers `unavailable` with this message, and every chat call site renders this copy
21
+ * instead of the generic error toast — so an outage reads as an outage, on both sides of
22
+ * the wire. Shared by the backend answer text (functions chat-internal-call) and the
23
+ * client surface (src/lib/chat-realtime), which previously carried two hand-synced copies.
24
+ */
25
+ export declare const CHAT_TEMPORARILY_UNAVAILABLE_MESSAGE = "Chat is temporarily unavailable. Please try again in a moment.";
17
26
  //# sourceMappingURL=chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C;4FAC4F;AAC5F,eAAO,MAAM,kCAAkC,KAAK,CAAC;AAErD,2EAA2E;AAC3E,eAAO,MAAM,yCAAyC,MAAM,CAAC"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C;4FAC4F;AAC5F,eAAO,MAAM,kCAAkC,KAAK,CAAC;AAErD,2EAA2E;AAC3E,eAAO,MAAM,yCAAyC,MAAM,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAO,MAAM,oCAAoC,mEACiB,CAAC"}
@@ -14,4 +14,13 @@ export const MAX_CHAT_MESSAGE_LENGTH = 4000;
14
14
  export const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;
15
15
  /** Guild chat channel description — same single-owner rule as the name. */
16
16
  export const MAX_GUILD_CHAT_CHANNEL_DESCRIPTION_LENGTH = 150;
17
+ /**
18
+ * The ONE user-facing sentence for "the chat service itself is down right now"
19
+ * (DJ ruling 2026-07-30). A chat callable that cannot reach the Cloudflare chat Worker
20
+ * answers `unavailable` with this message, and every chat call site renders this copy
21
+ * instead of the generic error toast — so an outage reads as an outage, on both sides of
22
+ * the wire. Shared by the backend answer text (functions chat-internal-call) and the
23
+ * client surface (src/lib/chat-realtime), which previously carried two hand-synced copies.
24
+ */
25
+ export const CHAT_TEMPORARILY_UNAVAILABLE_MESSAGE = 'Chat is temporarily unavailable. Please try again in a moment.';
17
26
  //# sourceMappingURL=chat.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAE5C;4FAC4F;AAC5F,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAErD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,yCAAyC,GAAG,GAAG,CAAC","sourcesContent":["/**\n * Maximum chat message length (characters) used by ttt-core's chat callable\n * and system-message-action schemas for backend validation.\n *\n * Split ownership by design: chat-core owns its own UI/runtime default\n * (`MAX_CHAT_MESSAGE_LENGTH` in `chat-core/src/constants.ts`); ttt-core owns\n * the value used by callable wire validation. The values are intentionally\n * aligned at 4000; consumers wanting a different limit should override at\n * their own call site rather than expecting cross-package coordination.\n */\nexport const MAX_CHAT_MESSAGE_LENGTH = 4000;\n\n/** Guild chat channel name — one owner for the create/update callable schemas AND the\n * channel form (whose zod previously carried its own 50 while the backend allowed 100). */\nexport const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;\n\n/** Guild chat channel description — same single-owner rule as the name. */\nexport const MAX_GUILD_CHAT_CHANNEL_DESCRIPTION_LENGTH = 150;\n"]}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/constants/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAE5C;4FAC4F;AAC5F,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAErD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,yCAAyC,GAAG,GAAG,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAC/C,gEAAgE,CAAC","sourcesContent":["/**\n * Maximum chat message length (characters) used by ttt-core's chat callable\n * and system-message-action schemas for backend validation.\n *\n * Split ownership by design: chat-core owns its own UI/runtime default\n * (`MAX_CHAT_MESSAGE_LENGTH` in `chat-core/src/constants.ts`); ttt-core owns\n * the value used by callable wire validation. The values are intentionally\n * aligned at 4000; consumers wanting a different limit should override at\n * their own call site rather than expecting cross-package coordination.\n */\nexport const MAX_CHAT_MESSAGE_LENGTH = 4000;\n\n/** Guild chat channel name — one owner for the create/update callable schemas AND the\n * channel form (whose zod previously carried its own 50 while the backend allowed 100). */\nexport const MAX_GUILD_CHAT_CHANNEL_NAME_LENGTH = 50;\n\n/** Guild chat channel description — same single-owner rule as the name. */\nexport const MAX_GUILD_CHAT_CHANNEL_DESCRIPTION_LENGTH = 150;\n\n/**\n * The ONE user-facing sentence for \"the chat service itself is down right now\"\n * (DJ ruling 2026-07-30). A chat callable that cannot reach the Cloudflare chat Worker\n * answers `unavailable` with this message, and every chat call site renders this copy\n * instead of the generic error toast — so an outage reads as an outage, on both sides of\n * the wire. Shared by the backend answer text (functions chat-internal-call) and the\n * client surface (src/lib/chat-realtime), which previously carried two hand-synced copies.\n */\nexport const CHAT_TEMPORARILY_UNAVAILABLE_MESSAGE =\n 'Chat is temporarily unavailable. Please try again in a moment.';\n"]}
@@ -92,6 +92,7 @@ export declare const AccountDeletionRequestV1Schema: z.ZodObject<{
92
92
  scheduledScrubAt: z.ZodNumber;
93
93
  graceDays: z.ZodNumber;
94
94
  cancelledAt: z.ZodOptional<z.ZodNumber>;
95
+ tokensRevokedAt: z.ZodOptional<z.ZodNumber>;
95
96
  scrubStartedAt: z.ZodOptional<z.ZodNumber>;
96
97
  parkedReason: z.ZodOptional<z.ZodString>;
97
98
  parkedAt: z.ZodOptional<z.ZodNumber>;
@@ -1 +1 @@
1
- {"version":3,"file":"account-deletion.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/account-deletion.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gDAAgD;AAChD,eAAO,MAAM,kCAAkC;;;;;;;;EAU7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,iCAAiC;;;;;;;;CAQ2B,CAAC;AAEnE,0FAA0F;AAC1F,MAAM,MAAM,2BAA2B,GAAG;KACvC,CAAC,IAAI,4BAA4B,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK;CAC5G,CAAC,4BAA4B,CAAC,CAAC;AAEhC;;gFAEgF;AAChF,eAAO,MAAM,gCAAgC,EAAE,SAAS,2BAA2B,EAEmB,CAAC;AAEvG;;4FAE4F;AAC5F,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,2BAA2B,CAE9F;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;kBAmBtB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0BhC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
1
+ {"version":3,"file":"account-deletion.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/account-deletion.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gDAAgD;AAChD,eAAO,MAAM,kCAAkC;;;;;;;;EAU7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,iCAAiC;;;;;;;;CAQ2B,CAAC;AAEnE,0FAA0F;AAC1F,MAAM,MAAM,2BAA2B,GAAG;KACvC,CAAC,IAAI,4BAA4B,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK;CAC5G,CAAC,4BAA4B,CAAC,CAAC;AAEhC;;gFAEgF;AAChF,eAAO,MAAM,gCAAgC,EAAE,SAAS,2BAA2B,EAEmB,CAAC;AAEvG;;4FAE4F;AAC5F,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,2BAA2B,CAE9F;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;kBAmBtB,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,yEAAyE;AACzE,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiChC,CAAC;AACZ,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC"}
@@ -118,6 +118,13 @@ export const AccountDeletionRequestV1Schema = z
118
118
  scheduledScrubAt: z.number(),
119
119
  graceDays: z.number(), // recorded for the audit/compliance trail (30 at launch)
120
120
  cancelledAt: z.number().optional(),
121
+ // When the user's refresh tokens were revoked for THIS request ("account deletion signs
122
+ // the user out of every session everywhere"). ABSENT = the obligation is still pending:
123
+ // the request doc IS the durable state (BACKEND-302/QUALITY-104) — the callable's
124
+ // immediate revoke is only the accelerator, and the scheduled scrub-worker drain
125
+ // re-revokes + stamps any ACTIVE request missing this field until it succeeds.
126
+ // Revocation is idempotent, so a lost stamp merely causes one redundant re-revoke.
127
+ tokensRevokedAt: z.number().optional(),
121
128
  scrubStartedAt: z.number().optional(),
122
129
  // Why a scrub is parked (e.g. 'blocking safety hold over user data') — kept for
123
130
  // the GDPR compliance record so a deferred erasure is explainable.
@@ -1 +1 @@
1
- {"version":3,"file":"account-deletion.js","sourceRoot":"","sources":["../../src/doc-schemas/account-deletion.ts"],"names":[],"mappings":"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","sourcesContent":["// Account-deletion / GDPR-erasure request SCHEMA — `accountDeletionRequests/{uid}`.\n//\n// N3 data-deletion flow. A user clicks \"delete account\" on their profile → a\n// request doc is created (one per user, doc id = uid, create-if-absent) and the\n// account is immediately deactivated/locked out. The request runs a 30-day grace\n// window (logging back in CANCELS it). After the window, the scheduled scrub\n// worker checks for any BLOCKING safety hold over the user's data:\n// - no hold → anonymize-in-place (scrub PII, release reserved name, anonymize\n// chat history, tombstone memberships) → `completed`.\n// - hold → `parkedOnHold` (re-checked periodically): resumes + `completed`\n// once cleared, or → `superseded` if it becomes a ban-for-cause /\n// evidence-preservation outcome (the erasure is overridden and the\n// data retained as evidence).\n//\n// The scrub itself deletes/anonymizes data across many collections; this doc is\n// ONLY the request lifecycle + the worker's resumable cursor.\n//\n// [C-02] Erasure-vs-safety-hold race fence. The destructive scrub and a safety\n// hold landing mid-scrub race over the SAME account. The fence is an epoch LEASE\n// stamped on THIS doc (`erasureLease`): the scrub transactionally acquires the\n// lease ONLY when the account owns no active blocking hold; every destructive\n// write re-checks the SAME epoch in its own transaction; and `commitSafetyHold`\n// (the SINGLE shared hold authority) reads this doc's live lease and PARKS the\n// erasure (revoking the epoch) before committing a hold against a leased account.\n// A revoked epoch makes every still-running destructive step a no-op. The lease\n// lives HERE — not a parallel safety-only deletion subsystem — so the one shared\n// hold/destructive contract owns the fence (engineering-rules ARCH-001).\n\nimport { z } from 'zod';\n\n/** Lifecycle of an account-deletion request. */\nexport const AccountDeletionRequestStatusSchema = z.enum([\n 'pending', // grace window running; user can still cancel by logging in\n 'cancelled', // user cancelled (logged back in) before the window elapsed\n 'scrubbing', // the scrub worker has started the anonymize-in-place erasure\n // [C-02] the scrub holds an ACTIVE erasure lease and is mid-destruction. A hold\n // landing now revokes the lease (→ parkedOnHold) so the scrub aborts deterministically.\n 'leased',\n 'parkedOnHold', // erasure deferred — a blocking safety hold covers the user's data\n 'completed', // erasure finished\n 'superseded', // overridden by a ban-for-cause / evidence-preservation outcome\n]);\nexport type AccountDeletionRequestStatus = z.infer<typeof AccountDeletionRequestStatusSchema>;\n\n/**\n * ACTIVE = the request is still OPEN and still cancellable. This is the one predicate the\n * lifecycle's enforcement points share — `requestAccountDeletion`'s idempotent re-return of the\n * existing schedule, `cancelAccountDeletion`'s cancel gate, the scrub worker's due-request query,\n * and the client's live own-request read — each of which previously restated\n * `status === 'pending' || status === 'parkedOnHold'` locally (ARCH-102).\n *\n * Declared as an EXHAUSTIVE Record over the status union, not as a subset array: a subset array\n * only catches a REMOVED member, whereas adding a lifecycle status must be a compile error here\n * until that status is classified. A new status silently defaulting to \"not active\" is exactly the\n * drift this classification exists to prevent.\n *\n * `scrubbing` / `leased` are deliberately NOT active — the destructive erasure has already begun,\n * so there is no schedule left to re-offer and nothing left to cancel. `cancelled` / `completed` /\n * `superseded` are terminal.\n */\nconst DELETION_REQUEST_STATUS_IS_ACTIVE = {\n pending: true,\n cancelled: false,\n scrubbing: false,\n leased: false,\n parkedOnHold: true,\n completed: false,\n superseded: false,\n} as const satisfies Record<AccountDeletionRequestStatus, boolean>;\n\n/** The statuses classified ACTIVE above, as a literal union — derived, never restated. */\nexport type ActiveDeletionRequestStatus = {\n [K in AccountDeletionRequestStatus]: (typeof DELETION_REQUEST_STATUS_IS_ACTIVE)[K] extends true ? K : never;\n}[AccountDeletionRequestStatus];\n\n/** The ACTIVE (open, still-cancellable) deletion-request statuses, projected from the\n * classification above in union-declaration order — so it can also feed a Firestore\n * `where('status', 'in', ACTIVE_DELETION_REQUEST_STATUSES)` query directly. */\nexport const ACTIVE_DELETION_REQUEST_STATUSES: readonly ActiveDeletionRequestStatus[] = (\n Object.keys(DELETION_REQUEST_STATUS_IS_ACTIVE) as AccountDeletionRequestStatus[]\n).filter((status): status is ActiveDeletionRequestStatus => DELETION_REQUEST_STATUS_IS_ACTIVE[status]);\n\n/** True for an ACTIVE (open, still-cancellable) deletion request. Takes `unknown` because every\n * caller reads the status off an unvalidated Firestore doc: anything outside the canonical active\n * set — a terminal/mid-scrub status, an unrecognized value, a missing field — is false. */\nexport function isActiveDeletionRequest(status: unknown): status is ActiveDeletionRequestStatus {\n return typeof status === 'string' && (ACTIVE_DELETION_REQUEST_STATUSES as readonly string[]).includes(status);\n}\n\n/**\n * [C-02] The erasure LEASE / epoch token — the race fence between the destructive\n * scrub and a mid-scrub safety hold.\n *\n * The scrub acquires this transactionally ONLY when the account owns no active\n * blocking hold; it then re-verifies the SAME `epoch` inside every destructive\n * Firestore transaction and immediately before AND after each non-transactional\n * external delete (Auth/Storage). `commitSafetyHold` reads this lease and, when it\n * is `active`, REVOKES it (sets `revokedByHold`/`revokedAt`, status → `parkedOnHold`)\n * in the SAME transaction that commits the hold — so a hold deterministically wins\n * the race and the scrub, finding its epoch revoked on the next check, aborts into\n * a recoverable parked state without finishing the destruction.\n */\nexport const ErasureLeaseV1Schema = z\n .object({\n /** Monotonic acquisition token. The \"live lease\" identity: every destructive step\n * re-reads the doc and proceeds ONLY if this still equals the epoch it acquired. */\n epoch: z.number().int().nonnegative(),\n /** 'active' = the scrub holds the lease; 'revoked' = a hold reclaimed it mid-scrub\n * (the scrub must abort); 'released' = the scrub finished/relinquished cleanly. */\n state: z.enum(['active', 'revoked', 'released']),\n acquiredAt: z.number(),\n /** Staleness boundary. A still-`active` lease past this is presumed crashed and may\n * be safely superseded by a fresh acquisition (idempotent retry / crash recovery). */\n expiresAt: z.number(),\n /** Last destructive phase the scrub reached under this epoch (observability + recovery). */\n phase: z.string().optional(),\n /** Set when a hold revoked the lease — the caseId/refId of the winning hold (audit trail). */\n revokedByHoldRefId: z.string().min(1).optional(),\n revokedAt: z.number().optional(),\n releasedAt: z.number().optional(),\n })\n .strict();\nexport type ErasureLeaseV1 = z.infer<typeof ErasureLeaseV1Schema>;\n\n/** `accountDeletionRequests/{uid}` — one per user; doc id IS the uid. */\nexport const AccountDeletionRequestV1Schema = z\n .object({\n schemaVersion: z.literal(1),\n uid: z.string().min(1),\n status: AccountDeletionRequestStatusSchema,\n requestedAt: z.number(),\n // requestedAt + graceDays; the scrub worker queries status='pending' AND\n // scheduledScrubAt <= now (composite index, ttt-prod firestore.indexes.json).\n scheduledScrubAt: z.number(),\n graceDays: z.number(), // recorded for the audit/compliance trail (30 at launch)\n cancelledAt: z.number().optional(),\n scrubStartedAt: z.number().optional(),\n // Why a scrub is parked (e.g. 'blocking safety hold over user data') — kept for\n // the GDPR compliance record so a deferred erasure is explainable.\n parkedReason: z.string().optional(),\n parkedAt: z.number().optional(),\n lastHoldCheckAt: z.number().optional(),\n completedAt: z.number().optional(),\n supersededAt: z.number().optional(),\n supersededReason: z.string().optional(),\n // [C-02] the erasure-vs-hold race fence (see ErasureLeaseV1). Absent until the\n // scrub first acquires the lease; thereafter it carries the live epoch + state.\n erasureLease: ErasureLeaseV1Schema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n })\n .strict();\nexport type AccountDeletionRequestV1 = z.infer<typeof AccountDeletionRequestV1Schema>;\n"]}
1
+ {"version":3,"file":"account-deletion.js","sourceRoot":"","sources":["../../src/doc-schemas/account-deletion.ts"],"names":[],"mappings":"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","sourcesContent":["// Account-deletion / GDPR-erasure request SCHEMA — `accountDeletionRequests/{uid}`.\n//\n// N3 data-deletion flow. A user clicks \"delete account\" on their profile → a\n// request doc is created (one per user, doc id = uid, create-if-absent) and the\n// account is immediately deactivated/locked out. The request runs a 30-day grace\n// window (logging back in CANCELS it). After the window, the scheduled scrub\n// worker checks for any BLOCKING safety hold over the user's data:\n// - no hold → anonymize-in-place (scrub PII, release reserved name, anonymize\n// chat history, tombstone memberships) → `completed`.\n// - hold → `parkedOnHold` (re-checked periodically): resumes + `completed`\n// once cleared, or → `superseded` if it becomes a ban-for-cause /\n// evidence-preservation outcome (the erasure is overridden and the\n// data retained as evidence).\n//\n// The scrub itself deletes/anonymizes data across many collections; this doc is\n// ONLY the request lifecycle + the worker's resumable cursor.\n//\n// [C-02] Erasure-vs-safety-hold race fence. The destructive scrub and a safety\n// hold landing mid-scrub race over the SAME account. The fence is an epoch LEASE\n// stamped on THIS doc (`erasureLease`): the scrub transactionally acquires the\n// lease ONLY when the account owns no active blocking hold; every destructive\n// write re-checks the SAME epoch in its own transaction; and `commitSafetyHold`\n// (the SINGLE shared hold authority) reads this doc's live lease and PARKS the\n// erasure (revoking the epoch) before committing a hold against a leased account.\n// A revoked epoch makes every still-running destructive step a no-op. The lease\n// lives HERE — not a parallel safety-only deletion subsystem — so the one shared\n// hold/destructive contract owns the fence (engineering-rules ARCH-001).\n\nimport { z } from 'zod';\n\n/** Lifecycle of an account-deletion request. */\nexport const AccountDeletionRequestStatusSchema = z.enum([\n 'pending', // grace window running; user can still cancel by logging in\n 'cancelled', // user cancelled (logged back in) before the window elapsed\n 'scrubbing', // the scrub worker has started the anonymize-in-place erasure\n // [C-02] the scrub holds an ACTIVE erasure lease and is mid-destruction. A hold\n // landing now revokes the lease (→ parkedOnHold) so the scrub aborts deterministically.\n 'leased',\n 'parkedOnHold', // erasure deferred — a blocking safety hold covers the user's data\n 'completed', // erasure finished\n 'superseded', // overridden by a ban-for-cause / evidence-preservation outcome\n]);\nexport type AccountDeletionRequestStatus = z.infer<typeof AccountDeletionRequestStatusSchema>;\n\n/**\n * ACTIVE = the request is still OPEN and still cancellable. This is the one predicate the\n * lifecycle's enforcement points share — `requestAccountDeletion`'s idempotent re-return of the\n * existing schedule, `cancelAccountDeletion`'s cancel gate, the scrub worker's due-request query,\n * and the client's live own-request read — each of which previously restated\n * `status === 'pending' || status === 'parkedOnHold'` locally (ARCH-102).\n *\n * Declared as an EXHAUSTIVE Record over the status union, not as a subset array: a subset array\n * only catches a REMOVED member, whereas adding a lifecycle status must be a compile error here\n * until that status is classified. A new status silently defaulting to \"not active\" is exactly the\n * drift this classification exists to prevent.\n *\n * `scrubbing` / `leased` are deliberately NOT active — the destructive erasure has already begun,\n * so there is no schedule left to re-offer and nothing left to cancel. `cancelled` / `completed` /\n * `superseded` are terminal.\n */\nconst DELETION_REQUEST_STATUS_IS_ACTIVE = {\n pending: true,\n cancelled: false,\n scrubbing: false,\n leased: false,\n parkedOnHold: true,\n completed: false,\n superseded: false,\n} as const satisfies Record<AccountDeletionRequestStatus, boolean>;\n\n/** The statuses classified ACTIVE above, as a literal union — derived, never restated. */\nexport type ActiveDeletionRequestStatus = {\n [K in AccountDeletionRequestStatus]: (typeof DELETION_REQUEST_STATUS_IS_ACTIVE)[K] extends true ? K : never;\n}[AccountDeletionRequestStatus];\n\n/** The ACTIVE (open, still-cancellable) deletion-request statuses, projected from the\n * classification above in union-declaration order — so it can also feed a Firestore\n * `where('status', 'in', ACTIVE_DELETION_REQUEST_STATUSES)` query directly. */\nexport const ACTIVE_DELETION_REQUEST_STATUSES: readonly ActiveDeletionRequestStatus[] = (\n Object.keys(DELETION_REQUEST_STATUS_IS_ACTIVE) as AccountDeletionRequestStatus[]\n).filter((status): status is ActiveDeletionRequestStatus => DELETION_REQUEST_STATUS_IS_ACTIVE[status]);\n\n/** True for an ACTIVE (open, still-cancellable) deletion request. Takes `unknown` because every\n * caller reads the status off an unvalidated Firestore doc: anything outside the canonical active\n * set — a terminal/mid-scrub status, an unrecognized value, a missing field — is false. */\nexport function isActiveDeletionRequest(status: unknown): status is ActiveDeletionRequestStatus {\n return typeof status === 'string' && (ACTIVE_DELETION_REQUEST_STATUSES as readonly string[]).includes(status);\n}\n\n/**\n * [C-02] The erasure LEASE / epoch token — the race fence between the destructive\n * scrub and a mid-scrub safety hold.\n *\n * The scrub acquires this transactionally ONLY when the account owns no active\n * blocking hold; it then re-verifies the SAME `epoch` inside every destructive\n * Firestore transaction and immediately before AND after each non-transactional\n * external delete (Auth/Storage). `commitSafetyHold` reads this lease and, when it\n * is `active`, REVOKES it (sets `revokedByHold`/`revokedAt`, status → `parkedOnHold`)\n * in the SAME transaction that commits the hold — so a hold deterministically wins\n * the race and the scrub, finding its epoch revoked on the next check, aborts into\n * a recoverable parked state without finishing the destruction.\n */\nexport const ErasureLeaseV1Schema = z\n .object({\n /** Monotonic acquisition token. The \"live lease\" identity: every destructive step\n * re-reads the doc and proceeds ONLY if this still equals the epoch it acquired. */\n epoch: z.number().int().nonnegative(),\n /** 'active' = the scrub holds the lease; 'revoked' = a hold reclaimed it mid-scrub\n * (the scrub must abort); 'released' = the scrub finished/relinquished cleanly. */\n state: z.enum(['active', 'revoked', 'released']),\n acquiredAt: z.number(),\n /** Staleness boundary. A still-`active` lease past this is presumed crashed and may\n * be safely superseded by a fresh acquisition (idempotent retry / crash recovery). */\n expiresAt: z.number(),\n /** Last destructive phase the scrub reached under this epoch (observability + recovery). */\n phase: z.string().optional(),\n /** Set when a hold revoked the lease — the caseId/refId of the winning hold (audit trail). */\n revokedByHoldRefId: z.string().min(1).optional(),\n revokedAt: z.number().optional(),\n releasedAt: z.number().optional(),\n })\n .strict();\nexport type ErasureLeaseV1 = z.infer<typeof ErasureLeaseV1Schema>;\n\n/** `accountDeletionRequests/{uid}` — one per user; doc id IS the uid. */\nexport const AccountDeletionRequestV1Schema = z\n .object({\n schemaVersion: z.literal(1),\n uid: z.string().min(1),\n status: AccountDeletionRequestStatusSchema,\n requestedAt: z.number(),\n // requestedAt + graceDays; the scrub worker queries status='pending' AND\n // scheduledScrubAt <= now (composite index, ttt-prod firestore.indexes.json).\n scheduledScrubAt: z.number(),\n graceDays: z.number(), // recorded for the audit/compliance trail (30 at launch)\n cancelledAt: z.number().optional(),\n // When the user's refresh tokens were revoked for THIS request (\"account deletion signs\n // the user out of every session everywhere\"). ABSENT = the obligation is still pending:\n // the request doc IS the durable state (BACKEND-302/QUALITY-104) — the callable's\n // immediate revoke is only the accelerator, and the scheduled scrub-worker drain\n // re-revokes + stamps any ACTIVE request missing this field until it succeeds.\n // Revocation is idempotent, so a lost stamp merely causes one redundant re-revoke.\n tokensRevokedAt: z.number().optional(),\n scrubStartedAt: z.number().optional(),\n // Why a scrub is parked (e.g. 'blocking safety hold over user data') — kept for\n // the GDPR compliance record so a deferred erasure is explainable.\n parkedReason: z.string().optional(),\n parkedAt: z.number().optional(),\n lastHoldCheckAt: z.number().optional(),\n completedAt: z.number().optional(),\n supersededAt: z.number().optional(),\n supersededReason: z.string().optional(),\n // [C-02] the erasure-vs-hold race fence (see ErasureLeaseV1). Absent until the\n // scrub first acquires the lease; thereafter it carries the live epoch + state.\n erasureLease: ErasureLeaseV1Schema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n })\n .strict();\nexport type AccountDeletionRequestV1 = z.infer<typeof AccountDeletionRequestV1Schema>;\n"]}
@@ -1521,6 +1521,14 @@ export declare const COLLECTION_SCHEMAS: {
1521
1521
  }>>;
1522
1522
  workProjectId: z.ZodOptional<z.ZodString>;
1523
1523
  hallItemId: z.ZodOptional<z.ZodString>;
1524
+ reportedUserId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1525
+ reportedItemType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1526
+ reportedItemId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1527
+ parentItemId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1528
+ closureHistory: z.ZodOptional<z.ZodArray<z.ZodObject<{
1529
+ completedAt: z.ZodNullable<z.ZodNumber>;
1530
+ reopenedAt: z.ZodNumber;
1531
+ }, z.core.$strip>>>;
1524
1532
  }, z.core.$strip>;
1525
1533
  readonly 'contentViolations/{violationId}': z.ZodObject<{
1526
1534
  id: z.ZodString;
@@ -2096,7 +2104,7 @@ export declare const COLLECTION_SCHEMAS: {
2096
2104
  workProjectId: z.ZodOptional<z.ZodString>;
2097
2105
  }, z.core.$strict>;
2098
2106
  }, z.core.$strict>, z.ZodObject<{
2099
- type: z.ZodLiteral<"commission.deleted">;
2107
+ type: z.ZodLiteral<"commission.closed">;
2100
2108
  ids: z.ZodObject<{
2101
2109
  commissionListingId: z.ZodString;
2102
2110
  workProjectId: z.ZodString;
@@ -2526,7 +2534,7 @@ export declare const COLLECTION_SCHEMAS: {
2526
2534
  workProjectId: z.ZodOptional<z.ZodString>;
2527
2535
  }, z.core.$strict>;
2528
2536
  }, z.core.$strict>, z.ZodObject<{
2529
- type: z.ZodLiteral<"commission.deleted">;
2537
+ type: z.ZodLiteral<"commission.closed">;
2530
2538
  ids: z.ZodObject<{
2531
2539
  commissionListingId: z.ZodString;
2532
2540
  workProjectId: z.ZodString;
@@ -2887,7 +2895,7 @@ export declare const COLLECTION_SCHEMAS: {
2887
2895
  workProjectId: z.ZodOptional<z.ZodString>;
2888
2896
  }, z.core.$strict>;
2889
2897
  }, z.core.$strict>, z.ZodObject<{
2890
- type: z.ZodLiteral<"commission.deleted">;
2898
+ type: z.ZodLiteral<"commission.closed">;
2891
2899
  ids: z.ZodObject<{
2892
2900
  commissionListingId: z.ZodString;
2893
2901
  workProjectId: z.ZodString;
@@ -3319,7 +3327,7 @@ export declare const COLLECTION_SCHEMAS: {
3319
3327
  workProjectId: z.ZodOptional<z.ZodString>;
3320
3328
  }, z.core.$strict>;
3321
3329
  }, z.core.$strict>, z.ZodObject<{
3322
- type: z.ZodLiteral<"commission.deleted">;
3330
+ type: z.ZodLiteral<"commission.closed">;
3323
3331
  ids: z.ZodObject<{
3324
3332
  commissionListingId: z.ZodString;
3325
3333
  workProjectId: z.ZodString;
@@ -4185,6 +4193,7 @@ export declare const COLLECTION_SCHEMAS: {
4185
4193
  scheduledScrubAt: z.ZodNumber;
4186
4194
  graceDays: z.ZodNumber;
4187
4195
  cancelledAt: z.ZodOptional<z.ZodNumber>;
4196
+ tokensRevokedAt: z.ZodOptional<z.ZodNumber>;
4188
4197
  scrubStartedAt: z.ZodOptional<z.ZodNumber>;
4189
4198
  parkedReason: z.ZodOptional<z.ZodString>;
4190
4199
  parkedAt: z.ZodOptional<z.ZodNumber>;
@@ -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;AAiM7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6NkB,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;AAiM7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6NkB,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"}
@@ -24,6 +24,19 @@ export declare const CheckoutDetailsSchema: z.ZodObject<{
24
24
  expiresAt: z.ZodNumber;
25
25
  workLaterUntil: z.ZodNullable<z.ZodNumber>;
26
26
  }, z.core.$strip>;
27
+ /**
28
+ * One prior closure of a userReport task, appended to `closureHistory` when a new distinct
29
+ * report resurfaces a previously-closed report group. ONE shape for BOTH reopen paths:
30
+ * the in-place reopen of a task still sitting there `completed` (its own `completedAt`), and
31
+ * the recreate of a task the guided close-out deleted (the group's `resolvedAt` — the same
32
+ * close-out batch wrote both, so they are the same fact from two survivors). `completedAt`
33
+ * is null when neither survivor recorded the closure instant.
34
+ */
35
+ export declare const AdminTaskClosureHistoryEntrySchema: z.ZodObject<{
36
+ completedAt: z.ZodNullable<z.ZodNumber>;
37
+ reopenedAt: z.ZodNumber;
38
+ }, z.core.$strip>;
39
+ export type AdminTaskClosureHistoryEntry = z.infer<typeof AdminTaskClosureHistoryEntrySchema>;
27
40
  export declare const AdminTaskSchema: z.ZodObject<{
28
41
  id: z.ZodString;
29
42
  taskType: z.ZodEnum<{
@@ -107,6 +120,14 @@ export declare const AdminTaskDocSchema: z.ZodObject<{
107
120
  }>>;
108
121
  workProjectId: z.ZodOptional<z.ZodString>;
109
122
  hallItemId: z.ZodOptional<z.ZodString>;
123
+ reportedUserId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
124
+ reportedItemType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
125
+ reportedItemId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
126
+ parentItemId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
127
+ closureHistory: z.ZodOptional<z.ZodArray<z.ZodObject<{
128
+ completedAt: z.ZodNullable<z.ZodNumber>;
129
+ reopenedAt: z.ZodNumber;
130
+ }, z.core.$strip>>>;
110
131
  }, z.core.$strip>;
111
132
  export type AdminTaskDoc = z.infer<typeof AdminTaskDocSchema>;
112
133
  //# sourceMappingURL=report-docs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"report-docs.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/report-docs.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;;;;;;;;;EAe9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,qBAAqB;;;;;EAA8D,CAAC;AAEjG,eAAO,MAAM,qBAAqB;;;;;iBAKhC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAa1B,CAAC;AAaH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAe7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"report-docs.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/report-docs.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;;;;;;;;;EAe9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,qBAAqB;;;;;EAA8D,CAAC;AAEjG,eAAO,MAAM,qBAAqB;;;;;iBAKhC,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC;;;iBAG7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgB1B,CAAC;AAgBH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2B7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -32,6 +32,18 @@ export const CheckoutDetailsSchema = z.object({
32
32
  expiresAt: z.number(),
33
33
  workLaterUntil: z.number().nullable(),
34
34
  });
35
+ /**
36
+ * One prior closure of a userReport task, appended to `closureHistory` when a new distinct
37
+ * report resurfaces a previously-closed report group. ONE shape for BOTH reopen paths:
38
+ * the in-place reopen of a task still sitting there `completed` (its own `completedAt`), and
39
+ * the recreate of a task the guided close-out deleted (the group's `resolvedAt` — the same
40
+ * close-out batch wrote both, so they are the same fact from two survivors). `completedAt`
41
+ * is null when neither survivor recorded the closure instant.
42
+ */
43
+ export const AdminTaskClosureHistoryEntrySchema = z.object({
44
+ completedAt: z.number().nullable(),
45
+ reopenedAt: z.number(),
46
+ });
35
47
  export const AdminTaskSchema = z.object({
36
48
  id: z.string(),
37
49
  taskType: AdminTaskTypeSchema,
@@ -43,6 +55,9 @@ export const AdminTaskSchema = z.object({
43
55
  priority: z.number(),
44
56
  createdAt: z.number(),
45
57
  lastUpdatedAt: z.number(),
58
+ // Absent on a task that is not completed. A REOPEN deletes the field (FieldValue.delete()),
59
+ // never writes null — a reopened task is shape-identical to a pending one, so "not
60
+ // completed" has exactly one representation.
46
61
  completedAt: z.number().optional(),
47
62
  itemData: z.unknown().optional(),
48
63
  });
@@ -56,7 +71,10 @@ export const AdminTaskSchema = z.object({
56
71
  // thresholdLibraryReview → runSubmitForThresholdLibraryReview.ts (foundingArtisanUid)
57
72
  // stakeShareAnomaly → runWorkProjectGuildmateUserStakeShareAudit.ts (metadata)
58
73
  // adminDispatch → runStartAdminSupportThread.ts (no extras)
59
- // (userReport tasks read from activeReportGroups — no adminTasks doc is written for them.)
74
+ // userReport report-core's createAdminTaskHandler + the app's
75
+ // runOnReportCreated (report identity: reportedUserId /
76
+ // reportedItemType / reportedItemId / parentItemId; reopen:
77
+ // closureHistory)
60
78
  export const AdminTaskDocSchema = AdminTaskSchema.extend({
61
79
  id: z.string().optional(),
62
80
  violationId: z.string().optional(),
@@ -72,5 +90,17 @@ export const AdminTaskDocSchema = AdminTaskSchema.extend({
72
90
  partyKind: z.enum(['user', 'workProject']).optional(),
73
91
  workProjectId: z.string().optional(),
74
92
  hallItemId: z.string().optional(),
93
+ // userReport tasks — report identity, denormalized by report-core's task creator so admin
94
+ // task surfaces can filter/scope without re-reading the group. Null (not absent) when the
95
+ // writer had no value: an unresolved chat sender has no reportedUserId, a parentless item
96
+ // no parentItemId — the Admin SDK rejects `undefined`, so writers coalesce to null.
97
+ reportedUserId: z.string().nullable().optional(),
98
+ reportedItemType: z.string().nullable().optional(),
99
+ reportedItemId: z.string().nullable().optional(),
100
+ parentItemId: z.string().nullable().optional(),
101
+ // userReport tasks — prior closures, appended (arrayUnion) when a new distinct report
102
+ // resurfaces a closed report group. Cross-boundary: Functions writes it, the admin queue
103
+ // UI reads it.
104
+ closureHistory: z.array(AdminTaskClosureHistoryEntrySchema).optional(),
75
105
  });
76
106
  //# sourceMappingURL=report-docs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"report-docs.js","sourceRoot":"","sources":["../../src/doc-schemas/report-docs.ts"],"names":[],"mappings":"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","sourcesContent":["// Zod schemas for the report-core-owned admin-task-queue Firestore document shape as\n// stored in TTT: adminTasks/{taskId} (AdminTask<AdminTaskType>).\n//\n// The report DOC shapes (contentReports/{reportId} + activeReportGroups/{groupKey}) are\n// NO LONGER modeled here — they are owned by the Trust & Safety report spine:\n// `ProtectedReportRootV1` + `ReportPublicProjectionV1` + `ReportGroupV1` in ./safety/report.ts.\n//\n// The admin-task TYPES still align with @ttt-productions/report-core's generic shapes;\n// AdminTaskType is the TTT specialization of the generic AdminTask<TTaskType>\n// task-type parameter.\n\nimport { z } from 'zod';\n\nexport const AdminTaskTypeSchema = z.enum([\n 'adminDispatch',\n 'thresholdLibraryReview',\n 'userReport',\n 'content-appeal',\n 'stakeShareAnomaly',\n 'pledgeLedgerAnomaly',\n 'pledgePaymentRepairNeeded',\n // Payment refund/dispute admin tray tasks (post-launch handlers). A Stripe chargeback opens a\n // dispute task; a user refund request opens a refund-request task for admin resolution.\n 'pledgeDisputeOpened',\n 'pledgeRefundRequested',\n // A member's proposal to change TEXT fields on a PUBLISHED hall item — reviewed in the same\n // admin queue as library publishes (hallContentChangeRequests/{changeRequestId} is the source doc).\n 'hallContentChangeRequest',\n]);\nexport type AdminTaskType = z.infer<typeof AdminTaskTypeSchema>;\n\nexport const AdminTaskStatusSchema = z.enum(['pending', 'checkedOut', 'workLater', 'completed']);\n\nexport const CheckoutDetailsSchema = z.object({\n userId: z.string(),\n checkedOutAt: z.number(),\n expiresAt: z.number(),\n workLaterUntil: z.number().nullable(),\n});\n\nexport const AdminTaskSchema = z.object({\n id: z.string(),\n taskType: AdminTaskTypeSchema,\n taskId: z.string(),\n originalPath: z.string(),\n status: AdminTaskStatusSchema,\n checkoutDetails: CheckoutDetailsSchema.nullable(),\n summary: z.string(),\n priority: z.number(),\n createdAt: z.number(),\n lastUpdatedAt: z.number(),\n completedAt: z.number().optional(),\n itemData: z.unknown().optional(),\n});\n\n// The STORED `adminTasks/{taskId}` doc. `AdminTaskSchema` above is the READ model — report-core's\n// read hooks inject `id` from the doc id, so stored docs omit `id` (only the content-appeal writer\n// persists it). The queue is polymorphic: each task type denormalizes a few top-level fields for\n// the admin browse view. Modeled as a superset-of-optionals (NOT a discriminated union) so the\n// drift-check keeps top-level unknown-field detection. Per-type writers (functions/src):\n// content-appeal → submitContentAppeal.ts (id, violationId, userId, fileType,\n// rejectionReason, appealMessage, rejectedFilePath)\n// thresholdLibraryReview → runSubmitForThresholdLibraryReview.ts (foundingArtisanUid)\n// stakeShareAnomaly → runWorkProjectGuildmateUserStakeShareAudit.ts (metadata)\n// adminDispatch → runStartAdminSupportThread.ts (no extras)\n// (userReport tasks read from activeReportGroups no adminTasks doc is written for them.)\nexport const AdminTaskDocSchema = AdminTaskSchema.extend({\n id: z.string().optional(),\n violationId: z.string().optional(),\n userId: z.string().optional(),\n fileType: z.string().optional(),\n rejectionReason: z.string().optional(),\n appealMessage: z.string().optional(),\n rejectedFilePath: z.string().optional(),\n foundingArtisanUid: z.string().nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n // Party-generic dispatch (adminDispatch tasks) + change-request tasks: the queue card\n // says which party/content the item is about. Denormalized from the source doc.\n partyKind: z.enum(['user', 'workProject']).optional(),\n workProjectId: z.string().optional(),\n hallItemId: z.string().optional(),\n});\nexport type AdminTaskDoc = z.infer<typeof AdminTaskDocSchema>;\n"]}
1
+ {"version":3,"file":"report-docs.js","sourceRoot":"","sources":["../../src/doc-schemas/report-docs.ts"],"names":[],"mappings":"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","sourcesContent":["// Zod schemas for the report-core-owned admin-task-queue Firestore document shape as\n// stored in TTT: adminTasks/{taskId} (AdminTask<AdminTaskType>).\n//\n// The report DOC shapes (contentReports/{reportId} + activeReportGroups/{groupKey}) are\n// NO LONGER modeled here — they are owned by the Trust & Safety report spine:\n// `ProtectedReportRootV1` + `ReportPublicProjectionV1` + `ReportGroupV1` in ./safety/report.ts.\n//\n// The admin-task TYPES still align with @ttt-productions/report-core's generic shapes;\n// AdminTaskType is the TTT specialization of the generic AdminTask<TTaskType>\n// task-type parameter.\n\nimport { z } from 'zod';\n\nexport const AdminTaskTypeSchema = z.enum([\n 'adminDispatch',\n 'thresholdLibraryReview',\n 'userReport',\n 'content-appeal',\n 'stakeShareAnomaly',\n 'pledgeLedgerAnomaly',\n 'pledgePaymentRepairNeeded',\n // Payment refund/dispute admin tray tasks (post-launch handlers). A Stripe chargeback opens a\n // dispute task; a user refund request opens a refund-request task for admin resolution.\n 'pledgeDisputeOpened',\n 'pledgeRefundRequested',\n // A member's proposal to change TEXT fields on a PUBLISHED hall item — reviewed in the same\n // admin queue as library publishes (hallContentChangeRequests/{changeRequestId} is the source doc).\n 'hallContentChangeRequest',\n]);\nexport type AdminTaskType = z.infer<typeof AdminTaskTypeSchema>;\n\nexport const AdminTaskStatusSchema = z.enum(['pending', 'checkedOut', 'workLater', 'completed']);\n\nexport const CheckoutDetailsSchema = z.object({\n userId: z.string(),\n checkedOutAt: z.number(),\n expiresAt: z.number(),\n workLaterUntil: z.number().nullable(),\n});\n\n/**\n * One prior closure of a userReport task, appended to `closureHistory` when a new distinct\n * report resurfaces a previously-closed report group. ONE shape for BOTH reopen paths:\n * the in-place reopen of a task still sitting there `completed` (its own `completedAt`), and\n * the recreate of a task the guided close-out deleted (the group's `resolvedAt` — the same\n * close-out batch wrote both, so they are the same fact from two survivors). `completedAt`\n * is null when neither survivor recorded the closure instant.\n */\nexport const AdminTaskClosureHistoryEntrySchema = z.object({\n completedAt: z.number().nullable(),\n reopenedAt: z.number(),\n});\nexport type AdminTaskClosureHistoryEntry = z.infer<typeof AdminTaskClosureHistoryEntrySchema>;\n\nexport const AdminTaskSchema = z.object({\n id: z.string(),\n taskType: AdminTaskTypeSchema,\n taskId: z.string(),\n originalPath: z.string(),\n status: AdminTaskStatusSchema,\n checkoutDetails: CheckoutDetailsSchema.nullable(),\n summary: z.string(),\n priority: z.number(),\n createdAt: z.number(),\n lastUpdatedAt: z.number(),\n // Absent on a task that is not completed. A REOPEN deletes the field (FieldValue.delete()),\n // never writes null — a reopened task is shape-identical to a pending one, so \"not\n // completed\" has exactly one representation.\n completedAt: z.number().optional(),\n itemData: z.unknown().optional(),\n});\n\n// The STORED `adminTasks/{taskId}` doc. `AdminTaskSchema` above is the READ model — report-core's\n// read hooks inject `id` from the doc id, so stored docs omit `id` (only the content-appeal writer\n// persists it). The queue is polymorphic: each task type denormalizes a few top-level fields for\n// the admin browse view. Modeled as a superset-of-optionals (NOT a discriminated union) so the\n// drift-check keeps top-level unknown-field detection. Per-type writers (functions/src):\n// content-appeal → submitContentAppeal.ts (id, violationId, userId, fileType,\n// rejectionReason, appealMessage, rejectedFilePath)\n// thresholdLibraryReview → runSubmitForThresholdLibraryReview.ts (foundingArtisanUid)\n// stakeShareAnomaly → runWorkProjectGuildmateUserStakeShareAudit.ts (metadata)\n// adminDispatch → runStartAdminSupportThread.ts (no extras)\n// userReport report-core's createAdminTaskHandler + the app's\n// runOnReportCreated (report identity: reportedUserId /\n// reportedItemType / reportedItemId / parentItemId; reopen:\n// closureHistory)\nexport const AdminTaskDocSchema = AdminTaskSchema.extend({\n id: z.string().optional(),\n violationId: z.string().optional(),\n userId: z.string().optional(),\n fileType: z.string().optional(),\n rejectionReason: z.string().optional(),\n appealMessage: z.string().optional(),\n rejectedFilePath: z.string().optional(),\n foundingArtisanUid: z.string().nullable().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n // Party-generic dispatch (adminDispatch tasks) + change-request tasks: the queue card\n // says which party/content the item is about. Denormalized from the source doc.\n partyKind: z.enum(['user', 'workProject']).optional(),\n workProjectId: z.string().optional(),\n hallItemId: z.string().optional(),\n // userReport tasks — report identity, denormalized by report-core's task creator so admin\n // task surfaces can filter/scope without re-reading the group. Null (not absent) when the\n // writer had no value: an unresolved chat sender has no reportedUserId, a parentless item\n // no parentItemId — the Admin SDK rejects `undefined`, so writers coalesce to null.\n reportedUserId: z.string().nullable().optional(),\n reportedItemType: z.string().nullable().optional(),\n reportedItemId: z.string().nullable().optional(),\n parentItemId: z.string().nullable().optional(),\n // userReport tasks — prior closures, appended (arrayUnion) when a new distinct report\n // resurfaces a closed report group. Cross-boundary: Functions writes it, the admin queue\n // UI reads it.\n closureHistory: z.array(AdminTaskClosureHistoryEntrySchema).optional(),\n});\nexport type AdminTaskDoc = z.infer<typeof AdminTaskDocSchema>;\n"]}
@@ -107,8 +107,8 @@ export declare const CommissionProposalSubmittedEventSchema: z.ZodObject<{
107
107
  commissionProposalId: z.ZodString;
108
108
  }, z.core.$strict>;
109
109
  }, z.core.$strict>;
110
- export declare const CommissionDeletedEventSchema: z.ZodObject<{
111
- type: z.ZodLiteral<"commission.deleted">;
110
+ export declare const CommissionClosedEventSchema: z.ZodObject<{
111
+ type: z.ZodLiteral<"commission.closed">;
112
112
  ids: z.ZodObject<{
113
113
  commissionListingId: z.ZodString;
114
114
  workProjectId: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"domain-events-work.d.ts","sourceRoot":"","sources":["../../src/media/domain-events-work.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,6BAA6B;;;;;;kBAU/B,CAAC;AAEZ,eAAO,MAAM,6BAA6B;;;;;kBAK/B,CAAC;AAEZ,eAAO,MAAM,+BAA+B;;;;;;kBAUjC,CAAC;AAEZ,eAAO,MAAM,wCAAwC;;;;;kBAS1C,CAAC;AAEZ,eAAO,MAAM,0BAA0B;;;;;;;;kBAY5B,CAAC;AAEZ,eAAO,MAAM,8BAA8B;;;;;;;kBAWhC,CAAC;AAEZ,eAAO,MAAM,8BAA8B;;;;;;;kBAWhC,CAAC;AAEZ,eAAO,MAAM,+BAA+B;;;;;;kBAUjC,CAAC;AAEZ,eAAO,MAAM,gCAAgC;;;;;;;kBAWlC,CAAC;AAEZ,eAAO,MAAM,iCAAiC;;;;;;;;kBAYnC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;;kBAYtC,CAAC;AAEZ,eAAO,MAAM,yBAAyB;;;;;;kBAU3B,CAAC;AAEZ,eAAO,MAAM,4BAA4B;;;;;;;kBAW9B,CAAC;AAEZ,eAAO,MAAM,sCAAsC;;;;;;;;kBAYxC,CAAC;AAEZ,eAAO,MAAM,4BAA4B;;;;;;kBAU9B,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;;kBAWpC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;kBAWtC,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;;;;;;kBAWpC,CAAC;AAIZ,eAAO,MAAM,gCAAgC;;;;;kBASlC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;;;;;;kBAYtC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;kBAStC,CAAC"}
1
+ {"version":3,"file":"domain-events-work.d.ts","sourceRoot":"","sources":["../../src/media/domain-events-work.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,6BAA6B;;;;;;kBAU/B,CAAC;AAEZ,eAAO,MAAM,6BAA6B;;;;;kBAK/B,CAAC;AAEZ,eAAO,MAAM,+BAA+B;;;;;;kBAUjC,CAAC;AAEZ,eAAO,MAAM,wCAAwC;;;;;kBAS1C,CAAC;AAEZ,eAAO,MAAM,0BAA0B;;;;;;;;kBAY5B,CAAC;AAEZ,eAAO,MAAM,8BAA8B;;;;;;;kBAWhC,CAAC;AAEZ,eAAO,MAAM,8BAA8B;;;;;;;kBAWhC,CAAC;AAEZ,eAAO,MAAM,+BAA+B;;;;;;kBAUjC,CAAC;AAEZ,eAAO,MAAM,gCAAgC;;;;;;;kBAWlC,CAAC;AAEZ,eAAO,MAAM,iCAAiC;;;;;;;;kBAYnC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;;kBAYtC,CAAC;AAEZ,eAAO,MAAM,yBAAyB;;;;;;kBAU3B,CAAC;AAEZ,eAAO,MAAM,4BAA4B;;;;;;;kBAW9B,CAAC;AAEZ,eAAO,MAAM,sCAAsC;;;;;;;;kBAYxC,CAAC;AAKZ,eAAO,MAAM,2BAA2B;;;;;;kBAU7B,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;;kBAWpC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;kBAWtC,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;;;;;;kBAWpC,CAAC;AAIZ,eAAO,MAAM,gCAAgC;;;;;kBASlC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;;;;;;kBAYtC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;kBAStC,CAAC"}