M.AIM.AISoloLabsAtlas — AI Dünyası

Prod'da Hayatta Kalma: Altyapı Vakaları — Atlas

KAZANIM Bu dersin sonunda: hata vermeden yaşayan yedi üretim belasını — açık kapı (RLS), şişen DB faturası, "yeşil ama yanlış" deploy, katmanlı CI kırığı, bot trafiğinin yaktığı fatura, yanlış eve giden deploy ve iki-şüphelili zaman aşımı — kendi ürünlerinde teşhis edip güvenle kapatabilirsin.

Bu dosyanın rolü: DERİNLİK + VAKA DEFTERİ — bu programı yazan stüdyonun KENDİ üretim altyapısında Mayıs–Ağustos 2026'da yaşanan yedi gerçek olay (dogfood: uydurma senaryo değil, faturası ve riski gerçek). Beceri kası çekirdekte: kök neden 2.4, index/fatura temeli 2.8, aylık tarama sessiz-tuzaklar.

📅 Son güncelleme: 4 Eylül 2026 (Vaka 5-6-7 eklendi). Bu modül vaka defteri protokolüyle büyür: her yeni prod vakası buraya bir bölüm olarak eklenir.


Vaka 1 · Sessiz güvenlik deliği: Row-Level Security

⚠ GERÇEK VAKA — Senaryo. Bir Next.js + Supabase ürününde her şey yolunda görünüyordu: kayıtlar akıyor, panel çalışıyor, tek bir hata yok. Gerçek durum: 31 public tablonun HEPSİNDE Row-Level Security (RLS) kapalıydı — kullanıcılar, şirketler, başvurular, denetim kayıtları dahil. Anlamı: sitenin herkese açık anon anahtarını (NEXT_PUBLIC_SUPABASE_ANON_KEY — adı üstünde, tarayıcıya giden PUBLIC bir değer) bilen HERKES, Supabase'in otomatik API'si üzerinden bu tabloları okuyabilir, düzenleyebilir, silebilirdi. Ve en acısı: Supabase'in kendi Security Advisor paneli 3 hafta boyunca "rls_disabled_in_public" diye uyardı — kimse bakmadı.

RLS nedir? Row-Level Security = tablonun kapısındaki görevli: "bu satırı KİM görebilir/değiştirebilir" kuralı. Kritik gerçek: Supabase'te (ve çoğu bulut Postgres'inde) RLS varsayılan KAPALI gelir. Tablo oluşturursun, uygulama çalışır, hiçbir uyarı seni durdurmaz — kapı ardına kadar açıktır. "Çalışıyor" ile "güvenli" arasındaki fark tam burasıdır.

Teşhis — RLS'siz tabloları tek sorguyla bul:

SELECT c.relname AS tablo
FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relkind = 'r' AND NOT c.relrowsecurity;

Çözüm — ama önce TEYİT (bu vakanın asıl dersi: güvenlik düğmesine panik içinde basılmaz, uygulamayı kırmadan basılır). İki soru soruldu:

  1. Client tarafında anon anahtarla DOĞRUDAN tablo sorgusu var mı? → Kod tarandı: yoktu. Bileşenler server action kullanıyor; anon anahtar yalnız Supabase Auth (giriş) için. RLS açılınca kırılacak client sorgusu yok.
  2. Sunucunun DB bağlantısı hangi rolle?
SELECT rolname, rolbypassrls FROM pg_roles WHERE rolname = current_user;
-- postgres | t   ← owner rolü RLS'i BYPASS eder

Sunucu postgres (owner, rolbypassrls = TRUE) ile bağlanıyor → RLS açılsa da sunucu erişimi etkilenmez. İki teyit alınınca fix tek satır × 31:

ALTER TABLE "User" ENABLE ROW LEVEL SECURITY;  -- (31 tablonun her birine)

