create-nextblock 0.17.1 → 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.
@@ -10,7 +10,7 @@ NextBlock CMS is an AI-Native, Open-Core Content Management System purpose-built
10
10
 
11
11
  The system's central value proposition — "Speed. Scalability. AI-Readiness (coming soon)." — is encoded directly in its architectural decisions: a Next.js 16 App Router application (`apps/nextblock`) backed by Supabase, leveraging React Server Components, edge caching, and an image-optimization pipeline targeting a default 100/100 Lighthouse Performance score. Users bootstrap new projects in under thirty seconds via the `npm create nextblock@latest` CLI, which produces a standalone, production-ready Next.js application.
12
12
 
13
- A live sandbox instance at `https://cms.nextblock.dev/` (accessible with demo credentials `demo@nextblock.dev` / `password`) resets daily via a cron-triggered endpoint (`/api/cron/reset-sandbox`) to provide evaluators with a clean-state environment.
13
+ A live sandbox instance at `https://cms.nextblock.dev/` (accessible with demo credentials `demo@nextblock.dev` / `password`) resets every 15 minutes via a cron-triggered endpoint (`/api/cron/reset-sandbox`) to provide evaluators with a clean-state environment.
14
14
 
15
15
  ### 1.1.2 Core Business Problem
16
16
 
@@ -247,7 +247,7 @@ The following architectural invariants are enforced at workspace level and must
247
247
  | Media Optimization | Blur placeholders generated for uploaded images | `sharp` + `plaiceholder` pipeline |
248
248
  | Developer Adoption | CLI install success rate | `apps/create-nextblock/bin/create-nextblock.js` |
249
249
  | Commerce Conversion | Checkout success by provider (Stripe / Freemius) | `app/api/checkout/route.ts` + webhooks |
250
- | Scheduled Job Health | Daily success of reset-sandbox and sync-currencies | `vercel.json` cron configuration |
250
+ | Scheduled Job Health | Success of reset-sandbox (every 15 min) and sync-currencies (daily) | `vercel.json` cron configuration |
251
251
  | Bundle Discipline | Removed console calls in production | `compiler.removeConsole` in `next.config.js` |
252
252
 
253
253
  ---
@@ -403,7 +403,7 @@ The system does not natively integrate with: alternative payment processors beyo
403
403
  - `tsconfig.base.json` — Shared TypeScript strict-mode configuration and `@nextblock-cms/*` path aliases
404
404
  - `components.json` — shadcn/ui configuration (Slate base, CSS variables, RSC)
405
405
  - `tailwind.config.js` — Root Tailwind CSS theme tokens and dark-mode configuration
406
- - `vercel.json` — Cron schedule definitions (reset-sandbox at 03:00 UTC, sync-currencies at 18:00 UTC)
406
+ - `vercel.json` — Cron schedule definitions (reset-sandbox every 15 minutes, sync-currencies at 18:00 UTC)
407
407
  - `.env.example` — Environment variable reference template
408
408
 
409
409
  ### 1.4.2 Documentation Hub (`docs/`)
@@ -1163,7 +1163,7 @@ The SDK library at `libs/sdk` provides a typed contract for external block autho
1163
1163
 
1164
1164
  **Description**
1165
1165
 
1166
- Two cron jobs are declared in `vercel.json`. The `/api/cron/reset-sandbox` endpoint runs daily at 03:00 UTC (`0 3 * * *`); it clears R2 storage, executes the generated SQL bootstrap (`SANDBOX_RESET_SQL`), normalizes media records, ensures required assets, seeds commerce and content data, and synchronizes Freemius products (product ID `24851`). The `/api/cron/sync-currencies` endpoint runs daily at 18:00 UTC (`0 18 * * *`) and invokes `syncStoreCurrencyRates()` from `@nextblock-cms/ecommerce/server`. Both endpoints require an `Authorization: Bearer ${CRON_SECRET}` header.
1166
+ Two cron jobs are declared in `vercel.json`. The `/api/cron/reset-sandbox` endpoint runs every 15 minutes (`*/15 * * * *`); it clears R2 storage, executes the generated SQL bootstrap (`SANDBOX_RESET_SQL`), normalizes media records, ensures required assets, seeds commerce and content data, and synchronizes Freemius products (product ID `24851`). The `/api/cron/sync-currencies` endpoint runs daily at 18:00 UTC (`0 18 * * *`) and invokes `syncStoreCurrencyRates()` from `@nextblock-cms/ecommerce/server`. Both endpoints require an `Authorization: Bearer ${CRON_SECRET}` header.
1167
1167
 
1168
1168
  **Dependencies**
1169
1169
 
@@ -1188,13 +1188,13 @@ Two cron jobs are declared in `vercel.json`. The `/api/cron/reset-sandbox` endpo
1188
1188
 
1189
1189
  **Description**
1190
1190
 
1191
- Sandbox mode is toggled via the `NEXT_PUBLIC_IS_SANDBOX` environment variable. When enabled, the application renders the `SandboxBanner` and `SandboxCredentialsAlert` components (with demo credentials `demo@nextblock.dev`/`password`), and relaxes Freemius webhook signature verification to tolerate signature mismatches. A live deployment at `https://cms.nextblock.dev/` demonstrates the feature and resets daily via F-025.
1191
+ Sandbox mode is toggled via the `NEXT_PUBLIC_IS_SANDBOX` environment variable. When enabled, the application renders the `SandboxBanner` and `SandboxCredentialsAlert` components (with demo credentials `demo@nextblock.dev`/`password`), and relaxes Freemius webhook signature verification to tolerate signature mismatches. A live deployment at `https://cms.nextblock.dev/` demonstrates the feature and resets every 15 minutes via F-025.
1192
1192
 
1193
1193
  **Dependencies**
1194
1194
 
1195
1195
  | Dependency Type | Details |
1196
1196
  |:--|:--|
1197
- | Prerequisite Features | F-025 (for daily reset) |
1197
+ | Prerequisite Features | F-025 (for the 15-minute reset) |
1198
1198
  | System Dependencies | None |
1199
1199
  | External Dependencies | None |
1200
1200
  | Integration Requirements | `NEXT_PUBLIC_IS_SANDBOX` flag |
@@ -1425,7 +1425,7 @@ This subsection provides the detailed, testable requirements that operationalize
1425
1425
  | F-023-RQ-002 | `activate ecommerce` MUST install the alias `@nextblock-cms/ecommerce@npm:@nextblock-cms/ecom@latest` and inject route wrappers with `verifyPackageOnline()` | Must-Have | High |
1426
1426
  | F-024-RQ-001 | SDK MUST expose `BlockContentSchema`, `BlockData`, `BlockProps`, `BlockEditorProps`, `BlockConfig`, `LucideIcon` | Must-Have | Low |
1427
1427
  | F-024-RQ-002 | External block authoring MUST follow the contract shape documented in `docs/07-BLOCK-SDK-AND-EXTENSIBILITY.md` | Must-Have | Medium |
