@ttt-productions/ttt-core 0.79.65 → 0.79.67

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 (164) hide show
  1. package/dist/constants/business-admin.d.ts +2 -2
  2. package/dist/constants/business-admin.d.ts.map +1 -1
  3. package/dist/constants/business-admin.js +3 -2
  4. package/dist/constants/business-admin.js.map +1 -1
  5. package/dist/constants/business-content.d.ts +13 -14
  6. package/dist/constants/business-content.d.ts.map +1 -1
  7. package/dist/constants/business-content.js +14 -15
  8. package/dist/constants/business-content.js.map +1 -1
  9. package/dist/constants/business-platform.d.ts +3 -0
  10. package/dist/constants/business-platform.d.ts.map +1 -1
  11. package/dist/constants/business-platform.js +3 -0
  12. package/dist/constants/business-platform.js.map +1 -1
  13. package/dist/constants/business-user.d.ts +2 -2
  14. package/dist/constants/business-user.d.ts.map +1 -1
  15. package/dist/constants/business-user.js +2 -2
  16. package/dist/constants/business-user.js.map +1 -1
  17. package/dist/constants/business-work-project.d.ts +0 -8
  18. package/dist/constants/business-work-project.d.ts.map +1 -1
  19. package/dist/constants/business-work-project.js +3 -10
  20. package/dist/constants/business-work-project.js.map +1 -1
  21. package/dist/constants/center-stage-rooms.d.ts +5 -0
  22. package/dist/constants/center-stage-rooms.d.ts.map +1 -1
  23. package/dist/constants/center-stage-rooms.js +7 -0
  24. package/dist/constants/center-stage-rooms.js.map +1 -1
  25. package/dist/constants/index.d.ts +1 -0
  26. package/dist/constants/index.d.ts.map +1 -1
  27. package/dist/constants/index.js +1 -0
  28. package/dist/constants/index.js.map +1 -1
  29. package/dist/constants/storage-keys.d.ts +4 -1
  30. package/dist/constants/storage-keys.d.ts.map +1 -1
  31. package/dist/constants/storage-keys.js +4 -1
  32. package/dist/constants/storage-keys.js.map +1 -1
  33. package/dist/constants/text-fields.d.ts +470 -0
  34. package/dist/constants/text-fields.d.ts.map +1 -0
  35. package/dist/constants/text-fields.js +148 -0
  36. package/dist/constants/text-fields.js.map +1 -0
  37. package/dist/doc-schemas/content.d.ts +3 -15
  38. package/dist/doc-schemas/content.d.ts.map +1 -1
  39. package/dist/doc-schemas/content.js +23 -23
  40. package/dist/doc-schemas/content.js.map +1 -1
  41. package/dist/doc-schemas/registry.d.ts +8 -15
  42. package/dist/doc-schemas/registry.d.ts.map +1 -1
  43. package/dist/media/atoms.d.ts +2 -0
  44. package/dist/media/atoms.d.ts.map +1 -1
  45. package/dist/media/atoms.js +4 -0
  46. package/dist/media/atoms.js.map +1 -1
  47. package/dist/media/domain-events-admin.d.ts +2 -0
  48. package/dist/media/domain-events-admin.d.ts.map +1 -1
  49. package/dist/media/domain-events-admin.js +6 -3
  50. package/dist/media/domain-events-admin.js.map +1 -1
  51. package/dist/media/domain-events.d.ts +2 -0
  52. package/dist/media/domain-events.d.ts.map +1 -1
  53. package/dist/media/pending-media.d.ts +22 -0
  54. package/dist/media/pending-media.d.ts.map +1 -1
  55. package/dist/media/target-info.d.ts +9 -10
  56. package/dist/media/target-info.d.ts.map +1 -1
  57. package/dist/media/target-info.js +10 -15
  58. package/dist/media/target-info.js.map +1 -1
  59. package/dist/permissions/work-project-permissions-data.d.ts +0 -15
  60. package/dist/permissions/work-project-permissions-data.d.ts.map +1 -1
  61. package/dist/permissions/work-project-permissions-data.js +0 -15
  62. package/dist/permissions/work-project-permissions-data.js.map +1 -1
  63. package/dist/schemas/admin.d.ts +54 -54
  64. package/dist/schemas/admin.d.ts.map +1 -1
  65. package/dist/schemas/admin.js +37 -35
  66. package/dist/schemas/admin.js.map +1 -1
  67. package/dist/schemas/atoms.d.ts +1 -1
  68. package/dist/schemas/atoms.d.ts.map +1 -1
  69. package/dist/schemas/atoms.js +4 -4
  70. package/dist/schemas/atoms.js.map +1 -1
  71. package/dist/schemas/chat.d.ts +13 -13
  72. package/dist/schemas/chat.js +17 -16
  73. package/dist/schemas/chat.js.map +1 -1
  74. package/dist/schemas/commissions.d.ts +1 -1
  75. package/dist/schemas/commissions.d.ts.map +1 -1
  76. package/dist/schemas/commissions.js +3 -2
  77. package/dist/schemas/commissions.js.map +1 -1
  78. package/dist/schemas/hall-library.d.ts +11 -32
  79. package/dist/schemas/hall-library.d.ts.map +1 -1
  80. package/dist/schemas/hall-library.js +22 -35
  81. package/dist/schemas/hall-library.js.map +1 -1
  82. package/dist/schemas/index.d.ts +1 -0
  83. package/dist/schemas/index.d.ts.map +1 -1
  84. package/dist/schemas/index.js +1 -0
  85. package/dist/schemas/index.js.map +1 -1
  86. package/dist/schemas/ncii.d.ts +14 -14
  87. package/dist/schemas/ncii.d.ts.map +1 -1
  88. package/dist/schemas/ncii.js +14 -16
  89. package/dist/schemas/ncii.js.map +1 -1
  90. package/dist/schemas/notification.d.ts +2 -2
  91. package/dist/schemas/notification.d.ts.map +1 -1
  92. package/dist/schemas/notification.js +14 -11
  93. package/dist/schemas/notification.js.map +1 -1
  94. package/dist/schemas/payments.d.ts +1 -1
  95. package/dist/schemas/payments.d.ts.map +1 -1
  96. package/dist/schemas/payments.js +3 -1
  97. package/dist/schemas/payments.js.map +1 -1
  98. package/dist/schemas/public-documents.d.ts +18 -18
  99. package/dist/schemas/safety.d.ts +9 -5
  100. package/dist/schemas/safety.d.ts.map +1 -1
  101. package/dist/schemas/safety.js +13 -7
  102. package/dist/schemas/safety.js.map +1 -1
  103. package/dist/schemas/social.d.ts +1 -1
  104. package/dist/schemas/social.d.ts.map +1 -1
  105. package/dist/schemas/social.js +2 -3
  106. package/dist/schemas/social.js.map +1 -1
  107. package/dist/schemas/text-field.d.ts +12 -0
  108. package/dist/schemas/text-field.d.ts.map +1 -0
  109. package/dist/schemas/text-field.js +20 -0
  110. package/dist/schemas/text-field.js.map +1 -0
  111. package/dist/schemas/users.d.ts +9 -9
  112. package/dist/schemas/users.d.ts.map +1 -1
  113. package/dist/schemas/users.js +9 -11
  114. package/dist/schemas/users.js.map +1 -1
  115. package/dist/schemas/utility.d.ts +4 -4
  116. package/dist/schemas/utility.d.ts.map +1 -1
  117. package/dist/schemas/utility.js +11 -11
  118. package/dist/schemas/utility.js.map +1 -1
  119. package/dist/schemas/work-project-management.d.ts +37 -30
  120. package/dist/schemas/work-project-management.d.ts.map +1 -1
  121. package/dist/schemas/work-project-management.js +47 -46
  122. package/dist/schemas/work-project-management.js.map +1 -1
  123. package/dist/types/audit.d.ts +1 -1
  124. package/dist/types/audit.d.ts.map +1 -1
  125. package/dist/types/audit.js.map +1 -1
  126. package/dist/upload-variables/apply-to-commission-variables.d.ts +1 -1
  127. package/dist/upload-variables/apply-to-commission-variables.d.ts.map +1 -1
  128. package/dist/upload-variables/apply-to-commission-variables.js +3 -2
  129. package/dist/upload-variables/apply-to-commission-variables.js.map +1 -1
  130. package/dist/upload-variables/create-admin-audition-variables.d.ts +4 -4
  131. package/dist/upload-variables/create-admin-audition-variables.js +5 -3
  132. package/dist/upload-variables/create-admin-audition-variables.js.map +1 -1
  133. package/dist/upload-variables/create-commission-variables.d.ts +2 -2
  134. package/dist/upload-variables/create-commission-variables.d.ts.map +1 -1
  135. package/dist/upload-variables/create-commission-variables.js +4 -3
  136. package/dist/upload-variables/create-commission-variables.js.map +1 -1
  137. package/dist/upload-variables/create-work-project-audition-variables.d.ts +2 -2
  138. package/dist/upload-variables/create-work-project-audition-variables.js +5 -3
  139. package/dist/upload-variables/create-work-project-audition-variables.js.map +1 -1
  140. package/dist/upload-variables/square-streetz-post-variables.d.ts +1 -1
  141. package/dist/upload-variables/square-streetz-post-variables.d.ts.map +1 -1
  142. package/dist/upload-variables/square-streetz-post-variables.js +2 -3
  143. package/dist/upload-variables/square-streetz-post-variables.js.map +1 -1
  144. package/dist/utils/hall-content.d.ts +10 -3
  145. package/dist/utils/hall-content.d.ts.map +1 -1
  146. package/dist/utils/hall-content.js +22 -13
  147. package/dist/utils/hall-content.js.map +1 -1
  148. package/dist/utils/index.d.ts +3 -0
  149. package/dist/utils/index.d.ts.map +1 -1
  150. package/dist/utils/index.js +3 -0
  151. package/dist/utils/index.js.map +1 -1
  152. package/dist/utils/text-field.d.ts +17 -0
  153. package/dist/utils/text-field.d.ts.map +1 -0
  154. package/dist/utils/text-field.js +36 -0
  155. package/dist/utils/text-field.js.map +1 -0
  156. package/dist/utils/work-publish-readiness.d.ts +69 -0
  157. package/dist/utils/work-publish-readiness.d.ts.map +1 -0
  158. package/dist/utils/work-publish-readiness.js +80 -0
  159. package/dist/utils/work-publish-readiness.js.map +1 -0
  160. package/dist/utils/work-realm-name.d.ts +8 -0
  161. package/dist/utils/work-realm-name.d.ts.map +1 -0
  162. package/dist/utils/work-realm-name.js +12 -0
  163. package/dist/utils/work-realm-name.js.map +1 -0
  164. package/package.json +4 -3
