@ttt-productions/ttt-core 0.79.37 → 0.79.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/business-content.d.ts +8 -0
- package/dist/constants/business-content.d.ts.map +1 -1
- package/dist/constants/business-content.js.map +1 -1
- package/dist/doc-schemas/backend-state.d.ts +2 -0
- package/dist/doc-schemas/backend-state.d.ts.map +1 -1
- package/dist/doc-schemas/backend-state.js +7 -1
- package/dist/doc-schemas/backend-state.js.map +1 -1
- package/dist/doc-schemas/chat-sync.d.ts +2 -2
- package/dist/doc-schemas/commissions.d.ts +5 -5
- package/dist/doc-schemas/content.d.ts +55 -9
- package/dist/doc-schemas/content.d.ts.map +1 -1
- package/dist/doc-schemas/content.js +29 -0
- package/dist/doc-schemas/content.js.map +1 -1
- package/dist/doc-schemas/media-activation-jobs.d.ts +3 -3
- package/dist/doc-schemas/media-assets.d.ts +12 -12
- package/dist/doc-schemas/messaging.d.ts +4 -4
- package/dist/doc-schemas/moderation.d.ts +21 -8
- package/dist/doc-schemas/moderation.d.ts.map +1 -1
- package/dist/doc-schemas/moderation.js +7 -0
- package/dist/doc-schemas/moderation.js.map +1 -1
- package/dist/doc-schemas/ncii/cases.d.ts +30 -3
- package/dist/doc-schemas/ncii/cases.d.ts.map +1 -1
- package/dist/doc-schemas/ncii/cases.js +20 -0
- package/dist/doc-schemas/ncii/cases.js.map +1 -1
- package/dist/doc-schemas/ncii/removal.d.ts +2 -2
- package/dist/doc-schemas/ncii/requests.d.ts +8 -8
- package/dist/doc-schemas/ncii/requests.js +1 -1
- package/dist/doc-schemas/ncii/requests.js.map +1 -1
- package/dist/doc-schemas/notification-archive-all-jobs.d.ts +3 -3
- package/dist/doc-schemas/notification-ledger.d.ts +9 -1
- package/dist/doc-schemas/notification-ledger.d.ts.map +1 -1
- package/dist/doc-schemas/notification-ledger.js +26 -1
- package/dist/doc-schemas/notification-ledger.js.map +1 -1
- package/dist/doc-schemas/payments.d.ts +3 -3
- package/dist/doc-schemas/registry.d.ts +170 -94
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/doc-schemas/registry.js +2 -4
- package/dist/doc-schemas/registry.js.map +1 -1
- package/dist/doc-schemas/report-docs.d.ts +8 -7
- package/dist/doc-schemas/report-docs.d.ts.map +1 -1
- package/dist/doc-schemas/report-docs.js +3 -0
- package/dist/doc-schemas/report-docs.js.map +1 -1
- package/dist/doc-schemas/safety/case.d.ts +2 -2
- package/dist/doc-schemas/safety/evidence.d.ts +12 -12
- package/dist/doc-schemas/safety/foundation.d.ts +11 -11
- package/dist/doc-schemas/safety/holds.d.ts +3 -3
- package/dist/doc-schemas/safety/report.d.ts +4 -17
- package/dist/doc-schemas/safety/report.d.ts.map +1 -1
- package/dist/doc-schemas/safety/report.js +6 -8
- package/dist/doc-schemas/safety/report.js.map +1 -1
- package/dist/doc-schemas/safety/sagas.d.ts +1 -0
- package/dist/doc-schemas/safety/sagas.d.ts.map +1 -1
- package/dist/doc-schemas/safety/sagas.js +3 -0
- package/dist/doc-schemas/safety/sagas.js.map +1 -1
- package/dist/doc-schemas/social.d.ts +17 -17
- package/dist/doc-schemas/square-announcement-jobs.d.ts +15 -15
- package/dist/doc-schemas/user.d.ts +8 -8
- package/dist/doc-schemas/user.d.ts.map +1 -1
- package/dist/doc-schemas/user.js +3 -1
- package/dist/doc-schemas/user.js.map +1 -1
- package/dist/doc-schemas/work-project.d.ts +1 -1
- package/dist/media/atoms.d.ts +4 -4
- package/dist/media/domain-events-user.d.ts +4 -4
- package/dist/media/domain-events.d.ts +4 -4
- package/dist/media/pending-media.d.ts +44 -44
- package/dist/media/target-info.d.ts +5 -5
- package/dist/paths/path-builders.d.ts +2 -0
- package/dist/paths/path-builders.d.ts.map +1 -1
- package/dist/paths/path-builders.js +5 -1
- package/dist/paths/path-builders.js.map +1 -1
- package/dist/schemas/admin.d.ts +51 -12
- package/dist/schemas/admin.d.ts.map +1 -1
- package/dist/schemas/admin.js +27 -11
- package/dist/schemas/admin.js.map +1 -1
- package/dist/schemas/atoms.d.ts +2 -2
- package/dist/schemas/commissions.d.ts +1 -1
- package/dist/schemas/hall-library.d.ts +1 -1
- package/dist/schemas/notification.d.ts +5 -5
- package/dist/schemas/social.d.ts +14 -14
- package/dist/schemas/work-project-management.d.ts +4 -4
- package/dist/upload-variables/square-streetz-post-variables.d.ts +2 -2
- package/package.json +1 -1
|
@@ -50,6 +50,14 @@ export type ModerationClearableSurface = keyof typeof MODERATION_CLEARABLE_TEXT_
|
|
|
50
50
|
* compile error until its label and cap exist.
|
|
51
51
|
*/
|
|
52
52
|
export type ClearableTextFieldName = (typeof MODERATION_CLEARABLE_TEXT_FIELDS)[ModerationClearableSurface][number];
|
|
53
|
+
/**
|
|
54
|
+
* The bounded computed-field portion of a moderation text-clear write. Writers
|
|
55
|
+
* may only set one of the canonical clearable field names, never an arbitrary
|
|
56
|
+
* document key. Sentinel-bearing moderation metadata stays runtime-specific.
|
|
57
|
+
*/
|
|
58
|
+
export type ModerationClearTextFieldPatch = {
|
|
59
|
+
[Field in ClearableTextFieldName]?: string;
|
|
60
|
+
};
|
|
53
61
|
/**
|
|
54
62
|
* The DISTINCT clearable text-field NAMES across the whole hall content family (tale/tune/
|
|
55
63
|
* television detail → title/description; chapter → title/content; track/episode →
|
|
@@ -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;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"}
|
|
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;;;;GAIG;AACH,MAAM,MAAM,6BAA6B,GAAG;KACzC,KAAK,IAAI,sBAAsB,CAAC,CAAC,EAAE,MAAM;CAC3C,CAAC;AAEF;;;;;;;;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"}
|
|
@@ -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/**\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"]}
|
|
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 bounded computed-field portion of a moderation text-clear write. Writers\n * may only set one of the canonical clearable field names, never an arbitrary\n * document key. Sentinel-bearing moderation metadata stays runtime-specific.\n */\nexport type ModerationClearTextFieldPatch = {\n [Field in ClearableTextFieldName]?: string;\n};\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"]}
|
|
@@ -19,6 +19,8 @@ export declare const OperatorStepUpSchema: z.ZodObject<{
|
|
|
19
19
|
createdAt: z.ZodNumber;
|
|
20
20
|
updatedAt: z.ZodNumber;
|
|
21
21
|
confirmedAt: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
failedAttempts: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
lockedUntil: z.ZodOptional<z.ZodNumber>;
|
|
22
24
|
}, z.core.$strip>;
|
|
23
25
|
export type OperatorStepUp = z.infer<typeof OperatorStepUpSchema>;
|
|
24
26
|
export declare const SafetyReconcilerCursorSchema: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-state.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/backend-state.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,2BAA2B;;;iBAGtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAOhF,eAAO,MAAM,iCAAiC;;;iBAG5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"backend-state.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/backend-state.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,2BAA2B;;;iBAGtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAOhF,eAAO,MAAM,iCAAiC;;;iBAG5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAS5F,eAAO,MAAM,oBAAoB;;;;;;;;;;;;iBAa/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE,eAAO,MAAM,4BAA4B;;;iBAIvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AASlF,eAAO,MAAM,gBAAgB;;;;;iBAS3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAU1D,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;iBAc7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAS9F,eAAO,MAAM,kCAAkC;;;;;;;;;;;;iBAgB7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAQ9F,eAAO,MAAM,mCAAmC;;;;;;;;iBAU9C,CAAC;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC"}
|
|
@@ -27,7 +27,9 @@ export const PublicUsersReconcilerCursorSchema = z.object({
|
|
|
27
27
|
// plus the currently open grant window. The secret is returned to the client EXACTLY ONCE by
|
|
28
28
|
// enrollOperatorStepUp and is never readable through Firestore afterwards; `status` goes
|
|
29
29
|
// 'pending' → 'active' on confirm, and each successful verify pushes `grantExpiresAt` out by
|
|
30
|
-
// the step-up window.
|
|
30
|
+
// the step-up window. `failedAttempts` and `lockedUntil` make the server-side TOTP brute-force
|
|
31
|
+
// lockout durable; omitted fields are the compatible no-lockout state for rows written before
|
|
32
|
+
// that protection shipped. (functions/src/safety/operatorStepUp.ts)
|
|
31
33
|
export const OperatorStepUpSchema = z.object({
|
|
32
34
|
secret: z.string(),
|
|
33
35
|
status: z.enum(['pending', 'active']),
|
|
@@ -37,6 +39,10 @@ export const OperatorStepUpSchema = z.object({
|
|
|
37
39
|
updatedAt: z.number(),
|
|
38
40
|
/** Set when enrollment is confirmed (status flips to 'active'). */
|
|
39
41
|
confirmedAt: z.number().optional(),
|
|
42
|
+
/** Consecutive failed TOTP checks since the most recent success or lockout. */
|
|
43
|
+
failedAttempts: z.number().int().nonnegative().optional(),
|
|
44
|
+
/** Epoch ms until which TOTP verification is refused; absent or 0 means not locked. */
|
|
45
|
+
lockedUntil: z.number().nonnegative().optional(),
|
|
40
46
|
});
|
|
41
47
|
// safetyReconcilerCursors/{cursorKey} — one persisted pagination cursor per reconciler
|
|
42
48
|
// needs-work backstop sweep (quarantine enqueue, NCMEC enqueue). The sweep pages a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend-state.js","sourceRoot":"","sources":["../../src/doc-schemas/backend-state.ts"],"names":[],"mappings":"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","sourcesContent":["// Backend-only state document SCHEMAS — Cloud-Functions-owned bookkeeping docs that no\n// client ever reads or writes (firestore.rules denies client access to every path below).\n// They are registered here for the same reason every other stored shape is: ARCH-104 gives\n// the path ONE owner, and COLLECTION_SCHEMAS is the inventory the schema-doc generator and\n// the drift-check read. Types are inferred via z.infer.\n\nimport { z } from 'zod';\nimport {\n ChildSafetyNcmecCompletionChannelSchema,\n ChildSafetyNcmecCompletionProofTypeSchema,\n} from './safety/case.js';\n\n// _systemData/hallMediaReaperCursor — the scheduled Hall-media orphan reaper's scan cursor.\n// `createdAtCursor` is the highest mediaAssets `createdAt` the reaper has POSITIVELY cleared\n// (candidate resolved referenced / reaped / already-deleted), so each pass resumes past\n// permanently-live Hall assets instead of re-reading the same oldest page forever.\n// (functions/src/media/reapOrphanedHallMediaCopies.ts)\nexport const HallMediaReaperCursorSchema = z.object({\n createdAtCursor: z.number(),\n updatedAt: z.number(),\n});\nexport type HallMediaReaperCursor = z.infer<typeof HallMediaReaperCursorSchema>;\n\n// _systemData/publicUsersReconcilerCursor — the scheduled publicUsers reconciler's sweep cursor.\n// `profileIdCursor` is the last `userProfiles` document id the sweep has POSITIVELY cleared, so\n// each pass resumes after it instead of re-reading the same oldest page forever. An EMPTY STRING\n// means start from the beginning — both the first-ever pass and the wrap after the sweep exhausts\n// the collection. (functions/src/users/reconcilePublicUsers.ts)\nexport const PublicUsersReconcilerCursorSchema = z.object({\n profileIdCursor: z.string(),\n updatedAt: z.number(),\n});\nexport type PublicUsersReconcilerCursor = z.infer<typeof PublicUsersReconcilerCursorSchema>;\n\n// operatorStepUp/{uid} — [H-08] per-operator TOTP step-up state: the authenticator secret\n// plus the currently open grant window. The secret is returned to the client EXACTLY ONCE by\n// enrollOperatorStepUp and is never readable through Firestore afterwards; `status` goes\n// 'pending' → 'active' on confirm, and each successful verify pushes `grantExpiresAt` out by\n// the step-up window. (functions/src/safety/operatorStepUp.ts)\nexport const OperatorStepUpSchema = z.object({\n secret: z.string(),\n status: z.enum(['pending', 'active']),\n /** Absent until the first successful verify; a grant is live while now < grantExpiresAt. */\n grantExpiresAt: z.number().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n /** Set when enrollment is confirmed (status flips to 'active'). */\n confirmedAt: z.number().optional(),\n});\nexport type OperatorStepUp = z.infer<typeof OperatorStepUpSchema>;\n\n// safetyReconcilerCursors/{cursorKey} — one persisted pagination cursor per reconciler\n// needs-work backstop sweep (quarantine enqueue, NCMEC enqueue). The sweep pages a\n// needs-work-filtered query from `afterValue` and WRAPS to the start when exhausted, so\n// coverage does not stall on the oldest rows. (functions/src/safety/reconcilerCursor.ts)\nexport const SafetyReconcilerCursorSchema = z.object({\n /** `orderBy` value of the last row examined last pass (exclusive lower bound). Absent ⇒ 0. */\n afterValue: z.number().optional(),\n updatedAt: z.number(),\n});\nexport type SafetyReconcilerCursor = z.infer<typeof SafetyReconcilerCursorSchema>;\n\n// sweepState/{sweepName} — durable cadence + cursor state for one scheduled user sweep. One doc\n// per sweep name; the fields a given sweep uses are the ones it declares, so every field except\n// `updatedAt` is optional. `orphanRegistrationCleanup` carries all three (the ~daily privateData\n// reaper's last completed pass + its rolling page cursor, and the ~weekly `listUsers()` scan);\n// `reconcileAccountStatus` carries only `fullScanLastRunAt`. The stamps are wall-clock so a\n// container recycle cannot reset the cadence.\n// (functions/src/users/orphanRegistrationCleanup.ts, functions/src/users/reconcileAccountStatus.ts)\nexport const SweepStateSchema = z.object({\n /** Wall-clock ms the last COMPLETED privateData-reaper pass finished (absent = never). */\n reaperLastRunAt: z.number().optional(),\n /** Full document path of the last `privateData` doc the reaper examined. Empty/absent means no\n * pass is in flight; a non-empty value means one is mid-scan and must continue. */\n reaperCursorPath: z.string().optional(),\n /** Wall-clock ms the last full `listUsers()` scan ran (absent = never). */\n fullScanLastRunAt: z.number().optional(),\n updatedAt: z.number(),\n});\nexport type SweepState = z.infer<typeof SweepStateSchema>;\n\n// childSafetyCases/{caseId}/ncmecSubmissions/{submissionId}/ncmecCompletionProof/record —\n// [H-05] the IMMUTABLE record of a verified manual-portal completion. Written create-if-absent in\n// the SAME transaction as the submission's `completed` transition, so a submission can never reach\n// `completed` without a bound proof record; a re-completion keeps the original. The submission's\n// `completionProofRef` stores this doc's path, never an operator free-text string.\n// [Q13/H-06] `portalReceiptArtifactId` binds the proof to a verified NcmecPortalReceiptArtifactV1\n// on the same (caseId, submissionId) — an arbitrary operator string is never accepted.\n// (functions/src/safety/ncmecReporting.ts)\nexport const NcmecCompletionProofRecordV1Schema = z.object({\n caseId: z.string(),\n submissionId: z.string(),\n channel: ChildSafetyNcmecCompletionChannelSchema,\n proofType: ChildSafetyNcmecCompletionProofTypeSchema,\n /** Id of the verified portal-receipt artifact this completion is bound to. */\n portalReceiptArtifactId: z.string(),\n /** Optional operator free-text note about the confirmation. */\n proofText: z.string().optional(),\n /** The NCMEC-assigned report id — REQUIRED. The number IS the proof; there is no\n * \"filed, number pending\" grace. */\n ncmecReportId: z.string(),\n recordedByUid: z.string(),\n recordedAt: z.number(),\n});\nexport type NcmecCompletionProofRecordV1 = z.infer<typeof NcmecCompletionProofRecordV1Schema>;\n\n// childSafetyCases/{caseId}/portalReceiptArtifacts/{artifactId} — [Q13/H-06] the immutable\n// record of a PDF/screenshot of the completed NCMEC CyberTipline submission, stored in the\n// restricted evidence vault. `markNcmecPortalComplete` accepts only the id of a verified\n// artifact bound to the SAME (caseId, submissionId); an arbitrary operator string is never\n// proof. Written create-only, never overwritten, and carries the server-verified storage facts\n// (generation + sha256) so a later transactional verification can confirm the same object\n// still exists unchanged. (functions/src/safety/ncmecOperatorCommands.ts)\nexport const NcmecPortalReceiptArtifactV1Schema = z.object({\n schemaVersion: z.literal(1),\n caseId: z.string(),\n submissionId: z.string(),\n /** Key of the object in the restricted evidence vault bucket. */\n evidenceVaultKey: z.string(),\n /** GCS object generation at capture time (immutable identity peg). */\n objectGeneration: z.string(),\n /** SHA-256 hex digest of the object bytes at capture time. */\n sha256: z.string(),\n contentType: z.string(),\n sizeBytes: z.number(),\n capturedAt: z.number(),\n registeredByUid: z.string(),\n /** Optional operator free-text describing what the artifact is. */\n description: z.string().optional(),\n});\nexport type NcmecPortalReceiptArtifactV1 = z.infer<typeof NcmecPortalReceiptArtifactV1Schema>;\n\n// childSafetyCases/{caseId}/ncmecPortalCorrections/{correctionId} — the immutable record that\n// the operator filed a CORRECTION on the NCMEC manual portal. There is no in-app correction\n// submission pipeline; this records the portal filing. Its EXISTENCE is the gate on the\n// corrected-no-apparent-violation disposition, so it is never a bare-discretion close. Each\n// correction is a fresh id — a later correction is an additional record, never a mutation of\n// the prior one. (functions/src/safety/recordNcmecPortalCorrection.ts)\nexport const NcmecPortalCorrectionRecordV1Schema = z.object({\n schemaVersion: z.literal(1),\n caseId: z.string(),\n /** The portal-assigned NCMEC report id being corrected. */\n ncmecReportId: z.string(),\n /** When the operator filed the correction on the portal (operator-supplied). */\n correctionFiledAt: z.number(),\n reason: z.string(),\n recordedByUid: z.string(),\n recordedAt: z.number(),\n});\nexport type NcmecPortalCorrectionRecordV1 = z.infer<typeof NcmecPortalCorrectionRecordV1Schema>;\n"]}
|
|
1
|
+
{"version":3,"file":"backend-state.js","sourceRoot":"","sources":["../../src/doc-schemas/backend-state.ts"],"names":[],"mappings":"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","sourcesContent":["// Backend-only state document SCHEMAS — Cloud-Functions-owned bookkeeping docs that no\n// client ever reads or writes (firestore.rules denies client access to every path below).\n// They are registered here for the same reason every other stored shape is: ARCH-104 gives\n// the path ONE owner, and COLLECTION_SCHEMAS is the inventory the schema-doc generator and\n// the drift-check read. Types are inferred via z.infer.\n\nimport { z } from 'zod';\nimport {\n ChildSafetyNcmecCompletionChannelSchema,\n ChildSafetyNcmecCompletionProofTypeSchema,\n} from './safety/case.js';\n\n// _systemData/hallMediaReaperCursor — the scheduled Hall-media orphan reaper's scan cursor.\n// `createdAtCursor` is the highest mediaAssets `createdAt` the reaper has POSITIVELY cleared\n// (candidate resolved referenced / reaped / already-deleted), so each pass resumes past\n// permanently-live Hall assets instead of re-reading the same oldest page forever.\n// (functions/src/media/reapOrphanedHallMediaCopies.ts)\nexport const HallMediaReaperCursorSchema = z.object({\n createdAtCursor: z.number(),\n updatedAt: z.number(),\n});\nexport type HallMediaReaperCursor = z.infer<typeof HallMediaReaperCursorSchema>;\n\n// _systemData/publicUsersReconcilerCursor — the scheduled publicUsers reconciler's sweep cursor.\n// `profileIdCursor` is the last `userProfiles` document id the sweep has POSITIVELY cleared, so\n// each pass resumes after it instead of re-reading the same oldest page forever. An EMPTY STRING\n// means start from the beginning — both the first-ever pass and the wrap after the sweep exhausts\n// the collection. (functions/src/users/reconcilePublicUsers.ts)\nexport const PublicUsersReconcilerCursorSchema = z.object({\n profileIdCursor: z.string(),\n updatedAt: z.number(),\n});\nexport type PublicUsersReconcilerCursor = z.infer<typeof PublicUsersReconcilerCursorSchema>;\n\n// operatorStepUp/{uid} — [H-08] per-operator TOTP step-up state: the authenticator secret\n// plus the currently open grant window. The secret is returned to the client EXACTLY ONCE by\n// enrollOperatorStepUp and is never readable through Firestore afterwards; `status` goes\n// 'pending' → 'active' on confirm, and each successful verify pushes `grantExpiresAt` out by\n// the step-up window. `failedAttempts` and `lockedUntil` make the server-side TOTP brute-force\n// lockout durable; omitted fields are the compatible no-lockout state for rows written before\n// that protection shipped. (functions/src/safety/operatorStepUp.ts)\nexport const OperatorStepUpSchema = z.object({\n secret: z.string(),\n status: z.enum(['pending', 'active']),\n /** Absent until the first successful verify; a grant is live while now < grantExpiresAt. */\n grantExpiresAt: z.number().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n /** Set when enrollment is confirmed (status flips to 'active'). */\n confirmedAt: z.number().optional(),\n /** Consecutive failed TOTP checks since the most recent success or lockout. */\n failedAttempts: z.number().int().nonnegative().optional(),\n /** Epoch ms until which TOTP verification is refused; absent or 0 means not locked. */\n lockedUntil: z.number().nonnegative().optional(),\n});\nexport type OperatorStepUp = z.infer<typeof OperatorStepUpSchema>;\n\n// safetyReconcilerCursors/{cursorKey} — one persisted pagination cursor per reconciler\n// needs-work backstop sweep (quarantine enqueue, NCMEC enqueue). The sweep pages a\n// needs-work-filtered query from `afterValue` and WRAPS to the start when exhausted, so\n// coverage does not stall on the oldest rows. (functions/src/safety/reconcilerCursor.ts)\nexport const SafetyReconcilerCursorSchema = z.object({\n /** `orderBy` value of the last row examined last pass (exclusive lower bound). Absent ⇒ 0. */\n afterValue: z.number().optional(),\n updatedAt: z.number(),\n});\nexport type SafetyReconcilerCursor = z.infer<typeof SafetyReconcilerCursorSchema>;\n\n// sweepState/{sweepName} — durable cadence + cursor state for one scheduled user sweep. One doc\n// per sweep name; the fields a given sweep uses are the ones it declares, so every field except\n// `updatedAt` is optional. `orphanRegistrationCleanup` carries all three (the ~daily privateData\n// reaper's last completed pass + its rolling page cursor, and the ~weekly `listUsers()` scan);\n// `reconcileAccountStatus` carries only `fullScanLastRunAt`. The stamps are wall-clock so a\n// container recycle cannot reset the cadence.\n// (functions/src/users/orphanRegistrationCleanup.ts, functions/src/users/reconcileAccountStatus.ts)\nexport const SweepStateSchema = z.object({\n /** Wall-clock ms the last COMPLETED privateData-reaper pass finished (absent = never). */\n reaperLastRunAt: z.number().optional(),\n /** Full document path of the last `privateData` doc the reaper examined. Empty/absent means no\n * pass is in flight; a non-empty value means one is mid-scan and must continue. */\n reaperCursorPath: z.string().optional(),\n /** Wall-clock ms the last full `listUsers()` scan ran (absent = never). */\n fullScanLastRunAt: z.number().optional(),\n updatedAt: z.number(),\n});\nexport type SweepState = z.infer<typeof SweepStateSchema>;\n\n// childSafetyCases/{caseId}/ncmecSubmissions/{submissionId}/ncmecCompletionProof/record —\n// [H-05] the IMMUTABLE record of a verified manual-portal completion. Written create-if-absent in\n// the SAME transaction as the submission's `completed` transition, so a submission can never reach\n// `completed` without a bound proof record; a re-completion keeps the original. The submission's\n// `completionProofRef` stores this doc's path, never an operator free-text string.\n// [Q13/H-06] `portalReceiptArtifactId` binds the proof to a verified NcmecPortalReceiptArtifactV1\n// on the same (caseId, submissionId) — an arbitrary operator string is never accepted.\n// (functions/src/safety/ncmecReporting.ts)\nexport const NcmecCompletionProofRecordV1Schema = z.object({\n caseId: z.string(),\n submissionId: z.string(),\n channel: ChildSafetyNcmecCompletionChannelSchema,\n proofType: ChildSafetyNcmecCompletionProofTypeSchema,\n /** Id of the verified portal-receipt artifact this completion is bound to. */\n portalReceiptArtifactId: z.string(),\n /** Optional operator free-text note about the confirmation. */\n proofText: z.string().optional(),\n /** The NCMEC-assigned report id — REQUIRED. The number IS the proof; there is no\n * \"filed, number pending\" grace. */\n ncmecReportId: z.string(),\n recordedByUid: z.string(),\n recordedAt: z.number(),\n});\nexport type NcmecCompletionProofRecordV1 = z.infer<typeof NcmecCompletionProofRecordV1Schema>;\n\n// childSafetyCases/{caseId}/portalReceiptArtifacts/{artifactId} — [Q13/H-06] the immutable\n// record of a PDF/screenshot of the completed NCMEC CyberTipline submission, stored in the\n// restricted evidence vault. `markNcmecPortalComplete` accepts only the id of a verified\n// artifact bound to the SAME (caseId, submissionId); an arbitrary operator string is never\n// proof. Written create-only, never overwritten, and carries the server-verified storage facts\n// (generation + sha256) so a later transactional verification can confirm the same object\n// still exists unchanged. (functions/src/safety/ncmecOperatorCommands.ts)\nexport const NcmecPortalReceiptArtifactV1Schema = z.object({\n schemaVersion: z.literal(1),\n caseId: z.string(),\n submissionId: z.string(),\n /** Key of the object in the restricted evidence vault bucket. */\n evidenceVaultKey: z.string(),\n /** GCS object generation at capture time (immutable identity peg). */\n objectGeneration: z.string(),\n /** SHA-256 hex digest of the object bytes at capture time. */\n sha256: z.string(),\n contentType: z.string(),\n sizeBytes: z.number(),\n capturedAt: z.number(),\n registeredByUid: z.string(),\n /** Optional operator free-text describing what the artifact is. */\n description: z.string().optional(),\n});\nexport type NcmecPortalReceiptArtifactV1 = z.infer<typeof NcmecPortalReceiptArtifactV1Schema>;\n\n// childSafetyCases/{caseId}/ncmecPortalCorrections/{correctionId} — the immutable record that\n// the operator filed a CORRECTION on the NCMEC manual portal. There is no in-app correction\n// submission pipeline; this records the portal filing. Its EXISTENCE is the gate on the\n// corrected-no-apparent-violation disposition, so it is never a bare-discretion close. Each\n// correction is a fresh id — a later correction is an additional record, never a mutation of\n// the prior one. (functions/src/safety/recordNcmecPortalCorrection.ts)\nexport const NcmecPortalCorrectionRecordV1Schema = z.object({\n schemaVersion: z.literal(1),\n caseId: z.string(),\n /** The portal-assigned NCMEC report id being corrected. */\n ncmecReportId: z.string(),\n /** When the operator filed the correction on the portal (operator-supplied). */\n correctionFiledAt: z.number(),\n reason: z.string(),\n recordedByUid: z.string(),\n recordedAt: z.number(),\n});\nexport type NcmecPortalCorrectionRecordV1 = z.infer<typeof NcmecPortalCorrectionRecordV1Schema>;\n"]}
|
|
@@ -91,8 +91,8 @@ export declare const ChatSyncFanoutJobSchema: z.ZodObject<{
|
|
|
91
91
|
revision: z.ZodNumber;
|
|
92
92
|
status: z.ZodEnum<{
|
|
93
93
|
pending: "pending";
|
|
94
|
-
deadLetter: "deadLetter";
|
|
95
94
|
complete: "complete";
|
|
95
|
+
deadLetter: "deadLetter";
|
|
96
96
|
}>;
|
|
97
97
|
attemptCount: z.ZodNumber;
|
|
98
98
|
nextAttemptAt: z.ZodNumber;
|
|
@@ -148,9 +148,9 @@ export declare const ChatAdminActionCommandSchema: z.ZodObject<{
|
|
|
148
148
|
expectedMessageRevision: z.ZodNumber;
|
|
149
149
|
payloadHash: z.ZodString;
|
|
150
150
|
state: z.ZodEnum<{
|
|
151
|
+
failed: "failed";
|
|
151
152
|
applied: "applied";
|
|
152
153
|
deadLetter: "deadLetter";
|
|
153
|
-
failed: "failed";
|
|
154
154
|
queued: "queued";
|
|
155
155
|
delivering: "delivering";
|
|
156
156
|
safetyRepair: "safetyRepair";
|
|
@@ -4,8 +4,8 @@ export declare const CommissionAttachmentSchema: z.ZodObject<{
|
|
|
4
4
|
name: z.ZodString;
|
|
5
5
|
mediaAssetId: z.ZodString;
|
|
6
6
|
type: z.ZodEnum<{
|
|
7
|
-
video: "video";
|
|
8
7
|
image: "image";
|
|
8
|
+
video: "video";
|
|
9
9
|
audio: "audio";
|
|
10
10
|
}>;
|
|
11
11
|
size: z.ZodNumber;
|
|
@@ -20,8 +20,8 @@ export declare const FullCommissionListingSchema: z.ZodObject<{
|
|
|
20
20
|
name: z.ZodString;
|
|
21
21
|
mediaAssetId: z.ZodString;
|
|
22
22
|
type: z.ZodEnum<{
|
|
23
|
-
video: "video";
|
|
24
23
|
image: "image";
|
|
24
|
+
video: "video";
|
|
25
25
|
audio: "audio";
|
|
26
26
|
}>;
|
|
27
27
|
size: z.ZodNumber;
|
|
@@ -59,10 +59,10 @@ export declare const CommissionProposalSchema: z.ZodObject<{
|
|
|
59
59
|
}, z.core.$strip>;
|
|
60
60
|
createdOn: z.ZodNumber;
|
|
61
61
|
status: z.ZodEnum<{
|
|
62
|
+
rejected: "rejected";
|
|
62
63
|
accepted: "accepted";
|
|
63
64
|
open: "open";
|
|
64
65
|
invited: "invited";
|
|
65
|
-
rejected: "rejected";
|
|
66
66
|
}>;
|
|
67
67
|
guildInviteId: z.ZodOptional<z.ZodString>;
|
|
68
68
|
invitedOn: z.ZodOptional<z.ZodNumber>;
|
|
@@ -87,10 +87,10 @@ export declare const CreateCommissionProposalTextResultSchema: z.ZodObject<{
|
|
|
87
87
|
}, z.core.$strip>;
|
|
88
88
|
createdOn: z.ZodNumber;
|
|
89
89
|
status: z.ZodEnum<{
|
|
90
|
+
rejected: "rejected";
|
|
90
91
|
accepted: "accepted";
|
|
91
92
|
open: "open";
|
|
92
93
|
invited: "invited";
|
|
93
|
-
rejected: "rejected";
|
|
94
94
|
}>;
|
|
95
95
|
guildInviteId: z.ZodOptional<z.ZodString>;
|
|
96
96
|
invitedOn: z.ZodOptional<z.ZodNumber>;
|
|
@@ -130,10 +130,10 @@ export declare const AuditionSchema: z.ZodObject<{
|
|
|
130
130
|
curated: "curated";
|
|
131
131
|
}>>;
|
|
132
132
|
curatedAssemblyStatus: z.ZodOptional<z.ZodEnum<{
|
|
133
|
+
failed: "failed";
|
|
133
134
|
closed: "closed";
|
|
134
135
|
assembling: "assembling";
|
|
135
136
|
ready: "ready";
|
|
136
|
-
failed: "failed";
|
|
137
137
|
}>>;
|
|
138
138
|
expectedOptionCount: z.ZodOptional<z.ZodNumber>;
|
|
139
139
|
curatedFailureReason: z.ZodOptional<z.ZodString>;
|
|
@@ -6,6 +6,7 @@ export declare const ItemsKeySchema: z.ZodEnum<{
|
|
|
6
6
|
}>;
|
|
7
7
|
export type ItemsKey = z.infer<typeof ItemsKeySchema>;
|
|
8
8
|
export declare const FullTaleSchema: z.ZodObject<{
|
|
9
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
9
10
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10
11
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
11
12
|
uid: z.ZodString;
|
|
@@ -19,6 +20,7 @@ export declare const FullTaleSchema: z.ZodObject<{
|
|
|
19
20
|
}, z.core.$strip>;
|
|
20
21
|
export type FullTale = z.infer<typeof FullTaleSchema>;
|
|
21
22
|
export declare const FullChapterSchema: z.ZodObject<{
|
|
23
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
22
24
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
23
25
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
24
26
|
uid: z.ZodString;
|
|
@@ -36,6 +38,7 @@ export declare const FullChapterSchema: z.ZodObject<{
|
|
|
36
38
|
}, z.core.$strip>;
|
|
37
39
|
export type FullChapter = z.infer<typeof FullChapterSchema>;
|
|
38
40
|
export declare const FullTuneSchema: z.ZodObject<{
|
|
41
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
39
42
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
40
43
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
41
44
|
uid: z.ZodString;
|
|
@@ -49,6 +52,7 @@ export declare const FullTuneSchema: z.ZodObject<{
|
|
|
49
52
|
}, z.core.$strip>;
|
|
50
53
|
export type FullTune = z.infer<typeof FullTuneSchema>;
|
|
51
54
|
export declare const FullTuneTrackSchema: z.ZodObject<{
|
|
55
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
52
56
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
53
57
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
54
58
|
uid: z.ZodString;
|
|
@@ -67,6 +71,7 @@ export declare const FullTuneTrackSchema: z.ZodObject<{
|
|
|
67
71
|
}, z.core.$strip>;
|
|
68
72
|
export type FullTuneTrack = z.infer<typeof FullTuneTrackSchema>;
|
|
69
73
|
export declare const FullTelevisionSchema: z.ZodObject<{
|
|
74
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
70
75
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
71
76
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
72
77
|
uid: z.ZodString;
|
|
@@ -80,6 +85,7 @@ export declare const FullTelevisionSchema: z.ZodObject<{
|
|
|
80
85
|
}, z.core.$strip>;
|
|
81
86
|
export type FullTelevision = z.infer<typeof FullTelevisionSchema>;
|
|
82
87
|
export declare const FullTelevisionEpisodeSchema: z.ZodObject<{
|
|
88
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
83
89
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
84
90
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
85
91
|
uid: z.ZodString;
|
|
@@ -129,8 +135,8 @@ export declare const ThresholdItemSchema: z.ZodObject<{
|
|
|
129
135
|
submittedAt: z.ZodNumber;
|
|
130
136
|
reviewStatus: z.ZodEnum<{
|
|
131
137
|
pending: "pending";
|
|
132
|
-
needs_revision: "needs_revision";
|
|
133
138
|
approved: "approved";
|
|
139
|
+
needs_revision: "needs_revision";
|
|
134
140
|
}>;
|
|
135
141
|
adminNotes: z.ZodOptional<z.ZodString>;
|
|
136
142
|
reviewedAt: z.ZodOptional<z.ZodNumber>;
|
|
@@ -153,13 +159,13 @@ export type ThresholdItem = z.infer<typeof ThresholdItemSchema>;
|
|
|
153
159
|
* surface targets the single `workRealms/{id}` doc (the realm grain of the one
|
|
154
160
|
* text-change pipeline — R1, 2026-07-12). */
|
|
155
161
|
export declare const HallContentTextSurfaceSchema: z.ZodEnum<{
|
|
162
|
+
workRealm: "workRealm";
|
|
156
163
|
tale: "tale";
|
|
157
164
|
tune: "tune";
|
|
158
165
|
television: "television";
|
|
159
166
|
chapter: "chapter";
|
|
160
167
|
tuneTrack: "tuneTrack";
|
|
161
168
|
televisionEpisode: "televisionEpisode";
|
|
162
|
-
workRealm: "workRealm";
|
|
163
169
|
}>;
|
|
164
170
|
export type HallContentTextSurface = z.infer<typeof HallContentTextSurfaceSchema>;
|
|
165
171
|
/** The ONE canonical hall sub-item kind (a Tale chapter / Tune track / Television
|
|
@@ -191,13 +197,13 @@ export declare const HallContentChangeRequestSchema: z.ZodObject<{
|
|
|
191
197
|
Television: "Television";
|
|
192
198
|
}>>;
|
|
193
199
|
surface: z.ZodEnum<{
|
|
200
|
+
workRealm: "workRealm";
|
|
194
201
|
tale: "tale";
|
|
195
202
|
tune: "tune";
|
|
196
203
|
television: "television";
|
|
197
204
|
chapter: "chapter";
|
|
198
205
|
tuneTrack: "tuneTrack";
|
|
199
206
|
televisionEpisode: "televisionEpisode";
|
|
200
|
-
workRealm: "workRealm";
|
|
201
207
|
}>;
|
|
202
208
|
workRealmId: z.ZodNullable<z.ZodString>;
|
|
203
209
|
subItemId: z.ZodNullable<z.ZodString>;
|
|
@@ -205,8 +211,8 @@ export declare const HallContentChangeRequestSchema: z.ZodObject<{
|
|
|
205
211
|
proposedFields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
206
212
|
status: z.ZodEnum<{
|
|
207
213
|
approved: "approved";
|
|
208
|
-
requested: "requested";
|
|
209
214
|
denied: "denied";
|
|
215
|
+
requested: "requested";
|
|
210
216
|
}>;
|
|
211
217
|
createdAt: z.ZodNumber;
|
|
212
218
|
lastUpdatedAt: z.ZodNumber;
|
|
@@ -249,6 +255,7 @@ export declare const PublishedHallItemSchema: z.ZodObject<{
|
|
|
249
255
|
}>>;
|
|
250
256
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
251
257
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
258
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
252
259
|
hasRealPeople: z.ZodOptional<z.ZodBoolean>;
|
|
253
260
|
}, z.core.$strip>;
|
|
254
261
|
export type PublishedHallItem = z.infer<typeof PublishedHallItemSchema>;
|
|
@@ -266,6 +273,19 @@ export declare const PublishedTuneTrackSchema: z.ZodObject<{
|
|
|
266
273
|
}>>;
|
|
267
274
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
268
275
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
276
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
277
|
+
edgeSyncState: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
278
|
+
processing: "processing";
|
|
279
|
+
failed: "failed";
|
|
280
|
+
}>>>;
|
|
281
|
+
edgeSyncProcessingAt: z.ZodOptional<z.ZodNumber>;
|
|
282
|
+
edgeSyncOp: z.ZodOptional<z.ZodEnum<{
|
|
283
|
+
block: "block";
|
|
284
|
+
blockClear: "blockClear";
|
|
285
|
+
}>>;
|
|
286
|
+
edgeSyncAssetIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
287
|
+
edgeSyncError: z.ZodOptional<z.ZodString>;
|
|
288
|
+
edgeSyncFailedAt: z.ZodOptional<z.ZodNumber>;
|
|
269
289
|
}, z.core.$strip>;
|
|
270
290
|
export type PublishedTuneTrack = z.infer<typeof PublishedTuneTrackSchema>;
|
|
271
291
|
export declare const PublishedChapterSchema: z.ZodObject<{
|
|
@@ -282,6 +302,19 @@ export declare const PublishedChapterSchema: z.ZodObject<{
|
|
|
282
302
|
}>>;
|
|
283
303
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
284
304
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
305
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
306
|
+
edgeSyncState: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
307
|
+
processing: "processing";
|
|
308
|
+
failed: "failed";
|
|
309
|
+
}>>>;
|
|
310
|
+
edgeSyncProcessingAt: z.ZodOptional<z.ZodNumber>;
|
|
311
|
+
edgeSyncOp: z.ZodOptional<z.ZodEnum<{
|
|
312
|
+
block: "block";
|
|
313
|
+
blockClear: "blockClear";
|
|
314
|
+
}>>;
|
|
315
|
+
edgeSyncAssetIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
316
|
+
edgeSyncError: z.ZodOptional<z.ZodString>;
|
|
317
|
+
edgeSyncFailedAt: z.ZodOptional<z.ZodNumber>;
|
|
285
318
|
}, z.core.$strip>;
|
|
286
319
|
export type PublishedChapter = z.infer<typeof PublishedChapterSchema>;
|
|
287
320
|
export declare const PublishedTelevisionEpisodeSchema: z.ZodObject<{
|
|
@@ -298,6 +331,19 @@ export declare const PublishedTelevisionEpisodeSchema: z.ZodObject<{
|
|
|
298
331
|
}>>;
|
|
299
332
|
moderationClearedFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
300
333
|
moderationClearedReason: z.ZodOptional<z.ZodString>;
|
|
334
|
+
moderatedAt: z.ZodOptional<z.ZodNumber>;
|
|
335
|
+
edgeSyncState: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
336
|
+
processing: "processing";
|
|
337
|
+
failed: "failed";
|
|
338
|
+
}>>>;
|
|
339
|
+
edgeSyncProcessingAt: z.ZodOptional<z.ZodNumber>;
|
|
340
|
+
edgeSyncOp: z.ZodOptional<z.ZodEnum<{
|
|
341
|
+
block: "block";
|
|
342
|
+
blockClear: "blockClear";
|
|
343
|
+
}>>;
|
|
344
|
+
edgeSyncAssetIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
345
|
+
edgeSyncError: z.ZodOptional<z.ZodString>;
|
|
346
|
+
edgeSyncFailedAt: z.ZodOptional<z.ZodNumber>;
|
|
301
347
|
}, z.core.$strip>;
|
|
302
348
|
export type PublishedTelevisionEpisode = z.infer<typeof PublishedTelevisionEpisodeSchema>;
|
|
303
349
|
export declare const HallLibraryInProgressEntrySchema: z.ZodObject<{
|
|
@@ -345,8 +391,8 @@ export declare const FuturePlanItemSchema: z.ZodObject<{
|
|
|
345
391
|
order: z.ZodNumber;
|
|
346
392
|
videoUrl: z.ZodOptional<z.ZodString>;
|
|
347
393
|
mediaType: z.ZodOptional<z.ZodEnum<{
|
|
348
|
-
video: "video";
|
|
349
394
|
image: "image";
|
|
395
|
+
video: "video";
|
|
350
396
|
audio: "audio";
|
|
351
397
|
other: "other";
|
|
352
398
|
}>>;
|
|
@@ -361,8 +407,8 @@ export declare const FuturePlansDocumentSchema: z.ZodObject<{
|
|
|
361
407
|
order: z.ZodNumber;
|
|
362
408
|
videoUrl: z.ZodOptional<z.ZodString>;
|
|
363
409
|
mediaType: z.ZodOptional<z.ZodEnum<{
|
|
364
|
-
video: "video";
|
|
365
410
|
image: "image";
|
|
411
|
+
video: "video";
|
|
366
412
|
audio: "audio";
|
|
367
413
|
other: "other";
|
|
368
414
|
}>>;
|
|
@@ -371,9 +417,9 @@ export declare const FuturePlansDocumentSchema: z.ZodObject<{
|
|
|
371
417
|
}, z.core.$strip>;
|
|
372
418
|
export type FuturePlansDocument = z.infer<typeof FuturePlansDocumentSchema>;
|
|
373
419
|
export declare const RuleGroupSchema: z.ZodEnum<{
|
|
420
|
+
workRealm: "workRealm";
|
|
374
421
|
workProjectType: "workProjectType";
|
|
375
422
|
hallWingType: "hallWingType";
|
|
376
|
-
workRealm: "workRealm";
|
|
377
423
|
generic: "generic";
|
|
378
424
|
merchandising: "merchandising";
|
|
379
425
|
}>;
|
|
@@ -393,9 +439,9 @@ export declare const RuleSchema: z.ZodObject<{
|
|
|
393
439
|
description: z.ZodString;
|
|
394
440
|
videoUrl: z.ZodOptional<z.ZodString>;
|
|
395
441
|
group: z.ZodOptional<z.ZodEnum<{
|
|
442
|
+
workRealm: "workRealm";
|
|
396
443
|
workProjectType: "workProjectType";
|
|
397
444
|
hallWingType: "hallWingType";
|
|
398
|
-
workRealm: "workRealm";
|
|
399
445
|
generic: "generic";
|
|
400
446
|
merchandising: "merchandising";
|
|
401
447
|
}>>;
|
|
@@ -422,9 +468,9 @@ export declare const RulesAndAgreementsSchema: z.ZodObject<{
|
|
|
422
468
|
description: z.ZodString;
|
|
423
469
|
videoUrl: z.ZodOptional<z.ZodString>;
|
|
424
470
|
group: z.ZodOptional<z.ZodEnum<{
|
|
471
|
+
workRealm: "workRealm";
|
|
425
472
|
workProjectType: "workProjectType";
|
|
426
473
|
hallWingType: "hallWingType";
|
|
427
|
-
workRealm: "workRealm";
|
|
428
474
|
generic: "generic";
|
|
429
475
|
merchandising: "merchandising";
|
|
430
476
|
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/content.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/content.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// UI-only filter/view types remain in ../types/content.ts.
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { HALL_WING_TYPE_KEYS, WORK_PROJECT_TYPE_KEYS } from '../types/content.js';
|
|
8
|
+
import { ModerationEdgeSyncOpSchema, ModerationEdgeSyncStateSchema } from './moderation.js';
|
|
8
9
|
const contentStatusSchema = z.enum(['unpublished', 'pending_approval', 'published']);
|
|
9
10
|
// Per-field moderation text-clear remedy (shared shape across the content family — Tale/Tune/
|
|
10
11
|
// Television details, their chapter/track/episode sub-items, and the published Hall projections of
|
|
@@ -28,6 +29,7 @@ export const FullTaleSchema = z.object({
|
|
|
28
29
|
coverCinematicAssetId: z.string().optional(),
|
|
29
30
|
workGenres: z.array(z.string()).optional(),
|
|
30
31
|
...moderationClearedFieldsShape,
|
|
32
|
+
moderatedAt: z.number().optional(),
|
|
31
33
|
});
|
|
32
34
|
export const FullChapterSchema = z.object({
|
|
33
35
|
uid: z.string(),
|
|
@@ -39,6 +41,7 @@ export const FullChapterSchema = z.object({
|
|
|
39
41
|
status: contentStatusSchema,
|
|
40
42
|
createdOn: z.number(),
|
|
41
43
|
...moderationClearedFieldsShape,
|
|
44
|
+
moderatedAt: z.number().optional(),
|
|
42
45
|
});
|
|
43
46
|
export const FullTuneSchema = z.object({
|
|
44
47
|
uid: z.string(),
|
|
@@ -50,6 +53,7 @@ export const FullTuneSchema = z.object({
|
|
|
50
53
|
workGenres: z.array(z.string()),
|
|
51
54
|
createdOn: z.number(),
|
|
52
55
|
...moderationClearedFieldsShape,
|
|
56
|
+
moderatedAt: z.number().optional(),
|
|
53
57
|
});
|
|
54
58
|
export const FullTuneTrackSchema = z.object({
|
|
55
59
|
uid: z.string(),
|
|
@@ -62,6 +66,7 @@ export const FullTuneTrackSchema = z.object({
|
|
|
62
66
|
status: contentStatusSchema,
|
|
63
67
|
createdOn: z.number(),
|
|
64
68
|
...moderationClearedFieldsShape,
|
|
69
|
+
moderatedAt: z.number().optional(),
|
|
65
70
|
});
|
|
66
71
|
export const FullTelevisionSchema = z.object({
|
|
67
72
|
uid: z.string(),
|
|
@@ -73,6 +78,7 @@ export const FullTelevisionSchema = z.object({
|
|
|
73
78
|
coverCinematicAssetId: z.string().optional(),
|
|
74
79
|
workGenres: z.array(z.string()),
|
|
75
80
|
...moderationClearedFieldsShape,
|
|
81
|
+
moderatedAt: z.number().optional(),
|
|
76
82
|
});
|
|
77
83
|
export const FullTelevisionEpisodeSchema = z.object({
|
|
78
84
|
uid: z.string(),
|
|
@@ -85,6 +91,7 @@ export const FullTelevisionEpisodeSchema = z.object({
|
|
|
85
91
|
status: contentStatusSchema,
|
|
86
92
|
createdOn: z.number(),
|
|
87
93
|
...moderationClearedFieldsShape,
|
|
94
|
+
moderatedAt: z.number().optional(),
|
|
88
95
|
});
|
|
89
96
|
// --- Threshold + Hall library items ---
|
|
90
97
|
/** `allWorkProjects/{workProjectId}/hallSubmissionReservation/reservation` — the Work's ONE
|
|
@@ -217,6 +224,7 @@ export const PublishedHallItemSchema = z.object({
|
|
|
217
224
|
// is the operator's reason (shown on the steward's edit surface). Backend-only-writable.
|
|
218
225
|
moderationClearedFields: z.array(z.string()).optional(),
|
|
219
226
|
moderationClearedReason: z.string().optional(),
|
|
227
|
+
moderatedAt: z.number().optional(),
|
|
220
228
|
// Parody / real-people flag (carried from the approved ThresholdItem's AUTHOR
|
|
221
229
|
// attestation — R3, 2026-07-12). When true, display surfaces render the ONE
|
|
222
230
|
// standard platform message (REAL_PEOPLE_DISCLAIMER_MESSAGE) prominently on the
|
|
@@ -237,6 +245,13 @@ export const PublishedTuneTrackSchema = z.object({
|
|
|
237
245
|
// cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.
|
|
238
246
|
moderationClearedFields: z.array(z.string()).optional(),
|
|
239
247
|
moderationClearedReason: z.string().optional(),
|
|
248
|
+
moderatedAt: z.number().optional(),
|
|
249
|
+
edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),
|
|
250
|
+
edgeSyncProcessingAt: z.number().optional(),
|
|
251
|
+
edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),
|
|
252
|
+
edgeSyncAssetIds: z.array(z.string().min(1)).optional(),
|
|
253
|
+
edgeSyncError: z.string().optional(),
|
|
254
|
+
edgeSyncFailedAt: z.number().optional(),
|
|
240
255
|
});
|
|
241
256
|
export const PublishedChapterSchema = z.object({
|
|
242
257
|
uid: z.string(),
|
|
@@ -252,6 +267,13 @@ export const PublishedChapterSchema = z.object({
|
|
|
252
267
|
// cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.
|
|
253
268
|
moderationClearedFields: z.array(z.string()).optional(),
|
|
254
269
|
moderationClearedReason: z.string().optional(),
|
|
270
|
+
moderatedAt: z.number().optional(),
|
|
271
|
+
edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),
|
|
272
|
+
edgeSyncProcessingAt: z.number().optional(),
|
|
273
|
+
edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),
|
|
274
|
+
edgeSyncAssetIds: z.array(z.string().min(1)).optional(),
|
|
275
|
+
edgeSyncError: z.string().optional(),
|
|
276
|
+
edgeSyncFailedAt: z.number().optional(),
|
|
255
277
|
});
|
|
256
278
|
export const PublishedTelevisionEpisodeSchema = z.object({
|
|
257
279
|
uid: z.string(),
|
|
@@ -267,6 +289,13 @@ export const PublishedTelevisionEpisodeSchema = z.object({
|
|
|
267
289
|
// cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.
|
|
268
290
|
moderationClearedFields: z.array(z.string()).optional(),
|
|
269
291
|
moderationClearedReason: z.string().optional(),
|
|
292
|
+
moderatedAt: z.number().optional(),
|
|
293
|
+
edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),
|
|
294
|
+
edgeSyncProcessingAt: z.number().optional(),
|
|
295
|
+
edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),
|
|
296
|
+
edgeSyncAssetIds: z.array(z.string().min(1)).optional(),
|
|
297
|
+
edgeSyncError: z.string().optional(),
|
|
298
|
+
edgeSyncFailedAt: z.number().optional(),
|
|
270
299
|
});
|
|
271
300
|
// --- Hall library user preferences (per-user Hall viewing-state doc) ---
|
|
272
301
|
// One per-user home, server-synced from day 1 (hall-viewing-experience Area 2, ruled
|