1428
- | F-025-RQ-001 | `/api/cron/reset-sandbox` MUST run daily at 03:00 UTC with `Bearer CRON_SECRET` authorization | Must-Have | Medium |
1428
+ | F-025-RQ-001 | `/api/cron/reset-sandbox` MUST run every 15 minutes with `Bearer CRON_SECRET` authorization | Must-Have | Medium |
1429
1429
  | F-025-RQ-002 | `/api/cron/sync-currencies` MUST run daily at 18:00 UTC with `Bearer CRON_SECRET` authorization | Must-Have | Low |
1430
1430
  | F-026-RQ-001 | Sandbox banner and credential alert MUST render when `NEXT_PUBLIC_IS_SANDBOX === 'true'` | Should-Have | Low |
1431
1431
  | F-027-RQ-001 | `/api/revalidate` MUST validate `REVALIDATE_SECRET_TOKEN` before calling `revalidatePath` | Must-Have | Medium |
@@ -1703,7 +1703,7 @@ The following matrix links features to the sections of the technical specificati
1703
1703
  - `README.md` — Product value proposition, competitive positioning, Lighthouse and CLI claims
1704
1704
  - `package.json` — Workspace dependency versions (Next.js, React, TypeScript, Nx, Tailwind, Tiptap)
1705
1705
  - `nx.json` — Nx plugin and release configuration
1706
- - `vercel.json` — Cron schedule definitions (reset-sandbox 03:00 UTC; sync-currencies 18:00 UTC)
1706
+ - `vercel.json` — Cron schedule definitions (reset-sandbox every 15 minutes; sync-currencies 18:00 UTC)
1707
1707
  - `.env.example` — Environment variable reference template
1708
1708
  - `eslint.config.mjs` — `@nx/enforce-module-boundaries` scope-tag rules (F-028)
1709
1709
  - `apps/nextblock/next.config.js` — Image format/device-size config; CSP; `transpilePackages`
@@ -2206,7 +2206,7 @@ The `vercel.json` file declares two scheduled jobs:
2206
2206
 
2207
2207
  | Path | Schedule (UTC) | Purpose |
2208
2208
  |:--|:--|:--|
2209
- | `/api/cron/reset-sandbox` | `0 3 * * *` (03:00 daily) | Resets sandbox R2 + data for the demo deployment (F-025, F-026) |
2209
+ | `/api/cron/reset-sandbox` | `*/15 * * * *` (every 15 minutes) | Resets sandbox R2 + data for the demo deployment (F-025, F-026) |
2210
2210
  | `/api/cron/sync-currencies` | `0 18 * * *` (18:00 daily) | FX rate synchronization (F-018, F-025) |
2211
2211
 
2212
2212
  Both endpoints enforce `Authorization: Bearer ${CRON_SECRET}` per the security mitigation in Section 2.4.4.
@@ -2524,7 +2524,7 @@ The premium `libs/ecommerce` is guarded at runtime by the `verifyPackageOnline('
2524
2524
  - `package.json` — Root workspace package metadata, all dependency versions, and npm scripts
2525
2525
  - `nx.json` — Nx workspace configuration, registered plugins, generators, and targets
2526
2526
  - `tsconfig.base.json` — Shared TypeScript strict-mode configuration and monorepo path aliases
2527
- - `vercel.json` — Cron schedules for `reset-sandbox` (03:00 UTC) and `sync-currencies` (18:00 UTC)
2527
+ - `vercel.json` — Cron schedules for `reset-sandbox` (every 15 minutes) and `sync-currencies` (18:00 UTC)
2528
2528
  - `tailwind.config.js` — Root Tailwind CSS theme tokens, dark-mode configuration, content globs
2529
2529
  - `postcss.config.js` — PostCSS pipeline with `@tailwindcss/postcss` and `autoprefixer`
2530
2530
  - `eslint.config.mjs` — Flat ESLint configuration with `@nx/enforce-module-boundaries` rules
@@ -3435,7 +3435,7 @@ flowchart LR
3435
3435
 
3436
3436
  ### 4.5.1 Sandbox Reset Cron
3437
3437
 
3438
- The sandbox reset cron at `/api/cron/reset-sandbox/` executes daily at 03:00 UTC and performs a comprehensive environment rebuild: R2 storage deletion and re-seeding, database bootstrap via generated `SANDBOX_RESET_SQL`, and seeding of commerce products, localized content, and navigation entries. The endpoint requires `NEXT_PUBLIC_IS_SANDBOX === 'true'` and rejects execution in production environments.
3438
+ The sandbox reset cron at `/api/cron/reset-sandbox/` executes every 15 minutes and performs a comprehensive environment rebuild: R2 storage deletion and re-seeding, database bootstrap via generated `SANDBOX_RESET_SQL`, and seeding of commerce products, localized content, and navigation entries. The endpoint requires `NEXT_PUBLIC_IS_SANDBOX === 'true'` and rejects execution in production environments.
3439
3439
 
3440
3440
  ```mermaid
3441
3441
  flowchart TB
@@ -3926,7 +3926,7 @@ The following table consolidates all documented timing constraints and SLAs acro
3926
3926
  | Sync-Currencies maxDuration | 30 seconds | `api/cron/sync-currencies` |
3927
3927
  | Reset-Sandbox maxDuration | 60 seconds | `api/cron/reset-sandbox` |
3928
3928
  | Currency Sync Schedule | 18:00 UTC daily (`0 18 * * *`) | `vercel.json` |
3929
- | Sandbox Reset Schedule | 03:00 UTC daily (`0 3 * * *`) | `vercel.json` |
3929
+ | Sandbox Reset Schedule | every 15 minutes (`*/15 * * * *`) | `vercel.json` |
3930
3930
  | Max Source Image Width | 2560 pixels | `api/process-image` |
3931
3931
  | Image Derivative Widths | 1920, 1280, 768, 384, 128 | `api/process-image` |
3932
3932
  | Lighthouse Performance Target | 100/100 | `README.md` |
@@ -3956,9 +3956,9 @@ flowchart LR
3956
3956
  HstsHeader[HSTS Header<br/>2 years max-age]
3957
3957
  end
3958
3958
 
3959
- subgraph Scheduled[" Scheduled Daily "]
3959
+ subgraph Scheduled[" Scheduled (Vercel Cron) "]
3960
3960
  CurrencyDay[18:00 UTC<br/>Sync Currencies]
3961
- ResetDay[03:00 UTC<br/>Sandbox Reset]
3961
+ ResetDay[Every 15 min<br/>Sandbox Reset]
3962
3962
  end
3963
3963
  ```
3964
3964
 
@@ -4197,7 +4197,7 @@ The integration landscape comprises eight external domains declared in `libs/env
4197
4197
  | Freemius | HTTPS + `x-freemius-signature` (HMAC SHA-256) | Sandbox bypass when `NEXT_PUBLIC_IS_SANDBOX===true` |
4198
4198
  | Frankfurter FX | HTTPS (JSON) | Cron runs 18:00 UTC daily; `maxDuration: 30s` |
4199
4199
  | SMTP | SMTP + TLS | Best-effort from server actions |
