@bettercms-ai/db 0.4.6 → 0.4.8

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.
package/dist/index.js CHANGED
@@ -22435,6 +22435,10 @@ var pages = pgTable2(
22435
22435
  // two runners never see the same row at the same time because they gate on status.
22436
22436
  // Migration 0189.
22437
22437
  unpublishAt: timestamp3("unpublish_at"),
22438
+ // Localization (migration 0389): this page's locale (NULL = project default) and, for a
22439
+ // translation, the SOURCE page it translates. Same model as content_entries.
22440
+ locale: varchar2("locale", { length: 16 }),
22441
+ translationOf: text3("translation_of"),
22438
22442
  // FLO-110: Preview token invalidation version
22439
22443
  previewTokenVersion: integer2("preview_token_version").notNull().default(0),
22440
22444
  // Phase 2: pgvector AI search (1536-dim OpenAI text-embedding-3-small)
@@ -22645,6 +22649,12 @@ var contentEntries = pgTable3(
22645
22649
  // instead of appending `-2` slug variants, which is what a second upload of the same CRM
22646
22650
  // export used to produce. NULL on every hand-authored entry.
22647
22651
  externalKey: text4("external_key"),
22652
+ // ── Localization (migration 0389) ───────────────────────────────────────────────────────
22653
+ // The locale this row is written in (BCP-47, one of projects.locale_config.locales); NULL =
22654
+ // the project's default language. A translation points at its SOURCE row, never at another
22655
+ // translation, so a group is { source } ∪ { rows where translation_of = source.id }.
22656
+ locale: varchar3("locale", { length: 16 }),
22657
+ translationOf: text4("translation_of"),
22648
22658
  // Which campaign owns this entry. Scopes review, publish, share and expiry in one indexed
22649
22659
  // predicate. NULL for everything outside a campaign.
22650
22660
  campaignId: text4("campaign_id"),
@@ -23493,6 +23503,24 @@ var projects = pgTable10(
23493
23503
  * A project whose owner turned the toggle on keeps this false and waits for a human.
23494
23504
  */
23495
23505
  promoteAfterSetup: boolean7("promote_after_setup").notNull().default(false),
23506
+ /**
23507
+ * The site was ROLLED BACK, so its builds wait for a promote (migration 0388) — Vercel's
23508
+ * Instant Rollback on the existing staging machinery. Another sibling of `require_promote`:
23509
+ * a rollback of an auto-deploying project turns that on and stamps this, so every later build
23510
+ * (push, Rebuild, a snapshot app's content publish) lands on `staging`, awaiting promote,
23511
+ * instead of replacing the rolled-back site. A promote — "Undo Rollback" — clears both, and
23512
+ * auto-deploy resumes. Never cleared by a build. @see src/lib/hosting/rollback.ts
23513
+ */
23514
+ rolledBackAt: timestamp11("rolled_back_at", { withTimezone: true }),
23515
+ // A content publish waiting to be applied in place to the live build (0381). Durable, so a
23516
+ // restart still applies it; cleared compare-and-set once the apply that saw it finishes.
23517
+ contentApplyPendingAt: timestamp11("content_apply_pending_at", { withTimezone: true }),
23518
+ // The structure digest the live release was built from (0381). Diffed against the published
23519
+ // state to list what waits for the next Rebuild.
23520
+ builtStructure: jsonb8("built_structure"),
23521
+ // The live-tree LEASE (0381): held by whichever writer is changing the served tree (a content
23522
+ // apply, a release starting, promote, rollback). Expires on its own if the holder dies.
23523
+ contentApplyLockUntil: timestamp11("content_apply_lock_until", { withTimezone: true }),
23496
23524
  // Cross-origin canvas opt-in (#235 lane). When true the editor may frame this project's
23497
23525
  // site at `canvas-<projectId>.bettercms.site` — the guest that infra/nginx/canvas.conf
23498
23526
  // injects talks postMessage instead of the same-origin DOM access the editor uses today.
@@ -23523,6 +23551,14 @@ var projects = pgTable10(
23523
23551
  // `location /` prefix match and is served off disk in all three modes — which is also why
23524
23552
  // the 'node' packaging hard-links _next/static to the release web root.
23525
23553
  renderMode: varchar10("render_mode", { length: 10 }).notNull().default("static"),
23554
+ // Where a 'node' app's published content comes from (migration 0387), recorded from the
23555
+ // live build's bcms-runtime.json `content` key beside render_mode, by the same writer.
23556
+ // 'snapshot' = the app renders the content its build fetched, so a publish must REBUILD it;
23557
+ // 'live' = it fetches content at request time, so a publish is live at once. NULL = not a
23558
+ // server app (or not known), read as 'live' wherever it matters.
23559
+ runtimeContent: varchar10("runtime_content", { length: 16 }),
23560
+ // What the build's setup and the on-demand editor setup last did (0391). @see lib/hosting/setup-state.ts
23561
+ setupState: jsonb8("setup_state").$type(),
23526
23562
  /**
23527
23563
  * The TEMPLATE's own presentation declaration — DTCG (`$type`/`$value`), owned by the
23528
23564
  * starter and RE-DECLARED WHOLESALE on every deploy (FLO-1178 Lane 2, migration 0251).
@@ -25152,6 +25188,15 @@ var releases = pgTable46(
25152
25188
  // log we have: buildLogKey has no writers, so a "view the build log" affordance is
25153
25189
  // only honest as a deep link to the Actions run. NULL ⇒ no log link is shown.
25154
25190
  runId: varchar30("run_id", { length: 32 }),
25191
+ /** Why this build ran: setup | site | code (0381), or content for a snapshot server app (0387). NULL on releases before it. */
25192
+ trigger: varchar30("trigger", { length: 16 }),
25193
+ /** ISO time each phase began (0381). `live` is derived from live_at by the timeline. */
25194
+ phaseMarks: jsonb25("phase_marks").$type(),
25195
+ // Every built page's <head>, by route (0391): the SEO the build imported for pages that do not
25196
+ // exist yet. @see lib/content/derive-seo-from-build.ts buildSeoManifest
25197
+ seoManifest: jsonb25("seo_manifest").$type(),
25198
+ /** The published structure digest captured when this build STARTED (0381). */
25199
+ builtStructure: jsonb25("built_structure"),
25155
25200
  ...auditColumns
25156
25201
  },
25157
25202
  (table) => [
@@ -25207,6 +25252,10 @@ var rebuildQueue = pgTable47("rebuild_queue", {
25207
25252
  * full — so once this is NULL, later page jobs leave it NULL.
25208
25253
  */
25209
25254
  routes: text48("routes").array(),
25255
+ /** Why this build runs: setup | site | code (0381), or content for a snapshot server app (0387). Carried into `releases.trigger`. */
25256
+ trigger: varchar31("trigger", { length: 16 }),
25257
+ /** When this attempt was queued (0381). Set on every enqueue; the release's `queued` mark. */
25258
+ queuedAt: timestamp45("queued_at", { withTimezone: true }),
25210
25259
  updatedAt: timestamp45("updated_at").notNull().defaultNow()
25211
25260
  });
25212
25261
 
@@ -25249,9 +25298,11 @@ var projectRepos = pgTable48("project_repos", {
25249
25298
  * workflow's install step: an unconstrained column there is a command-injection surface.
25250
25299
  */
25251
25300
  packageManager: varchar32("package_manager", { length: 10 }),
25252
- // Suppresses PUSH-triggered builds only. A CMS publish (repository_dispatch)
25253
- // still rebuilds — enforced by the workflow's job-level `if:`, not here.
25254
- autoDeploy: boolean22("auto_deploy").notNull().default(true),
25301
+ // "Deploy on push". Off by default (0380): a push builds only when this is true, whatever
25302
+ // path it arrives by (the push webhook, or a committed bcms-rebuild.yml's upload).
25303
+ autoDeploy: boolean22("auto_deploy").notNull().default(false),
25304
+ /** Variable names the repo's .env.example documents (recorded on connect and every build, 0382). */
25305
+ declaredEnv: text49("declared_env").array(),
25255
25306
  ...auditColumns
25256
25307
  });
25257
25308
 
@@ -25455,6 +25506,11 @@ var publishes = pgTable53(
25455
25506
  status: varchar37("status", { length: 16 }).notNull().default("queued"),
25456
25507
  /** Non-NULL = the publish is still in the future. The cron creates the set when it fires. */
25457
25508
  scheduledAt: timestamp49("scheduled_at", { withTimezone: true }),
25509
+ /**
25510
+ * When the set stopped gaining items (0381). A set is created empty and filled as each item
25511
+ * lands, so its creation time does not say which revision it belongs to; this does.
25512
+ */
25513
+ completedAt: timestamp49("completed_at", { withTimezone: true }),
25458
25514
  createdAt: timestamp49("created_at", { withTimezone: true }).notNull().defaultNow(),
25459
25515
  updatedAt: timestamp49("updated_at", { withTimezone: true }).notNull().defaultNow()
25460
25516
  },
@@ -26717,6 +26773,10 @@ var components = pgTable83(
26717
26773
  // matching pages.block_json. Validated as ContentBlock[] at the API layer.
26718
26774
  blockJson: jsonb43("block_json").$type().notNull().default([]),
26719
26775
  props: jsonb43("props").$type().notNull().default([]),
26776
+ // The editor controls this component declares ({ controls, cascade }, migration 0384).
26777
+ // Authoring chrome, DRAFT-only: outside the publish snapshot, so it never makes a component
26778
+ // "changed". Null keeps the dashboard's global controls. Validated at the API layer.
26779
+ design: jsonb43("design").$type(),
26720
26780
  // Draft/live split (migration 0186_component_draft_live_split.sql). `blockJson`/`props`
26721
26781
  // above are the DRAFT; these two are the LIVE snapshot that get_components_by_handle()
26722
26782
  // serves. Nullable: a never-published component has no live copy. A DB trigger fills them