Sonuç: sunucu (Prisma/postgres) erişimi aynen sürdü, anon/authenticated rolleri bloklandı. Politika (policy) yazmak GEREKMEDİ — çünkü mimari server-only: RLS açık + hiç policy yok = "kimse giremez" (deny-all), server-only mimaride tam istenen budur. Policy ancak client'ın anon anahtarla doğrudan tablo sorguladığı mimaride gerekir ("kullanıcı yalnız kendi satırını görsün" kuralı gibi).

Kalıcı ders: Rol haritasını ezberle — anon (tarayıcıdaki herkes) · authenticated (giriş yapmış kullanıcı) · service_role/owner (sunucu; RLS'i bypass eder). Yeni Supabase projesinde İLK İŞ: tüm tablolara RLS aç (server-only ise politikasız yeter). Ve panel uyarılarını okuyan biri olsun — Security Advisor 3 hafta bağırdı, duyulmadı.

⚡ Hızlı sınav 1: (a) RLS açıkken hiç policy yazmamak neden bazen tam doğru karardır? (b) NEXT_PUBLIC_ önekli bir değer neden asla sır sayılamaz? (c) RLS'i açmadan önce sorulan iki teyit sorusu neydi?

Vaka 2 · Serverless DB faturası neden şişer: awake-time + egress

⚠ GERÇEK VAKA — Senaryo. Kullanım-bazlı serverless Postgres (Neon) faturası bir ayda $31 → $141. Kırılım okununca iki kalem çıktı: Compute $93 (879 CU-saat) + Public network transfer $311 (3,1 TB dışa veri!*). Uygulamalar çalışıyordu, kullanıcılar mutluydu — para sessizce akıyordu. (*Krediler düşünce net $141.)

Faturalama modelini oku: serverless DB'de iki sayaç döner: compute = motor gücü (CU) × uyanık-saat, ve egress = DB'den dışarı çıkan veri (GB). Yani fatura = ne kadar güçlü × ne kadar süre uyanık + ne kadar veri taşıdın. İkisi de belirtisiz şişer.

Teşhis (iki kök-neden çıktı):

(a) Egress canavarı = eksik FK index'leri. Ders 2.8'in vakasının ta kendisi: pg_stat_user_tables okundu, bir üründe 68 bin satırlık tablodan 42 milyar satır okunmuş (149 GB transfer). ORM'ler (TypeORM @ManyToOne, Prisma ilişkileri) FK kolonuna otomatik index KOYMAZ; her katalog sorgusu tabloyu baştan sona tarayıp sonucu ağa döküyordu. 3,1 TB'lik egress'in asıl kaynağı buydu.

(b) Awake-time: DB hiç uyumuyordu. Serverless'ın bütün ekonomisi "boşken uyu" (scale-to-zero) üstüne kuruludur — ve 5 dakikadan sık gelen HER istek otomatik uykuyu engeller. Suçlular sıradan şeylerdi: Vercel URL'ini <5 dakikada bir dürten harici uptime monitörü + 7/24 açık bir Railway backend'inin kalıcı DB bağlantısı. Sonuç: DB'ler %92-95 uyanık — "kullanmadığın sürede ödemezsin" modeli, farkında olmadan "hep kullanıyorsun" moduna çevrilmişti. İroni: siteyi izleyen bekçi, faturayı şişiren hırsız çıktı.

Çözüm (üç katman, doğru sırayla):

  1. Asıl tedavi — index'ler: eksik FK index'leri prod'a + ORM şemasına + migration'a (2.8 akışı). Egress 149 GB → ~sıfır.
  2. Sigorta — CU tavanı 8 → 1: autoscaling'in tepesini sınırlar; fatura ∝ CU olduğundan en hızlı fren. AMA dikkat: tavan, awake-time'ı DÜŞÜRMEZ — motor küçülür, çalışma süresi aynı kalır. Pansuman, ameliyat değil.
  3. Awake-time tedavisi: harici monitörü ≥15 dk'ya seyrelt (ya da DB'ye dokunmayan statik /api/ping'e yönlendir — içinde SELECT 1 bile olmasın); */5 cron YASAK (zorunluysa ≥*/15); 7/24 backend'de idle-timeout düşün.

Kalıcı ders: Kullanım-bazlı fatura üç soruyla okunur: motor kaç CU? · kaç saat uyanık? · dışarı kaç GB çıktı? Warmup/monitör/cron gibi "iyilik" araçları scale-to-zero'yu öldürerek faturayı şişirebilir — cold-start konforu ile maliyet bir DENGE kararıdır, varsayılan değil. Ve harcama alarmı kur: bu vakada tek belirti ay sonu faturasıydı.

⚡ Hızlı sınav 2: (a) CU tavanını kısmak neden tek başına yetmez — hangi sayacı düşürmez? (b) Uptime monitörü faturayı hangi mekanizmayla şişirir? (c) Egress kalemi şişmişse ilk bakacağın Postgres görünümü hangisi?

Vaka 3 · Kod çalışıyordu — YANLIŞ çalışıyordu: sessiz başarısızlık

⚠ GERÇEK VAKA — Senaryo (üç olay, tek desen). Aynı hafta, üç ayrı sistemde: (1) Neon: deploy yeşil, uygulama sorunsuz — fatura sessizce 4,5 katına çıkıyor. (2) Supabase: uygulama kusursuz çalışıyor — veri 3 haftadır herkese açık. (3) Vercel: deploy ekranı "Ready ✓" diyor — ama pnpm-workspace.yaml'daki bir yer-tutucu hatası yüzünden build gerçekte native modülleri derlemiyor ve canlıda ESKİ sürüm kalıyor; üç dağıtım, kimse fark etmeden "kayboldu".

Bu üçünün ortak adı: sessiz başarısızlık — çöken değil, yanlış çalışan sistem. Çökme merhametlidir: seni arar, kırmızı ekran gösterir. Sessiz başarısızlık aranmayı bekler; bulana kadar da para, veri ya da itibar sızdırır. Yazılımdaki en pahalı hata sınıfı budur ve hiçbir hata mesajı yoktur.

Teşhis — üç olayın da tek panzehiri: beyanı değil ÖLÇÜYÜ oku.

Beyan ("yeşil") Ölçü (gerçek)
Deploy başarılı, uygulama çalışıyor Fatura kırılımı: compute-saat + egress GB trafiğinle orantılı mı?
Uygulama sorunsuz, hata yok pg_class.relrowsecurity sorgusu + Security Advisor paneli ne diyor?
Vercel "Ready ✓" Canlıda az önce yaptığın değişiklik GÖRÜNÜYOR mu? (curl -s site.com | grep "yeni-metin")

Üçüncü satır bu programın demir kuralının altyapı hâli: beyan kanıt değildir (1.5). "Deploy Ready" bir beyandır; kanıt, canlıda değişikliği kendi gözünle görmektir. Aynı ilke stüdyonun başka bir ürün denetiminde şöyle mühürlenmişti: "ölçmeden 'çalışıyor' deme."

Çözüm — sessiz başarısızlığa karşı üç alışkanlık:

  1. Her "çalışıyor"a bir ölçü bağla: deploy → canlıda sürüm/değişiklik kontrolü; güvenlik → aylık RLS/secret taraması; maliyet → harcama alarmı + fatura kırılımı okuma. (sessiz-tuzaklar kartı tam bu ritüel içindir — bu modülün üç vakası o kartın 1, 3 ve 7. satırlarının gerçek hayattaki hâlidir.)
  2. Panel uyarılarını gelen kutusu say: Security Advisor, spend alert, "failed deployment" maili — üçü de bu hafta bağırıyordu; sinyal vardı, dinleyen yoktu. Gözlemlenebilirlik (observability) araç sorunu değil, bakma alışkanlığı sorunudur.
  3. Varsayım avcılığı: "ORM index'i halleder" · "monitör zararsızdır" · "Ready = canlıda" — üç vakanın üçü de doğrulanmamış bir varsayımdan doğdu. Varsayımını yakala, ölçüyle sına.

⚡ Hızlı sınav 3: (a) Sessiz başarısızlık neden çökmeden daha pahalıdır? (b) "Deploy Ready ✓" hangi soruyla kanıta dönüşür? (c) Bu haftaki üç vakanın ortak kök-varsayımı neydi?

Vaka 4 · Soğan gibi CI: katmanlı hata ve sahte kırmızı

Tek cümlede: bir CI hatasını düzelttiğinde işin bitmez — çoğu zaman altındaki bir sonraki hatayı açığa çıkarmışsındır.

⚠ GERÇEK VAKA — Senaryo. Sabah bir üründen "CI failed" maili düştü. Görünürdeki hata basitti; ama düzeltilince altından İKİNCİ bir kırık çıktı, o düzeltilince ÜÇÜNCÜ. Üç ayrı hata, soğan katmanları gibi üst üste binmişti — ve en üstteki, alttaki ikisini haftalarca gizlemişti:

Katman 1 — sürüm çakışması (yüzey): 8 GitHub Actions workflow'unda pnpm kurulum adımı version: 10 diyordu; package.json ise packageManager: pnpm@9.15.9. CI daha kurulum aşamasında, 18. saniyede "Multiple versions of pnpm specified" ile çöküyordu. Kritik sonuç: testler HİÇ ÇALIŞMIYORDU — kırmızıydı ama "altyapı takıldı" gibi görünüyordu.

Katman 2 — bağımlılık kırığı: pnpm düzelince testler haftalar sonra İLK KEZ koştu ve bir servisin 6 testi birden düştü: servise zamanla iki yeni bağımlılık (bildirim + e-posta servisleri) eklenmiş, ama test kurulumu bunları taklit (mock) etmemişti — "can't resolve dependencies ... at index [3]". Tüm takımın birden düşmesi ipucuydu: bu tek tek iddia (assertion) hatası değil, KURULUM hatasıdır.

Katman 3 — bayat test: Ardından tek bir test düştü. Kod, bilinçli bir kararla davranışını DEĞİŞTİRMİŞTİ (push bildirimi reddedilse bile alarm e-posta yedeğiyle kurulacak); test hâlâ ESKİ sözleşmeyi bekliyordu. Yani kod doğruydu, test eskimişti — hangisinin haklı olduğuna koddaki niyet/açıklama okunarak karar verildi, test körlemesine "yeşile boyanmadı".

Teşhis — üç katmanın üçü de SİNYALİNDEN tanınır:

  • CI 18 saniyede öldü → testler hiç koşmamıştır. Süre bir teşhis aracıdır: normalde 4 dakika süren işin 18 saniyede bitmesi, "hata var"dan önce "hiçbir şey çalışmadı" demektir.
  • Bir takımın TÜM testleri birden düştü → kurulum/bağımlılık hatası (tek testin düşmesi mantık hatasına, hepsinin düşmesi zemine işaret eder).
  • Tek test düştü + kodda bilinçli değişiklik izi var → bayat test şüphesi (documentation drift): hakem, koddaki NİYETTİR — testi mi kod mu güncel, onu yorum/karar kaydı söyler.

Çözüm — üç katman, üç mikro-PR: her düzeltme ayrı küçük PR olarak gitti; her biri önce LOKALDE koşulup yeşil GÖRÜLDÜ, sonra ana dal CI'ı uçtan uca izlendi. Son durum: Lint & Test + Build + Docker hepsi yeşil — ve bu kez yeşil, gerçekten koşmuş testlerin yeşili.

Kalıcı ders (soğan kuralı + iki ek):

  1. "Bir CI hatasını düzelttiğinde işin bitmez — bir sonrakini açığa çıkarmışsındır." Yeşile ulaşana VE doğrulayana kadar ipi çekmeye devam et; "kırmızı = tek sorun" varsayma.
  2. Yeşil de kırmızı da yalan söyleyebilir: erken çöken CI testleri hiç koşturmadığı için aylarca "sahte güven" (ya da sahte panik) üretir — Vaka 3'teki sessiz-başarısızlık ailesinin CI üyesi budur. CI güvenlik ağıdır, AMA yalnız gerçekten koştuğunda.
  3. Test-kod çelişkisi her zaman kod hatası değildir: bilinçli davranış değişikliği eski testi "yanlış" çıkarır. Düşünmeden testi yeşile boyamak, yarın GERÇEK bir gerilemeyi gizler. AI-hızında geliştirmede bu üç kırık türü (sürüm pinleri, bağımlılık kayması, sözleşme kayması) özellikle hızlı birikir — mikro-PR + kapı disiplini (2.3) panzehirdir.

⚡ Hızlı sınav 4 (cevap anahtarlı):

  • (a) CI 18 saniyede kırmızı verdi; ilk hipotezin ne olur? → Testler hiç koşmadı — kurulum/altyapı katmanına bak, test loguna değil.
  • (b) Bir suite'in 6 testi birden düştü; tek tek mi incelersin? → Hayır: önce ortak kurulumu (DI/mock/fixture) incele — hepsinin paylaştığı zemin kırıktır.
  • (c) Kodla test çelişiyor; hangisini düzeltirsin? → Önce NİYETİ oku (yorum/karar kaydı/istek): davranış bilinçli değiştiyse TESTİ güncelle; değilse kodu. Körlemesine "testi geçir" ikisinden de tehlikelidir.

Vaka 5 · Fatura, kod yazana değil bota gider: trafik × önbellek

⚠ GERÇEK VAKA — Senaryo. Ağustos 2026 maliyet denetimi, sezgiye ters iki rakamla açıldı: 4 aydır tek satır dokunulmayan bir ürün ayda $0,00 yakarken, 17 gün önce commit alan bir vitrin ürünü ayda $111 yakıyordu — toplam Vercel faturasının %64'ü. Diğer 22 projenin tamamının toplamı: $3,32. İlk hipotezler ("cron şişiriyordur", "polling vardır") çekiciydi ama yanlıştı: cron'ların tamamı ayda ~17 bin çağrıydı; faturayı 14,8 milyon istek yakıyordu.

Teşhis — tahminle değil dışa aktarımla: Usage → Export'tan vercel-costs.csv indirilip projeye göre kırıldı. Suçlu projede tuzağın imzası görüldü: Edge Requests ≈ Function Invocations (14,8M ≈ 14,8M — bire bir). Bu oran şunu söyler: hiçbir istek önbellekten dönmüyor, her sayfa görüntülemesi bir fonksiyon çalıştırıyor.

Kök neden — üçlü kombinasyon: halka açık sayfalarda force-dynamic (önbellek kapalı) + robots.ts'te allow: "/" (botlara tam davet) + sınırsız dinamik segment ([tag], [slug] — botların asla bitiremeyeceği kombinasyon uzayı). Ve zincirleme etki: her istek veritabanına da gittiği için Vercel ve Neon faturası birlikte şişer.

Çözüm: halka açık okuma sayfalarına revalidate (önbellek), force-dynamic yalnız gerçekten dinamik olana; sınırsız segmentler robots'ta kısıtlandı; atıl ürün pause edildi (silme değil — alan adı ve veri durur, tek tıkla döner).

Kalıcı dersler:

  1. Maliyeti geliştirme aktivitesi değil, trafik × önbellek politikası belirler. "Eskiyi kapat" sezgisi yanlış hedefi gösterir; para, önbelleklenmeyen sayfalara çarpan bot trafiğinden gider.
  2. Sıçramada önce veriyi indir (maliyet CSV'si), sonra hipotez kur — cron/polling suçlamaları genelde milyonluk rakamı açıklayamaz.
  3. Edge ≈ Function birebirliği bir imzadır: gör, önbellek politikanı sorgula.

⚡ Hızlı sınav 5: (a) Ayda $111 yakan projeyi "az commit alıyor" diye kapatmak neden sorunu çözmezdi? (b) Edge Requests ≈ Function Invocations neyin kanıtıdır? (c) Üçlü kombinasyonun üç bileşeni neydi? (a: maliyet aktiviteden değil trafikten; b: hiçbir isteğin önbellekten dönmediğinin; c: force-dynamic + açık robots + sınırsız dinamik segment.)

Vaka 6 · Deploy yanlış eve gitti: bir komutun üç ayrı ürünü ezmesi

⚠ GERÇEK VAKA — Senaryo. Haziran 2026'da üç ayrı günde üç ayrı olay, hepsi aynı kök neden ailesinden: (1) A ürününün klasöründen çalıştırılan vercel deploy --prod, B ürününün canlı sitesine başka ürünün kodunu bastı — canlı pazaryeri bozuldu. (2) İki gün sonra, git'e bağlı bir üründe gereksiz yere çalıştırılan CLI deploy'u üçüncü bir ürünün prod'unu ezdi. (3) Ertesi gün bir ürünün domain'i başka ürünün içeriğini sunar bulundu; panik-debug sırasında silinen env değişkenleri boş kaydedilince bütün veritabanı sayfaları düştü.

Teşhis: curl <domain> → sayfa başlığı yanlış ürünü gösteriyor; vercel inspect <domain> → domain doğru projede ama içerik yanlış. Kök neden iki katman: cwd kayması (komut çalışırken çalışma dizini üst klasöre kayıyor) + miras .vercel linki (üst klasörde bir kez oluşan project.json, oradan atılan her deploy'u kendi projesine çekiyor). Üstüne --yes bayrağı, klasör adıyla proje adı farklıysa sessizce yeni bir proje yaratıyor.

Çözüm: yanlış basılan üründe vercel promote <son-iyi-deploy> ile geri dönüş; kaynağı açıkça belirtilen deploy (vercel deploy /tam/yol --prod); üst klasördeki stray .vercel silindi. Kalıcı çözüm süreçte: projeler GitHub'a bağlandı → deploy = git push; kural olarak yazıldı: "git'e bağlı projede CLI deploy YASAK." Boş env felaketinin dersi ayrı: env silmeden önce dur, yeniden eklerken aracın stdin tuzağını bil ve gerçek doğrulama = deploy + sayfa testi (env listesi yanıltıcı olabilir).

Kalıcı dersler:

  1. Deploy çıktısındaki hedef proje satırını OKU — beklediğin ad değilse daha bitmeden durdur.
  2. Deploy sonrası prod alias'ı curl ile doğrula: başlık doğru ürün mü?
  3. Aynı hatanın üç kez yaşanması süreç sorunudur, dikkat sorunu değil: çözüm "daha dikkatli ol" değil, hata sınıfını imkânsızlaştırmak oldu (git-bağlama + CLI yasağı).
  4. Acil müdahalede en tehlikeli an, paniğin ikinci hatası: domain'i kurtarırken env'i düşürmek. Yıkıcı düzeltmeden önce de "önce teyit" geçerli.

⚡ Hızlı sınav 6: (a) vercel inspect domain'in doğru projede olduğunu gösterirken site neden yanlış ürünü sunuyordu? (b) Üç olaydan sonra alınan önlem neden "dikkat edelim" değildi? (c) Yanlış deploy'u geri almanın en hızlı yolu ne? (a: o projenin production'ına başka kaynağın build'i basılmıştı; b: tekrarlayan hata süreçle çözülür — git-bağlama + CLI yasağı; c: son iyi deploy'a promote.)

Vaka 7 · İki şüpheli, tek hata izi: ETIMEDOUT

⚠ GERÇEK VAKA — Senaryo. Mayıs 2026'da bir ürün sayfası prod'da 500 vermeye başladı; log'da AggregateError [ETIMEDOUT] + bağlantı stack'i. Sorun şu ki bu iz iki ayrı şüpheliyi aynı anda gösteriyordu: Redis önbelleği ve Postgres veritabanı — ikisi de "bağlanamadım" diye aynı hatayı üretebiliyordu. Önbellek servisi try/catch ile sarılıydı ama istek yine de asılı kalıyordu.

Teşhis: iki şüpheli tek tek doğrulandı. (1) Redis istemcisinin varsayılanları tuzaktı: sonsuz yeniden deneme + açık offline kuyruğu = Redis'e ulaşılamadığında komutlar kuyruğunda sonsuza kadar bekler; try/catch'in yakalayacağı bir hata hiç fırlamaz, istek thread'i asılı kalır. (2) Ücretsiz kademedeki Postgres uykudan 8-12 saniyede uyanıyordu; bağlantı zaman aşımı 5 saniye olduğu için soğuk başlangıçta her seferinde düşüyordu. Ayırt edici ipucu: log'da Redis'in kendi "connection closed" satırı varsa şüpheli Redis; yoksa Postgres.

Çözüm: Redis istemcisine sınır kondu (sınırlı deneme, offline kuyruğu kapalı, bağlantı ve komut zaman aşımı) — böylece önbellek kaçırma null döner ve çağıran veritabanına düşer; Postgres bağlantı zaman aşımı uyanma süresinin üstüne çekildi (10 sn, env ile ayarlanabilir).

Kalıcı dersler:

  1. "Try/catch koydum" ≠ güvendeyim. Hata fırlatmayan bir bekleme, yakalanacak bir şey üretmez; asıl korunma istemci yapılandırmasında (zaman aşımları, kuyruk politikası).
  2. Kütüphane varsayılanları senin dostun değil: "sonsuz retry" bir kütüphane için makul, bir web isteği için felakettir.
  3. Aynı hata izi birden çok bileşenden gelebiliyorsa, önce ayırt edici ipucu bul (hangi log satırı hangi şüpheliye özgü?) — sonra hipotez kur.
  4. Uyuyan veritabanı + kısa zaman aşımı kombinasyonunu ücretsiz/hobi kademelerinde baştan hesapla.

⚡ Hızlı sınav 7: (a) try/catch neden bu vakada işe yaramadı? (b) Redis mi Postgres mi sorusunu hangi ipucu ayırıyordu? (c) Soğuk başlangıç sorununun iki taraflı çözümü ne olurdu? (a: hata fırlamıyordu, istek kuyrukta asılıydı; b: Redis'in kendi 'connection closed' log satırı; c: bağlantı zaman aşımını uyanma süresinin üstüne çekmek — ve/veya uyandırma stratejisi.)

Denetim penceresi

Bu modülün üç vakasını kendi ürününe tek turda uygula — kırmızı bayraklar: Supabase/bulut DB'de RLS'siz public tablo var · fatura kırılımını hiç okumadın (compute mi egress mi bilmiyorsun) · uptime monitörün/cron'un DB'yi <15 dk'da dürtüyor · son deploy'dan sonra canlıda değişikliği gözünle görmedin · panel uyarıları (advisor/alert) okunmadan duruyor. İkinci-ajan denetim istemi:

Bu ürünün "sessiz başarısızlık" taramasını yap — hiçbir şeyi değiştirme, raporla:
1) DB Supabase/RLS'li ise: public şemada relrowsecurity=false tablo listesi + bağlantı
   rolünün rolbypassrls durumu + client'ta anon-key ile doğrudan tablo sorgusu var mı?
2) Kullanım-bazlı DB ise: son fatura kırılımı (compute/egress) + autosuspend'i engelleyen
   <15dk istek kaynağı var mı (cron, monitör, kalıcı bağlantı)?
3) Son 3 deploy'un her biri için canlıda DOĞRULANABİLİR bir değişiklik kanıtı göster.
4) CI: son 10 koşunun sürelerini listele — anormal KISA süren kırmızı var mı (testler hiç
   koşmadan çöküyor olabilir)? Ayrıca en son ne zaman GERÇEKTEN test koştuğunu kanıtla.
Her madde: DURUM (TEMİZ/ŞÜPHELİ/SORUN) + kanıt + önerilen adım.

Mini egzersiz (KENDİ-PROJEN)

Üret: yukarıdaki denetim istemini gerçek bir projende koştur. Denetle: SORUN çıkan ilk maddeyi bu modüldeki ilgili vakanın akışıyla kapat — teyit adımlarını atlamadan (Vaka 1'deki "açmadan önce iki soru" disiplini her fix için geçerlidir). Kapattığın şeyin kanıtını (öncesi/sonrası sorgu çıktısı ya da fatura ekranı) kendi CLAUDE.md'ne tek satır kural olarak işle.

🧰 Taramayı komuta çevir (Seviye 3 köprüsü)

Yukarıdaki tarama istemini her seferinde bulup yapıştırmak, 3.1'in tanımladığı "üç kez elle yaptıysan otomatiğe bağla" eşiğine er geç takılır. O ders tam bunun için var: istemi kendi /prod-tarama komutuna çevir —

Bu sayfadaki "sessiz başarısızlık taraması" istemini /prod-tarama adlı bir skill'e
çevir (~/.claude/skills/prod-tarama/SKILL.md). Skill önce projenin stack'ini
keşfetsin (DB Supabase mi Neon mu, CI hangi platform, deploy nereye) ve uymayan
maddeleri raporda "uygulanamaz" diye işaretleyip atlasın; çıktı her madde için
DURUM (TEMİZ/ŞÜPHELİ/SORUN) + kanıt + önerilen adım olsun. Kurduktan sonra kabul
testi yap: /prod-tarama'yı bu projede çalıştır, raporu göster.

Bundan sonra prod'da her tuhaflıkta refleksin iki kelime: /prod-tarama. (Aylık ritüelin için aynı dönüşümü sessiz-tuzaklar istemine de uygulayabilirsin. Kendin yazmak istemezsen: üçünün de HAZIR hâli araç setinde.)

Kontrol soruları

(1) RLS varsayılan olarak neden tehlikelidir ve "deny-all" ne zaman tam doğru konfigürasyondur? (2) Serverless DB faturasının iki sayacı nedir; hangi "iyi niyetli" araçlar hangisini şişirir? (3) Sessiz başarısızlık sınıfını çökmeden ayıran özellik nedir? (4) "Beyan kanıt değildir" ilkesi bu üç vakada hangi üç ölçüye karşılık gelir?

Mentor istemi

AI Maestro "Prod'da Hayatta Kalma" modülünün hocası ol. Üç vakayı sırayla bana
YAŞAT: her vakada önce belirti-yokluğunu göster, teşhis sorgusunu/adımını bana
buldur, fix'ten önce teyit sorularını bana sordur. Sonunda üç hızlı sınavı ve 4
kontrol sorusunu karışık sor; "beyan kanıt değildir" bağını kurdur.

🔄 Güncelleme istemi (vaka defteri protokolü)

prod-vakalari.md'ye yeni vaka ekle: [olayı yapıştır]. Mevcut vaka formatına uy
(Senaryo → Teşhis → Çözüm['önce teyit'] → Kalıcı ders → Hızlı sınav), gerçek
komut/sorgu örnekleri kullan, ilgili çekirdek derslere ve sessiz-tuzaklar kartına
köprüle, "Son güncelleme" tarihini yenile; denetim istemine gerekiyorsa madde ekle.

Bu modül nerede derinleşiyor? (sarmal harita)

  • Index + fatura temeli2.8 · kök neden döngüsü2.4 · secret/env disiplini2.6
  • Beyana güvenmeme + ikinci-ajan denetimi1.5 · aylık proaktif taramasessiz-tuzaklar
  • Deploy sonrası canlı doğrulama2.3 · kırmızı bölge/yıkıcı işlem provası2.5

Vaka kaynağı: SoloLabs üretim altyapısı, 3-7 Ağustos 2026 (Neon fatura kırılımı, Supabase Security Advisor kayıtları, Vercel deploy günlükleri). Rakamlar gerçek faturadan; ürün adları anonimleştirildi.