4200
- | Vercel Cron | HTTPS + Bearer `CRON_SECRET` | 03:00 UTC (reset-sandbox, 60s); 18:00 UTC (sync-currencies, 30s) |
4200
+ | Vercel Cron | HTTPS + Bearer `CRON_SECRET` | every 15 min (reset-sandbox, 60s); 18:00 UTC (sync-currencies, 30s) |
4201
4201
  | Google Tag Manager | HTTPS (JS) | GTM id from `privacy_settings` (site_settings); allowlisted in CSP |
4202
4202
 
4203
4203
  ## 5.2 COMPONENT DETAILS
@@ -4641,7 +4641,7 @@ Observability instrumentation includes @vercel/speed-insights for performance me
4641
4641
  | Prefetch Accuracy | Correct `X-Prefetch-Priority` per page-type | `proxy.ts` |
4642
4642
  | Media Optimization | Blur placeholders on uploads | sharp + plaiceholder pipeline |
4643
4643
  | Commerce Conversion | Checkout success by provider | `app/api/checkout/route.ts` + webhooks |
4644
- | Scheduled Job Health | Daily success of sandbox reset + currency sync | `vercel.json` cron configuration |
4644
+ | Scheduled Job Health | Success of sandbox reset (every 15 min) + currency sync (daily) | `vercel.json` cron configuration |
4645
4645
  | Bundle Discipline | Removed console calls in production | `compiler.removeConsole` in `next.config.js` |
4646
4646
 
4647
4647
  ### 5.4.2 Logging and Tracing Strategy
@@ -4764,7 +4764,7 @@ Measurable performance objectives include 100/100 Lighthouse performance, a CLI
4764
4764
 
4765
4765
  #### 5.4.6.1 Sandbox Reset
4766
4766
 
4767
- The `/api/cron/reset-sandbox` endpoint, scheduled daily at 03:00 UTC, reconstructs the demo environment end-to-end: it clears and repopulates Cloudflare R2 media, runs a generated SQL bootstrap (`sandboxResetSql.ts`) against Supabase, normalizes legacy media records, ensures required media assets exist, and seeds commerce/content data. The endpoint only executes when in sandbox mode and after verifying the Bearer `CRON_SECRET`.
4767
+ The `/api/cron/reset-sandbox` endpoint, scheduled every 15 minutes, reconstructs the demo environment end-to-end: it clears and repopulates Cloudflare R2 media, runs a generated SQL bootstrap (`sandboxResetSql.ts`) against Supabase, normalizes legacy media records, ensures required media assets exist, and seeds commerce/content data. The endpoint only executes when in sandbox mode and after verifying the Bearer `CRON_SECRET`.
4768
4768
 
4769
4769
  #### 5.4.6.2 Currency Synchronization
4770
4770
 
@@ -4782,8 +4782,8 @@ Supabase provides point-in-time recovery at the platform level; the eleven canon
4782
4782
 
4783
4783
  ```mermaid
4784
4784
  flowchart LR
4785
- subgraph Scheduled["Daily Schedules (Vercel Cron)"]
4786
- Reset[03:00 UTC<br/>/api/cron/reset-sandbox<br/>maxDuration 60s]
4785
+ subgraph Scheduled["Schedules (Vercel Cron)"]
4786
+ Reset[Every 15 min<br/>/api/cron/reset-sandbox<br/>maxDuration 60s]
4787
4787
  Sync[18:00 UTC<br/>/api/cron/sync-currencies<br/>maxDuration 30s]
4788
4788
  end
4789
4789
 
@@ -5446,7 +5446,7 @@ Two scheduled recovery flows are declared in `vercel.json` and serve both routin
5446
5446
  ```mermaid
5447
5447
  flowchart LR
5448
5448
  subgraph Schedules["vercel.json crons[]"]
5449
- Reset03[03:00 UTC daily<br/>/api/cron/reset-sandbox<br/>maxDuration 60s]
5449
+ Reset03[Every 15 min<br/>/api/cron/reset-sandbox<br/>maxDuration 60s]
5450
5450
  Sync18[18:00 UTC daily<br/>/api/cron/sync-currencies<br/>maxDuration 30s]
5451
5451
  end
5452
5452
 
@@ -5483,7 +5483,7 @@ flowchart LR
5483
5483
  C4 --> C5
