When: new project; scaffold a Next.js + Supabase app or an early-stage one · Input: {{project_path}} {{project_name}} {{product_type}} {{languages}} {{apply}} {{client_project}} {{fix}} {{jurisdiction}} · Output: project card + M0-M5 + DoD · keywords: setup, scaffold, boilerplate, new project
0stars
UpdatedOct 30, 2026
v1
License: CC BY 4.0. The author shares the prompts of this repo under these terms.
Import with the CLI:
ple import ple:zeynepaslierhan/ortak-web-en/3f7e54b5148 lines
# Web project setup from scratch (Next.js + Supabase)
Goal: build the production foundation FROM SCRATCH for {{#if project_name}}"{{project_name}}"{{else}}the app{{/if}} in {{#if project_path}}`{{project_path}}`{{else}}`.`{{/if}}. {{#if apply}}Mode APPLY: run M0→M5 in order; {{#if client_project}}deliver each step as a separate patch (`git diff` output) or a branch proposal, NO commit/push{{else}}finish each step with its own commit (explicit file paths only) + that step's verification command{{/if}}; do not move on while a check is red.{{else}}Mode PLAN: edit no files; produce only a plan with the skeleton below.{{/if}}
{{#if client_project}}Client project: NO commit/push. Every step is a patch (diff) or branch proposal; end with a non-technical client summary.{{/if}}
{{#if fix}}If you find P0/P1 issues in existing code (in PLAN mode too, for these only), fix them with a minimal diff + test{{#if client_project}} (patch proposal only){{/if}}; list P2/P3 under "Deliberately deferred".{{/if}}
{{#if standards_dir}}Read index.md in {{standards_dir}} and apply the relevant rule tables too.{{/if}}
Jurisdiction: {{#if jurisdiction}}`{{jurisdiction}}`{{else}}`global`{{/if}} (global · eu · uk · us · tr). Legal items (1.11, 3.3, 3.4, 4.9) use the matching "Legal baseline" row.
Rules: never read/print `.env*` or key VALUES (name + location only). Stage with explicit file paths only. Never invent versions or thresholds; confirm dated facts by command. `\|` in tables is a markdown escape; type `|` in the shell. Severity: P0 critical (live data/account/payment/secret risk, now) · P1 high (before delivery) · P2 medium · P3 low. This prompt does not audit: M5 runs "Web full audit and launch gate"; do not repeat its checks here.
## Step 0 — stack detection
| Check | Command | Decision |
|---|---|---|
| Next version + router | `node -p "require('next/package.json').version"` (installed, not the `package.json` range); `ls app src/app pages 2>/dev/null` | New project: Next 16.x + App Router. On 15.x write a migration plan (security support for the 15 line ends 2027-01-31; confirm at `https://nextjs.org/support-policy`) |
| Security floor | `npm view next version`; `npm audit --omit=dev --audit-level=high` | Use the latest patched Next 16.x (floor on 2026-10-30: 16.4.1); version/CVE thresholds are owned by "Web security audit (Next.js + Supabase)" Step 1, not repeated here |
| Supabase | `jq '.dependencies' package.json \| grep supabase`; `ls supabase/migrations`; `supabase --version` | `@supabase/ssr` + `@supabase/supabase-js`; migrate any `auth-helpers` to ssr |
| Auth method | `grep -rn "signInWith" src app 2>/dev/null` | List email+password / magic link / OAuth providers |
| Hosting | `ls vercel.json .vercel 2>/dev/null` | Assume Vercel; payments, ads or paid client work cannot run on Hobby (Pro+) |
| i18n / payments | `grep -rlnE "next-intl\|i18n" --exclude-dir={node_modules,.next,.git} .`; `grep -rlnE "stripe\|lemonsqueezy\|iyzico\|paddle" --exclude-dir={node_modules,.next,.git} .` | Log items that do not apply under "Deliberately deferred" as "not applicable" |
{{#if product_type}}Product type: {{product_type}}.{{else}}Infer product type from README and routes (saas · content · ecommerce · dashboard · community) and give a one-line reason.{{/if}}
{{#if shared_backend}}Shared backend: schema, RLS, migrations, Storage and Supabase Auth settings live in the `{{shared_backend}}` repo; this repo connects with a tenant key (e.g. `site_key`). Do NOT apply here the dashboard/schema parts of 1.1, 1.3–1.8, 1.12–1.14, the `supabase` steps of 4.3, 4.5 or 4.7: route each to the backend owner as a task marked "owner: {{shared_backend}}" and write "— at owner" in the DoD. In this repo only: the tenant key comes from server env (not from client, URL or cookie); every read and write is scoped by tenant; types are generated from the backend repo; 2.3 applies to every route including GET (never skip authz trusting RLS). Verify: locally, with another tenant's key in env, this tenant's rows = 0; tenant key read from the request → P0.{{else}}If schema/RLS live in another repo (shared backend, tenant key), fetch this prompt again with `--var shared_backend=<backend repo>`.{{/if}}
## Project card
| Field | Value |
|---|---|
| Name · product type | {{#if project_name}}{{project_name}}{{else}}(package.json name){{/if}} · (Step 0 result) |
| Stack | Next (version) · React (version) · Supabase (Free/Pro) · hosting + plan · payment provider or "none" |
| Languages | {{#if languages}}{{languages}}{{else}}single language (default en){{/if}} |
| Environments | local → preview/staging (separate Supabase project or branch) → production; project ref of each (ref only, never a key) |
| Domain | apex A + www CNAME, values from the Vercel project domain card (verify in 4.8) |
| Live | {{#if live_url}}{{live_url}} — if the repo is ahead of live (undeployed commits), say so on the card{{else}}not yet{{/if}} |
## Legal baseline
Not legal advice; a lawyer approves the texts. Mark any threshold you cannot cite "(not verified)".
| Jurisdiction | Notice (5 elements) | Consent, rights, processors | Sales | Breach |
|---|---|---|---|---|
| global · eu · uk | Controller + contact, purposes + lawful basis, recipients/processors, retention, data subject rights (access, erasure, portability, objection, complaint) | GDPR-grade (uk: UK GDPR + PECR): cookie Reject as easy as Accept; DPA with every processor (Supabase, Vercel, Sentry, email, payments) | Terms + consumer pre-contract info + withdrawal/refund terms (not verified) | Supervisory authority within 72 hours of becoming aware (GDPR Art. 33) |
| us | Notice at collection: categories, purposes, retention, sharing/sale, rights; "Do Not Sell or Share" link where applicable (CCPA/CPRA thresholds not verified) | Honor opt-outs; CAN-SPAM for email: accurate sender, working unsubscribe, postal address | Terms + refund policy | State breach-notification laws; deadlines vary (not verified) |
| tr | KVKK aydınlatma: veri sorumlusu, amaç, alıcılar, toplama yöntemi + hukuki sebep, m.11 hakları; VERBİS registration (exemption threshold not verified) | Cookies per KVK Kurulu decision: Kabul/Reddet equal weight | Mesafeli satış sözleşmesi + ön bilgilendirme formu; ETBİS registration (not verified) | KVK Kurulu within 72 hours of detection |
## Setup order
Each row: what · why (1 line) · verification (command + expected).
### M0 — Skeleton
| # | What | Why | Verification |
|---|---|---|---|
| 0.1 | In an empty dir `npx create-next-app@latest <name> --typescript --app --eslint --src-dir` (skip in an existing repo); pin Node with `.nvmrc` + `engines` | Reproducible setup | `npm ci && npx tsc --noEmit` clean |
| 0.2 | Folders: `src/app`, `src/components`, `src/lib/supabase/{server,client,proxy}.ts`, `src/lib/env.ts`, `supabase/migrations`, `tests`, `e2e`, `docs` | Server/client boundary visible in structure | `ls` output matches the plan |
| 0.3 | `docs/MAP.md`: route list, tables, env NAMES, external services, decisions | A new agent/dev gets oriented in 5 minutes | File exists; every route/table is listed |
| 0.4 | `.env.example` (name + description only), `.env*` in `.gitignore`; `src/lib/env.ts` validates env with zod at startup | Missing env fails the build, not production | `git check-ignore .env.local`; build red when an env var is removed |
| 0.5 | `NEXT_PUBLIC_` only for values meant for the browser; `npm i server-only`, server modules `import 'server-only'`; client code reads env only as static `process.env.NEXT_PUBLIC_X` (`process.env[key]`, `const env = process.env`, `parse(process.env)` are not inlined at build → undefined in the browser) | No secrets in the client bundle; dynamic access silently returns empty | `grep -rn "NEXT_PUBLIC_" .env.example src \| grep -iE "SERVICE_ROLE\|SECRET\|ADMIN"` = 0; `grep -rlE "^[[:space:]]*['\"]use client" src \| xargs grep -nE 'process\.env\[\|= process\.env;?$\|\(process\.env\)'` = 0 (≠0 → P1; fine in server modules; review shared modules imported by the client by hand) |
| 0.6 | Server Components by default; `'use client'` only on the narrowest leaf (not on page/layout) | Small bundle, data stays on the server | `grep -rlE "^[[:space:]]*['\"]use client" src/app --include=page.tsx --include=layout.tsx` = 0 (comments do not count) |
| 0.7 | Dev server not exposed (no `-H 0.0.0.0`, no tunnel) | 2026-09-30 Next.js security release (CVE-2026-94486): dev server leaked source/routes/logs | `grep -nE "0\.0\.0\.0\|--hostname\|ngrok\|cloudflared" package.json` = 0 |
| 0.8 | Test base: `vitest` + `@playwright/test` + `@axe-core/playwright`; `npx playwright install chromium`; `test` and `test:e2e` scripts in `package.json` | Needed by CI gate and smoke | `npx vitest run` and `npx playwright test --list` exit 0 |
### M1 — Data + auth
| # | What | Why | Verification |
|---|---|---|---|
| 1.1 | One Supabase project (or branch) per environment; no prod keys on dev machines; prod keys only in the Vercel/CI secret store | Wrong-environment writes; leak blast radius | Prod ref from `supabase projects list`; `grep -c "<prod-ref>" .env.local` = 0 (count only, never print values); non-zero → P0 |
| 1.2 | Client uses only `sb_publishable_`; `sb_secret_` server only; do not use legacy `eyJ…` anon/service_role (deadline 2026-12-31; confirm at `supabase.com/docs/guides/api/api-keys`) | RLS bypass stays possible only on the server | `grep -rnE 'eyJ[A-Za-z0-9_-]{20,}' src .env.example` = 0; after `next build`, `grep -rl sb_secret_ .next/static` = 0 |
| 1.3 | Schema only via `supabase/migrations/<timestamp>_<name>.sql`; anything created in the dashboard is moved back into the repo | Schema rebuilds from git | `supabase start && supabase db reset` clean; `supabase db diff --linked` empty (no tables/policies made by hand in the dashboard) |
| 1.4 | Idempotent migrations (`if not exists`); `drop function` first when a signature changes; irreversible DDL split across two deploys | Re-runs and rollbacks are safe | After reset, apply each file a second time to the same local DB: `psql "$LOCAL_DB_URL" -v ON_ERROR_STOP=1 -f <file>` errors 0 (`LOCAL_DB_URL` = local DB URL from `supabase status`); `select proname,count(*) from pg_proc where pronamespace='public'::regnamespace group by 1 having count(*)>1` empty |
| 1.5 | `enable row level security` on every table inside the migration; policies `to authenticated` + `(select auth.uid())`; index filter/FK columns | Data closed by default; RLS performance | `select relname from pg_class where relrowsecurity=false and relnamespace='public'::regnamespace and relkind='r'` = 0; `grep -nE 'auth\.uid\(\)' supabase/migrations/*.sql \| grep -v 'select auth.uid()'` = 0; Dashboard > Advisors: Security ERROR = 0, Performance 0003 / 0006 / 0001 = 0 (measurement path: security audit 3.2) |
| 1.6 | Policies never read `user_metadata`; role/plan columns protected by column-level GRANT; views `security_invoker = true` | Users cannot escalate their own rights; views skip RLS by default | With a user session `update ... set role='admin'` → permission denied; `grep -nE 'user_meta_data\|user_metadata' supabase/migrations/*.sql` = 0 on policy lines; `select relname from pg_class where relkind='v' and relnamespace='public'::regnamespace and coalesce(array_to_string(reloptions,','),'') not like '%security_invoker=true%'` = 0 rows |
| 1.7 | Money `numeric(12,2)` or minor units `bigint`; time `timestamptz` (store UTC, display in local TZ) | Rounding and time-zone bugs | `information_schema.columns`: float money columns = 0, `timestamp without time zone` = 0 |
| 1.8 | `supabase gen types typescript --local > src/lib/database.types.ts`; clients use this type | Schema/code drift fails compile | After a migration: generate types + `git diff --exit-code src/lib/database.types.ts` + `tsc --noEmit` green |
| 1.9 | `@supabase/ssr`: `server.ts` (cookies), `client.ts` (browser), session refresh in `proxy.ts` (`export function proxy`, `matcher` excluding static files; `middleware.ts` is deprecated in Next 16); file sits at the same level as `app`: with `src/app` use `src/proxy.ts`, NOT the root (a root file is silently ignored: no session refresh, no guard) | Session refreshed per request | `ls middleware.ts src/middleware.ts` absent; with `src/app`, `src/proxy.ts` exists and root `proxy.ts` does not; unauthenticated `curl -s -o /dev/null -w '%{http_code}' <url>/<protected-page>` = 3xx (200 + protected content → P0; 3xx may also come from a page `redirect()`, not proof of the proxy); Playwright: sign in → reload → session kept |
| 1.10 | Server authz decisions use `getUser()` or `getClaims()`; never `getSession().user` for authz; authz checked in the data layer too, not only in the proxy | Cookie forgery and proxy bypass | `grep -rn "getSession()" src`: every match is outside authz |
| 1.11 | Auth lifecycle: sign-up, email verification, sign-in, password reset, email change (double confirmation), password change, sign out everywhere (`signOut({ scope: 'global' })`), account deletion (server route: auth user + tables + user folders in Storage) | Missing flow = support ticket + erasure right (Legal baseline) | Each flow end to end in Playwright; after deletion user rows and files = 0 |
| 1.12 | Passwords: min 15 characters (8 with MFA), accept at least 64 without truncation, no composition rules or periodic rotation; leaked-password protection on if the plan has it | NIST SP 800-63B-4 | Zod schema and Supabase Auth min length match; a 14-character password is rejected at sign-up, a 64-character one accepted; no complexity regex in the password schema (`grep -rnF '(?=.*[' src` = 0) |
| 1.13 | OAuth/email redirect allow list: prod Site URL is the exact domain, preview only its own pattern; no broad wildcard in prod | Open redirect and token leaks | Supabase Auth > URL Configuration list on the card; `**` only in the preview pattern; sign-in with `redirectTo=https://other-domain.example` is rejected or falls back to the Site URL |
| 1.14 | Storage buckets private by default; policy by path prefix `(storage.foldername(name))[1] = (select auth.uid())::text`; type and size limits | Access to others' files | With user A's session read B's path → denied |
1.9 extra evidence (shell): `npm run build 2>&1 | grep -iE 'proxy|middleware'` → a Proxy line in the route list (output text may vary by version, not verified; real evidence is the curl above).
### M2 — Security
| # | What | Why | Verification |
|---|---|---|---|
| 2.1 | Headers: HSTS `max-age=63072000; includeSubDomains`, `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, `Permissions-Policy` disabling unused features | OWASP Secure Headers baseline | `curl -sI <url> \| grep -ciE '^(strict-transport-security\|x-content-type-options\|referrer-policy\|permissions-policy):'` = 4 |
| 2.2 | CSP: per-request nonce in `proxy.ts`, no `unsafe-inline` in `script-src`, `frame-ancestors 'none'`; start with `Report-Only`, enforce once violations are clean | XSS and clickjacking; nonce routes render dynamically | `curl -sI <url> \| grep -i content-security-policy` twice: nonce differs, no `unsafe-inline` in script-src; CSP console violations in Playwright = 0 |
| 2.3 | Every Server Action and route handler does its own authn + authz + zod validation; bad input → 400 | An action is a public HTTP endpoint | Skip the UI: unauthenticated curl POST → 401/403 |
| 2.4 | Rate limit auth, forms, email-sending and costly endpoints per IP + account; 429 when exceeded; review Supabase Auth limits too | Brute force and billing attacks | Local/preview limit+1 loop: `for i in $(seq 1 <limit+1>); do curl -s -o /dev/null -w '%{http_code}\n' -X POST <url>/<endpoint>; done \| tail -1` → 429 |
| 2.5 | Secret scanning in CI (gitleaks/trufflehog, git history included; never print contents, file:line only); Dependabot security updates on; `npm audit --omit=dev --audit-level=high` in CI | A leaked secret is closed by rotation, not deletion | CI step green; `.github/dependabot.yml` or repo setting on |
### M3 — Product baseline
| # | What | Why | Verification |
|---|---|---|---|
| 3.1 | `not-found.tsx`, `error.tsx` (per segment), `global-error.tsx`; slow data in `<Suspense>` only in the relevant component; NO `loading.tsx` at the root (`app/loading.tsx`) or in a segment that calls `notFound()` | Controlled state instead of a broken screen; once streaming starts the status locks at 200 and a later `notFound()` cannot return 404 | `ls src/app/loading.tsx app/loading.tsx 2>/dev/null` empty; `curl -s -o /dev/null -w '%{http_code}' <url>/nonexistent-page-xyz` and `<url>/<dynamic-segment>/nonexistent-slug-xyz` = 404 (200 → P1); every `page.tsx` dir or a parent segment has `error.tsx` |
| 3.2 | SEO: root layout `metadataBase` (from env, fallback NOT localhost) + `title.template`; every route has title + description + full `openGraph` (nested objects do not merge; write it fully); `alternates.canonical` per route (not in the root layout: it is inherited, so 404/utility pages point canonical to home); `app/sitemap.ts` (only 200 + indexable URLs); `app/robots.ts` (Sitemap line; admin/auth pages `noindex`) | Share cards and indexing right from the start | On a prod build `curl -s <url> \| grep -E 'og:image\|og:url\|canonical'` all `https://` + prod domain |
| 3.3 | Legal pages linked from the footer: privacy notice (5 elements of the selected Legal baseline row), privacy policy, terms of use; if selling, the Sales column items; every data-collecting form links to the notice before the submit button | Legal minimum | 5/5 element headings found by grep; link on every form |
| 3.4 | Cookie consent: inventory (essential / consent-based), Accept and Reject equally weighted with one click, no pre-ticked boxes; analytics and third-party scripts load only after consent (us: opt-out model → honor opt-outs and log it under "Deliberately deferred") | Selected Legal baseline row + measurement reliability | After Reject, analytics requests in Network = 0 |
| 3.5 | Fonts self-hosted with `next/font`; for extended-Latin content (e.g. Turkish, Polish) add `latin-ext` to `subsets`; no unconsented requests to the Google Fonts CDN; in Tailwind v4 put the `next/font` `variable` classes on `<html>` or use `@theme inline` (`@theme` on `:root` cannot see a variable set on body) | Diacritics render correctly; unconsented CDN fonts drew enforcement in the EU (LG München 3 O 17493/20) | `grep -rn subsets src/app`; `fonts.gstatic.com` in Network = 0; in Playwright `getComputedStyle(document.body).fontFamily` contains the next/font name (otherwise P2) |
| 3.6 | Accessibility baseline: correct `<html lang>`, skip link, landmarks, one h1 per page, visible labels, error messages with `aria-live`/`role="alert"`, visible focus, touch targets ≥ 24px, `prefers-reduced-motion` | Costly to retrofit | Playwright + `@axe-core/playwright` smoke: critical violations 0 |
| 3.7 | i18n readiness: {{#if languages}}`app/[locale]` routing for {{languages}}, `alternates.languages` (hreflang), strings in dictionary files{{else}}strings collected in one module; install the library when a 2nd language ships{{/if}} | A new language needs no rewrite | Every locale route 200 + correct `lang` |
| 3.8 | Transactional email: custom SMTP for Supabase Auth (the default SMTP is not for production); SPF + DKIM (≥ 1024 bit, 2048 recommended) + DMARC on the sender domain; templates {{#if languages}}in every language{{else}}in the product language{{/if}} | Verify/reset emails avoid spam | `dig +short TXT <domain>`; `dig +short TXT <selector>._domainkey.<domain>`; `dig +short TXT _dmarc.<domain>` |
| 3.9 | If payments: price and product re-read on the server; webhook signature HMAC over the raw body + timing-safe compare; invalid signature runs no business logic (fail-closed); `webhook_events.event_id` UNIQUE (second delivery is a NOOP); subscriptions activate only from a provider event | Double charges, forged events, free subscriptions | Bad signature → 401 + DB changes 0; same event twice → single effect |
3.2 extra evidence (shell): `curl -s <url>/nonexistent-page-xyz | grep -c 'rel="canonical"'` = 0 (≠0 → P2).
### M4 — Observability + release
| # | What | Why | Verification |
|---|---|---|---|
| 4.1 | Sentry client + server + edge; `sendDefaultPii: false`, `beforeSend` scrubs email/password/cookie/Authorization; Replay, if used, masks text | Errors visible, no personal data in logs | Test error in dashboard; PII in event body 0 |
| 4.2 | External uptime monitor (≤ 5 min interval recommended) on home + `/api/health`; alert channel tested | Hear about outages before users do | Monitor listed + test alert received |
| 4.3 | CI gates (required on PRs): `tsc --noEmit`, lint, `vitest run`, `next build`, Playwright smoke (home, sign-in, protected route redirect, 404), `supabase db reset` + `supabase test db` (pgTAP: anon and other users cannot read/write rows) | Broken code never reaches main | A deliberately broken PR → CI red |
| 4.4 | Vercel: Preview → staging Supabase, Production → prod; each variable's scope chosen deliberately; diff of `.env.example` NAMES vs `vercel env ls production` = 0 | Most common bug: in Development, missing in Production | Name-list diff (values never read) empty |
| 4.5 | Migrations to staging first; staging evidence in the PR; then prod | Try without breaking live data | `supabase migration list` staging = prod order |
| 4.6 | Post-deploy smoke (every deploy + dependency upgrade): home 200, protected APIs 401/403 unauthenticated (not 5xx), `og:image` and canonical absolute https | Silent 500s after upgrades | `curl -s -o /dev/null -w '%{http_code}' <url>/api/<protected>` → 401/403 |
| 4.7 | Backups: Free plan has no automatic backups → scheduled off-site `supabase db dump`; Pro 7 days; PITR decision in writing if payment data exists; rehearse a restore into an isolated project and log it with date in `docs/MAP.md` | A backup is a guess until restored | Rehearsal record (date + duration + result) exists |
| 4.8 | Domain: apex A + www CNAME; values from `vercel domains inspect <domain>` (no IPs copied from another project) | Pointing at the wrong project or a dead IP | `dig +short <domain> A` and `dig +short www.<domain> CNAME` match inspect output; CNAME on apex = 0 |
| 4.9 | Incident response: personal-data breach notified per the Breach column of the selected Legal baseline row; owner and steps in `docs/MAP.md` | Legal obligation | Doc section exists |
### M5 — Launch gate
| # | What | Why | Verification |
|---|---|---|---|
| 5.1 | Fetch the gate from PLE and apply its output: `ple get "Web full audit and launch gate" --var project_path="{{#if project_path}}{{project_path}}{{else}}$(pwd){{/if}}" --var live_url="{{#if live_url}}{{live_url}}{{else}}<preview-url>{{/if}}" --var gate=launch{{#if jurisdiction}} --var jurisdiction={{jurisdiction}}{{/if}}{{#if client_project}} --var client_project=1{{/if}}`; if `ple` is unavailable, note it in a "PLE feedback:" line and do not treat the DoD table alone as evidence. No release without P0 = 0 and ownerless P1 = 0 | The only proof the setup passed an audit | Gate verdict PASS |
## Definition of done
Fill the table; status = ✅ passed · ❌ failed · ⏳ not measured (reason) · — not applicable.
| Item | Verification command | Status |
|---|---|---|
| Clean install | `npm ci && npx tsc --noEmit && npm run lint && npx vitest run && npm run build` | |
| Schema builds from git, runs twice | `supabase db reset` + each migration a second time with `psql -v ON_ERROR_STOP=1 -f` (1.4) | |
| Tables without RLS 0, Advisor ERROR 0 | pg_class query + Advisors > Security ERROR count + `supabase test db` | |
| Secrets in client 0 | `grep -rl sb_secret_ .next/static`; NEXT_PUBLIC_ grep | |
| All auth flows | `npx playwright test e2e/auth` | |
| Security headers + CSP | `curl -sI <url>` | |
| Protected endpoints 401/403 unauthenticated | curl loop | |
| SEO baseline | `curl -s <url>/sitemap.xml`, `/robots.txt`, og/canonical grep | |
| Legal + cookie consent | footer links + Network after Reject | |
| Sentry + uptime | test error + test alert | |
| Domain + email DNS | the two `dig`s of 4.8 + the three `dig`s of 3.8 | |
| Env name diff 0 | `.env.example` ↔ `vercel env ls production` | |
| Backup + restore rehearsal | rehearsal record | |
| Payments (if any) | bad signature + duplicate event test | |
| Launch gate | 5.1 gate verdict | |
## Deliberately deferred
List every item left out of scope or found "not applicable"; never leave it empty.
| Item | Reason | Revisit when |
|---|---|---|
## Next 3 steps
Three highest-risk open items: item no · one-sentence task · verification command.
Output skeleton (in this order): ## Project card · ## Setup order (M0–M5, each row what · why · verification{{#if apply}} · {{#if client_project}}patch name{{else}}short commit hash{{/if}} · test result{{/if}}) · ## Definition of done · ## Deliberately deferred · ## Next 3 steps{{#if client_project}} · ## Client summary (non-technical, max 6 lines){{/if}}.
Feedback: If this prompt missed a check, gave a wrong threshold or you hit a PLE problem, send one line: ple feedback --type prompt --prompt "Web project setup from scratch (Next.js + Supabase)" "<what is missing → what it should be>" (use --type bug or --type missing for PLE issues; if the command is unavailable, add a "PLE feedback:" line at the end of your report).Related prompts
Web security audit (Next.js + Supabase)When: scan for vulnerabilities; pre-delivery or periodic security audit of a Next.js + Supabase app · Input: {{project_path}} {{live_url}} {{scope}} {{fix}} {{client_project}} {{jurisdiction}} · Output: evidence-backed findings table + PASS/FAIL · keywords: RLS, secret leaks, CVE, security headers@zeynepaslierhan0Web production baseline auditWhen: pre-delivery gap sweep or inherited web app (accounts, legal, a11y, backups, monitoring) · Input: {{project_path}} {{live_url}} {{product_type}} {{has_sales}} {{jurisdiction}} {{client_project}} {{fix}} · Output: completeness matrix + top 10 gaps · keywords: production readiness, GDPR, backup@zeynepaslierhan0Web full audit and launch gateWhen: pre-delivery audit, pre-launch check, periodic audit; security+baseline+SEO in one run · Input: {{project_path}} {{live_url}} {{gate}} {{client_project}} {{fix}} {{jurisdiction}} · Output: PASS/FAIL + merged priority list · keywords: launch checklist, production readiness, release gate@zeynepaslierhan0Web SEO auditWhen: technical + content SEO audit of a Next.js site, pre-delivery or periodic · Input: {{project_path}} {{live_url}} {{target_market}} {{keywords}} {{fix}} {{client_project}} · Output: verdict + findings and measurement table · keywords: seo check, indexing, canonical, SEO audit, core web vitals@zeynepaslierhan0