All checks were successful
Deploy / deploy (push) Successful in 17s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
116 lines
8.5 KiB
Markdown
116 lines
8.5 KiB
Markdown
# 10 — `/sonuc` haritası en üstte (Talimat 1)
|
||
|
||
> Dal `is/0923-harita-ustte`, worktree `.claude/worktrees/0923-harita`, temel `origin/main` (c5769e2).
|
||
> Commit: **`ea4b30a`** — `fix(sonuc): harita en üste çıkar, liste sayısı çerezi kaymayı sıfırlar`.
|
||
> Çalışma ağacı temiz, push/merge yok. Tarayıcı/dev sunucusu açılmadı (AGENTS.md).
|
||
|
||
## Özet — 5 madde
|
||
|
||
1. `ManuelHarita` `/sonuc`'ta tablonun altından **en üste** alındı (tadımlığın üstüne). `mt-16`
|
||
kalktı; harita artık `main`'in ilk çocuğu, üst boşluğunu `main`'in `py-12`'sinden alıyor.
|
||
2. **Liste boşken harita DOM'a hiç girmiyor** — yer tutucu da yok. Bilal'in şartı korundu, ürünü
|
||
ilk kez gören ziyaretçide sayfa sırası hiç değişmiyor (tadımlık → tablo).
|
||
3. CLS için `kolaytercih.liste-sayi` çerezi eklendi: client listenin **yalnızca uzunluğunu**
|
||
aynalıyor, sunucu hidrasyondan önce haritaya tam ölçülü yer ayırıyor. Öznitelikler
|
||
`kolaytercih.profil` ile birebir aynı (`path=/; max-age=31536000; samesite=lax` + https'te `secure`).
|
||
4. Şartnamenin ötesinde tek ekleme: `yerAyir` **yalnızca hidrasyona kadar** geçerli
|
||
(yeni `useListeHidreMi()`). Gerekçe aşağıda — yoksa çekmeceden liste boşaltılınca boş Türkiye
|
||
haritası ekranda kalıyordu.
|
||
5. Tasarımcının işaretlediği iki açık kapandı: iskelete `motion-reduce:animate-none`, yurt dışı
|
||
şeridine sabit yükseklikli `loading` yer tutucu. Kararın **tersini** belgeleyen üç yorum bloğu
|
||
aynı commit'te güncellendi.
|
||
|
||
## Değişen dosyalar (7 dosya, +117 / −33)
|
||
|
||
| Dosya | Ne oldu |
|
||
|---|---|
|
||
| `src/features/liste/liste-dogrula.ts` | `LISTE_SAYI_CEREZ_ADI = "kolaytercih.liste-sayi"` sabiti (client store ile sunucunun ortak zemini) |
|
||
| `src/features/liste/liste-store.ts` | `sayiCereziniYaz()`; `kaydet()`, `yukle()` ve `"storage"` dinleyicisinde çağrı + `useListeHidreMi()` |
|
||
| `src/features/liste/components/manuel-harita.tsx` | `yerAyir` prop'u, `mt-16` kaldırıldı, boş-liste yorumu yeniden yazıldı |
|
||
| `src/features/liste/components/tercih-haritasi-lazy.tsx` | İskelete `motion-reduce:animate-none` |
|
||
| `src/features/liste/components/yurtdisi-haritalar-lazy.tsx` | `loading: () => <div className="mt-3 h-26" aria-hidden />` |
|
||
| `src/app/sonuc/page.tsx` | Çerez okuma (`haritayaYerAyir`), harita `:118`'in üstüne, yorum bloğu yeniden yazıldı |
|
||
| `src/features/rapor/components/tadimlik-satiri.tsx` | `first:mt-0` yorumu yeni sıraya göre düzeltildi |
|
||
|
||
## Şartnameden iki sapma (ikisi de bilinçli)
|
||
|
||
**1. `yerAyir` hidrasyondan sonra geçersiz (ek: `useListeHidreMi`).**
|
||
Şartname `if (liste.length === 0 && !yerAyir) return null;` diyordu. Bu hâliyle `yerAyir` sunucudan
|
||
gelen sabit bir prop olduğu için iki durumda boş harita ekranda **kalıcı** olurdu:
|
||
kullanıcı çekmeceden listeyi tamamen boşaltınca (çerez 0'a döner ama prop değişmez) ve bayat çerez
|
||
durumunda (localStorage silinmiş, çerez kalmış). İkisi de Bilal'in "liste eklenmezse gözükmesin"
|
||
şartını doğrudan çiğniyordu. Çözüm: store'un hidre olup olmadığını aynı snapshot'tan okumak —
|
||
|
||
```
|
||
if (liste.length === 0 && (hidre || !yerAyir)) return null;
|
||
```
|
||
|
||
`useListeHidreMi()` sunucu snapshot'ında `false`, hidrasyondan sonra `true` döner ve `liste` ile
|
||
**aynı** `abone`/`yukle()` çağrısından doğar; ikisi tek render'da tutarlı, hidrasyon uyuşmazlığı yok.
|
||
Ayrı iskelet dalı yazılmadı — fonksiyon akıyor, `pinler=[]` ile `TercihHaritasiLazy` monte oluyor ve
|
||
chunk hidrasyonu beklemeden inmeye başlıyor (şartnamenin istediği gibi).
|
||
|
||
**2. Yurt dışı yer tutucusu `h-40` değil `h-26`.**
|
||
Şartname "`h-40` ya da eşdeğer sabit yükseklik" diyordu. Gerçek yüksekliği koddan hesapladım:
|
||
figür `w-52` (208 px) × svg oranı 1050/447 = 88,6 px + `figcaption` `text-xs` 16 px ≈ **104,6 px**
|
||
(`yurtdisi-haritalar.tsx:60-128`). `h-26` = 104 px; `h-40` (160 px) ~55 px fazladan rezerve edip
|
||
kendisi kayma üretirdi. Kap `mt-3`'ü bileşenin kendi kökündekiyle aynı. Birden çok ülke alt satıra
|
||
kayarsa fark kalır — sunucu ülke sayısını bilemez (şartnamenin kabul ettiği artık kayma).
|
||
|
||
## Kabul kriterleri
|
||
|
||
| # | Kriter | Durum | Nasıl |
|
||
|---|---|---|---|
|
||
| 1 | Listesi olanda harita en üstte, hidrasyonda zıplama yok | ✔ **koddan çıkarım** | `sonuc/page.tsx:131` artık `TadimlikBolumu`'nun (`:134`) üstünde; `haritayaYerAyir` çerezden `cookies()` ile okunuyor, `pinler=[]` yolunda `HaritaIskeleti` aynı `aspect-[1050/447]` kutusunu veriyor. Tarayıcıda ölçülmedi. |
|
||
| 2 | Liste boşken harita DOM'da hiç yok, fazladan boşluk yok | ✔ **koddan çıkarım** | `manuel-harita.tsx` `return null` dalı korundu; JSX yorumları düğüm üretmediği için tadımlık `main`'in ilk çocuğu kalıyor → `first:mt-0` (`tadimlik-satiri.tsx:134`, dokunulmadı) geçerli. |
|
||
| 3 | İlk kez gelen ziyaretçide sıra değişmiyor | ✔ **koddan çıkarım** | Çerez yok → `Number.parseInt("")` = `NaN` → `haritayaYerAyir=false` → harita `null`. Sıra: tadımlık → tablo. |
|
||
| 4 | Çerez kişisel veri taşımıyor | ✔ **kod okuması** | Değer düz tamsayı (`${LISTE_SAYI_CEREZ_ADI}=${n}`); program kimliği, üniversite adı, sıralama yok. |
|
||
| 5 | `next typegen` + `tsc --noEmit` + `lint` temiz | ✔ **çalıştırıldı** | Üçü de hatasız geçti. |
|
||
| 5b | `pnpm build` temiz | ✘ **doğrulanamadı — diskte yer yok** | Bkz. aşağıdaki engel. Turbopack derlemesi **başarılı** ("✓ Compiled successfully in 76s"), build'in içindeki TypeScript adımı `.tsbuildinfo` yazarken `ENOSPC` ile düştü. Aynı kod üzerinde ayrı koşan `tsc --noEmit` temiz geçtiği için tip riski görmüyorum; yine de build **tekrar koşulmalı**. |
|
||
|
||
## Engel — makinede disk doldu
|
||
|
||
`/System/Volumes/Data` %100 dolu, ~1 GB boş. Bir Next build'i (229 statik üniversite sayfası)
|
||
bunu aşıyor; ikinci denemede kabuk bile çıktı dosyası açamaz hâle geldi. Kendi worktree'mdeki
|
||
`.next`'i sildim (81 MB → 0). Başkalarının worktree'lerine dokunmadım ama yer oradan çıkacak:
|
||
|
||
```
|
||
.claude/worktrees/0922-entegrasyon/.next 1,4 G
|
||
.claude/worktrees/0922-urap/.next 1,4 G
|
||
```
|
||
|
||
Bu iki klasör başka dalların build çıktısı (gitignore'lu, silinmesi veri kaybı değil) — **silme
|
||
kararı benim yetkimde değil**, orkestratör ya da Bilal onaylarsa yer açılıp build tekrar koşulabilir.
|
||
|
||
## Merge sonrası doğrulanması gerekenler
|
||
|
||
1. **`pnpm build`** — yukarıdaki engel yüzünden hiç tamamlanamadı; merge öncesi mutlaka temiz geçmeli
|
||
(AGENTS.md: push öncesi build zorunlu, üstelik push edilecek commit'in kendisi üzerinde).
|
||
2. `/listem` ve navbar rozeti hâlâ aynı store'a abone — `kaydet()` yoluna eklenen çerez yazımı her
|
||
mutasyonda koşuyor, ekstra render tetiklemiyor ama akışların bir kez elden geçmesi iyi olur.
|
||
3. Çerez, site genelinde ilk açılan sayfada (ana sayfa) doğuyor çünkü liste store'u `layout.tsx`
|
||
üzerinden her sayfada yükleniyor; `/sonuc`'a doğrudan gelen yeni ziyaretçide ilk açılışta çerez
|
||
henüz yoktur — o tek seferlik durumda harita hidrasyonda belirir (şartnamenin kabul ettiği kaçak).
|
||
4. `/meraklisina` mermaid şeması **etkilenmiyor**: sihirbaz adımları, aday havuzu, 24'lük iskelet ve
|
||
dilim etiketleri değişmedi; bu commit yalnızca `/sonuc`'un DOM sırasına dokunuyor.
|
||
5. Tasarımcının §2.5'te işaretlediği `program-tablosu.tsx:175` (`mt-16` ama `first:mt-0` yok →
|
||
girişli + listesiz kullanıcıda tepede 64 px ölü alan) **kapsamım dışındaydı**, dokunmadım.
|
||
|
||
## Güvenlik notu
|
||
|
||
Bu commit yeni bir çerez yazıyor (`kolaytercih.liste-sayi`, yalnız tamsayı, 1 yıl, `samesite=lax`).
|
||
Değer kişisel veri taşımasa da gizlilik/çerez metinleriyle örtüşmenin kontrolü için
|
||
**`guvenlik-uyum` denetimi önerilir**.
|
||
|
||
## Bilal'den istenen (3 madde)
|
||
|
||
1. **Diskte yer aç** (ya da yukarıdaki iki `.next` klasörünü silmeye izin ver) ki `pnpm build`
|
||
koşulabilsin — merge'ün tek açık şartı bu. **~2 dk.**
|
||
2. **`/sonuc`'u telefonda üç durumda gözle kontrol et**: (a) listeye 1-2 program ekleyip sayfayı
|
||
yenile — harita en üstte mi, zıplama var mı; (b) tarayıcı verisini silip ilk kez gir — harita hiç
|
||
yok mu, tadımlığın üstünde fazladan boşluk var mı; (c) çekmeceden listeyi boşalt — harita anında
|
||
kayboluyor mu. **~5 dk.**
|
||
3. **Yeni çerez onayın**: `kolaytercih.liste-sayi`, yalnız tamsayı, 1 yıl, işlevsel amaçlı —
|
||
`kolaytercih.profil` ile aynı sınıf. Gizlilik metninde çerez sayımı/listesi varsa oraya da
|
||
eklenmesi gerekir mi? **~2 dk.**
|