5484
5484
  ```
5485
5485
 
5486
- The sandbox reset (`apps/nextblock/app/api/cron/reset-sandbox/route.ts`) only executes when in sandbox mode, providing a self-healing loop for the public demo environment. It serves as a **nightly reconstruction rehearsal** that validates the schema migrations and seed scripts.
5486
+ The sandbox reset (`apps/nextblock/app/api/cron/reset-sandbox/route.ts`) only executes when in sandbox mode, providing a self-healing loop for the public demo environment. It serves as a **continuous reconstruction rehearsal** that validates the schema migrations and seed scripts.
5487
5487
 
5488
5488
  #### 6.1.6.3 Content Recovery via Revisions
5489
5489
 
@@ -5536,7 +5536,7 @@ Failover behavior is **implicit via Vercel's platform** and **explicit via dual-
5536
5536
  - The workspace uses **library decomposition** (eight components in an Nx monorepo) with boundaries enforced at compile time by ESLint `@nx/enforce-module-boundaries`.
5537
5537
  - **Scalability is platform-delegated**: Vercel provides automatic horizontal scaling of stateless serverless functions. Application-level tuning is confined to cache TTLs, `maxDuration`, and caching layers.
5538
5538
  - **Resilience is expressed at the integration surface** via a five-pattern classification (strict failure, dual-path, and graceful degrade), exemplified by the RPC + SQL fallback inventory deduction.
5539
- - **Disaster recovery** rests on Supabase platform PITR, 11 canonical migrations, `page_revisions`/`post_revisions` hybrid snapshot/diff content history, and a nightly sandbox-reset cron that doubles as a reconstruction rehearsal.
5539
+ - **Disaster recovery** rests on Supabase platform PITR, 11 canonical migrations, `page_revisions`/`post_revisions` hybrid snapshot/diff content history, and a 15-minute sandbox-reset cron that doubles as a reconstruction rehearsal.
5540
5540
 
5541
5541
  #### 6.1.7.2 Cross-References
5542
5542
 
@@ -5568,7 +5568,7 @@ Failover behavior is **implicit via Vercel's platform** and **explicit via dual-
5568
5568
  - `apps/nextblock/app/api/checkout/route.ts` — Checkout orchestration with `resolveProviderFromItem` chain and license-gate integration
5569
5569
  - `apps/nextblock/app/api/webhooks/stripe/route.ts` — Stripe signature verification + event dispatch
5570
5570
  - `apps/nextblock/app/api/webhooks/freemius/route.ts` — Freemius HMAC-SHA-256 verification + sandbox bypass
5571
- - `apps/nextblock/app/api/cron/reset-sandbox/route.ts` — Daily sandbox reset flow; R2 clearing, SQL bootstrap, media normalization, seeding
5571
+ - `apps/nextblock/app/api/cron/reset-sandbox/route.ts` — 15-minute sandbox reset flow; R2 clearing, SQL bootstrap, media normalization, seeding
5572
5572
  - `apps/nextblock/app/api/cron/sync-currencies/route.ts` — Daily Frankfurter FX sync; Bearer `CRON_SECRET` auth
5573
5573
  - `apps/nextblock/app/api/revalidate/route.ts` — On-demand ISR invalidation from Supabase webhooks
5574
5574
  - `apps/nextblock/app/api/upload/presigned-url/route.ts` — R2 presigned URL generation (300s TTL, 10 MB cap)
@@ -5583,7 +5583,7 @@ Failover behavior is **implicit via Vercel's platform** and **explicit via dual-
5583
5583
  - `libs/db/src/lib/supabase/middleware.ts` — Supabase session synchronization helper
5584
5584
  - `libs/db/project.json` — Nx project definition with `scope:public` tag
5585
5585
  - `libs/environment.d.ts` — NodeJS.ProcessEnv augmentation declaring all external-service env vars
5586
- - `vercel.json` — Two cron schedule declarations (03:00 UTC reset-sandbox; 18:00 UTC sync-currencies)
5586
+ - `vercel.json` — Two cron schedule declarations (every-15-minutes reset-sandbox; 18:00 UTC sync-currencies)
5587
5587
  - `nx.json` — Nx workspace orchestration and target defaults
5588
5588
  - `eslint.config.mjs` — `@nx/enforce-module-boundaries` rules for scope:public/scope:premium
5589
5589
  - `tsconfig.base.json` — Path aliases for all `@nextblock-cms/*` packages
@@ -5960,7 +5960,7 @@ flowchart TB
5960
5960
  | Manual restore | `psql` with duplicate-error collapser | `apps/nextblock/scripts/restore.js` |
5961
5961
  | Schema reconstruction | Replay 11 migrations in order | `npm run db:reset` via `supabase db reset --workdir libs/db/src` |
5962
5962
  | Content rollback | Hybrid snapshot/diff revisions | `page_revisions`, `post_revisions` (F-008) |
5963
- | Sandbox rehearsal | Daily 03:00 UTC cron, 60s maxDuration | `/api/cron/reset-sandbox` (§4.5) |
5963
+ | Sandbox rehearsal | Every 15 minutes, 60s maxDuration | `/api/cron/reset-sandbox` (§4.5) |
5964
5964
 
5965
5965
  The `backup.js` script reads `POSTGRES_URL` or `DATABASE_URL` via `dotenv`, parses the connection URL, supports a `--name` CLI flag (or interactive prompt) for friendly backup names, creates timestamped directories under `apps/nextblock/backups/`, and spawns `pg_dump` with `PGPASSWORD` and `PGSSLMODE` passed via environment variables.
5966
5966
 
@@ -6182,7 +6182,7 @@ All three paths **fail closed**: missing env vars, query errors, or non-`active`
6182
6182
 
6183
6183
  #### 6.2.4.2 Backup and Fault-Tolerance Policies
6184
6184
 
6185
- Detailed in §6.2.2.8. In summary: Supabase-managed PITR and managed backups (primary DR); `pg_dump` / `psql` scripts (operator-initiated); 11 migrations as schema-of-truth (rebuild); hybrid snapshot/diff revisions (content rollback). The Sandbox Reset Cron at 03:00 UTC daily (60s `maxDuration`) doubles as a reconstruction rehearsal, as documented in §4.5.
6185
+ Detailed in §6.2.2.8. In summary: Supabase-managed PITR and managed backups (primary DR); `pg_dump` / `psql` scripts (operator-initiated); 11 migrations as schema-of-truth (rebuild); hybrid snapshot/diff revisions (content rollback). The Sandbox Reset Cron every 15 minutes (60s `maxDuration`) doubles as a reconstruction rehearsal, as documented in §4.5.
6186
6186
 
6187
6187
  #### 6.2.4.3 Privacy Controls via Row-Level Security
6188
6188
 
@@ -6318,7 +6318,7 @@ Application-layer details:
6318
6318
 
6319
6319
  | Batch Workload | Mechanism | Frequency |
6320
6320
  |----------------|-----------|-----------|
6321
- | Sandbox reset (cron) | Service-role client replays seed migrations | Daily 03:00 UTC, 60s `maxDuration` |
6321
+ | Sandbox reset (cron) | Service-role client replays seed migrations | Every 15 minutes, 60s `maxDuration` |
6322
6322
  | Currency exchange-rate sync (cron) | Service-role client updates `currencies.exchange_rate` from Frankfurter API | Daily 18:00 UTC, 30s `maxDuration` |
6323
6323
  | Bulk variant upsert | `upsert_product_with_variants(jsonb)` PL/pgSQL function — admin-only via `is_admin()` | Ad-hoc, CMS-triggered |
6324
6324
  | Migration seeds | Direct SQL in migrations `00000000000008` through `00000000000010` with `ON CONFLICT` merge logic preserving existing values | At deploy time |
@@ -6820,7 +6820,7 @@ All "events" in this system are either **HTTP webhooks delivered by external pro
6820
6820
  | Stripe | `checkout.session.completed` (others ignored) | `libs/ecommerce/src/lib/stripe/webhooks.ts` |
6821
6821
  | Freemius | `install.upgraded`, `license.activated` (others ignored) | `apps/nextblock/app/api/webhooks/freemius/route.ts` |
6822
6822
  | Supabase DB Triggers | Row INSERT/UPDATE/DELETE on `pages` / `posts` | `apps/nextblock/app/api/revalidate/route.ts` |
6823
- | Vercel Cron Ticks | Scheduled GET at `0 3 * * *` / `0 18 * * *` | `/api/cron/reset-sandbox`, `/api/cron/sync-currencies` |
6823
+ | Vercel Cron Ticks | Scheduled GET at `*/15 * * * *` / `0 18 * * *` | `/api/cron/reset-sandbox`, `/api/cron/sync-currencies` |
6824
6824
 
6825
6825
  ##### 6.3.3.1.2 Stripe Event Dispatcher Discipline
6826
6826
 
@@ -6853,12 +6853,12 @@ The revalidation flow functions as a degenerate "stream" with batch size 1: ever
6853
6853
 
6854
6854
  #### 6.3.3.4 Batch Processing Flows
6855
6855
 
6856
- Two daily Vercel cron jobs constitute the entire batch processing surface, declared explicitly in `vercel.json`:
6856
+ Two Vercel cron jobs constitute the entire batch processing surface, declared explicitly in `vercel.json`:
6857
6857
 
6858
6858
  ```mermaid
6859
6859
  flowchart LR
6860
6860
  subgraph CronDecl["vercel.json crons[]"]
6861
- A[path: /api/cron/reset-sandbox<br/>schedule: 0 3 * * *]
6861
+ A[path: /api/cron/reset-sandbox<br/>schedule: */15 * * * *]
6862
6862
  B[path: /api/cron/sync-currencies<br/>schedule: 0 18 * * *]
6863
6863
  end
6864
6864
 
