@maudecode/kanvil 0.2.1 → 0.3.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 (294) hide show
  1. package/apps/server/.env.example +19 -0
  2. package/apps/server/dist/auth-JcS53IcO.mjs +12424 -0
  3. package/apps/server/dist/{config-CbNqtJEj.mjs → config-D3cAABi7.mjs} +27 -2
  4. package/apps/server/dist/index.mjs +2500 -294
  5. package/apps/server/dist/migrate.mjs +1 -1
  6. package/apps/server/dist/recover.mjs +4 -4
  7. package/apps/server/drizzle/0014_inbox_dismissal.sql +1 -0
  8. package/apps/server/drizzle/0015_notification_categories.sql +14 -0
  9. package/apps/server/drizzle/0016_ticket_resources.sql +19 -0
  10. package/apps/server/drizzle/0017_project_backgrounds.sql +3 -0
  11. package/apps/server/drizzle/0018_delivery_outbox.sql +65 -0
  12. package/apps/server/drizzle/0019_retire_push_deliveries.sql +1 -0
  13. package/apps/server/drizzle/0020_calendar_feeds.sql +16 -0
  14. package/apps/server/drizzle/0021_staged_uploads.sql +14 -0
  15. package/apps/server/drizzle/0022_manual_order.sql +6 -0
  16. package/apps/server/drizzle/0023_workspace_invitations.sql +22 -0
  17. package/apps/server/drizzle/0024_workflow_states.sql +39 -0
  18. package/apps/server/drizzle/0025_workspace_labels.sql +10 -0
  19. package/apps/server/drizzle/0026_public_read.sql +1 -0
  20. package/apps/server/drizzle/0027_custom_fields.sql +16 -0
  21. package/apps/server/drizzle/0028_project_lifecycle.sql +11 -0
  22. package/apps/server/drizzle/0029_ticket_relocation.sql +16 -0
  23. package/apps/server/drizzle/0030_repository_connections.sql +39 -0
  24. package/apps/server/drizzle/0031_repository_providers.sql +3 -0
  25. package/apps/server/drizzle/0032_workspace_ownership.sql +11 -0
  26. package/apps/server/drizzle/0033_import_runs.sql +38 -0
  27. package/apps/server/drizzle/0034_issue_sync.sql +38 -0
  28. package/apps/server/drizzle/0035_account_deletion.sql +9 -0
  29. package/apps/server/drizzle/0036_workspace_roles.sql +16 -0
  30. package/apps/server/drizzle/0037_email_code_owner.sql +14 -0
  31. package/apps/server/drizzle/meta/0014_snapshot.json +4246 -0
  32. package/apps/server/drizzle/meta/0015_snapshot.json +4297 -0
  33. package/apps/server/drizzle/meta/0016_snapshot.json +4443 -0
  34. package/apps/server/drizzle/meta/0017_snapshot.json +4468 -0
  35. package/apps/server/drizzle/meta/0018_snapshot.json +4948 -0
  36. package/apps/server/drizzle/meta/0019_snapshot.json +4826 -0
  37. package/apps/server/drizzle/meta/0020_snapshot.json +4947 -0
  38. package/apps/server/drizzle/meta/0021_snapshot.json +5059 -0
  39. package/apps/server/drizzle/meta/0022_snapshot.json +5094 -0
  40. package/apps/server/drizzle/meta/0023_snapshot.json +5267 -0
  41. package/apps/server/drizzle/meta/0024_snapshot.json +5405 -0
  42. package/apps/server/drizzle/meta/0025_snapshot.json +5474 -0
  43. package/apps/server/drizzle/meta/0026_snapshot.json +5481 -0
  44. package/apps/server/drizzle/meta/0027_snapshot.json +5605 -0
  45. package/apps/server/drizzle/meta/0028_snapshot.json +5699 -0
  46. package/apps/server/drizzle/meta/0029_snapshot.json +5809 -0
  47. package/apps/server/drizzle/meta/0030_snapshot.json +6066 -0
  48. package/apps/server/drizzle/meta/0031_snapshot.json +6074 -0
  49. package/apps/server/drizzle/meta/0032_snapshot.json +6100 -0
  50. package/apps/server/drizzle/meta/0033_snapshot.json +6406 -0
  51. package/apps/server/drizzle/meta/0034_snapshot.json +6698 -0
  52. package/apps/server/drizzle/meta/0035_snapshot.json +6704 -0
  53. package/apps/server/drizzle/meta/0036_snapshot.json +6825 -0
  54. package/apps/server/drizzle/meta/0037_snapshot.json +6825 -0
  55. package/apps/server/drizzle/meta/_journal.json +168 -0
  56. package/apps/web/dist/assets/CompositeItem-BbuEp99X.js +1 -0
  57. package/apps/web/dist/assets/Trans-DJGH63s1.js +1 -0
  58. package/apps/web/dist/assets/abnfDiagram-WEYOIA3C-DTOx8N4B.js +1 -0
  59. package/apps/web/dist/assets/admin-settings-CJG9PMKR.js +1 -0
  60. package/apps/web/dist/assets/arc-Y1ARJVZ4.js +1 -0
  61. package/apps/web/dist/assets/architecture-WOLXFQ4H-DlC3p5z3.js +1 -0
  62. package/apps/web/dist/assets/architectureDiagram-ZHVYKT53-DooN3Z58.js +36 -0
  63. package/apps/web/dist/assets/archive-restore-B6_SsOIP.js +1 -0
  64. package/apps/web/dist/assets/array-BifhSqXX.js +1 -0
  65. package/apps/web/dist/assets/az-AZ-BtrlbgjS.js +1 -0
  66. package/apps/web/dist/assets/az-D-kj4lmf.js +1 -0
  67. package/apps/web/dist/assets/az-DqY__MpS.js +1 -0
  68. package/apps/web/dist/assets/blockDiagram-RJAE7QA3-CD5AgY4U.js +140 -0
  69. package/apps/web/dist/assets/c4Diagram-XDPPPE54-CTDOcLuN.js +38 -0
  70. package/apps/web/dist/assets/channel-BhHvU4I-.js +1 -0
  71. package/apps/web/dist/assets/chunk-2E7WHVMD-D9qnBqTV.js +88 -0
  72. package/apps/web/dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  73. package/apps/web/dist/assets/chunk-4EMNKR2T-Kz5JiJ85.js +1 -0
  74. package/apps/web/dist/assets/chunk-55XCU76K-DnKiFpYM.js +1 -0
  75. package/apps/web/dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  76. package/apps/web/dist/assets/chunk-7S6XSTFO-CpdNd6Ke.js +2 -0
  77. package/apps/web/dist/assets/chunk-AQDTSKZB-CpyuSWt8.js +72 -0
  78. package/apps/web/dist/assets/chunk-DSNLSHJZ-DTC3y9rb.js +129 -0
  79. package/apps/web/dist/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
  80. package/apps/web/dist/assets/chunk-HAGFOTED-Bv8PrMYK.js +62 -0
  81. package/apps/web/dist/assets/chunk-HNE4Q36P-CDDJ_yRa.js +1 -0
  82. package/apps/web/dist/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
  83. package/apps/web/dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  84. package/apps/web/dist/assets/chunk-NGNAAXSQ-C2Wy9Xmz.js +136 -0
  85. package/apps/web/dist/assets/chunk-NQOKRVIF-lNtnsWHS.js +213 -0
  86. package/apps/web/dist/assets/chunk-UHW7PFBP-D79ptlTN.js +1 -0
  87. package/apps/web/dist/assets/chunk-VQ5W62QI-B8hWFCiM.js +1 -0
  88. package/apps/web/dist/assets/chunk-WQQL4CDK-DAGuWzS3.js +10 -0
  89. package/apps/web/dist/assets/chunk-XXDRQBXY-CnbRkih_.js +1 -0
  90. package/apps/web/dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  91. package/apps/web/dist/assets/chunk-YZO67HFG-C0ptzlKO.js +1 -0
  92. package/apps/web/dist/assets/chunk-ZAUX2LTX-ah8U5xoJ.js +1 -0
  93. package/apps/web/dist/assets/chunk-ZCHMQSOR-DYqATOIZ.js +2 -0
  94. package/apps/web/dist/assets/classDiagram-v2-4MYWR3UA-DYytA-ua.js +217 -0
  95. package/apps/web/dist/assets/core-jXc03Sty.js +1 -0
  96. package/apps/web/dist/assets/corner-left-up-DA7MG5uX.js +1 -0
  97. package/apps/web/dist/assets/cose-bilkent-JH36ORCC-lWVj4msc.js +1 -0
  98. package/apps/web/dist/assets/cynefin-EF2NZ3EQ-Xy6e6m1E.js +1 -0
  99. package/apps/web/dist/assets/cynefinDiagram-WF24UDRP-BYarZJSm.js +62 -0
  100. package/apps/web/dist/assets/cytoscape.esm-BegBNzOV.js +321 -0
  101. package/apps/web/dist/assets/dagre-NK4GIZVX-WLvvUY1o.js +4 -0
  102. package/apps/web/dist/assets/de-DAv77-wP.js +1 -0
  103. package/apps/web/dist/assets/de-DE-Bu_Ko2QA.js +1 -0
  104. package/apps/web/dist/assets/de-UHreLwyV.js +1 -0
  105. package/apps/web/dist/assets/default-D5TdIZQS.js +56 -0
  106. package/apps/web/dist/assets/defaultLocale-BFoDCU3G.js +1 -0
  107. package/apps/web/dist/assets/delivery-settings-BE5MW8U0.js +1 -0
  108. package/apps/web/dist/assets/diagram-CBK3MWTC-D6PtxkLg.js +24 -0
  109. package/apps/web/dist/assets/diagram-I5XIIV2D-DTOKQwIY.js +24 -0
  110. package/apps/web/dist/assets/diagram-ODIL2UCW-BmERt0Xu.js +30 -0
  111. package/apps/web/dist/assets/diagram-PFBEJUXE-WDUe08eD.js +3 -0
  112. package/apps/web/dist/assets/diagram-RJA3I4VV-B2K-NLGG.js +41 -0
  113. package/apps/web/dist/assets/diagram-TYUNFSNR-BLf7PpV7.js +200 -0
  114. package/apps/web/dist/assets/dist-CumnGVmJ.js +1 -0
  115. package/apps/web/dist/assets/ebnfDiagram-V4P3TTPT-DwBUQs9p.js +1 -0
  116. package/apps/web/dist/assets/el-D2ypddWn.js +1 -0
  117. package/apps/web/dist/assets/el-EJnrsyVr.js +1 -0
  118. package/apps/web/dist/assets/el-GR-CpKEps47.js +1 -0
  119. package/apps/web/dist/assets/elk-QONTBCTQ-AuT8PinL.js +27 -0
  120. package/apps/web/dist/assets/ellipsis-D6154JKs.js +1 -0
  121. package/apps/web/dist/assets/en-EnSRisMz.js +1 -0
  122. package/apps/web/dist/assets/en-US-DKYSujv3.js +1 -0
  123. package/apps/web/dist/assets/erDiagram-KYQIGQAA-h--u4Eo6.js +99 -0
  124. package/apps/web/dist/assets/es-B_49BMhR.js +1 -0
  125. package/apps/web/dist/assets/es-D2ScuV-5.js +1 -0
  126. package/apps/web/dist/assets/es-ES-DVkfi7H-.js +1 -0
  127. package/apps/web/dist/assets/eventmodeling-K75KTNOO-CW4hDt1j.js +1 -0
  128. package/apps/web/dist/assets/flowDiagram-IUGLLWBU-BGUscnNP.js +1 -0
  129. package/apps/web/dist/assets/forms-BcD6Wwyv.js +1 -0
  130. package/apps/web/dist/assets/fr-B-WmPGZD.js +1 -0
  131. package/apps/web/dist/assets/fr-C_VpS8u6.js +1 -0
  132. package/apps/web/dist/assets/fr-FR-DkHaEHqi.js +1 -0
  133. package/apps/web/dist/assets/ganttDiagram-R7GPNTJY-CB3lsQvj.js +292 -0
  134. package/apps/web/dist/assets/gitGraph-VSP46ZUC-Hu-kvdCR.js +1 -0
  135. package/apps/web/dist/assets/gitGraphDiagram-PDYL7XHY-DCuY3C1Q.js +106 -0
  136. package/apps/web/dist/assets/graphlib-DS17s2tU.js +1 -0
  137. package/apps/web/dist/assets/hi-CW4rdp_m.js +1 -0
  138. package/apps/web/dist/assets/hi-DvoDcUpL.js +1 -0
  139. package/apps/web/dist/assets/hi-IN-CbUDNSTK.js +1 -0
  140. package/apps/web/dist/assets/highlight-CMydIf9M.js +5 -0
  141. package/apps/web/dist/assets/id-CPASBZ2r.js +1 -0
  142. package/apps/web/dist/assets/id-CvL3yBVr.js +1 -0
  143. package/apps/web/dist/assets/id-ID-DLTkxt2j.js +1 -0
  144. package/apps/web/dist/assets/index-DoqlyejP.js +17 -0
  145. package/apps/web/dist/assets/index-DyQNFS69.css +2 -0
  146. package/apps/web/dist/assets/info-OHQRW6UA-Cc8VwTsk.js +1 -0
  147. package/apps/web/dist/assets/infoDiagram-MVDRKAX5-KIMOx55J.js +2 -0
  148. package/apps/web/dist/assets/init-C-OQMol4.js +1 -0
  149. package/apps/web/dist/assets/invitations-BmpelTJu.js +1 -0
  150. package/apps/web/dist/assets/isSameWeek-2ftYGvBT.js +1 -0
  151. package/apps/web/dist/assets/ishikawaDiagram-HPEHV2GE-CAou726L.js +70 -0
  152. package/apps/web/dist/assets/it-Cd7u97Jd.js +1 -0
  153. package/apps/web/dist/assets/it-DOLotXOj.js +1 -0
  154. package/apps/web/dist/assets/it-IT-CIzq0YwC.js +1 -0
  155. package/apps/web/dist/assets/item-Cq_ZbivE.js +1 -0
  156. package/apps/web/dist/assets/ja-B1iJt9qB.js +1 -0
  157. package/apps/web/dist/assets/ja-JP-CIE4-D-v.js +1 -0
  158. package/apps/web/dist/assets/ja-LkOrjegp.js +1 -0
  159. package/apps/web/dist/assets/journeyDiagram-BOSHW7O7-YbJuPYDH.js +139 -0
  160. package/apps/web/dist/assets/kanban-definition-FNSA4HC5-nuRnm9y8.js +89 -0
  161. package/apps/web/dist/assets/katex-B_JcIwqj.js +257 -0
  162. package/apps/web/dist/assets/ko-DPpXw683.js +1 -0
  163. package/apps/web/dist/assets/ko-KR-DYP5Zae6.js +1 -0
  164. package/apps/web/dist/assets/ko-fmUq1-8W.js +1 -0
  165. package/apps/web/dist/assets/label-settings-B3LsJxhk.js +1 -0
  166. package/apps/web/dist/assets/line-WsxZYwZr.js +1 -0
  167. package/apps/web/dist/assets/linear-C9iwaMOi.js +1 -0
  168. package/apps/web/dist/assets/lucide-DIlszs-T.js +1 -0
  169. package/apps/web/dist/assets/markdown-blocks-Bw26pRKB.js +2 -0
  170. package/apps/web/dist/assets/member-directory-CHKUw0u4.js +1 -0
  171. package/apps/web/dist/assets/mermaid-parser.core-B5c-1CnP.js +7 -0
  172. package/apps/web/dist/assets/mermaid.core-vGVkgzA3.js +44 -0
  173. package/apps/web/dist/assets/mindmap-definition-6OY57UG3-uooJyUak.js +98 -0
  174. package/apps/web/dist/assets/mk-CkaQRpqe.js +1 -0
  175. package/apps/web/dist/assets/mk-LWVrR-T-.js +1 -0
  176. package/apps/web/dist/assets/mk-MK-CpOo5Bd8.js +1 -0
  177. package/apps/web/dist/assets/nl-DiEjqOA8.js +1 -0
  178. package/apps/web/dist/assets/nl-NL-Mu8G8RON.js +1 -0
  179. package/apps/web/dist/assets/nl-ro6hbqo5.js +1 -0
  180. package/apps/web/dist/assets/ordinal-BDEzSJ7C.js +1 -0
  181. package/apps/web/dist/assets/packet-JDAUHWVQ-WJpqlH1d.js +1 -0
  182. package/apps/web/dist/assets/path-fybaL0A-.js +1 -0
  183. package/apps/web/dist/assets/pegDiagram-ECIUJNBX-CUvajD93.js +1 -0
  184. package/apps/web/dist/assets/pie-XZMESJXO-DvandPby.js +1 -0
  185. package/apps/web/dist/assets/pieDiagram-GNMPY74T-CqxeyIaP.js +39 -0
  186. package/apps/web/dist/assets/pl-Bx_fYLKY.js +1 -0
  187. package/apps/web/dist/assets/pl-CauoMfkf.js +1 -0
  188. package/apps/web/dist/assets/pl-PL-DGuxe2Aq.js +1 -0
  189. package/apps/web/dist/assets/preload-helper-BLdHbfdN.js +1 -0
  190. package/apps/web/dist/assets/project-lifecycle-Ba7iRF3u.js +1 -0
  191. package/apps/web/dist/assets/project-settings-CtOWgEam.js +1 -0
  192. package/apps/web/dist/assets/pt-BR-BpOhwoDW.js +1 -0
  193. package/apps/web/dist/assets/pt-BR-D-a7F5zJ.js +1 -0
  194. package/apps/web/dist/assets/pt-BR-DwkMPgq1.js +1 -0
  195. package/apps/web/dist/assets/public-project-CHRjhFIn.js +1 -0
  196. package/apps/web/dist/assets/quadrantDiagram-D57K4MC3-DFjNmaZc.js +7 -0
  197. package/apps/web/dist/assets/radar-ABXABTNO-CJhZF9j2.js +1 -0
  198. package/apps/web/dist/assets/railroad-I3PHUGI6-DZC10oBD.js +1 -0
  199. package/apps/web/dist/assets/railroad-abnf-LNEFI6M7-BUJF2n6u.js +1 -0
  200. package/apps/web/dist/assets/railroad-ebnf-DWYD2UWJ-CG7oB02K.js +1 -0
  201. package/apps/web/dist/assets/railroad-peg-JR7BVNR7-DBCZuZJY.js +1 -0
  202. package/apps/web/dist/assets/railroadDiagram-Y72NRBL7-CvN3poBq.js +1 -0
  203. package/apps/web/dist/assets/requirementDiagram-EQYSW5RA-BEItNirc.js +84 -0
  204. package/apps/web/dist/assets/rolldown-runtime-COiEfhsA.js +1 -0
  205. package/apps/web/dist/assets/rotate-ccw-Bm0ESNH_.js +1 -0
  206. package/apps/web/dist/assets/rough.esm-Dy-Kn_BL.js +1 -0
  207. package/apps/web/dist/assets/ru-D-WIMI5_.js +1 -0
  208. package/apps/web/dist/assets/ru-DOaRp00B.js +1 -0
  209. package/apps/web/dist/assets/ru-RU-DrXnqZbV.js +1 -0
  210. package/apps/web/dist/assets/sankeyDiagram-SY24JHO5-DluLIjax.js +40 -0
  211. package/apps/web/dist/assets/search-D94SZwrC.js +85 -0
  212. package/apps/web/dist/assets/send-D9TETK3s.js +1 -0
  213. package/apps/web/dist/assets/sequenceDiagram-BLEHNHQU-ZcwnsNxK.js +169 -0
  214. package/apps/web/dist/assets/settings-Dd9EVxua.js +1 -0
  215. package/apps/web/dist/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
  216. package/apps/web/dist/assets/sliders-horizontal-CiZZFL1o.js +1 -0
  217. package/apps/web/dist/assets/src-BWF7jMDv.js +1 -0
  218. package/apps/web/dist/assets/stateDiagram-v2-A6IESKWZ-DD6vH3rM.js +291 -0
  219. package/apps/web/dist/assets/swimlanes-B3ENRKFQ-pX_qyO4X.js +1 -0
  220. package/apps/web/dist/assets/swimlanesDiagram-AYQRV4AK-CeVsLUsg.js +8 -0
  221. package/apps/web/dist/assets/switch-B_u8n1o6.js +1 -0
  222. package/apps/web/dist/assets/table-DcCLC7fi.js +1 -0
  223. package/apps/web/dist/assets/ticket-detail-C9egaVSf.js +2 -0
  224. package/apps/web/dist/assets/ticket-editor-UlSZgpWF.js +2 -0
  225. package/apps/web/dist/assets/ticket-list-controls-BidzkMOD.js +1 -0
  226. package/apps/web/dist/assets/ticket-list-vNBO8mkk.js +5 -0
  227. package/apps/web/dist/assets/timeline-definition-JXYKGLGB-DLBjAxKq.js +120 -0
  228. package/apps/web/dist/assets/toDate-B3HYxwtT.js +1 -0
  229. package/apps/web/dist/assets/tr-BZEJyY-F.js +1 -0
  230. package/apps/web/dist/assets/tr-DeYojjLx.js +1 -0
  231. package/apps/web/dist/assets/tr-TR-B92YeFW5.js +1 -0
  232. package/apps/web/dist/assets/treeView-D4JQ5SDB-DsJ44q_q.js +1 -0
  233. package/apps/web/dist/assets/treemap-SAJKECNS-BmXoBpVL.js +1 -0
  234. package/apps/web/dist/assets/uk-DACrfgCP.js +1 -0
  235. package/apps/web/dist/assets/uk-UA-DmcDs-MU.js +1 -0
  236. package/apps/web/dist/assets/uk-f8X5q5C_.js +1 -0
  237. package/apps/web/dist/assets/upload-CGpna3R2.js +1 -0
  238. package/apps/web/dist/assets/useQueries-BihXYrAP.js +1 -0
  239. package/apps/web/dist/assets/usecaseDiagram-WPOLBNNX-eU2tr2si.js +328 -0
  240. package/apps/web/dist/assets/vennDiagram-Q3Y3IDCW-CoVTWGNg.js +34 -0
  241. package/apps/web/dist/assets/vi-CSGaJFlR.js +1 -0
  242. package/apps/web/dist/assets/vi-CkqUo4w_.js +1 -0
  243. package/apps/web/dist/assets/vi-VN-DM5JYNuP.js +1 -0
  244. package/apps/web/dist/assets/visual-editor-B6HiiLMg.js +208 -0
  245. package/apps/web/dist/assets/wardley-7MLQ67FV-C6mVVk98.js +1 -0
  246. package/apps/web/dist/assets/wardleyDiagram-IVAIDKWA-m3CeJc7a.js +78 -0
  247. package/apps/web/dist/assets/workspace-settings-CSvVqaL6.js +1 -0
  248. package/apps/web/dist/assets/xychartDiagram-4URNHDU4-Dw6fLaip.js +7 -0
  249. package/apps/web/dist/assets/zh-CN-BdRcimyZ.js +1 -0
  250. package/apps/web/dist/assets/zh-CN-CC7ghLLr.js +1 -0
  251. package/apps/web/dist/assets/zh-CN-CiUOkQXe.js +1 -0
  252. package/apps/web/dist/assets/zh-TW-BH1L9tOt.js +1 -0
  253. package/apps/web/dist/assets/zh-TW-BlIRMi1C.js +1 -0
  254. package/apps/web/dist/assets/zh-TW-Co4UBSfi.js +1 -0
  255. package/apps/web/dist/index.html +14 -8
  256. package/compose.yml +12 -0
  257. package/docs/api.md +285 -10
  258. package/docs/infrastructure.md +2 -2
  259. package/docs/localization.md +25 -0
  260. package/docs/plan.md +28 -10
  261. package/docs/self-hosting.md +44 -5
  262. package/docs/themes.md +1 -1
  263. package/docs/verification.md +1 -1
  264. package/docs/workspaces.md +18 -2
  265. package/package.json +12 -8
  266. package/apps/server/dist/auth-I1XEr0d4.mjs +0 -2931
  267. package/apps/web/dist/assets/CompositeItem-BWPJ5Mol.js +0 -1
  268. package/apps/web/dist/assets/admin-settings-DZqkC6ju.js +0 -1
  269. package/apps/web/dist/assets/date-picker-6H_iwP6t.js +0 -1
  270. package/apps/web/dist/assets/ellipsis-BT172Uvu.js +0 -1
  271. package/apps/web/dist/assets/forms-B4Vg3CPz.js +0 -92
  272. package/apps/web/dist/assets/image-edit-trigger-DGmVtWLC.js +0 -1
  273. package/apps/web/dist/assets/index-C_a21taR.js +0 -50
  274. package/apps/web/dist/assets/index-DM-D_3Sv.css +0 -2
  275. package/apps/web/dist/assets/kbd-tTQGZxaK.js +0 -1
  276. package/apps/web/dist/assets/link-DoIP9KJ6.js +0 -2
  277. package/apps/web/dist/assets/list-order-Bzsrihyr.js +0 -1
  278. package/apps/web/dist/assets/lucide-U995NW8E.js +0 -1
  279. package/apps/web/dist/assets/member-directory-BiCE8DRq.js +0 -1
  280. package/apps/web/dist/assets/popover-BhzZ0U1d.js +0 -1
  281. package/apps/web/dist/assets/project-label-provider-9L7Uts3_.js +0 -1
  282. package/apps/web/dist/assets/project-settings-Q7Q9Reec.js +0 -1
  283. package/apps/web/dist/assets/rotate-ccw-sjyLwLLy.js +0 -1
  284. package/apps/web/dist/assets/settings-B6qD6q1J.js +0 -1
  285. package/apps/web/dist/assets/settings-layout-B-AwUIMu.js +0 -1
  286. package/apps/web/dist/assets/switch-D0nFHj6l.js +0 -1
  287. package/apps/web/dist/assets/table-CYZiwo9g.js +0 -1
  288. package/apps/web/dist/assets/ticket-detail-B-3vbHSB.js +0 -2
  289. package/apps/web/dist/assets/ticket-editor-C3d8TZIT.js +0 -1
  290. package/apps/web/dist/assets/ticket-list-LtGGOnwN.js +0 -5
  291. package/apps/web/dist/assets/ticket-tags-2rdmkcJV.js +0 -1
  292. package/apps/web/dist/assets/upload-DXPRzAaa.js +0 -1
  293. package/apps/web/dist/assets/useNavigate-DFohfUD3.js +0 -1
  294. package/apps/web/dist/assets/workspace-settings-D3tCm1vH.js +0 -1
