dineway 0.1.4 → 0.1.6

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 (193) hide show
  1. package/README.md +6 -3
  2. package/dist/{apply-CAPvMfoU.mjs → apply-iVSqz2qs.mjs} +132 -39
  3. package/dist/astro/index.d.mts +18 -9
  4. package/dist/astro/index.mjs +238 -16
  5. package/dist/astro/middleware/auth.d.mts +16 -5
  6. package/dist/astro/middleware/auth.mjs +74 -37
  7. package/dist/astro/middleware/redirect.mjs +24 -8
  8. package/dist/astro/middleware/request-context.mjs +18 -5
  9. package/dist/astro/middleware/setup.mjs +1 -1
  10. package/dist/astro/middleware.mjs +411 -169
  11. package/dist/astro/types.d.mts +25 -8
  12. package/dist/{byline-DeWCMU_i.mjs → byline-OhH2dlRu.mjs} +6 -21
  13. package/dist/{bylines-DyqBV9EQ.mjs → bylines-BGpD9_hy.mjs} +16 -6
  14. package/dist/cache-BdSY-gQN.mjs +42 -0
  15. package/dist/chunks--4F8ddV4.mjs +18 -0
  16. package/dist/cli/index.mjs +935 -15
  17. package/dist/client/external-auth-headers.d.mts +1 -1
  18. package/dist/client/index.d.mts +11 -3
  19. package/dist/client/index.mjs +4 -3
  20. package/dist/{connection-C9pxzuag.mjs → connection-BCNICDWN.mjs} +22 -5
  21. package/dist/{content-zSgdNmnt.mjs → content-DWi4d0rT.mjs} +41 -2
  22. package/dist/database/instrumentation.d.mts +34 -0
  23. package/dist/database/instrumentation.mjs +53 -0
  24. package/dist/db/index.d.mts +3 -3
  25. package/dist/db/index.mjs +2 -2
  26. package/dist/db/libsql.d.mts +1 -1
  27. package/dist/db/libsql.mjs +11 -5
  28. package/dist/db/postgres.d.mts +1 -1
  29. package/dist/db/sqlite.d.mts +1 -1
  30. package/dist/db/sqlite.mjs +7 -1
  31. package/dist/db-errors-CEqD7qH9.mjs +23 -0
  32. package/dist/{default-WYlzADZL.mjs → default-VjJyuuG9.mjs} +2 -0
  33. package/dist/{dialect-helpers-B9uSp2GJ.mjs → dialect-helpers-DhTzaUxP.mjs} +3 -0
  34. package/dist/{error-DrxtnGPg.mjs → error-BmL6QipT.mjs} +7 -3
  35. package/dist/{index-C-jx21qs.d.mts → index-yvc6E_17.d.mts} +157 -30
  36. package/dist/index.d.mts +11 -11
  37. package/dist/index.mjs +24 -22
  38. package/dist/{loader-qKmo0wAY.mjs → loader-sMG4TZ-u.mjs} +9 -3
  39. package/dist/media/index.d.mts +1 -1
  40. package/dist/media/index.mjs +1 -1
  41. package/dist/media/local-runtime.d.mts +7 -7
  42. package/dist/page/index.d.mts +10 -2
  43. package/dist/page/index.mjs +22 -1
  44. package/dist/patterns-CrCYkMBb.mjs +92 -0
  45. package/dist/{placeholder-bOx1xCTY.d.mts → placeholder--wOi4TbO.d.mts} +1 -1
  46. package/dist/{placeholder-B3knXwNc.mjs → placeholder-Cp8g5Emj.mjs} +1 -1
  47. package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
  48. package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
  49. package/dist/{query-BiaPl_g2.mjs → query-kDmwCsHh.mjs} +118 -50
  50. package/dist/{redirect-JPqLAbxa.mjs → redirect-DnEWAkVg.mjs} +43 -99
  51. package/dist/{registry-DSd1GWB8.mjs → registry-C0zjeB9P.mjs} +191 -123
  52. package/dist/request-cache-Dk5qPSOx.mjs +66 -0
  53. package/dist/request-context.d.mts +4 -16
  54. package/dist/{runner-B5l1JfOj.d.mts → runner-CFI6B6J2.d.mts} +1 -1
  55. package/dist/{runner-BGUGywgG.mjs → runner-DWZm2KQm.mjs} +589 -137
  56. package/dist/runtime.d.mts +6 -6
  57. package/dist/runtime.mjs +2 -2
  58. package/dist/{search-BNruJHDL.mjs → search-BApX1xhM.mjs} +570 -424
  59. package/dist/seed/index.d.mts +2 -2
  60. package/dist/seed/index.mjs +11 -10
  61. package/dist/seo/index.d.mts +1 -1
  62. package/dist/storage/local.d.mts +1 -1
  63. package/dist/storage/local.mjs +1 -1
  64. package/dist/storage/s3.d.mts +11 -3
  65. package/dist/storage/s3.mjs +78 -15
  66. package/dist/taxonomies-1s5PaS_8.mjs +266 -0
  67. package/dist/transaction-Cn2rjY78.mjs +27 -0
  68. package/dist/{types-BgQeVaPj.d.mts → types-BuMDPy5C.d.mts} +52 -3
  69. package/dist/{types-DuNbGKjF.mjs → types-COeOq9nK.mjs} +6 -1
  70. package/dist/{types-ju-_ORz7.d.mts → types-CWbdtiux.d.mts} +13 -5
  71. package/dist/{types-D38djUXv.d.mts → types-Cj0KMIZV.d.mts} +16 -3
  72. package/dist/{types-DkvMXalq.d.mts → types-DOrVigru.d.mts} +159 -0
  73. package/dist/{validate-CXnRKfJK.mjs → validate-BZ5wnLLp.mjs} +2 -1
  74. package/dist/{validate-DVKJJ-M_.d.mts → validate-IPf8n4Fj.d.mts} +4 -51
  75. package/dist/{validate-CqRJb_xU.mjs → validate-VPnKoIzW.mjs} +10 -10
  76. package/dist/version-hmtC3Cmv.mjs +6 -0
  77. package/package.json +49 -38
  78. package/src/astro/routes/admin.astro +25 -9
  79. package/src/astro/routes/api/admin/api-tokens/[id].ts +4 -0
  80. package/src/astro/routes/api/admin/api-tokens/index.ts +24 -2
  81. package/src/astro/routes/api/admin/briefing.ts +76 -0
  82. package/src/astro/routes/api/admin/bylines/[id]/index.ts +3 -0
  83. package/src/astro/routes/api/admin/bylines/index.ts +2 -0
  84. package/src/astro/routes/api/admin/context/[id]/history.ts +35 -0
  85. package/src/astro/routes/api/admin/context/[id]/index.ts +35 -0
  86. package/src/astro/routes/api/admin/context/[id]/review.ts +57 -0
  87. package/src/astro/routes/api/admin/context/[id]/supersede.ts +58 -0
  88. package/src/astro/routes/api/admin/context/diff.ts +35 -0
  89. package/src/astro/routes/api/admin/context/index.ts +69 -0
  90. package/src/astro/routes/api/admin/context/stale.ts +35 -0
  91. package/src/astro/routes/api/admin/hitl-requests/[id]/index.ts +38 -0
  92. package/src/astro/routes/api/admin/hitl-requests/[id]/resolve.ts +54 -0
  93. package/src/astro/routes/api/admin/hitl-requests/index.ts +38 -0
  94. package/src/astro/routes/api/admin/hooks/exclusive/[hookName].ts +58 -17
  95. package/src/astro/routes/api/admin/oauth-clients/[id].ts +28 -1
  96. package/src/astro/routes/api/admin/oauth-clients/index.ts +25 -1
  97. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +54 -2
  98. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +54 -2
  99. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +51 -1
  100. package/src/astro/routes/api/admin/plugins/[id]/update.ts +98 -3
  101. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +72 -1
  102. package/src/astro/routes/api/admin/review-requests/[id]/index.ts +35 -0
  103. package/src/astro/routes/api/admin/review-requests/[id]/resolve.ts +52 -0
  104. package/src/astro/routes/api/admin/review-requests/index.ts +35 -0
  105. package/src/astro/routes/api/admin/users/[id]/disable.ts +26 -23
  106. package/src/astro/routes/api/admin/users/[id]/index.ts +41 -21
  107. package/src/astro/routes/api/auth/invite/register-options.ts +73 -0
  108. package/src/astro/routes/api/auth/magic-link/send.ts +2 -1
  109. package/src/astro/routes/api/auth/passkey/options.ts +2 -1
  110. package/src/astro/routes/api/auth/passkey/verify.ts +5 -1
  111. package/src/astro/routes/api/auth/signup/request.ts +20 -8
  112. package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +3 -4
  113. package/src/astro/routes/api/content/[collection]/[id]/compare.ts +1 -1
  114. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +16 -2
  115. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +16 -0
  116. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +9 -0
  117. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +1 -1
  118. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +45 -1
  119. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +12 -2
  120. package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +1 -1
  121. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +24 -0
  122. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +3 -0
  123. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +20 -0
  124. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +13 -0
  125. package/src/astro/routes/api/content/[collection]/[id].ts +36 -0
  126. package/src/astro/routes/api/content/[collection]/index.ts +48 -4
  127. package/src/astro/routes/api/content/[collection]/trash.ts +1 -1
  128. package/src/astro/routes/api/health.ts +54 -0
  129. package/src/astro/routes/api/import/wordpress/analyze.ts +2 -10
  130. package/src/astro/routes/api/import/wordpress/execute.ts +40 -6
  131. package/src/astro/routes/api/import/wordpress/prepare.ts +36 -5
  132. package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +33 -1
  133. package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +3 -3
  134. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +57 -15
  135. package/src/astro/routes/api/manifest.ts +13 -1
  136. package/src/astro/routes/api/mcp.ts +1 -0
  137. package/src/astro/routes/api/media/providers/[providerId]/[itemId].ts +7 -2
  138. package/src/astro/routes/api/media/upload-url.ts +11 -2
  139. package/src/astro/routes/api/media.ts +9 -7
  140. package/src/astro/routes/api/menus/[name]/items.ts +124 -5
  141. package/src/astro/routes/api/menus/[name]/reorder.ts +47 -1
  142. package/src/astro/routes/api/menus/[name].ts +84 -4
  143. package/src/astro/routes/api/menus/index.ts +46 -2
  144. package/src/astro/routes/api/oauth/authorize.ts +21 -8
  145. package/src/astro/routes/api/oauth/device/code.ts +2 -1
  146. package/src/astro/routes/api/oauth/device/token.ts +2 -1
  147. package/src/astro/routes/api/oauth/register.ts +182 -0
  148. package/src/astro/routes/api/oauth/token.ts +18 -7
  149. package/src/astro/routes/api/openapi.json.ts +3 -2
  150. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +21 -4
  151. package/src/astro/routes/api/redirects/[id].ts +103 -4
  152. package/src/astro/routes/api/redirects/index.ts +50 -2
  153. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +28 -0
  154. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +15 -0
  155. package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +13 -0
  156. package/src/astro/routes/api/schema/collections/[slug]/index.ts +27 -0
  157. package/src/astro/routes/api/schema/collections/index.ts +14 -0
  158. package/src/astro/routes/api/search/index.ts +1 -0
  159. package/src/astro/routes/api/search/suggest.ts +1 -0
  160. package/src/astro/routes/api/sections/[slug].ts +123 -4
  161. package/src/astro/routes/api/sections/index.ts +57 -2
  162. package/src/astro/routes/api/settings.ts +51 -2
  163. package/src/astro/routes/api/setup/admin-verify.ts +25 -5
  164. package/src/astro/routes/api/setup/admin.ts +16 -8
  165. package/src/astro/routes/api/setup/index.ts +3 -2
  166. package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +141 -4
  167. package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +64 -2
  168. package/src/astro/routes/api/taxonomies/index.ts +57 -2
  169. package/src/astro/routes/api/well-known/auth.ts +3 -1
  170. package/src/astro/routes/api/well-known/oauth-authorization-server.ts +8 -5
  171. package/src/astro/routes/api/well-known/oauth-protected-resource.ts +3 -2
  172. package/src/astro/routes/api/widget-areas/[name]/reorder.ts +58 -16
  173. package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +124 -38
  174. package/src/astro/routes/api/widget-areas/[name]/widgets.ts +66 -20
  175. package/src/astro/routes/api/widget-areas/[name].ts +55 -7
  176. package/src/astro/routes/api/widget-areas/index.ts +56 -6
  177. package/src/components/DinewayHead.astro +15 -7
  178. package/src/components/DinewayMedia.astro +1 -1
  179. package/src/components/InlinePortableTextEditor.tsx +1 -1
  180. package/src/components/Table.astro +68 -41
  181. package/src/components/index.ts +2 -12
  182. package/src/components/marks.ts +19 -0
  183. package/LICENSE +0 -9
  184. /package/dist/{adapters-BlzWJG82.d.mts → adapters-C2ypTrZZ.d.mts} +0 -0
  185. /package/dist/{config-Cq8H0SfX.mjs → config-BXwuX8Bx.mjs} +0 -0
  186. /package/dist/{load-C6FCD1FU.mjs → load-Coc9HpHH.mjs} +0 -0
  187. /package/dist/{manifest-schema-CTSEyIJ3.mjs → manifest-schema-D1MSVnoI.mjs} +0 -0
  188. /package/dist/{mode-BlyYtIFO.mjs → mode-47goXBBK.mjs} +0 -0
  189. /package/dist/{tokens-4vgYuXsZ.mjs → tokens-CJz9ubV6.mjs} +0 -0
  190. /package/dist/{transport-C5FYnid7.mjs → transport-DB5eDN4x.mjs} +0 -0
  191. /package/dist/{transport-gIL-e43D.d.mts → transport-Wge_IzKl.d.mts} +0 -0
  192. /package/dist/{types-CLLdsG3g.d.mts → types-BzcUjoqg.d.mts} +0 -0
  193. /package/dist/{types-DShnjzb6.mjs → types-griIBQOQ.mjs} +0 -0
