nextly 0.0.1 → 0.0.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +122 -0
  3. package/dist/_dts-chunks/collections-handler.d-DjgO74Wt.d.ts +20540 -0
  4. package/dist/_dts-chunks/config.d-DNwsDnjs.d.ts +2589 -0
  5. package/dist/_dts-chunks/define-component.d-BUgTHmt3.d.ts +1149 -0
  6. package/dist/_dts-chunks/image-processor.d-OO1PmMrv.d.ts +335 -0
  7. package/dist/_dts-chunks/index.d-axCAzZ7m.d.ts +17842 -0
  8. package/dist/_dts-chunks/media.d-DjDOZo4B.d.ts +117 -0
  9. package/dist/_dts-chunks/on-error.d-CHIKWNxd.d.ts +38 -0
  10. package/dist/_dts-chunks/storage.d-BUhQ2we_.d.ts +404 -0
  11. package/dist/actions/index.d.ts +239 -0
  12. package/dist/actions/index.mjs +281 -0
  13. package/dist/api/auth-state.d.ts +5 -0
  14. package/dist/api/auth-state.mjs +131 -0
  15. package/dist/api/collections-schema-detail.d.ts +56 -0
  16. package/dist/api/collections-schema-detail.mjs +244 -0
  17. package/dist/api/collections-schema-export.d.ts +56 -0
  18. package/dist/api/collections-schema-export.mjs +129 -0
  19. package/dist/api/collections-schema.d.ts +59 -0
  20. package/dist/api/collections-schema.mjs +207 -0
  21. package/dist/api/components-detail.d.ts +50 -0
  22. package/dist/api/components-detail.mjs +132 -0
  23. package/dist/api/components.d.ts +69 -0
  24. package/dist/api/components.mjs +144 -0
  25. package/dist/api/email-providers-default.d.ts +40 -0
  26. package/dist/api/email-providers-default.mjs +75 -0
  27. package/dist/api/email-providers-detail.d.ts +81 -0
  28. package/dist/api/email-providers-detail.mjs +109 -0
  29. package/dist/api/email-providers-test.d.ts +43 -0
  30. package/dist/api/email-providers-test.mjs +114 -0
  31. package/dist/api/email-providers.d.ts +69 -0
  32. package/dist/api/email-providers.mjs +110 -0
  33. package/dist/api/email-send-template.d.ts +41 -0
  34. package/dist/api/email-send-template.mjs +58 -0
  35. package/dist/api/email-send.d.ts +42 -0
  36. package/dist/api/email-send.mjs +58 -0
  37. package/dist/api/email-templates-detail.d.ts +74 -0
  38. package/dist/api/email-templates-detail.mjs +112 -0
  39. package/dist/api/email-templates-layout.d.ts +55 -0
  40. package/dist/api/email-templates-layout.mjs +92 -0
  41. package/dist/api/email-templates-preview.d.ts +48 -0
  42. package/dist/api/email-templates-preview.mjs +93 -0
  43. package/dist/api/email-templates.d.ts +61 -0
  44. package/dist/api/email-templates.mjs +118 -0
  45. package/dist/api/health.d.ts +68 -0
  46. package/dist/api/health.mjs +67 -0
  47. package/dist/api/index.d.ts +54 -0
  48. package/dist/api/index.mjs +16 -0
  49. package/dist/api/media-bulk.d.ts +74 -0
  50. package/dist/api/media-bulk.mjs +196 -0
  51. package/dist/api/media-folders.d.ts +112 -0
  52. package/dist/api/media-folders.mjs +187 -0
  53. package/dist/api/media-handlers.d.ts +102 -0
  54. package/dist/api/media-handlers.mjs +437 -0
  55. package/dist/api/media.d.ts +117 -0
  56. package/dist/api/media.mjs +242 -0
  57. package/dist/api/singles-detail.d.ts +87 -0
  58. package/dist/api/singles-detail.mjs +170 -0
  59. package/dist/api/singles-schema-detail.d.ts +54 -0
  60. package/dist/api/singles-schema-detail.mjs +182 -0
  61. package/dist/api/singles.d.ts +34 -0
  62. package/dist/api/singles.mjs +94 -0
  63. package/dist/api/storage-upload-url.d.ts +48 -0
  64. package/dist/api/storage-upload-url.mjs +202 -0
  65. package/dist/api/uploads.d.ts +109 -0
  66. package/dist/api/uploads.mjs +359 -0
  67. package/dist/auth/index.d.ts +425 -0
  68. package/dist/auth/index.mjs +199 -0
  69. package/dist/boot-apply-PQSYLDIN.mjs +7 -0
  70. package/dist/chunk-2OALJTK6.mjs +489 -0
  71. package/dist/chunk-2Q2SX2CS.mjs +365 -0
  72. package/dist/chunk-2TFX4ND3.mjs +13 -0
  73. package/dist/chunk-2TWPDSYD.mjs +87 -0
  74. package/dist/chunk-2W3DVD7S.mjs +647 -0
  75. package/dist/chunk-2ZFKXPQM.mjs +88 -0
  76. package/dist/chunk-3FA7FKAV.mjs +832 -0
  77. package/dist/chunk-3NZ2KMBL.mjs +58 -0
  78. package/dist/chunk-4MJLT6PZ.mjs +0 -0
  79. package/dist/chunk-56WO4WX7.mjs +0 -0
  80. package/dist/chunk-5APFUGAD.mjs +89 -0
  81. package/dist/chunk-5HMZ644B.mjs +108 -0
  82. package/dist/chunk-67GXH6PR.mjs +32 -0
  83. package/dist/chunk-6JNEPWRW.mjs +14368 -0
  84. package/dist/chunk-6NFHQIJD.mjs +45 -0
  85. package/dist/chunk-7P6ASYW6.mjs +9 -0
  86. package/dist/chunk-A3WPLSDT.mjs +1364 -0
  87. package/dist/chunk-AGJ6F2T3.mjs +144 -0
  88. package/dist/chunk-AK6Z23OX.mjs +1464 -0
  89. package/dist/chunk-APKKRD2G.mjs +102 -0
  90. package/dist/chunk-B2GV2BWH.mjs +73 -0
  91. package/dist/chunk-D5HQBNUB.mjs +74 -0
  92. package/dist/chunk-DNNG377Z.mjs +204 -0
  93. package/dist/chunk-DP3G27G5.mjs +135 -0
  94. package/dist/chunk-DV6WVX2Q.mjs +0 -0
  95. package/dist/chunk-DXGGXIUZ.mjs +57 -0
  96. package/dist/chunk-EGXBZCGC.mjs +943 -0
  97. package/dist/chunk-ERCNLX3V.mjs +176 -0
  98. package/dist/chunk-FQULBZ53.mjs +850 -0
  99. package/dist/chunk-G2AA4QLC.mjs +262 -0
  100. package/dist/chunk-GDBJ5JCU.mjs +488 -0
  101. package/dist/chunk-GJNSJU4S.mjs +19 -0
  102. package/dist/chunk-GZ6DCQKC.mjs +69 -0
  103. package/dist/chunk-H26B4FYG.mjs +167 -0
  104. package/dist/chunk-I4JMR3UR.mjs +21 -0
  105. package/dist/chunk-INV7QKLG.mjs +508 -0
  106. package/dist/chunk-IUDOC7N7.mjs +46 -0
  107. package/dist/chunk-IZWPRDC3.mjs +206 -0
  108. package/dist/chunk-KIMNCZGV.mjs +15 -0
  109. package/dist/chunk-L6HW2DA7.mjs +15 -0
  110. package/dist/chunk-LAZXX4HR.mjs +100 -0
  111. package/dist/chunk-LDKCUMHK.mjs +95 -0
  112. package/dist/chunk-LRXMECUA.mjs +0 -0
  113. package/dist/chunk-M52VMPGA.mjs +119 -0
  114. package/dist/chunk-MGUWEEI6.mjs +160 -0
  115. package/dist/chunk-NRUWQ5Z7.mjs +419 -0
  116. package/dist/chunk-NSEFNNU4.mjs +25360 -0
  117. package/dist/chunk-NTHVDFGO.mjs +138 -0
  118. package/dist/chunk-O3QHXMOX.mjs +3166 -0
  119. package/dist/chunk-P7NH2OSC.mjs +2605 -0
  120. package/dist/chunk-PKMABBB5.mjs +184 -0
  121. package/dist/chunk-PWS6XGJK.mjs +76 -0
  122. package/dist/chunk-R6JJQHFC.mjs +20 -0
  123. package/dist/chunk-RJLLGGPG.mjs +0 -0
  124. package/dist/chunk-SBACDPNX.mjs +689 -0
  125. package/dist/chunk-TO5AFLVQ.mjs +124 -0
  126. package/dist/chunk-TS7GHTG2.mjs +5436 -0
  127. package/dist/chunk-UJ2IMJ4W.mjs +133 -0
  128. package/dist/chunk-UOP63Q54.mjs +102 -0
  129. package/dist/chunk-UUOFWCM6.mjs +78 -0
  130. package/dist/chunk-V4EQTOA4.mjs +893 -0
  131. package/dist/chunk-VJ66NCL4.mjs +193 -0
  132. package/dist/chunk-VQJQHVEV.mjs +29 -0
  133. package/dist/chunk-VTJADRO3.mjs +141 -0
  134. package/dist/chunk-VWF3JO32.mjs +0 -0
  135. package/dist/chunk-W4MGXIRR.mjs +27 -0
  136. package/dist/chunk-W5KKPZT5.mjs +1204 -0
  137. package/dist/chunk-WD34YQ6T.mjs +381 -0
  138. package/dist/chunk-WZBYMYVW.mjs +14 -0
  139. package/dist/chunk-X23WKS3Z.mjs +50 -0
  140. package/dist/chunk-X7TXCYYN.mjs +6496 -0
  141. package/dist/chunk-XGI4EMS3.mjs +140 -0
  142. package/dist/chunk-XZKLBMN6.mjs +1153 -0
  143. package/dist/chunk-YB7INWPY.mjs +0 -0
  144. package/dist/chunk-YV4Y7SDL.mjs +83 -0
  145. package/dist/chunk-YZNBLFIW.mjs +1688 -0
  146. package/dist/chunk-YZZCTONM.mjs +263 -0
  147. package/dist/chunk-ZE6A3FYH.mjs +289 -0
  148. package/dist/cli/nextly.mjs +68 -0
  149. package/dist/cli/utils/index.d.ts +449 -0
  150. package/dist/cli/utils/index.mjs +49 -0
  151. package/dist/component-schema-service-5577KVW6.mjs +11 -0
  152. package/dist/config-loader-23YEMC3Z.mjs +23 -0
  153. package/dist/config.d.ts +44 -0
  154. package/dist/config.mjs +109 -0
  155. package/dist/container-ORGFGYSZ.mjs +9 -0
  156. package/dist/database/index.d.ts +12 -0
  157. package/dist/database/index.mjs +40 -0
  158. package/dist/database/seeders/index.d.ts +93 -0
  159. package/dist/database/seeders/index.mjs +47 -0
  160. package/dist/db-sync-demote-LJGKLB3S.mjs +117 -0
  161. package/dist/db-sync-promote-B26VSYQF.mjs +113 -0
  162. package/dist/dev-reload-broadcaster-B73IQ53V.mjs +25 -0
  163. package/dist/dist-M2NOU37V.mjs +19 -0
  164. package/dist/drizzle-kit-lazy-D2M2PXR2.mjs +13 -0
  165. package/dist/dynamic-collection-schema-service-IEXTPIZ7.mjs +8 -0
  166. package/dist/errors/index.d.ts +159 -0
  167. package/dist/errors/index.mjs +10 -0
  168. package/dist/factory-IWMBKUJM.mjs +15 -0
  169. package/dist/first-run-QIVKWJIF.mjs +63 -0
  170. package/dist/fresh-push-NR67DC3R.mjs +8 -0
  171. package/dist/index.d.ts +4175 -0
  172. package/dist/index.mjs +1336 -0
  173. package/dist/local-plugin-PTET4NAT.mjs +7 -0
  174. package/dist/logger-NU46DXNY.mjs +15 -0
  175. package/dist/logger-YE4TC7ZN.mjs +9 -0
  176. package/dist/migration-journal-EP532Y4L.mjs +139 -0
  177. package/dist/migrations/mysql/0000_eager_sentry.sql +174 -0
  178. package/dist/migrations/mysql/0001_soft_giant_girl.sql +27 -0
  179. package/dist/migrations/mysql/0002_media_table.sql +24 -0
  180. package/dist/migrations/mysql/0003_dynamic_singles.sql +37 -0
  181. package/dist/migrations/mysql/0004_dynamic_components.sql +35 -0
  182. package/dist/migrations/mysql/0005_user_management_tables.sql +92 -0
  183. package/dist/migrations/mysql/0006_api_keys.sql +36 -0
  184. package/dist/migrations/mysql/0007_general_settings.sql +20 -0
  185. package/dist/migrations/mysql/0008_site_settings_logo_url.sql +9 -0
  186. package/dist/migrations/mysql/0009_activity_log.sql +30 -0
  187. package/dist/migrations/mysql/0010_site_settings_sidebar.sql +13 -0
  188. package/dist/migrations/mysql/0011_missing_tables_and_columns.sql +54 -0
  189. package/dist/migrations/mysql/0012_image_sizes_and_focal_point.sql +30 -0
  190. package/dist/migrations/mysql/0012_media_folders.sql +43 -0
  191. package/dist/migrations/mysql/0013_user_brute_force_protection.sql +31 -0
  192. package/dist/migrations/mysql/0014_email_template_attachments.sql +12 -0
  193. package/dist/migrations/mysql/0015_media_uploaded_by_nullable.sql +15 -0
  194. package/dist/migrations/mysql/20260429_000000_000_initial_journal.sql +22 -0
  195. package/dist/migrations/mysql/20260501_000000_journal_batch.sql +17 -0
  196. package/dist/migrations/mysql/20260501_000001_audit_log.sql +24 -0
  197. package/dist/migrations/mysql/20260504_000000_nextly_meta.sql +21 -0
  198. package/dist/migrations/mysql/meta/0000_snapshot.json +1005 -0
  199. package/dist/migrations/mysql/meta/0001_snapshot.json +1099 -0
  200. package/dist/migrations/mysql/meta/_journal.json +41 -0
  201. package/dist/migrations/postgresql/0000_misty_king_bedlam.sql +169 -0
  202. package/dist/migrations/postgresql/0001_perpetual_captain_marvel.sql +8 -0
  203. package/dist/migrations/postgresql/0002_sad_spectrum.sql +16 -0
  204. package/dist/migrations/postgresql/0003_hesitant_ultron.sql +17 -0
  205. package/dist/migrations/postgresql/0004_media_table.sql +24 -0
  206. package/dist/migrations/postgresql/0005_media_folders.sql +36 -0
  207. package/dist/migrations/postgresql/0006_dynamic_collections_update.sql +50 -0
  208. package/dist/migrations/postgresql/0007_dynamic_singles.sql +38 -0
  209. package/dist/migrations/postgresql/0008_dynamic_components.sql +37 -0
  210. package/dist/migrations/postgresql/0009_user_management_tables.sql +95 -0
  211. package/dist/migrations/postgresql/0010_api_keys.sql +34 -0
  212. package/dist/migrations/postgresql/0011_general_settings.sql +20 -0
  213. package/dist/migrations/postgresql/0012_site_settings_logo_url.sql +9 -0
  214. package/dist/migrations/postgresql/0013_activity_log.sql +29 -0
  215. package/dist/migrations/postgresql/0014_image_sizes_and_focal_point.sql +33 -0
  216. package/dist/migrations/postgresql/0014_site_settings_sidebar.sql +13 -0
  217. package/dist/migrations/postgresql/0015_user_brute_force_protection.sql +29 -0
  218. package/dist/migrations/postgresql/0016_email_template_attachments.sql +12 -0
  219. package/dist/migrations/postgresql/0017_media_uploaded_by_nullable.sql +15 -0
  220. package/dist/migrations/postgresql/20260429_000000_000_initial_journal.sql +24 -0
  221. package/dist/migrations/postgresql/20260501_000000_journal_batch.sql +17 -0
  222. package/dist/migrations/postgresql/20260501_000001_audit_log.sql +24 -0
  223. package/dist/migrations/postgresql/20260504_000000_nextly_meta.sql +22 -0
  224. package/dist/migrations/postgresql/meta/0000_snapshot.json +1286 -0
  225. package/dist/migrations/postgresql/meta/0001_snapshot.json +1407 -0
  226. package/dist/migrations/postgresql/meta/0002_snapshot.json +1552 -0
  227. package/dist/migrations/postgresql/meta/0003_snapshot.json +1695 -0
  228. package/dist/migrations/postgresql/meta/0010_snapshot.json +2345 -0
  229. package/dist/migrations/postgresql/meta/_journal.json +90 -0
  230. package/dist/migrations/sqlite/0000_api_keys.sql +34 -0
  231. package/dist/migrations/sqlite/0001_general_settings.sql +20 -0
  232. package/dist/migrations/sqlite/0002_site_settings_logo_url.sql +9 -0
  233. package/dist/migrations/sqlite/0003_activity_log.sql +29 -0
  234. package/dist/migrations/sqlite/0004_image_sizes_and_focal_point.sql +29 -0
  235. package/dist/migrations/sqlite/0004_site_settings_sidebar.sql +11 -0
  236. package/dist/migrations/sqlite/0005_user_brute_force_protection.sql +29 -0
  237. package/dist/migrations/sqlite/0006_email_template_attachments.sql +12 -0
  238. package/dist/migrations/sqlite/0007_media_uploaded_by_nullable.sql +111 -0
  239. package/dist/migrations/sqlite/20260429_000000_000_initial_journal.sql +24 -0
  240. package/dist/migrations/sqlite/20260501_000000_journal_batch.sql +19 -0
  241. package/dist/migrations/sqlite/20260501_000001_audit_log.sql +24 -0
  242. package/dist/migrations/sqlite/20260504_000000_nextly_meta.sql +21 -0
  243. package/dist/migrations/sqlite/20260505_000000_user_management_tables.sql +77 -0
  244. package/dist/next.d.ts +57 -0
  245. package/dist/next.mjs +55 -0
  246. package/dist/observability/index.d.ts +87 -0
  247. package/dist/observability/index.mjs +57 -0
  248. package/dist/permissions-3DZZQZMI.mjs +39 -0
  249. package/dist/pipeline-YOML7SWF.mjs +29 -0
  250. package/dist/preview-ZZTR3QGS.mjs +9 -0
  251. package/dist/program-PW6UB2ZC.mjs +5934 -0
  252. package/dist/reconcile-single-tables-7ENVXJGB.mjs +7 -0
  253. package/dist/register-SF6E6FVU.mjs +49 -0
  254. package/dist/reload-config-HWQ4G5MM.mjs +23 -0
  255. package/dist/resolve-single-table-name-JSOMUB3R.mjs +7 -0
  256. package/dist/routeHandler-UNMMJIBM.mjs +77 -0
  257. package/dist/runtime-schema-generator-NRA6A6Z6.mjs +8 -0
  258. package/dist/runtime.d.ts +120 -0
  259. package/dist/runtime.mjs +73 -0
  260. package/dist/schema-hash-FMMG6VPJ.mjs +13 -0
  261. package/dist/schema-registry-EQ36FZDP.mjs +7 -0
  262. package/dist/scripts/load-env.mjs +42 -0
  263. package/dist/storage/index.d.ts +566 -0
  264. package/dist/storage/index.mjs +45 -0
  265. package/dist/super-admin-G5ZK5F4T.mjs +39 -0
  266. package/dist/system-table-service-WGSRVEGT.mjs +17 -0
  267. package/dist/users-7KELGRYJ.mjs +38 -0
  268. package/package.json +308 -9
