create-nextblock 0.17.0 → 0.17.2
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/package.json +1 -1
- package/templates/nextblock-template/app/api/cron/reset-sandbox/route.ts +4 -2
- package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +8203 -7038
- package/templates/nextblock-template/app/cms/settings/security/page.tsx +1 -1
- package/templates/nextblock-template/docs/02-ECOMMERCE-CAPABILITIES.md +1 -1
- package/templates/nextblock-template/docs/03-CMS-AND-EDITOR.md +1 -1
- package/templates/nextblock-template/docs/04-DATABASE-AND-AUTH.md +402 -293
- package/templates/nextblock-template/docs/05-DEVELOPER-GUIDE.md +15 -8
- package/templates/nextblock-template/docs/08-NEXTBLOCK-CORTEX-AI-ARCHITECTURE.md +5 -5
- package/templates/nextblock-template/docs/10-CUSTOM-BLOCKS.md +1 -1
- package/templates/nextblock-template/docs/11-SELF-HOSTED-DOCKER.md +4 -1
- package/templates/nextblock-template/docs/12-VERCEL-DEPLOYMENT.md +12 -9
- package/templates/nextblock-template/docs/13-STAYING-UP-TO-DATE.md +8 -0
- package/templates/nextblock-template/docs/14-MESSAGES-INBOX.md +2 -2
- package/templates/nextblock-template/docs/TECHNICAL_SPECIFICATION.md +154 -163
- package/templates/nextblock-template/lib/config/email-settings.ts +323 -323
- package/templates/nextblock-template/lib/seo/redirect-store.ts +3 -2
- package/templates/nextblock-template/lib/setup/migrations-bundle.ts +18 -203
- package/templates/nextblock-template/package.json +1 -1
|
@@ -178,11 +178,17 @@ Production rule:
|
|
|
178
178
|
- Add a new forward-only `.sql` file under
|
|
179
179
|
`libs/db/src/supabase/migrations` for each production schema/data change.
|
|
180
180
|
- Use `npm run db:migrate:check` before `npm run db:migrate`.
|
|
181
|
-
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
181
|
+
- Migration files are named `GGNNN_<snake_name>.sql` (GG = squash generation, NNN =
|
|
182
|
+
sequence, contiguous). The next number is the highest sequence on disk + 1 in the same
|
|
183
|
+
generation; `db:migrate:check` prints it and fails on any other name shape. See
|
|
184
|
+
[04-DATABASE-AND-AUTH.md](./04-DATABASE-AND-AUTH.md) → "Migration Structure".
|
|
185
|
+
- If `db:migrate:check` lists the generation baseline (`02001_baseline_schema.sql` …) as
|
|
186
|
+
pending on an existing database whose history is empty, do not run `db:migrate` yet.
|
|
187
|
+
Run `npm run db:migrate:repair-history:check`, then `npm run db:migrate:repair-history`,
|
|
188
|
+
then check again. If instead it shows retired 14-digit versions "recorded remotely with
|
|
189
|
+
no local file" beside the pending baseline, the database has not crossed the squash:
|
|
190
|
+
run `npm run db:migrate:repair-history:check -- --reconcile-squash`, then the same without
|
|
191
|
+
`:check`. The expected result after either repair is that only new unapplied migrations remain.
|
|
186
192
|
- Do not use `npm run db:reset`, `npm run sandbox:reset`,
|
|
187
193
|
`npm run db:migrate:fresh`, or `npm run db:push:sandbox` against production.
|
|
188
194
|
|
|
@@ -198,9 +204,10 @@ The migration-only script:
|
|
|
198
204
|
- runs `supabase db push` without `--include-all`
|
|
199
205
|
- never runs a reset, seed script, function deploy, or config push
|
|
200
206
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
The migration set is a squashed baseline (one generation at a time — see
|
|
208
|
+
[04-DATABASE-AND-AUTH.md](./04-DATABASE-AND-AUTH.md) → "Migration Structure"). Treat the
|
|
209
|
+
baseline files as grouped domains and append every new production change as a new
|
|
210
|
+
`GGNNN` migration; never edit the baseline or the catch-up.
|
|
204
211
|
|
|
205
212
|
## Sandbox Reset Operations
|
|
206
213
|
|
|
@@ -82,7 +82,7 @@ Known incomplete or future work:
|
|
|
82
82
|
|
|
83
83
|
| File | Purpose |
|
|
84
84
|
| --- | --- |
|
|
85
|
-
| `libs/db/src/supabase/migrations/
|
|
85
|
+
| `libs/db/src/supabase/migrations/02003_baseline_security_and_grants.sql` (originally `00000000000011_setup_cortex_ai_settings`, folded in by the generation-2 squash) | RLS hardening for the sensitive `site_settings` Cortex AI key row. |
|
|
86
86
|
| `apps/nextblock/app/api/cron/reset-sandbox/route.ts` | Sandbox reset route. Upserts active package activation for `cortex-ai` when `FREEMIUS_AI_SANDBOX_KEY` exists. |
|
|
87
87
|
| `apps/nextblock/app/api/cron/reset-sandbox/sandboxResetSql.ts` | Generated SQL bundle that includes the Cortex AI migration. |
|
|
88
88
|
|
|
@@ -271,7 +271,7 @@ The value is a JSON envelope:
|
|
|
271
271
|
}
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
-
The migration `
|
|
274
|
+
The migration `libs/db/src/supabase/migrations/02003_baseline_security_and_grants.sql` (originally `00000000000011_setup_cortex_ai_settings`, folded in by the generation-2 squash) hardens RLS:
|
|
275
275
|
|
|
276
276
|
- Public users can read non-sensitive site settings.
|
|
277
277
|
- The sensitive Cortex AI key row is readable only by authenticated admins.
|
|
@@ -1061,7 +1061,7 @@ Cortex can insert real photos into pages at zero inference cost, and external im
|
|
|
1061
1061
|
- In `libs/cortex/src/lib/ai-global-agent-tools.ts`; registered in `createCortexGlobalAgentTools`.
|
|
1062
1062
|
- Input: `{ query: string, count?: 1-15 (default 6), orientation?: 'landscape'|'portrait'|'square' }`.
|
|
1063
1063
|
- Key resolution: `resolveCortexAiStockPhotoProvider(supabase)` prefers an admin-stored, encrypted key in `site_settings` (`cortex_ai_pexels_api_key` / `cortex_ai_unsplash_access_key`, read via the service-role client), then falls back to the `PEXELS_API_KEY` / `UNSPLASH_ACCESS_KEY` env vars. Pexels wins when both exist. Returns a clear "not configured" message if neither is set. Both are free API keys.
|
|
1064
|
-
- The stored keys are protected by migration `
|
|
1064
|
+
- The stored keys are protected by migration `libs/db/src/supabase/migrations/02003_baseline_security_and_grants.sql` (originally `00000000000012_cortex_ai_stock_photo_settings`, folded in by the generation-2 squash), which adds them to the `site_settings` sensitive-keys RLS group (admin-only read/write, never anon-readable), and encrypted with the same envelope as the OpenRouter BYOK key.
|
|
1065
1065
|
- **The model is told up front whether stock photos are available.** The global-agent route resolves the provider and injects it into the system prompt: available → "use search_stock_photos"; not configured → "do NOT call search_stock_photos; use gradient/theme backgrounds." So a missing key never wastes a tool call, and the keys are never mandatory — Cortex builds pages either way.
|
|
1066
1066
|
- Admin UI: `/cms/settings/cortex-ai` has a Stock Photos card (save/clear Pexels + Unsplash keys, step-by-step, and why) via `saveStockPhotoKeysAction` / `clearStockPhotoKeysAction`.
|
|
1067
1067
|
- Rate-limit fallback: `resolveCortexAiStockPhotoProviders` returns ALL configured providers ordered Pexels→Unsplash; `executeSearchStockPhotos` tries them in order, falling through to the next on error/HTTP 429/empty results, and returns `attemptedProviders`.
|
|
@@ -1106,7 +1106,7 @@ from inside the editor.
|
|
|
1106
1106
|
| `apps/nextblock/app/cms/settings/cortex-ai/mcp-actions.ts` | Admin server actions: settings, mint, revoke. |
|
|
1107
1107
|
| `apps/nextblock/app/cms/settings/cortex-ai/McpServerSettingsCard.tsx` | Settings UI + copy-paste client config. |
|
|
1108
1108
|
| `apps/nextblock/app/cms/settings/cortex-ai/require-admin.ts` | Shared admin gate (also used by `actions.ts`). |
|
|
1109
|
-
| `libs/db/src/supabase/migrations/
|
|
1109
|
+
| `libs/db/src/supabase/migrations/02003_baseline_security_and_grants.sql` (originally `00000000000017_cortex_ai_mcp_server`, folded in by the generation-2 squash) | `mcp_access_tokens` table + `cortex_ai_mcp_settings` RLS. |
|
|
1110
1110
|
|
|
1111
1111
|
### Protocol decisions
|
|
1112
1112
|
|
|
@@ -1241,7 +1241,7 @@ tools cannot read token hashes or insert rows.
|
|
|
1241
1241
|
### Marketing surfaces that describe the MCP server
|
|
1242
1242
|
|
|
1243
1243
|
Three seeded content rows sell the MCP story and are kept at 100/100 in the built-in SEO
|
|
1244
|
-
engine (`libs/utils/src/lib/seo`). Migration `
|
|
1244
|
+
engine (`libs/utils/src/lib/seo`). Migration `libs/db/src/supabase/migrations/02004_baseline_seed.sql` (originally `00000000000037_reposition_marketing_and_cortex_mcp`, folded in by the generation-2 squash)
|
|
1245
1245
|
owns them; the sandbox reset route (`enrichCortexAiProducts`) mirrors the product sections
|
|
1246
1246
|
because it deletes and re-inserts product blocks after the SQL replay, so edit both together.
|
|
1247
1247
|
|
|
@@ -25,7 +25,7 @@ revisions without special-casing.
|
|
|
25
25
|
## Data Model
|
|
26
26
|
|
|
27
27
|
The table is created in
|
|
28
|
-
`libs/db/src/supabase/migrations/00000000000023_setup_custom_block_definitions.
|
|
28
|
+
`libs/db/src/supabase/migrations/02001_baseline_schema.sql` (originally `00000000000023_setup_custom_block_definitions`, folded in by the generation-2 squash).
|
|
29
29
|
|
|
30
30
|
`public.custom_block_definitions`:
|
|
31
31
|
|
|
@@ -103,7 +103,10 @@ Both named volumes persist your database and uploaded media across restarts.
|
|
|
103
103
|
> `public._nextblock_docker_migrations` — a different tracker from the one every other
|
|
104
104
|
> install uses), so applying the same SQL from the updater as well would run it through two
|
|
105
105
|
> trackers. The updater refreshes the SQL on disk and hands the schema step to the stack.
|
|
106
|
-
> Full details in [docs/13](./13-STAYING-UP-TO-DATE.md).
|
|
106
|
+
> Full details in [docs/13](./13-STAYING-UP-TO-DATE.md). Migration squashes (new
|
|
107
|
+
> `GG000`–`GG004` generations, see [docs/04](./04-DATABASE-AND-AUTH.md)) need nothing
|
|
108
|
+
> extra here: the generation's catch-up file consults `public._nextblock_docker_migrations`
|
|
109
|
+
> by file stem, so it replays only what this stack never applied.
|
|
107
110
|
|
|
108
111
|
### Ports (override with env vars)
|
|
109
112
|
|
|
@@ -167,15 +167,18 @@ the question entirely by resolving everything in-app, so the button prompts for
|
|
|
167
167
|
|
|
168
168
|
## Cron jobs and the Hobby plan
|
|
169
169
|
|
|
170
|
-
`vercel.json` declares two crons
|
|
171
|
-
`/api/cron/sync-currencies` at 18:00
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
170
|
+
`vercel.json` declares two crons: `/api/cron/reset-sandbox` **every 15 minutes**
|
|
171
|
+
(`*/15 * * * *`) and `/api/cron/sync-currencies` daily at 18:00 UTC. The 15-minute
|
|
172
|
+
schedule is what keeps the public sandbox at `cms.nextblock.dev` fresh; that project
|
|
173
|
+
runs on **Vercel Pro**, which allows cron schedules down to once per minute with
|
|
174
|
+
per-minute precision.
|
|
175
|
+
|
|
176
|
+
Vercel’s **Hobby (free) tier only allows cron jobs that run at most once per day**
|
|
177
|
+
(timing is approximate, ±59 min), and **a sub-daily schedule fails the deployment**
|
|
178
|
+
outright. So on a Hobby project you must **delete the `reset-sandbox` entry from
|
|
179
|
+
`vercel.json`** before deploying. Nothing is lost: `reset-sandbox` only does work in
|
|
180
|
+
sandbox mode — it returns 404 otherwise — so on a normal deploy it is a harmless
|
|
181
|
+
no-op anyway. `sync-currencies` is daily and deploys fine on Hobby.
|
|
179
182
|
|
|
180
183
|
## After deploy
|
|
181
184
|
|
|
@@ -278,6 +278,14 @@ types forward while leaving the schema behind — the app would then fail at run
|
|
|
278
278
|
project → `node_modules/@nextblock-cms/db`), deduping by version, so even a user who only
|
|
279
279
|
ran `npm install` gets the new SQL.
|
|
280
280
|
|
|
281
|
+
> **Migration squashes.** Every so often the folder is squashed into a new *generation*
|
|
282
|
+
> (`02000`–`02004`, then `02005+`; see [docs/04](./04-DATABASE-AND-AUTH.md) → "Migration
|
|
283
|
+
> Structure"). An install crosses a squash with no manual step: the new generation's files
|
|
284
|
+
> are simply pending, its `GG000_catchup_*` file replays only the retired migrations this
|
|
285
|
+
> database never recorded, the baseline DDL is idempotent, and the seed skips any database
|
|
286
|
+
> that already holds content. Retired files that linger in `<project>/supabase/migrations`
|
|
287
|
+
> are harmless — they are already recorded, so nothing applies them twice.
|
|
288
|
+
|
|
281
289
|
### Build-time migrations
|
|
282
290
|
|
|
283
291
|
A build-time hook ([`apps/nextblock/tools/build-migrate.mjs`](../apps/nextblock/tools/build-migrate.mjs))
|
|
@@ -285,8 +285,8 @@ Trusted platform headers (`x-vercel-forwarded-for`, `x-real-ip`) are preferred o
|
|
|
285
285
|
|
|
286
286
|
## Files
|
|
287
287
|
|
|
288
|
-
- `libs/db/src/supabase/migrations/
|
|
289
|
-
- `libs/db/src/supabase/migrations/
|
|
288
|
+
- `libs/db/src/supabase/migrations/02001_baseline_schema.sql` (originally `00000000000027_message_threads`, folded in by the generation-2 squash) — private lane, `form_endpoints`, the form-block data migration
|
|
289
|
+
- `libs/db/src/supabase/migrations/02001_baseline_schema.sql` (originally `00000000000028_interaction_replies`, folded in by the generation-2 squash) — `parent_id`, the reply CHECK, and the indexes `cms_interactions` never had
|
|
290
290
|
- `apps/nextblock/lib/messages/thread-token.ts` (+ `.test.ts`) — mint, parse, verify
|
|
291
291
|
- `apps/nextblock/lib/messages/threads.ts` — thread creation, recipient resolution, both notification emails
|
|
292
292
|
- `apps/nextblock/app/thread/**` — the visitor's page and the token-exchange route
|