@@ -6907,7 +6907,7 @@ flowchart LR
6907
6907
  SA6 --> SA7
6908
6908
  ```
6909
6909
 
6910
- ##### 6.3.3.4.1 Sandbox Reset Cron (03:00 UTC, maxDuration 60s)
6910
+ ##### 6.3.3.4.1 Sandbox Reset Cron (every 15 minutes, maxDuration 60s)
6911
6911
 
6912
6912
  Purpose: Reconstruct the public demo environment from scratch so that visitor-driven modifications do not pollute the demo. The handler executes eleven ordered steps including R2 bucket clearing via `ListObjectsV2Command` + `DeleteObjectsCommand`, seed asset re-upload via `PutObjectCommand`, SQL bootstrap via the `postgres` driver, media record normalization, Freemius product synchronization, and commerce catalog seeding. The `finally { db.end() }` block guarantees Postgres connection teardown even on error.
6913
6913
 
@@ -7361,7 +7361,7 @@ Per Section 5.1.4.2, each external integration carries explicit SLA-like propert
7361
7361
  | Freemius | HTTPS + `x-freemius-signature` HMAC-SHA-256 | Sandbox bypass when `NEXT_PUBLIC_IS_SANDBOX===true` |
7362
7362
  | Frankfurter | HTTPS (JSON) | Cron daily 18:00 UTC; `maxDuration: 30s` |
7363
7363
  | SMTP | SMTP + TLS | Best-effort from server actions |
7364
- | Vercel Cron | HTTPS + Bearer CRON_SECRET | 03:00 UTC (reset-sandbox 60s); 18:00 UTC (sync-currencies 30s) |
7364
+ | Vercel Cron | HTTPS + Bearer CRON_SECRET | every 15 min (reset-sandbox 60s); 18:00 UTC (sync-currencies 30s) |
7365
7365
  | Google Tag Manager | HTTPS (JS) | GTM id from `privacy_settings` (site_settings); allowlisted in CSP |
7366
7366
 
7367
7367
  #### 6.3.6.2 Known Integration Limitations
@@ -7394,7 +7394,7 @@ The `shipping_zone_locations.postal_code` column exists in the schema but the cu
7394
7394
  - **Four canonical patterns** (outbound HTTPS, signed webhook, token webhook, scheduled cron) cover every integration.
7395
7395
  - **Seven authentication mechanisms** coexist, each tailored to its upstream provider's requirements.
7396
7396
  - **Three-layer authorization** (cookie session → path-prefix guard → RLS + license gate) provides defense in depth.
7397
- - **Batch processing** is limited to two daily Vercel crons (sandbox reset at 03:00 UTC, currency sync at 18:00 UTC).
7397
+ - **Batch processing** is limited to two Vercel crons (sandbox reset every 15 minutes, currency sync daily at 18:00 UTC).
7398
7398
  - **Error handling** is classified into strict-fail, dual-path, and best-effort categories with the RPC + SQL fallback for inventory deduction being the most sophisticated resilience primitive.
7399
7399
  - **Known limitations** include incomplete Freemius reconciliation, a package alias mismatch, FX schema coupling, and an unused postal-code column.
7400
7400
 
@@ -7419,7 +7419,7 @@ The `shipping_zone_locations.postal_code` column exists in the schema but the cu
7419
7419
 
7420
7420
  #### Files Examined
7421
7421
 
7422
- - `vercel.json` — Cron schedule declarations (`reset-sandbox` at 03:00 UTC, `sync-currencies` at 18:00 UTC)
7422
+ - `vercel.json` — Cron schedule declarations (`reset-sandbox` every 15 minutes, `sync-currencies` at 18:00 UTC)
7423
7423
  - `libs/environment.d.ts` — NodeJS.ProcessEnv augmentation declaring all external-integration environment variables
7424
7424
  - `.env.example` — Authoritative environment variable template
7425
7425
  - `apps/nextblock/proxy.ts` — 272-line request proxy consolidating session sync, RBAC, locale, security headers, CSP, and page-type classification
@@ -8187,7 +8187,7 @@ For details beyond the scope of this section, consult:
8187
8187
 
8188
8188
  - `apps/nextblock/proxy.ts` — 272-line edge proxy (session sync, RBAC, locale, CSP, headers, page-type signaling)
8189
8189
  - `apps/nextblock/next.config.js` — 91-line image security config + `compiler.removeConsole`
8190
- - `apps/nextblock/vercel.json` — Cron schedule declarations (03:00 reset-sandbox, 18:00 sync-currencies)
8190
+ - `apps/nextblock/vercel.json` — Cron schedule declarations (every-15-minutes reset-sandbox, 18:00 sync-currencies)
8191
8191
 
8192
8192
  #### Authentication and Authorization
8193
8193
 
@@ -8537,7 +8537,7 @@ No dedicated `/api/health` or `/api/readiness` endpoint exists in the repository
8537
8537
 
8538
8538
  ##### 6.5.3.1.2 Scheduled-Execution Health Signal
8539
8539
 
8540
- The two Vercel cron schedules in `vercel.json` serve a dual purpose: they perform their business function (sandbox reset and currency sync) while simultaneously producing a daily heartbeat that is visible on the Vercel dashboard. A cron invocation that returns HTTP 500 is therefore the closest the system comes to an automated unhealthy signal, because it is automatically surfaced in Vercel's cron execution history.
8540
+ The two Vercel cron schedules in `vercel.json` serve a dual purpose: they perform their business function (sandbox reset and currency sync) while simultaneously producing a recurring heartbeat that is visible on the Vercel dashboard. A cron invocation that returns HTTP 500 is therefore the closest the system comes to an automated unhealthy signal, because it is automatically surfaced in Vercel's cron execution history.
8541
8541
 
8542
8542
  #### 6.5.3.2 Performance Metrics
8543
8543
 
@@ -8599,7 +8599,7 @@ SLAs are encoded directly in configuration files (`vercel.json`, `next.config.js
8599
8599
  | Sync-currencies `maxDuration` | 30 seconds | `vercel.json` + route |
8600
8600
  | Reset-sandbox `maxDuration` | 60 seconds | `vercel.json` + route |
8601
8601
  | Currency sync schedule | `0 18 * * *` (18:00 UTC daily) | `vercel.json` |
8602
- | Sandbox reset schedule | `0 3 * * *` (03:00 UTC daily) | `vercel.json` |
8602
+ | Sandbox reset schedule | `*/15 * * * *` (every 15 minutes) | `vercel.json` |
8603
8603
  | Max source image width | 2560 pixels | `/api/process-image` |
8604
8604
  | Lighthouse performance target | 100/100 | `README.md` |
8605
8605
  | CLI scaffold target | ≤ 30 seconds | `README.md` |
@@ -8642,9 +8642,9 @@ flowchart LR
8642
8642
  HstsHeader[HSTS Header<br/>2 years max-age]
8643
8643
  end
8644
8644
 
8645
- subgraph Scheduled[" Scheduled Daily "]
8645
+ subgraph Scheduled[" Scheduled (Vercel Cron) "]
8646
8646
  CurrencyDay[18:00 UTC<br/>Sync Currencies]