@@ -1,4 +1,4 @@
1
- import { d as createDatabase, t as readConfig } from "./config-CbNqtJEj.mjs";
1
+ import { d as createDatabase, t as readConfig } from "./config-D3cAABi7.mjs";
2
2
  import { t as migrateDatabase } from "./migrate-C9f4ozB4.mjs";
3
3
  //#region src/cli/migrate.ts
4
4
  const database = createDatabase(readConfig().DATABASE_URL);
@@ -1,6 +1,6 @@
1
- import { d as createDatabase, f as account, g as user, h as session, t as readConfig } from "./config-CbNqtJEj.mjs";
2
- import { C as instanceSettings, R as hasAdminRole, a as fail, t as createAuth } from "./auth-I1XEr0d4.mjs";
3
- import { and, eq, sql } from "drizzle-orm";
1
+ import { b as user, d as createDatabase, f as account, t as readConfig, y as session } from "./config-D3cAABi7.mjs";
2
+ import { W as instanceSettings, ct as hasAdminRole, f as fail, t as createAuth } from "./auth-JcS53IcO.mjs";
3
+ import { and, eq, isNull, sql } from "drizzle-orm";
4
4
  import { z } from "zod";
5
5
  import { parseArgs } from "node:util";
6
6
  import passwordPrompt from "@inquirer/password";
