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.
- package/package.json +1 -1
- package/templates/nextblock-template/app/api/cron/reset-sandbox/sandboxResetSql.ts +58 -1
- package/templates/nextblock-template/app/cms/settings/security/page.tsx +1 -1
- package/templates/nextblock-template/docs/12-VERCEL-DEPLOYMENT.md +12 -9
- package/templates/nextblock-template/docs/TECHNICAL_SPECIFICATION.md +59 -59
- package/templates/nextblock-template/lib/config/email-settings.ts +323 -323
- package/templates/nextblock-template/lib/setup/migrations-bundle.ts +5 -0
- package/templates/nextblock-template/package.json +1 -1
|
@@ -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
|
|
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 |
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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` |
|
|
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` (
|
|
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
|
|
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 |
|
|
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
|
|
3959
|
+
subgraph Scheduled[" Scheduled (Vercel Cron) "]
|
|
3960
3960
|
CurrencyDay[18:00 UTC<br/>Sync Currencies]
|
|
3961
|
-
ResetDay[
|
|
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` |
|
|
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 |
|
|
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
|
|
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["
|
|
4786
|
-
Reset[
|
|
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[
|
|
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 **
|
|
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
|
|
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` —
|
|
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 (
|
|
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 |
|
|
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
|
|
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 |
|
|
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
|
|
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
|
|
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:
|
|
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 (
|
|
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 |
|
|
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
|
|
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`
|
|
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 (
|
|
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
|
|
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 |
|
|
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
|
|
8645
|
+
subgraph Scheduled[" Scheduled (Vercel Cron) "]
|
|
8646
8646
|
CurrencyDay[18:00 UTC<br/>Sync Currencies]
|
|
8647
|
-
ResetDay[
|
|
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. **
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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/>
|
|
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 -.
|
|
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
|
-
|
|
|
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": "
|
|
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` |
|
|
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/>
|
|
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 |
|
|
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`
|
|
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`
|
|
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
|
|
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
|
|
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 |
|
|
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
|
|
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
|
|