8647
- ResetDay[03:00 UTC<br/>Sandbox Reset]
8647
+ ResetDay[Every 15 min<br/>Sandbox Reset]
8648
8648
  end
8649
8649
  ```
8650
8650
 
@@ -8755,7 +8755,7 @@ Operators have four primary recovery mechanisms, all described in detail in Sect
8755
8755
  1. **Content rollback via revisions.** `page_revisions` and `post_revisions` tables store hybrid snapshot/diff records (JSON Patch via `fast-json-patch`) keyed by `UNIQUE (page_id, version)`. Any published state can be restored without a database restore.
8756
8756
  2. **Supabase Point-in-Time Recovery.** Platform-level PITR is the authoritative recovery path for catastrophic data loss.
8757
8757
  3. **Schema reconstruction from migrations.** The eleven canonical SQL files in `libs/db/src/supabase/migrations/` (`000_foundation_and_enums` through `010_seed_content_scaffold`) allow deterministic schema rebuild on a fresh Supabase project.
8758
- 4. **Nightly sandbox reset as reconstruction rehearsal.** The 03:00 UTC `/api/cron/reset-sandbox` job exercises the full R2-clear → SQL-bootstrap → media-normalize → seed pipeline daily, serving as continuous validation that the recovery procedure still works.
8758
+ 4. **15-minute sandbox reset as reconstruction rehearsal.** The 15-minute `/api/cron/reset-sandbox` job exercises the full R2-clear → SQL-bootstrap → media-normalize → seed pipeline every 15 minutes, serving as continuous validation that the recovery procedure still works.
8759
8759
 
8760
8760
  #### 6.5.4.5 Post-mortem Processes
8761
8761
 
@@ -8847,7 +8847,7 @@ The following observability gaps are acknowledged and documented for honest stak
8847
8847
  - **Alert routing is manual.** The primary alert path is the `FeedbackModal` → `submitFeedback` → SMTP → `feedback@nextblock.dev` flow; platform alerts are configured in Vercel/Supabase consoles.
8848
8848
  - **No distributed tracing, no alert manager, no runbooks, no post-mortems, no persistent audit log table.** These absences are deliberate for the system's scale and are documented as explicit gaps.
8849
8849
  - **SLAs are codified in config, not monitored actively.** The canonical SLA table (Section 4.12) lists all timing constraints; crossings surface as HTTP errors or terminated function invocations in the Vercel log stream.
8850
- - **Disaster recovery rests on Supabase PITR, canonical migrations, content revisions, and the nightly sandbox-reset reconstruction rehearsal** (detailed in Section 6.1.6 and Section 5.4.6).
8850
+ - **Disaster recovery rests on Supabase PITR, canonical migrations, content revisions, and the 15-minute sandbox-reset reconstruction rehearsal** (detailed in Section 6.1.6 and Section 5.4.6).
8851
8851
 
8852
8852
  #### 6.5.7.2 Cross-References to Related Sections
8853
8853
 
@@ -8890,7 +8890,7 @@ The following observability gaps are acknowledged and documented for honest stak
8890
8890
  - `libs/ecommerce/src/lib/stripe/webhooks.ts` — Stripe webhook handler with `[Stripe Webhook Error]` prefix; `console.error` on missing `STRIPE_WEBHOOK_SECRET` and on `constructEvent` failure
8891
8891
  - `libs/db/src/lib/package-validation.ts` — License gate with `console.error` and 60-second `unstable_cache` tagged `'package-activation'`
8892
8892
  - `libs/environment.d.ts` — `NodeJS.ProcessEnv` augmentation declaring external-service env vars (Supabase, R2/S3, SMTP, Freemius, OpenRouter/Cortex AI). GTM is no longer env-configured — it lives in `privacy_settings`.
8893
- - `vercel.json` — Two cron schedule declarations: `0 3 * * *` reset-sandbox (60s) and `0 18 * * *` sync-currencies (30s)
8893
+ - `vercel.json` — Two cron schedule declarations: `*/15 * * * *` reset-sandbox (60s) and `0 18 * * *` sync-currencies (30s)
8894
8894
  - `package.json` (root) — Dependency declarations including `@vercel/speed-insights` and `@next/third-parties`
8895
8895
  - `apps/nextblock/package.json` — Template-level dependency declarations including `@vercel/analytics` (declared but not imported)
8896
8896
  - `docs/05-DEVELOPER-GUIDE.md` — Operational handbook, deployment notes, sandbox operations
@@ -9093,7 +9093,7 @@ Because no integration test suite exists, there is no dedicated test environment
9093
9093
  |:--|:--|
9094
9094
  | Local Supabase via `libs/db/src/supabase/config.toml` | Developer database for hand-driven verification |
9095
9095
  | Vercel Preview Deployments | Per-branch verification prior to production |
9096
- | Sandbox production environment | End-to-end smoke testing via `NEXT_PUBLIC_IS_SANDBOX=true` flag with nightly reset cron |
9096
+ | Sandbox production environment | End-to-end smoke testing via `NEXT_PUBLIC_IS_SANDBOX=true` flag with a 15-minute reset cron |
9097
9097
 
9098
9098
  ---
9099
9099
 
@@ -9103,7 +9103,7 @@ Because no integration test suite exists, there is no dedicated test environment
9103
9103
 
9104
9104
  No E2E test framework (Playwright, Cypress, WebdriverIO, Puppeteer) is installed. This is explicitly documented as the accepted tradeoff in ADR §5.3.1: *"Vitest-only — Limited end-to-end coverage."* The absence is compensated by:
9105
9105
 
9106
- 1. **Sandbox reset cron as reconstruction rehearsal.** The `/api/cron/reset-sandbox` endpoint (§6.1.6.2) runs nightly at 03:00 UTC, clearing R2, running `SANDBOX_RESET_SQL`, normalizing legacy media, re-seeding commerce and content. A successful reset validates that the full happy-path data pipeline — migrations, storage, seeding — functions end-to-end.
9106
+ 1. **Sandbox reset cron as reconstruction rehearsal.** The `/api/cron/reset-sandbox` endpoint (§6.1.6.2) runs every 15 minutes, clearing R2, running `SANDBOX_RESET_SQL`, normalizing legacy media, re-seeding commerce and content. A successful reset validates that the full happy-path data pipeline — migrations, storage, seeding — functions end-to-end.
9107
9107
  2. **Lighthouse performance score targeting 100/100.** Per §5.3.4 and §5.4.5, the 100/100 Lighthouse target provides an observational E2E signal on a per-deployment basis.
9108
9108
  3. **Production monitoring via Vercel Speed Insights + structured `console.warn`/`console.error`.** Per §6.4.3.5, production diagnostics survive `compiler.removeConsole` stripping and provide post-release observability.
9109
9109
 
@@ -9536,7 +9536,7 @@ The accepted tradeoff in §5.3.1 ("Vitest-only — Limited end-to-end coverage")
9536
9536
  - `apps/create-nextblock/package.json` — npm-init stub `"test": "echo \"Error: no test specified\" && exit 1"`
9537
9537
  - `apps/nextblock/project.json` — No test target declared
9538
9538
  - `tools/scripts/release-lib.js` — Library release pipeline; runs `npx nx run ${nxProject}:build --skip-nx-cache --with-deps` with no test invocation
9539
- - `vercel.json` — Cron declarations (03:00 UTC reset-sandbox; 18:00 UTC sync-currencies); no test hooks
9539
+ - `vercel.json` — Cron declarations (every-15-minutes reset-sandbox; 18:00 UTC sync-currencies); no test hooks
9540
9540
  - `docs/05-DEVELOPER-GUIDE.md` — Developer command reference; no test commands documented
9541
9541
  - `.agent/skills/nx-operations/SKILL.md` — Front matter mentions tests but body documents only Building, Linting, and Development
9542
9542
 
@@ -10555,7 +10555,7 @@ The repository supports three deployment environments, with promotion driven by
10555
10555
  | Preview / Staging | Push to non-deployment branch or PR | Vercel Preview Deployment (unique URL per commit) |
10556
10556
  | Production | Push to Vercel-integrated deployment branch (default base: `master`) | Vercel Production Deployment (`NEXT_PUBLIC_URL`) |
10557
10557
 
10558
- A special **Sandbox production environment** is gated by `NEXT_PUBLIC_IS_SANDBOX=true` and is reset nightly at 03:00 UTC via the `/api/cron/reset-sandbox` endpoint. Sandbox serves as a public demonstration site and as a continuous reconstruction rehearsal for the disaster recovery pipeline (see §8.2.2.5).
10558
+ A special **Sandbox production environment** is gated by `NEXT_PUBLIC_IS_SANDBOX=true` and is reset every 15 minutes via the `/api/cron/reset-sandbox` endpoint. Sandbox serves as a public demonstration site and as a continuous reconstruction rehearsal for the disaster recovery pipeline (see §8.2.2.5).
10559
10559
 
10560
10560
  #### 8.2.2.4 Environment Promotion Flow Diagram
10561
10561
 
@@ -10566,7 +10566,7 @@ flowchart LR
10566
10566
  Preview[Vercel Preview Deployment<br/>Per-commit URL<br/>Shared Supabase preview]
10567
10567
  Merge[Merge to master]
10568
10568
  Prod[Vercel Production Deployment<br/>NEXT_PUBLIC_URL<br/>Production Supabase]
10569
- Sandbox[Sandbox Production<br/>NEXT_PUBLIC_IS_SANDBOX=true<br/>Nightly reset 03:00 UTC]
10569
+ Sandbox[Sandbox Production<br/>NEXT_PUBLIC_IS_SANDBOX=true<br/>Reset every 15 min]
10570
10570
  ResetCycle[R2 clear +<br/>SANDBOX_RESET_SQL +<br/>media normalize +<br/>seed content]
10571
10571
 
10572
10572
  Dev --> PR
@@ -10576,7 +10576,7 @@ flowchart LR
10576
10576
  Prod -.parallel branch.-> Sandbox
10577
10577
 
10578
10578
  Sandbox -->|cron/reset-sandbox| ResetCycle
10579
- ResetCycle -.nightly.-> Sandbox
10579
+ ResetCycle -.every 15 min.-> Sandbox
10580
10580
 
10581
10581
  style Dev fill:#e0f2fe,stroke:#0284c7
10582
10582
  style Preview fill:#fef3c7,stroke:#d97706
@@ -10593,7 +10593,7 @@ Disaster recovery relies on **four compounding recovery mechanisms**, none of wh
10593
10593
  | Supabase Point-in-Time Recovery (PITR) | Catastrophic data loss | Platform-managed by Supabase |
10594
10594
  | Content revisions | Accidental edits / content rollback | `page_revisions` + `post_revisions` tables with JSON Patch diffs (via `fast-json-patch`), `UNIQUE(page_id, version)` |
10595
10595
  | Schema reconstruction from migrations | Cold-start rebuild | 11 canonical SQL files in `libs/db/src/supabase/migrations/` applied in order |
10596
- | Nightly sandbox reset (reconstruction rehearsal) | Continuous validation that recovery pipeline works | `/api/cron/reset-sandbox` at 03:00 UTC |
10596
+ | 15-minute sandbox reset (reconstruction rehearsal) | Continuous validation that recovery pipeline works | `/api/cron/reset-sandbox` every 15 minutes |
10597
10597
 
10598
10598
  Backup responsibility matrix:
10599
10599
 
@@ -11038,7 +11038,7 @@ Scheduled jobs deploy automatically with the application via `vercel.json`:
11038
11038
  ```json