@@ -13,7 +13,7 @@ async function recoverLocalPassword(database, config, email, password, enablePas
13
13
  const hash = await (await createAuth(database, config).$context).password.hash(password);
14
14
  return database.db.transaction(async (tx) => {
15
15
  await tx.execute(sql`SELECT pg_advisory_xact_lock(7361083)`);
16
- const identity = (await tx.select().from(user).where(eq(user.email, normalizedEmail)).for("update"))[0];
16
+ const identity = (await tx.select().from(user).where(and(eq(user.email, normalizedEmail), isNull(user.deletedAt))).for("update"))[0];
17
17
  if (!identity) fail(404, "not_found", "No account has this email address");
18
18
  if (enablePasswordSignIn) {
19
19
  if (!hasAdminRole(identity.role) || identity.banned) fail(403, "forbidden", "Recover an active administrator to enable password sign-in");
@@ -0,0 +1 @@
1
+ ALTER TABLE "notifications" ADD COLUMN "dismissed_at" timestamp with time zone;
@@ -0,0 +1,14 @@
1
+ ALTER TABLE "events" ALTER COLUMN "actor_id" DROP NOT NULL;--> statement-breakpoint
2
+ ALTER TABLE "notification_preferences" ADD COLUMN "categories" jsonb DEFAULT '{}'::jsonb NOT NULL;--> statement-breakpoint
3
+ ALTER TABLE "notification_preferences" ADD COLUMN "reminder_amount" integer DEFAULT 1 NOT NULL;--> statement-breakpoint
4
+ ALTER TABLE "notification_preferences" ADD COLUMN "reminder_unit" text DEFAULT 'days' NOT NULL;--> statement-breakpoint
5
+ ALTER TABLE "notifications" ADD COLUMN "category" text DEFAULT 'update' NOT NULL;--> statement-breakpoint
6
+ ALTER TABLE "notifications" ADD COLUMN "reminder_key" text;--> statement-breakpoint
7
+ ALTER TABLE "notifications" ADD CONSTRAINT "notification_event_user" UNIQUE("event_id","user_id");--> statement-breakpoint
8
+ ALTER TABLE "notifications" ADD CONSTRAINT "notification_reminder" UNIQUE("user_id","reminder_key");--> statement-breakpoint
9
+ UPDATE "notifications" SET "category" = CASE
10
+ WHEN "events"."type" LIKE 'comment.%' THEN 'comment'
11
+ WHEN "events"."type" = 'ticket.updated' AND "events"."data"->'changedFields' ? 'assigneeId' THEN 'assignment'
12
+ WHEN "events"."type" = 'ticket.updated' AND "events"."data"->'changedFields' ? 'status' THEN 'status'
13
+ ELSE 'update' END
14
+ FROM "events" WHERE "events"."id" = "notifications"."event_id";
@@ -0,0 +1,19 @@
1
+ CREATE TABLE "resources" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "project_id" uuid NOT NULL,
4
+ "ticket_id" uuid NOT NULL,
5
+ "actor_id" text NOT NULL,
6
+ "url" text NOT NULL,
7
+ "title" text DEFAULT '' NOT NULL,
8
+ "provider" text,
9
+ "remote_state" text,
10
+ "remote_checked_at" timestamp with time zone,
11
+ "version" integer DEFAULT 1 NOT NULL,
12
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
13
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ ALTER TABLE "resources" ADD CONSTRAINT "resources_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
17
+ ALTER TABLE "resources" ADD CONSTRAINT "resources_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
18
+ ALTER TABLE "resources" ADD CONSTRAINT "resources_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
19
+ CREATE INDEX "resource_ticket" ON "resources" USING btree ("ticket_id");
@@ -0,0 +1,3 @@
1
+ ALTER TABLE "projects" ADD COLUMN "background" text;--> statement-breakpoint
2
+ ALTER TABLE "projects" ADD COLUMN "background_object_id" uuid;--> statement-breakpoint
3
+ ALTER TABLE "projects" ADD CONSTRAINT "projects_background_object_id_blob_objects_id_fk" FOREIGN KEY ("background_object_id") REFERENCES "public"."blob_objects"("id") ON DELETE no action ON UPDATE no action;
@@ -0,0 +1,65 @@
1
+ CREATE TABLE "deliveries" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "notification_id" uuid,
4
+ "event_id" bigint,
5
+ "device_id" uuid,
6
+ "channel_id" uuid,
7
+ "destination_id" uuid,
8
+ "attempts" integer DEFAULT 0 NOT NULL,
9
+ "available_at" timestamp with time zone DEFAULT now() NOT NULL,
10
+ "receipt_id" text,
11
+ "finished_at" timestamp with time zone,
12
+ "error" text,
13
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
14
+ CONSTRAINT "delivery_device" UNIQUE("notification_id","device_id"),
15
+ CONSTRAINT "delivery_channel" UNIQUE("notification_id","channel_id"),
16
+ CONSTRAINT "delivery_destination" UNIQUE("event_id","destination_id"),
17
+ CONSTRAINT "delivery_one_target" CHECK (num_nonnulls("deliveries"."device_id", "deliveries"."channel_id", "deliveries"."destination_id") = 1)
18
+ );
19
+ --> statement-breakpoint
20
+ CREATE TABLE "notification_channels" (
21
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
22
+ "user_id" text NOT NULL,
23
+ "kind" text NOT NULL,
24
+ "name" text NOT NULL,
25
+ "settings" text NOT NULL,
26
+ "paused" boolean DEFAULT false NOT NULL,
27
+ "routes" jsonb DEFAULT '[]'::jsonb NOT NULL,
28
+ "version" integer DEFAULT 1 NOT NULL,
29
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
30
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
31
+ "last_attempt_at" timestamp with time zone,
32
+ "last_success_at" timestamp with time zone,
33
+ "last_error" text
34
+ );
35
+ --> statement-breakpoint
36
+ CREATE TABLE "project_destinations" (
37
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
38
+ "project_id" uuid NOT NULL,
39
+ "kind" text NOT NULL,
40
+ "name" text NOT NULL,
41
+ "settings" text NOT NULL,
42
+ "paused" boolean DEFAULT false NOT NULL,
43
+ "events" text[] DEFAULT '{}' NOT NULL,
44
+ "created_by" text,
45
+ "version" integer DEFAULT 1 NOT NULL,
46
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
47
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
48
+ "last_attempt_at" timestamp with time zone,
49
+ "last_success_at" timestamp with time zone,
50
+ "last_error" text
51
+ );
52
+ --> statement-breakpoint
53
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_notification_id_notifications_id_fk" FOREIGN KEY ("notification_id") REFERENCES "public"."notifications"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
54
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_event_id_events_id_fk" FOREIGN KEY ("event_id") REFERENCES "public"."events"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
55
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_device_id_push_devices_id_fk" FOREIGN KEY ("device_id") REFERENCES "public"."push_devices"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
56
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_channel_id_notification_channels_id_fk" FOREIGN KEY ("channel_id") REFERENCES "public"."notification_channels"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
57
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_destination_id_project_destinations_id_fk" FOREIGN KEY ("destination_id") REFERENCES "public"."project_destinations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
58
+ ALTER TABLE "notification_channels" ADD CONSTRAINT "notification_channels_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
59
+ ALTER TABLE "project_destinations" ADD CONSTRAINT "project_destinations_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
60
+ ALTER TABLE "project_destinations" ADD CONSTRAINT "project_destinations_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
61
+ CREATE INDEX "delivery_pending" ON "deliveries" USING btree ("finished_at","available_at");--> statement-breakpoint
62
+ CREATE INDEX "notification_channel_user" ON "notification_channels" USING btree ("user_id");--> statement-breakpoint
63
+ CREATE INDEX "project_destination_project" ON "project_destinations" USING btree ("project_id");--> statement-breakpoint
64
+ INSERT INTO "deliveries" ("id", "notification_id", "device_id", "attempts", "available_at", "receipt_id", "finished_at", "error")
65
+ SELECT "id", "notification_id", "device_id", "attempts", "available_at", "receipt_id", "finished_at", "error" FROM "push_deliveries";
@@ -0,0 +1 @@
1
+ DROP TABLE "push_deliveries" CASCADE;
@@ -0,0 +1,16 @@
1
+ CREATE TABLE "calendar_feeds" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "project_id" uuid NOT NULL,
4
+ "created_by" text NOT NULL,
5
+ "name" text NOT NULL,
6
+ "labels" text[] DEFAULT '{}' NOT NULL,
7
+ "time_zone" text NOT NULL,
8
+ "token_hash" text NOT NULL,
9
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
10
+ CONSTRAINT "calendar_feeds_token_hash_unique" UNIQUE("token_hash")
11
+ );
12
+ --> statement-breakpoint
13
+ ALTER TABLE "tickets" ADD COLUMN "start_at" timestamp with time zone;--> statement-breakpoint
14
+ ALTER TABLE "calendar_feeds" ADD CONSTRAINT "calendar_feeds_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
15
+ ALTER TABLE "calendar_feeds" ADD CONSTRAINT "calendar_feeds_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
16
+ CREATE INDEX "calendar_feed_project" ON "calendar_feeds" USING btree ("project_id");
@@ -0,0 +1,14 @@
1
+ CREATE TABLE "staged_uploads" (
2
+ "id" uuid PRIMARY KEY NOT NULL,
3
+ "project_id" uuid NOT NULL,
4
+ "actor_id" text NOT NULL,
5
+ "name" text NOT NULL,
6
+ "content_type" text NOT NULL,
7
+ "size" integer NOT NULL,
8
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
9
+ );
10
+ --> statement-breakpoint
11
+ ALTER TABLE "staged_uploads" ADD CONSTRAINT "staged_uploads_id_blob_objects_id_fk" FOREIGN KEY ("id") REFERENCES "public"."blob_objects"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
12
+ ALTER TABLE "staged_uploads" ADD CONSTRAINT "staged_uploads_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
13
+ ALTER TABLE "staged_uploads" ADD CONSTRAINT "staged_uploads_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
14
+ CREATE INDEX "staged_uploads_created" ON "staged_uploads" USING btree ("created_at");
@@ -0,0 +1,6 @@
1
+ ALTER TABLE "projects" ADD COLUMN "position" bigint DEFAULT 0 NOT NULL;--> statement-breakpoint
2
+ ALTER TABLE "tickets" ADD COLUMN "position" bigint DEFAULT 0 NOT NULL;--> statement-breakpoint
3
+ CREATE INDEX "ticket_project_position" ON "tickets" USING btree ("project_id","position");--> statement-breakpoint
4
+ -- Existing tickets keep creation order and projects keep their alphabetical order, spaced for later moves.
5
+ UPDATE "tickets" SET "position" = "number"::bigint * 1024;--> statement-breakpoint
6
+ UPDATE "projects" SET "position" = ordered.rank * 1024 FROM (SELECT "id", row_number() OVER (PARTITION BY "workspace_id" ORDER BY "name", "id") AS rank FROM "projects") AS ordered WHERE "projects"."id" = ordered."id";
@@ -0,0 +1,22 @@
1
+ CREATE TABLE "invitations" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "workspace_id" uuid NOT NULL,
4
+ "email" text NOT NULL,
5
+ "role" text NOT NULL,
6
+ "project_ids" uuid[],
7
+ "token_hash" text NOT NULL,
8
+ "status" text DEFAULT 'pending' NOT NULL,
9
+ "invited_by" text,
10
+ "accepted_by" text,
11
+ "expires_at" timestamp with time zone NOT NULL,
12
+ "sent_at" timestamp with time zone DEFAULT now() NOT NULL,
13
+ "version" integer DEFAULT 1 NOT NULL,
14
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
15
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
16
+ CONSTRAINT "invitations_token_hash_unique" UNIQUE("token_hash")
17
+ );
18
+ --> statement-breakpoint
19
+ ALTER TABLE "invitations" ADD CONSTRAINT "invitations_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
20
+ ALTER TABLE "invitations" ADD CONSTRAINT "invitations_invited_by_user_id_fk" FOREIGN KEY ("invited_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
21
+ ALTER TABLE "invitations" ADD CONSTRAINT "invitations_accepted_by_user_id_fk" FOREIGN KEY ("accepted_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
22
+ CREATE INDEX "invitation_workspace" ON "invitations" USING btree ("workspace_id","status");
@@ -0,0 +1,39 @@
1
+ CREATE TABLE "workflow_states" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "project_id" uuid NOT NULL,
4
+ "slug" text NOT NULL,
5
+ "name" text NOT NULL,
6
+ "category" text NOT NULL,
7
+ "color" text DEFAULT 'default' NOT NULL,
8
+ "position" integer NOT NULL,
9
+ "version" integer DEFAULT 1 NOT NULL,
10
+ CONSTRAINT "workflow_state_slug" UNIQUE("project_id","slug"),
11
+ CONSTRAINT "workflow_state_category" UNIQUE("project_id","id","category"),
12
+ CONSTRAINT "workflow_state_category_check" CHECK ("workflow_states"."category" IN ('backlog', 'todo', 'in_progress', 'in_review', 'done', 'cancelled'))
13
+ );
14
+ --> statement-breakpoint
15
+ ALTER TABLE "tickets" ALTER COLUMN "status" DROP DEFAULT;--> statement-breakpoint
16
+ ALTER TABLE "tickets" ADD COLUMN "state_id" uuid;--> statement-breakpoint
17
+ -- Every existing project starts with the six canonical states, and each ticket moves to the state
18
+ -- of its status. A status outside the canonical set becomes To do.
19
+ INSERT INTO "workflow_states" ("project_id", "slug", "name", "category", "position")
20
+ SELECT "projects"."id", defaults.slug, defaults.name, defaults.slug, 0
21
+ FROM "projects"
22
+ CROSS JOIN (VALUES
23
+ ('backlog', 'Backlog'),
24
+ ('todo', 'To do'),
25
+ ('in_progress', 'In progress'),
26
+ ('in_review', 'In review'),
27
+ ('done', 'Done'),
28
+ ('cancelled', 'Cancelled')
29
+ ) AS defaults(slug, name);--> statement-breakpoint
30
+ UPDATE "tickets" SET "status" = 'todo'
31
+ WHERE "status" NOT IN ('backlog', 'todo', 'in_progress', 'in_review', 'done', 'cancelled');--> statement-breakpoint
32
+ UPDATE "tickets" SET "state_id" = "workflow_states"."id"
33
+ FROM "workflow_states"
34
+ WHERE "workflow_states"."project_id" = "tickets"."project_id"
35
+ AND "workflow_states"."category" = "tickets"."status";--> statement-breakpoint
36
+ ALTER TABLE "tickets" ALTER COLUMN "state_id" SET NOT NULL;--> statement-breakpoint
37
+ ALTER TABLE "workflow_states" ADD CONSTRAINT "workflow_states_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
38
+ ALTER TABLE "tickets" ADD CONSTRAINT "ticket_workflow_state" FOREIGN KEY ("project_id","state_id","status") REFERENCES "public"."workflow_states"("project_id","id","category") ON DELETE no action ON UPDATE cascade;--> statement-breakpoint
39
+ CREATE INDEX "ticket_state" ON "tickets" USING btree ("state_id");
@@ -0,0 +1,10 @@
1
+ CREATE TABLE "workspace_labels" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "workspace_id" uuid NOT NULL,
4
+ "name" text NOT NULL,
5
+ "color" text DEFAULT 'gray' NOT NULL,
6
+ "version" integer DEFAULT 1 NOT NULL,
7
+ CONSTRAINT "workspace_label_name" UNIQUE("workspace_id","name")
8
+ );
9
+ --> statement-breakpoint
10
+ ALTER TABLE "workspace_labels" ADD CONSTRAINT "workspace_labels_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1 @@
1
+ ALTER TABLE "projects" ADD COLUMN "public_read_enabled" boolean DEFAULT false NOT NULL;
@@ -0,0 +1,16 @@
1
+ CREATE TABLE "custom_fields" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "project_id" uuid NOT NULL,
4
+ "name" text NOT NULL,
5
+ "type" text NOT NULL,
6
+ "options" jsonb DEFAULT '[]'::jsonb NOT NULL,
7
+ "required" boolean DEFAULT false NOT NULL,
8
+ "default_value" jsonb,
9
+ "position" bigint DEFAULT 0 NOT NULL,
10
+ "version" integer DEFAULT 1 NOT NULL,
11
+ CONSTRAINT "custom_field_name" UNIQUE("project_id","name")
12
+ );
13
+ --> statement-breakpoint
14
+ ALTER TABLE "tickets" ADD COLUMN "custom_fields" jsonb DEFAULT '{}'::jsonb NOT NULL;--> statement-breakpoint
15
+ ALTER TABLE "custom_fields" ADD CONSTRAINT "custom_fields_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
16
+ CREATE INDEX "custom_field_project_position" ON "custom_fields" USING btree ("project_id","position");
@@ -0,0 +1,11 @@
1
+ CREATE TABLE "event_audiences" (
2
+ "event_id" bigint NOT NULL,
3
+ "user_id" text NOT NULL,
4
+ CONSTRAINT "event_audiences_event_id_user_id_pk" PRIMARY KEY("event_id","user_id")
5
+ );
6
+ --> statement-breakpoint
7
+ ALTER TABLE "projects" ADD COLUMN "archived_at" timestamp with time zone;--> statement-breakpoint
8
+ ALTER TABLE "projects" ADD COLUMN "deleted_at" timestamp with time zone;--> statement-breakpoint
9
+ ALTER TABLE "event_audiences" ADD CONSTRAINT "event_audiences_event_id_events_id_fk" FOREIGN KEY ("event_id") REFERENCES "public"."events"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
10
+ ALTER TABLE "event_audiences" ADD CONSTRAINT "event_audiences_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
11
+ CREATE INDEX "event_audience_user" ON "event_audiences" USING btree ("user_id","event_id");
@@ -0,0 +1,16 @@
1
+ CREATE TABLE "project_prefixes" (
2
+ "prefix" text PRIMARY KEY NOT NULL,
3
+ "project_id" uuid NOT NULL
4
+ );
5
+ --> statement-breakpoint
6
+ CREATE TABLE "ticket_aliases" (
7
+ "key" text PRIMARY KEY NOT NULL,
8
+ "ticket_id" uuid NOT NULL
9
+ );
10
+ --> statement-breakpoint
11
+ ALTER TABLE "project_prefixes" ADD CONSTRAINT "project_prefixes_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
12
+ ALTER TABLE "ticket_aliases" ADD CONSTRAINT "ticket_aliases_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
13
+ CREATE INDEX "project_prefix_project" ON "project_prefixes" USING btree ("project_id");--> statement-breakpoint
14
+ CREATE INDEX "ticket_alias_ticket" ON "ticket_aliases" USING btree ("ticket_id");--> statement-breakpoint
15
+ -- Every existing prefix is reserved for its project.
16
+ INSERT INTO "project_prefixes" ("prefix", "project_id") SELECT "key", "id" FROM "projects";
@@ -0,0 +1,39 @@
1
+ CREATE TABLE "received_webhooks" (
2
+ "connection_id" uuid NOT NULL,
3
+ "delivery_id" text NOT NULL,
4
+ "event" text NOT NULL,
5
+ "outcome" text NOT NULL,
6
+ "received_at" timestamp with time zone DEFAULT now() NOT NULL,
7
+ CONSTRAINT "received_webhooks_connection_id_delivery_id_pk" PRIMARY KEY("connection_id","delivery_id")
8
+ );
9
+ --> statement-breakpoint
10
+ CREATE TABLE "repository_connections" (
11
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
12
+ "project_id" uuid NOT NULL,
13
+ "provider" text NOT NULL,
14
+ "repository" text NOT NULL,
15
+ "settings" text NOT NULL,
16
+ "paused" boolean DEFAULT false NOT NULL,
17
+ "comment_on_link" boolean DEFAULT false NOT NULL,
18
+ "transitions" jsonb DEFAULT '{}'::jsonb NOT NULL,
19
+ "created_by" text,
20
+ "version" integer DEFAULT 1 NOT NULL,
21
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
22
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
23
+ "last_event_at" timestamp with time zone,
24
+ "last_event_error" text,
25
+ "last_attempt_at" timestamp with time zone,
26
+ "last_success_at" timestamp with time zone,
27
+ "last_error" text,
28
+ CONSTRAINT "repository_connection_name" UNIQUE("project_id","repository")
29
+ );
30
+ --> statement-breakpoint
31
+ ALTER TABLE "deliveries" DROP CONSTRAINT "delivery_one_target";--> statement-breakpoint
32
+ ALTER TABLE "deliveries" ADD COLUMN "connection_id" uuid;--> statement-breakpoint
33
+ ALTER TABLE "resources" ADD COLUMN "remote_kind" text;--> statement-breakpoint
34
+ ALTER TABLE "received_webhooks" ADD CONSTRAINT "received_webhooks_connection_id_repository_connections_id_fk" FOREIGN KEY ("connection_id") REFERENCES "public"."repository_connections"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
35
+ ALTER TABLE "repository_connections" ADD CONSTRAINT "repository_connections_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
36
+ ALTER TABLE "repository_connections" ADD CONSTRAINT "repository_connections_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
37
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_connection_id_repository_connections_id_fk" FOREIGN KEY ("connection_id") REFERENCES "public"."repository_connections"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
38
+ ALTER TABLE "deliveries" ADD CONSTRAINT "delivery_connection" UNIQUE("event_id","connection_id");--> statement-breakpoint
39
+ ALTER TABLE "deliveries" ADD CONSTRAINT "delivery_one_target" CHECK (num_nonnulls("deliveries"."device_id", "deliveries"."channel_id", "deliveries"."destination_id", "deliveries"."connection_id") = 1);
@@ -0,0 +1,3 @@
1
+ ALTER TABLE "repository_connections" DROP CONSTRAINT "repository_connection_name";--> statement-breakpoint
2
+ ALTER TABLE "repository_connections" ADD COLUMN "base_url" text;--> statement-breakpoint
3
+ ALTER TABLE "repository_connections" ADD CONSTRAINT "repository_connection_name" UNIQUE NULLS NOT DISTINCT("project_id","provider","base_url","repository");
@@ -0,0 +1,11 @@
1
+ ALTER TABLE "workspaces" ADD COLUMN "owner_id" text;--> statement-breakpoint
2
+ ALTER TABLE "workspaces" ADD COLUMN "deleted_at" timestamp with time zone;--> statement-breakpoint
3
+ ALTER TABLE "workspaces" ADD CONSTRAINT "workspaces_owner_id_user_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
4
+ --> statement-breakpoint
5
+ -- Each workspace is owned by its earliest-created active administrator member, ties broken by
6
+ -- account ID. A workspace without one stays unowned until an instance administrator transfers it.
7
+ UPDATE "workspaces" w SET "owner_id" = (
8
+ SELECT m."user_id" FROM "workspace_members" m JOIN "user" u ON u."id" = m."user_id"
9
+ WHERE m."workspace_id" = w."id" AND m."role" = 'admin' AND NOT coalesce(u."banned", false)
10
+ ORDER BY u."created_at", u."id" LIMIT 1
11
+ );
@@ -0,0 +1,38 @@
1
+ CREATE TABLE "import_records" (
2
+ "run_id" uuid NOT NULL,
3
+ "seq" integer NOT NULL,
4
+ "kind" text NOT NULL,
5
+ "ref" text NOT NULL,
6
+ "label" text NOT NULL,
7
+ "payload" jsonb,
8
+ "status" text DEFAULT 'pending' NOT NULL,
9
+ "target_id" text,
10
+ "error" jsonb,
11
+ CONSTRAINT "import_records_run_id_seq_pk" PRIMARY KEY("run_id","seq"),
12
+ CONSTRAINT "import_record_ref" UNIQUE("run_id","kind","ref")
13
+ );
14
+ --> statement-breakpoint
15
+ CREATE TABLE "import_runs" (
16
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
17
+ "workspace_id" uuid NOT NULL,
18
+ "actor_id" text NOT NULL,
19
+ "project_id" uuid,
20
+ "key" text NOT NULL,
21
+ "name" text NOT NULL,
22
+ "visibility" text NOT NULL,
23
+ "status" text NOT NULL,
24
+ "counts" jsonb NOT NULL,
25
+ "members" jsonb NOT NULL,
26
+ "issues" jsonb NOT NULL,
27
+ "version" integer DEFAULT 1 NOT NULL,
28
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
29
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
30
+ );
31
+ --> statement-breakpoint
32
+ ALTER TABLE "import_records" ADD CONSTRAINT "import_records_run_id_import_runs_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."import_runs"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
33
+ ALTER TABLE "import_runs" ADD CONSTRAINT "import_runs_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
34
+ ALTER TABLE "import_runs" ADD CONSTRAINT "import_runs_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
35
+ ALTER TABLE "import_runs" ADD CONSTRAINT "import_runs_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
36
+ CREATE INDEX "import_record_pending" ON "import_records" USING btree ("run_id","status","seq");--> statement-breakpoint
37
+ CREATE INDEX "import_run_actor" ON "import_runs" USING btree ("workspace_id","actor_id");--> statement-breakpoint
38
+ CREATE INDEX "import_run_status" ON "import_runs" USING btree ("status");
@@ -0,0 +1,38 @@
1
+ CREATE TABLE "issue_links" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "connection_id" uuid NOT NULL,
4
+ "ticket_id" uuid NOT NULL,
5
+ "origin" text NOT NULL,
6
+ "state" text NOT NULL,
7
+ "reason" text,
8
+ "number" integer,
9
+ "url" text,
10
+ "base" jsonb,
11
+ "remote" jsonb,
12
+ "remote_at" timestamp with time zone,
13
+ "synced_from" timestamp with time zone DEFAULT now() NOT NULL,
14
+ "version" integer DEFAULT 1 NOT NULL,
15
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
16
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
17
+ CONSTRAINT "issue_link_ticket" UNIQUE("connection_id","ticket_id"),
18
+ CONSTRAINT "issue_link_number" UNIQUE("connection_id","number")
19
+ );
20
+ --> statement-breakpoint
21
+ CREATE TABLE "synced_comments" (
22
+ "link_id" uuid NOT NULL,
23
+ "comment_id" uuid,
24
+ "remote_id" text NOT NULL,
25
+ CONSTRAINT "synced_comments_link_id_remote_id_pk" PRIMARY KEY("link_id","remote_id"),
26
+ CONSTRAINT "synced_comment_local" UNIQUE("link_id","comment_id")
27
+ );
28
+ --> statement-breakpoint
29
+ ALTER TABLE "deliveries" ADD COLUMN "issue_link_id" uuid;--> statement-breakpoint
30
+ ALTER TABLE "repository_connections" ADD COLUMN "outbound" jsonb DEFAULT '{"enabled":false,"labels":[],"match":"any"}'::jsonb NOT NULL;--> statement-breakpoint
31
+ ALTER TABLE "repository_connections" ADD COLUMN "inbound" jsonb DEFAULT '{"enabled":false,"labels":[],"match":"any"}'::jsonb NOT NULL;--> statement-breakpoint
32
+ ALTER TABLE "issue_links" ADD CONSTRAINT "issue_links_connection_id_repository_connections_id_fk" FOREIGN KEY ("connection_id") REFERENCES "public"."repository_connections"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
33
+ ALTER TABLE "issue_links" ADD CONSTRAINT "issue_links_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
34
+ ALTER TABLE "synced_comments" ADD CONSTRAINT "synced_comments_link_id_issue_links_id_fk" FOREIGN KEY ("link_id") REFERENCES "public"."issue_links"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
35
+ ALTER TABLE "synced_comments" ADD CONSTRAINT "synced_comments_comment_id_comments_id_fk" FOREIGN KEY ("comment_id") REFERENCES "public"."comments"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
36
+ CREATE INDEX "issue_link_ticket_id" ON "issue_links" USING btree ("ticket_id");--> statement-breakpoint
37
+ ALTER TABLE "deliveries" ADD CONSTRAINT "deliveries_issue_link_id_issue_links_id_fk" FOREIGN KEY ("issue_link_id") REFERENCES "public"."issue_links"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
38
+ CREATE UNIQUE INDEX "delivery_issue_sync" ON "deliveries" USING btree ("issue_link_id") WHERE "deliveries"."event_id" IS NULL AND "deliveries"."finished_at" IS NULL;
@@ -0,0 +1,9 @@
1
+ ALTER TABLE "user" ADD COLUMN "deleted_at" timestamp;--> statement-breakpoint
2
+ -- A deleted account is a tombstone that keeps shared history attributed. It can never carry a
3
+ -- name, address, photo, or role again, and stays disabled, so no later update brings it back.
4
+ ALTER TABLE "user" ADD CONSTRAINT "user_deleted_tombstone" CHECK (
5
+ "deleted_at" IS NULL OR (
6
+ "name" = 'Deleted account' AND "email" = 'deleted+' || "id" || '@kanvil.invalid'
7
+ AND "image" IS NULL AND "role" IS NULL AND "banned" AND NOT "email_verified"
8
+ )
9
+ );
@@ -0,0 +1,16 @@
1
+ CREATE TABLE "workspace_roles" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "workspace_id" uuid NOT NULL,
4
+ "name" text NOT NULL,
5
+ "permissions" text[] DEFAULT '{}' NOT NULL,
6
+ "version" integer DEFAULT 1 NOT NULL,
7
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
8
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
9
+ CONSTRAINT "workspace_role_name" UNIQUE("workspace_id","name")
10
+ );
11
+ --> statement-breakpoint
12
+ ALTER TABLE "project_members" ADD COLUMN "role_id" uuid;--> statement-breakpoint
13
+ ALTER TABLE "workspace_members" ADD COLUMN "role_id" uuid;--> statement-breakpoint
14
+ ALTER TABLE "workspace_roles" ADD CONSTRAINT "workspace_roles_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
15
+ ALTER TABLE "project_members" ADD CONSTRAINT "project_members_role_id_workspace_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."workspace_roles"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
16
+ ALTER TABLE "workspace_members" ADD CONSTRAINT "workspace_members_role_id_workspace_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."workspace_roles"("id") ON DELETE no action ON UPDATE no action;
@@ -0,0 +1,14 @@
1
+ -- Email codes are keyed by address. When an account's address changes or the account goes, its
2
+ -- outstanding codes go with it, so an address given to another account never carries a code over.
3
+ CREATE FUNCTION "forget_email_codes"() RETURNS trigger AS $$
4
+ BEGIN
5
+ IF TG_OP = 'UPDATE' AND OLD."email" IS NOT DISTINCT FROM NEW."email" THEN
6
+ RETURN NULL;
7
+ END IF;
8
+ DELETE FROM "verification"
9
+ WHERE "identifier" IN ('sign-in-otp-' || lower(OLD."email"), 'forget-password-otp-' || lower(OLD."email"));
10
+ RETURN NULL;
11
+ END;
12
+ $$ LANGUAGE plpgsql;--> statement-breakpoint
13
+ CREATE TRIGGER "user_email_codes" AFTER UPDATE OF "email" OR DELETE ON "user"
14
+ FOR EACH ROW EXECUTE FUNCTION "forget_email_codes"();