@ttt-productions/ttt-core 0.78.27 → 0.79.0

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 (156) hide show
  1. package/dist/capabilities/capability-registry.d.ts +2 -2
  2. package/dist/capabilities/capability-registry.d.ts.map +1 -1
  3. package/dist/capabilities/capability-registry.js +5 -5
  4. package/dist/capabilities/capability-registry.js.map +1 -1
  5. package/dist/capabilities/messaging-surfaces.d.ts.map +1 -1
  6. package/dist/capabilities/messaging-surfaces.js +7 -3
  7. package/dist/capabilities/messaging-surfaces.js.map +1 -1
  8. package/dist/constants/app-mode.d.ts +8 -8
  9. package/dist/constants/app-mode.d.ts.map +1 -1
  10. package/dist/constants/app-mode.js +17 -22
  11. package/dist/constants/app-mode.js.map +1 -1
  12. package/dist/constants/business-content.d.ts +0 -2
  13. package/dist/constants/business-content.d.ts.map +1 -1
  14. package/dist/constants/business-content.js +0 -2
  15. package/dist/constants/business-content.js.map +1 -1
  16. package/dist/constants/chat.d.ts +0 -8
  17. package/dist/constants/chat.d.ts.map +1 -1
  18. package/dist/constants/chat.js +0 -9
  19. package/dist/constants/chat.js.map +1 -1
  20. package/dist/constants/conversation-files.d.ts +7 -0
  21. package/dist/constants/conversation-files.d.ts.map +1 -0
  22. package/dist/constants/conversation-files.js +14 -0
  23. package/dist/constants/conversation-files.js.map +1 -0
  24. package/dist/constants/index.d.ts +1 -0
  25. package/dist/constants/index.d.ts.map +1 -1
  26. package/dist/constants/index.js +1 -0
  27. package/dist/constants/index.js.map +1 -1
  28. package/dist/doc-schemas/chat-sync.d.ts +0 -4
  29. package/dist/doc-schemas/chat-sync.d.ts.map +1 -1
  30. package/dist/doc-schemas/chat-sync.js +2 -9
  31. package/dist/doc-schemas/chat-sync.js.map +1 -1
  32. package/dist/doc-schemas/commissions.d.ts +2 -2
  33. package/dist/doc-schemas/media-activation-jobs.d.ts +3 -8
  34. package/dist/doc-schemas/media-activation-jobs.d.ts.map +1 -1
  35. package/dist/doc-schemas/media-assets.d.ts +22 -34
  36. package/dist/doc-schemas/media-assets.d.ts.map +1 -1
  37. package/dist/doc-schemas/media-assets.js +24 -21
  38. package/dist/doc-schemas/media-assets.js.map +1 -1
  39. package/dist/doc-schemas/messaging.d.ts +41 -20
  40. package/dist/doc-schemas/messaging.d.ts.map +1 -1
  41. package/dist/doc-schemas/messaging.js +64 -13
  42. package/dist/doc-schemas/messaging.js.map +1 -1
  43. package/dist/doc-schemas/moderation.d.ts +1 -1
  44. package/dist/doc-schemas/ncii/allegations.d.ts +21 -9
  45. package/dist/doc-schemas/ncii/allegations.d.ts.map +1 -1
  46. package/dist/doc-schemas/ncii/cases.d.ts +10 -4
  47. package/dist/doc-schemas/ncii/cases.d.ts.map +1 -1
  48. package/dist/doc-schemas/ncii/holds.d.ts +10 -4
  49. package/dist/doc-schemas/ncii/holds.d.ts.map +1 -1
  50. package/dist/doc-schemas/ncii/removal.d.ts +13 -7
  51. package/dist/doc-schemas/ncii/removal.d.ts.map +1 -1
  52. package/dist/doc-schemas/ncii/requests.d.ts +11 -5
  53. package/dist/doc-schemas/ncii/requests.d.ts.map +1 -1
  54. package/dist/doc-schemas/registry.d.ts +148 -121
  55. package/dist/doc-schemas/registry.d.ts.map +1 -1
  56. package/dist/doc-schemas/registry.js +5 -1
  57. package/dist/doc-schemas/registry.js.map +1 -1
  58. package/dist/doc-schemas/safety/case.d.ts +10 -4
  59. package/dist/doc-schemas/safety/case.d.ts.map +1 -1
  60. package/dist/doc-schemas/safety/case.js +4 -3
  61. package/dist/doc-schemas/safety/case.js.map +1 -1
  62. package/dist/doc-schemas/safety/evidence.d.ts +2 -3
  63. package/dist/doc-schemas/safety/evidence.d.ts.map +1 -1
  64. package/dist/doc-schemas/safety/foundation.d.ts +15 -8
  65. package/dist/doc-schemas/safety/foundation.d.ts.map +1 -1
  66. package/dist/doc-schemas/safety/foundation.js +32 -6
  67. package/dist/doc-schemas/safety/foundation.js.map +1 -1
  68. package/dist/doc-schemas/safety/holds.d.ts +1 -1
  69. package/dist/doc-schemas/safety/report.d.ts +25 -10
  70. package/dist/doc-schemas/safety/report.d.ts.map +1 -1
  71. package/dist/doc-schemas/safety/report.js +2 -1
  72. package/dist/doc-schemas/safety/report.js.map +1 -1
  73. package/dist/doc-schemas/work-project.d.ts +0 -1
  74. package/dist/doc-schemas/work-project.d.ts.map +1 -1
  75. package/dist/doc-schemas/work-project.js +0 -8
  76. package/dist/doc-schemas/work-project.js.map +1 -1
  77. package/dist/ids/chat-ids.d.ts +1 -2
  78. package/dist/ids/chat-ids.d.ts.map +1 -1
  79. package/dist/ids/chat-ids.js +1 -4
  80. package/dist/ids/chat-ids.js.map +1 -1
  81. package/dist/media/conversation-file-ref.d.ts +13 -0
  82. package/dist/media/conversation-file-ref.d.ts.map +1 -0
  83. package/dist/media/conversation-file-ref.js +37 -0
  84. package/dist/media/conversation-file-ref.js.map +1 -0
  85. package/dist/media/domain-events-admin.d.ts +1 -1
  86. package/dist/media/domain-events-social.d.ts +0 -7
  87. package/dist/media/domain-events-social.d.ts.map +1 -1
  88. package/dist/media/domain-events-social.js +2 -13
  89. package/dist/media/domain-events-social.js.map +1 -1
  90. package/dist/media/domain-events.d.ts +1 -7
  91. package/dist/media/domain-events.d.ts.map +1 -1
  92. package/dist/media/domain-events.js +1 -2
  93. package/dist/media/domain-events.js.map +1 -1
  94. package/dist/media/edge-serving-contract.d.ts +6 -11
  95. package/dist/media/edge-serving-contract.d.ts.map +1 -1
  96. package/dist/media/edge-serving-contract.js.map +1 -1
  97. package/dist/media/file-origin.d.ts +1 -1
  98. package/dist/media/file-origin.d.ts.map +1 -1
  99. package/dist/media/file-origin.js +6 -1
  100. package/dist/media/file-origin.js.map +1 -1
  101. package/dist/media/index.d.ts +1 -0
  102. package/dist/media/index.d.ts.map +1 -1
  103. package/dist/media/index.js +1 -0
  104. package/dist/media/index.js.map +1 -1
  105. package/dist/media/pending-media.d.ts +25 -79
  106. package/dist/media/pending-media.d.ts.map +1 -1
  107. package/dist/media/photodna-coverage.js +1 -1
  108. package/dist/media/photodna-coverage.js.map +1 -1
  109. package/dist/media/start-upload.d.ts +1 -1
  110. package/dist/media/target-info.d.ts +6 -26
  111. package/dist/media/target-info.d.ts.map +1 -1
  112. package/dist/media/target-info.js +9 -35
  113. package/dist/media/target-info.js.map +1 -1
  114. package/dist/media/ttt-media-specs.d.ts.map +1 -1
  115. package/dist/media/ttt-media-specs.js +8 -5
  116. package/dist/media/ttt-media-specs.js.map +1 -1
  117. package/dist/media/upload-tray-display.js +1 -1
  118. package/dist/media/upload-tray-display.js.map +1 -1
  119. package/dist/paths/collection-refs.d.ts +2 -0
  120. package/dist/paths/collection-refs.d.ts.map +1 -1
  121. package/dist/paths/collection-refs.js +4 -0
  122. package/dist/paths/collection-refs.js.map +1 -1
  123. package/dist/paths/collections.d.ts +1 -0
  124. package/dist/paths/collections.d.ts.map +1 -1
  125. package/dist/paths/collections.js +7 -0
  126. package/dist/paths/collections.js.map +1 -1
  127. package/dist/paths/path-builders.d.ts +2 -0
  128. package/dist/paths/path-builders.d.ts.map +1 -1
  129. package/dist/paths/path-builders.js +5 -0
  130. package/dist/paths/path-builders.js.map +1 -1
  131. package/dist/report/report-config-values.d.ts +3 -1
  132. package/dist/report/report-config-values.d.ts.map +1 -1
  133. package/dist/report/report-config-values.js +5 -1
  134. package/dist/report/report-config-values.js.map +1 -1
  135. package/dist/safety/ncii-intake-derivations.d.ts.map +1 -1
  136. package/dist/safety/ncii-intake-derivations.js +17 -5
  137. package/dist/safety/ncii-intake-derivations.js.map +1 -1
  138. package/dist/schemas/admin.d.ts +3 -0
  139. package/dist/schemas/admin.d.ts.map +1 -1
  140. package/dist/schemas/admin.js +5 -0
  141. package/dist/schemas/admin.js.map +1 -1
  142. package/dist/schemas/chat.js +3 -3
  143. package/dist/schemas/chat.js.map +1 -1
  144. package/dist/schemas/commissions.d.ts +1 -1
  145. package/dist/schemas/media.d.ts +0 -4
  146. package/dist/schemas/media.d.ts.map +1 -1
  147. package/dist/schemas/media.js +5 -10
  148. package/dist/schemas/media.js.map +1 -1
  149. package/dist/schemas/ncii.d.ts +3 -0
  150. package/dist/schemas/ncii.d.ts.map +1 -1
  151. package/dist/schemas/notification.d.ts +1 -0
  152. package/dist/schemas/notification.d.ts.map +1 -1
  153. package/dist/types/audit.d.ts +1 -1
  154. package/dist/types/audit.d.ts.map +1 -1
  155. package/dist/types/audit.js.map +1 -1
  156. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"work-project.js","sourceRoot":"","sources":["../../src/doc-schemas/work-project.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,mFAAmF;AACnF,2FAA2F;AAC3F,qFAAqF;AACrF,+DAA+D;AAC/D,EAAE;AACF,uFAAuF;AACvF,qGAAqG;AACrG,iGAAiG;AAEjG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAwB,MAAM,yBAAyB,CAAC;AAElF,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAkB,iBAAiB,CAAC,CAAC;AAC3E,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAEpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAGpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAC9C,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,MAAM,EAAE,qBAAqB;IAC7B;;;;OAIG;IACH,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE;IACvD;;;;;;;OAOG;IACH,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5C;;;;;;;;;;;;;;;;OAgBG;IACH,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE;IACvF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,MAAM,EAAE,qBAAqB;CAC9B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAC9C,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACxD,CAAC;AAGF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACzC,SAAS,EAAE,aAAa;IACxB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,qBAAqB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IACxE,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC9D,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC5D,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/C,kBAAkB,EAAE,wBAAwB,CAAC,QAAQ,EAAE;IACvD,sFAAsF;IACtF,oFAAoF;IACpF,qFAAqF;IACrF,kFAAkF;IAClF,kFAAkF;IAClF,mFAAmF;IACnF,yBAAyB;IACzB,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9C,8EAA8E;IAC9E,gFAAgF;IAChF,gFAAgF;IAChF,iFAAiF;IACjF,6EAA6E;IAC7E,8EAA8E;IAC9E,6DAA6D;IAC7D,yBAAyB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9C,oGAAoG;IACpG,kGAAkG;IAClG,gGAAgG;IAChG,yEAAyE;IACzE,uBAAuB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAGH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/C,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE;IAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC;IACpC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACzC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE;IAClC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAGH,8EAA8E;AAC9E,+EAA+E;AAC/E,iFAAiF;AACjF,mFAAmF;AACnF,sFAAsF;AACtF,wFAAwF;AACxF,+EAA+E;AAC/E,8EAA8E;AAE9E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC5B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,6EAA6E;IAC7E,4EAA4E;IAC5E,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,gFAAgF;IAChF,gFAAgF;IAChF,uBAAuB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5C,yBAAyB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9C,yBAAyB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB;;yFAEqF;IACrF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAGH,mGAAmG;AACnG,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC5B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,UAAU,EAAE,aAAa;IACzB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAGH,oFAAoF;AACpF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC3C,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC1C,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE;IACxB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE;IAClC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,+EAA+E;IAC/E,6EAA6E;IAC7E,6EAA6E;IAC7E,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE;IACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,+EAA+E;IAC/E,+EAA+E;IAC/E,6EAA6E;IAC7E,+EAA+E;IAC/E,yEAAyE;IACzE,yBAAyB;IACzB,oBAAoB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC5C,0EAA0E;IAC1E,gFAAgF;IAChF,6EAA6E;IAC7E,mDAAmD;IACnD,yBAAyB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9C,+FAA+F;IAC/F,oGAAoG;IACpG,uBAAuB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACvD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC","sourcesContent":["// WorkProject / Realm / Guild Firestore document SCHEMAS — single source of truth.\n// Covers allWorkProjects/{workProjectId}, its guildmateUsers/publicGuildmateUsers/\n// workAssets subcollections, publicWorkProjects/{workProjectId}, workRealms/{workRealmId},\n// and the guildInviteConversations invite shell. Types are inferred via z.infer so a\n// document's shape and its TypeScript type cannot drift apart.\n//\n// Terminology: the current-owner field is `workStewardUid` (locked rename from the old\n// `ownerUid`; see ttt-prod docs/design/terminology-naming-convention.md — Steward row). The original\n// creator is `foundingArtisanUid` (locked rename from the old `createdByUid`; Founding Artisan).\n\nimport { z } from 'zod';\nimport { HALL_WING_TYPE_KEYS, WORK_PROJECT_TYPE_KEYS } from '../types/content.js';\nimport { isGuildStandingId, type GuildStandingId } from '../permissions/index.js';\n\nconst guildStandingIdSchema = z.custom<GuildStandingId>(isGuildStandingId);\nconst userRefSchema = z.object({ uid: z.string() });\n\nexport const GuildmateStatusSchema = z.enum(['active', 'departed']);\nexport type GuildmateStatus = z.infer<typeof GuildmateStatusSchema>;\n\nexport const GuildmateUserSchema = z.object({\n uid: z.string(),\n guildStandings: z.array(guildStandingIdSchema),\n tradeProfessions: z.array(z.string()),\n stakeShareCount: z.number(),\n joinedAt: z.number(),\n status: GuildmateStatusSchema,\n /**\n * Holder kind for this stake entry. Absent/`'user'` = a real guildmate person.\n * `'foundingWork'` = the realm founding-Work holder (keyed by the founding\n * workProjectId, NOT a user uid).\n */\n holderType: z.enum(['user', 'foundingWork']).optional(),\n /**\n * Per-(user, workProject) monotonic INPUT-trigger version for the chat\n * channel-auth projection (chat-edge-rebuild Contract B / P3). Absent ⇒ 0.\n * Bumped atomically in the authoritative mutation on member create/reactivate,\n * departure/removal, standing change, AND trade-profession change; the\n * `workChannelsForUser` fanout keys on the POST-increment value. It NEVER\n * increments or replaces the per-pair OUTPUT `channelAuthVersion`.\n */\n guildAuthInputVersion: z.number().optional(),\n /**\n * N3 data-deletion / account-end forfeiture tombstone. Set together with\n * `status: 'departed'` when a member leaves involuntarily-of-record: their\n * stake shares STAY in the immutable 1000-split (never removed) but are\n * forfeited — the future payout engine routes a tombstone's slice to the\n * community fund and excludes it from active distribution. `departedReason`\n * distinguishes the cause; `'bannedForCause'` is reserved for the future\n * ban-forfeiture path (included now so it needs no second package publish).\n *\n * `'selfLeave'` is DIFFERENT share semantics: a PRE-PUBLISH voluntary guild\n * exit (leaveWorkProject). There the 1000-split is still fluid, so the\n * member's `stakeShareCount` is ZEROED and returned to the pool for the\n * steward to re-allocate — NOT retained as a community-fund tombstone. A\n * self-leave is impossible once `status: 'published'` (the stake-share freeze\n * blocks it), so the tombstone and the pool-return dispositions never overlap\n * in a single Work's lifecycle.\n */\n departedReason: z.enum(['voluntaryDeletion', 'bannedForCause', 'selfLeave']).optional(),\n departedAt: z.number().optional(),\n});\nexport type GuildmateUser = z.infer<typeof GuildmateUserSchema>;\n\nexport const PublicGuildmateUserSchema = z.object({\n uid: z.string(),\n tradeProfessions: z.array(z.string()),\n joinedAt: z.number(),\n status: GuildmateStatusSchema,\n});\nexport type PublicGuildmateUser = z.infer<typeof PublicGuildmateUserSchema>;\n\nexport const PendingStakeSharesSchema = z.record(\n z.string(),\n z.object({ amount: z.number(), createdAt: z.number() }),\n);\nexport type PendingStakeShares = z.infer<typeof PendingStakeSharesSchema>;\n\nexport const FullWorkProjectSchema = z.object({\n workProjectId: z.string(),\n createdOn: z.number(),\n type: z.string(),\n workingDescription: z.string(),\n workingTitle: z.string(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n createdBy: userRefSchema,\n status: z.enum(['open', 'pendingVerification', 'published', 'rejected']),\n guildmateUserIds: z.record(z.string(), z.boolean()).optional(),\n invitedUserIds: z.record(z.string(), z.boolean()).optional(),\n workRealmId: z.string(),\n realmCanonStatus: z.enum(['canon', 'nonCanon']),\n pendingStakeShares: PendingStakeSharesSchema.optional(),\n // Running total of chat-attachment STORED-OUTPUT bytes across all of this Work's chat\n // channels, checked against MAX_WORK_CHAT_ATTACHMENT_STORAGE_BYTES (charter 2 GiB /\n // full 10 GiB; DJ ruling 2026-07-25). Absent ⇒ 0 — the field is never initialized on\n // create and needs no backfill; the first finalize writes it via an increment, so\n // every pre-existing Work reads as 0 used. Maintained at asset finalize (+ stored\n // bytes) and retire (− stored bytes), with a pessimistic pre-check at startUpload.\n // Backend-only-writable.\n chatAttachmentBytesUsed: z.number().optional(),\n // Moderation \"require retitle\" remedy (work/realm report path). When an admin\n // upholds a report on an abusive public title/description, they may replace the\n // text with a generic placeholder and set this flag; the steward is prompted to\n // re-enter compliant text the next time they open the work (unpublished = direct\n // self-edit clears it; published = via the post-launch change-request flow).\n // Distinct from the `publicWorkHidden` hide (DMCA/copyright) — this keeps the\n // work visible under the placeholder. Backend-only-writable.\n moderationRetitleRequired: z.boolean().optional(),\n moderationRetitleReason: z.string().optional(),\n // Per-field extension of the retitle remedy (uniform with the Tale/Tune/Television content family):\n // which text fields ('title', 'description', …) an admin cleared to a placeholder — \"all or any\",\n // instead of the always-both retitle — and the operator's reason surfaced on the steward's edit\n // surface. Empty/absent when nothing was cleared. Backend-only-writable.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n});\nexport type FullWorkProject = z.infer<typeof FullWorkProjectSchema>;\n\n// Top-level safe signed-in-user Work shell / search projection. Server/callable-written only.\nexport const PublicWorkProjectSchema = z.object({\n workProjectId: z.string(),\n publicWorkStatus: z.enum(['draft', 'released']),\n publicWorkHidden: z.boolean(),\n workRealmId: z.string(),\n realmCanonStatus: z.enum(['canon', 'nonCanon']),\n type: z.enum(WORK_PROJECT_TYPE_KEYS),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n workingTitle: z.string(),\n workingTitle_lowercase: z.string(),\n workingDescription: z.string(),\n coverAssetId: z.string().optional(),\n workStewardUid: z.string(),\n foundingArtisanUid: z.string(),\n createdOn: z.number(),\n updatedOn: z.number(),\n});\nexport type PublicWorkProject = z.infer<typeof PublicWorkProjectSchema>;\n\n// ===========================================================================\n// Work-project FILE FOLDER system (S7) — supersedes the flat workAssets model.\n// A default folder (every active guildmate views/uploads) + custom folders whose\n// audience is controlled by TRADE PROFESSIONS, while file-system ADMINISTRATION is\n// controlled by guild standings (StewardOwner / WorkProjectManager / WorkAssetAdmin).\n// See ttt-prod docs/design/work-project-file-folders.md. Realm sharing of a file is the\n// `realmFileCanonStatus` seam on the file's mediaAssets doc (media-assets.ts).\n// ===========================================================================\n\n/** `allWorkProjects/{workProjectId}/workFileFolders/{workFileFolderId}`. */\nexport const WorkFileFolderSchema = z.object({\n workFileFolderId: z.string(),\n workProjectId: z.string(),\n name: z.string(),\n // The auto-created \"All Guildmates\" folder (view/upload open to every active\n // guildmate; delete/manage needs file-admin). Exactly one per work project.\n isDefault: z.boolean(),\n // Custom-folder access — trade-profession ids (TRADE_PROFESSION_OPTIONS). Empty\n // on the default folder; file admins always see/manage every folder regardless.\n canViewTradeProfessions: z.array(z.string()),\n canUploadTradeProfessions: z.array(z.string()),\n canDeleteTradeProfessions: z.array(z.string()),\n fileCount: z.number(),\n /** Sum of this folder's files' `sizeBytes`. Maintained alongside `fileCount`\n * (increment on upload, decrement on delete); the project-wide storage usage +\n * `MAX_WORK_FILE_STORAGE_BYTES` cap are computed by summing this across folders. */\n storageBytes: z.number(),\n createdBy: userRefSchema,\n createdAt: z.number(),\n updatedAt: z.number(),\n});\nexport type WorkFileFolder = z.infer<typeof WorkFileFolderSchema>;\n\n/** `allWorkProjects/{workProjectId}/workFileFolders/{workFileFolderId}/workFiles/{workFileId}`. */\nexport const WorkFileSchema = z.object({\n workFileId: z.string(),\n workProjectId: z.string(),\n workFileFolderId: z.string(),\n name: z.string(),\n mediaAssetId: z.string(),\n contentType: z.string(),\n sizeBytes: z.number(),\n uploadedBy: userRefSchema,\n createdAt: z.number(),\n});\nexport type WorkFile = z.infer<typeof WorkFileSchema>;\n\n// Realm source of truth and Realm search/tag surface. Server/callable-written only.\nexport const WorkRealmSchema = z.object({\n workRealmId: z.string(),\n realmType: z.enum(['public', 'standalone']),\n realmStatus: z.enum(['draft', 'released']),\n realmHidden: z.boolean(),\n workingTitle: z.string(),\n workingTitle_lowercase: z.string(),\n workingDescription: z.string(),\n // Square realm cover art (the 'realm-cover' upload origin; processor-written).\n // Optional while the realm is a DRAFT; releasing the realm REQUIRES it — the\n // realm release callable enforces presence (never required at founding, so a\n // work creation is never blocked on realm art).\n realmCoverAssetId: z.string().optional(),\n workStewardUid: z.string(),\n foundingArtisanUid: z.string(),\n foundingWorkProjectId: z.string(),\n createdOn: z.number(),\n updatedOn: z.number(),\n // MONOTONIC publish lock (R1 ruling, 2026-07-12): set true by the hall publish\n // core the first time any work in this realm publishes, and never unset — even\n // if that work later unpublishes (the realm name already went public). While\n // absent/false, realm info is direct-edit; once true, realm text changes route\n // exclusively through the change-request pipeline (surface 'workRealm').\n // Backend-only-writable.\n hasEverPublishedWork: z.boolean().optional(),\n // Moderation \"require retitle\" remedy (see FullWorkProject above) — admin\n // replaces an abusive realm title/description with a placeholder + sets this so\n // the steward must re-enter compliant text. Distinct from `realmHidden` (the\n // DMCA/copyright takedown). Backend-only-writable.\n moderationRetitleRequired: z.boolean().optional(),\n moderationRetitleReason: z.string().optional(),\n // Per-field extension of the retitle remedy (see FullWorkProject) — which realm text fields an\n // admin cleared to a placeholder (\"all or any\"), plus the operator's reason. Backend-only-writable.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n});\nexport type WorkRealm = z.infer<typeof WorkRealmSchema>;\n"]}