11039
11039
  {
11040
11040
  "crons": [
11041
- {"path": "/api/cron/reset-sandbox", "schedule": "0 3 * * *"},
11041
+ {"path": "/api/cron/reset-sandbox", "schedule": "*/15 * * * *"},
11042
11042
  {"path": "/api/cron/sync-currencies", "schedule": "0 18 * * *"}
11043
11043
  ]
11044
11044
  }
@@ -11046,7 +11046,7 @@ Scheduled jobs deploy automatically with the application via `vercel.json`:
11046
11046
 
11047
11047
  | Cron | Schedule (UTC) | maxDuration | Authentication |
11048
11048
  |:--|:--|:--|:--|
11049
- | `/api/cron/reset-sandbox` | `0 3 * * *` (03:00 daily) | 60s | `Authorization: Bearer ${CRON_SECRET}` |
11049
+ | `/api/cron/reset-sandbox` | `*/15 * * * *` (every 15 minutes) | 60s | `Authorization: Bearer ${CRON_SECRET}` |
11050
11050
  | `/api/cron/sync-currencies` | `0 18 * * *` (18:00 daily) | 30s | `Authorization: Bearer ${CRON_SECRET}` |
11051
11051
 
11052
11052
  Purpose: `reset-sandbox` performs R2 clear + `SANDBOX_RESET_SQL` + media normalize + content seed; `sync-currencies` performs Frankfurter FX fetch + currency row update.
@@ -11102,7 +11102,7 @@ flowchart TB
11102
11102
  subgraph CronPipeline["Scheduled Jobs - Vercel Cron"]
11103
11103
  CronDecl[vercel.json crons array]
11104
11104
  CronRuntime[Vercel Cron Dispatcher]
11105
- ResetJob[/api/cron/reset-sandbox<br/>03:00 UTC]
11105
+ ResetJob[/api/cron/reset-sandbox<br/>every 15 min]
11106
11106
  SyncJob[/api/cron/sync-currencies<br/>18:00 UTC]
11107
11107
  end
11108
11108
 
@@ -11276,7 +11276,7 @@ Per §4.12, the following are the codified timing constraints. Breaches surface
11276
11276
  | Sync-currencies maxDuration | 30s | `vercel.json` + route export |
11277
11277
  | Reset-sandbox maxDuration | 60s | `vercel.json` + route export |
11278
11278
  | Currency sync schedule | 18:00 UTC daily | `vercel.json` |
