Skip to main content

Ne zaman: eksik özellik taraması; teslim öncesi ya da devralınan web uygulamasında hesap, hukuk, a11y, yedek, izleme · Girdi: {{proje_yolu}} {{canli_url}} {{urun_turu}} {{satis_var}} {{musteri}} {{duzelt}} · Çıktı: tamlık matrisi + ilk 10 eksik · anahtar: KVKK / production readiness, backup

0
Oct 30, 2026
v2

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/54c160a3
183 lines
# Web profesyonel temel özellikler — tamlık denetimi

Rolün: profesyonel bir web ürününde bulunması gereken özellik ve operasyon temelini ölçen denetçi. Her maddeyi kanıtla işaretle: **Var** (dosya:satır ya da komut çıktısı eşiği sağlıyor) · **Kısmen** (var ama eşik/kapsam eksik) · **Yok** · **Ölçülemedi** (neden) · **Geçerli değil** (Adım 0 gerekçesi). Tahminle "Var" yazma.

## Girdiler
| Değişken | Anlam | Bu koşuda |
|---|---|---|
| proje_yolu | Repo kökü (aşağıda `<kök>`) | {{#if proje_yolu}}`{{proje_yolu}}`{{else}}`.`{{/if}} |
| canli_url | Canlı adres (aşağıda `<url>`) | {{#if canli_url}}`{{canli_url}}`{{else}}yok → canlı ölçümler "Ölçülemeyenler"e{{/if}} |
| urun_turu | saas · icerik · eticaret · panel · topluluk | {{#if urun_turu}}{{urun_turu}}{{else}}koddan çıkar (Adım 0){{/if}} |
| satis_var | Ödeme/satış: satış maddeleri (F10-F17) zorunlu | {{#if satis_var}}evet{{else}}verilmedi → Adım 0'da ödeme sağlayıcısı bulunursa F10-F17'yi uygula, yoksa "Geçerli değil"{{/if}} |
| musteri | Müşteri projesi | {{#if musteri}}evet: commit/push YOK; rapor + yama önerisi + müşteri özeti{{else}}iç proje{{/if}} |
| duzelt | Küçük P0/P1 eksikleri tamamla | {{#if duzelt}}evet: minimal diff + test (Adım 3){{else}}yalnız rapor{{/if}} |

{{#if standart_dizini}}"{{standart_dizini}} içindeki index.md'yi oku, ilgili kural tablolarını da uygula."{{/if}}

## Değişmez kurallar
- Her bulgu: ID · Nerede (dosya:satır ya da URL) · Ölçülen · Beklenen/eşik · Şiddet · Düzeltme (minimal) · Doğrulama komutu.
- Şiddet (paket ortak): P0 kritik (canlı veri/hesap/ödeme/sır riski, hemen) · P1 yüksek (teslimden önce) · P2 orta · P3 düşük.
- Ölçmediğini "ölçülemedi (neden)" yaz. Eşik, sürüm, fiyat, kota uydurma; "(doğrulanmadı)" işaretli eşikte güncel resmî kaynağı aç ve tarihini yaz.
- `.env` ve anahtar dosyalarının DEĞERİNİ okuma/yazdırma; yalnız anahtar adı + konum.
- Tablolardaki `\|` markdown kaçışıdır, kabukta `|` yaz.
- Hukuk satırları kontrol listesidir, hukuki danışmanlık değildir; raporda bunu bir kez belirt.
- Sahiplik: başlık/RLS/sır/yetki/girdi doğrulama/hata sızıntısı/webhook imzası/olay runbook'u → «Web güvenlik denetimi (Next.js + Supabase)»; indekslenme, meta/OG/ikon, yapılandırılmış veri, 404 durum kodu, CWV, kırık link → «Web SEO denetimi». "atıf" satırlarını burada ölçme; matriste "Geçerli değil (sahibi: …)" yaz. Çağrı biçimi: `ple get "<tam başlık>" --var proje_yolu=<kök> --var canli_url=<url>`.

## Adım 0 — Yığın ve bağlam tespiti
- [ ] `package.json`: `next` sürümü; `app/` mi `pages/` mi; `@supabase/*` paketleri; auth yöntemi (`@supabase/ssr`, NextAuth, Clerk…).
- [ ] Barındırma: `vercel.json`, `netlify.toml`, `Dockerfile`; i18n (`next-intl`, `i18next`, `[locale]` segmenti); ödeme sağlayıcısı (`grep -rniE "stripe|lemonsqueezy|iyzico|paddle|paytr" package.json src app lib 2>/dev/null`).
- [ ] Ürün türü: {{#if urun_turu}}`{{urun_turu}}` verildi; koddaki kanıtla çelişirse yaz.{{else}}rotalardan çıkar (`/checkout`→eticaret, `/billing`→saas, `/blog`→icerik, `/admin` ağırlıklı→panel, gönderi/yorum→topluluk) ve gerekçesini yaz.{{/if}}
- [ ] Yapıldı ≠ canlıda var: `git -C <kök> fetch -q; git -C <kök> rev-list --count @{u}..HEAD` (upstream yoksa "upstream yok" yaz); >0 ise "repo uzaktan ileride (N commit)". Canlı deployment'ın commit SHA'sını (Vercel panel > Deployments) `git rev-parse --short HEAD` ile karşılaştır; farklıysa "canlı, raporun anlattığı kod DEĞİL" yaz ve canlı ölçümleri ayrı etiketle. {{#if canli_url}}Canlıyı ölç: `curl -sI {{canli_url}}`.{{/if}}
- [ ] Backend sahipliği: teslim kapısı Backend=ortak verdiyse ya da `ls <kök>/supabase/migrations 2>/dev/null` boş ve kod kiracı anahtarıyla (`grep -rn "site_key" src app lib 2>/dev/null`) başka repodaki ortak Supabase projesine bağlanıyorsa backend=ortak: A1/A3'ün proje ayarı kısmı, A9, I1-I4, I6, I7 ve F7 imha işini burada ölçme; matriste "Geçerli değil (sahibi: <backend repo>)" yaz, bulguyu o repoya yönlendir.
- [ ] Yalnız yönetici girişi varsa (ziyaretçi hesabı yok): A5/A6 "Geçerli değil"; ziyaretçi form verisinin erişim/silme talebi F1 metnindeki KVKK m.11 başvuru yoluyla karşılanır.
- [ ] Uygulanmayan alanları "Geçerli değil" bölümüne gerekçesiyle taşı.

Ürün türüne göre ek odak (matrise ekle):
| Tür | Ek maddeler |
|---|---|
| saas | Abonelik durum makinesi, iptal sonrası erişim, plan değişimi, deneme bitişi e-postası |
| icerik | İçerik/görsel lisans kaydı, yayın akışı (taslak → onay → yayın), form talebi sahibine ulaşıyor (L7); OG, RUM, kırık link → SEO denetimi |
| eticaret | Mesafeli satış seti, stok/sipariş transaction, ETBİS, iade akışı |
| panel | Rol/izin ekranı, audit log, liste sayfalama, toplu işlem onayı |
| topluluk | Şikâyet/raporlama, engelleme, moderasyon kuyruğu, kullanıcı içeriği silme |

## Adım 1 — Kontrol listesi (her satır matrise bir satır olur)

**A. Hesap yaşam döngüsü**
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| A1 | Kayıt + e-posta doğrulama | Lokal: `supabase/config.toml` `[auth.email] enable_confirmations = true`; prod: Dashboard > Authentication > Email "Confirm email" ya da Management API `GET /v1/projects/{ref}/config/auth` → `mailer_autoconfirm=false` (token DEĞERİNİ yazdırma); test hesabıyla doğrulamadan giriş dene | Doğrulamasız giriş 0 | P1 |
| A2 | Giriş, çıkış, oturum yenileme | Akışı yürü; çıkıştan sonra `curl -s -o /dev/null -w "%{http_code}"` korumalı sayfa/API | 401 ya da login'e yönlendirme | P1 |
| A3 | Parola sıfırlama | `grep -rn "resetPasswordForEmail"`; link süresi prod `mailer_otp_exp`, lokal `otp_expiry` | ≤3600 sn | P1 |
| A4 | E-posta ve parola değiştirme | `grep -rn "updateUser"`; e-posta değişiminde yeniden doğrulama | — | P2 |
| A5 | Hesap silme (uçtan uca) | Test hesabını sil; PII kolonları + Storage `<bucket>/<userid>/` nesneleri temizlendi mi; finansal kayıt ayrıştırıldı mı | Talep→tamam ≤30 gün | P2 |
| A6 | Veri dışa aktarımı | Kullanıcının kendi verisini indirebildiği uç (JSON/CSV) | — | P2 |
| A7 | Erişilebilir kimlik doğrulama (WCAG 3.3.8) | `grep -rn "onPaste"` (preventDefault); `autocomplete` değerleri `current-password`, `new-password`, `one-time-code`; CAPTCHA varsa bilişsel test gerektirmeyen alternatifi | Engelleme 0 | P1 |
| A8 | Auth olayları sunucuda loglanıyor | Auth yalnız istemcide mi (AuthContext); logger çağrı yerlerini grep'le; başarısız girişi tetikle, log/Sentry'de gör | Çağrılmayan auth logger 0 | P2 |
| A9 | Auth prod ayarı | Management API/Dashboard: `security_captcha_enabled=true` (signup/signin/reset), `smtp_host` dolu (dahili SMTP saatte 2 e-postayla sınırlı — Supabase going-into-prod, 2026-10-30), e-posta link tracking kapalı, test telefon numarası yok | — | P1 |

**B. Durumlar ve hata yüzeyi**
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| B1 | Yükleniyor/boş/hata ayrı | Throttle + boş veri + hata simülasyonu; boş durumda açıklama + CTA, hatada "yeniden dene" | Gösterge >300 ms bekleme (doğrulanmadı) | P3 |
| B2 | Çevrimdışı | Ağı kes; anlamlı mesaj mı, sessiz donma mı | — | P3 |
| B3 | 404/500 sayfası + hata sınırları | App Router: `ls app/{not-found,error,global-error}.* src/app/{not-found,error,global-error}.* 2>/dev/null`, segment `error.tsx` sayısı; Pages Router: `pages/404.*`, `pages/500.*` (404 durum kodu: SEO D) | not-found + global-error var | P2 |
| B4 | Hata sızıntısı | atıf: güvenlik 9.1 | — | — |
| B5 | Tek hata şeması + doğru kod | Route'lar `{ error: { code, message } }`; oturumsuz → 401, yetkisiz → 403, geçersiz girdi → 400, olmayan kaynak → 404 (her biri ayrı curl); tahmin edilebilir id'de bilinçli 404 | 401/403 karışıklığı 0 | P2 |
| B6 | Kritik hata kalıcı | Ödeme/silme hatası otomatik kapanan toast değil; bu akışlarda `useOptimistic` 0 | 0 | P1 |
| B7 | Başarı semantiği | Yazan endpoint'i çağır, ardından DB'de beklenen satırı sorgula; yeni kaynakta 201 + id, gövdesizde 204 | 200 dönüp yan etkisiz endpoint 0 | P1 |

**C. Formlar** — C1 sunucu doğrulaması: atıf güvenlik 5.1 · C2 alan düzeyinde anlaşılır hata, `aria-describedby` bağlı (P2) · C3 her input'un görünür `<label>`ı (P2) · C4 çok adımlı formda tekrar giriş yok, WCAG 3.3.7 (P2) · C5 gönderimde çift tıklama kilidi (P2).

**D. Erişilebilirlik — WCAG 2.2 AA hızlı kontroller**
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| D1 | Otomatik tarama | `npx @axe-core/cli <url> --tags wcag2a,wcag2aa,wcag21a,wcag21aa,wcag22aa --load-delay 2000 --exit` ya da `npx pa11y <url>` ana 5 sayfa. WCAG 2.2 kuralları (target-size) axe'ta varsayılan kapalı: `wcag22aa` etiketsiz koşu D5'i ölçmez; etiket listesi best-practice kurallarını dışarıda bırakır. Animasyon/geçiş bitmeden ölçülen color-contrast yalancı pozitif olabilir → ≥2 sn bekle ya da Playwright `emulateMedia({ reducedMotion: 'reduce' })` (site `prefers-reduced-motion`'a uyuyorsa) | Critical/serious 0 | P1 |
| D2 | Klavye + görünür odak | Tab ile tüm akış; `grep -rnE "outline-none"` ve `"outline: ?none"` eşleşmelerinin yanında `focus-visible` var mı | Tuzak 0 | P1 |
| D3 | Kontrast | axe sonucu + elle örnek | Metin 4.5:1, büyük metin/UI 3:1 | P2 |
| D4 | Alt metin, `html lang` | `alt`sız `<img`/`<Image` grep'i; `<html lang=` | Eksik 0 | P2 |
| D5 | Hedef boyutu (2.5.8) | Küçük ikon butonlarını ölç | ≥24×24 CSS px | P2 |
| D6 | Sürükleme alternatifi (2.5.7), tutarlı yardım (3.2.6) | `draggable`, `dnd-kit`, `onDrag` grep'i → buton alternatifi; yardım linki sırası sayfalar arası aynı. 4.1.1 Parsing 2.2'de kaldırıldı, ihlal yazma | 0 | P2 |

**E. Performans ve mobil**
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| E1 | Core Web Vitals + RUM | atıf: SEO J (saha/lab) ve N (RUM) | — | — |
| E2 | Route başına JS bütçesi | `next build` çıktısında First Load JS sütunu varsa onu, yoksa (Next 16 çıktısında olmayabilir — doğrulanmadı) `@next/bundle-analyzer` ya da `npx next --help`'te listelenen analiz komutu; kapalı/flag'li route dinamik import | Bütçe yazılı mı (sayı yoksa "tanımsız") | P3 |
| E3 | ISR tutarlılığı | ISR/statik sayfada `new Date()`/`Math.random()` render'da yok (görsel boyutu: SEO J) | Eksik 0 | P3 |
| E4 | Duyarlı | 320 px viewport'ta konsol: `document.documentElement.scrollWidth > innerWidth` false (WCAG 1.4.10); viewport meta | Yatay kaydırma 0 | P2 |
| E5 | Büyük liste | .map ile 500+ DOM öğesi (önce `content-visibility:auto`, sonra virtualize); liste API'sini limit'siz ve `limit=100000` ile çağır, dönen kayıt sayısını yaz (doğrulanmadı: varsayılan ≤50, maks ≤200) | Sınırsız sorgu 0 | P2 |
| E6 | Video | `curl -sI <video-url>` Content-Type `video/mp4` ya da `video/webm`; `<video>`'da gerçek .mp4 (H.264) + .webm `<source>`; tek .mov yok; Safari + Chromium'da oynar; büyük video Storage yerine stream/embed sağlayıcıda (doğrulanmadı) | Oynamayan tarayıcı 0 | P2 |

**F. Hukuk (Türkiye)** — kontrol listesi, hukuki danışmanlık değildir.
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| F1 | KVKK aydınlatma metni | Her veri toplama noktasından (kayıt, form) bağlantı | — | P1 |
| F2 | Açık rıza ayrı | Aydınlatma dışı amaçlar (ticari ileti vb.) ayrı, önceden işaretsiz kutu | — | P1 |
| F3 | Çerez bandı + onaya bağlı analitik | "Reddet" "Kabul et" ile aynı katmanda, eşit tık sayısında; ön tarama `curl -s <url> \| grep -cE 'googletagmanager.com/gtag/js\|connect.facebook.net'` (> 0 → aday); kesin ölçüm: gizli pencerede onaysız ve "Reddet" sonrası Network'te analitik/pazarlama isteği | Onaysız izleme isteği 0; tarayıcı yoksa ölçülemedi | P1 |
| F4 | Gizlilik politikası + kullanım şartları | Footer bağlantıları, güncellenme tarihi | — | P2 |
| F5 | İletişim/künye | Satış yapan sitede unvan, MERSİS/vergi no, adres, e-posta, telefon (6563 s. Kanun m.3); tek kanal DM yetmez | — | P2 |
| F6 | Yurt dışı aktarım | Yurt dışı servis envanteri (barındırma, DB, e-posta, izleme); standart sözleşme imza tarihi → Kurum bildirimi | ≤5 iş günü | P1 |
| F7 | Saklama süreleri | Form/auth/log verisi için süre tanımlı + imha işi (cron) | Periyodik imha var | P2 |
| F8 | Çerez rehberi güncelliği | KVKK Çerez Rehberi 28.07.2025 sürümüne göre band metni (doğrulanmadı — güncel PDF'i oku) | — | P2 |
| F9 | VERBİS | Muafiyet otomatik varsayılmaz; çalışan sayısı + bilanço eşiği kvkk.gov.tr'den tarihle teyit (doğrulanmadı: 2023 eşiği 100 milyon TL) | Teyit tarihi yazılı | P3 |

Satış/ödeme maddeleri ({{#if satis_var}}satış var: hepsi zorunlu{{else}}yalnız ödeme/satış tespit edildiyse; yoksa F10-F17 "Geçerli değil"{{/if}}):
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| F10 | Ön bilgilendirme + mesafeli satış sözleşmesi | Checkout'u yürü: linkler + onay kutusu; işaretsiz ödemeye geçilemez | Geçiş 0 | P1 |
| F11 | Yönetmelik değişikliği | RG 24.05.2025/32909 (yürürlük 2026-01-01) m.5 bentleri ve cayma istisnaları metne işlendi mi (doğrulanmadı — Resmî Gazete'den teyit et) | — | P1 |
| F12 | İade/iptal + fatura | İade/iptal sayfası; fatura kesim akışı ve kullanıcıya iletimi tanımlı | — | P1 |
| F13 | ETBİS | Kendi sitesinden satışta kayıt belgesi; bilgi değişince bildirim (doğrulanmadı: 30 gün) | — | P2 |
| F14 | POST idempotensi | Ödeme/para/stok POST'u `Idempotency-Key` kabul eder; aynı key ile iki kez POST → DB'de tek kayıt (webhook imza + event id: güvenlik 8.1-8.3) | Çift işleme 0 | P0 |
| F15 | Abonelik/sipariş durumu | Status kolonu CHECK/enum ile sağlayıcının durum kümesine sınırlı (geçersiz değer INSERT'i hata verir); iptalde erişim `now() > ends_at` ile kesilir, `status='cancelled'` tek başına değil | Erken kesme 0 | P1 |
| F16 | Para/stok yazımı | ≥2 yazma tek transaction/lock; eşzamanlı iki istek probe'u; finansal kayıt hard delete yok (`deleted_at` ya da append-only) | Negatif bakiye 0 | P1 |
| F17 | AB Erişilebilirlik Yasası (AB tüketicisine satış varsa) | 28 Haziran 2025'ten beri; WCAG AA (D) + erişilebilirlik beyanı `curl -sI <url>/accessibility` ya da `/erisilebilirlik` 200; hizmet sunan mikroişletme istisnası (doğrulanmadı — güncel kaynağı kontrol et) | Beyan sayfası 200 | P2 |

**G. İşlem e-postası teslimi** — gönderen alan adını (From) bul, sonra: `dig +short TXT <alan>` içinde `v=spf1` (SPF) · `dig +short TXT <selector>._domainkey.<alan>` (DKIM; selector e-posta sağlayıcısının DNS ayar ekranında) · `dig +short TXT _dmarc.<alan>` (DMARC, en az `p=none`) · gönderen kendi alan adı, From hizalı · Supabase Auth custom SMTP (A9) · pazarlama/toplu e-postada `List-Unsubscribe` + `List-Unsubscribe-Post: List-Unsubscribe=One-Click` (RFC 8058) ve görünür çıkış linki (gönderilmiş bir mailin ham başlığında grep). Eşik (Google gönderen kuralları, 2026-10-30): tüm gönderenlere SPF ya da DKIM; Gmail'e >5000/gün gönderende SPF + DKIM + DMARC + hizalama + tek tık çıkış; spam oranı <%0,1, asla ≥%0,3 (Postmaster Tools). Eksik SPF/DKIM = P1, DMARC yok = P1, çıkış başlığı yok (toplu) = P1.

**H. İzleme ve log**
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| H1 | Hata izleme client + server | Sentry init: `instrumentation.ts`, `sentry.*.config`, error boundary; test hatası panelde | 2/2 | P1 |
| H2 | Kaynak haritası yükleme | `withSentryConfig` sourcemaps yükleme; CI'da auth anahtarı ADI var mı (değer okunmaz); PII temizliği: güvenlik 9.5 | — | P2 |
| H3 | Uptime + alarm kanalı | Harici monitör kaydı, aralık; test alarmı okunan bir kanala düşüyor mu | ≤5 dk | P1 |
| H4 | Yapılandırılmış log | JSON log (seviye, zaman, request id); log'da PII/sır: güvenlik 9.4 | — | P2 |

**I. Veri, yedek, ortam**
| ID | Madde | Nasıl ölç | Eşik | Ş |
|---|---|---|---|---|
| I1 | Yedek planı yazılı | Supabase plan + Backups sekmesinde son yedek tarihi; Free'de otomatik yedek yok → `supabase db dump` cron/Action ile off-site; Pro günlük yedek 7 gün (2026-08 notu; güncel sayfadan teyit et) | Yazılı plan + son yedek ≤1 gün | P0 |
| I2 | Geri yükleme provası | Dump'ı izole projeye geri yükle, tarihli kayıt | ≥yılda 1 | P0 |
| I3 | PITR kararı | Ödeme/kritik veri ya da DB >4 GB ise PITR açık/kararı kayıtlı | — | P1 |
| I4 | Prod Free planda değil | Free'de pasiflikte proje duraklar, yedek indirilemez | Müşteri prod'u Free 0 | P1 |
| I5 | Ortam ayrımı | `vercel env ls` (yalnız adlar): `NEXT_PUBLIC_SUPABASE_URL` Production ve Preview için ayrı satır mı; preview ve canlı sayfanın Network'ünde Supabase host'u (public ref) farklı mı | Ortak prod verisi 0 | P1 |
| I6 | Supabase org | Hesapta MFA, owner ≥2, SSL Enforcement, Network Restrictions | owner ≥2 | P1 |
| I7 | İndeks/N+1 | RLS'te ve filtrede kullanılan kolon indeksli: Dashboard > Advisors > Performance ya da `npx supabase inspect db --help`'teki seq-scans/index komutları (`--linked`); SQL Editor'de `EXPLAIN ANALYZE` Seq Scan + >1.000 satır; liste isteği başına ek sorgu O(1) (≤3) | — | P2 |
| I8 | Kimlik taşıma | userid değiştiren onarım/taşımada `select name from storage.objects where name like '<eski-userid>/%'` | Eski prefix'te nesne 0 | P1 |

**J. Teslim hattı** — J1 CI kapıları: PR'da lint + typecheck + test + build (`ls .github/workflows`; yoksa P1) · J2 dağıtım sonrası smoke testi: ana rotalar 200, korumalı API oturumsuz 401, kritik API gerçekten yazıyor (DB satırını sorgula) (yoksa P1) · J3 geri alma yolu yazılı (önceki deploy'a dönüş komutu) (P2) · J4 bildirilmemiş (geçişli) bağımlılık: koddaki her import `package.json`'da; `npx knip --include unlisted` (unlisted 0), şüphelide `npm ls <paket>` (pnpm: `pnpm why <paket>`) yalnız başka paketin altında görünüyorsa bildirilmemiş (P2).

**K. Altyapı sürekliliği** — K1 TLS: `echo | openssl s_client -connect <alan>:443 -servername <alan> 2>/dev/null | openssl x509 -noout -dates`; bitişe 21-30 gün kala bağımsız alarm; CA/B azami sertifika ömrü 2026-03-15'ten 200, 2027-03-15'ten 100, 2029-03-15'ten 47 gün — yenileme otomasyonu şart (P1) · K2 `dig CAA <alan>` sağlayıcıyı (ör. Let's Encrypt) engellemiyor (P1) · K3 `whois <alan> | grep -i status` (ya da rdap): `clientTransferProhibited` + auto-renew; .tr alanlarında alan farklıysa "ölçülemedi" yaz; domain bitişi ve ödeme kartı son kullanma registrar hatırlatmasından önce ayrı takvimde (P1) · K4 harcama sınırı: Supabase Spend Cap (Pro'da varsayılan açık, aşımda kısıtlar) ve Vercel Spend Management (varsayılan yalnız uyarır) bilinçli seçili, uyarı eşikleri tanımlı (P2) · K5 kota kalemleri (bandwidth, invocation, image optimization, egress, MAU) Usage panelinden izleniyor; sayıları güncel fiyat sayfasından teyit et (P3).

**L. Ürün cilası ve işletme**
| ID | Madde | Nasıl ölç | Ş |
|---|---|---|---|
| L1 | Favicon, manifest, OG görseli | atıf: SEO I | — |
| L2 | i18n hazırlığı | Sabit metinler sözlükte mi; tarih/para `Intl` ile; `lang` dinamik | P3 |
| L3 | Destek kanalı + durum bildirimi | İletişim formundan test mesajı ulaşıyor mu (sahibin görmesi: L7); kesinti için durum sayfası/banner | P2 |
| L4 | Yönetim/operasyon araçları | Kullanıcı arama, devre dışı bırakma, rol değişimi, kritik işlem audit log'u | P2 |
| L5 | Dokümantasyon | README (kurulum, komutlar, env ADLARI), HARITA (mimari/dosya haritası), devir notu | P2 |
| L6 | Kırık link | atıf: SEO N | — |
| L7 | Form talebini sahibi görüyor | Her form (iletişim/randevu/teklif) için yazma yolu + okuma yolu: admin listesinde aynı tablonun `.select(`'i ya da sahibine bildirim e-postası; test gönderimini sahibin ekranında/kutusunda gör (backend=ortak ise admin listesi backend reposunda olabilir, orada ara). Yalnız yazma yolu varsa P1 | P1 |

L7 ön tarama: yazma `grep -rnE "\.(insert|upsert|rpc)\(" src app lib 2>/dev/null` · bildirim `grep -rniE "resend|nodemailer|sendmail|postmark|sendgrid" src app lib 2>/dev/null`.

**M. Olay müdahale** — M1 runbook, sınırlama komutları, anahtar rotasyonu, olay kaydı damgaları: atıf güvenlik Adım 12 · M2 kişisel veri ihlalinde Kurul bildirimi tespitten ≤72 saat (KVKK m.12/5, ihlalbildirim.kvkk.gov.tr; AB kullanıcısı varsa GDPR m.33) ve ilgili kişilere "en kısa sürede" bildirim akışı yazılı (akış yazılı değilse P1; süren ihlalde süre aşımı P0) · M3 post-mortem suçsuz ve her bulguyu yeni teste bağlar; açık bulgunun yaşı raporlanıyor (P2).

## Adım 2 — Sıralama
- Her Yok/Kısmen için etki (3 yüksek · 2 orta · 1 düşük) ve efor (S ≤1 saat · M ≤1 gün · L >1 gün) ver.
- Sıra: önce şiddet (P0→P3), eşitte etki/efor oranı büyük olan. İlk 10'u "İlk 10 eksik"e taşı.

## Adım 3 — Düzeltme
{{#if duzelt}}{{#if musteri}}Kod değiştirme; her P0/P1 için ayrı dal adı + yama (diff) öner, commit/push YOK.{{else}}Yalnız S eforlu P0/P1 eksikleri minimal diff ile tamamla (ör. not-found sayfası, `lang`, label, sourcemap ayarı, CAA kaydı önerisi); her değişikliğe test ya da doğrulama komutu ekle, testleri koş, yalnız açık dosya yollarını stage et. M/L eforluları yalnız raporla.{{/if}}{{else}}Kod değiştirme; yalnız raporla.{{/if}}

## Çıktı (bu sırayla)
## Verdikt
Tek cümle + GEÇ/KAL. KAL: açık P0 varsa ya da sahibi ve tarihi yazılı olmayan açık P1 varsa (paket ortak kural). Yanına P0/P1 sayısı ve tamlık yüzdesi (Var ÷ Geçerli değil hariç madde) yaz.
## Bulgular
**Tamlık matrisi** — | Alan (A–M) | Var | Kısmen | Yok | Ölçülemedi | Geçerli değil |
**Eksikler (şiddet sıralı)** — her Yok/Kısmen bir satır: | ID | Alan | Nerede | Ölçülen | Beklenen/eşik | Şiddet | Düzeltme | Doğrulama | Etki/efor |. İlk 10 satır "İlk 10 eksik"tir; kalınla işaretle.
## Temiz bulunanlar
"Var" işaretli maddeler ve kanıtı (atlanamaz; kapsamı gösterir).
## Ölçülemeyenler
Madde · neden (erişim yok, canlı adres yok, panel gerekli) · kimin bakması gerektiği.
## Geçerli değil
Madde · gerekçe (Adım 0 tespiti).
## Sıradaki 3 adım
{{#if musteri}}
## Müşteri özeti
Teknik olmayan dille en çok 6 satır: ne durumda, en büyük 3 risk, önerilen sıra.
{{/if}}

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 profesyonel temel özellikler" "<ne eksik → ne olmalı>" (PLE aksaklığında --type bug ya da missing; komut yoksa raporun sonuna «PLE geri bildirim:» satırı ekle).

Related prompts