@@ -110,10 +110,10 @@ export declare const MAX_REQUIRE_RETITLE_REASON_LENGTH = 500;
110
110
  export declare const MAX_USER_FACING_REASON_DETAIL_LENGTH = 2000;
111
111
  /** Admin broadcast / user notification message body. */
112
112
  export declare const MAX_NOTIFICATION_MESSAGE_LENGTH = 2000;
113
+ /** Admin broadcast title — the same length as a Work title. */
114
+ export declare const MAX_BROADCAST_TITLE_LENGTH = 150;
113
115
  /** Admin user-search query input. */
114
116
  export declare const MAX_USER_SEARCH_QUERY_LENGTH = 100;
115
- /** Operator reason on the admin "mark as NCII linked evidence" intake. */
116
- export declare const MAX_NCII_EVIDENCE_REASON_LENGTH = 1000;
117
117
  /** Operator written rationale on a TAKE IT DOWN validity decision (immutable row). */
118
118
  export declare const MAX_NCII_RATIONALE_LENGTH = 4000;
119
119
  /** Requester's statement of nonconsent (statutory intake — in-app and no-login). */
@@ -1 +1 @@
1
- {"version":3,"file":"business-admin.d.ts","sourceRoot":"","sources":["../../src/constants/business-admin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"business-admin.d.ts","sourceRoot":"","sources":["../../src/constants/business-admin.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  // Admin + content-moderation business-rule constants — task priority, dispatches,
2
2
  // the moderation/feedback workflow, and admin-task lifecycle.
3
3
  import { ACTIVE_LIMITS } from './app-mode.js';
4
+ import { MAX_WORK_PROJECT_TITLE_LENGTH } from './business-work-project.js';
4
5
  // --- Admin Task Priority System ---
5
6
  export const TASK_PRIORITY = {
6
7
  CRITICAL: 4,
@@ -125,11 +126,11 @@ export const MAX_REQUIRE_RETITLE_REASON_LENGTH = 500;
125
126
  export const MAX_USER_FACING_REASON_DETAIL_LENGTH = 2000;
126
127
  /** Admin broadcast / user notification message body. */
127
128
  export const MAX_NOTIFICATION_MESSAGE_LENGTH = 2000;
129
+ /** Admin broadcast title — the same length as a Work title. */
130
+ export const MAX_BROADCAST_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;
128
131
  /** Admin user-search query input. */
129
132
  export const MAX_USER_SEARCH_QUERY_LENGTH = 100;
130
133
  // --- NCII / child-safety statutory + operator text caps ---
131
- /** Operator reason on the admin "mark as NCII linked evidence" intake. */
132
- export const MAX_NCII_EVIDENCE_REASON_LENGTH = 1000;
133
134
  /** Operator written rationale on a TAKE IT DOWN validity decision (immutable row). */
134
135
  export const MAX_NCII_RATIONALE_LENGTH = 4000;
135
136
  /** Requester's statement of nonconsent (statutory intake — in-app and no-login). */
@@ -1 +1 @@
1
- {"version":3,"file":"business-admin.js","sourceRoot":"","sources":["../../src/constants/business-admin.ts"],"names":[],"mappings":"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","sourcesContent":["// Admin + content-moderation business-rule constants — task priority, dispatches,\n// the moderation/feedback workflow, and admin-task lifecycle.\nimport { ACTIVE_LIMITS } from './app-mode.js';\nimport type { AdminTaskType } from '../doc-schemas/report-docs.js';\n\n// --- Admin Task Priority System ---\n\nexport const TASK_PRIORITY = {\n CRITICAL: 4,\n HIGH: 3,\n NORMAL: 2,\n LOW: 1,\n} as const;\n\nexport type TaskPriorityLevel = (typeof TASK_PRIORITY)[keyof typeof TASK_PRIORITY];\n\nexport const TASK_PRIORITY_LABELS = {\n 4: 'CRITICAL',\n 3: 'HIGH',\n 2: 'NORMAL',\n 1: 'LOW',\n} as const;\n\n/**\n * Canonical NUMERIC priority scale for `adminTasks.priority`, shared by BOTH\n * priority systems so `checkoutNextImportantTask` (orderBy priority desc across all\n * task types) compares commensurable values. The userReport report-core score formula\n * already writes on this scale (≈40–2250); the level-based types (thresholdLibraryReview,\n * content-appeal, adminDispatch) map their TASK_PRIORITY level onto these numbers instead\n * of writing the raw 1–4.\n *\n * Resulting order: safety reports (1200–2250) > money anomalies (1100) >\n * CRITICAL (1000) > HIGH (800) > routine reports interleave below > spam-tier (~80).\n */\nexport const TASK_PRIORITY_SCORE = {\n LOW: 50,\n NORMAL: 200,\n HIGH: 800,\n CRITICAL: 1000,\n /** Money-integrity anomaly (stake-share / pledge-ledger corruption signal) — outranks\n * everything except safety-class reports. The three anomaly creators that previously\n * hardcoded `priority: 1` (LOW) all write this. */\n MONEY_ANOMALY: 1100,\n} as const;\n\nexport type TaskPriorityScore = (typeof TASK_PRIORITY_SCORE)[keyof typeof TASK_PRIORITY_SCORE];\n\n/** Maps a level-based TASK_PRIORITY value (1–4) to its canonical numeric score. */\nexport const TASK_PRIORITY_LEVEL_TO_SCORE = {\n [TASK_PRIORITY.LOW]: TASK_PRIORITY_SCORE.LOW,\n [TASK_PRIORITY.NORMAL]: TASK_PRIORITY_SCORE.NORMAL,\n [TASK_PRIORITY.HIGH]: TASK_PRIORITY_SCORE.HIGH,\n [TASK_PRIORITY.CRITICAL]: TASK_PRIORITY_SCORE.CRITICAL,\n} as const;\n\n// --- Admin Dispatches ---\n\n/** Maximum length for an admin-dispatch subject line. */\nexport const MAX_ADMIN_DISPATCH_SUBJECT_LENGTH = 100;\n\n/** Maximum length for the initial body text of an admin dispatch. */\nexport const MAX_ADMIN_DISPATCH_INITIAL_TEXT_LENGTH = 1000;\n\n// --- Content Moderation Workflow ---\n\n/** Maximum length for a content-violation appeal message. */\nexport const MAX_APPEAL_MESSAGE_LENGTH = 1000;\n\n/** Threshold-review reviewer notes (revision notes shown to the author). One owner for\n * the review callable schema AND the admin work-view input. */\nexport const MAX_THRESHOLD_REVIEW_NOTES_LENGTH = 2000;\n\n/** Operator-facing reason stamped on a threshold item whose publish parked terminally\n * (`publishParkedReason`). Server-authored text, bounded so a long copy-failure message\n * cannot grow the doc without limit. */\nexport const MAX_THRESHOLD_PUBLISH_PARKED_REASON_LENGTH = 2000;\n\n// --- Moderation / safety operator text caps ---\n// Each is declared ONCE here and derived by every input schema AND persisted doc schema\n// that carries the field — the numbers must never be re-hardcoded at an enforcement point.\n\n/** Operator-facing INTERNAL reason/rationale (LE-loggable; account actions, case reopens). */\nexport const MAX_INTERNAL_REASON_LENGTH = 2000;\n\n/** The generic owner-readable (user-facing) reason — deliberately short, no detail leaks. */\nexport const MAX_USER_FACING_REASON_LENGTH = 280;\n\n/** Structured close-out summary on report/safety-case resolutions. */\nexport const MAX_SAFETY_RESOLUTION_SUMMARY_LENGTH = 2000;\n\n/** Optional operator note attached to a close-out. */\nexport const MAX_SAFETY_ADMIN_NOTE_LENGTH = 4000;\n\n// --- Report intake text caps ---\n\n/** Reporter free-text narrative/comment (segregated private doc; never on the root). */\nexport const MAX_REPORT_NARRATIVE_LENGTH = 4000;\n\n/** The ids a client names as the target of a report — the item, its parent reference, and the\n * owner hint. They are hints the server re-derives, so the cap only bounds what is read. */\nexport const MAX_REPORT_TARGET_ID_LENGTH = 256;\n\n/** The report DIALOG's comment field cap (the client-side compose bound — tighter than\n * the server narrative cap above, which also absorbs upgrade concatenations). */\nexport const MAX_REPORT_COMMENT_LENGTH = 1000;\n\n/** Minimum operator rationale/reason length on safety-console staged actions. */\nexport const MIN_SAFETY_RATIONALE_LENGTH = 10;\n\n/** Operator reason on an admin chat-moderation action (adminModerateChatMessage /\n * adminReadChannelContext). ONE owner for both callables' `reason` bound. */\nexport const MAX_CHAT_MODERATION_REASON_LENGTH = 1000;\n\n/** Broadcast explicitUids selector audience cap (schema + composer both derive). */\nexport const MAX_BROADCAST_EXPLICIT_UIDS = 2000;\n\n// --- Operator step-up sentinel error codes ---\n// The two backend HttpsError messages the operator TOTP step-up throws; the frontend\n// matches them to open the step-up dialog in ENROLL vs VERIFY mode. ONE declaration —\n// both the callable (functions operatorStepUp.ts) and the frontend hook import these.\nexport const STEP_UP_ENROLL_REQUIRED = 'OPERATOR_STEP_UP_ENROLL_REQUIRED';\nexport const STEP_UP_REQUIRED = 'OPERATOR_STEP_UP_REQUIRED';\n\n/** The frozen report-time captured text snapshot (edit-to-evade guard; NO PII). */\nexport const MAX_REPORT_SNAPSHOT_TEXT_LENGTH = 4000;\n\n// --- Admin console config-content text caps ---\n// Every number the system uses lives HERE — even a field only one surface consumes\n// today, because any future client (TV / phone / admin app) reads ttt-core.\n\nexport const MAX_FUTURE_PLAN_TITLE_LENGTH = 200;\nexport const MAX_FUTURE_PLAN_DESCRIPTION_LENGTH = 4000;\nexport const MAX_PLATFORM_RULE_TITLE_LENGTH = 200;\nexport const MAX_PLATFORM_RULE_DESCRIPTION_LENGTH = 4000;\nexport const MAX_AGREEMENT_POINT_LENGTH = 2000;\nexport const MAX_CONTENT_PAGE_HEADING_LENGTH = 300;\nexport const MAX_CONTENT_PAGE_BODY_LENGTH = 20000;\n/** Sections in one long-form content page (Terms, Privacy, the DMCA policy's process text). */\nexport const MAX_CONTENT_PAGE_SECTIONS = 300;\nexport const MAX_TAKE_IT_DOWN_COPY_LENGTH = 8000;\n/** DMCA policy page: the labeled contact blocks (service provider, designated agent) and their rows. */\nexport const MAX_DMCA_CONTACT_BLOCKS = 10;\nexport const MAX_DMCA_CONTACT_ROWS = 20;\nexport const MAX_DMCA_CONTACT_LABEL_LENGTH = 100;\nexport const MAX_DMCA_CONTACT_VALUE_LENGTH = 500;\nexport const MAX_MAINTENANCE_MESSAGE_LENGTH = 2000;\n\n/** `_appConfig/app.appVersion` — the force-refresh version string VersionGate compares. */\nexport const MAX_APP_VERSION_LENGTH = 64;\n\n/** Announcement-banner copy on `_appConfig/app.announcementMessage`. Deliberately far\n * shorter than the maintenance message: the announcement renders as a one-line banner\n * on the landing page and login screen, not a full-page takeover. */\nexport const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;\n\n/** Admin notes on a content-appeal review (reviewContentAppeal). */\nexport const MAX_APPEAL_REVIEW_NOTES_LENGTH = 2000;\n\n/** Admin reason on a Work/Realm forced-retitle remedy. */\nexport const MAX_REQUIRE_RETITLE_REASON_LENGTH = 500;\n\n/** Optional user-facing DETAIL text on a normal-report resolution. */\nexport const MAX_USER_FACING_REASON_DETAIL_LENGTH = 2000;\n\n/** Admin broadcast / user notification message body. */\nexport const MAX_NOTIFICATION_MESSAGE_LENGTH = 2000;\n\n/** Admin user-search query input. */\nexport const MAX_USER_SEARCH_QUERY_LENGTH = 100;\n\n// --- NCII / child-safety statutory + operator text caps ---\n\n/** Operator reason on the admin \"mark as NCII linked evidence\" intake. */\nexport const MAX_NCII_EVIDENCE_REASON_LENGTH = 1000;\n\n/** Operator written rationale on a TAKE IT DOWN validity decision (immutable row). */\nexport const MAX_NCII_RATIONALE_LENGTH = 4000;\n\n/** Requester's statement of nonconsent (statutory intake — in-app and no-login). */\nexport const MAX_NCII_NONCONSENT_STATEMENT_LENGTH = 4000;\n\n/** Typed-name electronic signature on a statutory request. */\nexport const MAX_NCII_SIGNED_NAME_LENGTH = 256;\n\n/** Requester's optional supporting facts (statutory intake). */\nexport const MAX_NCII_SUPPORTING_FACTS_LENGTH = 8000;\n\n/** Bounded, non-sensitive summary on an NCII request action row. */\nexport const MAX_NCII_ACTION_SUMMARY_LENGTH = 280;\n\n/** Operator description of a registered evidence artifact (e.g. portal screenshot). */\nexport const MAX_SAFETY_ARTIFACT_DESCRIPTION_LENGTH = 500;\n\n/** Operator proof note on a manual NCMEC portal filing. */\nexport const MAX_NCMEC_PORTAL_PROOF_TEXT_LENGTH = 2000;\n\n/** Requester's typed name on the no-login TAKE IT DOWN statutory intake. */\nexport const MAX_NCII_REQUESTER_NAME_LENGTH = 256;\n\n/** Name of the depicted person a representative files on behalf of. */\nexport const MAX_NCII_REPRESENTED_PERSON_NAME_LENGTH = 256;\n\n/** Representative's stated basis of authority (parent/guardian/counsel etc.). */\nexport const MAX_NCII_AUTHORITY_BASIS_LENGTH = 2000;\n\n/** Optional pointer/reference to authority evidence supplied by a representative. */\nexport const MAX_NCII_AUTHORITY_EVIDENCE_REF_LENGTH = 512;\n\n/** The external URL a no-login statutory request names as the content to remove. */\nexport const MAX_NCII_LOCATOR_URL_LENGTH = 2048;\n\n/** The client-generated idempotency key of a statutory request: a retried submit carries the same\n * key, and the server derives the request id from it. */\nexport const NCII_IDEMPOTENCY_KEY_MIN_LENGTH = 8;\nexport const NCII_IDEMPOTENCY_KEY_MAX_LENGTH = 256;\n\n/** A statutory requester's contact email (the address-length ceiling of an email). */\nexport const MAX_NCII_CONTACT_EMAIL_LENGTH = 320;\n\n/** A statutory requester's contact phone number. */\nexport const NCII_CONTACT_PHONE_MIN_LENGTH = 3;\nexport const NCII_CONTACT_PHONE_MAX_LENGTH = 64;\n\n/** Maximum length for a feedback suggestion. */\nexport const MAX_FEEDBACK_SUGGESTION_LENGTH = 100;\n\n/** Maximum number of distinct submitters tracked per feedback suggestion. Mode-varied. */\nexport const MAX_FEEDBACK_SUBMITTERS = ACTIVE_LIMITS.batches.maxFeedbackSubmitters;\n\n/**\n * Canonical list of feedback types accepted by `submitFeedback`. Used both\n * for runtime validation in the schema (`SubmitFeedbackInputSchema`) and\n * for type-safe consumer props on the frontend `<FeedbackSubmission />`\n * component. Adding a new type here is the single source of truth — no\n * mirroring in callers required.\n */\nexport const FEEDBACK_TYPES = [\n 'tradeProfessionSuggestions',\n 'craftSkillTagSuggestions',\n 'talesWorkGenreSuggestions',\n 'tunesWorkGenreSuggestions',\n 'televisionWorkGenreSuggestions',\n] as const;\n\n/** Union of canonical feedback types. */\nexport type FeedbackType = (typeof FEEDBACK_TYPES)[number];\n\n/** Maximum number of items submitted in a single hallLibrary-review submission. Mode-varied. */\nexport const MAX_HALL_LIBRARY_SUBMIT_BATCH = ACTIVE_LIMITS.hall.maxSubmitBatch;\n\n// --- Admin Tasks ---\n\n/** Admin task lifecycle statuses. */\nexport const ADMIN_TASK_STATUS = {\n PENDING: 'pending',\n CHECKED_OUT: 'checkedOut',\n WORK_LATER: 'workLater',\n COMPLETED: 'completed',\n} as const;\n\n/**\n * Who resolves each kind of admin task. `checkin` means the generic queue check-in completes it\n * (the task carries no decision of its own). Every other owner is the domain decision that closes\n * the task — and deletes it in the same transaction — so a generic check-in must never mark one\n * of those tasks resolved: that would drop the decision it exists to collect.\n */\nexport const ADMIN_TASK_RESOLUTION_OWNERS = [\n 'checkin',\n 'reportResolution',\n 'thresholdReview',\n 'appealReview',\n 'refundDecision',\n 'changeRequestReview',\n 'dispatchClose',\n] as const;\nexport type AdminTaskResolutionOwner = (typeof ADMIN_TASK_RESOLUTION_OWNERS)[number];\n\n/** The resolution owner of every admin task type. A new task type fails the build until classified. */\nexport const ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE = {\n adminDispatch: 'dispatchClose',\n thresholdLibraryReview: 'thresholdReview',\n userReport: 'reportResolution',\n 'content-appeal': 'appealReview',\n stakeShareAnomaly: 'checkin',\n pledgeLedgerAnomaly: 'checkin',\n pledgePaymentRepairNeeded: 'checkin',\n pledgeDisputeOpened: 'checkin',\n pledgeRefundRequested: 'refundDecision',\n pledgeRefundFailed: 'refundDecision',\n hallContentChangeRequest: 'changeRequestReview',\n} as const satisfies Record<AdminTaskType, AdminTaskResolutionOwner>;\n\n/**\n * Whether a generic check-in may mark a task of this stored type resolved. The type is read off an\n * untrusted stored task as a string, so an unknown type answers `false` (fails closed).\n */\nexport function isAdminTaskResolvedByCheckin(taskType: string): boolean {\n return (\n Object.hasOwn(ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE, taskType) &&\n ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE[taskType as AdminTaskType] === 'checkin'\n );\n}\n"]}
1
+ {"version":3,"file":"business-admin.js","sourceRoot":"","sources":["../../src/constants/business-admin.ts"],"names":[],"mappings":"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","sourcesContent":["// Admin + content-moderation business-rule constants — task priority, dispatches,\n// the moderation/feedback workflow, and admin-task lifecycle.\nimport { ACTIVE_LIMITS } from './app-mode.js';\nimport { MAX_WORK_PROJECT_TITLE_LENGTH } from './business-work-project.js';\nimport type { AdminTaskType } from '../doc-schemas/report-docs.js';\n\n// --- Admin Task Priority System ---\n\nexport const TASK_PRIORITY = {\n CRITICAL: 4,\n HIGH: 3,\n NORMAL: 2,\n LOW: 1,\n} as const;\n\nexport type TaskPriorityLevel = (typeof TASK_PRIORITY)[keyof typeof TASK_PRIORITY];\n\nexport const TASK_PRIORITY_LABELS = {\n 4: 'CRITICAL',\n 3: 'HIGH',\n 2: 'NORMAL',\n 1: 'LOW',\n} as const;\n\n/**\n * Canonical NUMERIC priority scale for `adminTasks.priority`, shared by BOTH\n * priority systems so `checkoutNextImportantTask` (orderBy priority desc across all\n * task types) compares commensurable values. The userReport report-core score formula\n * already writes on this scale (≈40–2250); the level-based types (thresholdLibraryReview,\n * content-appeal, adminDispatch) map their TASK_PRIORITY level onto these numbers instead\n * of writing the raw 1–4.\n *\n * Resulting order: safety reports (1200–2250) > money anomalies (1100) >\n * CRITICAL (1000) > HIGH (800) > routine reports interleave below > spam-tier (~80).\n */\nexport const TASK_PRIORITY_SCORE = {\n LOW: 50,\n NORMAL: 200,\n HIGH: 800,\n CRITICAL: 1000,\n /** Money-integrity anomaly (stake-share / pledge-ledger corruption signal) — outranks\n * everything except safety-class reports. The three anomaly creators that previously\n * hardcoded `priority: 1` (LOW) all write this. */\n MONEY_ANOMALY: 1100,\n} as const;\n\nexport type TaskPriorityScore = (typeof TASK_PRIORITY_SCORE)[keyof typeof TASK_PRIORITY_SCORE];\n\n/** Maps a level-based TASK_PRIORITY value (1–4) to its canonical numeric score. */\nexport const TASK_PRIORITY_LEVEL_TO_SCORE = {\n [TASK_PRIORITY.LOW]: TASK_PRIORITY_SCORE.LOW,\n [TASK_PRIORITY.NORMAL]: TASK_PRIORITY_SCORE.NORMAL,\n [TASK_PRIORITY.HIGH]: TASK_PRIORITY_SCORE.HIGH,\n [TASK_PRIORITY.CRITICAL]: TASK_PRIORITY_SCORE.CRITICAL,\n} as const;\n\n// --- Admin Dispatches ---\n\n/** Maximum length for an admin-dispatch subject line. */\nexport const MAX_ADMIN_DISPATCH_SUBJECT_LENGTH = 100;\n\n/** Maximum length for the initial body text of an admin dispatch. */\nexport const MAX_ADMIN_DISPATCH_INITIAL_TEXT_LENGTH = 1000;\n\n// --- Content Moderation Workflow ---\n\n/** Maximum length for a content-violation appeal message. */\nexport const MAX_APPEAL_MESSAGE_LENGTH = 1000;\n\n/** Threshold-review reviewer notes (revision notes shown to the author). One owner for\n * the review callable schema AND the admin work-view input. */\nexport const MAX_THRESHOLD_REVIEW_NOTES_LENGTH = 2000;\n\n/** Operator-facing reason stamped on a threshold item whose publish parked terminally\n * (`publishParkedReason`). Server-authored text, bounded so a long copy-failure message\n * cannot grow the doc without limit. */\nexport const MAX_THRESHOLD_PUBLISH_PARKED_REASON_LENGTH = 2000;\n\n// --- Moderation / safety operator text caps ---\n// Each is declared ONCE here and derived by every input schema AND persisted doc schema\n// that carries the field — the numbers must never be re-hardcoded at an enforcement point.\n\n/** Operator-facing INTERNAL reason/rationale (LE-loggable; account actions, case reopens). */\nexport const MAX_INTERNAL_REASON_LENGTH = 2000;\n\n/** The generic owner-readable (user-facing) reason — deliberately short, no detail leaks. */\nexport const MAX_USER_FACING_REASON_LENGTH = 280;\n\n/** Structured close-out summary on report/safety-case resolutions. */\nexport const MAX_SAFETY_RESOLUTION_SUMMARY_LENGTH = 2000;\n\n/** Optional operator note attached to a close-out. */\nexport const MAX_SAFETY_ADMIN_NOTE_LENGTH = 4000;\n\n// --- Report intake text caps ---\n\n/** Reporter free-text narrative/comment (segregated private doc; never on the root). */\nexport const MAX_REPORT_NARRATIVE_LENGTH = 4000;\n\n/** The ids a client names as the target of a report — the item, its parent reference, and the\n * owner hint. They are hints the server re-derives, so the cap only bounds what is read. */\nexport const MAX_REPORT_TARGET_ID_LENGTH = 256;\n\n/** The report DIALOG's comment field cap (the client-side compose bound — tighter than\n * the server narrative cap above, which also absorbs upgrade concatenations). */\nexport const MAX_REPORT_COMMENT_LENGTH = 1000;\n\n/** Minimum operator rationale/reason length on safety-console staged actions. */\nexport const MIN_SAFETY_RATIONALE_LENGTH = 10;\n\n/** Operator reason on an admin chat-moderation action (adminModerateChatMessage /\n * adminReadChannelContext). ONE owner for both callables' `reason` bound. */\nexport const MAX_CHAT_MODERATION_REASON_LENGTH = 1000;\n\n/** Broadcast explicitUids selector audience cap (schema + composer both derive). */\nexport const MAX_BROADCAST_EXPLICIT_UIDS = 2000;\n\n// --- Operator step-up sentinel error codes ---\n// The two backend HttpsError messages the operator TOTP step-up throws; the frontend\n// matches them to open the step-up dialog in ENROLL vs VERIFY mode. ONE declaration —\n// both the callable (functions operatorStepUp.ts) and the frontend hook import these.\nexport const STEP_UP_ENROLL_REQUIRED = 'OPERATOR_STEP_UP_ENROLL_REQUIRED';\nexport const STEP_UP_REQUIRED = 'OPERATOR_STEP_UP_REQUIRED';\n\n/** The frozen report-time captured text snapshot (edit-to-evade guard; NO PII). */\nexport const MAX_REPORT_SNAPSHOT_TEXT_LENGTH = 4000;\n\n// --- Admin console config-content text caps ---\n// Every number the system uses lives HERE — even a field only one surface consumes\n// today, because any future client (TV / phone / admin app) reads ttt-core.\n\nexport const MAX_FUTURE_PLAN_TITLE_LENGTH = 200;\nexport const MAX_FUTURE_PLAN_DESCRIPTION_LENGTH = 4000;\nexport const MAX_PLATFORM_RULE_TITLE_LENGTH = 200;\nexport const MAX_PLATFORM_RULE_DESCRIPTION_LENGTH = 4000;\nexport const MAX_AGREEMENT_POINT_LENGTH = 2000;\nexport const MAX_CONTENT_PAGE_HEADING_LENGTH = 300;\nexport const MAX_CONTENT_PAGE_BODY_LENGTH = 20000;\n/** Sections in one long-form content page (Terms, Privacy, the DMCA policy's process text). */\nexport const MAX_CONTENT_PAGE_SECTIONS = 300;\nexport const MAX_TAKE_IT_DOWN_COPY_LENGTH = 8000;\n/** DMCA policy page: the labeled contact blocks (service provider, designated agent) and their rows. */\nexport const MAX_DMCA_CONTACT_BLOCKS = 10;\nexport const MAX_DMCA_CONTACT_ROWS = 20;\nexport const MAX_DMCA_CONTACT_LABEL_LENGTH = 100;\nexport const MAX_DMCA_CONTACT_VALUE_LENGTH = 500;\nexport const MAX_MAINTENANCE_MESSAGE_LENGTH = 2000;\n\n/** `_appConfig/app.appVersion` — the force-refresh version string VersionGate compares. */\nexport const MAX_APP_VERSION_LENGTH = 64;\n\n/** Announcement-banner copy on `_appConfig/app.announcementMessage`. Deliberately far\n * shorter than the maintenance message: the announcement renders as a one-line banner\n * on the landing page and login screen, not a full-page takeover. */\nexport const MAX_ANNOUNCEMENT_MESSAGE_LENGTH = 300;\n\n/** Admin notes on a content-appeal review (reviewContentAppeal). */\nexport const MAX_APPEAL_REVIEW_NOTES_LENGTH = 2000;\n\n/** Admin reason on a Work/Realm forced-retitle remedy. */\nexport const MAX_REQUIRE_RETITLE_REASON_LENGTH = 500;\n\n/** Optional user-facing DETAIL text on a normal-report resolution. */\nexport const MAX_USER_FACING_REASON_DETAIL_LENGTH = 2000;\n\n/** Admin broadcast / user notification message body. */\nexport const MAX_NOTIFICATION_MESSAGE_LENGTH = 2000;\n\n/** Admin broadcast title — the same length as a Work title. */\nexport const MAX_BROADCAST_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;\n\n/** Admin user-search query input. */\nexport const MAX_USER_SEARCH_QUERY_LENGTH = 100;\n\n// --- NCII / child-safety statutory + operator text caps ---\n\n/** Operator written rationale on a TAKE IT DOWN validity decision (immutable row). */\nexport const MAX_NCII_RATIONALE_LENGTH = 4000;\n\n/** Requester's statement of nonconsent (statutory intake — in-app and no-login). */\nexport const MAX_NCII_NONCONSENT_STATEMENT_LENGTH = 4000;\n\n/** Typed-name electronic signature on a statutory request. */\nexport const MAX_NCII_SIGNED_NAME_LENGTH = 256;\n\n/** Requester's optional supporting facts (statutory intake). */\nexport const MAX_NCII_SUPPORTING_FACTS_LENGTH = 8000;\n\n/** Bounded, non-sensitive summary on an NCII request action row. */\nexport const MAX_NCII_ACTION_SUMMARY_LENGTH = 280;\n\n/** Operator description of a registered evidence artifact (e.g. portal screenshot). */\nexport const MAX_SAFETY_ARTIFACT_DESCRIPTION_LENGTH = 500;\n\n/** Operator proof note on a manual NCMEC portal filing. */\nexport const MAX_NCMEC_PORTAL_PROOF_TEXT_LENGTH = 2000;\n\n/** Requester's typed name on the no-login TAKE IT DOWN statutory intake. */\nexport const MAX_NCII_REQUESTER_NAME_LENGTH = 256;\n\n/** Name of the depicted person a representative files on behalf of. */\nexport const MAX_NCII_REPRESENTED_PERSON_NAME_LENGTH = 256;\n\n/** Representative's stated basis of authority (parent/guardian/counsel etc.). */\nexport const MAX_NCII_AUTHORITY_BASIS_LENGTH = 2000;\n\n/** Optional pointer/reference to authority evidence supplied by a representative. */\nexport const MAX_NCII_AUTHORITY_EVIDENCE_REF_LENGTH = 512;\n\n/** The external URL a no-login statutory request names as the content to remove. */\nexport const MAX_NCII_LOCATOR_URL_LENGTH = 2048;\n\n/** The client-generated idempotency key of a statutory request: a retried submit carries the same\n * key, and the server derives the request id from it. */\nexport const NCII_IDEMPOTENCY_KEY_MIN_LENGTH = 8;\nexport const NCII_IDEMPOTENCY_KEY_MAX_LENGTH = 256;\n\n/** A statutory requester's contact email (the address-length ceiling of an email). */\nexport const MAX_NCII_CONTACT_EMAIL_LENGTH = 320;\n\n/** A statutory requester's contact phone number. */\nexport const NCII_CONTACT_PHONE_MIN_LENGTH = 3;\nexport const NCII_CONTACT_PHONE_MAX_LENGTH = 64;\n\n/** Maximum length for a feedback suggestion. */\nexport const MAX_FEEDBACK_SUGGESTION_LENGTH = 100;\n\n/** Maximum number of distinct submitters tracked per feedback suggestion. Mode-varied. */\nexport const MAX_FEEDBACK_SUBMITTERS = ACTIVE_LIMITS.batches.maxFeedbackSubmitters;\n\n/**\n * Canonical list of feedback types accepted by `submitFeedback`. Used both\n * for runtime validation in the schema (`SubmitFeedbackInputSchema`) and\n * for type-safe consumer props on the frontend `<FeedbackSubmission />`\n * component. Adding a new type here is the single source of truth — no\n * mirroring in callers required.\n */\nexport const FEEDBACK_TYPES = [\n 'tradeProfessionSuggestions',\n 'craftSkillTagSuggestions',\n 'talesWorkGenreSuggestions',\n 'tunesWorkGenreSuggestions',\n 'televisionWorkGenreSuggestions',\n] as const;\n\n/** Union of canonical feedback types. */\nexport type FeedbackType = (typeof FEEDBACK_TYPES)[number];\n\n/** Maximum number of items submitted in a single hallLibrary-review submission. Mode-varied. */\nexport const MAX_HALL_LIBRARY_SUBMIT_BATCH = ACTIVE_LIMITS.hall.maxSubmitBatch;\n\n// --- Admin Tasks ---\n\n/** Admin task lifecycle statuses. */\nexport const ADMIN_TASK_STATUS = {\n PENDING: 'pending',\n CHECKED_OUT: 'checkedOut',\n WORK_LATER: 'workLater',\n COMPLETED: 'completed',\n} as const;\n\n/**\n * Who resolves each kind of admin task. `checkin` means the generic queue check-in completes it\n * (the task carries no decision of its own). Every other owner is the domain decision that closes\n * the task — and deletes it in the same transaction — so a generic check-in must never mark one\n * of those tasks resolved: that would drop the decision it exists to collect.\n */\nexport const ADMIN_TASK_RESOLUTION_OWNERS = [\n 'checkin',\n 'reportResolution',\n 'thresholdReview',\n 'appealReview',\n 'refundDecision',\n 'changeRequestReview',\n 'dispatchClose',\n] as const;\nexport type AdminTaskResolutionOwner = (typeof ADMIN_TASK_RESOLUTION_OWNERS)[number];\n\n/** The resolution owner of every admin task type. A new task type fails the build until classified. */\nexport const ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE = {\n adminDispatch: 'dispatchClose',\n thresholdLibraryReview: 'thresholdReview',\n userReport: 'reportResolution',\n 'content-appeal': 'appealReview',\n stakeShareAnomaly: 'checkin',\n pledgeLedgerAnomaly: 'checkin',\n pledgePaymentRepairNeeded: 'checkin',\n pledgeDisputeOpened: 'checkin',\n pledgeRefundRequested: 'refundDecision',\n pledgeRefundFailed: 'refundDecision',\n hallContentChangeRequest: 'changeRequestReview',\n} as const satisfies Record<AdminTaskType, AdminTaskResolutionOwner>;\n\n/**\n * Whether a generic check-in may mark a task of this stored type resolved. The type is read off an\n * untrusted stored task as a string, so an unknown type answers `false` (fails closed).\n */\nexport function isAdminTaskResolvedByCheckin(taskType: string): boolean {\n return (\n Object.hasOwn(ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE, taskType) &&\n ADMIN_TASK_RESOLUTION_OWNER_BY_TYPE[taskType as AdminTaskType] === 'checkin'\n );\n}\n"]}
@@ -74,7 +74,8 @@ export declare const HALL_CLEARABLE_TEXT_FIELD_NAMES: readonly ["title", "descri
74
74
  * The raw doc field names each published hall-content surface exposes as changeable TEXT.
75
75
  * Cross-boundary: the member "Update details" field picker offers this set per surface and
76
76
  * the change-request submit runner validates against it. Detail surfaces (tale/tune/
77
- * television) live on the hall parent doc; sub-item surfaces on the published chapter/
77
+ * television) are the hall parent doc's snapshot of the Work's own title and description
78
+ * (`HALL_DETAIL_TEXT_FIELD_TO_WORK_SHELL_FIELD`); sub-item surfaces are the published chapter/
78
79
  * track/episode doc. This is the HALL-SURFACE SUBSET of the canonical
79
80
  * MODERATION_CLEARABLE_TEXT_FIELDS above (it excludes the `workProject` shell) — every
80
81
  * tuple is projected from that one owner, so the two can never drift.
@@ -88,19 +89,6 @@ export declare const HALL_CONTENT_TEXT_FIELDS: {
88
89
  readonly televisionEpisode: readonly ["title", "description"];
89
90
  readonly workRealm: readonly ["workingTitle", "workingDescription"];
90
91
  };
91
- /** Per-field max lengths for proposed hall-content text. DERIVED from the owning
92
- * constants — never independent numbers — so the change-request pipeline can never
93
- * drift from the authoring limits again (the pre-2026-07-13 copy carried its own
94
- * 200/5000/100000 set while authoring enforced 150/300/2500). Keyed on the derived
95
- * ClearableTextFieldName union, so a new clearable field fails the build here until
96
- * it has a cap. */
97
- export declare const HALL_CONTENT_TEXT_FIELD_MAX: {
98
- readonly title: 150;
99
- readonly description: 1000;
100
- readonly content: number;
101
- readonly workingTitle: 150;
102
- readonly workingDescription: 1000;
103
- };
104
92
  /** One work-project type's two hall text surfaces — the published DETAIL on the hall parent
105
93
  * and its chapter/track/episode SUB-ITEM — each with the clearable/changeable field tuple
106
94
  * that surface exposes. */
@@ -161,6 +149,17 @@ export declare const WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD: {
161
149
  readonly workingTitle: "title";
162
150
  readonly workingDescription: "description";
163
151
  };
152
+ /**
153
+ * Hall parent DETAIL text field → the Work field it snapshots: the inverse of
154
+ * `WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD`. A Tale / Tune / Television section has no text of
155
+ * its own, so a detail change request or a detail moderation clear names the Hall field and acts
156
+ * on this Work field, the Work's public mirror, and the Hall entry together. Both sides are
157
+ * projected from the canonical clearable-field map.
158
+ */
159
+ export declare const HALL_DETAIL_TEXT_FIELD_TO_WORK_SHELL_FIELD: {
160
+ readonly title: "workingTitle";
161
+ readonly description: "workingDescription";
162
+ };
164
163
  /**
165
164
  * CANONICAL per-work-type rule for what a Tale chapter / Tune track / Television episode must
166
165
  * carry before it may be submitted, approved, or published. ONE owner for the member-side
@@ -1 +1 @@
1
- {"version":3,"file":"business-content.d.ts","sourceRoot":"","sources":["../../src/constants/business-content.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"business-content.d.ts","sourceRoot":"","sources":["../../src/constants/business-content.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  // Content-surface business-rule constants — commissions, auditions, the social
2
2
  // feed, and messaging.
3
- import { MAX_WORK_PROJECT_TITLE_LENGTH, MAX_WORK_PROJECT_DESCRIPTION_LENGTH, MAX_CHAPTER_CONTENT_LENGTH, MAX_WORK_REALM_TITLE_LENGTH, MAX_WORK_REALM_DESCRIPTION_LENGTH, } from "./business-work-project.js";
3
+ import { MAX_WORK_PROJECT_TITLE_LENGTH } from "./business-work-project.js";
4
4
  import { ACTIVE_LIMITS } from './app-mode.js';
5
5
  import { HALL_LIBRARY_TARGET_FIELDS } from '../media/hall-library-target-fields.js';
6
6
  import { HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE } from './hall-content-routing.js';
@@ -71,7 +71,8 @@ export const HALL_CLEARABLE_TEXT_FIELD_NAMES = [
71
71
  * The raw doc field names each published hall-content surface exposes as changeable TEXT.
72
72
  * Cross-boundary: the member "Update details" field picker offers this set per surface and
73
73
  * the change-request submit runner validates against it. Detail surfaces (tale/tune/
74
- * television) live on the hall parent doc; sub-item surfaces on the published chapter/
74
+ * television) are the hall parent doc's snapshot of the Work's own title and description
75
+ * (`HALL_DETAIL_TEXT_FIELD_TO_WORK_SHELL_FIELD`); sub-item surfaces are the published chapter/
75
76
  * track/episode doc. This is the HALL-SURFACE SUBSET of the canonical
76
77
  * MODERATION_CLEARABLE_TEXT_FIELDS above (it excludes the `workProject` shell) — every
77
78
  * tuple is projected from that one owner, so the two can never drift.
@@ -86,19 +87,6 @@ export const HALL_CONTENT_TEXT_FIELDS = {
86
87
  // Realm grain (R1, 2026-07-12): targets the `workRealms/{id}` doc directly.
87
88
  workRealm: MODERATION_CLEARABLE_TEXT_FIELDS.workRealm,
88
89
  };
89
- /** Per-field max lengths for proposed hall-content text. DERIVED from the owning
90
- * constants — never independent numbers — so the change-request pipeline can never
91
- * drift from the authoring limits again (the pre-2026-07-13 copy carried its own
92
- * 200/5000/100000 set while authoring enforced 150/300/2500). Keyed on the derived
93
- * ClearableTextFieldName union, so a new clearable field fails the build here until
94
- * it has a cap. */
95
- export const HALL_CONTENT_TEXT_FIELD_MAX = {
96
- title: MAX_WORK_PROJECT_TITLE_LENGTH,
97
- description: MAX_WORK_PROJECT_DESCRIPTION_LENGTH,
98
- content: MAX_CHAPTER_CONTENT_LENGTH,
99
- workingTitle: MAX_WORK_REALM_TITLE_LENGTH,
100
- workingDescription: MAX_WORK_REALM_DESCRIPTION_LENGTH,
101
- };
102
90
  /**
103
91
  * WorkProjectType → hall text-surface routing. Surface identities project from the lower-level
104
92
  * `HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE` owner; this map adds the clearable field tuples each
@@ -145,6 +133,17 @@ export const WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD = {
145
133
  [MODERATION_CLEARABLE_TEXT_FIELDS.workProject[0]]: MODERATION_CLEARABLE_TEXT_FIELDS.tale[0], // workingTitle → title
146
134
  [MODERATION_CLEARABLE_TEXT_FIELDS.workProject[1]]: MODERATION_CLEARABLE_TEXT_FIELDS.tale[1], // workingDescription → description
147
135
  };
136
+ /**
137
+ * Hall parent DETAIL text field → the Work field it snapshots: the inverse of
138
+ * `WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD`. A Tale / Tune / Television section has no text of
139
+ * its own, so a detail change request or a detail moderation clear names the Hall field and acts
140
+ * on this Work field, the Work's public mirror, and the Hall entry together. Both sides are
141
+ * projected from the canonical clearable-field map.
142
+ */
143
+ export const HALL_DETAIL_TEXT_FIELD_TO_WORK_SHELL_FIELD = {
144
+ [MODERATION_CLEARABLE_TEXT_FIELDS.tale[0]]: MODERATION_CLEARABLE_TEXT_FIELDS.workProject[0], // title → workingTitle
145
+ [MODERATION_CLEARABLE_TEXT_FIELDS.tale[1]]: MODERATION_CLEARABLE_TEXT_FIELDS.workProject[1], // description → workingDescription
146
+ };
148
147
  // --- Hall sub-item publish requirements ---
149
148
  /**
150
149
  * CANONICAL per-work-type rule for what a Tale chapter / Tune track / Television episode must
@@ -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 { HALL_LIBRARY_TARGET_FIELDS } from '../media/hall-library-target-fields.js';\nimport type { WorkProjectType } from '../types/content.js';\nimport { HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE } from './hall-content-routing.js';\nexport {\n HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE,\n HALL_CONTENT_DETAIL_SURFACES,\n HALL_CONTENT_SUB_ITEM_SURFACES,\n type HallContentDetailSurface,\n type HallContentSubItemSurface,\n} from './hall-content-routing.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 * WorkProjectType → hall text-surface routing. Surface identities project from the lower-level\n * `HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE` owner; this map adds the clearable field tuples each\n * surface 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 identity and field tuple is PROJECTED from its canonical owner — no surface or field\n * literal is restated here — and the `satisfies Record<WorkProjectType, …>` makes adding a\n * work-project type a compile error until its surfaces are routed.\n */\nexport const HALL_CONTENT_SURFACES_BY_WORK_TYPE = {\n Tales: {\n detailSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tales.detailSurface,\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tale,\n subItemSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tales.subItemSurface,\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.chapter,\n },\n Tunes: {\n detailSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tunes.detailSurface,\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tune,\n subItemSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tunes.subItemSurface,\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack,\n },\n Television: {\n detailSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Television.detailSurface,\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.television,\n subItemSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Television.subItemSurface,\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode,\n },\n} as const satisfies Record<WorkProjectType, HallContentSurfaceRouting>;\n\n/**\n * Work-shell text field → the field it appears as on the PUBLISHED hall parent\n * (`PublishedHallItem`): a Work's `workingTitle` is the hall item's `title`, its\n * `workingDescription` the hall item's `description`. The moderation placeholder writers\n * dual-write the shell and its published projection through a COMPUTED key, so the mapping\n * has to be a closed const map whose values are declared `PublishedHallItem` keys rather than\n * an inline ternary over two string literals. Both sides are projected from the canonical\n * clearable-field map, so neither name is restated here.\n */\nexport const WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD = {\n [MODERATION_CLEARABLE_TEXT_FIELDS.workProject[0]]: MODERATION_CLEARABLE_TEXT_FIELDS.tale[0], // workingTitle → title\n [MODERATION_CLEARABLE_TEXT_FIELDS.workProject[1]]: MODERATION_CLEARABLE_TEXT_FIELDS.tale[1], // workingDescription → description\n} as const satisfies Record<\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS.workProject)[number],\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS.tale)[number]\n>;\n\n// --- Hall sub-item publish requirements ---\n\n/**\n * CANONICAL per-work-type rule for what a Tale chapter / Tune track / Television episode must\n * carry before it may be submitted, approved, or published. ONE owner for the member-side\n * eligibility filter, the submit core, the approve core, and the publish core — each of which\n * otherwise restates the same three-way branch (ENG-002 / ENG-005).\n *\n * Every type requires a non-empty `title` and `photoAssetId`; a Tale chapter additionally\n * requires its `content`, a Tune track its audio, a Television episode its video. The media\n * field names are PROJECTED from the canonical upload target-field map and the text field names\n * from the clearable-field map, so no field literal is restated. These are exactly the fields\n * the published sub-item schemas (`PublishedChapter` / `PublishedTuneTrack` /\n * `PublishedTelevisionEpisode`) declare as REQUIRED.\n */\nexport const HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE = {\n Tales: [\n MODERATION_CLEARABLE_TEXT_FIELDS.chapter[0], // title\n HALL_LIBRARY_TARGET_FIELDS['chapter-photo'], // photoAssetId\n MODERATION_CLEARABLE_TEXT_FIELDS.chapter[1], // content\n ],\n Tunes: [\n MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack[0], // title\n HALL_LIBRARY_TARGET_FIELDS['tune-track-photo'], // photoAssetId\n HALL_LIBRARY_TARGET_FIELDS['tune-track-audio'], // audioAssetId\n ],\n Television: [\n MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode[0], // title\n HALL_LIBRARY_TARGET_FIELDS['television-episode-photo'], // photoAssetId\n HALL_LIBRARY_TARGET_FIELDS['television-episode-video'], // videoAssetId\n ],\n} as const satisfies Record<WorkProjectType, readonly string[]>;\n\n/** A field name some work type requires on a publishable hall sub-item. */\nexport type HallSubItemRequiredField =\n (typeof HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE)[WorkProjectType][number];\n\n/**\n * User-facing wording for each required sub-item field, used when a surface has to say what is\n * still missing. Keyed on the derived union, so a new requirement fails the build until it has\n * wording.\n */\nexport const HALL_SUB_ITEM_REQUIREMENT_LABELS = {\n title: 'a title',\n content: 'chapter text',\n photoAssetId: 'a picture',\n audioAssetId: 'an audio file',\n videoAssetId: 'a video file',\n} as const satisfies Record<HallSubItemRequiredField, string>;\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/** Longest mention placeholder (`@m` + the composer counter) a stored or sent mention may carry. */\nexport const MAX_MENTION_PLACEHOLDER_LENGTH = 32;\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 { MAX_WORK_PROJECT_TITLE_LENGTH } from \"./business-work-project.js\";\nimport { ACTIVE_LIMITS } from './app-mode.js';\nimport { HALL_LIBRARY_TARGET_FIELDS } from '../media/hall-library-target-fields.js';\nimport type { WorkProjectType } from '../types/content.js';\nimport { HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE } from './hall-content-routing.js';\nexport {\n HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE,\n HALL_CONTENT_DETAIL_SURFACES,\n HALL_CONTENT_SUB_ITEM_SURFACES,\n type HallContentDetailSurface,\n type HallContentSubItemSurface,\n} from './hall-content-routing.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) are the hall parent doc's snapshot of the Work's own title and description\n * (`HALL_DETAIL_TEXT_FIELD_TO_WORK_SHELL_FIELD`); sub-item surfaces are 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/** 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 * WorkProjectType → hall text-surface routing. Surface identities project from the lower-level\n * `HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE` owner; this map adds the clearable field tuples each\n * surface 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 identity and field tuple is PROJECTED from its canonical owner — no surface or field\n * literal is restated here — and the `satisfies Record<WorkProjectType, …>` makes adding a\n * work-project type a compile error until its surfaces are routed.\n */\nexport const HALL_CONTENT_SURFACES_BY_WORK_TYPE = {\n Tales: {\n detailSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tales.detailSurface,\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tale,\n subItemSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tales.subItemSurface,\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.chapter,\n },\n Tunes: {\n detailSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tunes.detailSurface,\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.tune,\n subItemSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Tunes.subItemSurface,\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack,\n },\n Television: {\n detailSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Television.detailSurface,\n detailFields: MODERATION_CLEARABLE_TEXT_FIELDS.television,\n subItemSurface: HALL_CONTENT_SURFACE_NAMES_BY_WORK_TYPE.Television.subItemSurface,\n subItemFields: MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode,\n },\n} as const satisfies Record<WorkProjectType, HallContentSurfaceRouting>;\n\n/**\n * Work-shell text field → the field it appears as on the PUBLISHED hall parent\n * (`PublishedHallItem`): a Work's `workingTitle` is the hall item's `title`, its\n * `workingDescription` the hall item's `description`. The moderation placeholder writers\n * dual-write the shell and its published projection through a COMPUTED key, so the mapping\n * has to be a closed const map whose values are declared `PublishedHallItem` keys rather than\n * an inline ternary over two string literals. Both sides are projected from the canonical\n * clearable-field map, so neither name is restated here.\n */\nexport const WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD = {\n [MODERATION_CLEARABLE_TEXT_FIELDS.workProject[0]]: MODERATION_CLEARABLE_TEXT_FIELDS.tale[0], // workingTitle → title\n [MODERATION_CLEARABLE_TEXT_FIELDS.workProject[1]]: MODERATION_CLEARABLE_TEXT_FIELDS.tale[1], // workingDescription → description\n} as const satisfies Record<\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS.workProject)[number],\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS.tale)[number]\n>;\n\n/**\n * Hall parent DETAIL text field → the Work field it snapshots: the inverse of\n * `WORK_SHELL_TEXT_FIELD_TO_HALL_ITEM_FIELD`. A Tale / Tune / Television section has no text of\n * its own, so a detail change request or a detail moderation clear names the Hall field and acts\n * on this Work field, the Work's public mirror, and the Hall entry together. Both sides are\n * projected from the canonical clearable-field map.\n */\nexport const HALL_DETAIL_TEXT_FIELD_TO_WORK_SHELL_FIELD = {\n [MODERATION_CLEARABLE_TEXT_FIELDS.tale[0]]: MODERATION_CLEARABLE_TEXT_FIELDS.workProject[0], // title → workingTitle\n [MODERATION_CLEARABLE_TEXT_FIELDS.tale[1]]: MODERATION_CLEARABLE_TEXT_FIELDS.workProject[1], // description → workingDescription\n} as const satisfies Record<\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS.tale)[number],\n (typeof MODERATION_CLEARABLE_TEXT_FIELDS.workProject)[number]\n>;\n\n// --- Hall sub-item publish requirements ---\n\n/**\n * CANONICAL per-work-type rule for what a Tale chapter / Tune track / Television episode must\n * carry before it may be submitted, approved, or published. ONE owner for the member-side\n * eligibility filter, the submit core, the approve core, and the publish core — each of which\n * otherwise restates the same three-way branch (ENG-002 / ENG-005).\n *\n * Every type requires a non-empty `title` and `photoAssetId`; a Tale chapter additionally\n * requires its `content`, a Tune track its audio, a Television episode its video. The media\n * field names are PROJECTED from the canonical upload target-field map and the text field names\n * from the clearable-field map, so no field literal is restated. These are exactly the fields\n * the published sub-item schemas (`PublishedChapter` / `PublishedTuneTrack` /\n * `PublishedTelevisionEpisode`) declare as REQUIRED.\n */\nexport const HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE = {\n Tales: [\n MODERATION_CLEARABLE_TEXT_FIELDS.chapter[0], // title\n HALL_LIBRARY_TARGET_FIELDS['chapter-photo'], // photoAssetId\n MODERATION_CLEARABLE_TEXT_FIELDS.chapter[1], // content\n ],\n Tunes: [\n MODERATION_CLEARABLE_TEXT_FIELDS.tuneTrack[0], // title\n HALL_LIBRARY_TARGET_FIELDS['tune-track-photo'], // photoAssetId\n HALL_LIBRARY_TARGET_FIELDS['tune-track-audio'], // audioAssetId\n ],\n Television: [\n MODERATION_CLEARABLE_TEXT_FIELDS.televisionEpisode[0], // title\n HALL_LIBRARY_TARGET_FIELDS['television-episode-photo'], // photoAssetId\n HALL_LIBRARY_TARGET_FIELDS['television-episode-video'], // videoAssetId\n ],\n} as const satisfies Record<WorkProjectType, readonly string[]>;\n\n/** A field name some work type requires on a publishable hall sub-item. */\nexport type HallSubItemRequiredField =\n (typeof HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE)[WorkProjectType][number];\n\n/**\n * User-facing wording for each required sub-item field, used when a surface has to say what is\n * still missing. Keyed on the derived union, so a new requirement fails the build until it has\n * wording.\n */\nexport const HALL_SUB_ITEM_REQUIREMENT_LABELS = {\n title: 'a title',\n content: 'chapter text',\n photoAssetId: 'a picture',\n audioAssetId: 'an audio file',\n videoAssetId: 'a video file',\n} as const satisfies Record<HallSubItemRequiredField, string>;\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/** Longest mention placeholder (`@m` + the composer counter) a stored or sent mention may carry. */\nexport const MAX_MENTION_PLACEHOLDER_LENGTH = 32;\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"]}
@@ -8,6 +8,9 @@ export declare const SHORT_LINK_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpq
8
8
  export declare const FIRESTORE_BATCH_LIMIT = 500;
9
9
  /** Firestore's published limit on one document id, in UTF-8 bytes. */
10
10
  export declare const FIRESTORE_DOCUMENT_ID_MAX_BYTES = 1500;
11
+ /** Firestore's published limit on an indexed field value, in UTF-8 bytes: a longer value is
12
+ * truncated in the index, so an equality query on it is not exact. */
13
+ export declare const FIRESTORE_INDEXED_VALUE_MAX_BYTES = 1500;
11
14
  /**
12
15
  * Minimum pledgePayment amount accepted by the Stripe checkout flow, in cents
13
16
  * (USD). $2.50 is the platform's business floor (DJ, 2026-06-11) — above
@@ -1 +1 @@
1
- {"version":3,"file":"business-platform.d.ts","sourceRoot":"","sources":["../../src/constants/business-platform.ts"],"names":[],"mappings":"AAKA,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,wFAAwF;AACxF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,6DAA6D,CAAC;AAI3F,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAIpD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,WAAa,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,QAA2B,CAAC;AAExE,uGAAuG;AACvG,eAAO,MAAM,qCAAqC,MAAM,CAAC"}
1
+ {"version":3,"file":"business-platform.d.ts","sourceRoot":"","sources":["../../src/constants/business-platform.ts"],"names":[],"mappings":"AAKA,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,wFAAwF;AACxF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,uFAAuF;AACvF,eAAO,MAAM,gBAAgB,6DAA6D,CAAC;AAI3F,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAEpD;uEACuE;AACvE,eAAO,MAAM,iCAAiC,OAAO,CAAC;AAItD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,WAAa,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,QAA2B,CAAC;AAExE,uGAAuG;AACvG,eAAO,MAAM,qCAAqC,MAAM,CAAC"}
@@ -12,6 +12,9 @@ export const SHORT_LINK_CHARS = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxy
12
12
  export const FIRESTORE_BATCH_LIMIT = 500;
13
13
  /** Firestore's published limit on one document id, in UTF-8 bytes. */
14
14
  export const FIRESTORE_DOCUMENT_ID_MAX_BYTES = 1500;
15
+ /** Firestore's published limit on an indexed field value, in UTF-8 bytes: a longer value is
16
+ * truncated in the index, so an equality query on it is not exact. */
17
+ export const FIRESTORE_INDEXED_VALUE_MAX_BYTES = 1500;
15
18
  // --- Payments ---
16
19
  /**
17
20
  * Minimum pledgePayment amount accepted by the Stripe checkout flow, in cents
@@ -1 +1 @@
1
- {"version":3,"file":"business-platform.js","sourceRoot":"","sources":["../../src/constants/business-platform.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,8BAA8B;AAE9B,sBAAsB;AAEtB,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC,wFAAwF;AACxF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,uFAAuF;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,0DAA0D,CAAC;AAE3F,2BAA2B;AAE3B,4DAA4D;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC,sEAAsE;AACtE,MAAM,CAAC,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAEpD,mBAAmB;AAEnB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAG,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,UAAU,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExE,uGAAuG;AACvG,MAAM,CAAC,MAAM,qCAAqC,GAAG,GAAG,CAAC","sourcesContent":["// Platform-infrastructure business-rule constants — short links, Firestore\n// limits, and payment bounds.\n\n// --- Short Links ---\n\n/** The length of the generated ID for short links. */\nexport const SHORT_LINK_LENGTH = 6;\n\n/** The maximum number of attempts to generate a unique short link ID before failing. */\nexport const SHORT_LINK_MAX_ATTEMPTS = 5;\n\n/** Character set for short link IDs. Excludes ambiguous characters (0, O, l, 1, I). */\nexport const SHORT_LINK_CHARS = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';\n\n// --- Firestore Limits ---\n\n/** Maximum operations in a single Firestore write batch. */\nexport const FIRESTORE_BATCH_LIMIT = 500;\n\n/** Firestore's published limit on one document id, in UTF-8 bytes. */\nexport const FIRESTORE_DOCUMENT_ID_MAX_BYTES = 1500;\n\n// --- Payments ---\n\n/**\n * Minimum pledgePayment amount accepted by the Stripe checkout flow, in cents\n * (USD). $2.50 is the platform's business floor (DJ, 2026-06-11) — above\n * Stripe's 50¢ technical card-charge floor. Promoted out of the Zod schema so\n * the webhook can re-assert it server-side against the Stripe-confirmed\n * amount, independent of the client input bound. Mode-invariant by design.\n */\nexport const MIN_PLEDGE_PAYMENT_AMOUNT_CENTS = 250;\n\n/**\n * Maximum pledgePayment amount accepted by the Stripe checkout flow, in cents\n * (USD). $500,000.00. Well below Stripe's hard per-charge ceiling, but\n * high enough that legitimate large gifts pass without friction. Anything\n * above this is rejected by the schema before a Stripe session is created\n * or any rate-limit / audit-event side effects are incurred.\n */\nexport const MAX_PLEDGE_PAYMENT_AMOUNT_CENTS = 50_000_000;\n\n/**\n * Eligibility window for a user-initiated pledge refund REQUEST: 60 days from the\n * pledge, in milliseconds. Cross-boundary — the UI shows/hides the \"request refund\"\n * button by comparing `Date.now() - pledge.createdAt` against this, and the\n * requestPledgeRefund callable re-enforces it server-side before creating the request.\n */\nexport const PLEDGE_REFUND_REQUEST_WINDOW_MS = 60 * 24 * 60 * 60 * 1000;\n\n/** Longest Stripe Checkout session id the success-page lookup accepts (Stripe ids are far shorter). */\nexport const MAX_STRIPE_CHECKOUT_SESSION_ID_LENGTH = 256;\n"]}
1
+ {"version":3,"file":"business-platform.js","sourceRoot":"","sources":["../../src/constants/business-platform.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,8BAA8B;AAE9B,sBAAsB;AAEtB,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC,wFAAwF;AACxF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,uFAAuF;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,0DAA0D,CAAC;AAE3F,2BAA2B;AAE3B,4DAA4D;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC,sEAAsE;AACtE,MAAM,CAAC,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAEpD;uEACuE;AACvE,MAAM,CAAC,MAAM,iCAAiC,GAAG,IAAI,CAAC;AAEtD,mBAAmB;AAEnB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAG,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,UAAU,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExE,uGAAuG;AACvG,MAAM,CAAC,MAAM,qCAAqC,GAAG,GAAG,CAAC","sourcesContent":["// Platform-infrastructure business-rule constants — short links, Firestore\n// limits, and payment bounds.\n\n// --- Short Links ---\n\n/** The length of the generated ID for short links. */\nexport const SHORT_LINK_LENGTH = 6;\n\n/** The maximum number of attempts to generate a unique short link ID before failing. */\nexport const SHORT_LINK_MAX_ATTEMPTS = 5;\n\n/** Character set for short link IDs. Excludes ambiguous characters (0, O, l, 1, I). */\nexport const SHORT_LINK_CHARS = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';\n\n// --- Firestore Limits ---\n\n/** Maximum operations in a single Firestore write batch. */\nexport const FIRESTORE_BATCH_LIMIT = 500;\n\n/** Firestore's published limit on one document id, in UTF-8 bytes. */\nexport const FIRESTORE_DOCUMENT_ID_MAX_BYTES = 1500;\n\n/** Firestore's published limit on an indexed field value, in UTF-8 bytes: a longer value is\n * truncated in the index, so an equality query on it is not exact. */\nexport const FIRESTORE_INDEXED_VALUE_MAX_BYTES = 1500;\n\n// --- Payments ---\n\n/**\n * Minimum pledgePayment amount accepted by the Stripe checkout flow, in cents\n * (USD). $2.50 is the platform's business floor (DJ, 2026-06-11) — above\n * Stripe's 50¢ technical card-charge floor. Promoted out of the Zod schema so\n * the webhook can re-assert it server-side against the Stripe-confirmed\n * amount, independent of the client input bound. Mode-invariant by design.\n */\nexport const MIN_PLEDGE_PAYMENT_AMOUNT_CENTS = 250;\n\n/**\n * Maximum pledgePayment amount accepted by the Stripe checkout flow, in cents\n * (USD). $500,000.00. Well below Stripe's hard per-charge ceiling, but\n * high enough that legitimate large gifts pass without friction. Anything\n * above this is rejected by the schema before a Stripe session is created\n * or any rate-limit / audit-event side effects are incurred.\n */\nexport const MAX_PLEDGE_PAYMENT_AMOUNT_CENTS = 50_000_000;\n\n/**\n * Eligibility window for a user-initiated pledge refund REQUEST: 60 days from the\n * pledge, in milliseconds. Cross-boundary — the UI shows/hides the \"request refund\"\n * button by comparing `Date.now() - pledge.createdAt` against this, and the\n * requestPledgeRefund callable re-enforces it server-side before creating the request.\n */\nexport const PLEDGE_REFUND_REQUEST_WINDOW_MS = 60 * 24 * 60 * 60 * 1000;\n\n/** Longest Stripe Checkout session id the success-page lookup accepts (Stripe ids are far shorter). */\nexport const MAX_STRIPE_CHECKOUT_SESSION_ID_LENGTH = 256;\n"]}
@@ -2,8 +2,8 @@
2
2
  export declare const USERNAME_MIN_LENGTH = 3;
3
3
  /** Maximum length for a user display name (inclusive). */
4
4
  export declare const USERNAME_MAX_LENGTH = 20;
5
- /** Allowed characters in a user display name: letters and numbers only. */
6
- export declare const USERNAME_REGEX: RegExp;
5
+ /** Maximum length for the name of a theme a member builds in Theme Studio. */
6
+ export declare const MAX_THEME_NAME_LENGTH = 50;
7
7
  /**
8
8
  * Display-name sentinel for an erased account (N3 data-deletion / GDPR erasure).
9
9
  * The `publicUsers/{uid}` doc is kept (so uid→name resolvers keep working) with
@@ -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;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAI9C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAItC,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAM3C,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,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAI9C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAItC,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,8FAA8F;AAC9F,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAM3C,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"}
@@ -5,8 +5,8 @@
5
5
  export const USERNAME_MIN_LENGTH = 3;
6
6
  /** Maximum length for a user display name (inclusive). */
7
7
  export const USERNAME_MAX_LENGTH = 20;
8
- /** Allowed characters in a user display name: letters and numbers only. */
9
- export const USERNAME_REGEX = /^[a-zA-Z0-9]+$/;
8
+ /** Maximum length for the name of a theme a member builds in Theme Studio. */
9
+ export const MAX_THEME_NAME_LENGTH = 50;
10
10
  /**
11
11
  * Display-name sentinel for an erased account (N3 data-deletion / GDPR erasure).
12
12
  * The `publicUsers/{uid}` doc is kept (so uid→name resolvers keep working) with
@@ -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;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,4BAA4B;AAE5B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,mCAAmC;AAEnC,0FAA0F;AAC1F,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,uDAAuD;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,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\n// --- Account Passwords ---\n\n/**\n * Minimum length (inclusive) for a TTT account password. Counted in JavaScript\n * string length units (UTF-16 code units), consistent with HTML input length\n * behavior and the Firebase Auth SDK. Above Firebase's hard floor of 6 and within\n * the supported hosted password-policy range, which is set from this declaration.\n */\nexport const PASSWORD_MIN_LENGTH = 7;\n\n/**\n * Maximum length (inclusive) for a TTT account password, in the same UTF-16\n * code-unit units as the minimum. Long enough for passphrases and\n * password-manager output while keeping the product input finite.\n */\nexport const PASSWORD_MAX_LENGTH = 64;\n\n// --- Age from a date of birth ---\n\n/** Whole years of age at which a person may hold a (teen) account; younger is refused. */\nexport const AGE_TEEN_FLOOR_YEARS = 13;\n\n/** Whole years of age at which an account is adult. */\nexport const AGE_ADULT_FLOOR_YEARS = 18;\n\n/** The earliest birth year a date of birth may carry; an earlier year is not a real entry. */\nexport const DATE_OF_BIRTH_MIN_YEAR = 1900;\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,8EAA8E;AAC9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,4BAA4B;AAE5B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,mCAAmC;AAEnC,0FAA0F;AAC1F,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,uDAAuD;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,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/** Maximum length for the name of a theme a member builds in Theme Studio. */\nexport const MAX_THEME_NAME_LENGTH = 50;\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\n// --- Account Passwords ---\n\n/**\n * Minimum length (inclusive) for a TTT account password. Counted in JavaScript\n * string length units (UTF-16 code units), consistent with HTML input length\n * behavior and the Firebase Auth SDK. Above Firebase's hard floor of 6 and within\n * the supported hosted password-policy range, which is set from this declaration.\n */\nexport const PASSWORD_MIN_LENGTH = 7;\n\n/**\n * Maximum length (inclusive) for a TTT account password, in the same UTF-16\n * code-unit units as the minimum. Long enough for passphrases and\n * password-manager output while keeping the product input finite.\n */\nexport const PASSWORD_MAX_LENGTH = 64;\n\n// --- Age from a date of birth ---\n\n/** Whole years of age at which a person may hold a (teen) account; younger is refused. */\nexport const AGE_TEEN_FLOOR_YEARS = 13;\n\n/** Whole years of age at which an account is adult. */\nexport const AGE_ADULT_FLOOR_YEARS = 18;\n\n/** The earliest birth year a date of birth may carry; an earlier year is not a real entry. */\nexport const DATE_OF_BIRTH_MIN_YEAR = 1900;\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"]}
@@ -55,16 +55,8 @@ export declare const MAX_REALM_FILE_FOLDERS = 30;
55
55
  * this one is always a generated UUID.
56
56
  */
57
57
  export declare const MAX_REALM_FILE_SHARE_REQUEST_ID_LENGTH = 64;
58
- /** Allowed characters in titles: letters, numbers, spaces. */
59
- export declare const TITLE_PATTERN: RegExp;
60
58
  /** Maximum number of auditions a single workProject can have open at once. Mode-varied. */
61
59
  export declare const MAX_WORK_PROJECT_AUDITIONS: number;
62
- export declare const MAX_TALE_TITLE_LENGTH = 150;
63
- export declare const MAX_TALE_DESCRIPTION_LENGTH = 1000;
64
- export declare const MAX_TUNE_TITLE_LENGTH = 150;
65
- export declare const MAX_TUNE_DESCRIPTION_LENGTH = 1000;
66
- export declare const MAX_TELEVISION_TITLE_LENGTH = 150;
67
- export declare const MAX_TELEVISION_DESCRIPTION_LENGTH = 1000;
68
60
  /** Maximum number of chapters a Tale can have. Mode-varied. */
69
61
  export declare const MAX_CHAPTERS: number;
70
62
  /** Maximum length for a chapter title. */
@@ -1 +1 @@
1
- {"version":3,"file":"business-work-project.d.ts","sourceRoot":"","sources":["../../src/constants/business-work-project.ts"],"names":[],"mappings":"AAGA,oEAAoE;AACpE,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,yEAAyE;AACzE,eAAO,MAAM,cAAc,QAAyC,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAI9C,8CAA8C;AAC9C,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;uFACuF;AACvF,eAAO,MAAM,mCAAmC,OAAO,CAAC;AAOxD,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AACzE,eAAO,MAAM,iCAAiC,OAAsC,CAAC;AAErF,0DAA0D;AAC1D,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,QAA2C,CAAC;AAEzE,2EAA2E;AAC3E,eAAO,MAAM,cAAc,QAAyC,CAAC;AAErE,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,QAAoD,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sCAAsC,KAAK,CAAC;AAEzD,8DAA8D;AAC9D,eAAO,MAAM,aAAa,QAAoB,CAAC;AAE/C,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,QAAoD,CAAC;AAK5F,eAAO,MAAM,qBAAqB,MAAgC,CAAC;AACnE,eAAO,MAAM,2BAA2B,OAAsC,CAAC;AAE/E,eAAO,MAAM,qBAAqB,MAAgC,CAAC;AACnE,eAAO,MAAM,2BAA2B,OAAsC,CAAC;AAE/E,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AACzE,eAAO,MAAM,iCAAiC,OAAsC,CAAC;AAErF,+DAA+D;AAC/D,eAAO,MAAM,YAAY,QAAwC,CAAC;AAElE,0CAA0C;AAC1C,eAAO,MAAM,wBAAwB,MAAgC,CAAC;AAEtE;wFACwF;AACxF,eAAO,MAAM,0BAA0B,QAAoD,CAAC;AAE5F,qFAAqF;AACrF,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,0EAA0E;AAC1E,eAAO,MAAM,eAAe,QAA0C,CAAC;AAEvE,wCAAwC;AACxC,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AAEzE,8CAA8C;AAC9C,eAAO,MAAM,iCAAiC,OAAsC,CAAC;AAErF,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,QAAkD,CAAC;AAEvF,2CAA2C;AAC3C,eAAO,MAAM,mCAAmC,MAAgC,CAAC;AAEjF,iDAAiD;AACjD,eAAO,MAAM,yCAAyC,OAAsC,CAAC"}
1
+ {"version":3,"file":"business-work-project.d.ts","sourceRoot":"","sources":["../../src/constants/business-work-project.ts"],"names":[],"mappings":"AAGA,oEAAoE;AACpE,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,yEAAyE;AACzE,eAAO,MAAM,cAAc,QAAyC,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAI9C,8CAA8C;AAC9C,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;uFACuF;AACvF,eAAO,MAAM,mCAAmC,OAAO,CAAC;AAOxD,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AACzE,eAAO,MAAM,iCAAiC,OAAsC,CAAC;AAErF,0DAA0D;AAC1D,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,QAA2C,CAAC;AAEzE,2EAA2E;AAC3E,eAAO,MAAM,cAAc,QAAyC,CAAC;AAErE,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,QAAoD,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sCAAsC,KAAK,CAAC;AAEzD,2FAA2F;AAC3F,eAAO,MAAM,0BAA0B,QAAoD,CAAC;AAM5F,+DAA+D;AAC/D,eAAO,MAAM,YAAY,QAAwC,CAAC;AAElE,0CAA0C;AAC1C,eAAO,MAAM,wBAAwB,MAAgC,CAAC;AAEtE;wFACwF;AACxF,eAAO,MAAM,0BAA0B,QAAoD,CAAC;AAE5F,qFAAqF;AACrF,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,0EAA0E;AAC1E,eAAO,MAAM,eAAe,QAA0C,CAAC;AAEvE,wCAAwC;AACxC,eAAO,MAAM,2BAA2B,MAAgC,CAAC;AAEzE,8CAA8C;AAC9C,eAAO,MAAM,iCAAiC,OAAsC,CAAC;AAErF,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,QAAkD,CAAC;AAEvF,2CAA2C;AAC3C,eAAO,MAAM,mCAAmC,MAAgC,CAAC;AAEjF,iDAAiD;AACjD,eAAO,MAAM,yCAAyC,OAAsC,CAAC"}
@@ -62,18 +62,11 @@ export const MAX_REALM_FILE_FOLDERS = 30;
62
62
  * this one is always a generated UUID.
63
63
  */
64
64
  export const MAX_REALM_FILE_SHARE_REQUEST_ID_LENGTH = 64;
65
- /** Allowed characters in titles: letters, numbers, spaces. */
66
- export const TITLE_PATTERN = /^[a-zA-Z0-9 ]+$/;
67
65
  /** Maximum number of auditions a single workProject can have open at once. Mode-varied. */
68
66
  export const MAX_WORK_PROJECT_AUDITIONS = ACTIVE_LIMITS.workProject.maxWorkProjectAuditions;
69
- // --- WorkProject Subtypes (Tales / Tunes / Television) ---
70
- // Length aliases — kept as named exports so call sites read clearly.
71
- export const MAX_TALE_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;
72
- export const MAX_TALE_DESCRIPTION_LENGTH = MAX_WORK_PROJECT_DESCRIPTION_LENGTH;
73
- export const MAX_TUNE_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;
74
- export const MAX_TUNE_DESCRIPTION_LENGTH = MAX_WORK_PROJECT_DESCRIPTION_LENGTH;
75
- export const MAX_TELEVISION_TITLE_LENGTH = MAX_WORK_PROJECT_TITLE_LENGTH;
76
- export const MAX_TELEVISION_DESCRIPTION_LENGTH = MAX_WORK_PROJECT_DESCRIPTION_LENGTH;
67
+ // --- WorkProject sub-items (chapters / tracks / episodes) ---
68
+ // Length aliases — kept as named exports so call sites read clearly. The Tale / Tune / Television
69
+ // section itself has no text: the Work's own title and description are its text.
77
70
  /** Maximum number of chapters a Tale can have. Mode-varied. */
78
71
  export const MAX_CHAPTERS = ACTIVE_LIMITS.workProject.maxChapters;
79
72
  /** Maximum length for a chapter title. */