@@ -1,12 +1,12 @@
1
1
  import { t as __exportAll } from "./chunk-ClPoSABd.mjs";
2
- import { a as isSqlite, n as currentTimestamp, r as currentTimestampValue, s as listTablesLike, t as binaryType } from "./dialect-helpers-B9uSp2GJ.mjs";
3
- import { t as validateIdentifier } from "./validate-CqRJb_xU.mjs";
2
+ import { t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
3
+ import { a as isSqlite, n as currentTimestamp, r as currentTimestampValue, s as listTablesLike, t as binaryType } from "./dialect-helpers-DhTzaUxP.mjs";
4
4
  import { Migrator, sql } from "kysely";
5
5
 
6
6
  //#region src/database/migrations/001_initial.ts
7
7
  var _001_initial_exports = /* @__PURE__ */ __exportAll({
8
- down: () => down$32,
9
- up: () => up$32
8
+ down: () => down$41,
9
+ up: () => up$41
10
10
  });
11
11
  /**
12
12
  * Initial schema migration
@@ -15,7 +15,7 @@ var _001_initial_exports = /* @__PURE__ */ __exportAll({
15
15
  * by the SchemaRegistry when collections are added via the admin UI.
16
16
  * This migration only creates system tables.
17
17
  */
18
- async function up$32(db) {
18
+ async function up$41(db) {
19
19
  await db.schema.createTable("revisions").ifNotExists().addColumn("id", "text", (col) => col.primaryKey()).addColumn("collection", "text", (col) => col.notNull()).addColumn("entry_id", "text", (col) => col.notNull()).addColumn("data", "text", (col) => col.notNull()).addColumn("author_id", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
20
20
  await db.schema.createIndex("idx_revisions_entry").ifNotExists().on("revisions").columns(["collection", "entry_id"]).execute();
21
21
  await db.schema.createTable("taxonomies").ifNotExists().addColumn("id", "text", (col) => col.primaryKey()).addColumn("name", "text", (col) => col.notNull()).addColumn("slug", "text", (col) => col.notNull()).addColumn("label", "text", (col) => col.notNull()).addColumn("parent_id", "text").addColumn("data", "text").addUniqueConstraint("taxonomies_name_slug_unique", ["name", "slug"]).addForeignKeyConstraint("taxonomies_parent_fk", ["parent_id"], "taxonomies", ["id"], (cb) => cb.onDelete("set null")).execute();
@@ -35,7 +35,7 @@ async function up$32(db) {
35
35
  await db.schema.createIndex("idx_audit_action").ifNotExists().on("audit_logs").column("action").execute();
36
36
  await db.schema.createIndex("idx_audit_timestamp").ifNotExists().on("audit_logs").column("timestamp").execute();
37
37
  }
38
- async function down$32(db) {
38
+ async function down$41(db) {
39
39
  await db.schema.dropTable("audit_logs").execute();
40
40
  await db.schema.dropTable("options").execute();
41
41
  await db.schema.dropTable("users").execute();
@@ -48,26 +48,26 @@ async function down$32(db) {
48
48
  //#endregion
49
49
  //#region src/database/migrations/002_media_status.ts
50
50
  var _002_media_status_exports = /* @__PURE__ */ __exportAll({
51
- down: () => down$31,
52
- up: () => up$31
51
+ down: () => down$40,
52
+ up: () => up$40
53
53
  });
54
54
  /**
55
55
  * Add status column to media table for tracking upload state.
56
56
  * Status values: 'pending' | 'ready' | 'failed'
57
57
  */
58
- async function up$31(db) {
58
+ async function up$40(db) {
59
59
  await db.schema.alterTable("media").addColumn("status", "text", (col) => col.notNull().defaultTo("ready")).execute();
60
60
  await db.schema.createIndex("idx_media_status").on("media").column("status").execute();
61
61
  }
62
- async function down$31(db) {
62
+ async function down$40(db) {
63
63
  await db.schema.dropIndex("idx_media_status").execute();
64
64
  }
65
65
 
66
66
  //#endregion
67
67
  //#region src/database/migrations/003_schema_registry.ts
68
68
  var _003_schema_registry_exports = /* @__PURE__ */ __exportAll({
69
- down: () => down$30,
70
- up: () => up$30
69
+ down: () => down$39,
70
+ up: () => up$39
71
71
  });
72
72
  /**
73
73
  * Migration: Schema Registry Tables
@@ -75,14 +75,14 @@ var _003_schema_registry_exports = /* @__PURE__ */ __exportAll({
75
75
  * Creates the schema registry tables that store collection and field definitions.
76
76
  * This enables dynamic schema management where the database is the source of truth.
77
77
  */
78
- async function up$30(db) {
78
+ async function up$39(db) {
79
79
  await db.schema.createTable("_dineway_collections").addColumn("id", "text", (col) => col.primaryKey()).addColumn("slug", "text", (col) => col.notNull().unique()).addColumn("label", "text", (col) => col.notNull()).addColumn("label_singular", "text").addColumn("description", "text").addColumn("icon", "text").addColumn("supports", "text").addColumn("source", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
80
80
  await db.schema.createTable("_dineway_fields").addColumn("id", "text", (col) => col.primaryKey()).addColumn("collection_id", "text", (col) => col.notNull()).addColumn("slug", "text", (col) => col.notNull()).addColumn("label", "text", (col) => col.notNull()).addColumn("type", "text", (col) => col.notNull()).addColumn("column_type", "text", (col) => col.notNull()).addColumn("required", "integer", (col) => col.defaultTo(0)).addColumn("unique", "integer", (col) => col.defaultTo(0)).addColumn("default_value", "text").addColumn("validation", "text").addColumn("widget", "text").addColumn("options", "text").addColumn("sort_order", "integer", (col) => col.defaultTo(0)).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addForeignKeyConstraint("fields_collection_fk", ["collection_id"], "_dineway_collections", ["id"], (cb) => cb.onDelete("cascade")).execute();
81
81
  await db.schema.createIndex("idx_fields_collection_slug").on("_dineway_fields").columns(["collection_id", "slug"]).unique().execute();
82
82
  await db.schema.createIndex("idx_fields_collection").on("_dineway_fields").column("collection_id").execute();
83
83
  await db.schema.createIndex("idx_fields_sort").on("_dineway_fields").columns(["collection_id", "sort_order"]).execute();
84
84
  }
85
- async function down$30(db) {
85
+ async function down$39(db) {
86
86
  await db.schema.dropTable("_dineway_fields").execute();
87
87
  await db.schema.dropTable("_dineway_collections").execute();
88
88
  }
@@ -90,8 +90,8 @@ async function down$30(db) {
90
90
  //#endregion
91
91
  //#region src/database/migrations/004_plugins.ts
92
92
  var _004_plugins_exports = /* @__PURE__ */ __exportAll({
93
- down: () => down$29,
94
- up: () => up$29
93
+ down: () => down$38,
94
+ up: () => up$38
95
95
  });
96
96
  /**
97
97
  * Migration: Plugin System Tables
@@ -101,7 +101,7 @@ var _004_plugins_exports = /* @__PURE__ */ __exportAll({
101
101
  *
102
102
  * @see PLUGIN-SYSTEM.md § Plugin Storage
103
103
  */
104
- async function up$29(db) {
104
+ async function up$38(db) {
105
105
  await db.schema.createTable("_plugin_storage").addColumn("plugin_id", "text", (col) => col.notNull()).addColumn("collection", "text", (col) => col.notNull()).addColumn("id", "text", (col) => col.notNull()).addColumn("data", "text", (col) => col.notNull()).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addPrimaryKeyConstraint("pk_plugin_storage", [
106
106
  "plugin_id",
107
107
  "collection",
@@ -119,7 +119,7 @@ async function up$29(db) {
119
119
  "index_name"
120
120
  ]).execute();
121
121
  }
122
- async function down$29(db) {
122
+ async function down$38(db) {
123
123
  await db.schema.dropTable("_plugin_indexes").execute();
124
124
  await db.schema.dropTable("_plugin_state").execute();
125
125
  await db.schema.dropTable("_plugin_storage").execute();
@@ -128,8 +128,8 @@ async function down$29(db) {
128
128
  //#endregion
129
129
  //#region src/database/migrations/005_menus.ts
130
130
  var _005_menus_exports = /* @__PURE__ */ __exportAll({
131
- down: () => down$28,
132
- up: () => up$28
131
+ down: () => down$37,
132
+ up: () => up$37
133
133
  });
134
134
  /**
135
135
  * Navigation Menus migration
@@ -137,13 +137,13 @@ var _005_menus_exports = /* @__PURE__ */ __exportAll({
137
137
  * Creates tables for admin-editable navigation menus.
138
138
  * Menu items can reference content entries, taxonomy terms, or custom URLs.
139
139
  */
140
- async function up$28(db) {
140
+ async function up$37(db) {
141
141
  await db.schema.createTable("_dineway_menus").addColumn("id", "text", (col) => col.primaryKey()).addColumn("name", "text", (col) => col.notNull().unique()).addColumn("label", "text", (col) => col.notNull()).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
142
142
  await db.schema.createTable("_dineway_menu_items").addColumn("id", "text", (col) => col.primaryKey()).addColumn("menu_id", "text", (col) => col.notNull()).addColumn("parent_id", "text").addColumn("sort_order", "integer", (col) => col.notNull().defaultTo(0)).addColumn("type", "text", (col) => col.notNull()).addColumn("reference_collection", "text").addColumn("reference_id", "text").addColumn("custom_url", "text").addColumn("label", "text", (col) => col.notNull()).addColumn("title_attr", "text").addColumn("target", "text").addColumn("css_classes", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addForeignKeyConstraint("menu_items_menu_fk", ["menu_id"], "_dineway_menus", ["id"], (cb) => cb.onDelete("cascade")).addForeignKeyConstraint("menu_items_parent_fk", ["parent_id"], "_dineway_menu_items", ["id"], (cb) => cb.onDelete("cascade")).execute();
143
143
  await db.schema.createIndex("idx_menu_items_menu").on("_dineway_menu_items").columns(["menu_id", "sort_order"]).execute();
144
144
  await db.schema.createIndex("idx_menu_items_parent").on("_dineway_menu_items").column("parent_id").execute();
145
145
  }
146
- async function down$28(db) {
146
+ async function down$37(db) {
147
147
  await db.schema.dropTable("_dineway_menu_items").execute();
148
148
  await db.schema.dropTable("_dineway_menus").execute();
149
149
  }
@@ -151,8 +151,8 @@ async function down$28(db) {
151
151
  //#endregion
152
152
  //#region src/database/migrations/006_taxonomy_defs.ts
153
153
  var _006_taxonomy_defs_exports = /* @__PURE__ */ __exportAll({
154
- down: () => down$27,
155
- up: () => up$27
154
+ down: () => down$36,
155
+ up: () => up$36
156
156
  });
157
157
  /**
158
158
  * Taxonomy definitions migration
@@ -160,7 +160,7 @@ var _006_taxonomy_defs_exports = /* @__PURE__ */ __exportAll({
160
160
  * Adds _dineway_taxonomy_defs table to store taxonomy definitions (category, tag, custom)
161
161
  * and seeds default category and tag taxonomies.
162
162
  */
163
- async function up$27(db) {
163
+ async function up$36(db) {
164
164
  await db.schema.createTable("_dineway_taxonomy_defs").addColumn("id", "text", (col) => col.primaryKey()).addColumn("name", "text", (col) => col.notNull().unique()).addColumn("label", "text", (col) => col.notNull()).addColumn("label_singular", "text").addColumn("hierarchical", "integer", (col) => col.defaultTo(0)).addColumn("collections", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
165
165
  await db.insertInto("_dineway_taxonomy_defs").values([{
166
166
  id: "taxdef_category",
@@ -178,22 +178,22 @@ async function up$27(db) {
178
178
  collections: JSON.stringify(["posts"])
179
179
  }]).execute();
180
180
  }
181
- async function down$27(db) {
181
+ async function down$36(db) {
182
182
  await db.schema.dropTable("_dineway_taxonomy_defs").execute();
183
183
  }
184
184
 
185
185
  //#endregion
186
186
  //#region src/database/migrations/007_widgets.ts
187
187
  var _007_widgets_exports = /* @__PURE__ */ __exportAll({
188
- down: () => down$26,
189
- up: () => up$26
188
+ down: () => down$35,
189
+ up: () => up$35
190
190
  });
191
- async function up$26(db) {
191
+ async function up$35(db) {
192
192
  await db.schema.createTable("_dineway_widget_areas").addColumn("id", "text", (col) => col.primaryKey()).addColumn("name", "text", (col) => col.notNull().unique()).addColumn("label", "text", (col) => col.notNull()).addColumn("description", "text").addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)).execute();
193
193
  await db.schema.createTable("_dineway_widgets").addColumn("id", "text", (col) => col.primaryKey()).addColumn("area_id", "text", (col) => col.notNull().references("_dineway_widget_areas.id").onDelete("cascade")).addColumn("sort_order", "integer", (col) => col.notNull().defaultTo(0)).addColumn("type", "text", (col) => col.notNull()).addColumn("title", "text").addColumn("content", "text").addColumn("menu_name", "text").addColumn("component_id", "text").addColumn("component_props", "text").addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)).execute();
194
194
  await db.schema.createIndex("idx_widgets_area").on("_dineway_widgets").columns(["area_id", "sort_order"]).execute();
195
195
  }
196
- async function down$26(db) {
196
+ async function down$35(db) {
197
197
  await db.schema.dropTable("_dineway_widgets").execute();
198
198
  await db.schema.dropTable("_dineway_widget_areas").execute();
199
199
  }
@@ -201,8 +201,8 @@ async function down$26(db) {
201
201
  //#endregion
202
202
  //#region src/database/migrations/008_auth.ts
203
203
  var _008_auth_exports = /* @__PURE__ */ __exportAll({
204
- down: () => down$25,
205
- up: () => up$25
204
+ down: () => down$34,
205
+ up: () => up$34
206
206
  });
207
207
  /**
208
208
  * Auth migration - passkey-first authentication
@@ -216,7 +216,7 @@ var _008_auth_exports = /* @__PURE__ */ __exportAll({
216
216
  * - Creates oauth_accounts table (external provider links)
217
217
  * - Creates allowed_domains table (self-signup)
218
218
  */
219
- async function up$25(db) {
219
+ async function up$34(db) {
220
220
  await db.schema.createTable("users_new").addColumn("id", "text", (col) => col.primaryKey()).addColumn("email", "text", (col) => col.notNull().unique()).addColumn("name", "text").addColumn("avatar_url", "text").addColumn("role", "integer", (col) => col.notNull().defaultTo(10)).addColumn("email_verified", "integer", (col) => col.notNull().defaultTo(0)).addColumn("data", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
221
221
  await sql`
222
222
  INSERT INTO users_new (id, email, name, role, data, created_at, updated_at)
@@ -249,7 +249,7 @@ async function up$25(db) {
249
249
  await db.schema.createTable("auth_challenges").addColumn("challenge", "text", (col) => col.primaryKey()).addColumn("type", "text", (col) => col.notNull()).addColumn("user_id", "text").addColumn("data", "text").addColumn("expires_at", "text", (col) => col.notNull()).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
250
250
  await db.schema.createIndex("idx_auth_challenges_expires").on("auth_challenges").column("expires_at").execute();
251
251
  }
252
- async function down$25(db) {
252
+ async function down$34(db) {
253
253
  await db.schema.dropTable("auth_challenges").execute();
254
254
  await db.schema.dropTable("allowed_domains").execute();
255
255
  await db.schema.dropTable("oauth_accounts").execute();
@@ -282,8 +282,8 @@ async function down$25(db) {
282
282
  //#endregion
283
283
  //#region src/database/migrations/009_user_disabled.ts
284
284
  var _009_user_disabled_exports = /* @__PURE__ */ __exportAll({
285
- down: () => down$24,
286
- up: () => up$24
285
+ down: () => down$33,
286
+ up: () => up$33
287
287
  });
288
288
  /**
289
289
  * User disabled column - for soft-disabling users
@@ -292,19 +292,19 @@ var _009_user_disabled_exports = /* @__PURE__ */ __exportAll({
292
292
  * - Adds disabled column to users table (INTEGER, default 0)
293
293
  * - Disabled users cannot log in
294
294
  */
295
- async function up$24(db) {
295
+ async function up$33(db) {
296
296
  await sql`ALTER TABLE users ADD COLUMN disabled INTEGER NOT NULL DEFAULT 0`.execute(db);
297
297
  await db.schema.createIndex("idx_users_disabled").on("users").column("disabled").execute();
298
298
  }
299
- async function down$24(db) {
299
+ async function down$33(db) {
300
300
  await db.schema.dropIndex("idx_users_disabled").execute();
301
301
  }
302
302
 
303
303
  //#endregion
304
304
  //#region src/database/migrations/011_sections.ts
305
305
  var _011_sections_exports = /* @__PURE__ */ __exportAll({
306
- down: () => down$23,
307
- up: () => up$23
306
+ down: () => down$32,
307
+ up: () => up$32
308
308
  });
309
309
  /**
310
310
  * Migration: Add sections tables and performance indexes
@@ -313,15 +313,15 @@ var _011_sections_exports = /* @__PURE__ */ __exportAll({
313
313
  * They provide a library of pre-built page sections (heroes, CTAs, testimonials, etc.)
314
314
  * that content authors can browse and insert with a single click.
315
315
  */
316
- async function up$23(db) {
316
+ async function up$32(db) {
317
317
  await db.schema.createTable("_dineway_section_categories").addColumn("id", "text", (col) => col.primaryKey()).addColumn("slug", "text", (col) => col.notNull().unique()).addColumn("label", "text", (col) => col.notNull()).addColumn("sort_order", "integer", (col) => col.defaultTo(0)).addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)).execute();
318
318
  await db.schema.createTable("_dineway_sections").addColumn("id", "text", (col) => col.primaryKey()).addColumn("slug", "text", (col) => col.notNull().unique()).addColumn("title", "text", (col) => col.notNull()).addColumn("description", "text").addColumn("category_id", "text", (col) => col.references("_dineway_section_categories.id").onDelete("set null")).addColumn("keywords", "text").addColumn("content", "text", (col) => col.notNull()).addColumn("preview_media_id", "text").addColumn("source", "text", (col) => col.notNull().defaultTo("user")).addColumn("theme_id", "text").addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)).addColumn("updated_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)).execute();
319
319
  await db.schema.createIndex("idx_sections_category").on("_dineway_sections").columns(["category_id"]).execute();
320
320
  await db.schema.createIndex("idx_sections_source").on("_dineway_sections").columns(["source"]).execute();
321
321
  }
322
- async function down$23(db) {
323
- await db.schema.dropIndex("idx_content_taxonomies_term").execute();
324
- await db.schema.dropIndex("idx_media_mime_type").execute();
322
+ async function down$32(db) {
323
+ await db.schema.dropIndex("idx_sections_source").execute();
324
+ await db.schema.dropIndex("idx_sections_category").execute();
325
325
  await db.schema.dropTable("_dineway_sections").execute();
326
326
  await db.schema.dropTable("_dineway_section_categories").execute();
327
327
  }
@@ -329,8 +329,8 @@ async function down$23(db) {
329
329
  //#endregion
330
330
  //#region src/database/migrations/012_search.ts
331
331
  var _012_search_exports = /* @__PURE__ */ __exportAll({
332
- down: () => down$22,
333
- up: () => up$22
332
+ down: () => down$31,
333
+ up: () => up$31
334
334
  });
335
335
  /**
336
336
  * Migration: Search Support
@@ -338,11 +338,11 @@ var _012_search_exports = /* @__PURE__ */ __exportAll({
338
338
  * Adds search configuration to collections and searchable flag to fields.
339
339
  * FTS5 tables are created dynamically when search is enabled for a collection.
340
340
  */
341
- async function up$22(db) {
341
+ async function up$31(db) {
342
342
  await db.schema.alterTable("_dineway_collections").addColumn("search_config", "text").execute();
343
343
  await db.schema.alterTable("_dineway_fields").addColumn("searchable", "integer", (col) => col.defaultTo(0)).execute();
344
344
  }
345
- async function down$22(db) {
345
+ async function down$31(db) {
346
346
  await db.schema.alterTable("_dineway_fields").dropColumn("searchable").execute();
347
347
  await db.schema.alterTable("_dineway_collections").dropColumn("search_config").execute();
348
348
  }
@@ -350,8 +350,8 @@ async function down$22(db) {
350
350
  //#endregion
351
351
  //#region src/database/migrations/013_scheduled_publishing.ts
352
352
  var _013_scheduled_publishing_exports = /* @__PURE__ */ __exportAll({
353
- down: () => down$21,
354
- up: () => up$21
353
+ down: () => down$30,
354
+ up: () => up$30
355
355
  });
356
356
  /**
357
357
  * Migration: Add scheduled publishing support
@@ -360,7 +360,7 @@ var _013_scheduled_publishing_exports = /* @__PURE__ */ __exportAll({
360
360
  * When scheduled_at is set and status is 'scheduled', the content
361
361
  * will be auto-published when the scheduled time is reached.
362
362
  */
363
- async function up$21(db) {
363
+ async function up$30(db) {
364
364
  const tableNames = await listTablesLike(db, "ec_%");
365
365
  for (const tableName of tableNames) {
366
366
  const table = { name: tableName };
@@ -375,7 +375,7 @@ async function up$21(db) {
375
375
  `.execute(db);
376
376
  }
377
377
  }
378
- async function down$21(db) {
378
+ async function down$30(db) {
379
379
  const tableNames = await listTablesLike(db, "ec_%");
380
380
  for (const tableName of tableNames) {
381
381
  const table = { name: tableName };
@@ -392,10 +392,10 @@ async function down$21(db) {
392
392
  //#endregion
393
393
  //#region src/database/migrations/014_draft_revisions.ts
394
394
  var _014_draft_revisions_exports = /* @__PURE__ */ __exportAll({
395
- down: () => down$20,
396
- up: () => up$20
395
+ down: () => down$29,
396
+ up: () => up$29
397
397
  });
398
- async function up$20(db) {
398
+ async function up$29(db) {
399
399
  const tables = await db.selectFrom("_dineway_collections").select("slug").execute();
400
400
  for (const row of tables) {
401
401
  const tableName = `ec_${row.slug}`;
@@ -417,7 +417,7 @@ async function up$20(db) {
417
417
  `.execute(db);
418
418
  }
419
419
  }
420
- async function down$20(db) {
420
+ async function down$29(db) {
421
421
  const tables = await db.selectFrom("_dineway_collections").select("slug").execute();
422
422
  for (const row of tables) {
423
423
  const tableName = `ec_${row.slug}`;
@@ -441,8 +441,8 @@ async function down$20(db) {
441
441
  //#endregion
442
442
  //#region src/database/migrations/015_indexes.ts
443
443
  var _015_indexes_exports = /* @__PURE__ */ __exportAll({
444
- down: () => down$19,
445
- up: () => up$19
444
+ down: () => down$28,
445
+ up: () => up$28
446
446
  });
447
447
  /**
448
448
  * Add performance indexes for common query patterns.
@@ -455,7 +455,7 @@ var _015_indexes_exports = /* @__PURE__ */ __exportAll({
455
455
  * 5. Retroactive author_id + updated_at on existing ec_* content tables
456
456
  * (new tables get these from createContentTable() in registry.ts)
457
457
  */
458
- async function up$19(db) {
458
+ async function up$28(db) {
459
459
  await db.schema.createIndex("idx_media_mime_type").on("media").column("mime_type").execute();
460
460
  await db.schema.createIndex("idx_media_filename").on("media").column("filename").execute();
461
461
  await db.schema.createIndex("idx_media_created_at").on("media").column("created_at").execute();
@@ -475,7 +475,7 @@ async function up$19(db) {
475
475
  `.execute(db);
476
476
  }
477
477
  }
478
- async function down$19(db) {
478
+ async function down$28(db) {
479
479
  const tableNames = await listTablesLike(db, "ec_%");
480
480
  for (const tableName of tableNames) {
481
481
  const table = { name: tableName };
@@ -493,8 +493,8 @@ async function down$19(db) {
493
493
  //#endregion
494
494
  //#region src/database/migrations/016_api_tokens.ts
495
495
  var _016_api_tokens_exports = /* @__PURE__ */ __exportAll({
496
- down: () => down$18,
497
- up: () => up$18
496
+ down: () => down$27,
497
+ up: () => up$27
498
498
  });
499
499
  /**
500
500
  * API token tables for programmatic access.
@@ -504,7 +504,7 @@ var _016_api_tokens_exports = /* @__PURE__ */ __exportAll({
504
504
  * 2. _dineway_oauth_tokens — OAuth access/refresh tokens (ec_oat_/ec_ort_...)
505
505
  * 3. _dineway_device_codes — OAuth Device Flow state (RFC 8628)
506
506
  */
507
- async function up$18(db) {
507
+ async function up$27(db) {
508
508
  await db.schema.createTable("_dineway_api_tokens").addColumn("id", "text", (col) => col.primaryKey()).addColumn("name", "text", (col) => col.notNull()).addColumn("token_hash", "text", (col) => col.notNull().unique()).addColumn("prefix", "text", (col) => col.notNull()).addColumn("user_id", "text", (col) => col.notNull()).addColumn("scopes", "text", (col) => col.notNull()).addColumn("expires_at", "text").addColumn("last_used_at", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addForeignKeyConstraint("api_tokens_user_fk", ["user_id"], "users", ["id"], (cb) => cb.onDelete("cascade")).execute();
509
509
  await db.schema.createIndex("idx_api_tokens_token_hash").on("_dineway_api_tokens").column("token_hash").execute();
510
510
  await db.schema.createIndex("idx_api_tokens_user_id").on("_dineway_api_tokens").column("user_id").execute();
@@ -513,7 +513,7 @@ async function up$18(db) {
513
513
  await db.schema.createIndex("idx_oauth_tokens_expires").on("_dineway_oauth_tokens").column("expires_at").execute();
514
514
  await db.schema.createTable("_dineway_device_codes").addColumn("device_code", "text", (col) => col.primaryKey()).addColumn("user_code", "text", (col) => col.notNull().unique()).addColumn("scopes", "text", (col) => col.notNull()).addColumn("user_id", "text").addColumn("status", "text", (col) => col.notNull().defaultTo("pending")).addColumn("expires_at", "text", (col) => col.notNull()).addColumn("interval", "integer", (col) => col.notNull().defaultTo(5)).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
515
515
  }
516
- async function down$18(db) {
516
+ async function down$27(db) {
517
517
  await db.schema.dropTable("_dineway_device_codes").execute();
518
518
  await db.schema.dropTable("_dineway_oauth_tokens").execute();
519
519
  await db.schema.dropTable("_dineway_api_tokens").execute();
@@ -522,8 +522,8 @@ async function down$18(db) {
522
522
  //#endregion
523
523
  //#region src/database/migrations/017_authorization_codes.ts
524
524
  var _017_authorization_codes_exports = /* @__PURE__ */ __exportAll({
525
- down: () => down$17,
526
- up: () => up$17
525
+ down: () => down$26,
526
+ up: () => up$26
527
527
  });
528
528
  /**
529
529
  * Authorization codes for OAuth 2.1 Authorization Code + PKCE flow.
@@ -533,20 +533,20 @@ var _017_authorization_codes_exports = /* @__PURE__ */ __exportAll({
533
533
  *
534
534
  * Also adds client_id tracking to oauth_tokens for per-client revocation.
535
535
  */
536
- async function up$17(db) {
536
+ async function up$26(db) {
537
537
  await db.schema.createTable("_dineway_authorization_codes").addColumn("code_hash", "text", (col) => col.primaryKey()).addColumn("client_id", "text", (col) => col.notNull()).addColumn("redirect_uri", "text", (col) => col.notNull()).addColumn("user_id", "text", (col) => col.notNull()).addColumn("scopes", "text", (col) => col.notNull()).addColumn("code_challenge", "text", (col) => col.notNull()).addColumn("code_challenge_method", "text", (col) => col.notNull().defaultTo("S256")).addColumn("resource", "text").addColumn("expires_at", "text", (col) => col.notNull()).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addForeignKeyConstraint("auth_codes_user_fk", ["user_id"], "users", ["id"], (cb) => cb.onDelete("cascade")).execute();
538
538
  await db.schema.createIndex("idx_auth_codes_expires").on("_dineway_authorization_codes").column("expires_at").execute();
539
539
  await sql`ALTER TABLE _dineway_oauth_tokens ADD COLUMN client_id TEXT`.execute(db);
540
540
  }
541
- async function down$17(db) {
541
+ async function down$26(db) {
542
542
  await db.schema.dropTable("_dineway_authorization_codes").execute();
543
543
  }
544
544
 
545
545
  //#endregion
546
546
  //#region src/database/migrations/018_seo.ts
547
547
  var _018_seo_exports = /* @__PURE__ */ __exportAll({
548
- down: () => down$16,
549
- up: () => up$16
548
+ down: () => down$25,
549
+ up: () => up$25
550
550
  });
551
551
  /**
552
552
  * Migration: SEO support
@@ -559,7 +559,7 @@ var _018_seo_exports = /* @__PURE__ */ __exportAll({
559
559
  * need it. The `has_seo` flag controls whether the admin shows SEO fields
560
560
  * and whether the collection's content appears in sitemaps.
561
561
  */
562
- async function up$16(db) {
562
+ async function up$25(db) {
563
563
  await db.schema.createTable("_dineway_seo").addColumn("collection", "text", (col) => col.notNull()).addColumn("content_id", "text", (col) => col.notNull()).addColumn("seo_title", "text").addColumn("seo_description", "text").addColumn("seo_image", "text").addColumn("seo_canonical", "text").addColumn("seo_no_index", "integer", (col) => col.notNull().defaultTo(0)).addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addPrimaryKeyConstraint("_dineway_seo_pk", ["collection", "content_id"]).execute();
564
564
  await sql`
565
565
  CREATE INDEX idx_dineway_seo_collection
@@ -570,7 +570,7 @@ async function up$16(db) {
570
570
  ADD COLUMN has_seo INTEGER NOT NULL DEFAULT 0
571
571
  `.execute(db);
572
572
  }
573
- async function down$16(db) {
573
+ async function down$25(db) {
574
574
  await sql`DROP TABLE IF EXISTS _dineway_seo`.execute(db);
575
575
  await sql`
576
576
  ALTER TABLE _dineway_collections
@@ -581,8 +581,8 @@ async function down$16(db) {
581
581
  //#endregion
582
582
  //#region src/database/migrations/019_i18n.ts
583
583
  var _019_i18n_exports = /* @__PURE__ */ __exportAll({
584
- down: () => down$15,
585
- up: () => up$15
584
+ down: () => down$24,
585
+ up: () => up$24
586
586
  });
587
587
  /**
588
588
  * Quote an identifier for use in raw SQL. Escapes embedded double-quotes
@@ -695,7 +695,7 @@ async function upPostgres(db) {
695
695
  ADD COLUMN translatable INTEGER NOT NULL DEFAULT 1
696
696
  `.execute(db);
697
697
  }
698
- async function up$15(db) {
698
+ async function up$24(db) {
699
699
  if (!isSqlite(db)) return upPostgres(db);
700
700
  const orphanedTmps = await listTablesLike(db, "ec_%_i18n_tmp");
701
701
  for (const tmpName of orphanedTmps) {
@@ -812,7 +812,7 @@ async function downPostgres(db) {
812
812
  await sql`ALTER TABLE ${sql.ref(t)} DROP COLUMN translation_group`.execute(db);
813
813
  }
814
814
  }
815
- async function down$15(db) {
815
+ async function down$24(db) {
816
816
  if (!isSqlite(db)) return downPostgres(db);
817
817
  await sql`
818
818
  ALTER TABLE _dineway_fields
@@ -919,8 +919,8 @@ async function down$15(db) {
919
919
  //#endregion
920
920
  //#region src/database/migrations/020_collection_url_pattern.ts
921
921
  var _020_collection_url_pattern_exports = /* @__PURE__ */ __exportAll({
922
- down: () => down$14,
923
- up: () => up$14
922
+ down: () => down$23,
923
+ up: () => up$23
924
924
  });
925
925
  /**
926
926
  * Migration: URL pattern for collections
@@ -929,13 +929,13 @@ var _020_collection_url_pattern_exports = /* @__PURE__ */ __exportAll({
929
929
  * can declare its own URL structure (e.g. "/{slug}" for pages, "/blog/{slug}"
930
930
  * for posts). Used for menu URL resolution, sitemaps, and path-based lookups.
931
931
  */
932
- async function up$14(db) {
932
+ async function up$23(db) {
933
933
  await sql`
934
934
  ALTER TABLE _dineway_collections
935
935
  ADD COLUMN url_pattern TEXT
936
936
  `.execute(db);
937
937
  }
938
- async function down$14(db) {
938
+ async function down$23(db) {
939
939
  await sql`
940
940
  ALTER TABLE _dineway_collections
941
941
  DROP COLUMN url_pattern
@@ -945,8 +945,8 @@ async function down$14(db) {
945
945
  //#endregion
946
946
  //#region src/database/migrations/021_remove_section_categories.ts
947
947
  var _021_remove_section_categories_exports = /* @__PURE__ */ __exportAll({
948
- down: () => down$13,
949
- up: () => up$13
948
+ down: () => down$22,
949
+ up: () => up$22
950
950
  });
951
951
  /**
952
952
  * Migration: Remove section categories
@@ -955,12 +955,12 @@ var _021_remove_section_categories_exports = /* @__PURE__ */ __exportAll({
955
955
  * Rather than building the missing UI for a feature with very little need at this stage,
956
956
  * we're removing the feature entirely.
957
957
  */
958
- async function up$13(db) {
958
+ async function up$22(db) {
959
959
  await db.schema.dropIndex("idx_sections_category").ifExists().execute();
960
960
  await db.schema.alterTable("_dineway_sections").dropColumn("category_id").execute();
961
961
  await db.schema.dropTable("_dineway_section_categories").execute();
962
962
  }
963
- async function down$13(db) {
963
+ async function down$22(db) {
964
964
  await db.schema.createTable("_dineway_section_categories").addColumn("id", "text", (col) => col.primaryKey()).addColumn("slug", "text", (col) => col.notNull().unique()).addColumn("label", "text", (col) => col.notNull()).addColumn("sort_order", "integer", (col) => col.defaultTo(0)).addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)).execute();
965
965
  await db.schema.alterTable("_dineway_sections").addColumn("category_id", "text", (col) => col.references("_dineway_section_categories.id").onDelete("set null")).execute();
966
966
  await db.schema.createIndex("idx_sections_category").on("_dineway_sections").columns(["category_id"]).execute();
@@ -969,8 +969,8 @@ async function down$13(db) {
969
969
  //#endregion
970
970
  //#region src/database/migrations/022_marketplace_plugin_state.ts
971
971
  var _022_marketplace_plugin_state_exports = /* @__PURE__ */ __exportAll({
972
- down: () => down$12,
973
- up: () => up$12
972
+ down: () => down$21,
973
+ up: () => up$21
974
974
  });
975
975
  /**
976
976
  * Migration: Add marketplace fields to _plugin_state
@@ -979,7 +979,7 @@ var _022_marketplace_plugin_state_exports = /* @__PURE__ */ __exportAll({
979
979
  * whether a plugin was installed from config or marketplace,
980
980
  * and which marketplace version is installed.
981
981
  */
982
- async function up$12(db) {
982
+ async function up$21(db) {
983
983
  await sql`
984
984
  ALTER TABLE _plugin_state
985
985
  ADD COLUMN source TEXT NOT NULL DEFAULT 'config'
@@ -994,7 +994,7 @@ async function up$12(db) {
994
994
  WHERE source = 'marketplace'
995
995
  `.execute(db);
996
996
  }
997
- async function down$12(db) {
997
+ async function down$21(db) {
998
998
  await sql`
999
999
  DROP INDEX IF EXISTS idx_plugin_state_source
1000
1000
  `.execute(db);
@@ -1011,8 +1011,8 @@ async function down$12(db) {
1011
1011
  //#endregion
1012
1012
  //#region src/database/migrations/023_plugin_metadata.ts
1013
1013
  var _023_plugin_metadata_exports = /* @__PURE__ */ __exportAll({
1014
- down: () => down$11,
1015
- up: () => up$11
1014
+ down: () => down$20,
1015
+ up: () => up$20
1016
1016
  });
1017
1017
  /**
1018
1018
  * Migration: Add display metadata to _plugin_state
@@ -1021,7 +1021,7 @@ var _023_plugin_metadata_exports = /* @__PURE__ */ __exportAll({
1021
1021
  * so the admin UI can show meaningful info without re-fetching
1022
1022
  * from the marketplace on every page load.
1023
1023
  */
1024
- async function up$11(db) {
1024
+ async function up$20(db) {
1025
1025
  await sql`
1026
1026
  ALTER TABLE _plugin_state
1027
1027
  ADD COLUMN display_name TEXT
@@ -1031,7 +1031,7 @@ async function up$11(db) {
1031
1031
  ADD COLUMN description TEXT
1032
1032
  `.execute(db);
1033
1033
  }
1034
- async function down$11(db) {
1034
+ async function down$20(db) {
1035
1035
  await sql`
1036
1036
  ALTER TABLE _plugin_state
1037
1037
  DROP COLUMN description
@@ -1045,8 +1045,8 @@ async function down$11(db) {
1045
1045
  //#endregion
1046
1046
  //#region src/database/migrations/024_media_placeholders.ts
1047
1047
  var _024_media_placeholders_exports = /* @__PURE__ */ __exportAll({
1048
- down: () => down$10,
1049
- up: () => up$10
1048
+ down: () => down$19,
1049
+ up: () => up$19
1050
1050
  });
1051
1051
  /**
1052
1052
  * Migration: Add placeholder columns to media table
@@ -1054,7 +1054,7 @@ var _024_media_placeholders_exports = /* @__PURE__ */ __exportAll({
1054
1054
  * Stores blurhash and dominant_color for LQIP (Low Quality Image Placeholder)
1055
1055
  * support. Generated at upload time from image pixel data.
1056
1056
  */
1057
- async function up$10(db) {
1057
+ async function up$19(db) {
1058
1058
  await sql`
1059
1059
  ALTER TABLE media
1060
1060
  ADD COLUMN blurhash TEXT
@@ -1064,7 +1064,7 @@ async function up$10(db) {
1064
1064
  ADD COLUMN dominant_color TEXT
1065
1065
  `.execute(db);
1066
1066
  }
1067
- async function down$10(db) {
1067
+ async function down$19(db) {
1068
1068
  await sql`
1069
1069
  ALTER TABLE media
1070
1070
  DROP COLUMN dominant_color
@@ -1078,8 +1078,8 @@ async function down$10(db) {
1078
1078
  //#endregion
1079
1079
  //#region src/database/migrations/025_oauth_clients.ts
1080
1080
  var _025_oauth_clients_exports = /* @__PURE__ */ __exportAll({
1081
- down: () => down$9,
1082
- up: () => up$9
1081
+ down: () => down$18,
1082
+ up: () => up$18
1083
1083
  });
1084
1084
  /**
1085
1085
  * Migration: Create OAuth clients table
@@ -1090,18 +1090,18 @@ var _025_oauth_clients_exports = /* @__PURE__ */ __exportAll({
1090
1090
  * Each client has a set of pre-registered redirect URIs (JSON array).
1091
1091
  * The authorize endpoint rejects any redirect_uri not in the client's list.
1092
1092
  */
1093
- async function up$9(db) {
1093
+ async function up$18(db) {
1094
1094
  await db.schema.createTable("_dineway_oauth_clients").addColumn("id", "text", (col) => col.primaryKey()).addColumn("name", "text", (col) => col.notNull()).addColumn("redirect_uris", "text", (col) => col.notNull()).addColumn("scopes", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
1095
1095
  }
1096
- async function down$9(db) {
1096
+ async function down$18(db) {
1097
1097
  await db.schema.dropTable("_dineway_oauth_clients").execute();
1098
1098
  }
1099
1099
 
1100
1100
  //#endregion
1101
1101
  //#region src/database/migrations/026_cron_tasks.ts
1102
1102
  var _026_cron_tasks_exports = /* @__PURE__ */ __exportAll({
1103
- down: () => down$8,
1104
- up: () => up$8
1103
+ down: () => down$17,
1104
+ up: () => up$17
1105
1105
  });
1106
1106
  /**
1107
1107
  * Migration: Create cron tasks table for plugin scheduled tasks.
@@ -1112,7 +1112,7 @@ var _026_cron_tasks_exports = /* @__PURE__ */ __exportAll({
1112
1112
  * The `next_run_at` + `status` + `enabled` index drives the "find overdue
1113
1113
  * tasks" query used by CronExecutor.tick().
1114
1114
  */
1115
- async function up$8(db) {
1115
+ async function up$17(db) {
1116
1116
  await db.schema.createTable("_dineway_cron_tasks").addColumn("id", "text", (col) => col.primaryKey()).addColumn("plugin_id", "text", (col) => col.notNull()).addColumn("task_name", "text", (col) => col.notNull()).addColumn("schedule", "text", (col) => col.notNull()).addColumn("is_oneshot", "integer", (col) => col.notNull().defaultTo(0)).addColumn("data", "text").addColumn("next_run_at", "text", (col) => col.notNull()).addColumn("last_run_at", "text").addColumn("status", "text", (col) => col.notNull().defaultTo("idle")).addColumn("locked_at", "text").addColumn("enabled", "integer", (col) => col.notNull().defaultTo(1)).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addUniqueConstraint("uq_cron_tasks_plugin_task", ["plugin_id", "task_name"]).execute();
1117
1117
  await db.schema.createIndex("idx_cron_tasks_due").on("_dineway_cron_tasks").columns([
1118
1118
  "enabled",
@@ -1121,17 +1121,17 @@ async function up$8(db) {
1121
1121
  ]).execute();
1122
1122
  await db.schema.createIndex("idx_cron_tasks_plugin").on("_dineway_cron_tasks").column("plugin_id").execute();
1123
1123
  }
1124
- async function down$8(db) {
1124
+ async function down$17(db) {
1125
1125
  await db.schema.dropTable("_dineway_cron_tasks").execute();
1126
1126
  }
1127
1127
 
1128
1128
  //#endregion
1129
1129
  //#region src/database/migrations/027_comments.ts
1130
1130
  var _027_comments_exports = /* @__PURE__ */ __exportAll({
1131
- down: () => down$7,
1132
- up: () => up$7
1131
+ down: () => down$16,
1132
+ up: () => up$16
1133
1133
  });
1134
- async function up$7(db) {
1134
+ async function up$16(db) {
1135
1135
  await db.schema.createTable("_dineway_comments").addColumn("id", "text", (col) => col.primaryKey()).addColumn("collection", "text", (col) => col.notNull()).addColumn("content_id", "text", (col) => col.notNull()).addColumn("parent_id", "text", (col) => col.references("_dineway_comments.id").onDelete("cascade")).addColumn("author_name", "text", (col) => col.notNull()).addColumn("author_email", "text", (col) => col.notNull()).addColumn("author_url", "text").addColumn("author_user_id", "text", (col) => col.references("users.id").onDelete("set null")).addColumn("body", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo("pending")).addColumn("ip_hash", "text").addColumn("user_agent", "text").addColumn("moderation_metadata", "text").addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
1136
1136
  await db.schema.createIndex("idx_comments_content").on("_dineway_comments").columns([
1137
1137
  "collection",
@@ -1147,30 +1147,30 @@ async function up$7(db) {
1147
1147
  await db.schema.alterTable("_dineway_collections").addColumn("comments_closed_after_days", "integer", (col) => col.defaultTo(90)).execute();
1148
1148
  await db.schema.alterTable("_dineway_collections").addColumn("comments_auto_approve_users", "integer", (col) => col.defaultTo(1)).execute();
1149
1149
  }
1150
- async function down$7(db) {
1150
+ async function down$16(db) {
1151
1151
  await db.schema.dropTable("_dineway_comments").execute();
1152
1152
  }
1153
1153
 
1154
1154
  //#endregion
1155
1155
  //#region src/database/migrations/028_drop_author_url.ts
1156
1156
  var _028_drop_author_url_exports = /* @__PURE__ */ __exportAll({
1157
- down: () => down$6,
1158
- up: () => up$6
1157
+ down: () => down$15,
1158
+ up: () => up$15
1159
1159
  });
1160
- async function up$6(db) {
1160
+ async function up$15(db) {
1161
1161
  await sql`ALTER TABLE _dineway_comments DROP COLUMN author_url`.execute(db);
1162
1162
  }
1163
- async function down$6(db) {
1163
+ async function down$15(db) {
1164
1164
  await db.schema.alterTable("_dineway_comments").addColumn("author_url", "text").execute();
1165
1165
  }
1166
1166
 
1167
1167
  //#endregion
1168
1168
  //#region src/database/migrations/029_redirects.ts
1169
1169
  var _029_redirects_exports = /* @__PURE__ */ __exportAll({
1170
- down: () => down$5,
1171
- up: () => up$5
1170
+ down: () => down$14,
1171
+ up: () => up$14
1172
1172
  });
1173
- async function up$5(db) {
1173
+ async function up$14(db) {
1174
1174
  await db.schema.createTable("_dineway_redirects").addColumn("id", "text", (col) => col.primaryKey()).addColumn("source", "text", (col) => col.notNull()).addColumn("destination", "text", (col) => col.notNull()).addColumn("type", "integer", (col) => col.notNull().defaultTo(301)).addColumn("is_pattern", "integer", (col) => col.notNull().defaultTo(0)).addColumn("enabled", "integer", (col) => col.notNull().defaultTo(1)).addColumn("hits", "integer", (col) => col.notNull().defaultTo(0)).addColumn("last_hit_at", "text").addColumn("group_name", "text").addColumn("auto", "integer", (col) => col.notNull().defaultTo(0)).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
1175
1175
  await db.schema.createIndex("idx_redirects_source").on("_dineway_redirects").column("source").execute();
1176
1176
  await db.schema.createIndex("idx_redirects_enabled").on("_dineway_redirects").column("enabled").execute();
@@ -1179,7 +1179,7 @@ async function up$5(db) {
1179
1179
  await db.schema.createIndex("idx_404_log_path").on("_dineway_404_log").column("path").execute();
1180
1180
  await db.schema.createIndex("idx_404_log_created").on("_dineway_404_log").column("created_at").execute();
1181
1181
  }
1182
- async function down$5(db) {
1182
+ async function down$14(db) {
1183
1183
  await db.schema.dropTable("_dineway_404_log").execute();
1184
1184
  await db.schema.dropTable("_dineway_redirects").execute();
1185
1185
  }
@@ -1187,8 +1187,8 @@ async function down$5(db) {
1187
1187
  //#endregion
1188
1188
  //#region src/database/migrations/030_widen_scheduled_index.ts
1189
1189
  var _030_widen_scheduled_index_exports = /* @__PURE__ */ __exportAll({
1190
- down: () => down$4,
1191
- up: () => up$4
1190
+ down: () => down$13,
1191
+ up: () => up$13
1192
1192
  });
1193
1193
  /**
1194
1194
  * Migration: Widen scheduled publishing index
@@ -1197,7 +1197,7 @@ var _030_widen_scheduled_index_exports = /* @__PURE__ */ __exportAll({
1197
1197
  * Published posts can now have scheduled draft changes, so widen the
1198
1198
  * index to cover all rows where scheduled_at IS NOT NULL.
1199
1199
  */
1200
- async function up$4(db) {
1200
+ async function up$13(db) {
1201
1201
  const tableNames = await listTablesLike(db, "ec_%");
1202
1202
  for (const tableName of tableNames) {
1203
1203
  const table = { name: tableName };
@@ -1211,7 +1211,7 @@ async function up$4(db) {
1211
1211
  `.execute(db);
1212
1212
  }
1213
1213
  }
1214
- async function down$4(db) {
1214
+ async function down$13(db) {
1215
1215
  const tableNames = await listTablesLike(db, "ec_%");
1216
1216
  for (const tableName of tableNames) {
1217
1217
  const table = { name: tableName };
@@ -1229,10 +1229,10 @@ async function down$4(db) {
1229
1229
  //#endregion
1230
1230
  //#region src/database/migrations/031_bylines.ts
1231
1231
  var _031_bylines_exports = /* @__PURE__ */ __exportAll({
1232
- down: () => down$3,
1233
- up: () => up$3
1232
+ down: () => down$12,
1233
+ up: () => up$12
1234
1234
  });
1235
- async function up$3(db) {
1235
+ async function up$12(db) {
1236
1236
  await db.schema.createTable("_dineway_bylines").addColumn("id", "text", (col) => col.primaryKey()).addColumn("slug", "text", (col) => col.notNull().unique()).addColumn("display_name", "text", (col) => col.notNull()).addColumn("bio", "text").addColumn("avatar_media_id", "text", (col) => col.references("media.id").onDelete("set null")).addColumn("website_url", "text").addColumn("user_id", "text", (col) => col.references("users.id").onDelete("set null")).addColumn("is_guest", "integer", (col) => col.notNull().defaultTo(0)).addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db))).execute();
1237
1237
  await sql`
1238
1238
  CREATE UNIQUE INDEX ${sql.ref("idx_bylines_user_id_unique")}
@@ -1264,7 +1264,7 @@ async function up$3(db) {
1264
1264
  `.execute(db);
1265
1265
  }
1266
1266
  }
1267
- async function down$3(db) {
1267
+ async function down$12(db) {
1268
1268
  const tableNames = await listTablesLike(db, "ec_%");
1269
1269
  for (const tableName of tableNames) {
1270
1270
  await sql`
@@ -1282,8 +1282,8 @@ async function down$3(db) {
1282
1282
  //#endregion
1283
1283
  //#region src/database/migrations/032_rate_limits.ts
1284
1284
  var _032_rate_limits_exports = /* @__PURE__ */ __exportAll({
1285
- down: () => down$2,
1286
- up: () => up$2
1285
+ down: () => down$11,
1286
+ up: () => up$11
1287
1287
  });
1288
1288
  /**
1289
1289
  * Migration: Rate limits table + device code polling tracking.
@@ -1294,12 +1294,12 @@ var _032_rate_limits_exports = /* @__PURE__ */ __exportAll({
1294
1294
  * 2. Add last_polled_at column to _dineway_device_codes for
1295
1295
  * RFC 8628 slow_down enforcement.
1296
1296
  */
1297
- async function up$2(db) {
1297
+ async function up$11(db) {
1298
1298
  await db.schema.createTable("_dineway_rate_limits").addColumn("key", "text", (col) => col.notNull()).addColumn("window", "text", (col) => col.notNull()).addColumn("count", "integer", (col) => col.notNull().defaultTo(1)).addPrimaryKeyConstraint("pk_rate_limits", ["key", "window"]).execute();
1299
1299
  await db.schema.createIndex("idx_rate_limits_window").on("_dineway_rate_limits").column("window").execute();
1300
1300
  await db.schema.alterTable("_dineway_device_codes").addColumn("last_polled_at", "text").execute();
1301
1301
  }
1302
- async function down$2(db) {
1302
+ async function down$11(db) {
1303
1303
  await db.schema.dropTable("_dineway_rate_limits").execute();
1304
1304
  await db.schema.alterTable("_dineway_device_codes").dropColumn("last_polled_at").execute();
1305
1305
  }
@@ -1307,8 +1307,8 @@ async function down$2(db) {
1307
1307
  //#endregion
1308
1308
  //#region src/database/migrations/033_optimize_content_indexes.ts
1309
1309
  var _033_optimize_content_indexes_exports = /* @__PURE__ */ __exportAll({
1310
- down: () => down$1,
1311
- up: () => up$1
1310
+ down: () => down$10,
1311
+ up: () => up$10
1312
1312
  });
1313
1313
  /**
1314
1314
  * Migration: Optimize content table indexes for SQLite-compatible performance
@@ -1321,7 +1321,7 @@ var _033_optimize_content_indexes_exports = /* @__PURE__ */ __exportAll({
1321
1321
  *
1322
1322
  * Impact: Reduces row reads by 90%+ for admin panel operations on SQLite-compatible adapters.
1323
1323
  */
1324
- async function up$1(db) {
1324
+ async function up$10(db) {
1325
1325
  const tableNames = await listTablesLike(db, "ec_%");
1326
1326
  for (const tableName of tableNames) {
1327
1327
  const table = { name: tableName };
@@ -1363,7 +1363,7 @@ async function up$1(db) {
1363
1363
  WHERE status = 'trash'
1364
1364
  `.execute(db);
1365
1365
  }
1366
- async function down$1(db) {
1366
+ async function down$10(db) {
1367
1367
  const tableNames = await listTablesLike(db, "ec_%");
1368
1368
  for (const tableName of tableNames) {
1369
1369
  const table = { name: tableName };
@@ -1396,10 +1396,10 @@ async function down$1(db) {
1396
1396
  //#endregion
1397
1397
  //#region src/database/migrations/034_published_at_index.ts
1398
1398
  var _034_published_at_index_exports = /* @__PURE__ */ __exportAll({
1399
- down: () => down,
1400
- up: () => up
1399
+ down: () => down$9,
1400
+ up: () => up$9
1401
1401
  });
1402
- async function up(db) {
1402
+ async function up$9(db) {
1403
1403
  const tableNames = await listTablesLike(db, "ec_%");
1404
1404
  for (const tableName of tableNames) {
1405
1405
  const table = { name: tableName };
@@ -1409,7 +1409,7 @@ async function up(db) {
1409
1409
  `.execute(db);
1410
1410
  }
1411
1411
  }
1412
- async function down(db) {
1412
+ async function down$9(db) {
1413
1413
  const tableNames = await listTablesLike(db, "ec_%");
1414
1414
  for (const tableName of tableNames) {
1415
1415
  const table = { name: tableName };
@@ -1417,6 +1417,449 @@ async function down(db) {
1417
1417
  }
1418
1418
  }
1419
1419
 
1420
+ //#endregion
1421
+ //#region src/database/migrations/035_backfill_url_patterns.ts
1422
+ var _035_backfill_url_patterns_exports = /* @__PURE__ */ __exportAll({
1423
+ down: () => down$8,
1424
+ up: () => up$8
1425
+ });
1426
+ /**
1427
+ * Backfill default URL patterns for the built-in posts and pages collections.
1428
+ *
1429
+ * Existing rows keep custom patterns; only missing defaults are filled.
1430
+ */
1431
+ async function up$8(db) {
1432
+ await sql`
1433
+ UPDATE _dineway_collections
1434
+ SET url_pattern = '/posts/{slug}'
1435
+ WHERE slug = 'posts' AND url_pattern IS NULL
1436
+ `.execute(db);
1437
+ await sql`
1438
+ UPDATE _dineway_collections
1439
+ SET url_pattern = '/{slug}'
1440
+ WHERE slug = 'pages' AND url_pattern IS NULL
1441
+ `.execute(db);
1442
+ }
1443
+ async function down$8(db) {
1444
+ await sql`
1445
+ UPDATE _dineway_collections
1446
+ SET url_pattern = NULL
1447
+ WHERE slug = 'posts' AND url_pattern = '/posts/{slug}'
1448
+ `.execute(db);
1449
+ await sql`
1450
+ UPDATE _dineway_collections
1451
+ SET url_pattern = NULL
1452
+ WHERE slug = 'pages' AND url_pattern = '/{slug}'
1453
+ `.execute(db);
1454
+ }
1455
+
1456
+ //#endregion
1457
+ //#region src/database/migrations/036_activity_log.ts
1458
+ var _036_activity_log_exports = /* @__PURE__ */ __exportAll({
1459
+ down: () => down$7,
1460
+ up: () => up$7
1461
+ });
1462
+ /**
1463
+ * Site Context Engine activity foundation.
1464
+ *
1465
+ * This is an append-only domain activity log for meaningful site operations,
1466
+ * not a request log. Actor IDs intentionally have no foreign key because the
1467
+ * actor source can be users, API tokens, or a stable system actor.
1468
+ */
1469
+ async function up$7(db) {
1470
+ await db.schema.createTable("_dineway_activity_log").addColumn("id", "text", (col) => col.primaryKey()).addColumn("actor_type", "text", (col) => col.notNull().check(sql`actor_type in ('user', 'api_token', 'system')`)).addColumn("actor_id", "text", (col) => col.notNull()).addColumn("auth_metadata", "text").addColumn("action_type", "text", (col) => col.notNull()).addColumn("subject_type", "text", (col) => col.notNull()).addColumn("subject_id", "text").addColumn("related_subject_type", "text").addColumn("related_subject_id", "text").addColumn("source_type", "text", (col) => col.check(sql`source_type is null or source_type in ('api_route', 'mcp_tool', 'system', 'plugin', 'unknown')`)).addColumn("source_name", "text").addColumn("result_status", "text", (col) => col.notNull().defaultTo("succeeded").check(sql`result_status in ('succeeded', 'pending', 'failed', 'blocked')`)).addColumn("scope", "text", (col) => col.notNull()).addColumn("summary", "text", (col) => col.notNull()).addColumn("detail", "text").addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).execute();
1471
+ await db.schema.createIndex("idx_dineway_activity_actor").on("_dineway_activity_log").columns([
1472
+ "actor_type",
1473
+ "actor_id",
1474
+ "created_at"
1475
+ ]).execute();
1476
+ await db.schema.createIndex("idx_dineway_activity_scope").on("_dineway_activity_log").columns(["scope", "created_at"]).execute();
1477
+ await db.schema.createIndex("idx_dineway_activity_action_type").on("_dineway_activity_log").columns(["action_type", "created_at"]).execute();
1478
+ await db.schema.createIndex("idx_dineway_activity_subject").on("_dineway_activity_log").columns([
1479
+ "subject_type",
1480
+ "subject_id",
1481
+ "created_at"
1482
+ ]).execute();
1483
+ await db.schema.createIndex("idx_dineway_activity_related_subject").on("_dineway_activity_log").columns([
1484
+ "related_subject_type",
1485
+ "related_subject_id",
1486
+ "created_at"
1487
+ ]).execute();
1488
+ await db.schema.createIndex("idx_dineway_activity_source").on("_dineway_activity_log").columns([
1489
+ "source_type",
1490
+ "source_name",
1491
+ "created_at"
1492
+ ]).execute();
1493
+ await db.schema.createIndex("idx_dineway_activity_result_status").on("_dineway_activity_log").columns(["result_status", "created_at"]).execute();
1494
+ await db.schema.createIndex("idx_dineway_activity_created_at").on("_dineway_activity_log").column("created_at").execute();
1495
+ }
1496
+ async function down$7(db) {
1497
+ await db.schema.dropTable("_dineway_activity_log").execute();
1498
+ }
1499
+
1500
+ //#endregion
1501
+ //#region src/database/migrations/037_context_entries.ts
1502
+ var _037_context_entries_exports = /* @__PURE__ */ __exportAll({
1503
+ down: () => down$6,
1504
+ up: () => up$6
1505
+ });
1506
+ const CONTEXT_TYPE_SQL = [
1507
+ "brand_voice",
1508
+ "seo_strategy",
1509
+ "audience",
1510
+ "content_guideline",
1511
+ "forbidden_terms",
1512
+ "editorial_policy",
1513
+ "migration_note",
1514
+ "plugin_note",
1515
+ "agent_reasoning",
1516
+ "decision",
1517
+ "risk",
1518
+ "content_gap",
1519
+ "style_exception"
1520
+ ].map((type) => `'${type}'`).join(", ");
1521
+ /**
1522
+ * Typed, versioned Site Context Engine entries.
1523
+ *
1524
+ * Entries are scoped by deterministic strings (`site`, `collection:{slug}`,
1525
+ * `content:{collection}:{id}`, `plugin:{id}`). Supersede keeps audit history by
1526
+ * marking old entries non-current and linking replacements through
1527
+ * `supersedes_id`.
1528
+ */
1529
+ async function up$6(db) {
1530
+ await db.schema.createTable("_dineway_context_entries").addColumn("id", "text", (col) => col.primaryKey()).addColumn("scope", "text", (col) => col.notNull()).addColumn("context_type", "text", (col) => col.notNull().check(sql`context_type in (${sql.raw(CONTEXT_TYPE_SQL)})`)).addColumn("title", "text", (col) => col.notNull()).addColumn("body", "text", (col) => col.notNull()).addColumn("policy_key", "text").addColumn("source_activity_id", "text").addColumn("created_by_actor_type", "text", (col) => col.notNull().check(sql`created_by_actor_type in ('user', 'api_token', 'system')`)).addColumn("created_by_actor_id", "text", (col) => col.notNull()).addColumn("created_auth_metadata", "text").addColumn("supersedes_id", "text").addColumn("version", "integer", (col) => col.notNull().defaultTo(1)).addColumn("is_current", "integer", (col) => col.notNull().defaultTo(1).check(sql`is_current in (0, 1)`)).addColumn("valid_until", "text").addColumn("reviewed_at", "text").addColumn("reviewed_by_actor_type", "text", (col) => col.check(sql`reviewed_by_actor_type is null or reviewed_by_actor_type in ('user', 'api_token', 'system')`)).addColumn("reviewed_by_actor_id", "text").addColumn("review_note", "text").addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addForeignKeyConstraint("fk_dineway_context_source_activity", ["source_activity_id"], "_dineway_activity_log", ["id"], (cb) => cb.onDelete("set null")).addForeignKeyConstraint("fk_dineway_context_supersedes", ["supersedes_id"], "_dineway_context_entries", ["id"], (cb) => cb.onDelete("set null")).execute();
1531
+ await db.schema.createTable("_dineway_context_tags").addColumn("context_entry_id", "text", (col) => col.notNull()).addColumn("tag", "text", (col) => col.notNull()).addPrimaryKeyConstraint("pk_dineway_context_tags", ["context_entry_id", "tag"]).addForeignKeyConstraint("fk_dineway_context_tags_entry", ["context_entry_id"], "_dineway_context_entries", ["id"], (cb) => cb.onDelete("cascade")).execute();
1532
+ await db.schema.createIndex("idx_dineway_context_scope_current").on("_dineway_context_entries").columns([
1533
+ "scope",
1534
+ "is_current",
1535
+ "context_type",
1536
+ "updated_at"
1537
+ ]).execute();
1538
+ await db.schema.createIndex("idx_dineway_context_type").on("_dineway_context_entries").columns(["context_type", "updated_at"]).execute();
1539
+ await db.schema.createIndex("idx_dineway_context_stale").on("_dineway_context_entries").columns(["is_current", "valid_until"]).execute();
1540
+ await db.schema.createIndex("idx_dineway_context_policy").on("_dineway_context_entries").columns([
1541
+ "scope",
1542
+ "policy_key",
1543
+ "is_current"
1544
+ ]).execute();
1545
+ await db.schema.createIndex("idx_dineway_context_supersedes").on("_dineway_context_entries").column("supersedes_id").execute();
1546
+ await db.schema.createIndex("idx_dineway_context_actor").on("_dineway_context_entries").columns([
1547
+ "created_by_actor_type",
1548
+ "created_by_actor_id",
1549
+ "created_at"
1550
+ ]).execute();
1551
+ await db.schema.createIndex("idx_dineway_context_created_at").on("_dineway_context_entries").column("created_at").execute();
1552
+ await db.schema.createIndex("idx_dineway_context_tags_tag").on("_dineway_context_tags").columns(["tag", "context_entry_id"]).execute();
1553
+ }
1554
+ async function down$6(db) {
1555
+ await db.schema.dropTable("_dineway_context_tags").execute();
1556
+ await db.schema.dropTable("_dineway_context_entries").execute();
1557
+ }
1558
+
1559
+ //#endregion
1560
+ //#region src/database/migrations/038_review_requests.ts
1561
+ var _038_review_requests_exports = /* @__PURE__ */ __exportAll({
1562
+ down: () => down$5,
1563
+ up: () => up$5
1564
+ });
1565
+ /**
1566
+ * Lightweight content review requests for Phase 5a.
1567
+ *
1568
+ * Review requests bind human approval to immutable content revision/action
1569
+ * identifiers so an approval cannot be reused after the draft or action changes.
1570
+ */
1571
+ async function up$5(db) {
1572
+ await db.schema.createTable("_dineway_review_requests").addColumn("id", "text", (col) => col.primaryKey()).addColumn("status", "text", (col) => col.notNull().defaultTo("pending").check(sql`status in ('pending', 'approved', 'rejected')`)).addColumn("collection", "text", (col) => col.notNull()).addColumn("entry_id", "text", (col) => col.notNull()).addColumn("scope", "text", (col) => col.notNull()).addColumn("live_revision_id", "text").addColumn("draft_revision_id", "text").addColumn("reviewed_rev", "text", (col) => col.notNull()).addColumn("action_type", "text", (col) => col.notNull()).addColumn("action_hash", "text", (col) => col.notNull()).addColumn("risk_reason", "text").addColumn("review_payload", "text", (col) => col.notNull()).addColumn("requested_by_actor_type", "text", (col) => col.notNull().check(sql`requested_by_actor_type in ('user', 'api_token', 'system')`)).addColumn("requested_by_actor_id", "text", (col) => col.notNull()).addColumn("requested_auth_metadata", "text").addColumn("resolved_by_actor_type", "text", (col) => col.check(sql`resolved_by_actor_type is null or resolved_by_actor_type in ('user', 'api_token', 'system')`)).addColumn("resolved_by_actor_id", "text").addColumn("resolved_auth_metadata", "text").addColumn("review_note", "text").addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("resolved_at", "text").execute();
1573
+ await db.schema.createIndex("idx_dineway_review_status_created").on("_dineway_review_requests").columns(["status", "created_at"]).execute();
1574
+ await db.schema.createIndex("idx_dineway_review_target").on("_dineway_review_requests").columns([
1575
+ "collection",
1576
+ "entry_id",
1577
+ "status"
1578
+ ]).execute();
1579
+ await db.schema.createIndex("idx_dineway_review_scope").on("_dineway_review_requests").columns([
1580
+ "scope",
1581
+ "status",
1582
+ "created_at"
1583
+ ]).execute();
1584
+ await db.schema.createIndex("idx_dineway_review_action").on("_dineway_review_requests").columns(["action_type", "action_hash"]).execute();
1585
+ await db.schema.createIndex("idx_dineway_review_requested_actor").on("_dineway_review_requests").columns([
1586
+ "requested_by_actor_type",
1587
+ "requested_by_actor_id",
1588
+ "created_at"
1589
+ ]).execute();
1590
+ await db.schema.createIndex("idx_dineway_review_resolved_at").on("_dineway_review_requests").column("resolved_at").execute();
1591
+ }
1592
+ async function down$5(db) {
1593
+ await db.schema.dropTable("_dineway_review_requests").execute();
1594
+ }
1595
+
1596
+ //#endregion
1597
+ //#region src/database/migrations/039_entity_aliases.ts
1598
+ var _039_entity_aliases_exports = /* @__PURE__ */ __exportAll({
1599
+ down: () => down$4,
1600
+ up: () => up$4
1601
+ });
1602
+ const ENTITY_ALIAS_TYPES = [
1603
+ "content",
1604
+ "collection",
1605
+ "plugin",
1606
+ "taxonomy",
1607
+ "menu"
1608
+ ];
1609
+ /**
1610
+ * Portable alias table for deterministic entity resolution.
1611
+ *
1612
+ * This replaces CRMy's PostgreSQL-specific alias arrays with a normalized
1613
+ * mapping table that works across SQLite/libSQL and PostgreSQL.
1614
+ */
1615
+ async function up$4(db) {
1616
+ const entityTypesSql = sql.join(ENTITY_ALIAS_TYPES.map((value) => sql.lit(value)), sql`, `);
1617
+ await db.schema.createTable("_dineway_entity_aliases").addColumn("id", "text", (col) => col.primaryKey()).addColumn("entity_type", "text", (col) => col.notNull().check(sql`entity_type in (${entityTypesSql})`)).addColumn("collection_slug", "text").addColumn("entity_id", "text", (col) => col.notNull()).addColumn("alias", "text", (col) => col.notNull()).addColumn("normalized_alias", "text", (col) => col.notNull()).addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).execute();
1618
+ await db.schema.createIndex("idx_dineway_entity_alias_lookup").on("_dineway_entity_aliases").columns(["entity_type", "normalized_alias"]).execute();
1619
+ await db.schema.createIndex("idx_dineway_entity_alias_collection_lookup").on("_dineway_entity_aliases").columns([
1620
+ "entity_type",
1621
+ "collection_slug",
1622
+ "normalized_alias"
1623
+ ]).execute();
1624
+ await db.schema.createIndex("idx_dineway_entity_alias_entity").on("_dineway_entity_aliases").columns(["entity_type", "entity_id"]).execute();
1625
+ await db.schema.createIndex("idx_dineway_entity_alias_unique").on("_dineway_entity_aliases").columns([
1626
+ "entity_type",
1627
+ "collection_slug",
1628
+ "entity_id",
1629
+ "normalized_alias"
1630
+ ]).unique().execute();
1631
+ }
1632
+ async function down$4(db) {
1633
+ await db.schema.dropTable("_dineway_entity_aliases").execute();
1634
+ }
1635
+
1636
+ //#endregion
1637
+ //#region src/database/migrations/040_handoff_snapshots.ts
1638
+ var _040_handoff_snapshots_exports = /* @__PURE__ */ __exportAll({
1639
+ down: () => down$3,
1640
+ up: () => up$3
1641
+ });
1642
+ const ACTOR_TYPES$2 = [
1643
+ "user",
1644
+ "api_token",
1645
+ "system"
1646
+ ];
1647
+ const HANDOFF_KINDS = [
1648
+ "pause",
1649
+ "review_request",
1650
+ "assignment"
1651
+ ];
1652
+ const REFERENCE_TYPES = ["review_request", "assignment"];
1653
+ async function up$3(db) {
1654
+ const actorTypesSql = sql.join(ACTOR_TYPES$2.map((value) => sql.lit(value)), sql`, `);
1655
+ const handoffKindsSql = sql.join(HANDOFF_KINDS.map((value) => sql.lit(value)), sql`, `);
1656
+ const referenceTypesSql = sql.join(REFERENCE_TYPES.map((value) => sql.lit(value)), sql`, `);
1657
+ await db.schema.createTable("_dineway_handoff_snapshots").addColumn("id", "text", (col) => col.primaryKey()).addColumn("scope", "text", (col) => col.notNull()).addColumn("actor_type", "text", (col) => col.notNull().check(sql`actor_type in (${actorTypesSql})`)).addColumn("actor_id", "text", (col) => col.notNull()).addColumn("auth_metadata", "text").addColumn("objective", "text", (col) => col.notNull()).addColumn("reasoning", "text", (col) => col.notNull()).addColumn("key_findings", "text", (col) => col.notNull().defaultTo(sql`'[]'`)).addColumn("touched_objects", "text", (col) => col.notNull().defaultTo(sql`'[]'`)).addColumn("pending_actions", "text", (col) => col.notNull().defaultTo(sql`'[]'`)).addColumn("tool_evidence", "text", (col) => col.notNull().defaultTo(sql`'[]'`)).addColumn("confidence", "real").addColumn("handoff_kind", "text", (col) => col.notNull().check(sql`handoff_kind in (${handoffKindsSql})`).defaultTo(sql`'pause'`)).addColumn("reference_type", "text", (col) => col.check(sql`reference_type is null or reference_type in (${referenceTypesSql})`)).addColumn("reference_id", "text").addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("resumed_at", "text").execute();
1658
+ await db.schema.createIndex("idx_dineway_handoff_scope_created").on("_dineway_handoff_snapshots").columns(["scope", "created_at"]).execute();
1659
+ await db.schema.createIndex("idx_dineway_handoff_actor_created").on("_dineway_handoff_snapshots").columns([
1660
+ "actor_type",
1661
+ "actor_id",
1662
+ "created_at"
1663
+ ]).execute();
1664
+ await db.schema.createIndex("idx_dineway_handoff_kind_created").on("_dineway_handoff_snapshots").columns(["handoff_kind", "created_at"]).execute();
1665
+ await db.schema.createIndex("idx_dineway_handoff_reference").on("_dineway_handoff_snapshots").columns(["reference_type", "reference_id"]).execute();
1666
+ }
1667
+ async function down$3(db) {
1668
+ await db.schema.dropTable("_dineway_handoff_snapshots").execute();
1669
+ }
1670
+
1671
+ //#endregion
1672
+ //#region src/database/migrations/041_assignments.ts
1673
+ var _041_assignments_exports = /* @__PURE__ */ __exportAll({
1674
+ down: () => down$2,
1675
+ up: () => up$2
1676
+ });
1677
+ const ACTOR_TYPES$1 = [
1678
+ "user",
1679
+ "api_token",
1680
+ "system"
1681
+ ];
1682
+ const ASSIGNMENT_STATUSES = [
1683
+ "pending",
1684
+ "accepted",
1685
+ "in_progress",
1686
+ "blocked",
1687
+ "completed",
1688
+ "declined",
1689
+ "cancelled"
1690
+ ];
1691
+ const ASSIGNMENT_PRIORITIES = [
1692
+ "low",
1693
+ "normal",
1694
+ "high",
1695
+ "urgent"
1696
+ ];
1697
+ async function up$2(db) {
1698
+ const actorTypesSql = sql.join(ACTOR_TYPES$1.map((value) => sql.lit(value)), sql`, `);
1699
+ const statusesSql = sql.join(ASSIGNMENT_STATUSES.map((value) => sql.lit(value)), sql`, `);
1700
+ const prioritiesSql = sql.join(ASSIGNMENT_PRIORITIES.map((value) => sql.lit(value)), sql`, `);
1701
+ await db.schema.createTable("_dineway_assignments").addColumn("id", "text", (col) => col.primaryKey()).addColumn("scope", "text", (col) => col.notNull()).addColumn("assignment_type", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo(sql`'pending'`).check(sql`status in (${statusesSql})`)).addColumn("priority", "text", (col) => col.notNull().defaultTo(sql`'normal'`).check(sql`priority in (${prioritiesSql})`)).addColumn("title", "text", (col) => col.notNull()).addColumn("summary", "text").addColumn("details", "text").addColumn("assigned_by_actor_type", "text", (col) => col.notNull().check(sql`assigned_by_actor_type in (${actorTypesSql})`)).addColumn("assigned_by_actor_id", "text", (col) => col.notNull()).addColumn("assigned_to_actor_type", "text", (col) => col.check(sql`assigned_to_actor_type is null or assigned_to_actor_type in (${actorTypesSql})`)).addColumn("assigned_to_actor_id", "text").addColumn("metadata", "text", (col) => col.notNull().defaultTo(sql`'{}'`)).addColumn("related_handoff_snapshot_id", "text", (col) => col.references("_dineway_handoff_snapshots.id").onDelete("set null")).addColumn("due_at", "text").addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("accepted_at", "text").addColumn("started_at", "text").addColumn("blocked_at", "text").addColumn("completed_at", "text").addColumn("declined_at", "text").addColumn("cancelled_at", "text").execute();
1702
+ await db.schema.createIndex("idx_dineway_assignment_status_created").on("_dineway_assignments").columns(["status", "created_at"]).execute();
1703
+ await db.schema.createIndex("idx_dineway_assignment_scope_status").on("_dineway_assignments").columns([
1704
+ "scope",
1705
+ "status",
1706
+ "created_at"
1707
+ ]).execute();
1708
+ await db.schema.createIndex("idx_dineway_assignment_type_status").on("_dineway_assignments").columns([
1709
+ "assignment_type",
1710
+ "status",
1711
+ "created_at"
1712
+ ]).execute();
1713
+ await db.schema.createIndex("idx_dineway_assignment_assigned_to").on("_dineway_assignments").columns([
1714
+ "assigned_to_actor_type",
1715
+ "assigned_to_actor_id",
1716
+ "status",
1717
+ "created_at"
1718
+ ]).execute();
1719
+ await db.schema.createIndex("idx_dineway_assignment_assigned_by").on("_dineway_assignments").columns([
1720
+ "assigned_by_actor_type",
1721
+ "assigned_by_actor_id",
1722
+ "status",
1723
+ "created_at"
1724
+ ]).execute();
1725
+ await db.schema.createIndex("idx_dineway_assignment_priority_created").on("_dineway_assignments").columns(["priority", "created_at"]).execute();
1726
+ await db.schema.createIndex("idx_dineway_assignment_due_at").on("_dineway_assignments").column("due_at").execute();
1727
+ await db.schema.createIndex("idx_dineway_assignment_handoff").on("_dineway_assignments").column("related_handoff_snapshot_id").execute();
1728
+ }
1729
+ async function down$2(db) {
1730
+ await db.schema.dropTable("_dineway_assignments").execute();
1731
+ }
1732
+
1733
+ //#endregion
1734
+ //#region src/database/migrations/042_hitl_requests.ts
1735
+ var _042_hitl_requests_exports = /* @__PURE__ */ __exportAll({
1736
+ down: () => down$1,
1737
+ up: () => up$1
1738
+ });
1739
+ const ACTOR_TYPES = [
1740
+ "user",
1741
+ "api_token",
1742
+ "system"
1743
+ ];
1744
+ const HITL_STATUSES = [
1745
+ "pending",
1746
+ "approved",
1747
+ "rejected"
1748
+ ];
1749
+ const HITL_PRIORITIES = [
1750
+ "low",
1751
+ "normal",
1752
+ "high",
1753
+ "urgent"
1754
+ ];
1755
+ async function up$1(db) {
1756
+ const actorTypesSql = sql.join(ACTOR_TYPES.map((value) => sql.lit(value)), sql`, `);
1757
+ const statusesSql = sql.join(HITL_STATUSES.map((value) => sql.lit(value)), sql`, `);
1758
+ const prioritiesSql = sql.join(HITL_PRIORITIES.map((value) => sql.lit(value)), sql`, `);
1759
+ await db.schema.createTable("_dineway_hitl_requests").addColumn("id", "text", (col) => col.primaryKey()).addColumn("scope", "text", (col) => col.notNull()).addColumn("action_type", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo(sql`'pending'`).check(sql`status in (${statusesSql})`)).addColumn("priority", "text", (col) => col.notNull().defaultTo(sql`'normal'`).check(sql`priority in (${prioritiesSql})`)).addColumn("title", "text", (col) => col.notNull()).addColumn("summary", "text").addColumn("risk_reason", "text", (col) => col.notNull()).addColumn("review_payload", "text", (col) => col.notNull()).addColumn("target_ref_type", "text", (col) => col.notNull()).addColumn("target_ref_id", "text", (col) => col.notNull()).addColumn("requested_by_actor_type", "text", (col) => col.notNull().check(sql`requested_by_actor_type in (${actorTypesSql})`)).addColumn("requested_by_actor_id", "text", (col) => col.notNull()).addColumn("requested_auth_metadata", "text").addColumn("resolved_by_actor_type", "text", (col) => col.check(sql`resolved_by_actor_type is null or resolved_by_actor_type in (${actorTypesSql})`)).addColumn("resolved_by_actor_id", "text").addColumn("resolved_auth_metadata", "text").addColumn("review_note", "text").addColumn("metadata", "text", (col) => col.notNull().defaultTo(sql`'{}'`)).addColumn("related_assignment_id", "text", (col) => col.references("_dineway_assignments.id").onDelete("set null")).addColumn("related_handoff_snapshot_id", "text", (col) => col.references("_dineway_handoff_snapshots.id").onDelete("set null")).addColumn("sla_due_at", "text").addColumn("created_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("updated_at", "text", (col) => col.notNull().defaultTo(currentTimestamp(db))).addColumn("resolved_at", "text").execute();
1760
+ await db.schema.alterTable("_dineway_assignments").addColumn("related_hitl_request_id", "text", (col) => col.references("_dineway_hitl_requests.id").onDelete("set null")).execute();
1761
+ await db.schema.createIndex("idx_dineway_hitl_status_created").on("_dineway_hitl_requests").columns(["status", "created_at"]).execute();
1762
+ await db.schema.createIndex("idx_dineway_hitl_scope_status").on("_dineway_hitl_requests").columns([
1763
+ "scope",
1764
+ "status",
1765
+ "created_at"
1766
+ ]).execute();
1767
+ await db.schema.createIndex("idx_dineway_hitl_action_status").on("_dineway_hitl_requests").columns([
1768
+ "action_type",
1769
+ "status",
1770
+ "created_at"
1771
+ ]).execute();
1772
+ await db.schema.createIndex("idx_dineway_hitl_requested_actor").on("_dineway_hitl_requests").columns([
1773
+ "requested_by_actor_type",
1774
+ "requested_by_actor_id",
1775
+ "status",
1776
+ "created_at"
1777
+ ]).execute();
1778
+ await db.schema.createIndex("idx_dineway_hitl_target_ref").on("_dineway_hitl_requests").columns([
1779
+ "target_ref_type",
1780
+ "target_ref_id",
1781
+ "status",
1782
+ "created_at"
1783
+ ]).execute();
1784
+ await db.schema.createIndex("idx_dineway_hitl_priority_created").on("_dineway_hitl_requests").columns(["priority", "created_at"]).execute();
1785
+ await db.schema.createIndex("idx_dineway_hitl_assignment").on("_dineway_hitl_requests").column("related_assignment_id").execute();
1786
+ await db.schema.createIndex("idx_dineway_hitl_handoff").on("_dineway_hitl_requests").column("related_handoff_snapshot_id").execute();
1787
+ await db.schema.createIndex("idx_dineway_hitl_sla_due_at").on("_dineway_hitl_requests").column("sla_due_at").execute();
1788
+ await db.schema.createIndex("idx_dineway_assignment_hitl").on("_dineway_assignments").column("related_hitl_request_id").execute();
1789
+ }
1790
+ async function down$1(db) {
1791
+ await db.schema.dropIndex("idx_dineway_assignment_hitl").execute();
1792
+ await db.schema.alterTable("_dineway_assignments").dropColumn("related_hitl_request_id").execute();
1793
+ await db.schema.dropTable("_dineway_hitl_requests").execute();
1794
+ }
1795
+
1796
+ //#endregion
1797
+ //#region src/database/migrations/043_bounded_404_log.ts
1798
+ var _043_bounded_404_log_exports = /* @__PURE__ */ __exportAll({
1799
+ down: () => down,
1800
+ up: () => up
1801
+ });
1802
+ /**
1803
+ * Migration: Bounded 404 logging
1804
+ *
1805
+ * Hardens `_dineway_404_log` against unauthenticated storage growth.
1806
+ * Previously every 404 inserted a new row, so a requester could grow the
1807
+ * table without bound by hitting unique URLs.
1808
+ */
1809
+ async function up(db) {
1810
+ await db.schema.alterTable("_dineway_404_log").addColumn("hits", "integer", (col) => col.notNull().defaultTo(1)).execute();
1811
+ await db.schema.alterTable("_dineway_404_log").addColumn("last_seen_at", "text").execute();
1812
+ await sql`
1813
+ UPDATE _dineway_404_log
1814
+ SET last_seen_at = created_at
1815
+ WHERE last_seen_at IS NULL
1816
+ `.execute(db);
1817
+ await sql`
1818
+ WITH ranked AS (
1819
+ SELECT
1820
+ id,
1821
+ path,
1822
+ ROW_NUMBER() OVER (
1823
+ PARTITION BY path
1824
+ ORDER BY created_at DESC, id DESC
1825
+ ) AS rn,
1826
+ COUNT(*) OVER (PARTITION BY path) AS path_count,
1827
+ MAX(created_at) OVER (PARTITION BY path) AS latest_created_at
1828
+ FROM _dineway_404_log
1829
+ )
1830
+ UPDATE _dineway_404_log
1831
+ SET
1832
+ hits = (SELECT path_count FROM ranked WHERE ranked.id = _dineway_404_log.id),
1833
+ last_seen_at = (SELECT latest_created_at FROM ranked WHERE ranked.id = _dineway_404_log.id)
1834
+ WHERE id IN (SELECT id FROM ranked WHERE rn = 1)
1835
+ `.execute(db);
1836
+ await sql`
1837
+ DELETE FROM _dineway_404_log
1838
+ WHERE id IN (
1839
+ SELECT id FROM (
1840
+ SELECT
1841
+ id,
1842
+ ROW_NUMBER() OVER (
1843
+ PARTITION BY path
1844
+ ORDER BY created_at DESC, id DESC
1845
+ ) AS rn
1846
+ FROM _dineway_404_log
1847
+ ) AS ranked
1848
+ WHERE rn > 1
1849
+ )
1850
+ `.execute(db);
1851
+ await db.schema.createIndex("idx_404_log_path_unique").on("_dineway_404_log").column("path").unique().execute();
1852
+ await db.schema.dropIndex("idx_404_log_path").execute();
1853
+ await db.schema.createIndex("idx_404_log_last_seen").on("_dineway_404_log").column("last_seen_at").execute();
1854
+ }
1855
+ async function down(db) {
1856
+ await db.schema.dropIndex("idx_404_log_last_seen").execute();
1857
+ await db.schema.dropIndex("idx_404_log_path_unique").execute();
1858
+ await db.schema.createIndex("idx_404_log_path").on("_dineway_404_log").column("path").execute();
1859
+ await db.schema.alterTable("_dineway_404_log").dropColumn("last_seen_at").execute();
1860
+ await db.schema.alterTable("_dineway_404_log").dropColumn("hits").execute();
1861
+ }
1862
+
1420
1863
  //#endregion
1421
1864
  //#region src/database/migrations/runner.ts
1422
1865
  const MIGRATIONS = Object.freeze({
@@ -1452,7 +1895,16 @@ const MIGRATIONS = Object.freeze({
1452
1895
  "031_bylines": _031_bylines_exports,
1453
1896
  "032_rate_limits": _032_rate_limits_exports,
1454
1897
  "033_optimize_content_indexes": _033_optimize_content_indexes_exports,
1455
- "034_published_at_index": _034_published_at_index_exports
1898
+ "034_published_at_index": _034_published_at_index_exports,
1899
+ "035_backfill_url_patterns": _035_backfill_url_patterns_exports,
1900
+ "036_activity_log": _036_activity_log_exports,
1901
+ "037_context_entries": _037_context_entries_exports,
1902
+ "038_review_requests": _038_review_requests_exports,
1903
+ "039_entity_aliases": _039_entity_aliases_exports,
1904
+ "040_handoff_snapshots": _040_handoff_snapshots_exports,
1905
+ "041_assignments": _041_assignments_exports,
1906
+ "042_hitl_requests": _042_hitl_requests_exports,
1907
+ "043_bounded_404_log": _043_bounded_404_log_exports
1456
1908
  });
1457
1909
  /** Total number of registered migrations. Exported for use in tests. */
1458
1910
  const MIGRATION_COUNT = Object.keys(MIGRATIONS).length;