11279
- | Sandbox reset schedule | 03:00 UTC daily | `vercel.json` |
11279
+ | Sandbox reset schedule | every 15 minutes | `vercel.json` |
11280
11280
  | Max source image width | 2560 px | `/api/process-image` |
11281
11281
  | Image derivative widths | 1920, 1280, 768, 384, 128 | `next.config.js` `deviceSizes`/`imageSizes` |
11282
11282
  | Image quality presets | 60, 75 | `next.config.js` `qualities` |
@@ -11402,7 +11402,7 @@ graph TB
11402
11402
  | Review Vercel log stream | Daily / on-alert | Vercel console |
11403
11403
  | Review Supabase Advisors | Weekly | Supabase console |
11404
11404
  | Review feedback inbox | Daily | `feedback@nextblock.dev` |
11405
- | Sandbox reset validation | Automated | `/api/cron/reset-sandbox` nightly at 03:00 UTC |
11405
+ | Sandbox reset validation | Automated | `/api/cron/reset-sandbox` every 15 minutes |
11406
11406
  | FX rate sync | Automated | `/api/cron/sync-currencies` daily at 18:00 UTC |
11407
11407
  | Dependency audit | Per release | `npm audit`, manual review |
11408
11408
  | Security patch review | On advisory | `npm update` + regression testing |
@@ -11534,12 +11534,12 @@ Operators should select tiers based on expected monthly active users, storage fo
11534
11534
  - **Vercel-native, platform-delegated deployment**: no Docker, no Kubernetes, no Terraform, no GitHub Actions — all four absences are intentional ADRs documented in §5.3.7.3 and §3.7.1.
11535
11535
  - **Three managed platform providers** compose the production footprint: Vercel (app + edge + cron + RUM), Supabase (PostgreSQL 17 + Auth + Storage metadata), Cloudflare R2 (S3-compatible object storage).
11536
11536
  - **Hybrid CI/CD** combines Vercel Git integration (for application deployment) with three Node.js release scripts under `tools/scripts/` (for library/CLI/DB releases).
11537
- - **Two Vercel cron schedules** in `vercel.json`: `/api/cron/reset-sandbox` at 03:00 UTC (60s max) and `/api/cron/sync-currencies` at 18:00 UTC (30s max).
11537
+ - **Two Vercel cron schedules** in `vercel.json`: `/api/cron/reset-sandbox` every 15 minutes (60s max) and `/api/cron/sync-currencies` at 18:00 UTC (30s max).
11538
11538
  - **Infrastructure as Code is declarative**, distributed across `vercel.json`, `nx.json`, `libs/db/src/supabase/{migrations/, config.toml, templates/}`, `.env.example`, and per-project `project.json` files.
11539
11539
  - **Library publication uses a Twin Package Strategy** for `@nextblock-cms/ecom`: stub to public npm registry + real module to private GitHub Packages.
11540
11540
  - **11 canonical SQL migrations** compose the database schema; re-running them from a fresh Supabase project deterministically reconstructs the system.
11541
11541
  - **Monitoring is intentionally minimal**: Vercel Speed Insights for RUM, GTM for client analytics, structured `console.warn`/`console.error` logs for server-side events. No Prometheus/Grafana/Datadog/PagerDuty.
11542
- - **Disaster recovery relies on four compounding mechanisms**: Supabase PITR, content revisions with JSON Patch diffs, schema reconstruction from migrations, and nightly sandbox reset as a continuous reconstruction rehearsal.
11542
+ - **Disaster recovery relies on four compounding mechanisms**: Supabase PITR, content revisions with JSON Patch diffs, schema reconstruction from migrations, and 15-minute sandbox reset as a continuous reconstruction rehearsal.
11543
11543
  - **Cost optimization is designed in**: zero egress on R2, platform-delegated scaling on Vercel, 1-year image cache TTL, daily (not per-request) FX sync.
11544
11544
 
11545
11545
  ### 8.11.2 Cross-References to Other Sections
@@ -11573,7 +11573,7 @@ Operators should select tiers based on expected monthly active users, storage fo
11573
11573
  **Files Examined**
11574
11574
 
11575
11575
  - `.env.example` — Authoritative inventory of 40+ environment variables across 7 categories (Platform, Secrets, FX, Supabase, R2, SMTP, Stripe, Freemius)
11576
- - `vercel.json` — Declarative cron schedule definitions (2 crons: reset-sandbox at 03:00 UTC, sync-currencies at 18:00 UTC)
11576
+ - `vercel.json` — Declarative cron schedule definitions (2 crons: reset-sandbox every 15 minutes, sync-currencies at 18:00 UTC)
11577
11577
  - `package.json` (root) — Workspace identity (`nextblock`), 51 npm scripts, Nx plugin versions, dependency overrides, `packageManager`
11578
11578
  - `nx.json` — Workspace orchestration: 6 plugins, `defaultBase: master`, production named-input exclusions, `release.version.preVersionCommand`
11579
11579
  - `apps/nextblock/next.config.js` — Image pipeline config, `compiler.removeConsole`, `transpilePackages`, dynamic `remotePatterns`, `turbopack.resolveAlias`
@@ -11762,7 +11762,7 @@ Reproduced from Section 4.12 for quick reference during operational work. Values
11762
11762
  | Sync-currencies `maxDuration` | 30 seconds | `api/cron/sync-currencies` |
11763
11763
  | Reset-sandbox `maxDuration` | 60 seconds | `api/cron/reset-sandbox` |
11764
11764
  | Currency sync schedule | `0 18 * * *` (18:00 UTC daily) | `vercel.json` |
11765
- | Sandbox reset schedule | `0 3 * * *` (03:00 UTC daily) | `vercel.json` |
11765
+ | Sandbox reset schedule | `*/15 * * * *` (every 15 minutes) | `vercel.json` |
11766
11766
  | Max source image width | 2560 pixels | `api/process-image` |
11767
11767
  | Image derivative widths | 1920, 1280, 768, 384, 128 | `api/process-image` |
11768
11768
  | Lighthouse performance target | 100/100 | `README.md` |
@@ -12140,7 +12140,7 @@ The glossary defines domain-specific, product-specific, and platform-specific te
12140
12140
 
12141
12141
  **Sandbox Mode** — The demonstration environment activated by `NEXT_PUBLIC_IS_SANDBOX=true`. The `cms.nextblock.dev` deployment operates in sandbox mode with demo credentials `demo@nextblock.dev` / `password`.
12142
12142
 
12143
- **Sandbox Reset** — The nightly 03:00 UTC cron job at `/api/cron/reset-sandbox` that clears R2, bootstraps SQL, normalizes media, and re-seeds content.
12143
+ **Sandbox Reset** — The 15-minute cron job at `/api/cron/reset-sandbox` that clears R2, bootstraps SQL, normalizes media, and re-seeds content.
12144
12144
 
12145
12145
  **Scope Tag** — An Nx project tag (`scope:public` or `scope:premium`) validated by the `@nx/enforce-module-boundaries` ESLint rule. See Section 9.1.5.
12146
12146