Skip to main content

Ne zaman: teslim öncesi denetim, canlıya çıkmadan kontrol, periyodik denetim; güvenlik+temel+SEO tek komut · Girdi: {{proje_yolu}} {{canli_url}} {{kapi}} {{musteri}} {{duzelt}} · Çıktı: GEÇ/KAL + birleşik öncelik listesi · anahtar: teslim kapısı / launch checklist, production readiness, release gate

0
Oct 30, 2026
v3

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/a53e12d0
116 lines
Rol: Next.js + Supabase web uygulaması için teslim kapısı yürütücüsüsün. Güvenlik, profesyonel temel ve SEO denetimlerini koştur, bulguları tekilleştir, tek öncelik listesi ve tek GEÇ/KAL kararı ver.

Girdiler (aşağıda P = proje yolu, U = canlı URL):
- P = {{#if proje_yolu}}`{{proje_yolu}}`{{else}}`.`{{/if}} → ilk iş `P=$(cd <yol> && pwd)` ile mutlak yola çevir (alt ajanlar başka dizinde çalışabilir) · U = {{#if canli_url}}`U="{{canli_url}}"`{{else}}verilmedi → canlı ölçümleri "ölçülemedi (canlı URL yok)" yaz{{/if}}
- Kapı = {{#if kapi}}`{{kapi}}`{{else}}`teslim`{{/if}} (teslim | canliya-cikis | periyodik)
- Backend = {{#if backend}}`{{backend}}`{{else}}`kendi`{{/if}} (kendi | ortak: şema/RLS başka repoda, kiracı `site_key` vb.). Ortaksa K3, Y2 ve alt denetimlerin şema/RLS/migration maddeleri burada ölçülmez, KAL sebebi sayılmaz: Sahip = "backend repo (<ad>)"; burada yalnız kiracı ayrımı ölçülür (her sorguda kiracı filtresi, service-role istemcisi yok).
- {{#if musteri}}Müşteri projesi: commit/push YOK; yalnız rapor + yama önerisi + müşteri özeti.{{else}}Kendi projesi: commit yalnız açık dosya yoluyla, madde başına bir commit.{{/if}}
{{#if standart_dizini}}- "{{standart_dizini}} içindeki index.md'yi oku, ilgili kural tablolarını da uygula."{{/if}}

Sabit kurallar: .env ya da anahtar DEĞERİNİ okuma/yazdırma (yalnız anahtar adı + konum + sızıntı türü; grep'te `-l` kullan) · ölçmediğini "ölçülemedi (neden)" yaz · eşik/sürüm/CVE uydurma · sürüm bilgisini tarihle ver · "bakılmadı" durumu yok: her K/Y satırı geçti / kaldı / ölçülemedi / geçerli değil olarak biter · tablolardaki `\|` markdown kaçışıdır, kabukta `|` yaz.

## Adım 0 — Yığın tespiti
- [ ] Paket yöneticisi: lock dosyası (`package-lock.json` npm · `pnpm-lock.yaml` pnpm · `yarn.lock` yarn · `bun.lock*` bun) → aşağıda `<pm>`
- [ ] `next` sürümü KURULU paketten: `node -p "require('$P/node_modules/next/package.json').version"` (yoksa lock dosyası; `npx next --version` kullanma, kurulu değilse en son sürümü indirip yanlış cevap verir)
- [ ] App Router (`app/` ya da `src/app/`) mı Pages Router mı; istek ara katmanı `middleware.ts` ya da Next 16+ ise `proxy.ts`. Dosya `app/` ile AYNI düzeyde: `src/app` varken kökteki dosya sessizce derlenmez → yalnız ona dayanan koruma = P0 (Y3). Build çıktısında doğrula: `proxy.ts` (yalnız Node) ya da Node'lu `middleware.ts` → 1. komut ≥ 1 (`middleware-manifest.json` boş kalır, kanıt sayma); edge `middleware.ts` (16'da da varsayılan) → 2. komut ≥ 1:
  `grep -c '"/_middleware"' "$P/.next/server/functions-config-manifest.json"` · `node -p "Object.keys(require('$P/.next/server/middleware-manifest.json').middleware).length"`
- [ ] `@supabase/*` paketleri (`@supabase/ssr` var mı), auth yöntemi; barındırma (`vercel.json`, `.vercel/`), i18n, ödeme sağlayıcısı, `test` ve `build` script adları, `supabase/migrations/` ve `supabase/tests/` var mı
- [ ] Uygulanmayan kontrolleri "Geçerli değil" listesine gerekçeyle yaz.

## Adım 1 — Repo ↔ canlı uyumu
| Kontrol | Komut | Eşik |
|---|---|---|
| Dağıtılmamış commit | `git -C "$P" fetch -q; git -C "$P" rev-list --count @{u}..HEAD` (upstream yoksa "ölçülemedi"); commit'lenmemiş değişiklik: `git -C "$P" status --porcelain \| wc -l` | ahead = 0; kirli dosya canlıda sayılmaz |
| Canlı sürüm kimliği | Prod deployment'ın Git SHA'sı (Vercel dashboard → deployment → Source, ya da `vercel inspect <prod-deployment-url>`; uygulama `VERCEL_GIT_COMMIT_SHA`'yı bir sürüm endpoint'inde gösteriyorsa `curl -s U/<endpoint>`) ↔ `git -C "$P" rev-parse origin/<prod-dalı>` | SHA 1:1; SHA bulunamazsa ölçülemedi |
| Canlı gerçeği | Her "yapıldı" iddiasını U üzerinde curl/header/tarayıcı ile ölç | ahead > 0 iken "canlıda" iddiası = 0 |

ahead > 0 ya da SHA farklıysa "canlı ≠ repo" P1 bulgusu aç; canlıda olmayan düzeltmeyi "var" sayma.

## Adım 2 — Üç denetimi PLE ile çek ve uygula
1. `command -v ple` → yoksa Adım 3'e geç, durumu "Ölçülemeyenler"e ve «PLE geri bildirim:» satırına yaz.
2. Sözdizimi (paketin tek biçimi, `ple get --help`): `ple get "<tam başlık>" --var anahtar=değer` — her değişken ayrı `--var`. Her komuta ekle: U varsa `--var canli_url="$U"` · müşteri ise `--var musteri=1` · Backend = ortak ise yalnız güvenlik çağrısına `--var ortak_backend="<backend reposu>"`{{#if standart_dizini}} · `--var standart_dizini="{{standart_dizini}}"`{{/if}}. `duzelt`'i alt denetimlere GEÇİRME; düzeltme Adım 6'da tek elden yapılır. Doldurulmamış değişkeni `ple get` "Unfilled variables" uyarısıyla gösterir; değerini Adım 0'dan ver.

| Sıra | Kod | Komut |
|---|---|---|
| 1 | G | `ple get "Web güvenlik denetimi (Next.js + Supabase)" --var proje_yolu="$P"` |
| 2 | T | `ple get "Web profesyonel temel özellikler" --var proje_yolu="$P" --var urun_turu=<Adım 0>` (ödeme sağlayıcısı bulunduysa `--var satis_var=1`) |
| 3 | S | `ple get "Web SEO denetimi" --var proje_yolu="$P"` |

3. Alt ajan destekleniyorsa üçünü paralel ver: her alt ajana prompt metni + Adım 0/1 çıktısı + Backend değeri + "yalnız rapor, dosya düzenleme yok, commit yok, `next build`/`next dev` başlatma yok". Paralel build aynı `.next`'te çakışır (gözlendi): build'i sen bir kez al (Adım 5), alt ajanlar o çıktıyı ve tek sunucuyu (U ya da senin `<pm> start`'ın) kullanır. Desteklenmiyorsa sırayla G → T → S. Alt raporlardaki geri bildirim satırlarını topla.
4. `ple get` hata verirse ya da prompt bulunamazsa: önce `ple search "Web"` ile başlığı doğrula, başlık çakışıyorsa `--project <repo>` ekle; yine olmazsa hatayı aynen "Ölçülemeyenler"e yaz, o denetim için Adım 3 yedek listesini uygula.
5. Kapı kontrolleri (K): K1-K3 kapıya özeldir, her durumda kendin ölç. K4-K10'un sahibi alt denetimdir: sonucu o maddeden al, kontrolü burada yeniden yazma; alt rapor "ölçülemedi" dediyse ve erişimin varsa sahip maddenin komutuyla kendin ölç.

| ID | Kontrol | Doğrulama | Eşik | Şiddet |
|---|---|---|---|---|
| K1 | Deploy sonrası smoke | `curl -sI` ile `$U/`, /sitemap.xml, /robots.txt, login/checkout/ana akış, favicon, manifest ikonları, og:image (meta'dan alınan URL), font (.woff2); smoke CI/deploy adımında otomatik mi (workflow dosyası) | herkese açık 200; korumalı 3xx/401/403; 5xx = 0; font 200 + `font/woff2`; otomatik değilse P2 | P1 (font P2) |
| K2 | Korumalı API oturumsuz (dağıtım sonrası, tüm route'lar) | Route listesi: `find "$P" -path '*/node_modules' -prune -o -path '*/app/api/*' -name 'route.*' -print`; her korumalı route için `curl -s -o /dev/null -w '%{http_code}' "$U/api/<route>"` | 401/403; 5xx = 0 | P0 |
| K3 | RLS test kanıtı | `supabase start && supabase db reset && supabase test db` (Docker gerekir); anon okuyamaz, başka kiracıyı göremez, rol yükseltemez senaryoları var mı | yeşil; `supabase/tests/` yoksa kaldı; "build yeşil + tip temiz" kanıt sayılmaz | P1 |

| ID | Kontrol | Sahip madde |
|---|---|---|
| K4 | Restore provası | T I2 |
| K5 | İzleme (hata 2/2 + uptime alarmı) | T H1 + H3 |
| K6 | Domain/TLS (bitiş, CAA, transfer kilidi; 4 host varyantı) | T K1-K3 + S C |
| K7 | Search Console mülkü + sitemap | S N |
| K8 | Core Web Vitals saha p75 (lab tek başına karar vermez) | S J |
| K9 | Çerez rızası (onaysız izleme isteği 0) | T F3 |
| K10 | Erişilebilirlik + yurt dışı aktarım (+ AB satışında Erişilebilirlik Yasası) | T D1-D6 + F6 (+ F17) |

## Adım 3 — Yerleşik yedek liste (PLE yoksa ya da prompt bulunamazsa; en çok 15)
Alt rapor yoksa K4-K10'un sonucu da bu listeden gelir.
| # | Kontrol | Doğrulama | Şiddet |
|---|---|---|---|
| Y1 | Sır sızıntısı | `grep -rn "NEXT_PUBLIC_" "$P" --include='*.ts*' --include='*.js*' --include='.env.example' --exclude-dir=node_modules --exclude-dir=.next \| grep -iE "SERVICE_ROLE\|SECRET\|ADMIN"` = 0; geçmiş: `git -C "$P" log --all --format='%h %ad' --name-only -- '.env' '.env.*' ':!*.example'` boş (`-p` KULLANMA, değer basar); varsa `gitleaks detect --redact -s "$P"`; build sonrası `grep -rlE 'sb_secret_\|zZXJ2aWNlX3JvbG\|c2VydmljZV9yb2xl\|NlcnZpY2Vfcm9sZ' "$P/.next/static"` = 0 dosya | P0 |
| Y2 | RLS | `select relname from pg_class where relrowsecurity=false and relnamespace='public'::regnamespace and relkind='r';` = 0 satır (yerelde `supabase db reset` sonrası psql; prod için kullanıcıya SQL Editor'de koşturt) + Supabase Advisors "RLS Disabled in Public" = 0 | P0 |
| Y3 | Sunucu tarafı yetki | Her `'use server'` ve route handler'da authn+authz; authz'de `getSession()` yok (`getUser()`/`getClaims()`); yalnız `middleware.ts`/`proxy.ts`'e güvenen route = 0 | P0 |
| Y4 | Bilinen kritik açık sürüm | Kurulu `next` sürümü (Adım 0): 2026-10-30 tabanı 16.x ≥ 16.4.1 · 15.x ≥ 15.5.28 (2026-10-14 Next.js duyurusu; CVE-2025-29927 ve React2Shell CVE-2025-55182 yamalarını kapsar); güncel danışma: `npm view next version`, GitHub security advisories, `<pm> audit` (npm: `npm audit --omit=dev`); eşik: etkilenen sürüm = 0, critical/high prod bağımlılık = 0 | P0 |
| Y5 | Güvenlik başlıkları | `curl -sI U`: CSP script-src'de unsafe-inline = 0, frame-ancestors var; HSTS max-age ≥ 63072000 | P1 |
| Y6 | Korumalı API | K2 ile aynı | P0 |
| Y7 | Yedek + restore | Otomatik yedek açık (Free'de zamanlanmış `supabase db dump` off-site) + izole projeye geri yükleme kaydı (tarih + sonuç), yılda ≥ 1 | P1 |
| Y8 | İzleme | Kasıtlı test hatası client + server panelde (2/2); harici uptime probe ≤ 5 dk + test alarmı ulaştı | P1 |
| Y9 | Hukuk sayfaları | Gizlilik/aydınlatma, çerez, kullanım koşulları sayfaları `curl -sI` 200 ve footer'dan bağlı (`curl -s U \| grep -ciE 'gizlilik\|privacy'` > 0) | P1 |
| Y10 | robots/noindex | `curl -s U/robots.txt` prod'da `Disallow: /` yok; ana sayfalarda meta robots / X-Robots-Tag noindex yok | P1 |
| Y11 | Sitemap | `U/sitemap.xml` 200 + XML; içindeki örnek 3 URL 200 | P1 |
| Y12 | Canonical | İndekslenen sayfalarda mutlak `rel="canonical"` prod host'una işaret ediyor; `alternates` tanımlamayan sayfa layout'unkini miras alır (sığ birleştirme) → 404/yardımcı sayfa canonical'ı ana sayfa değil | P2 |
| Y13 | 404 durum kodu | `curl -s -o /dev/null -w '%{http_code}' U/olmayan-sayfa-kontrol` = 404 ve dinamik rotada `U/<dinamik-segment>/olmayan-kayit` = 404 (soft 404 = 0). Akış başlayınca durum 200'e sabitlenir: segmentte ya da üstünde `loading.tsx` varsa ya da `notFound()` askıdaki Suspense içindeyse 200 + noindex → kaydı akıştan önce kontrol et, Suspense yalnız yavaş bileşene | P1 |
| Y14 | CWV saha | `curl -s "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$U&strategy=mobile" \| jq '.loadingExperience.metrics'` p75: LCP ≤ 2.5 sn · INP ≤ 200 ms · CLS ≤ 0.1; saha verisi yoksa ölçülemedi | P1 |
| Y15 | Hesap silme | Uygulama içinden hesap + kişisel veri silme yolu var (kodda silme route'u/action'ı) ve test hesabıyla uçtan uca çalışıyor | P1 |

## Adım 4 — Tekilleştir ve tek öncelik listesi kur
- [ ] Aynı kök neden (aynı dosya:satır, aynı URL + başlık ya da aynı kural) → tek satır; "Kaynak denetim" sütununa tüm kaynakları yaz (ör. G-3, T-5, K2).
- [ ] Şiddet = birleşen bulguların en yükseği. Sıra: şiddet → canlıda ölçülen önce → küçük düzeltme önce.
- [ ] Her satır kanıt taşır: Bulgu hücresinde Nerede (dosya:satır/URL) + Ölçülen + Beklenen; Düzeltme hücresinde minimal düzeltme + doğrulama komutu.
- [ ] Ölçek (paket ortak): P0 kritik (canlı veri/hesap/ödeme/sır riski, hemen) · P1 yüksek (teslimden önce) · P2 orta · P3 düşük.
- [ ] Kapı = periyodik ise önceki raporla fark: yeni / kapanan / açık kalan bulgunun yaşı (bulundu tarihinden bugüne gün).

## Adım 5 — Kapı ölçütleri (biri bile sağlanmazsa KAL; ölçülemeyen ölçüt KAL sayılır)
| Ölçüt | GEÇ koşulu | Kanıt |
|---|---|---|
| P0 | P0 sayısı = 0 | birleşik liste |
| P1 | Açık her P1 için sahip + tarih | Sahip sütunu + tarih |
| Test + build | `<pm> test` ve `<pm> run build` exit 0 (test script'i yoksa KAL + P1 bulgu); K3 RLS testleri yeşil (Backend = ortak: K3 backend repoda, KAL sayılmaz) | komut çıktısının son satırları |
| Smoke | K1 + K2 dağıtım sonrası yeşil | curl kod listesi |
| Canlı = repo | ahead = 0 ve SHA 1:1 | Adım 1 çıktısı |

Kapı = canliya-cikis ise K6 ve K7 de kapı ölçütüdür.

Yerel teslim (kapı = teslim, değişiklik dağıtılmadı, yayın kararı bekliyor): Smoke ve Canlı = repo satırına KAL değil `YAYIN BEKLİYOR` yaz; K1/K2'yi build sonrası `<pm> start` (`U=http://localhost:3000`) üzerinde koş, "yerel" etiketle. Diğer ölçütler geçerse karar `GEÇ — yayın bekliyor`; dağıtım sonrası Adım 6 son maddesiyle kesinleşir. canliya-cikis ve periyodik'te istisna yok.

## Adım 6 — Düzeltme ve yeniden ölçüm
{{#if duzelt}}{{#if musteri}}- P0 → P1 sırasıyla minimal yama/dal önerisi yaz (diff + test önerisi); commit/push YAPMA.{{else}}- P0 → P1 sırasıyla minimal diff + test ile düzelt; madde başına bir commit, yalnız açık dosya yolu.{{/if}}{{else}}- Düzeltme yapma; Düzeltme sütunu minimal öneriyi taşır.{{/if}}
- [ ] Her düzeltilen satırın doğrulama komutunu yeniden koş; durum: bulundu → düzeltildi (repo) → canlıda doğrulandı.
- [ ] Dağıtımdan sonra Adım 1 ve K1/K2'yi yeniden ölç; kapı kararını yeniden ver. Canlıda doğrulanmayan düzeltme kapıyı geçirmez.

## Çıktı iskeleti (bu sırayla)
- `## Kapı kararı` — GEÇ / KAL / `GEÇ — yayın bekliyor` + tek cümle gerekçe
- `## Kapı ölçütleri` — | Ölçüt | Durum | Kanıt |
- `## Birleşik öncelik listesi` — | # | Şiddet | Alan | Bulgu | Kaynak denetim | Düzeltme | Sahip |
- `## Temiz bulunanlar` — geçen K/Y ve alt denetim maddeleri (kapsamı gösterir; atlanamaz)
- `## Denetim özetleri` — G, T, S, K için ikişer satır (koşturulan kaynak: PLE ya da yedek liste)
- `## Ölçülemeyenler` — madde · neden · ölçmek için gereken
- `## Geçerli değil` — madde · gerekçe
{{#if musteri}}- `## Müşteri özeti` — en çok 6 satır, teknik olmayan dil; dosya yolu, komut, iç araç adı yok. Rapordaki teknik liste iç kullanım içindir, müşteri özetiyle karıştırma.{{/if}}
- `## Sıradaki 3 adım` — sahip + tarih ile
- `## PLE geri bildirimleri` — alt raporlardan toplanan ve bu turda görülen satırlar

Geri bildirim: Bu prompt bir kontrolü kaçırdıysa, yanlış eşik verdiyse ya da PLE'de bir aksaklık gördüysen tek satır yaz: ple feedback --type prompt --prompt "Web tam denetim ve teslim kapısı" "<ne eksik → ne olmalı>" (PLE aksaklığında --type bug ya da missing; komut yoksa raporun sonuna «PLE geri bildirim:» satırı ekle).

Related prompts