1
+ {"version":3,"file":"work-project.js","sourceRoot":"","sources":["../../src/doc-schemas/work-project.ts"],"names":[],"mappings":"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","sourcesContent":["// WorkProject / Realm / Guild Firestore document SCHEMAS — single source of truth.\n// Covers allWorkProjects/{workProjectId}, its guildmateUsers/publicGuildmateUsers/\n// workAssets subcollections, publicWorkProjects/{workProjectId}, workRealms/{workRealmId},\n// and the guildInviteConversations invite shell. Types are inferred via z.infer so a\n// document's shape and its TypeScript type cannot drift apart.\n//\n// Terminology: the current-owner field is `workStewardUid` (locked rename from the old\n// `ownerUid`; see ttt-prod docs/design/terminology-naming-convention.md — Steward row). The original\n// creator is `foundingArtisanUid` (locked rename from the old `createdByUid`; Founding Artisan).\n\nimport { z } from 'zod';\nimport { HALL_WING_TYPE_KEYS, WORK_PROJECT_TYPE_KEYS } from '../types/content.js';\nimport { isGuildStandingId, type GuildStandingId } from '../permissions/index.js';\n\nconst guildStandingIdSchema = z.custom<GuildStandingId>(isGuildStandingId);\nconst userRefSchema = z.object({ uid: z.string() });\n\nexport const GuildmateStatusSchema = z.enum(['active', 'departed']);\nexport type GuildmateStatus = z.infer<typeof GuildmateStatusSchema>;\n\nexport const GuildmateUserSchema = z.object({\n uid: z.string(),\n guildStandings: z.array(guildStandingIdSchema),\n tradeProfessions: z.array(z.string()),\n stakeShareCount: z.number(),\n joinedAt: z.number(),\n status: GuildmateStatusSchema,\n /**\n * Holder kind for this stake entry. Absent/`'user'` = a real guildmate person.\n * `'foundingWork'` = the realm founding-Work holder (keyed by the founding\n * workProjectId, NOT a user uid).\n */\n holderType: z.enum(['user', 'foundingWork']).optional(),\n /**\n * Per-(user, workProject) monotonic INPUT-trigger version for the chat\n * channel-auth projection (chat-edge-rebuild Contract B / P3). Absent ⇒ 0.\n * Bumped atomically in the authoritative mutation on member create/reactivate,\n * departure/removal, standing change, AND trade-profession change; the\n * `workChannelsForUser` fanout keys on the POST-increment value. It NEVER\n * increments or replaces the per-pair OUTPUT `channelAuthVersion`.\n */\n guildAuthInputVersion: z.number().optional(),\n /**\n * N3 data-deletion / account-end forfeiture tombstone. Set together with\n * `status: 'departed'` when a member leaves involuntarily-of-record: their\n * stake shares STAY in the immutable 1000-split (never removed) but are\n * forfeited — the future payout engine routes a tombstone's slice to the\n * community fund and excludes it from active distribution. `departedReason`\n * distinguishes the cause; `'bannedForCause'` is reserved for the future\n * ban-forfeiture path (included now so it needs no second package publish).\n *\n * `'selfLeave'` is DIFFERENT share semantics: a PRE-PUBLISH voluntary guild\n * exit (leaveWorkProject). There the 1000-split is still fluid, so the\n * member's `stakeShareCount` is ZEROED and returned to the pool for the\n * steward to re-allocate — NOT retained as a community-fund tombstone. A\n * self-leave is impossible once `status: 'published'` (the stake-share freeze\n * blocks it), so the tombstone and the pool-return dispositions never overlap\n * in a single Work's lifecycle.\n */\n departedReason: z.enum(['voluntaryDeletion', 'bannedForCause', 'selfLeave']).optional(),\n departedAt: z.number().optional(),\n});\nexport type GuildmateUser = z.infer<typeof GuildmateUserSchema>;\n\nexport const PublicGuildmateUserSchema = z.object({\n uid: z.string(),\n tradeProfessions: z.array(z.string()),\n joinedAt: z.number(),\n status: GuildmateStatusSchema,\n});\nexport type PublicGuildmateUser = z.infer<typeof PublicGuildmateUserSchema>;\n\nexport const PendingStakeSharesSchema = z.record(\n z.string(),\n z.object({ amount: z.number(), createdAt: z.number() }),\n);\nexport type PendingStakeShares = z.infer<typeof PendingStakeSharesSchema>;\n\nexport const FullWorkProjectSchema = z.object({\n workProjectId: z.string(),\n createdOn: z.number(),\n type: z.string(),\n workingDescription: z.string(),\n workingTitle: z.string(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n createdBy: userRefSchema,\n status: z.enum(['open', 'pendingVerification', 'published', 'rejected']),\n guildmateUserIds: z.record(z.string(), z.boolean()).optional(),\n invitedUserIds: z.record(z.string(), z.boolean()).optional(),\n workRealmId: z.string(),\n realmCanonStatus: z.enum(['canon', 'nonCanon']),\n pendingStakeShares: PendingStakeSharesSchema.optional(),\n // Moderation \"require retitle\" remedy (work/realm report path). When an admin\n // upholds a report on an abusive public title/description, they may replace the\n // text with a generic placeholder and set this flag; the steward is prompted to\n // re-enter compliant text the next time they open the work (unpublished = direct\n // self-edit clears it; published = via the post-launch change-request flow).\n // Distinct from the `publicWorkHidden` hide (DMCA/copyright) — this keeps the\n // work visible under the placeholder. Backend-only-writable.\n moderationRetitleRequired: z.boolean().optional(),\n moderationRetitleReason: z.string().optional(),\n // Per-field extension of the retitle remedy (uniform with the Tale/Tune/Television content family):\n // which text fields ('title', 'description', …) an admin cleared to a placeholder — \"all or any\",\n // instead of the always-both retitle — and the operator's reason surfaced on the steward's edit\n // surface. Empty/absent when nothing was cleared. Backend-only-writable.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n});\nexport type FullWorkProject = z.infer<typeof FullWorkProjectSchema>;\n\n// Top-level safe signed-in-user Work shell / search projection. Server/callable-written only.\nexport const PublicWorkProjectSchema = z.object({\n workProjectId: z.string(),\n publicWorkStatus: z.enum(['draft', 'released']),\n publicWorkHidden: z.boolean(),\n workRealmId: z.string(),\n realmCanonStatus: z.enum(['canon', 'nonCanon']),\n type: z.enum(WORK_PROJECT_TYPE_KEYS),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n workingTitle: z.string(),\n workingTitle_lowercase: z.string(),\n workingDescription: z.string(),\n coverAssetId: z.string().optional(),\n workStewardUid: z.string(),\n foundingArtisanUid: z.string(),\n createdOn: z.number(),\n updatedOn: z.number(),\n});\nexport type PublicWorkProject = z.infer<typeof PublicWorkProjectSchema>;\n\n// ===========================================================================\n// Work-project FILE FOLDER system (S7) — supersedes the flat workAssets model.\n// A default folder (every active guildmate views/uploads) + custom folders whose\n// audience is controlled by TRADE PROFESSIONS, while file-system ADMINISTRATION is\n// controlled by guild standings (StewardOwner / WorkProjectManager / WorkAssetAdmin).\n// See ttt-prod docs/design/work-project-file-folders.md. Realm sharing of a file is the\n// `realmFileCanonStatus` seam on the file's mediaAssets doc (media-assets.ts).\n// ===========================================================================\n\n/** `allWorkProjects/{workProjectId}/workFileFolders/{workFileFolderId}`. */\nexport const WorkFileFolderSchema = z.object({\n workFileFolderId: z.string(),\n workProjectId: z.string(),\n name: z.string(),\n // The auto-created \"All Guildmates\" folder (view/upload open to every active\n // guildmate; delete/manage needs file-admin). Exactly one per work project.\n isDefault: z.boolean(),\n // Custom-folder access — trade-profession ids (TRADE_PROFESSION_OPTIONS). Empty\n // on the default folder; file admins always see/manage every folder regardless.\n canViewTradeProfessions: z.array(z.string()),\n canUploadTradeProfessions: z.array(z.string()),\n canDeleteTradeProfessions: z.array(z.string()),\n fileCount: z.number(),\n /** Sum of this folder's files' `sizeBytes`. Maintained alongside `fileCount`\n * (increment on upload, decrement on delete); the project-wide storage usage +\n * `MAX_WORK_FILE_STORAGE_BYTES` cap are computed by summing this across folders. */\n storageBytes: z.number(),\n createdBy: userRefSchema,\n createdAt: z.number(),\n updatedAt: z.number(),\n});\nexport type WorkFileFolder = z.infer<typeof WorkFileFolderSchema>;\n\n/** `allWorkProjects/{workProjectId}/workFileFolders/{workFileFolderId}/workFiles/{workFileId}`. */\nexport const WorkFileSchema = z.object({\n workFileId: z.string(),\n workProjectId: z.string(),\n workFileFolderId: z.string(),\n name: z.string(),\n mediaAssetId: z.string(),\n contentType: z.string(),\n sizeBytes: z.number(),\n uploadedBy: userRefSchema,\n createdAt: z.number(),\n});\nexport type WorkFile = z.infer<typeof WorkFileSchema>;\n\n// Realm source of truth and Realm search/tag surface. Server/callable-written only.\nexport const WorkRealmSchema = z.object({\n workRealmId: z.string(),\n realmType: z.enum(['public', 'standalone']),\n realmStatus: z.enum(['draft', 'released']),\n realmHidden: z.boolean(),\n workingTitle: z.string(),\n workingTitle_lowercase: z.string(),\n workingDescription: z.string(),\n // Square realm cover art (the 'realm-cover' upload origin; processor-written).\n // Optional while the realm is a DRAFT; releasing the realm REQUIRES it — the\n // realm release callable enforces presence (never required at founding, so a\n // work creation is never blocked on realm art).\n realmCoverAssetId: z.string().optional(),\n workStewardUid: z.string(),\n foundingArtisanUid: z.string(),\n foundingWorkProjectId: z.string(),\n createdOn: z.number(),\n updatedOn: z.number(),\n // MONOTONIC publish lock (R1 ruling, 2026-07-12): set true by the hall publish\n // core the first time any work in this realm publishes, and never unset — even\n // if that work later unpublishes (the realm name already went public). While\n // absent/false, realm info is direct-edit; once true, realm text changes route\n // exclusively through the change-request pipeline (surface 'workRealm').\n // Backend-only-writable.\n hasEverPublishedWork: z.boolean().optional(),\n // Moderation \"require retitle\" remedy (see FullWorkProject above) — admin\n // replaces an abusive realm title/description with a placeholder + sets this so\n // the steward must re-enter compliant text. Distinct from `realmHidden` (the\n // DMCA/copyright takedown). Backend-only-writable.\n moderationRetitleRequired: z.boolean().optional(),\n moderationRetitleReason: z.string().optional(),\n // Per-field extension of the retitle remedy (see FullWorkProject) — which realm text fields an\n // admin cleared to a placeholder (\"all or any\"), plus the operator's reason. Backend-only-writable.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n});\nexport type WorkRealm = z.infer<typeof WorkRealmSchema>;\n"]}
@@ -40,9 +40,8 @@ export declare function degradedCauseId(kind: 'syncEvent' | 'fanoutJob', ref: st
40
40
  export declare function channelAuthEventId(channelKeyHash: string, uid: string, channelAuthVersion: number): Promise<string>;
41
41
  export declare function accountAccessEventId(uid: string, accountAccessVersion: number, channelKeyHash: string): Promise<string>;
42
42
  export declare function configEventId(channelKeyHash: string, configVersion: number): Promise<string>;
43
- export declare function attachmentFlipEventId(pendingMediaId: string, terminalState: string): Promise<string>;
44
43
  export declare function serverMessageEventId(threadRef: string, sourceDocId: string): Promise<string>;
45
- /** `chatMessageOutbox` commandId for invite/system messages (= attachment uses the pendingMediaId directly). */
44
+ /** `chatMessageOutbox` commandId for invite/system messages. */
46
45
  export declare function serverMessageCommandId(threadRef: string, sourceDocId: string): Promise<string>;
47
46
  export type SyncFanoutSelectorKind = 'channelMembers' | 'workChannelsForUser' | 'policyEditAffectedUsers';
48
47
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"chat-ids.d.ts","sourceRoot":"","sources":["../../src/ids/chat-ids.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-ids.d.ts","sourceRoot":"","sources":["../../src/ids/chat-ids.ts"],"names":[],"mappings":"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"}
@@ -63,13 +63,10 @@ export function accountAccessEventId(uid, accountAccessVersion, channelKeyHash)
63
63
  export function configEventId(channelKeyHash, configVersion) {
64
64
  return hash('config', channelKeyHash, configVersion);
65
65
  }
66
- export function attachmentFlipEventId(pendingMediaId, terminalState) {
67
- return hash('attachment-flip', pendingMediaId, terminalState);
68
- }
69
66
  export function serverMessageEventId(threadRef, sourceDocId) {
70
67
  return hash('server-msg', threadRef, sourceDocId);
71
68
  }
72
- /** `chatMessageOutbox` commandId for invite/system messages (= attachment uses the pendingMediaId directly). */
69
+ /** `chatMessageOutbox` commandId for invite/system messages. */
73
70
  export function serverMessageCommandId(threadRef, sourceDocId) {
74
71
  return hash('server-msg', threadRef, sourceDocId);
75
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chat-ids.js","sourceRoot":"","sources":["../../src/ids/chat-ids.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Frozen deterministic ID + eventId formulas for the chat realtime + notification\n * redesign. The durable design owners are ttt-prod\n * docs/design/chat-realtime-system.md and docs/design/notification-system.md.\n *\n * These ids are computed INDEPENDENTLY by multiple producers/consumers\n * (Cloud Functions, the chat Worker, sometimes the client) and MUST match\n * byte-for-byte, so the construction is frozen here as the single source of\n * truth. Hashing uses `@ttt-productions/edge-protocol-core`'s runtime-neutral\n * WebCrypto SHA-256 (works in Node 22, Cloudflare Workers, and browsers), so\n * every builder is async.\n */\n\nimport { sha256Hex } from '@ttt-productions/edge-protocol-core';\n\n/** ASCII unit separator — never appears in uids/doc-ids/collection names/numbers. */\nconst UNIT_SEPARATOR = '\\x1f';\n/** A null/absent part hashes as this byte (distinct from any real value). */\nconst NULL_BYTE = '\\x00';\n\nfunction encodePart(part: string | number | null | undefined): string {\n if (part === null || part === undefined) return NULL_BYTE;\n return typeof part === 'number' ? String(part) : part;\n}\n\n/**\n * Canonical collision-safe hash — every `hash(...)` in the chat/notification\n * doc set uses THIS. `domainTag` then each part, separated by `0x1F`; numbers\n * base-10; a null/absent part becomes the literal byte `0x00`. The full 64-char\n * lowercase-hex SHA-256 is the document id. Two id families can never collide\n * because their `domainTag`s differ.\n */\nexport function hash(\n domainTag: string,\n ...parts: Array<string | number | null | undefined>\n): Promise<string> {\n const input = domainTag + UNIT_SEPARATOR + parts.map(encodePart).join(UNIT_SEPARATOR);\n return sha256Hex(input);\n}\n\n// ── Channel identity ────────────────────────────────────────────────────────\n\n/** A logical chat channel — a typed tuple, NEVER a Firestore path string. */\nexport type ChannelRef =\n | { scope: 'channel'; workProjectId: string; guildChatChannelId: string }\n | { scope: 'invite'; guildInviteId: string };\n\n/** Per-scope collision-safe channel key. The raw tuple is stored alongside wherever this is a doc id. */\nexport function channelKey(ref: ChannelRef): Promise<string> {\n return ref.scope === 'channel'\n ? hash('chat-channel', ref.workProjectId, ref.guildChatChannelId)\n : hash('chat-invite', ref.guildInviteId);\n}\n\n/** Per-(channel, user) projection doc id (replaces the unsafe `{channelRef}__{uid}`). */\nexport async function authPairKey(ref: ChannelRef, uid: string): Promise<string> {\n return hash('chat-channel-auth', await channelKey(ref), uid);\n}\n\n/** Member-in-work degraded scope key (the `workChannelsForUser` selector blocks per uid×Work). */\nexport function userWorkScopeKey(uid: string, workProjectId: string): Promise<string> {\n return hash('chat-user-work', uid, workProjectId);\n}\n\n/** member-in-work degraded summary doc id. */\nexport function degradedMemberInWorkScopeKey(uid: string, workProjectId: string): Promise<string> {\n return hash('chat-degraded-user-work', uid, workProjectId);\n}\n\n/** Namespaced degraded cause id (`kind` keeps event-derived and job-derived causes from colliding). */\nexport function degradedCauseId(kind: 'syncEvent' | 'fanoutJob', ref: string): Promise<string> {\n return hash('chat-degraded-cause', kind, ref);\n}\n\n// ── chatSyncEvents eventIds ─────────────────────────────────────────────────\n\nexport function channelAuthEventId(channelKeyHash: string, uid: string, channelAuthVersion: number): Promise<string> {\n return hash('channel-auth', channelKeyHash, uid, channelAuthVersion);\n}\nexport function accountAccessEventId(uid: string, accountAccessVersion: number, channelKeyHash: string): Promise<string> {\n return hash('account-access', uid, accountAccessVersion, channelKeyHash);\n}\nexport function configEventId(channelKeyHash: string, configVersion: number): Promise<string> {\n return hash('config', channelKeyHash, configVersion);\n}\nexport function attachmentFlipEventId(pendingMediaId: string, terminalState: string): Promise<string> {\n return hash('attachment-flip', pendingMediaId, terminalState);\n}\nexport function serverMessageEventId(threadRef: string, sourceDocId: string): Promise<string> {\n return hash('server-msg', threadRef, sourceDocId);\n}\n\n/** `chatMessageOutbox` commandId for invite/system messages (= attachment uses the pendingMediaId directly). */\nexport function serverMessageCommandId(threadRef: string, sourceDocId: string): Promise<string> {\n return hash('server-msg', threadRef, sourceDocId);\n}\n\n// ── chatSyncFanoutJobs ──────────────────────────────────────────────────────\n\nexport type SyncFanoutSelectorKind = 'channelMembers' | 'workChannelsForUser' | 'policyEditAffectedUsers';\n\n/**\n * `scopeKey` = `channelKey` for channelMembers/policyEditAffectedUsers, or\n * `userWorkScopeKey(uid, workProjectId)` for workChannelsForUser. `causeVersion`\n * = the channel's post-mutation configVersion, or the user's post-mutation\n * guildAuthInputVersion respectively.\n */\nexport function chatSyncFanoutJobId(\n selectorKind: SyncFanoutSelectorKind,\n scopeKey: string,\n causeVersion: number,\n): Promise<string> {\n return hash('chat-sync-fanout', selectorKind, scopeKey, causeVersion);\n}\n\n// ── Inbox projection eventId ────────────────────────────────────────────────\n\nexport function inboxProjectionEventId(\n channelKeyHash: string,\n recipientUid: string,\n kind: string,\n sourceVersion: number,\n): Promise<string> {\n return hash('chat-inbox-event', channelKeyHash, recipientUid, kind, sourceVersion);\n}\n\n// ── Notification ledger / archive ───────────────────────────────────────────\n\n/** Delivery-ledger row id. Shared-admin occurrences pass `recipientUid = null` (hashed as `'shared'`). */\nexport function notificationDeliveryId(\n recipientUid: string | null,\n notificationType: string,\n eventId: string,\n): Promise<string> {\n return hash('notif-delivery', recipientUid ?? 'shared', notificationType, eventId);\n}\n\n/** Archive history doc id (= `archiveOccurrenceId`). */\nexport function notificationArchiveHistoryId(\n category: string,\n audienceScope: string,\n requestId: string,\n): Promise<string> {\n return hash('notification-archive', category, audienceScope, requestId);\n}\n\n/** Archive replay-vs-conflict discriminator. */\nexport function notificationArchivePayloadHash(\n activeId: string,\n observedActivityGeneration: string,\n category: string,\n audienceScope: string,\n): Promise<string> {\n return hash('notification-archive-payload', activeId, observedActivityGeneration, category, audienceScope);\n}\n\n// ── Moderation audit ids (append-only; create-if-absent) ────────────────────\n\nexport function moderationRequestedAuditId(requestId: string): Promise<string> {\n return hash('chat-moderation-requested', requestId);\n}\nexport function moderationAppliedAuditId(requestId: string, resultingMessageRevision: number): Promise<string> {\n return hash('chat-moderation-applied', requestId, resultingMessageRevision);\n}\nexport function moderationFailedAuditId(requestId: string, terminalFailureGeneration: number): Promise<string> {\n return hash('chat-moderation-failed', requestId, terminalFailureGeneration);\n}\n\n// ── History anonymization ───────────────────────────────────────────────────\n\nexport function chatAnonymizeJobId(channelDoId: string, epoch: number, anonymizedUid: string): Promise<string> {\n return hash('chat-anonymize', channelDoId, epoch, anonymizedUid);\n}\n"]}
1
+ {"version":3,"file":"chat-ids.js","sourceRoot":"","sources":["../../src/ids/chat-ids.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Frozen deterministic ID + eventId formulas for the chat realtime + notification\n * redesign. The durable design owners are ttt-prod\n * docs/design/chat-realtime-system.md and docs/design/notification-system.md.\n *\n * These ids are computed INDEPENDENTLY by multiple producers/consumers\n * (Cloud Functions, the chat Worker, sometimes the client) and MUST match\n * byte-for-byte, so the construction is frozen here as the single source of\n * truth. Hashing uses `@ttt-productions/edge-protocol-core`'s runtime-neutral\n * WebCrypto SHA-256 (works in Node 22, Cloudflare Workers, and browsers), so\n * every builder is async.\n */\n\nimport { sha256Hex } from '@ttt-productions/edge-protocol-core';\n\n/** ASCII unit separator — never appears in uids/doc-ids/collection names/numbers. */\nconst UNIT_SEPARATOR = '\\x1f';\n/** A null/absent part hashes as this byte (distinct from any real value). */\nconst NULL_BYTE = '\\x00';\n\nfunction encodePart(part: string | number | null | undefined): string {\n if (part === null || part === undefined) return NULL_BYTE;\n return typeof part === 'number' ? String(part) : part;\n}\n\n/**\n * Canonical collision-safe hash — every `hash(...)` in the chat/notification\n * doc set uses THIS. `domainTag` then each part, separated by `0x1F`; numbers\n * base-10; a null/absent part becomes the literal byte `0x00`. The full 64-char\n * lowercase-hex SHA-256 is the document id. Two id families can never collide\n * because their `domainTag`s differ.\n */\nexport function hash(\n domainTag: string,\n ...parts: Array<string | number | null | undefined>\n): Promise<string> {\n const input = domainTag + UNIT_SEPARATOR + parts.map(encodePart).join(UNIT_SEPARATOR);\n return sha256Hex(input);\n}\n\n// ── Channel identity ────────────────────────────────────────────────────────\n\n/** A logical chat channel — a typed tuple, NEVER a Firestore path string. */\nexport type ChannelRef =\n | { scope: 'channel'; workProjectId: string; guildChatChannelId: string }\n | { scope: 'invite'; guildInviteId: string };\n\n/** Per-scope collision-safe channel key. The raw tuple is stored alongside wherever this is a doc id. */\nexport function channelKey(ref: ChannelRef): Promise<string> {\n return ref.scope === 'channel'\n ? hash('chat-channel', ref.workProjectId, ref.guildChatChannelId)\n : hash('chat-invite', ref.guildInviteId);\n}\n\n/** Per-(channel, user) projection doc id (replaces the unsafe `{channelRef}__{uid}`). */\nexport async function authPairKey(ref: ChannelRef, uid: string): Promise<string> {\n return hash('chat-channel-auth', await channelKey(ref), uid);\n}\n\n/** Member-in-work degraded scope key (the `workChannelsForUser` selector blocks per uid×Work). */\nexport function userWorkScopeKey(uid: string, workProjectId: string): Promise<string> {\n return hash('chat-user-work', uid, workProjectId);\n}\n\n/** member-in-work degraded summary doc id. */\nexport function degradedMemberInWorkScopeKey(uid: string, workProjectId: string): Promise<string> {\n return hash('chat-degraded-user-work', uid, workProjectId);\n}\n\n/** Namespaced degraded cause id (`kind` keeps event-derived and job-derived causes from colliding). */\nexport function degradedCauseId(kind: 'syncEvent' | 'fanoutJob', ref: string): Promise<string> {\n return hash('chat-degraded-cause', kind, ref);\n}\n\n// ── chatSyncEvents eventIds ─────────────────────────────────────────────────\n\nexport function channelAuthEventId(channelKeyHash: string, uid: string, channelAuthVersion: number): Promise<string> {\n return hash('channel-auth', channelKeyHash, uid, channelAuthVersion);\n}\nexport function accountAccessEventId(uid: string, accountAccessVersion: number, channelKeyHash: string): Promise<string> {\n return hash('account-access', uid, accountAccessVersion, channelKeyHash);\n}\nexport function configEventId(channelKeyHash: string, configVersion: number): Promise<string> {\n return hash('config', channelKeyHash, configVersion);\n}\nexport function serverMessageEventId(threadRef: string, sourceDocId: string): Promise<string> {\n return hash('server-msg', threadRef, sourceDocId);\n}\n\n/** `chatMessageOutbox` commandId for invite/system messages. */\nexport function serverMessageCommandId(threadRef: string, sourceDocId: string): Promise<string> {\n return hash('server-msg', threadRef, sourceDocId);\n}\n\n// ── chatSyncFanoutJobs ──────────────────────────────────────────────────────\n\nexport type SyncFanoutSelectorKind = 'channelMembers' | 'workChannelsForUser' | 'policyEditAffectedUsers';\n\n/**\n * `scopeKey` = `channelKey` for channelMembers/policyEditAffectedUsers, or\n * `userWorkScopeKey(uid, workProjectId)` for workChannelsForUser. `causeVersion`\n * = the channel's post-mutation configVersion, or the user's post-mutation\n * guildAuthInputVersion respectively.\n */\nexport function chatSyncFanoutJobId(\n selectorKind: SyncFanoutSelectorKind,\n scopeKey: string,\n causeVersion: number,\n): Promise<string> {\n return hash('chat-sync-fanout', selectorKind, scopeKey, causeVersion);\n}\n\n// ── Inbox projection eventId ────────────────────────────────────────────────\n\nexport function inboxProjectionEventId(\n channelKeyHash: string,\n recipientUid: string,\n kind: string,\n sourceVersion: number,\n): Promise<string> {\n return hash('chat-inbox-event', channelKeyHash, recipientUid, kind, sourceVersion);\n}\n\n// ── Notification ledger / archive ───────────────────────────────────────────\n\n/** Delivery-ledger row id. Shared-admin occurrences pass `recipientUid = null` (hashed as `'shared'`). */\nexport function notificationDeliveryId(\n recipientUid: string | null,\n notificationType: string,\n eventId: string,\n): Promise<string> {\n return hash('notif-delivery', recipientUid ?? 'shared', notificationType, eventId);\n}\n\n/** Archive history doc id (= `archiveOccurrenceId`). */\nexport function notificationArchiveHistoryId(\n category: string,\n audienceScope: string,\n requestId: string,\n): Promise<string> {\n return hash('notification-archive', category, audienceScope, requestId);\n}\n\n/** Archive replay-vs-conflict discriminator. */\nexport function notificationArchivePayloadHash(\n activeId: string,\n observedActivityGeneration: string,\n category: string,\n audienceScope: string,\n): Promise<string> {\n return hash('notification-archive-payload', activeId, observedActivityGeneration, category, audienceScope);\n}\n\n// ── Moderation audit ids (append-only; create-if-absent) ────────────────────\n\nexport function moderationRequestedAuditId(requestId: string): Promise<string> {\n return hash('chat-moderation-requested', requestId);\n}\nexport function moderationAppliedAuditId(requestId: string, resultingMessageRevision: number): Promise<string> {\n return hash('chat-moderation-applied', requestId, resultingMessageRevision);\n}\nexport function moderationFailedAuditId(requestId: string, terminalFailureGeneration: number): Promise<string> {\n return hash('chat-moderation-failed', requestId, terminalFailureGeneration);\n}\n\n// ── History anonymization ───────────────────────────────────────────────────\n\nexport function chatAnonymizeJobId(channelDoId: string, epoch: number, anonymizedUid: string): Promise<string> {\n return hash('chat-anonymize', channelDoId, epoch, anonymizedUid);\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ export declare const ConversationFileRefSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
+ kind: z.ZodLiteral<"guildInvite">;
4
+ guildInviteId: z.ZodString;
5
+ }, z.core.$strict>, z.ZodObject<{
6
+ kind: z.ZodLiteral<"adminSupport">;
7
+ adminDispatchId: z.ZodString;
8
+ }, z.core.$strict>], "kind">;
9
+ export type ConversationFileRef = z.infer<typeof ConversationFileRefSchema>;
10
+ /** The supported conversation-scope kinds (for iteration / exhaustiveness tests). */
11
+ export declare const CONVERSATION_FILE_SCOPE_KINDS: readonly ["guildInvite", "adminSupport"];
12
+ export type ConversationFileScopeKind = ConversationFileRef['kind'];
13
+ //# sourceMappingURL=conversation-file-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-file-ref.d.ts","sourceRoot":"","sources":["../../src/media/conversation-file-ref.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,yBAAyB;;;;;;4BASpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,qFAAqF;AACrF,eAAO,MAAM,6BAA6B,0CAA2C,CAAC;AACtF,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ // ============================================================================
2
+ // ConversationFileRef — the ONE declaration of which conversation a Conversation
3
+ // File belongs to. Owned here (ttt-core) and imported by the `conversation-file`
4
+ // upload target-info schema, the conversation-file path builders' callers, and
5
+ // every backend/frontend consumer.
6
+ //
7
+ // EXACTLY TWO supported scopes (DJ ruling 2026-07-25):
8
+ // - guildInvite — a 1:1 guild-invite conversation (guildInviteConversations/{id})
9
+ // - adminSupport — an admin dispatch thread (pendingAdminDispatches/{id}); covers
10
+ // BOTH user-to-admin and Work-to-admin correspondence.
11
+ //
12
+ // Guild chat CHANNELS are deliberately EXCLUDED: guildmates share files through the
13
+ // existing Work Files feature, so a second per-channel file surface would duplicate
14
+ // it. There is no `guildChannel` member here, and there never should be — the
15
+ // contract test asserts it is rejected.
16
+ //
17
+ // Structurally these two members mirror the `guildInvite` / `adminSupport` members
18
+ // of `MediaServingScope` (doc-schemas/media-assets.ts) because a Conversation File's
19
+ // serving scope IS its conversation. They stay separate declarations because they
20
+ // answer different questions (which conversation owns the file vs. which grant may
21
+ // serve its bytes) and MediaServingScope also covers non-conversation surfaces.
22
+ // ============================================================================
23
+ import { z } from 'zod';
24
+ import { guildInviteIdSchema, adminDispatchIdSchema } from '../schemas/atoms.js';
25
+ export const ConversationFileRefSchema = z.discriminatedUnion('kind', [
26
+ z.object({
27
+ kind: z.literal('guildInvite'),
28
+ guildInviteId: guildInviteIdSchema,
29
+ }).strict(),
30
+ z.object({
31
+ kind: z.literal('adminSupport'),
32
+ adminDispatchId: adminDispatchIdSchema,
33
+ }).strict(),
34
+ ]);
35
+ /** The supported conversation-scope kinds (for iteration / exhaustiveness tests). */
36
+ export const CONVERSATION_FILE_SCOPE_KINDS = ['guildInvite', 'adminSupport'];
37
+ //# sourceMappingURL=conversation-file-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-file-ref.js","sourceRoot":"","sources":["../../src/media/conversation-file-ref.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iFAAiF;AACjF,iFAAiF;AACjF,+EAA+E;AAC/E,mCAAmC;AACnC,EAAE;AACF,uDAAuD;AACvD,sFAAsF;AACtF,qFAAqF;AACrF,2EAA2E;AAC3E,EAAE;AACF,oFAAoF;AACpF,oFAAoF;AACpF,8EAA8E;AAC9E,wCAAwC;AACxC,EAAE;AACF,mFAAmF;AACnF,qFAAqF;AACrF,kFAAkF;AAClF,mFAAmF;AACnF,gFAAgF;AAChF,+EAA+E;AAE/E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IACpE,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;QAC9B,aAAa,EAAE,mBAAmB;KACnC,CAAC,CAAC,MAAM,EAAE;IACX,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;QAC/B,eAAe,EAAE,qBAAqB;KACvC,CAAC,CAAC,MAAM,EAAE;CACZ,CAAC,CAAC;AAGH,qFAAqF;AACrF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,aAAa,EAAE,cAAc,CAAU,CAAC","sourcesContent":["// ============================================================================\n// ConversationFileRef — the ONE declaration of which conversation a Conversation\n// File belongs to. Owned here (ttt-core) and imported by the `conversation-file`\n// upload target-info schema, the conversation-file path builders' callers, and\n// every backend/frontend consumer.\n//\n// EXACTLY TWO supported scopes (DJ ruling 2026-07-25):\n// - guildInvite — a 1:1 guild-invite conversation (guildInviteConversations/{id})\n// - adminSupport — an admin dispatch thread (pendingAdminDispatches/{id}); covers\n// BOTH user-to-admin and Work-to-admin correspondence.\n//\n// Guild chat CHANNELS are deliberately EXCLUDED: guildmates share files through the\n// existing Work Files feature, so a second per-channel file surface would duplicate\n// it. There is no `guildChannel` member here, and there never should be — the\n// contract test asserts it is rejected.\n//\n// Structurally these two members mirror the `guildInvite` / `adminSupport` members\n// of `MediaServingScope` (doc-schemas/media-assets.ts) because a Conversation File's\n// serving scope IS its conversation. They stay separate declarations because they\n// answer different questions (which conversation owns the file vs. which grant may\n// serve its bytes) and MediaServingScope also covers non-conversation surfaces.\n// ============================================================================\n\nimport { z } from 'zod';\nimport { guildInviteIdSchema, adminDispatchIdSchema } from '../schemas/atoms.js';\n\nexport const ConversationFileRefSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('guildInvite'),\n guildInviteId: guildInviteIdSchema,\n }).strict(),\n z.object({\n kind: z.literal('adminSupport'),\n adminDispatchId: adminDispatchIdSchema,\n }).strict(),\n]);\nexport type ConversationFileRef = z.infer<typeof ConversationFileRefSchema>;\n\n/** The supported conversation-scope kinds (for iteration / exhaustiveness tests). */\nexport const CONVERSATION_FILE_SCOPE_KINDS = ['guildInvite', 'adminSupport'] as const;\nexport type ConversationFileScopeKind = ConversationFileRef['kind'];\n"]}
@@ -7,6 +7,7 @@ export declare const ModerationViolationCreatedEventSchema: z.ZodObject<{
7
7
  fileOrigin: z.ZodEnum<{
8
8
  "commission-proposal": "commission-proposal";
9
9
  "profile-picture": "profile-picture";
10
+ "conversation-file": "conversation-file";
10
11
  "audition-entry": "audition-entry";
11
12
  "work-asset": "work-asset";
12
13
  "craft-skill-media": "craft-skill-media";
@@ -23,7 +24,6 @@ export declare const ModerationViolationCreatedEventSchema: z.ZodObject<{
23
24
  "tune-track-audio": "tune-track-audio";
24
25
  "television-episode-photo": "television-episode-photo";
25
26
  "television-episode-video": "television-episode-video";
26
- "guild-chat-message-attachment": "guild-chat-message-attachment";
27
27
  "ncii-evidence": "ncii-evidence";
28
28
  }>;
29
29
  pendingMediaId: z.ZodString;
@@ -22,11 +22,4 @@ export declare const SquareStreetzPostUnlikedEventSchema: z.ZodObject<{
22
22
  authorId: z.ZodString;
23
23
  }, z.core.$strict>;
24
24
  }, z.core.$strict>;
25
- export declare const ChatAttachmentFinalizedEventSchema: z.ZodObject<{
26
- type: z.ZodLiteral<"chat.attachmentFinalized">;
27
- ids: z.ZodObject<{
28
- guildChatMessageId: z.ZodString;
29
- conversationId: z.ZodString;
30
- }, z.core.$strict>;
31
- }, z.core.$strict>;
32
25
  //# sourceMappingURL=domain-events-social.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain-events-social.d.ts","sourceRoot":"","sources":["../../src/media/domain-events-social.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,mCAAmC;;;;;;kBAUrC,CAAC;AAEZ,eAAO,MAAM,iCAAiC;;;;;;;kBAWnC,CAAC;AAEZ,eAAO,MAAM,mCAAmC;;;;;;;kBAWrC,CAAC;AAEZ,eAAO,MAAM,kCAAkC;;;;;;kBAUpC,CAAC"}
1
+ {"version":3,"file":"domain-events-social.d.ts","sourceRoot":"","sources":["../../src/media/domain-events-social.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,mCAAmC;;;;;;kBAUrC,CAAC;AAEZ,eAAO,MAAM,iCAAiC;;;;;;;kBAWnC,CAAC;AAEZ,eAAO,MAAM,mCAAmC;;;;;;;kBAWrC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- // DomainEvent schemas for the social domain — Square Streetz posts and chat
3
- // attachments. Assembled into the discriminated union in ./domain-events.ts.
2
+ // DomainEvent schemas for the social domain — Square Streetz posts.
3
+ // Assembled into the discriminated union in ./domain-events.ts.
4
4
  export const SquareStreetzPostCreatedEventSchema = z
5
5
  .object({
6
6
  type: z.literal('squareStreetz.postCreated'),
@@ -36,15 +36,4 @@ export const SquareStreetzPostUnlikedEventSchema = z
36
36
  .strict(),
37
37
  })
38
38
  .strict();
39
- export const ChatAttachmentFinalizedEventSchema = z
40
- .object({
41
- type: z.literal('chat.attachmentFinalized'),
42
- ids: z
43
- .object({
44
- guildChatMessageId: z.string().min(1),
45
- conversationId: z.string().min(1),
46
- })
47
- .strict(),
48
- })
49
- .strict();
50
39
  //# sourceMappingURL=domain-events-social.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain-events-social.js","sourceRoot":"","sources":["../../src/media/domain-events-social.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,4EAA4E;AAC5E,6EAA6E;AAE7E,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAC5C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC1B,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAC/C,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC;IAC1C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC5B,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAC5C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC5B,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC;KAChD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC;IAC3C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACrC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAClC,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC","sourcesContent":["import { z } from \"zod\";\n\n// DomainEvent schemas for the social domain — Square Streetz posts and chat\n// attachments. Assembled into the discriminated union in ./domain-events.ts.\n\nexport const SquareStreetzPostCreatedEventSchema = z\n .object({\n type: z.literal('squareStreetz.postCreated'),\n ids: z\n .object({\n userId: z.string().min(1),\n postId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nexport const SquareStreetzPostLikedEventSchema = z\n .object({\n type: z.literal('squareStreetz.postLiked'),\n ids: z\n .object({\n userId: z.string().min(1),\n postId: z.string().min(1),\n authorId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nexport const SquareStreetzPostUnlikedEventSchema = z\n .object({\n type: z.literal('squareStreetz.postUnliked'),\n ids: z\n .object({\n userId: z.string().min(1),\n postId: z.string().min(1),\n authorId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nexport const ChatAttachmentFinalizedEventSchema = z\n .object({\n type: z.literal('chat.attachmentFinalized'),\n ids: z\n .object({\n guildChatMessageId: z.string().min(1),\n conversationId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n"]}
1
+ {"version":3,"file":"domain-events-social.js","sourceRoot":"","sources":["../../src/media/domain-events-social.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,oEAAoE;AACpE,gEAAgE;AAEhE,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAC5C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC1B,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAC/C,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC;IAC1C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC5B,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC;KACjD,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAC5C,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC5B,CAAC;SACD,MAAM,EAAE;CACZ,CAAC;KACD,MAAM,EAAE,CAAC","sourcesContent":["import { z } from \"zod\";\n\n// DomainEvent schemas for the social domain — Square Streetz posts.\n// Assembled into the discriminated union in ./domain-events.ts.\n\nexport const SquareStreetzPostCreatedEventSchema = z\n .object({\n type: z.literal('squareStreetz.postCreated'),\n ids: z\n .object({\n userId: z.string().min(1),\n postId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nexport const SquareStreetzPostLikedEventSchema = z\n .object({\n type: z.literal('squareStreetz.postLiked'),\n ids: z\n .object({\n userId: z.string().min(1),\n postId: z.string().min(1),\n authorId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nexport const SquareStreetzPostUnlikedEventSchema = z\n .object({\n type: z.literal('squareStreetz.postUnliked'),\n ids: z\n .object({\n userId: z.string().min(1),\n postId: z.string().min(1),\n authorId: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n"]}
@@ -91,6 +91,7 @@ export declare const DomainEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
91
91
  fileOrigin: z.ZodEnum<{
92
92
  "commission-proposal": "commission-proposal";
93
93
  "profile-picture": "profile-picture";
94
+ "conversation-file": "conversation-file";
94
95
  "audition-entry": "audition-entry";
95
96
  "work-asset": "work-asset";
96
97
  "craft-skill-media": "craft-skill-media";
@@ -107,17 +108,10 @@ export declare const DomainEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
107
108
  "tune-track-audio": "tune-track-audio";
108
109
  "television-episode-photo": "television-episode-photo";
109
110
  "television-episode-video": "television-episode-video";
110
- "guild-chat-message-attachment": "guild-chat-message-attachment";
111
111
  "ncii-evidence": "ncii-evidence";
112
112
  }>;
113
113
  pendingMediaId: z.ZodString;
114
114
  }, z.core.$strict>;
115
- }, z.core.$strict>, z.ZodObject<{
116
- type: z.ZodLiteral<"chat.attachmentFinalized">;
117
- ids: z.ZodObject<{
118
- guildChatMessageId: z.ZodString;
119
- conversationId: z.ZodString;
120
- }, z.core.$strict>;
121
115
  }, z.core.$strict>, z.ZodObject<{
122
116
  type: z.ZodLiteral<"follow.created">;
123
117
  ids: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"domain-events.d.ts","sourceRoot":"","sources":["../../src/media/domain-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoDxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAgBzC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BA2C5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,IAAI,OAAO,CACpE,WAAW,EACX;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CACZ,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"domain-events.d.ts","sourceRoot":"","sources":["../../src/media/domain-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmDxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAgBzC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BA0C5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,IAAI,OAAO,CACpE,WAAW,EACX;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CACZ,CAAC,KAAK,CAAC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { ProfilePictureUpdatedEventSchema, ProfilePreferencesUpdatedEventSchema, CraftSkillCreatedEventSchema, CraftSkillUpdatedEventSchema, CraftSkillDeletedEventSchema, FollowCreatedEventSchema, FollowRemovedEventSchema, MentionReadEventSchema, AuthStatusChangedEventSchema, } from "./domain-events-user.js";
3
3
  import { WorkProjectCreatedEventSchema, WorkProjectUpdatedEventSchema, WorkProjectPublishedEventSchema, WorkProjectStakeSharesUpdatedEventSchema, GuildInviteSentEventSchema, GuildInviteAcceptedEventSchema, GuildInviteDeclinedEventSchema, GuildInviteCancelledEventSchema, AuditionPromptCreatedEventSchema, AuditionEntrySubmittedEventSchema, AuditionEntryVoteRecordedEventSchema, AuditionClosedEventSchema, CommissionCreatedEventSchema, CommissionProposalSubmittedEventSchema, CommissionDeletedEventSchema, CommissionProposalSavedEventSchema, CommissionProposalRemovedEventSchema, HallLibraryCoverUpdatedEventSchema, WorkRealmCoverUpdatedEventSchema, HallLibrarySubItemUpdatedEventSchema, ThresholdLibrarySubmittedEventSchema, } from "./domain-events-work.js";
4
- import { SquareStreetzPostCreatedEventSchema, SquareStreetzPostLikedEventSchema, SquareStreetzPostUnlikedEventSchema, ChatAttachmentFinalizedEventSchema, } from "./domain-events-social.js";
4
+ import { SquareStreetzPostCreatedEventSchema, SquareStreetzPostLikedEventSchema, SquareStreetzPostUnlikedEventSchema, } from "./domain-events-social.js";
5
5
  import { ModerationViolationCreatedEventSchema, ThresholdLibraryApprovedEventSchema, ThresholdLibraryNeedsRevisionEventSchema, AdminDispatchSystemMarkedEventSchema, AdminDispatchThreadUpdatedEventSchema, AdminAppealReviewedEventSchema, AdminDispatchReviewedEventSchema, ViolationAppealSubmittedEventSchema, } from "./domain-events-admin.js";
6
6
  export * from "./domain-events-user.js";
7
7
  export * from "./domain-events-work.js";
@@ -33,7 +33,6 @@ export const DomainEventSchema = z.discriminatedUnion('type', [
33
33
  WorkRealmCoverUpdatedEventSchema,
34
34
  HallLibrarySubItemUpdatedEventSchema,
35
35
  ModerationViolationCreatedEventSchema,
36
- ChatAttachmentFinalizedEventSchema,
37
36
  FollowCreatedEventSchema,
38
37
  FollowRemovedEventSchema,
39
38
  SquareStreetzPostLikedEventSchema,
@@ -1 +1 @@
1
- {"version":3,"file":"domain-events.js","sourceRoot":"","sources":["../../src/media/domain-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,gCAAgC,EAChC,oCAAoC,EACpC,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,+BAA+B,EAC/B,wCAAwC,EACxC,0BAA0B,EAC1B,8BAA8B,EAC9B,8BAA8B,EAC9B,+BAA+B,EAC/B,gCAAgC,EAChC,iCAAiC,EACjC,oCAAoC,EACpC,yBAAyB,EACzB,4BAA4B,EAC5B,sCAAsC,EACtC,4BAA4B,EAC5B,kCAAkC,EAClC,oCAAoC,EACpC,kCAAkC,EAClC,gCAAgC,EAChC,oCAAoC,EACpC,oCAAoC,GACrC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,mCAAmC,EACnC,iCAAiC,EACjC,mCAAmC,EACnC,kCAAkC,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,qCAAqC,EACrC,mCAAmC,EACnC,wCAAwC,EACxC,oCAAoC,EACpC,qCAAqC,EACrC,8BAA8B,EAC9B,gCAAgC,EAChC,mCAAmC,GACpC,MAAM,0BAA0B,CAAC;AAElC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAEzC,+EAA+E;AAC/E,uEAAuE;AACvE,6EAA6E;AAC7E,gEAAgE;AAChE,EAAE;AACF,gDAAgD;AAChD,0CAA0C;AAC1C,iDAAiD;AACjD,mEAAmE;AACnE,EAAE;AACF,0EAA0E;AAC1E,mEAAmE;AACnE,+EAA+E;AAE/E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC5D,gCAAgC;IAChC,4BAA4B;IAC5B,mCAAmC;IACnC,gCAAgC;IAChC,iCAAiC;IACjC,4BAA4B;IAC5B,sCAAsC;IACtC,6BAA6B;IAC7B,kCAAkC;IAClC,gCAAgC;IAChC,oCAAoC;IACpC,qCAAqC;IACrC,kCAAkC;IAClC,wBAAwB;IACxB,wBAAwB;IACxB,iCAAiC;IACjC,mCAAmC;IACnC,oCAAoC;IACpC,4BAA4B;IAC5B,4BAA4B;IAC5B,6BAA6B;IAC7B,+BAA+B;IAC/B,wCAAwC;IACxC,0BAA0B;IAC1B,8BAA8B;IAC9B,8BAA8B;IAC9B,+BAA+B;IAC/B,oCAAoC;IACpC,yBAAyB;IACzB,4BAA4B;IAC5B,kCAAkC;IAClC,oCAAoC;IACpC,oCAAoC;IACpC,mCAAmC;IACnC,wCAAwC;IACxC,oCAAoC;IACpC,qCAAqC;IACrC,8BAA8B;IAC9B,gCAAgC;IAChC,sBAAsB;IACtB,4BAA4B;IAC5B,mCAAmC;CACpC,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport {\n ProfilePictureUpdatedEventSchema,\n ProfilePreferencesUpdatedEventSchema,\n CraftSkillCreatedEventSchema,\n CraftSkillUpdatedEventSchema,\n CraftSkillDeletedEventSchema,\n FollowCreatedEventSchema,\n FollowRemovedEventSchema,\n MentionReadEventSchema,\n AuthStatusChangedEventSchema,\n} from \"./domain-events-user.js\";\nimport {\n WorkProjectCreatedEventSchema,\n WorkProjectUpdatedEventSchema,\n WorkProjectPublishedEventSchema,\n WorkProjectStakeSharesUpdatedEventSchema,\n GuildInviteSentEventSchema,\n GuildInviteAcceptedEventSchema,\n GuildInviteDeclinedEventSchema,\n GuildInviteCancelledEventSchema,\n AuditionPromptCreatedEventSchema,\n AuditionEntrySubmittedEventSchema,\n AuditionEntryVoteRecordedEventSchema,\n AuditionClosedEventSchema,\n CommissionCreatedEventSchema,\n CommissionProposalSubmittedEventSchema,\n CommissionDeletedEventSchema,\n CommissionProposalSavedEventSchema,\n CommissionProposalRemovedEventSchema,\n HallLibraryCoverUpdatedEventSchema,\n WorkRealmCoverUpdatedEventSchema,\n HallLibrarySubItemUpdatedEventSchema,\n ThresholdLibrarySubmittedEventSchema,\n} from \"./domain-events-work.js\";\nimport {\n SquareStreetzPostCreatedEventSchema,\n SquareStreetzPostLikedEventSchema,\n SquareStreetzPostUnlikedEventSchema,\n ChatAttachmentFinalizedEventSchema,\n} from \"./domain-events-social.js\";\nimport {\n ModerationViolationCreatedEventSchema,\n ThresholdLibraryApprovedEventSchema,\n ThresholdLibraryNeedsRevisionEventSchema,\n AdminDispatchSystemMarkedEventSchema,\n AdminDispatchThreadUpdatedEventSchema,\n AdminAppealReviewedEventSchema,\n AdminDispatchReviewedEventSchema,\n ViolationAppealSubmittedEventSchema,\n} from \"./domain-events-admin.js\";\n\nexport * from \"./domain-events-user.js\";\nexport * from \"./domain-events-work.js\";\nexport * from \"./domain-events-social.js\";\nexport * from \"./domain-events-admin.js\";\n\n// ============================================================================\n// DomainEvent — typed business actions emitted by mutations and upload\n// processors. The frontend registry (ttt-prod/src/lib/domain-events.ts) maps\n// each variant to a list of TanStack Query cache invalidations.\n//\n// Adding a new variant is a coordinated deploy:\n// 1. Add it here. Publish this package.\n// 2. Add a registry entry in ttt-prod. Deploy.\n// 3. Update producers (mutation hooks or processors) to emit it.\n//\n// The schema is .strict() end-to-end — unknown event types fail parse and\n// the consuming hook in ttt-prod logs to Sentry and skips the doc.\n// ============================================================================\n\nexport const DomainEventSchema = z.discriminatedUnion('type', [\n ProfilePictureUpdatedEventSchema,\n CraftSkillCreatedEventSchema,\n SquareStreetzPostCreatedEventSchema,\n AuditionPromptCreatedEventSchema,\n AuditionEntrySubmittedEventSchema,\n CommissionCreatedEventSchema,\n CommissionProposalSubmittedEventSchema,\n WorkProjectUpdatedEventSchema,\n HallLibraryCoverUpdatedEventSchema,\n WorkRealmCoverUpdatedEventSchema,\n HallLibrarySubItemUpdatedEventSchema,\n ModerationViolationCreatedEventSchema,\n ChatAttachmentFinalizedEventSchema,\n FollowCreatedEventSchema,\n FollowRemovedEventSchema,\n SquareStreetzPostLikedEventSchema,\n SquareStreetzPostUnlikedEventSchema,\n ProfilePreferencesUpdatedEventSchema,\n CraftSkillDeletedEventSchema,\n CraftSkillUpdatedEventSchema,\n WorkProjectCreatedEventSchema,\n WorkProjectPublishedEventSchema,\n WorkProjectStakeSharesUpdatedEventSchema,\n GuildInviteSentEventSchema,\n GuildInviteAcceptedEventSchema,\n GuildInviteDeclinedEventSchema,\n GuildInviteCancelledEventSchema,\n AuditionEntryVoteRecordedEventSchema,\n AuditionClosedEventSchema,\n CommissionDeletedEventSchema,\n CommissionProposalSavedEventSchema,\n CommissionProposalRemovedEventSchema,\n ThresholdLibrarySubmittedEventSchema,\n ThresholdLibraryApprovedEventSchema,\n ThresholdLibraryNeedsRevisionEventSchema,\n AdminDispatchSystemMarkedEventSchema,\n AdminDispatchThreadUpdatedEventSchema,\n AdminAppealReviewedEventSchema,\n AdminDispatchReviewedEventSchema,\n MentionReadEventSchema,\n AuthStatusChangedEventSchema,\n ViolationAppealSubmittedEventSchema,\n]);\n\nexport type DomainEvent = z.infer<typeof DomainEventSchema>;\n\n// Helper for callers that need to extract the ids type for a specific\n// event variant (e.g. registry entries in the consuming repo).\nexport type DomainEventIdsFor<T extends DomainEvent['type']> = Extract<\n DomainEvent,\n { type: T }\n>['ids'];\n\n\n\n\n\n"]}
1
+ {"version":3,"file":"domain-events.js","sourceRoot":"","sources":["../../src/media/domain-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,gCAAgC,EAChC,oCAAoC,EACpC,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,+BAA+B,EAC/B,wCAAwC,EACxC,0BAA0B,EAC1B,8BAA8B,EAC9B,8BAA8B,EAC9B,+BAA+B,EAC/B,gCAAgC,EAChC,iCAAiC,EACjC,oCAAoC,EACpC,yBAAyB,EACzB,4BAA4B,EAC5B,sCAAsC,EACtC,4BAA4B,EAC5B,kCAAkC,EAClC,oCAAoC,EACpC,kCAAkC,EAClC,gCAAgC,EAChC,oCAAoC,EACpC,oCAAoC,GACrC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,mCAAmC,EACnC,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,qCAAqC,EACrC,mCAAmC,EACnC,wCAAwC,EACxC,oCAAoC,EACpC,qCAAqC,EACrC,8BAA8B,EAC9B,gCAAgC,EAChC,mCAAmC,GACpC,MAAM,0BAA0B,CAAC;AAElC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AAEzC,+EAA+E;AAC/E,uEAAuE;AACvE,6EAA6E;AAC7E,gEAAgE;AAChE,EAAE;AACF,gDAAgD;AAChD,0CAA0C;AAC1C,iDAAiD;AACjD,mEAAmE;AACnE,EAAE;AACF,0EAA0E;AAC1E,mEAAmE;AACnE,+EAA+E;AAE/E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC5D,gCAAgC;IAChC,4BAA4B;IAC5B,mCAAmC;IACnC,gCAAgC;IAChC,iCAAiC;IACjC,4BAA4B;IAC5B,sCAAsC;IACtC,6BAA6B;IAC7B,kCAAkC;IAClC,gCAAgC;IAChC,oCAAoC;IACpC,qCAAqC;IACrC,wBAAwB;IACxB,wBAAwB;IACxB,iCAAiC;IACjC,mCAAmC;IACnC,oCAAoC;IACpC,4BAA4B;IAC5B,4BAA4B;IAC5B,6BAA6B;IAC7B,+BAA+B;IAC/B,wCAAwC;IACxC,0BAA0B;IAC1B,8BAA8B;IAC9B,8BAA8B;IAC9B,+BAA+B;IAC/B,oCAAoC;IACpC,yBAAyB;IACzB,4BAA4B;IAC5B,kCAAkC;IAClC,oCAAoC;IACpC,oCAAoC;IACpC,mCAAmC;IACnC,wCAAwC;IACxC,oCAAoC;IACpC,qCAAqC;IACrC,8BAA8B;IAC9B,gCAAgC;IAChC,sBAAsB;IACtB,4BAA4B;IAC5B,mCAAmC;CACpC,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport {\n ProfilePictureUpdatedEventSchema,\n ProfilePreferencesUpdatedEventSchema,\n CraftSkillCreatedEventSchema,\n CraftSkillUpdatedEventSchema,\n CraftSkillDeletedEventSchema,\n FollowCreatedEventSchema,\n FollowRemovedEventSchema,\n MentionReadEventSchema,\n AuthStatusChangedEventSchema,\n} from \"./domain-events-user.js\";\nimport {\n WorkProjectCreatedEventSchema,\n WorkProjectUpdatedEventSchema,\n WorkProjectPublishedEventSchema,\n WorkProjectStakeSharesUpdatedEventSchema,\n GuildInviteSentEventSchema,\n GuildInviteAcceptedEventSchema,\n GuildInviteDeclinedEventSchema,\n GuildInviteCancelledEventSchema,\n AuditionPromptCreatedEventSchema,\n AuditionEntrySubmittedEventSchema,\n AuditionEntryVoteRecordedEventSchema,\n AuditionClosedEventSchema,\n CommissionCreatedEventSchema,\n CommissionProposalSubmittedEventSchema,\n CommissionDeletedEventSchema,\n CommissionProposalSavedEventSchema,\n CommissionProposalRemovedEventSchema,\n HallLibraryCoverUpdatedEventSchema,\n WorkRealmCoverUpdatedEventSchema,\n HallLibrarySubItemUpdatedEventSchema,\n ThresholdLibrarySubmittedEventSchema,\n} from \"./domain-events-work.js\";\nimport {\n SquareStreetzPostCreatedEventSchema,\n SquareStreetzPostLikedEventSchema,\n SquareStreetzPostUnlikedEventSchema,\n} from \"./domain-events-social.js\";\nimport {\n ModerationViolationCreatedEventSchema,\n ThresholdLibraryApprovedEventSchema,\n ThresholdLibraryNeedsRevisionEventSchema,\n AdminDispatchSystemMarkedEventSchema,\n AdminDispatchThreadUpdatedEventSchema,\n AdminAppealReviewedEventSchema,\n AdminDispatchReviewedEventSchema,\n ViolationAppealSubmittedEventSchema,\n} from \"./domain-events-admin.js\";\n\nexport * from \"./domain-events-user.js\";\nexport * from \"./domain-events-work.js\";\nexport * from \"./domain-events-social.js\";\nexport * from \"./domain-events-admin.js\";\n\n// ============================================================================\n// DomainEvent — typed business actions emitted by mutations and upload\n// processors. The frontend registry (ttt-prod/src/lib/domain-events.ts) maps\n// each variant to a list of TanStack Query cache invalidations.\n//\n// Adding a new variant is a coordinated deploy:\n// 1. Add it here. Publish this package.\n// 2. Add a registry entry in ttt-prod. Deploy.\n// 3. Update producers (mutation hooks or processors) to emit it.\n//\n// The schema is .strict() end-to-end — unknown event types fail parse and\n// the consuming hook in ttt-prod logs to Sentry and skips the doc.\n// ============================================================================\n\nexport const DomainEventSchema = z.discriminatedUnion('type', [\n ProfilePictureUpdatedEventSchema,\n CraftSkillCreatedEventSchema,\n SquareStreetzPostCreatedEventSchema,\n AuditionPromptCreatedEventSchema,\n AuditionEntrySubmittedEventSchema,\n CommissionCreatedEventSchema,\n CommissionProposalSubmittedEventSchema,\n WorkProjectUpdatedEventSchema,\n HallLibraryCoverUpdatedEventSchema,\n WorkRealmCoverUpdatedEventSchema,\n HallLibrarySubItemUpdatedEventSchema,\n ModerationViolationCreatedEventSchema,\n FollowCreatedEventSchema,\n FollowRemovedEventSchema,\n SquareStreetzPostLikedEventSchema,\n SquareStreetzPostUnlikedEventSchema,\n ProfilePreferencesUpdatedEventSchema,\n CraftSkillDeletedEventSchema,\n CraftSkillUpdatedEventSchema,\n WorkProjectCreatedEventSchema,\n WorkProjectPublishedEventSchema,\n WorkProjectStakeSharesUpdatedEventSchema,\n GuildInviteSentEventSchema,\n GuildInviteAcceptedEventSchema,\n GuildInviteDeclinedEventSchema,\n GuildInviteCancelledEventSchema,\n AuditionEntryVoteRecordedEventSchema,\n AuditionClosedEventSchema,\n CommissionDeletedEventSchema,\n CommissionProposalSavedEventSchema,\n CommissionProposalRemovedEventSchema,\n ThresholdLibrarySubmittedEventSchema,\n ThresholdLibraryApprovedEventSchema,\n ThresholdLibraryNeedsRevisionEventSchema,\n AdminDispatchSystemMarkedEventSchema,\n AdminDispatchThreadUpdatedEventSchema,\n AdminAppealReviewedEventSchema,\n AdminDispatchReviewedEventSchema,\n MentionReadEventSchema,\n AuthStatusChangedEventSchema,\n ViolationAppealSubmittedEventSchema,\n]);\n\nexport type DomainEvent = z.infer<typeof DomainEventSchema>;\n\n// Helper for callers that need to extract the ids type for a specific\n// event variant (e.g. registry entries in the consuming repo).\nexport type DomainEventIdsFor<T extends DomainEvent['type']> = Extract<\n DomainEvent,\n { type: T }\n>['ids'];\n\n\n\n\n\n"]}
@@ -10,8 +10,8 @@ export interface EdgeServingRecord {
10
10
  accessTier: MediaAccessTier;
11
11
  ownerType: string;
12
12
  ownerId: string;
13
- /** Work-project scoped media (work files, pre-publish content). A chat asset
14
- * never sets this — its workProjectId lives ONLY inside the typed `scope`. */
13
+ /** Work-project scoped media (work files, pre-publish content). A conversation-file
14
+ * asset never sets this — a conversation scope carries no workProjectId. */
15
15
  workProjectId?: string;
16
16
  /** Typed scope for scoped-tier assets; absent/null for everything else. The
17
17
  * serving path EXACT-matches a grant against it. */
@@ -68,16 +68,11 @@ export interface GrantTokenPayload {
68
68
  w: string;
69
69
  f: string;
70
70
  };
71
- /** Guild-CHANNEL chat attachment scope — the SAME ids the asset's typed
72
- * `scope` carries; EXACT-matched (never a {w} Work grant cross-match). */
73
- gc?: {
74
- w: string;
75
- c: string;
76
- };
77
- /** Guild-INVITE chat attachment scope (guildInviteId). */
71
+ /** Guild-INVITE conversation scope (guildInviteId) — a Conversation File in that
72
+ * conversation; EXACT-matched (never a {w} Work grant cross-match). */
78
73
  gi?: string;
79
- /** Admin-SUPPORT thread attachment scope (adminDispatchId) — the SAME id the
80
- * asset's typed `scope` carries; EXACT-matched (one grant covers the thread). */
74
+ /** Admin-SUPPORT thread scope (adminDispatchId) — the SAME id the asset's typed
75
+ * `scope` carries; EXACT-matched (one grant covers the thread's files). */
81
76
  as?: {
82
77
  d: string;
83
78
  };
@@ -1 +1 @@
1
- {"version":3,"file":"edge-serving-contract.d.ts","sourceRoot":"","sources":["../../src/media/edge-serving-contract.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,gCAAgC,CAAC;AAExC;qCACqC;AACrC,eAAO,MAAM,0BAA0B,oCAAoC,CAAC;AAE5E;;8EAE8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,kBAAkB,CAAC;IAClC,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB;kFAC8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;wDACoD;IACpD,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED;qEACqE;AACrE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,kBAAkB,CAAC;IAClC,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,CAAC,EAAE,CAAC,CAAC;IACL,GAAG,EAAE,SAAS,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACX,gDAAgD;IAChD,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IAChC,CAAC,EAAE,CAAC,CAAC;IACL,GAAG,EAAE,OAAO,CAAC;IACb,iFAAiF;IACjF,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QACL,sDAAsD;QACtD,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,4EAA4E;QAC5E,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;QACX;oFAC4E;QAC5E,EAAE,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9B;kFAC0E;QAC1E,EAAE,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9B,0DAA0D;QAC1D,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ;yFACiF;QACjF,EAAE,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnB;;oFAE4E;QAC5E,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;CACH"}
1
+ {"version":3,"file":"edge-serving-contract.d.ts","sourceRoot":"","sources":["../../src/media/edge-serving-contract.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,gCAAgC,CAAC;AAExC;qCACqC;AACrC,eAAO,MAAM,0BAA0B,oCAAoC,CAAC;AAE5E;;8EAE8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,kBAAkB,CAAC;IAClC,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB;gFAC4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;wDACoD;IACpD,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED;qEACqE;AACrE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,kBAAkB,CAAC;IAClC,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,CAAC,EAAE,CAAC,CAAC;IACL,GAAG,EAAE,SAAS,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACX,gDAAgD;IAChD,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IAChC,CAAC,EAAE,CAAC,CAAC;IACL,GAAG,EAAE,OAAO,CAAC;IACb,iFAAiF;IACjF,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QACL,sDAAsD;QACtD,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,4EAA4E;QAC5E,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;QACX;oFAC4E;QAC5E,EAAE,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9B;+EACuE;QACvE,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ;mFAC2E;QAC3E,EAAE,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnB;;oFAE4E;QAC5E,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"edge-serving-contract.js","sourceRoot":"","sources":["../../src/media/edge-serving-contract.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iFAAiF;AACjF,+EAA+E;AAC/E,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,8EAA8E;AAC9E,yEAAyE;AACzE,+EAA+E;AAQ/E;qCACqC;AACrC,MAAM,CAAC,MAAM,0BAA0B,GAAG,iCAAiC,CAAC","sourcesContent":["// ============================================================================\n// MEDIA EDGE-SERVING CONTRACT — the ONE declaration of the wire contracts shared\n// by the backend (functions media-authority client / edge-sync / media-session\n// route / createMediaGrant) and the Cloudflare media-worker. Consolidated here\n// 2026-07-13 from the former hand-mirrored pair (media-worker/src/types.ts +\n// apply-endpoint.ts ↔ functions media-authority-client.ts / edge-sync.ts); the\n// worker's \"deliberately dependency-free\" rationale no longer holds — it already\n// imports @ttt-productions/edge-protocol-core, and these shapes are TTT media\n// business truth, so they live in ttt-core. Tier/status/scope derive from the\n// canonical doc-schemas enums — the worker never re-declares them again.\n// ============================================================================\n\nimport type {\n MediaAccessTier,\n MediaServingStatus,\n MediaServingScope,\n} from '../doc-schemas/media-assets.js';\n\n/** The signed internal apply route — one declaration; the functions client posts to\n * it and the worker routes on it. */\nexport const MEDIA_AUTHORITY_APPLY_PATH = '/internal/media-authority/apply';\n\n/** The derived edge serving record (built by functions edge-sync\n * `buildEdgeServingRecord`, stored in the shard DO + KV cache, read by the worker's\n * serving path). A projection of MediaServingAuthorityRecord — same enums. */\nexport interface EdgeServingRecord {\n servingStatus: MediaServingStatus;\n accessTier: MediaAccessTier;\n ownerType: string;\n ownerId: string;\n /** Work-project scoped media (work files, pre-publish content). A chat asset\n * never sets this — its workProjectId lives ONLY inside the typed `scope`. */\n workProjectId?: string;\n /** Typed scope for scoped-tier assets; absent/null for everything else. The\n * serving path EXACT-matches a grant against it. */\n scope?: MediaServingScope | null;\n variants: Record<string, { contentType: string; sizeBytes: number }>;\n}\n\n/** The apply endpoint's authoritative ack (the worker's MediaAuthorityApplyResult;\n * the functions client verifies the exact version + hash off it). */\nexport interface MediaAuthorityApplyAck {\n applied: boolean;\n idempotent: boolean;\n stale: boolean;\n authorityVersion: number;\n payloadHash: string;\n servingStatus: MediaServingStatus;\n kvCache: 'warmed' | 'deleted' | 'deferred';\n}\n\n/**\n * Signed-token payloads (cookie + grant). Wire format (worker token.ts /\n * edge-protocol-core signToken):\n * v1.{base64url(JSON payload)}.{base64url(HMAC-SHA256(secret, \"v1.\" + payloadB64))}\n * Timestamps are SECONDS. The app side (Next media-session route, the\n * createMediaGrant callable) signs; the worker verifies — same shapes, ONE home.\n */\nexport interface SessionTokenPayload {\n v: 1;\n typ: 'session';\n uid: string;\n /** 1 = artisan creator (unlocks the 'artisan' tier). */\n art: 0 | 1;\n /** 1 = admin (unlocks the 'adminOnly' tier). */\n adm: 0 | 1;\n iat: number;\n exp: number;\n}\n\nexport interface GrantTokenPayload {\n v: 1;\n typ: 'grant';\n /** Must equal the session cookie's uid — grants are user-bound, never bearer. */\n uid: string;\n exp: number;\n scope: {\n /** Grants every scoped asset of this work project. */\n w?: string;\n /** Or one exact owner (e.g. a commission proposal): ownerType + ownerId. */\n t?: string;\n o?: string;\n /** Work-project FILE FOLDER scope — the SAME ids the asset's typed `scope`\n * carries; EXACT-matched (a {w} Work grant never reaches a folder file). */\n wf?: { w: string; f: string };\n /** Guild-CHANNEL chat attachment scope — the SAME ids the asset's typed\n * `scope` carries; EXACT-matched (never a {w} Work grant cross-match). */\n gc?: { w: string; c: string };\n /** Guild-INVITE chat attachment scope (guildInviteId). */\n gi?: string;\n /** Admin-SUPPORT thread attachment scope (adminDispatchId) — the SAME id the\n * asset's typed `scope` carries; EXACT-matched (one grant covers the thread). */\n as?: { d: string };\n /** Admin-REVIEW reveal scope — bound to exactly ONE mediaAssetId (minted only for\n * a full/jr admin against a report group's server-derived target). EXACT-matched\n * against the REQUESTED asset id, regardless of the record's scope kind. */\n ar?: string;\n };\n}\n"]}
1
+ {"version":3,"file":"edge-serving-contract.js","sourceRoot":"","sources":["../../src/media/edge-serving-contract.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iFAAiF;AACjF,+EAA+E;AAC/E,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,8EAA8E;AAC9E,yEAAyE;AACzE,+EAA+E;AAQ/E;qCACqC;AACrC,MAAM,CAAC,MAAM,0BAA0B,GAAG,iCAAiC,CAAC","sourcesContent":["// ============================================================================\n// MEDIA EDGE-SERVING CONTRACT — the ONE declaration of the wire contracts shared\n// by the backend (functions media-authority client / edge-sync / media-session\n// route / createMediaGrant) and the Cloudflare media-worker. Consolidated here\n// 2026-07-13 from the former hand-mirrored pair (media-worker/src/types.ts +\n// apply-endpoint.ts ↔ functions media-authority-client.ts / edge-sync.ts); the\n// worker's \"deliberately dependency-free\" rationale no longer holds — it already\n// imports @ttt-productions/edge-protocol-core, and these shapes are TTT media\n// business truth, so they live in ttt-core. Tier/status/scope derive from the\n// canonical doc-schemas enums — the worker never re-declares them again.\n// ============================================================================\n\nimport type {\n MediaAccessTier,\n MediaServingStatus,\n MediaServingScope,\n} from '../doc-schemas/media-assets.js';\n\n/** The signed internal apply route — one declaration; the functions client posts to\n * it and the worker routes on it. */\nexport const MEDIA_AUTHORITY_APPLY_PATH = '/internal/media-authority/apply';\n\n/** The derived edge serving record (built by functions edge-sync\n * `buildEdgeServingRecord`, stored in the shard DO + KV cache, read by the worker's\n * serving path). A projection of MediaServingAuthorityRecord — same enums. */\nexport interface EdgeServingRecord {\n servingStatus: MediaServingStatus;\n accessTier: MediaAccessTier;\n ownerType: string;\n ownerId: string;\n /** Work-project scoped media (work files, pre-publish content). A conversation-file\n * asset never sets this — a conversation scope carries no workProjectId. */\n workProjectId?: string;\n /** Typed scope for scoped-tier assets; absent/null for everything else. The\n * serving path EXACT-matches a grant against it. */\n scope?: MediaServingScope | null;\n variants: Record<string, { contentType: string; sizeBytes: number }>;\n}\n\n/** The apply endpoint's authoritative ack (the worker's MediaAuthorityApplyResult;\n * the functions client verifies the exact version + hash off it). */\nexport interface MediaAuthorityApplyAck {\n applied: boolean;\n idempotent: boolean;\n stale: boolean;\n authorityVersion: number;\n payloadHash: string;\n servingStatus: MediaServingStatus;\n kvCache: 'warmed' | 'deleted' | 'deferred';\n}\n\n/**\n * Signed-token payloads (cookie + grant). Wire format (worker token.ts /\n * edge-protocol-core signToken):\n * v1.{base64url(JSON payload)}.{base64url(HMAC-SHA256(secret, \"v1.\" + payloadB64))}\n * Timestamps are SECONDS. The app side (Next media-session route, the\n * createMediaGrant callable) signs; the worker verifies — same shapes, ONE home.\n */\nexport interface SessionTokenPayload {\n v: 1;\n typ: 'session';\n uid: string;\n /** 1 = artisan creator (unlocks the 'artisan' tier). */\n art: 0 | 1;\n /** 1 = admin (unlocks the 'adminOnly' tier). */\n adm: 0 | 1;\n iat: number;\n exp: number;\n}\n\nexport interface GrantTokenPayload {\n v: 1;\n typ: 'grant';\n /** Must equal the session cookie's uid — grants are user-bound, never bearer. */\n uid: string;\n exp: number;\n scope: {\n /** Grants every scoped asset of this work project. */\n w?: string;\n /** Or one exact owner (e.g. a commission proposal): ownerType + ownerId. */\n t?: string;\n o?: string;\n /** Work-project FILE FOLDER scope — the SAME ids the asset's typed `scope`\n * carries; EXACT-matched (a {w} Work grant never reaches a folder file). */\n wf?: { w: string; f: string };\n /** Guild-INVITE conversation scope (guildInviteId) — a Conversation File in that\n * conversation; EXACT-matched (never a {w} Work grant cross-match). */\n gi?: string;\n /** Admin-SUPPORT thread scope (adminDispatchId) — the SAME id the asset's typed\n * `scope` carries; EXACT-matched (one grant covers the thread's files). */\n as?: { d: string };\n /** Admin-REVIEW reveal scope — bound to exactly ONE mediaAssetId (minted only for\n * a full/jr admin against a report group's server-derived target). EXACT-matched\n * against the REQUESTED asset id, regardless of the record's scope kind. */\n ar?: string;\n };\n}\n"]}
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  export declare const FileOriginSchema: z.ZodEnum<{
3
3
  "commission-proposal": "commission-proposal";
4
4
  "profile-picture": "profile-picture";
5
+ "conversation-file": "conversation-file";
5
6
  "audition-entry": "audition-entry";
6
7
  "work-asset": "work-asset";
7
8
  "craft-skill-media": "craft-skill-media";
@@ -18,7 +19,6 @@ export declare const FileOriginSchema: z.ZodEnum<{
18
19
  "tune-track-audio": "tune-track-audio";
19
20
  "television-episode-photo": "television-episode-photo";
20
21
  "television-episode-video": "television-episode-video";
21
- "guild-chat-message-attachment": "guild-chat-message-attachment";
22
22
  "ncii-evidence": "ncii-evidence";
23
23
  }>;
24
24
  export type FileOrigin = z.infer<typeof FileOriginSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"file-origin.d.ts","sourceRoot":"","sources":["../../src/media/file-origin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EA0B3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"file-origin.d.ts","sourceRoot":"","sources":["../../src/media/file-origin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EA+B3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
@@ -20,7 +20,12 @@ export const FileOriginSchema = z.enum([
20
20
  'tune-track-audio',
21
21
  'television-episode-photo',
22
22
  'television-episode-video',
23
- 'guild-chat-message-attachment',
23
+ // Conversation Files — the flat, Firestore-owned file list on a guild-INVITE
24
+ // conversation or an admin-SUPPORT dispatch thread. Replaces the removed
25
+ // `guild-chat-message-attachment` origin: files are no longer embedded in,
26
+ // sequenced with, or mutated through a chat message. Guild chat channels are
27
+ // deliberately EXCLUDED (guildmates share files through Work Files).
28
+ 'conversation-file',
24
29
  'work-asset',
25
30
  // NCII / TAKE IT DOWN evidence upload (App-Check, no login). Preserved byte-exact,
26
31
  // never transcoded, never served — lands in the admin-only nciiEvidence bucket.
@@ -1 +1 @@
1
- {"version":3,"file":"file-origin.js","sourceRoot":"","sources":["../../src/media/file-origin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IACrC,iBAAiB;IACjB,mBAAmB;IACnB,eAAe;IACf,oBAAoB;IACpB,qBAAqB;IACrB,iBAAiB;IACjB,gBAAgB;IAChB,uBAAuB;IACvB,0BAA0B;IAC1B,0BAA0B;IAC1B,6BAA6B;IAC7B,2EAA2E;IAC3E,8EAA8E;IAC9E,wEAAwE;IACxE,aAAa;IACb,eAAe;IACf,kBAAkB;IAClB,kBAAkB;IAClB,0BAA0B;IAC1B,0BAA0B;IAC1B,+BAA+B;IAC/B,YAAY;IACZ,mFAAmF;IACnF,gFAAgF;IAChF,eAAe;CAChB,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nexport const FileOriginSchema = z.enum([\n 'profile-picture',\n 'craft-skill-media',\n 'squareStreetz',\n 'commission-posting',\n 'commission-proposal',\n 'audition-prompt',\n 'audition-entry',\n 'admin-audition-prompt',\n 'hallLibrary-cover-square',\n 'hallLibrary-cover-poster',\n 'hallLibrary-cover-cinematic',\n // Realm cover art (square). Optional while a realm is a draft; REQUIRED to\n // release the realm — enforced in the realm release callable, not at founding\n // (realms are founded by a work; the image never blocks work creation).\n 'realm-cover',\n 'chapter-photo',\n 'tune-track-photo',\n 'tune-track-audio',\n 'television-episode-photo',\n 'television-episode-video',\n 'guild-chat-message-attachment',\n 'work-asset',\n // NCII / TAKE IT DOWN evidence upload (App-Check, no login). Preserved byte-exact,\n // never transcoded, never served — lands in the admin-only nciiEvidence bucket.\n 'ncii-evidence',\n]);\n\nexport type FileOrigin = z.infer<typeof FileOriginSchema>;\n\n"]}
1
+ {"version":3,"file":"file-origin.js","sourceRoot":"","sources":["../../src/media/file-origin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IACrC,iBAAiB;IACjB,mBAAmB;IACnB,eAAe;IACf,oBAAoB;IACpB,qBAAqB;IACrB,iBAAiB;IACjB,gBAAgB;IAChB,uBAAuB;IACvB,0BAA0B;IAC1B,0BAA0B;IAC1B,6BAA6B;IAC7B,2EAA2E;IAC3E,8EAA8E;IAC9E,wEAAwE;IACxE,aAAa;IACb,eAAe;IACf,kBAAkB;IAClB,kBAAkB;IAClB,0BAA0B;IAC1B,0BAA0B;IAC1B,6EAA6E;IAC7E,yEAAyE;IACzE,2EAA2E;IAC3E,6EAA6E;IAC7E,qEAAqE;IACrE,mBAAmB;IACnB,YAAY;IACZ,mFAAmF;IACnF,gFAAgF;IAChF,eAAe;CAChB,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nexport const FileOriginSchema = z.enum([\n 'profile-picture',\n 'craft-skill-media',\n 'squareStreetz',\n 'commission-posting',\n 'commission-proposal',\n 'audition-prompt',\n 'audition-entry',\n 'admin-audition-prompt',\n 'hallLibrary-cover-square',\n 'hallLibrary-cover-poster',\n 'hallLibrary-cover-cinematic',\n // Realm cover art (square). Optional while a realm is a draft; REQUIRED to\n // release the realm — enforced in the realm release callable, not at founding\n // (realms are founded by a work; the image never blocks work creation).\n 'realm-cover',\n 'chapter-photo',\n 'tune-track-photo',\n 'tune-track-audio',\n 'television-episode-photo',\n 'television-episode-video',\n // Conversation Files — the flat, Firestore-owned file list on a guild-INVITE\n // conversation or an admin-SUPPORT dispatch thread. Replaces the removed\n // `guild-chat-message-attachment` origin: files are no longer embedded in,\n // sequenced with, or mutated through a chat message. Guild chat channels are\n // deliberately EXCLUDED (guildmates share files through Work Files).\n 'conversation-file',\n 'work-asset',\n // NCII / TAKE IT DOWN evidence upload (App-Check, no login). Preserved byte-exact,\n // never transcoded, never served — lands in the admin-only nciiEvidence bucket.\n 'ncii-evidence',\n]);\n\nexport type FileOrigin = z.infer<typeof FileOriginSchema>;\n\n"]}
@@ -1,5 +1,6 @@
1
1
  export { FileOriginSchema, type FileOrigin } from "./file-origin.js";
2
2
  export { MentionSchema, MentionTypeSchema, rejectDuplicateMentionPlaceholders, type Mention, type MentionType, } from "./atoms.js";
3
+ export * from "./conversation-file-ref.js";
3
4
  export * from "./domain-events.js";
4
5
  export { TTT_MEDIA_SPECS, } from "./ttt-media-specs.js";
5
6
  export * from "./start-upload.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kCAAkC,EAClC,KAAK,OAAO,EACZ,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kCAAkC,EAClC,KAAK,OAAO,EACZ,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export { FileOriginSchema } from "./file-origin.js";
2
2
  export { MentionSchema, MentionTypeSchema, rejectDuplicateMentionPlaceholders, } from "./atoms.js";
3
+ export * from "./conversation-file-ref.js";
3
4
  export * from "./domain-events.js";
4
5
  export { TTT_MEDIA_SPECS, } from "./ttt-media-specs.js";
5
6
  export * from "./start-upload.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kCAAkC,GAGnC,MAAM,YAAY,CAAC;AACpB,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC","sourcesContent":["export { FileOriginSchema, type FileOrigin } from \"./file-origin.js\";\nexport {\n MentionSchema,\n MentionTypeSchema,\n rejectDuplicateMentionPlaceholders,\n type Mention,\n type MentionType,\n} from \"./atoms.js\";\nexport * from \"./domain-events.js\";\nexport {\n TTT_MEDIA_SPECS,\n} from \"./ttt-media-specs.js\";\nexport * from \"./start-upload.js\";\nexport * from \"./target-info.js\";\nexport * from \"./hall-library-target-fields.js\";\nexport * from \"./pending-media.js\";\nexport * from \"./upload-tray-display.js\";\nexport * from \"./media-asset-url.js\";\nexport * from \"./photodna-coverage.js\";\nexport * from \"./edge-serving-contract.js\";\n\n\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kCAAkC,GAGnC,MAAM,YAAY,CAAC;AACpB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EACL,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC","sourcesContent":["export { FileOriginSchema, type FileOrigin } from \"./file-origin.js\";\nexport {\n MentionSchema,\n MentionTypeSchema,\n rejectDuplicateMentionPlaceholders,\n type Mention,\n type MentionType,\n} from \"./atoms.js\";\nexport * from \"./conversation-file-ref.js\";\nexport * from \"./domain-events.js\";\nexport {\n TTT_MEDIA_SPECS,\n} from \"./ttt-media-specs.js\";\nexport * from \"./start-upload.js\";\nexport * from \"./target-info.js\";\nexport * from \"./hall-library-target-fields.js\";\nexport * from \"./pending-media.js\";\nexport * from \"./upload-tray-display.js\";\nexport * from \"./media-asset-url.js\";\nexport * from \"./photodna-coverage.js\";\nexport * from \"./edge-serving-contract.js\";\n\n\n"]}