@@ -0,0 +1,7 @@
1
+ import {
2
+ localStorage
3
+ } from "./chunk-G2AA4QLC.mjs";
4
+ import "./chunk-7P6ASYW6.mjs";
5
+ export {
6
+ localStorage
7
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ createLogger,
3
+ formatBytes,
4
+ formatCount,
5
+ formatDuration,
6
+ logger
7
+ } from "./chunk-MGUWEEI6.mjs";
8
+ import "./chunk-7P6ASYW6.mjs";
9
+ export {
10
+ createLogger,
11
+ formatBytes,
12
+ formatCount,
13
+ formatDuration,
14
+ logger
15
+ };
@@ -0,0 +1,9 @@
1
+ import {
2
+ getNextlyLogger,
3
+ setNextlyLogger
4
+ } from "./chunk-W4MGXIRR.mjs";
5
+ import "./chunk-7P6ASYW6.mjs";
6
+ export {
7
+ getNextlyLogger,
8
+ setNextlyLogger
9
+ };
@@ -0,0 +1,139 @@
1
+ import "./chunk-YB7INWPY.mjs";
2
+ import {
3
+ nextlyMigrationJournalMysql,
4
+ nextlyMigrationJournalPg,
5
+ nextlyMigrationJournalSqlite
6
+ } from "./chunk-H26B4FYG.mjs";
7
+ import "./chunk-7P6ASYW6.mjs";
8
+
9
+ // src/domains/schema/journal/migration-journal.ts
10
+ import { eq } from "drizzle-orm";
11
+ var FAILED_INSERT_PREFIX = "journal-failed-";
12
+ var ERROR_MESSAGE_MAX_LEN = 1e3;
13
+ function stringifyError(err) {
14
+ if (err instanceof Error) return err.message;
15
+ if (typeof err === "string") return err;
16
+ if (typeof err === "number" || typeof err === "boolean") return String(err);
17
+ if (err === null) return "null";
18
+ try {
19
+ return JSON.stringify(err);
20
+ } catch {
21
+ return "[unstringifiable error]";
22
+ }
23
+ }
24
+ var DrizzleMigrationJournal = class {
25
+ db;
26
+ dialect;
27
+ logger;
28
+ // Per-row start time. Stored in-memory between recordStart and
29
+ // recordEnd so we can compute duration_ms without a SELECT round-trip.
30
+ // Keyed by the journal row's id (UUID). If the process restarts
31
+ // mid-apply, the row stays at status='in_progress' indefinitely
32
+ // (admin tooling can find these via the status index).
33
+ startTimes = /* @__PURE__ */ new Map();
34
+ constructor(deps) {
35
+ this.db = deps.db;
36
+ this.dialect = deps.dialect;
37
+ this.logger = deps.logger;
38
+ }
39
+ async recordStart(args) {
40
+ let id;
41
+ try {
42
+ id = crypto.randomUUID();
43
+ } catch (err) {
44
+ const msg = err instanceof Error ? err.message : String(err);
45
+ this.logger.warn?.(
46
+ `[MigrationJournal] crypto.randomUUID() unavailable (${msg}). Skipping journal entry.`
47
+ );
48
+ return `${FAILED_INSERT_PREFIX}no-uuid`;
49
+ }
50
+ const startedAt = /* @__PURE__ */ new Date();
51
+ const startMs = Date.now();
52
+ const table = this.tableForDialect();
53
+ try {
54
+ const inserter = this.db.insert(table);
55
+ const insertValues = {
56
+ id,
57
+ source: args.source,
58
+ status: "in_progress",
59
+ startedAt,
60
+ statementsPlanned: args.statementsPlanned
61
+ };
62
+ if (args.scope) {
63
+ insertValues.scopeKind = args.scope.kind;
64
+ if (args.scope.slug !== void 0) {
65
+ insertValues.scopeSlug = args.scope.slug;
66
+ }
67
+ }
68
+ if (typeof args.batch === "number") {
69
+ insertValues.batch = args.batch;
70
+ }
71
+ await inserter.values(insertValues);
72
+ this.startTimes.set(id, startMs);
73
+ return id;
74
+ } catch (err) {
75
+ const msg = err instanceof Error ? err.message : String(err);
76
+ this.logger.warn?.(
77
+ `[MigrationJournal] recordStart failed (${msg}). Pipeline will continue without journal entry.`
78
+ );
79
+ return `${FAILED_INSERT_PREFIX}${id}`;
80
+ }
81
+ }
82
+ async recordEnd(journalId, args) {
83
+ if (journalId.startsWith(FAILED_INSERT_PREFIX)) {
84
+ return;
85
+ }
86
+ const endedAt = /* @__PURE__ */ new Date();
87
+ const endMs = endedAt.getTime();
88
+ const startMs = this.startTimes.get(journalId);
89
+ const durationMs = startMs !== void 0 ? Math.max(0, endMs - startMs) : null;
90
+ this.startTimes.delete(journalId);
91
+ const status = args.success ? "success" : "failed";
92
+ let errorMessage = null;
93
+ if (!args.success && args.error !== void 0) {
94
+ const raw = stringifyError(args.error);
95
+ errorMessage = raw.length > ERROR_MESSAGE_MAX_LEN ? `${raw.slice(0, ERROR_MESSAGE_MAX_LEN)}...` : raw;
96
+ }
97
+ const table = this.tableForDialect();
98
+ const idColumn = table.id;
99
+ try {
100
+ const updater = this.db.update(table);
101
+ const setValues = {
102
+ status,
103
+ endedAt,
104
+ durationMs,
105
+ statementsExecuted: args.statementsExecuted,
106
+ errorMessage
107
+ };
108
+ if (args.summary) {
109
+ setValues.summaryAdded = args.summary.added;
110
+ setValues.summaryRemoved = args.summary.removed;
111
+ setValues.summaryRenamed = args.summary.renamed;
112
+ setValues.summaryChanged = args.summary.changed;
113
+ }
114
+ await updater.set(setValues).where(eq(idColumn, journalId));
115
+ } catch (err) {
116
+ const msg = err instanceof Error ? err.message : String(err);
117
+ this.logger.warn?.(
118
+ `[MigrationJournal] recordEnd failed for journal '${journalId}' (${msg}). Pipeline result unaffected.`
119
+ );
120
+ }
121
+ }
122
+ tableForDialect() {
123
+ switch (this.dialect) {
124
+ case "postgresql":
125
+ return nextlyMigrationJournalPg;
126
+ case "mysql":
127
+ return nextlyMigrationJournalMysql;
128
+ case "sqlite":
129
+ return nextlyMigrationJournalSqlite;
130
+ default: {
131
+ const exhaustive = this.dialect;
132
+ throw new Error(`Unsupported dialect: ${String(exhaustive)}`);
133
+ }
134
+ }
135
+ }
136
+ };
137
+ export {
138
+ DrizzleMigrationJournal
139
+ };
@@ -0,0 +1,174 @@
1
+ CREATE TABLE `accounts` (
2
+ `id` int AUTO_INCREMENT NOT NULL,
3
+ `user_id` varchar(191) NOT NULL,
4
+ `type` varchar(191) NOT NULL,
5
+ `provider` varchar(191) NOT NULL,
6
+ `provider_account_id` varchar(191) NOT NULL,
7
+ `refresh_token` text,
8
+ `access_token` text,
9
+ `expires_at` int,
10
+ `token_type` varchar(191),
11
+ `scope` text,
12
+ `id_token` text,
13
+ `session_state` varchar(255),
14
+ CONSTRAINT `accounts_id` PRIMARY KEY(`id`),
15
+ CONSTRAINT `accounts_provider_providerAccountId_unique` UNIQUE(`provider`,`provider_account_id`)
16
+ );
17
+ --> statement-breakpoint
18
+ CREATE TABLE `content_schema_events` (
19
+ `id` int AUTO_INCREMENT NOT NULL,
20
+ `op` varchar(191) NOT NULL,
21
+ `table_name` varchar(255) NOT NULL,
22
+ `sql` varchar(1024) NOT NULL,
23
+ `meta` json,
24
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
25
+ CONSTRAINT `content_schema_events_id` PRIMARY KEY(`id`)
26
+ );
27
+ --> statement-breakpoint
28
+ CREATE TABLE `email_verification_tokens` (
29
+ `id` int AUTO_INCREMENT NOT NULL,
30
+ `identifier` varchar(255) NOT NULL,
31
+ `token_hash` varchar(255) NOT NULL,
32
+ `expires` datetime NOT NULL,
33
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
34
+ CONSTRAINT `email_verification_tokens_id` PRIMARY KEY(`id`),
35
+ CONSTRAINT `evt_identifier_token_hash_unique` UNIQUE(`identifier`,`token_hash`)
36
+ );
37
+ --> statement-breakpoint
38
+ CREATE TABLE `example_users` (
39
+ `id` int AUTO_INCREMENT NOT NULL,
40
+ `name` varchar(255),
41
+ CONSTRAINT `example_users_id` PRIMARY KEY(`id`)
42
+ );
43
+ --> statement-breakpoint
44
+ CREATE TABLE `password_reset_tokens` (
45
+ `id` int AUTO_INCREMENT NOT NULL,
46
+ `identifier` varchar(255) NOT NULL,
47
+ `token_hash` varchar(255) NOT NULL,
48
+ `expires` datetime NOT NULL,
49
+ `used_at` datetime,
50
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
51
+ CONSTRAINT `password_reset_tokens_id` PRIMARY KEY(`id`),
52
+ CONSTRAINT `prt_identifier_token_hash_unique` UNIQUE(`identifier`,`token_hash`)
53
+ );
54
+ --> statement-breakpoint
55
+ CREATE TABLE `permissions` (
56
+ `id` varchar(191) NOT NULL,
57
+ `name` varchar(100) NOT NULL,
58
+ `slug` varchar(100) NOT NULL,
59
+ `action` varchar(50) NOT NULL,
60
+ `resource` varchar(50) NOT NULL,
61
+ `description` varchar(255),
62
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
63
+ `updated_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
64
+ CONSTRAINT `permissions_id` PRIMARY KEY(`id`),
65
+ CONSTRAINT `permissions_action_resource_unique` UNIQUE(`action`,`resource`),
66
+ CONSTRAINT `permissions_slug_unique` UNIQUE(`slug`)
67
+ );
68
+ --> statement-breakpoint
69
+ CREATE TABLE `role_inherits` (
70
+ `id` varchar(191) NOT NULL,
71
+ `parent_role_id` varchar(191) NOT NULL,
72
+ `child_role_id` varchar(191) NOT NULL,
73
+ CONSTRAINT `role_inherits_id` PRIMARY KEY(`id`),
74
+ CONSTRAINT `role_inherits_parent_child_unique` UNIQUE(`parent_role_id`,`child_role_id`)
75
+ );
76
+ --> statement-breakpoint
77
+ CREATE TABLE `role_permissions` (
78
+ `id` varchar(191) NOT NULL,
79
+ `role_id` varchar(191) NOT NULL,
80
+ `permission_id` varchar(191) NOT NULL,
81
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
82
+ CONSTRAINT `role_permissions_id` PRIMARY KEY(`id`),
83
+ CONSTRAINT `role_permissions_role_permission_unique` UNIQUE(`role_id`,`permission_id`)
84
+ );
85
+ --> statement-breakpoint
86
+ CREATE TABLE `roles` (
87
+ `id` varchar(191) NOT NULL,
88
+ `name` varchar(50) NOT NULL,
89
+ `slug` varchar(50) NOT NULL,
90
+ `description` varchar(255),
91
+ `level` int NOT NULL DEFAULT 0,
92
+ `is_system` int NOT NULL DEFAULT 0,
93
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
94
+ `updated_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
95
+ CONSTRAINT `roles_id` PRIMARY KEY(`id`),
96
+ CONSTRAINT `roles_name_unique` UNIQUE(`name`),
97
+ CONSTRAINT `roles_slug_unique` UNIQUE(`slug`)
98
+ );
99
+ --> statement-breakpoint
100
+ CREATE TABLE `sessions` (
101
+ `session_token` varchar(255) NOT NULL,
102
+ `user_id` varchar(191) NOT NULL,
103
+ `expires` datetime NOT NULL,
104
+ CONSTRAINT `sessions_session_token` PRIMARY KEY(`session_token`)
105
+ );
106
+ --> statement-breakpoint
107
+ CREATE TABLE `system_migrations` (
108
+ `id` int AUTO_INCREMENT NOT NULL,
109
+ `name` varchar(255) NOT NULL,
110
+ `run_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
111
+ CONSTRAINT `system_migrations_id` PRIMARY KEY(`id`)
112
+ );
113
+ --> statement-breakpoint
114
+ CREATE TABLE `user_permission_cache` (
115
+ `id` varchar(255) NOT NULL,
116
+ `user_id` varchar(191) NOT NULL,
117
+ `action` varchar(50) NOT NULL,
118
+ `resource` varchar(100) NOT NULL,
119
+ `has_permission` int NOT NULL,
120
+ `role_ids` json NOT NULL,
121
+ `expires_at` datetime NOT NULL,
122
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
123
+ CONSTRAINT `user_permission_cache_id` PRIMARY KEY(`id`)
124
+ );
125
+ --> statement-breakpoint
126
+ CREATE TABLE `user_roles` (
127
+ `id` varchar(191) NOT NULL,
128
+ `user_id` varchar(191) NOT NULL,
129
+ `role_id` varchar(191) NOT NULL,
130
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 08:28:18.841',
131
+ `expires_at` datetime,
132
+ CONSTRAINT `user_roles_id` PRIMARY KEY(`id`),
133
+ CONSTRAINT `user_roles_user_role_unique` UNIQUE(`user_id`,`role_id`)
134
+ );
135
+ --> statement-breakpoint
136
+ CREATE TABLE `users` (
137
+ `id` varchar(191) NOT NULL,
138
+ `name` varchar(255),
139
+ `email` varchar(255) NOT NULL,
140
+ `email_verified` datetime,
141
+ `password_updated_at` datetime,
142
+ `image` varchar(255),
143
+ `password_hash` varchar(255),
144
+ CONSTRAINT `users_id` PRIMARY KEY(`id`),
145
+ CONSTRAINT `users_email_unique` UNIQUE(`email`)
146
+ );
147
+ --> statement-breakpoint
148
+ CREATE TABLE `verification_tokens` (
149
+ `identifier` varchar(191) NOT NULL,
150
+ `token` varchar(191) NOT NULL,
151
+ `expires` datetime NOT NULL,
152
+ CONSTRAINT `verification_tokens_identifier_token_pk` UNIQUE(`identifier`,`token`)
153
+ );
154
+ --> statement-breakpoint
155
+ CREATE INDEX `accounts_user_id_idx` ON `accounts` (`user_id`);--> statement-breakpoint
156
+ CREATE INDEX `content_schema_events_created_at_idx` ON `content_schema_events` (`created_at`);--> statement-breakpoint
157
+ CREATE INDEX `content_schema_events_table_name_idx` ON `content_schema_events` (`table_name`);--> statement-breakpoint
158
+ CREATE INDEX `evt_expires_idx` ON `email_verification_tokens` (`expires`);--> statement-breakpoint
159
+ CREATE INDEX `prt_expires_idx` ON `password_reset_tokens` (`expires`);--> statement-breakpoint
160
+ CREATE INDEX `prt_used_at_idx` ON `password_reset_tokens` (`used_at`);--> statement-breakpoint
161
+ CREATE INDEX `permissions_resource_idx` ON `permissions` (`resource`);--> statement-breakpoint
162
+ CREATE INDEX `permissions_action_idx` ON `permissions` (`action`);--> statement-breakpoint
163
+ CREATE INDEX `role_inherits_child_idx` ON `role_inherits` (`child_role_id`);--> statement-breakpoint
164
+ CREATE INDEX `role_inherits_parent_idx` ON `role_inherits` (`parent_role_id`);--> statement-breakpoint
165
+ CREATE INDEX `role_permissions_role_id_idx` ON `role_permissions` (`role_id`);--> statement-breakpoint
166
+ CREATE INDEX `roles_level_idx` ON `roles` (`level`);--> statement-breakpoint
167
+ CREATE INDEX `roles_is_system_idx` ON `roles` (`is_system`);--> statement-breakpoint
168
+ CREATE INDEX `sessions_user_id_idx` ON `sessions` (`user_id`);--> statement-breakpoint
169
+ CREATE INDEX `upc_user_id_idx` ON `user_permission_cache` (`user_id`);--> statement-breakpoint
170
+ CREATE INDEX `upc_expires_at_idx` ON `user_permission_cache` (`expires_at`);--> statement-breakpoint
171
+ CREATE INDEX `upc_user_action_resource_idx` ON `user_permission_cache` (`user_id`,`action`,`resource`);--> statement-breakpoint
172
+ CREATE INDEX `user_roles_user_id_idx` ON `user_roles` (`user_id`);--> statement-breakpoint
173
+ CREATE INDEX `user_roles_expires_at_idx` ON `user_roles` (`expires_at`);--> statement-breakpoint
174
+ CREATE INDEX `verification_tokens_token_idx` ON `verification_tokens` (`token`);
@@ -0,0 +1,27 @@
1
+ CREATE TABLE `field_permissions` (
2
+ `id` varchar(255) NOT NULL,
3
+ `role_id` varchar(191) NOT NULL,
4
+ `collection_slug` varchar(100) NOT NULL,
5
+ `field_path` varchar(255) NOT NULL,
6
+ `action` varchar(10) NOT NULL,
7
+ `condition` json,
8
+ `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222',
9
+ `updated_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222',
10
+ CONSTRAINT `field_permissions_id` PRIMARY KEY(`id`),
11
+ CONSTRAINT `field_permissions_role_collection_field_unique` UNIQUE(`role_id`,`collection_slug`,`field_path`)
12
+ );
13
+ --> statement-breakpoint
14
+ ALTER TABLE `content_schema_events` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.221';--> statement-breakpoint
15
+ ALTER TABLE `email_verification_tokens` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
16
+ ALTER TABLE `password_reset_tokens` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
17
+ ALTER TABLE `permissions` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
18
+ ALTER TABLE `permissions` MODIFY COLUMN `updated_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
19
+ ALTER TABLE `role_permissions` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
20
+ ALTER TABLE `roles` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
21
+ ALTER TABLE `roles` MODIFY COLUMN `updated_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
22
+ ALTER TABLE `system_migrations` MODIFY COLUMN `run_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.221';--> statement-breakpoint
23
+ ALTER TABLE `user_permission_cache` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
24
+ ALTER TABLE `user_roles` MODIFY COLUMN `created_at` datetime NOT NULL DEFAULT '2025-11-15 11:30:23.222';--> statement-breakpoint
25
+ CREATE INDEX `field_permissions_role_id_idx` ON `field_permissions` (`role_id`);--> statement-breakpoint
26
+ CREATE INDEX `field_permissions_collection_idx` ON `field_permissions` (`collection_slug`);--> statement-breakpoint
27
+ CREATE INDEX `field_permissions_lookup_idx` ON `field_permissions` (`role_id`,`collection_slug`,`field_path`);
@@ -0,0 +1,24 @@
1
+ CREATE TABLE `media` (
2
+ `id` varchar(255) NOT NULL,
3
+ `filename` varchar(255) NOT NULL,
4
+ `original_filename` varchar(255) NOT NULL,
5
+ `mime_type` varchar(100) NOT NULL,
6
+ `size` int NOT NULL,
7
+ `width` int,
8
+ `height` int,
9
+ `duration` int,
10
+ `url` text NOT NULL,
11
+ `thumbnail_url` text,
12
+ `alt_text` text,
13
+ `caption` text,
14
+ `tags` json,
15
+ `uploaded_by` varchar(191) NOT NULL,
16
+ `uploaded_at` datetime NOT NULL DEFAULT (now()),
17
+ `updated_at` datetime NOT NULL DEFAULT (now()),
18
+ CONSTRAINT `media_id` PRIMARY KEY(`id`)
19
+ );
20
+ --> statement-breakpoint
21
+ ALTER TABLE `media` ADD CONSTRAINT `media_uploaded_by_users_id_fk` FOREIGN KEY (`uploaded_by`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
22
+ CREATE INDEX `media_uploaded_by_idx` ON `media` (`uploaded_by`);--> statement-breakpoint
23
+ CREATE INDEX `media_mime_type_idx` ON `media` (`mime_type`);--> statement-breakpoint
24
+ CREATE INDEX `media_uploaded_at_idx` ON `media` (`uploaded_at`);
@@ -0,0 +1,37 @@
1
+ -- Migration: Create dynamic_singles table
2
+ -- This migration creates the dynamic_singles table for storing Singles (Globals) metadata
3
+ -- Singles are single-document entities for site-wide configuration (site settings, navigation, etc.)
4
+
5
+ CREATE TABLE IF NOT EXISTS `dynamic_singles` (
6
+ `id` varchar(36) PRIMARY KEY,
7
+ `slug` varchar(255) NOT NULL UNIQUE,
8
+ `label` varchar(255) NOT NULL,
9
+ `table_name` varchar(255) NOT NULL UNIQUE,
10
+ `description` text,
11
+ `fields` json NOT NULL,
12
+ `admin` json,
13
+ `access_rules` json,
14
+ `source` varchar(20) NOT NULL DEFAULT 'ui',
15
+ `locked` boolean NOT NULL DEFAULT false,
16
+ `status` boolean NOT NULL DEFAULT false,
17
+ `config_path` varchar(500),
18
+ `schema_hash` varchar(64) NOT NULL,
19
+ `schema_version` int NOT NULL DEFAULT 1,
20
+ `migration_status` varchar(20) NOT NULL DEFAULT 'pending',
21
+ `last_migration_id` varchar(36),
22
+ `created_by` varchar(36),
23
+ `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
24
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
25
+ );
26
+ --> statement-breakpoint
27
+
28
+ -- Create indexes for query performance
29
+ CREATE INDEX `dynamic_singles_source_idx` ON `dynamic_singles` (`source`);
30
+ --> statement-breakpoint
31
+ CREATE INDEX `dynamic_singles_migration_status_idx` ON `dynamic_singles` (`migration_status`);
32
+ --> statement-breakpoint
33
+ CREATE INDEX `dynamic_singles_created_by_idx` ON `dynamic_singles` (`created_by`);
34
+ --> statement-breakpoint
35
+ CREATE INDEX `dynamic_singles_created_at_idx` ON `dynamic_singles` (`created_at`);
36
+ --> statement-breakpoint
37
+ CREATE INDEX `dynamic_singles_updated_at_idx` ON `dynamic_singles` (`updated_at`);
@@ -0,0 +1,35 @@
1
+ -- Migration: Create dynamic_components table
2
+ -- This migration creates the dynamic_components table for storing Component metadata
3
+ -- Components are reusable field group templates that can be embedded in Collections and Singles
4
+
5
+ CREATE TABLE IF NOT EXISTS `dynamic_components` (
6
+ `id` varchar(36) PRIMARY KEY,
7
+ `slug` varchar(255) NOT NULL UNIQUE,
8
+ `label` varchar(255) NOT NULL,
9
+ `table_name` varchar(255) NOT NULL UNIQUE,
10
+ `description` text,
11
+ `fields` json NOT NULL,
12
+ `admin` json,
13
+ `source` varchar(20) NOT NULL DEFAULT 'ui',
14
+ `locked` boolean NOT NULL DEFAULT false,
15
+ `config_path` varchar(500),
16
+ `schema_hash` varchar(64) NOT NULL,
17
+ `schema_version` int NOT NULL DEFAULT 1,
18
+ `migration_status` varchar(20) NOT NULL DEFAULT 'pending',
19
+ `last_migration_id` varchar(36),
20
+ `created_by` varchar(36),
21
+ `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
22
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
23
+ );
24
+ --> statement-breakpoint
25
+
26
+ -- Create indexes for query performance
27
+ CREATE INDEX `dynamic_components_source_idx` ON `dynamic_components` (`source`);
28
+ --> statement-breakpoint
29
+ CREATE INDEX `dynamic_components_migration_status_idx` ON `dynamic_components` (`migration_status`);
30
+ --> statement-breakpoint
31
+ CREATE INDEX `dynamic_components_created_by_idx` ON `dynamic_components` (`created_by`);
32
+ --> statement-breakpoint
33
+ CREATE INDEX `dynamic_components_created_at_idx` ON `dynamic_components` (`created_at`);
34
+ --> statement-breakpoint
35
+ CREATE INDEX `dynamic_components_updated_at_idx` ON `dynamic_components` (`updated_at`);
@@ -0,0 +1,92 @@
1
+ -- Migration: Create Plan 12 system tables
2
+ -- This migration creates the user_field_definitions, email_providers, and email_templates
3
+ -- tables required by the User Management & Extendable User Schema feature (Plan 12).
4
+
5
+ -- ============================================================
6
+ -- user_field_definitions
7
+ -- Stores metadata for custom user fields that extend the base user model.
8
+ -- Fields can be sourced from defineConfig() (code) or admin Settings UI (ui).
9
+ -- ============================================================
10
+
11
+ CREATE TABLE IF NOT EXISTS `user_field_definitions` (
12
+ `id` varchar(36) PRIMARY KEY,
13
+ `name` varchar(255) NOT NULL,
14
+ `label` varchar(255) NOT NULL,
15
+ `type` varchar(50) NOT NULL,
16
+ `required` boolean NOT NULL DEFAULT false,
17
+ `default_value` varchar(255),
18
+ `options` json,
19
+ `placeholder` varchar(255),
20
+ `description` text,
21
+ `sort_order` int NOT NULL DEFAULT 0,
22
+ `source` varchar(10) NOT NULL DEFAULT 'ui',
23
+ `is_active` boolean NOT NULL DEFAULT true,
24
+ `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
25
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
26
+ UNIQUE KEY `user_field_defs_name_unique_idx` (`name`)
27
+ );
28
+ --> statement-breakpoint
29
+
30
+ CREATE INDEX `user_field_defs_source_idx` ON `user_field_definitions` (`source`);
31
+ --> statement-breakpoint
32
+ CREATE INDEX `user_field_defs_is_active_idx` ON `user_field_definitions` (`is_active`);
33
+ --> statement-breakpoint
34
+ CREATE INDEX `user_field_defs_sort_order_idx` ON `user_field_definitions` (`sort_order`);
35
+ --> statement-breakpoint
36
+ CREATE INDEX `user_field_defs_created_at_idx` ON `user_field_definitions` (`created_at`);
37
+ --> statement-breakpoint
38
+
39
+ -- ============================================================
40
+ -- email_providers
41
+ -- Stores email provider configurations (SMTP, Resend, SendLayer)
42
+ -- managed via the admin Settings UI.
43
+ -- ============================================================
44
+
45
+ CREATE TABLE IF NOT EXISTS `email_providers` (
46
+ `id` varchar(36) PRIMARY KEY,
47
+ `name` varchar(255) NOT NULL,
48
+ `type` varchar(50) NOT NULL,
49
+ `from_email` varchar(255) NOT NULL,
50
+ `from_name` varchar(255),
51
+ `configuration` json NOT NULL,
52
+ `is_default` boolean NOT NULL DEFAULT false,
53
+ `is_active` boolean NOT NULL DEFAULT true,
54
+ `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
55
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
56
+ );
57
+ --> statement-breakpoint
58
+
59
+ CREATE INDEX `email_providers_type_idx` ON `email_providers` (`type`);
60
+ --> statement-breakpoint
61
+ CREATE INDEX `email_providers_is_active_idx` ON `email_providers` (`is_active`);
62
+ --> statement-breakpoint
63
+ CREATE INDEX `email_providers_created_at_idx` ON `email_providers` (`created_at`);
64
+ --> statement-breakpoint
65
+
66
+ -- ============================================================
67
+ -- email_templates
68
+ -- Stores email templates with {{variable}} interpolation support,
69
+ -- managed via the admin Settings UI.
70
+ -- ============================================================
71
+
72
+ CREATE TABLE IF NOT EXISTS `email_templates` (
73
+ `id` varchar(36) PRIMARY KEY,
74
+ `name` varchar(255) NOT NULL,
75
+ `slug` varchar(255) NOT NULL UNIQUE,
76
+ `subject` text NOT NULL,
77
+ `html_content` text NOT NULL,
78
+ `plain_text_content` text,
79
+ `variables` json,
80
+ `use_layout` boolean NOT NULL DEFAULT true,
81
+ `is_active` boolean NOT NULL DEFAULT true,
82
+ `provider_id` varchar(36),
83
+ `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
84
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
85
+ );
86
+ --> statement-breakpoint
87
+
88
+ CREATE INDEX `email_templates_is_active_idx` ON `email_templates` (`is_active`);
89
+ --> statement-breakpoint
90
+ CREATE INDEX `email_templates_provider_id_idx` ON `email_templates` (`provider_id`);
91
+ --> statement-breakpoint
92
+ CREATE INDEX `email_templates_created_at_idx` ON `email_templates` (`created_at`);
@@ -0,0 +1,36 @@
1
+ -- Migration: Create api_keys table for API Key Authentication (Plan 14)
2
+ -- This migration creates the api_keys table required for programmatic API access
3
+ -- using long-lived secret keys with SHA-256 hashed storage.
4
+
5
+ -- UP
6
+
7
+ CREATE TABLE IF NOT EXISTS `api_keys` (
8
+ `id` varchar(191) NOT NULL PRIMARY KEY,
9
+ `name` varchar(255) NOT NULL,
10
+ `description` text,
11
+ `key_hash` varchar(64) NOT NULL,
12
+ `key_prefix` varchar(16) NOT NULL,
13
+ `token_type` varchar(20) NOT NULL,
14
+ `role_id` varchar(191),
15
+ `user_id` varchar(191) NOT NULL,
16
+ `expires_at` datetime,
17
+ `last_used_at` datetime,
18
+ `is_active` boolean NOT NULL DEFAULT true,
19
+ `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
21
+ CONSTRAINT `api_keys_role_id_fk` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE SET NULL,
22
+ CONSTRAINT `api_keys_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
23
+ );
24
+
25
+ CREATE UNIQUE INDEX `api_keys_key_hash_unique` ON `api_keys` (`key_hash`);
26
+ CREATE INDEX `api_keys_user_id_idx` ON `api_keys` (`user_id`);
27
+ CREATE INDEX `api_keys_role_id_idx` ON `api_keys` (`role_id`);
28
+ CREATE INDEX `api_keys_is_active_expires_at_idx` ON `api_keys` (`is_active`, `expires_at`);
29
+
30
+ -- DOWN
31
+
32
+ DROP INDEX `api_keys_is_active_expires_at_idx` ON `api_keys`;
33
+ DROP INDEX `api_keys_role_id_idx` ON `api_keys`;
34
+ DROP INDEX `api_keys_user_id_idx` ON `api_keys`;
35
+ DROP INDEX `api_keys_key_hash_unique` ON `api_keys`;
36
+ DROP TABLE IF EXISTS `api_keys`;
@@ -0,0 +1,20 @@
1
+ -- Migration: Create site_settings table for general application settings
2
+ -- This migration creates the site_settings singleton table.
3
+ -- Only one row ever exists with id = 'default'.
4
+
5
+ -- UP
6
+
7
+ CREATE TABLE IF NOT EXISTS `site_settings` (
8
+ `id` varchar(50) NOT NULL PRIMARY KEY,
9
+ `application_name` varchar(255),
10
+ `site_url` varchar(2048),
11
+ `admin_email` varchar(255),
12
+ `timezone` varchar(100),
13
+ `date_format` varchar(50),
14
+ `time_format` varchar(50),
15
+ `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
16
+ );
17
+
18
+ -- DOWN
19
+
20
+ DROP TABLE IF EXISTS `site_settings`;
@@ -0,0 +1,9 @@
1
+ -- Migration: Add logo_url column to site_settings
2
+
3
+ -- UP
4
+
5
+ ALTER TABLE `site_settings` ADD COLUMN `logo_url` varchar(2048);
6
+
7
+ -- DOWN
8
+
9
+ ALTER TABLE `site_settings` DROP COLUMN `logo_url`;
@@ -0,0 +1,30 @@
1
+ -- Migration: Create activity_log table for Dashboard Activity Feed (Plan 16)
2
+ -- This migration creates the activity_log table that records create/update/delete
3
+ -- actions across all collections for the dashboard activity feed.
4
+
5
+ -- UP
6
+
7
+ CREATE TABLE IF NOT EXISTS `activity_log` (
8
+ `id` varchar(191) NOT NULL PRIMARY KEY,
9
+ `user_id` varchar(191) NOT NULL,
10
+ `user_name` varchar(255) NOT NULL,
11
+ `user_email` varchar(255) NOT NULL,
12
+ `action` varchar(10) NOT NULL,
13
+ `collection` varchar(255) NOT NULL,
14
+ `entry_id` varchar(191),
15
+ `entry_title` text,
16
+ `metadata` text,
17
+ `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
18
+ CONSTRAINT `activity_log_user_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE
19
+ );
20
+
21
+ CREATE INDEX `idx_activity_log_created_at` ON `activity_log` (`created_at`);
22
+ CREATE INDEX `idx_activity_log_collection` ON `activity_log` (`collection`, `created_at`);
23
+ CREATE INDEX `idx_activity_log_user_id` ON `activity_log` (`user_id`, `created_at`);
24
+
25
+ -- DOWN
26
+
27
+ DROP INDEX `idx_activity_log_user_id` ON `activity_log`;
28
+ DROP INDEX `idx_activity_log_collection` ON `activity_log`;
29
+ DROP INDEX `idx_activity_log_created_at` ON `activity_log`;
30
+ DROP TABLE IF EXISTS `activity_log`;