News:

SMF - Just Installed!

Main Menu

Recent posts

#31
Announcements & Releases / 1.1.29
Last post by hitsumo - Sep 15, 2026, 04:01 PM
# Anime Tracker 1.1.29

**Release date:** 2026-08-23

Two pieces of work: a countdown for anime that have not started airing yet,
and completing the project's GPL-2.0 licence notices. The second one is
comments only — it has no effect on screen.

## New: "time until episode 1" for anime that have not started

- **The problem:** for an airing anime the detail page counted down —
  "Next Episode: 3 d 4 h". For an anime that had **not started** it only
  printed "Release Date: 07.10.2026", leaving you to count the days on a
  calendar.
- **Everything needed was already stored:** the release date, the broadcast
  time and the broadcast timezone. 1.1.28 brought all three to the form and
  the detail page for upcoming anime; the only missing step was building a
  countdown out of them.
- **Now it does.** A new **Premiere** row appears on the detail page:
  *"Time until ep. 1: 45 d 7 h"*. The format is identical to the airing case —
  same calculation, same look.
- **The list page too.** The "next episode" column showed a dash (`-`) for
  upcoming anime; it now shows the same countdown.
- **The label is deliberately not "Next Episode".** With no episode aired yet,
  "next" would be misleading.
- **If no broadcast time is recorded** the countdown uses midnight on that
  date. The day count is still right; only the hours within the day are a
  guess.
- **If the release date has passed but the status is still "not started"**,
  the row reads *"Premiere date has passed"*. The airing message ("New episode
  aired") would be wrong here — nothing has aired; this is a hint that the
  record's status needs updating.
- **Nothing is written to the database.** The countdown is computed on every
  render; no derived value is stored.

## Licence notices

Everything in this section is comment lines; no running code is affected.

### Why

Anime Tracker is GPL-2.0 licensed, and the full licence text already shipped
both in the repository (`LICENSE.txt`) and inside the installed application
(`files/license.txt`) — so nothing was missing licence-wise. What was missing
were the **per-file notices:** 80 of 195 source files carried none at all, and
the ones that did were written in three different styles.

This was not a violation; GPL-2 does not require per-file headers. But having
files with and without a notice sitting side by side in the same folder makes
a first-time reader ask "is this file outside the licence?" In an open-source
project that question should never come up.

### What changed

- **A short notice was added to the 80 files that had none.** The wording is
  the one already used by the majority of the codebase:
 
  ```
  Anime Tracker - <file title>
  https://www.sicakcikolata.com
  Copyright (C) 2025-2026 Okan Sumer
  Licensed under GNU General Public License v2
  ```
 
  Each file got it in its own comment syntax. Breakdown: 60 migration files,
  five application pages (`recent`, `series_timeline`, `statistics`,
  `sync_aired`, `admin_catalog_requests`), `anime_form.js`, four
  example/template files, four packaging files (Dockerfile, Docker Compose,
  Docker entrypoint, Windows installer script) and three one-off CLI scripts.
 
- **The full GPL header in 21 files was normalised.** Those headers still had
  the FSF template's square-bracket placeholders in them — the copyright line
  literally read `Copyright (C) 2025 [Okan Sumer]`. The brackets are gone and
  the indentation is aligned. The same 21 headers had drifted into six
  whitespace variants; they are now one text. In `list_settings.php` the
  comment block was accidentally opened twice (a `/**` inside a `/**`); that
  is fixed too.
 
- **`db.php`'s truncated notice was completed.** It ran as far as the warranty
  disclaimer but the final paragraph ("You should have received a copy of the
  GNU General Public License...") was missing. It was the only half-written
  notice in the codebase.
 
- **Copyright year is now `2025-2026` instead of `2025`.** The project was
  published in 2025 and is still being developed in 2026. A copyright line was
  also added to both the Turkish and the English licence section of the README.
 
- **The author name is now spelled one way.** Two spellings were in
  circulation; since code comments in this project are written in ASCII
  Turkish, the majority form won. The README, being prose, keeps the proper
  spelling.
 

### What did not change

- `LICENSE.txt` and `files/license.txt` were left alone — both are the full
  GPLv2 text and identical to each other. The Docker image and the Windows
  installer already shipped the licence.
- No licence-acceptance page was added to the Windows installer. GPL does not
  ask for click-through consent, and `license.txt` sits in the install
  directory.
- No visible licence/warranty text was added to the About page. That can be
  done later; a notice-cleanup release is not the place to quietly change the
  interface.

## Verification

That the **licence sweep** touched nothing but comments was **measured**, not
assumed:

- All 331 PHP files were compared before and after with comments and
  whitespace stripped: **331/331 byte-identical.**
- The same 331 files were run through the parser: 331/331 passed.
- The scan was re-run: **195/195** source files now carry a copyright and
  licence line (it was 115/195 before).
- In files that use CRLF line endings the inserted lines were written with
  CRLF too; no file's line-ending style was disturbed.

The **countdown** was measured separately — both that it works and that it
breaks nothing else:

- The date arithmetic was exercised in 13 cases: the real record
  (07.10.2026 23:45 JST → 07.10.2026 14:45 UTC), a record with no time, one
  with no timezone, an invalid timezone, Istanbul time, a malformed date,
  missing fields, and four different broadcast statuses. 13/13 as expected.
- The detail page's broadcast block was rendered **from lines pulled out of
  the file itself**, across five broadcast statuses × chronology markers
  present/absent = 10 cases. The result was compared with the same test on
  1.1.28: **only the "not started" rows changed**; the other eight came out
  byte-identical.
- The same test was run on the list page cell: of seven cases **exactly one**
  changed (upcoming anime, `-` replaced by the countdown); six unchanged.
- The chronology button was counted in every case: **exactly once**, so the
  rule established in 1.1.28 still holds.
- Of the 331 PHP files, exactly **five** differ semantically from the
  licence-sweep state — the five that carry this feature. The other 326 are
  byte-identical with comments stripped.

## Schema / migration

- **No schema change.** No new table, column or preference — the countdown is
  computed on every render, never stored.
  `migration/1.1.29/upgrade.sql` only carries the version stamp.
- **No manual step is needed on the central catalog database** — the catalog
  wire was not touched.

## Deployment note

**On the application server** 195 files changed, but in 190 of them the only
difference is a copyright/licence comment. The five files that carry the
countdown must be uploaded **together**:

```
files/functions/anime_helpers.php    (the calculation and its wording)
files/anime_details.php              (the Premiere row)
files/index.php                      (the list column)
files/lang/tr.php, files/lang/en.php (the Premiere label)
```

Plus `files/version.txt` and the new `files/migration/1.1.29/` folder. The
remaining files are cosmetic and can be uploaded whenever convenient.

**Partial-upload warning:** if `anime_helpers.php` stays old, the detail page
calls a function that does not exist and the page fails to load. If the
language files stay old, the key name shows instead of the label. Treat those
five as one unit. No such dependency exists among the other 190 files.

The files in the old migration folders (`0.5.1` ... `1.1.28`) changed as well,
but they do not need to reach the application server again: the migration
runner only executes folders numbered above the current version, so those
files are never read again.

**On the distribution server** (the one installations check for updates)
there are two functional steps: the published `version.txt` must be moved to
1.1.29 — otherwise "Check for updates" still reports 1.1.28 as the latest —
and the `updates/1.1.29/anime-tracker-1.1.29.zip` package must be published,
otherwise the "Update" button gets a 404 at the download address. The
`catalog.php`, `admin_push.php` and two example config files on that same
server changed too, but the only difference in them is the copyright line.
#32
Duyurular ve Sürümler / 1.1.39
Last post by hitsumo - Sep 15, 2026, 04:00 PM
# Anime Tracker 1.1.39

**Yayın tarihi:** 2026-09-08

Şema değişikliği yok. Tek iş: aynı listeyi gösteren binlerce adres artık arama
motorlarına ayrı birer sayfa gibi görünmüyor.

## 1. Liste kopyaları artık indekslenmiyor

1.1.37 "bu **kayıt** indekslenmeye değer mi" sorusunu cevaplamıştı. Geriye aynı
sorunun ikinci yarısı kalmıştı: aynı kayıtları gösteren kaç tane **adres** var?

Liste sayfasındaki her düğme adrese bir parametre ekliyor — harf filtresi,
sıralama sütunu, yön, sayfa numarası, sayfa boyu, sekme. Bir tarayıcı bunların
hepsine tıklıyor ve her kombinasyonu ayrı bir sayfa sanıyor. Canlı katalogla
ölçüldüğünde **1.568 farklı (harf, sayfa) çifti × 10 sıralama kombinasyonu ≈
15.700 adres** çıkıyor; sayfa boyunun altı değeri bunu ~94.000'e taşıyor.

Ölçüm (8 Eylül 2026, Search Console'un 1.000 adreslik örneği):

| Pay | Ne  |
| --- | --- |
| %65 | boş taslak detay sayfası — 1.1.37 bunları zaten kapattı, düşmeleri yeniden taramaya bağlı |
| **%29** | **liste kopyası** — bu sürümün konusu |
| %5  | gerçek içerikli sayfa |
| %1  | kronoloji / seri / yardım |

Aynı gün site haritası **564** adres tarif ediyordu; dizinde **5.463** adres
vardı.

Bu kopyalar yeni bir giriş kapısı **açmıyor**: hiçbiri bir arama sorgusunun
cevabı değil — "H harfi, izleme durumuna göre azalan, sayfa 43" diye kimse
aramıyor. Ama var olan kapının önünde sıra bekliyorlar. Tarama bütçesi sabit
olduğu için ölçüm, bütçenin 20'de 1'inin indekslenmesini istediğimiz sayfalara
gittiğini gösterdi.

Bundan sonra **çıplak liste sayfası** indeksleniyor; bir filtre, sıralama, arama
ya da sayfa numarası verildiği anda adres `noindex, follow` taşıyor. Sayfa
dizine girmiyor ama **bağlantıları izleniyor** — katalogun tamamına giden tek iç
yol sayfalama olduğu için bu şart.

**Site içinde hiçbir şey değişmedi.** Filtreler, sıralama, sayfalama ve sekmeler
aynen çalışıyor; değişen tek şey bu adreslerin arama motoruna ne söylediği.
Ziyaretçinin göreceği bir fark yok.

### Neden `canonical` yetmedi

Bu sayfalar 1.1.30'dan beri doğru `canonical` taşıyordu — hepsi çıplak liste
sayfasını gösteriyor. Ama `canonical` bir **tavsiye**; ölçüm, Google'ın onu yok
sayıp kopyaları yine de indekslediğini gösterdi. Yandex aynı bilgiyi
`Clean-param` olarak alıyor ve ona uyuyor.

### Neden `robots.txt`'e yasak eklenmedi

`Disallow: /*?sort=` gibi bir kural adresi **taramaya** kapatır. Kapalı bir
adresteki `noindex` okunamaz, yani hâlihazırda dizinde duran binlerce kopya
orada kalırdı. Önce okunmalı, sonra düşmeli.

### Seri kronolojisinde de aynı düzeltme

`series_timeline.php` bir serinin **tüm** üyeleri için aynı çizelgeyi çiziyor —
yani beş üyeli bir seride beş adres aynı sayfa; görünüm ve zincir sekmeleri bunu
bir kat daha çoğaltıyor. Buradaki `canonical` de doğruydu ama yine yalnızca
tavsiyeydi. Artık adres canonical'in kendisi değilse `noindex, follow` taşıyor.
Site haritasının listelediği adres eskisi gibi indeksleniyor; **site haritası
çıktısı değişmedi.**

## Yükleme sonrası ne beklenmeli

Kopyaların dizinden düşmesi **anında olmaz** ve ölçüsü haftalardır: Google önce
o adresi yeniden taramalı, `noindex`'i görmeli, sonra düşürmeli.

Search Console'da beklenen eğri: **"Dizine eklenmedi" sayısı önce artar** (düşen
her sayfa oraya, "noindex etiketiyle hariç tutuldu" nedeniyle geçer), "Dizine
eklenen" sayısı düşer. **Bu başarıdır, hata değil.**

Doğru ölçülecek şey sayfa sayısı değil, Performans raporundaki **gösterim ve
tıklama**. Düşen adreslerin gösterimi zaten sıfıra yakındı, yani toplam
gösterimin düşmemesi beklenir.

## Kapsam dışı (bilinçli)

- **Sayfa numarası hâlâ sınırsız.** `?page=780` boş ekran değil, listenin son
  sayfasını döndürür. Bu davranış elle adres düzenleyen ziyaretçi için doğru;
  arama motoru tarafındaki zararını zaten `noindex` kapattı.
- **Kronoloji sayfasına dokunulmadı** — tek parametresi kayıt kimliği ve o zaten
  canonical.
- **Son eklenenler, istatistikler ve öneriler** 1.1.30'dan beri zaten indeksleme
  dışı.

## Dosyalar

**Yeni:**

```
files/migration/1.1.39/upgrade.sql   (şemasız; sürüm damgası + gerekçe kaydı)
```

**Değişen:**

```
files/functions/seo_helpers.php   kural (tek yer)
files/index.php                   biçimlendirilmiş adrese noindex, follow
files/series_timeline.php         canonical olmayan adrese noindex, follow
files/robots.php                  Clean-param listesi tek yerden okunuyor
files/version.txt
```

Yeni dil anahtarı yok — arayüzde görünen hiçbir metin değişmedi. Yeni CSS/JS de
yok.

## Dağıtım notu

- `files/functions/seo_helpers.php`, `files/index.php` ve `files/robots.php`
  **birlikte** yüklenmelidir. Yardımcı dosyanın eski kopyası sunucuda kalırsa
  ana sayfa ve `robots.txt` çöker (iki yeni fonksiyon bulunamaz). Ters sıra
  güvenlidir: önce yardımcı dosya, sonra ötekiler — yeni yardımcı, eski
  sayfalarla da çalışır.
- `files/series_timeline.php` yeni fonksiyon çağırmaz, tek başına yüklenebilir.
- **Merkez katalog sunucusunda yapılacak bir şey yok.** Katalog telinde yeni
  alan yok, elle `ALTER` gerekmiyor, `catalog_server/` altındaki hiçbir dosya
  değişmedi.
- Migration şema değiştirmez, yalnızca sürüm damgasını taşır ve kendiliğinden
  koşar.
- **Dağıtım sunucusunda** her zamanki iki adım: yayımlanan `version.txt`
  1.1.39'a çekilmeli ve `updates/1.1.39/anime-tracker-1.1.39.zip` paketi
  yayımlanmalı.
- Self-host kurulumlar etkilenmez — o modda zaten her sayfa indekslemeye kapalı.
#33
Duyurular ve Sürümler / 1.1.38
Last post by hitsumo - Sep 15, 2026, 03:59 PM
# Anime Tracker 1.1.38

**Yayın tarihi:** 2026-09-04

1.1.36 zincire bir **ad** verdi. Bu sürüm bağın **türünü** veriyor: artık "bu
iki kayıt birbirine ait ama biri diğerinin devamı değil" cümlesi yazılabilir —
ve uygulama onu anlar.

## Sorun

1.1.36'nın teşhisi, çözdüğünden fazlasını söylüyordu. Ortadaki eksik yalnızca
"hangi hat" bilgisi değildi; **"ne tür bağ"** bilgisiydi.

- *Space Adventure Cobra (1982)* filmi, AniDB'ye göre TV dizisinin
  **alternatif versiyonu**. Katalog yalnızca "bağlı" ya da "bağsız"
  diyebiliyordu, yani doğru cevap **söylenemiyordu** — ve söylenemeyen bu cümle
  ekranda *eksik veri* gibi görünüyordu.
- *Sailor Moon Crystal* (yine alternatif versiyon) tam tersini yapmıştı: 90'lar
  zincirinin **içine** bağlanmıştı, yani zaman çizelgesi var olmayan bir izleme
  sırası iddia ediyordu.

1.1.36 ikisini de görünür kıldı (ad vererek), ama **neden** ayrı durduklarını
kayda geçirmedi. Bu sürüm onu yapıyor.

## Çözüm: tipli ve sırasız ilişkiler

Düzenleme sayfasının altına yeni bir bölüm geldi: **İlişkiler**. Bir anime
seçip türü işaretliyorsunuz; form tek bir soru soruyor:

> Seçtiğiniz anime, bu animenin ___'idir.

| Seçenek | Anlamı |
| --- | --- |
| Alternatif versiyonu | Aynı hikâyenin başka bir anlatımı |
| Alternatif kurgusu | Aynı karakterler, başka bir dünya/kurgu |
| Yan hikâyesi / Ana hikâyesi | Yan anlatı ile ana anlatı (iki yön) |
| Özeti / Tam hikâyesi | Kısaltılmış anlatım ile tamamı (iki yön) |
| İlişkilisi (diğer) | Yukarıdakilerin hiçbiri |

İlişkiler detay sayfasında **İlişkili Animeler** başlığı altında, türe göre
gruplanmış olarak görünür.

## İki uç, iki farklı cümle

Yan hikâye ve özet **çift yönlüdür**: A, B'nin yan hikâyesiyse B, A'nın yan
hikâyesi *değildir* — **ana** hikâyesidir. Bu yüzden aynı kayıt iki animenin
sayfasında iki farklı etiketle görünür:

```
ZZ Filmi sayfasında:   Yan Hikâye   → ZZ TV Dizisi   (yanlış olurdu)
ZZ TV Dizisi sayfasında: Ana Hikâye  → ...
```

Doğrusu: filmi "yan hikâye" diye eklediğinizde dizinin sayfasında film "Yan
Hikâye", filmin sayfasında dizi "Ana Hikâye" olarak görünür. Alternatif
versiyon, alternatif kurgu ve "diğer" iki yönden de aynı okunur, onlarda tek
etiket vardır.

## `sequel` bilerek yok

Listede **devam/öncesi** diye bir tür göremezsiniz. İzleme sırası hâlâ tek bir
yerde duruyor: **Sıradaki Anime** alanı. Sequel burada da saklanabilseydi aynı
çift hakkında iki kaynak konuşabilir, çeliştiklerinde de birinin kazanması
gerekirdi. Değeri hiç eklememek, çelişkiyi "önerilmez" değil **girilemez**
yapıyor.

Buradaki hiçbir tür sıra belirtmez. Seri kronolojisi ve konu spoiler kapısı bu
sürümde **hiç değişmedi** — ikisi de eskisi gibi yalnızca "Sıradaki Anime"
bağlarını izliyor.

## Kabul edilmeyen iki durum

**Aynı çifte ikinci ilişki eklenemez.** İki satır ya tekrardır ya çelişkidir;
tek ve daha iyi bir tür seçerek anlatılamayacak üçüncü bir durum yok. Yeni bir
tür girmek isterseniz önce mevcut olanı silin.

**"Sıradaki Anime" ile bağlı iki kayıt arasına ilişki kurulamaz.** O çift aynı
anda hem sıralı hem sırasız olduğunu iddia ederdi — yani tam olarak Sailor Moon
Crystal hatası. Uygulama bunu reddeder ve çözümü söyler: önce bağı kaldırın.

Bu kontrol 1.1.36'nın kuralını tekrar etmez, **çağırır**: bağ yalnızca iki ucun
**zincir adı aynıysa** izlenir. Adlar farklı olduğu için zaten izlenmeyen
"uykudaki" bir bağ hiçbir şeyi engellemez.

## Yedeğinize girer

JSON yedeği ilişkileri de taşır. Karşı uç, yerel kayıt numarasıyla değil
**kimlikle** (MAL / AniDB / katalog kimliği / başlık) yazılır — tıpkı kronoloji
notlarında olduğu gibi — ve geri yüklemede yeniden bulunur. Yani yedek al /
geri yükle turunda ilişkiler kaybolmaz.

Geri yükleme iki durumda bir ilişkiyi atlar ve bunu size sayı olarak bildirir:
karşı uç bu kurulumda yoksa, ya da tür tanınmıyorsa. Tanınmayan bir tür
"diğer"e **düşürülmez** — anlamadığı bir bağı kaydetmek, sonradan doğrusunu
girmenizi de engellerdi.

## Var olan verinize etkisi yok

Migration yalnızca boş bir tablo oluşturur; hiçbir bağı dönüştürmez, hiçbir
kaydı değiştirmez. Yükledikten sonra listeniz, zincirleriniz ve spoiler kapınız
bire bir aynıdır — ilişkileri siz elle girersiniz.

## Ekleme ve düzenleme formu artık sekmeli

Aynı sürümde ikinci, ayrı bir iş. Anime ekleme ve düzenleme formu tek uzun
sayfaydı ve yeni İlişkiler paneli onu daha da uzatıyordu — üstelik kaydet
tuşlarının **altında** kalıyordu. Alanlar beş sekmeye bölündü:

| Sekme | İçindekiler |
| --- | --- |
| Künye | Ad, alternatif isimler, ortam türü, ülke, durum, bölüm sayıları, tarihler, +18, filler takibi, resim |
| Konu ve Türler | Konu metinleri (TR/EN, katalog + kişisel), türler, cümleler |
| Seri ve İlişkiler | Seri adı, zincir adı, sıradaki anime **ve İlişkiler paneli** |
| Yayın ve Kaynaklar | Bölüm aralığı, yayın günü/saati/saat dilimi, AniDB/MAL/AnimeSchedule bağlantıları |
| Kişisel | İzleme durumu, izlenen bölüm, izleme tarihleri, kişisel notlar |

Ekleme sayfasında da aynı sekmeler var; tek fark, orada "Seri" sekmesinin
İlişkiler panelini taşımaması — kayıt henüz oluşmadığı için ilişkinin bir ucu
eksik olurdu.

**Form hâlâ tek parça kaydedilir.** Sekme değiştirmek hiçbir şeyi göndermez ya
da kaydetmez; **Güncelle** her sekmede sayfanın en altında durur ve *bütün*
alanları birlikte kaydeder — hangi sekmenin açık olduğu fark etmez.

Üç incelik:

- **Zorunlu bir alan başka sekmede boş kaldıysa** tarayıcı formu sessizce
  göndermez ("odaklanılamayan alan"). Artık o alanın sekmesi kendiliğinden
  açılır, uyarı balonu görünür hâle gelir.
- **JavaScript kapalıysa** sekme çubuğu hiç görünmez ve bütün alanlar eskisi
  gibi alt alta listelenir. Sayfa 1.1.37'deki gibi çalışır.
- **"Otomatik Doldur" raporu** artık başka sekmedeki bir alana "(gizli
  bölümde)" demiyor — alan oradadır, sekmeye basınca görünür. Not yalnızca
  gerçekten gizli alanlar için çıkar (örneğin duruma bağlı yayın bölümü).

Ayrıca düzenleme sayfası **yarı yarıya küçüldü**: İlişkiler kutusunun anime
listesi sunucuda ikinci kez basılmıyor, tarayıcıda "Sıradaki Anime"
kutusundan kopyalanıyor. 8.000 kayıtlık bir katalogda ölçüldü: 3,9 MB → 1,9 MB.

## Değişen dosyalar

**Yeni:**

```
files/functions/relation_helpers.php   türler, yön/ters etiket ve kurallar
files/add_anime_relation.php           ilişki ekleme ucu
files/delete_anime_relation.php        ilişki silme ucu
files/migration/1.1.38/upgrade.sql
```

**Değişen:**

```
files/functions.php                  yeni yardımcı dosyanın yüklenmesi
files/edit_anime.php                 "İlişkiler" paneli + sekmeler
files/add_anime.php                  sekmeler
files/anime_details.php              "İlişkili Animeler" bölümü
files/list_settings.php              yedekte dışa aktarım + geri yükleme
files/js/anime_form.js               sekme geçişi, doğrulama, seçenek kopyalama
files/css/series.css                 panel ve bölüm stilleri
files/css/components.css             sekme çubuğu stilleri
files/robots.php                     iki yeni uç arama motorlarına kapalı
files/lang/tr.php, files/lang/en.php 37 yeni metin
files/schema.sql
files/version.txt
```

## Dağıtım notu

- `files/functions.php` ile `files/functions/relation_helpers.php` **birlikte**
  yüklenmelidir. Yükleyici dosyayı çağırıp bulamazsa **her sayfa** çöker.
- `files/edit_anime.php` ve `files/anime_details.php`, `relation_helpers.php`
  olmadan yüklenirse o iki sayfa "undefined function" verir; aynı pakette
  gitmeliler.
- `files/lang/*.php` de aynı pakette gitmelidir, yoksa metin yerine anahtar adı
  görünür.
- `files/css/series.css`, `files/css/components.css` ve `files/js/anime_form.js`
  `files/version.txt` ile birlikte gitmelidir: bağlantılardaki sürüm damgası
  `version.txt`'ten üretilir, eskide kalırsa tarayıcı yeni sayfayı eski stil ve
  eski betikle çizer (sekmeler açılmaz).
- `files/add_anime.php` ve `files/edit_anime.php`, `files/js/anime_form.js`
  olmadan yüklenirse sekme çubuğu hiç görünmez ve form eski hâlindeki gibi tek
  uzun liste olur — bozulmaz ama sürümün yarısı görünmez.
- **Merkez katalog sunucusunda yapılacak bir şey yok.** İlişkiler, tıpkı
  "Sıradaki Anime" ve "Zincir Adı" gibi uygulamaya özeldir: katalog telinde
  yeni alan yok, elle `ALTER` gerekmiyor, `catalog_server/` altında değişen
  dosya yok.
- Migration tek bir tablo ekler ve kendiliğinden koşar.
- **Dağıtım sunucusunda** her zamanki iki adım: yayımlanan `version.txt`
  1.1.38'e çekilmeli ve `updates/1.1.38/anime-tracker-1.1.38.zip` paketi
  yayımlanmalı.

## Sırada ne var

Yol haritasının üçüncü ve son adımı: devam/öncesi ilişkisinin de tabloya
taşınması ve "Sıradaki Anime" alanının emekliye ayrılması. O adım şimdilik
bekliyor, çünkü bugünkü veride **dallanma yok** — bir kaydın iki ayrı devamının
olduğu bir durum henüz ortaya çıkmadı.
#34
Duyurular ve Sürümler / 1.1.37
Last post by hitsumo - Sep 15, 2026, 03:58 PM
# Anime Tracker 1.1.37

**Yayın tarihi:** 2026-09-02

Şema değişikliği yok. Birbirinden bağımsız dört küçük iş: biri arama
motorlarıyla, ikisi yeni dillerin önünü açmakla, biri de dışarıya kendini
tanıtmakla ilgili.

## 1. Boş kayıtlar artık arama motorlarına verilmiyor

Katalog üç yoldan büyüyor ve bunlardan ikisi — offline listenin online'a
aktarılması ve MAL/AniList içe aktarımı — kaydı **ince taslak** olarak açıyor:
başlık ve kimlik var, konu yok, görsel yok. Katalogun büyük çoğunluğu bugün bu
durumda.

Bugüne kadar site haritasının tek filtresi "yetişkin içeriği değil" idi, yani bu
taslakların **hepsi** site haritasına giriyordu; IndexNow eklendiğinden beri aynı
adresler arama motorlarına aktif olarak da bildiriliyordu. Site yakın zamanda
Google, Yandex ve Bing'e tanıtıldığı için bu artık teorik bir sorun değildi.

Bundan sonra bir kayıt, ziyaretçiye **başlık dışında verecek bir şeyi varsa**
duyuruluyor: konu (herhangi bir dilde), görsel ya da kronoloji notu. Bölüm sayısı
veya tarih tek başına yetmiyor — onlar okuyucunun bir arama sonucundan beklediği
içerik değil, künye alanı.

Boş bir kaydın detay sayfası artık `noindex, follow` taşıyor: sayfa indekslenmez
ama **bağlantıları izlenir**, yani aynı serideki dolu kayıtlar oradan
keşfedilmeye devam eder.

**Hiçbir kayıt silinmez ya da gizlenmez.** Site içinde her şey eskisi gibi
görünür ve gezilir; değişen tek şey arama motorlarına ne bildirildiği. Bir
taslağa konu ya da görsel eklediğiniz anda kayıt kendiliğinden yeniden
indekslenebilir hâle gelir.

Kural site haritası, IndexNow ve detay sayfası tarafından **tek bir yerden**
okunuyor; üçünün ayrışması mümkün değil.

Self-host kurulumlar etkilenmez — o modda zaten her sayfa indekslemeye kapalı.

## 2. Eksik çeviri artık İngilizceye düşüyor

Arayüz metinleri sırayla aranır: seçili dil, sonra yedek dil, sonra anahtarın
kendisi. Yedek şimdiye kadar Türkçeydi.

İki dil varken bunun bir önemi yoktu. Üçüncü bir dil eklenince oluyor:
çevrilmemiş bir metinde Endonezce konuşan bir ziyaretçiye Türkçe düşmek,
İngilizce düşmekten belirgin biçimde kötü.

Bu aynı zamanda **dil katkısını mümkün kılan şey**: bir çevirmenin sözlüğün
tamamını bitirmesi gerekmiyor. Eksik bırakılan her anahtar İngilizceye düşer,
ekranda bozuk bir şey görünmez, dosya parça parça tamamlanabilir.

Yönetici arayüzünde de aynı değişiklik yapıldı.

## 3. AniList istekleri kendini tanıtıyor

Giden isteklere `AnimeTracker/<sürüm> (+depo adresi)` kimliği eklendi.

Bu bir uyum değişikliği değil — içe aktarım zaten yalnızca **kullanıcının kendi
listesini** çekiyor, katalog taramıyor ve künye verisi toplamıyor. Sebep, fark
edildiğinde ne olacağı: kimliksiz bir istek karşı taraf için tanınmayan bir
bottur ve sessizce engellenir; kimlikli bir istek önce bir e-posta getirir.

AnimeSchedule'a eklenmedi, o istekler zaten anahtarla imzalı.

## 4. README'ye "yeni dil ekleme" bölümü

Üç adım: `lang/en.php`'yi kopyala, değerleri çevir (anahtarlara dokunma),
izinli diller listesine kodu ekle.

Bir uyarıyla birlikte: çoğu metinde ufak bir hata zararsızdır, ama **sonucu
olan** metinler bir insan gözünden geçmeli — 18+ uyarısı, silme onayları,
spoiler kapısı ve yedekleme/geri yükleme uyarıları. Yanlış çevrilirse sonuç
yalnızca "tuhaf" olmaz; kullanıcı veri kaybedebilir ya da spoiler görebilir.

## Değişen dosyalar

**Yeni:**

```
files/migration/1.1.37/upgrade.sql   (şemasız; sürüm damgası + gerekçe kaydı)
```

**Değişen:**

```
files/functions/seo_helpers.php          indekslenebilirlik kuralı (tek yer)
files/anime_details.php                  ince sayfaya noindex, follow
files/functions/i18n_helpers.php         yedek dil TR -> EN
files/functions/anilist_import_helpers.php   User-Agent
README.md                                yeni dil ekleme (TR + EN)
files/version.txt
```

## Dağıtım notu

- `files/anime_details.php` ile `files/functions/seo_helpers.php` **birlikte**
  yüklenmelidir: sayfa yeni bir yardımcı fonksiyon çağırıyor, eski yardımcı
  dosyada o fonksiyon yok. Diğer iki işin dosyaları birbirinden bağımsızdır.
- **Merkez katalog sunucusunda yapılacak bir şey yok.** Katalog telinde yeni
  alan yok, elle `ALTER` gerekmiyor, `catalog_server/` altındaki hiçbir dosya
  değişmedi.
- Migration şema değiştirmez, yalnızca sürüm damgasını taşır ve kendiliğinden
  koşar.
- **Dağıtım sunucusunda** her zamanki iki adım: yayımlanan `version.txt`
  1.1.37'ye çekilmeli ve `updates/1.1.37/anime-tracker-1.1.37.zip` paketi
  yayımlanmalı.
- Yükleme sonrası arama motorlarının site haritasını yeniden okuması gerekir;
  hâlihazırda indekslenmiş boş sayfaların düşmesi zaman alır.
#35
Duyurular ve Sürümler / 1.1.36
Last post by hitsumo - Sep 15, 2026, 03:57 PM
# Anime Tracker 1.1.36

**Yayın tarihi:** 2026-09-02

Bu sürüm zincire bir **ad** veriyor — ve bununla birlikte "bu iki kayıt aynı
hikâyenin iki ayrı anlatımı" diyebilmenizi sağlıyor.

## Sorun

1.1.25'ten beri bir seri adı altında birden çok zincir olabiliyordu, ama
zincirin kendisi bir şey değildi: yalnızca "Sıradaki Anime" bağlantılarını
yürüyünce ortaya çıkan geçici bir kümeydi. Bunun üç sonucu vardı.

**Zincir adlandırılamıyordu.** Sekmeler "Diğer Zincir 1..N" diyordu; hangisinin
ne olduğunu ancak içine bakınca anlıyordunuz.

**"Bunlar ayrı hatlar" denemiyordu.** Elinizde yalnızca "birbirine bağlı mı"
vardı. İki gerçek örnek:

- *Space Adventure Cobra (1982)* filmi, AniDB'ye göre *Space Cobra* TV
  dizisinin **alternatif versiyonu** — devamı değil. İkisi de bağlanmamıştı,
  dolayısıyla ikisi de "1 anime" diyen bir zincir gösteriyordu ve hiçbir
  sekme çıkmıyordu.
- *Sailor Moon Crystal* (yine alternatif versiyon) ise tam tersi: 90'lar
  zincirinin **içine**, Sailor Stars'ın arkasına bağlanmıştı. Zaman çizelgesi
  "Sailor Stars'tan sonra Crystal" diyordu ve spoiler kapısı, Crystal'ı açan
  kişiye 90'lar serisinin sekiz kaydını "izlenmemiş öncül" olarak sayıyordu.

**Tek kayıtlık bir hat ifade edilemiyordu.** Hiçbir yere bağlanmamış tek kayıt
zincir sayılmıyordu — bu kural doğruydu (yoksa seri adını paylaşan her bağımsız
film ayrı bir sekme üretirdi), ama Cobra'nın filmi gibi **bilerek** ayrı duran
bir kaydı da görünmez kılıyordu.

## Çözüm: üyelik addan, sıra bağdan

Düzenleme ve ekleme ekranlarına yeni bir alan geldi: **Zincir Adı
(opsiyonel)**. Mevcut adlar otomatik önerilir.

| Alan | Neyi söyler |
| --- | --- |
| Seri Adı | Hangi seri |
| **Zincir Adı** | **Serinin içinde hangi hat** |
| Sıradaki Anime | O hattaki sıra |

Aynı adı taşıyan kayıtlar tek zincir sayılır ve seri kronolojisinde **kendi
adıyla** bir sekme alır. "Diğer Zincir 1" yerine "Crystal" yazar.

Sailor Moon'da yapmanız gereken: Sailor Stars'ın "Sıradaki Anime" bağını
kaldırmak ve iki hatta ad vermek. Sonuç:

```
[ 90'lar Anime ] [ Crystal ] [ Diğer Zincir 1 ] [ Yayın Tarihi ]
```

Cobra'da ise tek bağ kurmadan, yalnızca ad vererek:

```
[ Alternatif Versiyon (Film) ] [ 1982 TV Serisi ] [ Yayın Tarihi ]
```

## Adı olan tek kayıt da zincirdir

Adsız tek bir kayıt hâlâ zincir sayılmaz — o yalnızca bir kayıttır. Ama **adı
olan** tek kayıt bilinçli bir beyandır: "bu kayıt kendi hattıdır." Cobra'nın
1982 filmi tam olarak budur.

## Spoiler kapısı da sınırda durur

Kapı artık yalnızca **aynı hattaki** önceki halkalara bakar. Crystal'ı açan
kişiye 90'lar serisi bir daha "önce izlemelisin" diye sunulmaz.

Bir ayrım bilinçli: adlı bir hattın bağlanmamış üyesi **listede görünür**
(yayın tarihine göre sona eklenir), ama spoiler kapısı onu **öncül saymaz**.
Listede bir kaydı göstermek zararsızdır; "şunu önce izlemelisin" demek ise bir
iddiadır ve yalnızca sizin elle kurduğunuz bağa dayanmalıdır. Girilmemiş bir
bağı tarihten uydurmak, uyarıyı tahmine çevirirdi.

## Sekme sırası değişti

Zincir sekmeleri artık bir arada duruyor, **"Yayın Tarihi" sona geçti**.
Adlar gelince araya giren bir sekme okumayı bölüyordu. Adresler ve davranış
aynı; değişen yalnızca sıra.

## Zincir adı vermezseniz hiçbir şey değişmez

1.1.36 öncesi her kaydın zincir adı boştur ve boş ile boş "aynı" sayılır — yani
hiçbir yürüyüş kısalmaz, zincir keşfi ve spoiler kapısı 1.1.35 ile **birebir
aynı** sonucu verir. Bu iddia değil ölçümdür: 1.1.35 algoritması testte satır
satır korundu ve iki sürümün çıktısı aynı veri üzerinde karşılaştırıldı.

## Değişen dosyalar

**Yeni:**

```
files/migration/1.1.36/upgrade.sql
```

**Değişen:**

```
files/functions/series_helpers.php   zincirin tek kuralı (chain_same) + üyelik
files/series_timeline.php            sekme etiketleri ve sırası
files/add_anime.php                  Zincir Adı alanı
files/edit_anime.php                 Zincir Adı alanı
files/list_settings.php              JSON geri yüklemede zincir adı taşınır
files/lang/tr.php, files/lang/en.php form metinleri + yardım sayfası
files/schema.sql
files/version.txt
```

## Dağıtım notu

- `files/functions/series_helpers.php` ile `files/series_timeline.php`
  **birlikte** yüklenmelidir: sayfa `chain_name_norm()` çağırıyor, eski
  yardımcı dosyada o fonksiyon yok.
- `files/lang/*.php` de aynı pakette gitmelidir, yoksa yeni alanın etiketi
  yerine anahtar adı görünür.
- **Merkez katalog sunucusunda yapılacak bir şey yok.** Zincir adı, tıpkı
  "Sıradaki Anime" gibi uygulamaya özeldir: katalog telinde yeni alan yok,
  elle `ALTER` gerekmiyor, `catalog_server/` altında değişen dosya yok. Katalog
  senkronu zincir adını **ezmez**.
- Migration tek bir kolon ve bir index ekler, kendiliğinden koşar.
- **Dağıtım sunucusunda** her zamanki iki adım: yayımlanan `version.txt`
  1.1.36'ya çekilmeli ve `updates/1.1.36/anime-tracker-1.1.36.zip` paketi
  yayımlanmalı.

## Sırada ne var

Zincir adı, bir hattın **ne olduğunu** yazmanızı sağlıyor ama ilişkinin
**türünü** hâlâ bilmiyor: "Alternatif Versiyon" yazdığınızda insan anlar,
uygulama anlamaz. Bir sonraki sürüm bunu veri hâline getirecek (sequel,
alternative version, side story, summary...), AniDB'nin ayrımına uyumlu şekilde.
#36
Duyurular ve Sürümler / 1.1.35
Last post by hitsumo - Sep 15, 2026, 03:57 PM
# Anime Tracker 1.1.35

**Yayın tarihi:** 2026-08-31

Bu sürüm tek bir soruyu çözer: **katalogdan sildiğin bir anime neden bir
sonraki içe aktarımda geri geliyor?**

Katalog sahibi kataloğa tohumu açık bir AniList listesinden atıyor, sonra
elle ayıklıyor — AniDB karşılığı olmayan kayıtları siliyor. Bu iş akışı iki
yerden birden bozuluyordu ve aslında ikisi aynı kusurun iki yüzü:

1. **Ne sildiğin hiçbir yerde yazmıyordu.** Ayıklama kararı yalnızca senin
  aklındaydı; silinen kayıt arkasında iz bırakmıyordu. İki hafta sonra
  "bunu bilerek mi çıkarmıştım, yoksa hiç gelmedi mi" sorusunun cevabı
  yoktu.
 
2. **Bir sonraki içe aktarım hepsini geri getiriyordu.** İçe aktarmada bir
  satır "eşleşmedi" sayılır *çünkü* katalogda öyle bir kayıt yoktur — ki
  silmek tam olarak o durumu üretir. Yani silmek, animeyi bir sonraki içe
  aktarmanın taze adayı hâline getiriyordu.
 

Aynı kusurun üçüncü bir yüzü daha vardı: katalog önerilerindeki
tekilleştirme yalnızca bekleyen satırlara bakıyordu. Yani **reddettiğin bir
öneri de** her içe aktarımda yeniden açılıyordu; reddetmek "bir daha sorma"
demiyordu.

## Kara liste

Artık katalogdan bir anime sildiğinizde kimliği bir listeye yazılıyor. Bu
listedeki animeler AniList ve MyAnimeList içe aktarımlarında katalog
önerisi olarak **açılmıyor**.

Liste iki işi birden görüyor: hem *ne sildiğinin defteri*, hem de *geri
gelmesini engelleyen kapı*. Yönetici panelinde yeni bir kart var — **İçe
Aktarma Kara Listesi**.

Sayfada yapabilecekleriniz:

- Silinen animeleri tarih sırasıyla görmek (kim sildi, MAL / AniDB kimliği,
  varsa not)
- Başlığa ya da kimliğe göre aramak
- Fikir değiştirdiğinizde bir kaydı **listeden çıkarmak** — o anime bir
  sonraki içe aktarımda yeniden gelebilir
- Hiç eklenmemiş bir animeyi baştan **elle engellemek** (reddettiğiniz bir
  öneri için de bunu yapabilirsiniz)

## İçe aktarma önizlemesinde ne görünür

Önizleme özetinin altına yeni bir satır geliyor:

> Bunlardan 2 tanesi yönetici kara listesinde; içe aktarımda atlanacak.

İçe aktarma bittiğinde de sonuç mesajının sonuna ekleniyor:

> 2 anime yönetici kara listesinde olduğu için atlandı.

Kara liste boşsa ya da hiçbir kayıt engellenmediyse bu satırların ikisi de
hiç görünmez.

## Kara liste neyi engellemez

**Katalogda gerçekten duran bir anime** kara listede olsa bile üyenin
listesine eklenebilir. Kara liste "katalogda olmasın" demektir, "kimse
izleyemesin" demek değil. Kapı yalnızca *eşleşmeyen* satırlarda durur.

Bu durum pratikte yalnızca silinip sonra elle geri eklenmiş bir animede
oluşur; yönetici sayfası öyle bir kaydı **"Katalogda var"** rozetiyle
işaretler, temizleyebilesiniz diye.

## Eşleşme başlığa göre değil kimliğe göre

Liste `mal_id` ve `anidb_id` üzerinden eşleşir — kataloğun zaten anahtar
kabul ettiği kararlı kimlikler. **Başlığa göre eşleşmez:** birbiriyle
ilgisiz iki yapım aynı başlığı fazlasıyla sık paylaşır ve eski bir silmenin
adı yüzünden meşru bir animeyi sessizce düşüren bir içe aktarma, çözdüğü
sorundan daha kötü olurdu.

Kimliği hiç olmayan bir animeyi sildiğinizde kayıt **yine de tutulur** ama
hiçbir şeyi engelleyemez — eşleştirilecek anahtar yoktur. Sayfa bunu
**"Engellemez"** rozetiyle açıkça söyler, öyle değilmiş gibi yapmaz. Elle
eklerken ise en az bir kimlik zorunludur.

## Tek kullanıcılı kurulumda hiçbir şey değişmez

Kara liste **yalnızca çok kullanıcılı (online) modda** etkindir. Tek
kullanıcılı bir kurulumun paylaşılan kataloğu ve küratörü yoktur; sahibinin
silmeleri kişiseldir ve içe aktarması kendi listesinde ne varsa getirmeye
devam etmelidir.

Böyle bir kurulumda: silme hiçbir kayıt tutmaz, içe aktarma hiçbir şeyi
engellemez, yeni sayfa "bu özellik burada etkin değil" der. Kataloğu
senkronlayan bir kullanıcı da küratörün neyi kara listeye aldığından
etkilenmez — liste merkeze **gönderilmez**.

## Değişen dosyalar

**Yeni:**

```
files/functions/blacklist_helpers.php   (listenin tek kural yeri)
files/admin/admin_blacklist.php         (yönetici sayfası)
files/migration/1.1.35/upgrade.sql
```

**Değişen:**

```
files/functions.php                     (yeni yardımcı dosyanın yüklenmesi)
files/index.php                         (silme kaydı yazar)
files/list_settings.php                 (AniList + MAL içe aktarma kapısı)
files/admin/admin.php                   (yeni kart)
files/lang/tr.php, files/lang/en.php    (içe aktarma bildirimleri)
files/lang/admin_tr.php, admin_en.php   (yönetici sayfası metinleri)
files/schema.sql
files/version.txt
```

## Dağıtım notu

- `files/functions.php` ile `files/functions/blacklist_helpers.php`
  **birlikte** yüklenmelidir. Yükleyici satırı olmadan dosya hiç okunmaz ve
  silme ile içe aktarma sayfaları açılmaz.
- `files/lang/*.php` dosyaları `files/admin/admin_blacklist.php` ve
  `files/list_settings.php` ile birlikte gitmelidir; yoksa metin yerine
  anahtar adı görünür.
- **Merkez katalog sunucusunda yapılacak bir şey yok.** Katalog telinde yeni
  alan yok, elle `ALTER` gerekmiyor, `catalog_server/` altındaki hiçbir dosya
  değişmedi.
- Migration otomatik koşar ve tek bir tablo oluşturur. Dosyalar yüklenip
  migration henüz koşmadıysa uygulama **çökmez**: silme çalışmaya devam eder
  (kayıt tutulmaz, sunucu günlüğüne yazılır), içe aktarma hiçbir şeyi
  engellemez ve yönetici sayfası "tablo okunamadı" der. Bir sonraki sayfa
  açılışında migration kendiliğinden koşar ve her şey yerine oturur.
- **Dağıtım sunucusunda** iki işlevsel adım her zamanki gibi: yayımlanan
  `version.txt` 1.1.35'e çekilmeli — yoksa "Güncelleme Denetle" hâlâ
  1.1.34'ü son sürüm sanar — ve `updates/1.1.35/anime-tracker-1.1.35.zip`
  paketi yayımlanmalı, yoksa "Güncelle" düğmesi indirme adresinde 404 alır.
#37
Duyurular ve Sürümler / 1.1.34
Last post by hitsumo - Sep 15, 2026, 03:55 PM
# Anime Tracker 1.1.34

**Yayın tarihi:** 2026-08-26

Küçük bir sürüm; şema değişikliği yok. Üç ayrı iş var, ikisi asıl işten
sonra eklendi:

1. **Anime eklerken izleme durumu seçmek artık zorunlu değil** — asıl konu,
  hemen aşağıda.
2. **Spoiler kapısı sayfaya uyduruldu** — 1.1.33'te gelen kutu kalktı.
3. **Kurulum yedeğinin adı** — yalnızca Windows `.exe` kurulumunu ilgilendirir.

## Sorun

Anime ekleme formunda "İzleme Durumu" listesi açılışta **"Seçiniz"**
satırında duruyordu ve alan zorunlu işaretliydi. Tarayıcı bu satırı geçerli
bir cevap saymadığı için, izleme durumu seçilmeden **anime kaydedilemiyordu**;
form gönderilmiyor, ekranda "bu alanı doldurun" uyarısı çıkıyordu.

Oysa izleme durumunun boş kalması bu alanda geçerli bir durum. Katalogdan içe
aktarılan animeler tam olarak böyle, izleme durumu boş olarak listeye
giriyor; liste ve detay ekranları o kayıtları "Seçim Yapılmamış" diye
gösteriyor. Yani veri tarafı bu durumu zaten destekliyordu, yalnızca **elle
ekleme** onu yasaklıyordu.

Çıkış yolu aslında vardı: listenin **en altındaki** "Seçim Yapılmamış"
seçeneği. Ama tepedeki "Seçiniz" ile neredeyse aynı anlama geldiği için
pratikte görünmüyordu — iki satır da "henüz seçmedim" diyordu, biri kabul
ediliyor, öteki reddediliyordu.

## Ne değişti

Boş "Seçiniz" satırı kaldırıldı. **"Seçim Yapılmamış" artık listenin başında
ve açılışta seçili.**

Yani anime eklerken izleme durumuna hiç dokunmazsanız anime izleme durumu boş
olarak kaydediliyor. Listede "Seçim Yapılmamış" görünüyor, sonradan detay ya
da düzenleme ekranından istediğiniz zaman verilebiliyor. Bir durum seçmek
isteyenler için değişen bir şey yok, seçenekler aynı.

| Önce | Sonra |
| --- | --- |
| Seçiniz *(seçili, kaydettirmiyor)* | **Seçim Yapılmamış** *(seçili, kaydediyor)* |
| İzlendi | İzlendi |
| İzleniyor | İzleniyor |
| İzlenme Planlandı | İzlenme Planlandı |
| İzleme Ertelendi | İzleme Ertelendi |
| İzleme Bırakıldı | İzleme Bırakıldı |
| Seçim Yapılmamış | —   |

## Düzenleme ekranı

Anime düzenleme ekranındaki aynı liste de aynı sıraya getirildi. Orada
davranış zaten doğruydu — izleme durumu boş olan bir animeyi açtığınızda
"Seçim Yapılmamış" seçili geliyordu, o yüzden düzenlemede kimse takılmıyordu.
Değişen yalnızca sıra ve işe yaramayan "Seçiniz" satırının kalkması; iki ekran
artık aynı listeyi aynı sırada gösteriyor.

## Değişmeyenler

- **Yayın Durumu hâlâ zorunlu.** O alan animenin kendi bilgisi, kişisel bir
  tercih değil: her animenin bir yayın durumu vardır, boş bırakmak bir seçim
  değil eksik kayıttır. MyAnimeList ve AniDB bağlantılarının zorunluluğu da
  yerinde duruyor.
- **Var olan kayıtlara dokunulmadı.** Bugüne kadar seçtiğiniz izleme
  durumları olduğu gibi duruyor; toplu bir düzeltme yapılmadı.
- **Kişisel Konu, notlar, izleme tarihleri** ve geri kalan her şey aynı.

## Spoiler kapısı sayfaya uyduruldu

İkinci iş, yine ayrı bir konu. 1.1.33'te gelen spoiler kapısı, kesikli turuncu
çerçeve + krem zemin + iç boşluktan oluşan bir **kutu** içindeydi. Anime detay
sayfası ise düz satır düzenindedir: solda etiket, sağda değer, altında ince gri
bir ayraç. Kutu o düzenin içinde yamalı duruyordu — izlediğiniz "1. sezon" sade
bir satırken, izlemediğiniz "2. sezon" renkli bir pano gibi görünüyordu.

Artık kapı da sade:

- **Çerçeve, krem zemin ve iç boşluk kalktı.**
- **Uyarı metni**, sayfanın öteki küçük notlarıyla (örneğin çeviri notu) aynı
  gri ve aynı boyutta.
- **"Yine de okumak istiyorum" / "Konuyu gizle"** artık dolgulu turuncu bir
  düğme değil, düz mavi bir metin — **altı çizgisiz**. Üzerine gelince rengi
  koyulaşıyor. Cümle içinde geçen bağlantılarda alt çizgi gerekli, çünkü düz
  metinden başka türlü ayrılmazlar; burada etiket kendi satırında tek başına
  duruyor, renk zaten tıklanabilir olduğunu söylüyor.

Kapının **işleyişi değişmedi**: aynı kural, aynı yerler, aynı tercih. Yalnızca
görünümü sayfanın geri kalanına uyduruldu. Öneriler → Sürpriz kartındaki
tanıtım metni de aynı sadeleşmeden yararlanıyor.

## Kurulum yedeğinin adı

Üçüncü iş, öncekilerle hiç ilgisi yok. Windows kurulum `.exe`'si, üzerine
kurulum yapılan bir makinede dosyaları değiştirmeden önce masaüstüne bir
veritabanı yedeği bırakır. O yedeğin adındaki tarih, `.exe` **derlenirken**
elle yazılan sabit bir değerden geliyordu.

İki sorun vardı. Birincisi kozmetik: değer elle güncellenmediği için ad,
kurulumun yapıldığı günü değil, güncellemenin unutulduğu günü gösteriyordu.
İkincisi asıl olan: ad sabit olduğu için **aynı `.exe` ile ikinci kez kurulum
yapıldığında birinci kurulumun yedeği sessizce üzerine yazılıyordu.** Yedek tam
da "kurulum ters giderse buradan dön" diye alınıyor; dönülecek noktanın
kaybolması onu amacından ediyordu.

Artık damga derleme anında değil, **kurulum anında** üretiliyor ve saati de
içeriyor:

```
at_install_backup_2026-08-26_182630.sql
```

Aynı gün yapılan iki kurulum bile ayrı dosyalara yazıyor. Elle güncellenmesi
gereken bir değer kalmadı.

Bu değişiklik yalnızca `.exe` kurulumunu ilgilendirir; sunucudaki uygulama
dosyalarıyla ve güncelleme paketiyle ilgisi yoktur.

## Değişen dosyalar

**Yeni:**

```
files/migration/1.1.34/upgrade.sql
```

**Değişen:**

```
files/add_anime.php    izleme durumu listesi + boş değerin boş kabul edilmesi
files/edit_anime.php   aynı liste düzeni
files/css/base.css     spoiler kapısı: kutu kaldırıldı, düğmeler sade
                       mavi metin (altı çizgisiz)
files/version.txt
installer.nsi          kurulum yedeğinin adı (yalnızca .exe derlemesi)
```

## Dağıtım notu

- Veritabanı şeması değişmedi; `files/migration/1.1.34/upgrade.sql` yalnızca
  sürüm damgasıdır.
- **Sunucuya giden dosyalar** (`installer.nsi` gitmez, `files/` ağacının
  dışındadır): `files/add_anime.php`, `files/edit_anime.php`,
  `files/css/base.css`, `files/version.txt` ve yeni
  `files/migration/1.1.34/` klasörü.
- Dosyaların birbirine **kod** bağımlılığı yok: biri eskide kalırsa yalnızca
  kendi sayfası eski davranışla çalışır, hiçbir sayfa bozulmaz. Yeni fonksiyon,
  yeni yardımcı ya da yeni dil anahtarı olmadığı için "eski dosya yeni
  fonksiyonu çağırır" riski bu sürümde yok.
- **Tek istisna:** `files/css/base.css` ile `files/version.txt` **birlikte**
  gitmelidir. Stil adreslerindeki sürüm damgası `version.txt`'ten üretilir;
  sürüm eskide kalırsa tarayıcı damgayı aynı görür ve önbellekteki eski stili
  kullanmaya devam eder, yani kapı hâlâ kutulu görünebilir. Sıra önemli değil,
  birlikte gitmeleri yeterli. **1.1.33 atlanıp doğrudan bu sürüme geçiliyorsa** ayrıca bir şey
  yapmaya gerek yok: `base.css`, 1.1.33'te gelen spoiler kurallarını da taşır —
  tek kopya iki sürümü birden getirir.
- Merkez katalog sunucusunda yapılacak bir şey yok; izleme durumu kişisel bir
  alandır, katalog telinde yer almaz.
- **Dağıtım sunucusunda** her zamanki iki adım: yayımlanan `version.txt`
  1.1.34'e çekilmeli — yoksa "Güncelleme Denetle" hâlâ 1.1.33'ü son sürüm
  sanar — ve `updates/1.1.34/anime-tracker-1.1.34.zip` paketi yayımlanmalı,
  yoksa "Güncelle" düğmesi indirme adresinde 404 alır.
#38
Duyurular ve Sürümler / 1.1.33
Last post by hitsumo - Sep 15, 2026, 03:54 PM
# Anime Tracker 1.1.33

**Yayın tarihi:** 2026-08-25

Bu sürümde iki iş var. Birincisi asıl konu: **devam sezonunun konusu, önceki
sezonu ele veriyor.** İkincisi, yardım sayfalarının büyümesi — en altta.

Bir serinin ikinci ve sonraki halkalarının özeti neredeyse her zaman kendinden
öncekinin sonunu anlatır. "X öldükten sonra geriye kalan ekip..." diye başlayan
bir konu, o animeyi henüz izlememiş kişiye hiçbir şey anlatmaz ama bir önceki
sezonu baştan sona spoiler'lar. Kullanıcı devam sezonunun sayfasını yalnızca
"kaç bölüm" diye açsa bile konu ekranda duruyordu.

Artık böyle bir sayfada konu doğrudan basılmıyor; **"Yine de okumak
istiyorum"** düğmesinin arkasında bekliyor.

## Nasıl görünüyor

Zincirde bu animeden önce gelen halkalardan biri bile izlenmemişse "Konu"
satırında metin yerine şu kutu çıkıyor:

> Seri S2 ve zincirdeki 1 kayıt daha henüz izlenmedi — bu konu önceki
> sezonları ele verebilir.
>
> **[ Yine de okumak istiyorum ]**

Düğmeye basıldığında konu yerinde açılıyor, düğme "Konuyu gizle"ye dönüşüyor.
Yalnızca tek bir halka eksikse metin de tekil oluyor: "Seri S2 henüz izlenmedi
— bu konu önceki sezonu ele verebilir."

Önceki halkaların **hepsi** izlendiyse ortada düğme de yok; sayfa 1.1.32'deki
gibi görünüyor.

## Kural

| Durum | Sonuç |
| --- | --- |
| Zincirde önceki halkaların hepsi izlendi | Konu doğrudan görünür |
| Önceki halkalardan biri izlenmedi | Konu düğmenin arkasında |
| Önceki halka **yarım** izlendi ("İzleniyor") | Konu düğmenin arkasında |
| Bu animeyi izliyor / bitirdiysen / bıraktıysan | Konu doğrudan görünür |
| Zincirde hiç yer almayan bağımsız kayıt | Konu doğrudan görünür |

Üç noktası bilinçli seçildi:

**Yalnız bir önceki halkaya değil, zincirdeki tüm öncekilere bakılıyor.**
S3'ün sayfasında S2 izlenmiş ama S1 atlanmışsa konu yine de S1'i ele
verebilir; "yalnızca en yakın halkaya bak" kuralı o kişiyi korumazdı.

**Yarım izlenen sezon izlenmiş sayılmıyor.** Bıraktığın yerden sonrasını
anlatan bir özet de spoiler'dır.

**Başladığın animede kapı kurulmuyor.** İzlemekte olduğun (ya da bitirdiğin,
ertelediğin, bıraktığın) bir animenin konusunda senin için spoiler yoktur —
önceki sezonu atlamış olsan bile onu zaten bu animeyi izlerken öğrendin.

## Nerede geçerli

- **Anime detay sayfası** — "Konu" satırı.
- **Öneriler → Sürpriz** — kartın 200 karakterlik tanıtım metni. Bu olmasaydı
  koruma delik olurdu: detay sayfası konuyu gizlerken sürpriz kartı aynı
  metnin ilk cümlelerini basardı, ki spoiler cümlesi genelde özetin ilk
  cümlesidir.

**Kişisel Konu kapının dışında.** O metni sen yazıyorsun ve yalnızca sen
görüyorsun; kişiyi kendi notundan korumanın anlamı yok.

## Giriş yapmamış ziyaretçide

Anonim ziyaretçinin kişisel izleme verisi yok, yani hiçbir şey izlenmiş
sayılmıyor ve devam halkalarının konusu onda da düğmenin arkasında açılıyor.
Katalogu ilk kez gezen kişi tam da korunması gereken kişi; maliyeti tek tık.

## Kapatılabilir

**Liste Ayarları → Spoiler Koruması** altında bir kutucuk var; varsayılan
olarak **açık**. Kapatıldığında hiç düğme çıkmıyor, konu her zaman doğrudan
görünüyor. Tercih kişiye özel, yalnızca kendi hesabını etkiliyor.

## Küçük notlar

- Kutu tarayıcının kendi açılır bölümü (`<details>`), **JavaScript
  kullanmıyor**: betikler kapalıyken de açılıyor, klavyeyle geziliyor ve
  açmak yeni bir istek atmıyor — metin zaten sayfayla geliyor.
- Detay sayfasının arama motorlarına verdiği açıklama değişmedi. O açıklama
  tüm dünyaya yayımlanan tek bir metin, ziyaretçiye göre değişmez.
- Ana liste sayfası zaten hiç konu basmıyor, orada bir değişiklik yok.

## Yardım sayfaları büyüdü

Aynı sürümde ikinci bir iş: yardım baştan tarandı ve **yazılmış ama hiç
belgelenmemiş** özellikler yazıldı. Dört yeni bölüm eklendi:

- **Liste, Arama ve Filtreler** — Genel Liste ile Kişisel Liste arasındaki
  fark ve varsayılan sekme tercihi, arama kutusunun neyi taradığı, altı
  filtre (tür, izleme durumu, yayın durumu, harf, yıl, ülke), duygu
  filtresinin nereden geldiği, "Sayfada Göster" ve sıralama okları, artı
  "Son Güncellenenler" sayfası.
- **Kişisel Tercihler** — Liste Ayarları'ndaki yedi tercih tek listede;
  arayüz dili ve yetişkin içerik (+18) ayrıntılı anlatıldı.
- **Liste Taşıma ve İçe Aktarma** — JSON yedeği alma ve geri yükleme,
  MyAnimeList dosyası aktarma, AniList kullanıcı adıyla aktarma (iki türü
  ve önizleme adımı), "Listeyi Temizle"nin ne kadar geri alınamaz olduğu.
- **Üyelik ve Katkı** — giriş, kayıt, davetiye talebi, hesap sayfası, dört
  rolün ne yapabildiği, eklediğiniz animenin onay kuyruğuna düşmesi ve
  "Düzeltme Öner" kutusu.

"Seriler ve Bölüm Bilgisi" sayfasına üç bölüm girdi: **Seri Kronolojisi
sayfası** (sekmeler ve "Diğer Zincir" başlıkları), **Spoiler Koruması**
(yukarıdaki kuralın tamamı) ve **Yayın Bilgileri ve Geri Sayım**.

Ayrıca birkaç düzeltme: `+/-` butonlarının detay sayfasında da olduğu
yazıldı, kişisel alanlar listesine izlemeye başlama/bitirme tarihleri ve
katalog alanları listesine Ülke eklendi, cümle etiketlerini "yönetici"
değil küratörlerin atadığı düzeltildi, güncelleme bölümünün yalnızca
kişisel kurulumda göründüğü not edildi ve hiçbir yere gitmeyen bir iç
bağlantı onarıldı.

## Değişen dosyalar

**Yeni:**

```
files/set_spoiler_pref.php
files/help/help_list.php
files/help/help_prefs.php
files/help/help_transfer.php
files/help/help_account.php
files/migration/1.1.33/upgrade.sql
```

**Değişen:**

```
files/functions/series_helpers.php   (zincirin geriye yürünmesi + kapı)
files/anime_details.php              (Konu satırı)
files/recommendations.php            (Sürpriz kartının tanıtımı)
files/list_settings.php              (Spoiler Koruması kutucuğu)
files/css/base.css                   (kutunun görünümü)
files/help.php                       (içindekiler: dört yeni grup)
files/help/help_series.php           (üç yeni bölüm)
files/lang/tr.php, files/lang/en.php (128'er yeni metin + düzeltmeler)
files/version.txt
```

## Dağıtım notu

- `files/functions/series_helpers.php` ile üç sayfa (`anime_details.php`,
  `recommendations.php`, `list_settings.php`) **birlikte** yüklenmelidir.
  Yardımcı dosya eskide kalırsa sayfalar var olmayan bir fonksiyonu çağırır ve
  açılmaz.
- `files/css/base.css` eskide kalırsa kapı **çalışır** ama çirkin görünür
  (düz metin bir açılır satır olur); işlevsel kayıp yok.
- Dil dosyaları eskide kalırsa uyarı metni yerine anahtar adı görünür.
- `files/set_spoiler_pref.php` eksik kalırsa kapı yine çalışır, yalnızca Liste
  Ayarları'ndaki kutucuk 404 verir.
- `files/help.php` ile dört yeni yardım sayfası **birlikte** yüklenmelidir;
  içindekiler onlara bağlantı verir. Yardım tarafının eksik kalması
  uygulamanın geri kalanını etkilemez.
- Merkez katalog sunucusunda yapılacak bir şey yok; şema değişmedi, katalog
  teline dokunulmadı.
- **Dağıtım sunucusunda** iki işlevsel adım her zamanki gibi: yayımlanan
  `version.txt` 1.1.33'e çekilmeli — yoksa "Güncelleme Denetle" hâlâ 1.1.32'yi
  son sürüm sanar — ve `updates/1.1.33/anime-tracker-1.1.33.zip` paketi
  yayımlanmalı, yoksa "Güncelle" düğmesi indirme adresinde 404 alır.
#39
Duyurular ve Sürümler / 1.1.32
Last post by hitsumo - Sep 15, 2026, 03:54 PM
# Anime Tracker 1.1.32

**Yayın tarihi:** 2026-08-24

Bu sürüm tek bir soruyu çözer: **bir sayfa değiştiğinde arama motoru bunu ne
zaman öğrenir?**

1.1.30 siteye bir sitemap verdi. Sitemap "burada neler var" sorusunu
cevaplar ve tarayıcı onu kendi takvimiyle okur — günler, bazen haftalar.
Yeni eklenen bir animenin adresi o okumaya kadar bilinmez; silinen bir adres
de tarayıcı tekrar uğrayana kadar arama sonuçlarında durur.

**IndexNow** öteki soruyu cevaplar: *şimdi ne değişti?* Bing ile Yandex'in
ortak kullandığı bir bildirim protokolü; tek bir uca haber verirsin, katılan
motorlar paylaşır. Google katılmaz — bu yüzden IndexNow sitemap'in yerine
geçmez, yanına eklenir.

## Ekranda hiçbir şey değişmedi

Bu sürüm site yöneticisini ilgilendirir, listesini tutan kullanıcıyı değil.
Yeni bir düğme, yeni bir alan, değişen bir sayfa yok. Kendi bilgisayarında
tek kullanıcı olarak çalıştıranlar için ise hiç devreye girmez: giriş
istemeyen bir kurulum zaten "beni dizine ekleme" diyor, adres duyurması
kendisiyle çelişirdi.

## Ne zaman haber verilir

| Yaptığın iş | Duyurulan |
| --- | --- |
| Yeni anime eklemek | Yeni animenin adresleri |
| Var olan animeyi düzenlemek | O animenin adresleri |
| Anime silmek | Silinen adresler (motor uğrar, 404 görür, dizinden düşürür) |
| Kronoloji notu eklemek/değiştirmek/silmek | Etkilenen kronoloji sayfası |
| Üye önerisini onaylamak | Onaylanan animenin adresleri |
| Katalogdan içeri aktarmak | Yalnızca **gerçekten değişen** kayıtlar |

Hangi adreslerin duyurulduğu sitemap'in kuralına bağlıdır — sitemap ne
listeliyorsa o: yetişkin işaretli kayıtlar dışarıda, kronoloji sayfası
yalnız notu olan animede, seri zaman çizelgesi yalnız seriyi temsil eden
kayıtta.

Ana sayfa bilerek dışarıda. Neredeyse her yazmada değişiyor, tarayıcılar
zaten sık uğruyor ve yeni anime kendi detay adresinden keşfediliyor; her
seferinde duyurmak, en az ihtiyacı olan sayfaya bütçe harcamak olurdu.

## Kaydettiğinde bir şey beklemezsin

Akla ilk gelen çözüm — kaydet düğmesine basınca arama motoruna istek atmak —
üç ayrı yerden yanlıştı:

- Kaydetme işlemine üçüncü taraf bir ağ isteği girerdi; uç yavaşlarsa form
  yavaşlamış gibi hissedilirdi.
- Başarısız istek kaybolurdu. Tekrar denemesi yok, adres hiç duyurulmamış
  olurdu.
- 500 satırlık bir içeri aktarma 500 istek atardı; aynı animeyi bir dakikada
  beş kez düzenlemek beş istek atardı — protokolün gönderenlerden
  *yapmamasını* istediği şey tam olarak bu.

Bu yüzden kaydetme sırasında yapılan tek şey küçük bir kayıt: "şu adres
değişti". Gönderimi, saatte bir çalışan ayrı bir görev toplu hâlde yapıyor —
bölüm senkronunda 1.0.19'dan beri kullanılan düzenin aynısı. Aynı sayfa gün
içinde on kez değişse tek satır kalır, tek duyuru gider.

Bunun pratik anlamı: **"şimdi ping atmalı mıyım?" diye düşünmen gereken bir
an yok.** Sen her zamanki gibi kaydediyorsun, gerisi kendiliğinden oluyor.

## Kurulum (bir kez)

Özellik varsayılan olarak **kapalıdır** ve iki satır yapılandırma ister:

1. Anahtarı üret:
 
  ```
  php indexnow_ping.php --genkey
  ```
 
2. Yazdırdığı satırları `config.php`'ye ekle:
 
  ```php
  define('INDEXNOW_KEY', '...');
  define('SITE_URL', 'https://siteadresin');
  ```
 
  `SITE_URL` burada **zorunlu**. Web isteğinde sitenin adresi isteğin
  kendisinden çıkarılabiliyor, ama komut satırında böyle bir bilgi yok;
  olmadan her adres `http://localhost/...` diye üretilir ve reddedilir.
  Betik onsuz çalışmayı reddeder, yanlış adres göndermez.
 
3. `https://siteadresin/<anahtar>.txt` adresinin anahtarı düz metin olarak
  döndürdüğünü kontrol et. (Bu dosya `robots.txt` gibi üretiliyor; diske
  elle bir `.txt` koymana gerek yok.)
 
4. Görevi zamanla — saatte bir yeterli:
 
  ```
  0 * * * * php /yol/indexnow_ping.php >> /var/log/anime_indexnow.log 2>&1
  ```
 

Anahtar tanımlı değilse hiçbir şey kuyruğa yazılmaz, hiçbir istek gitmez ve
uygulamanın geri kalanı etkilenmez.

## Yönetici için dört komut

```
php indexnow_ping.php             bekleyenleri gönder
php indexnow_ping.php --status    yapılandırma + kuyruk raporu, gönderim yok
php indexnow_ping.php --dry-run   sıradaki partinin adreslerini yazdır, gönderim yok
php indexnow_ping.php --retry     takılan satırların sayacını sıfırla, sonra gönder
```

`--status` çıktısı şuna benzer:

```
indexnow status
  mode:          online (indexable)
  key:           a1b2... (32 chars)
  site url:      https://siteadresin
  key file:      https://siteadresin/a1b2....txt
  curl:          yes
  queued:        14
  stuck:         0 (attempts >= 5; use --retry)
  last ping:     2026-08-24 09:00:00 UTC
  last count:    31
```

## Bir şey ters giderse

Gönderim başarısız olursa kuyruk **silinmez**. Geçici bir arıza (aşırı
istek, sunucu hatası, bağlantı kopması) bir sonraki koşuda kendiliğinden
telafi edilir. Kalıcı bir sorun — yanlış anahtar, tutmayan adres — beş
denemeden sonra o satırları beklemeye alır ki arkalarındaki yeni adresleri
tıkamasınlar; satırlar silinmez, `--status` bunları `stuck` diye sayar ve
sebep düzeltilince `--retry` hepsini geri alır.

Her başarısızlığın ayrıntısı sunucu hata günlüğüne yazılır.

## Değişen dosyalar

**Yeni:**

```
files/functions/indexnow_helpers.php    (kuyruk + gönderim mantığı)
files/indexnow_ping.php                 (cron/komut satırı görevi)
files/indexnow_key.php                  (anahtar dosyasını üreten sayfa)
files/migration/1.1.32/upgrade.sql
```

**Değişen:**

```
files/functions.php                     (yeni yardımcı dosyanın yüklenmesi)
files/functions/seo_helpers.php         (tek anime için adres kuralı)
files/add_anime.php                     (ekleme sonrası kuyruğa yazar)
files/edit_anime.php                    (düzenleme sonrası kuyruğa yazar)
files/index.php                         (silmeden ÖNCE kuyruğa yazar)
files/catalog_import.php                (yalnız gerçekten değişenleri yazar)
files/admin/admin_catalog_requests.php  (öneri onayı kuyruğa yazar)
files/add_chronology_marker.php         (kronoloji sayfası kazanılabilir)
files/update_chronology_marker.php      (kronoloji içeriği değişti)
files/delete_chronology_marker.php      (son not silinmiş olabilir)
files/.htaccess                         (anahtar dosyası yönlendirmesi)
files/config_example.php                (INDEXNOW_KEY açıklaması)
files/schema.sql
files/version.txt
```

## Dağıtım notu

- `files/functions.php` ile `files/functions/indexnow_helpers.php`
  **birlikte** yüklenmelidir. Yükleyici satırı olmadan dosya hiç okunmaz ve
  kuyruğa yazan her sayfa açılmaz.
- `files/functions/seo_helpers.php` de aynı pakette gitmelidir: adres kuralı
  orada duruyor, eski dosyada o fonksiyon yok.
- `files/.htaccess` yenilenmezse anahtar dosyası adresi 403 döner ve
  gönderimler sessizce reddedilir. Site çalışmaya devam eder; yalnızca
  IndexNow işe yaramaz.
- **Merkez katalog sunucusunda yapılacak bir şey yok.** 1.1.31'in aksine
  katalog telinde yeni alan yok, elle `ALTER` gerekmiyor.
- Migration otomatik koşar ve tek bir tablo oluşturur.
- **Dağıtım sunucusunda** iki işlevsel adım her zamanki gibi: yayımlanan
  `version.txt` 1.1.32'ye çekilmeli — yoksa "Güncelleme Denetle" hâlâ
  1.1.31'i son sürüm sanar — ve `updates/1.1.32/anime-tracker-1.1.32.zip`
  paketi yayımlanmalı, yoksa "Güncelle" düğmesi indirme adresinde 404 alır.
  Paketin üç yeni dosyayı taşıdığı açılıp denetlenmelidir.
#40
Duyurular ve Sürümler / 1.1.31
Last post by hitsumo - Sep 15, 2026, 03:50 PM
# Anime Tracker 1.1.31

**Yayın tarihi:** 2026-08-24

Bu sürüm tek bir soruyu çözer: **tarihin tamamını bilmiyorsan ne yazacaksın?**

Eski yapımların çoğunda kaynaklar günü vermez, bazen ayı da vermez — elde
yalnızca yıl kalır. Şimdiye kadar iki seçenek vardı ve ikisi de kötüydü:

- **Alanı boş bırakmak.** Bilinen yıl da kayboluyordu.
- **Günü uydurmak.** Ekranda `01.01.1979` görünüyordu; okuyan kişi bunu
  "3 Kasım değil, 1 Ocak" diye anlıyordu. Yani yanlış bir kesinlik.

Artık tarihin **bilinen kadarı** girilebiliyor, bilinmeyen kısım `??` olarak
görünüyor.

## Nasıl görünüyor

| Bilinen | Ekranda |
| --- | --- |
| Gün, ay, yıl | `08.04.2005` |
| Ay ve yıl | `??.04.2005` |
| Yalnız yıl | `??.??.2005` |
| Hiçbiri | `??.??.????` |

Kural hem **Yayın Tarihi** hem **Yayın Bitiş Tarihi** için geçerli, ikisi
birbirinden bağımsız: başlangıcı gün gün bilip bitişin yalnızca yılını
bilmek serbest.

## Nasıl giriliyor

Anime ekleme ve düzenleme ekranında her tarih alanının başında bir açılır
kutu var:

- **Tam tarih** — bugünkü takvim seçici, hiçbir şey değişmedi (varsayılan).
- **Ay ve yıl** — bir ay kutusu ve bir yıl kutusu çıkar.
- **Yalnız yıl** — yalnız yıl kutusu çıkar.
- **Bilinmiyor** — hiçbir kutu çıkmaz.

Kimse elle `??` yazmaz; seçim neyse ekranda o görünür. Tam tarihten "yalnız
yıl"a geçtiğinde yazdığın yıl kendiliğinden yıl kutusuna taşınır, yeniden
yazman gerekmez.

## "Bilinmiyor" ile "boş" aynı şey değil

Bu ayrım bilerek korundu:

- **Alanı boş bırakırsan** anime detayında eskisi gibi **"Belirtilmemiş"**
  yazar — "henüz doldurmadım" demektir.
- **"Bilinmiyor" seçersen** `??.??.????` yazar — "baktım, kaynak yok"
  demektir.

Böylece bir listede hangi kaydın doldurulmayı beklediği, hangisinin
gerçekten kaynaksız olduğu ayırt edilebilir.

## Kısmi tarihe geri sayım yapılmaz

Yayını başlamamış animelerde detay sayfası "ilk bölüme kalan süre"yi
sayıyor. Tarihin günü bilinmiyorsa bu satır **hiç basılmaz**. Ekranda
`??.??.2027` yazarken "42 gün kaldı" demek, bilinmeyen bir güne kesin bir
sayı uydurmak olurdu.

## Yıl filtresi ve sıralama bozulmadı

Ana listedeki **yıla göre filtre** ve seri kronolojisindeki tarih sıralaması
aynen çalışıyor. Yalnızca yılı bilinen bir anime kendi yılının filtresinde
görünür ve o yılın başında sıralanır.

## "Otomatik Doldur" artık kısmi tarihi de getiriyor

AnimeSchedule bağlantısıyla çalışan **Otomatik Doldur** düğmesi, tarihleri
AniList'ten alıyor. AniList eski yapımların çoğunda yalnızca yılı tutar; bu
kayıtlar şimdiye kadar **tamamen düşüyordu** ve alan boş kalıyordu. Artık
bilinen parça forma giriyor ve hassasiyet kutusu kendiliğinden doğru seçeneğe
geçiyor.

Bir nokta korundu: elle girdiğin bir tarihin üzerine hiçbir zaman
yazılmıyor. Tam tarih girmişsen AniList "yalnız yıl" dese bile senin girdiğin
gün olduğu gibi kalıyor.

## Seri kronolojisinde

"Yayın Tarihi" sekmesindeki tarihler de aynı biçimi kullanıyor
(`??.04.2005 – ??.06.2005` gibi). Başlangıç ve bitiş aynı değere işaret
ediyorsa yalnızca biri yazılır; farklıysa ikisi de.

## Katalogla ilgili iki not

**Hassasiyet katalogla birlikte taşınıyor.** Küratörün girdiği "yalnızca yıl
biliniyor" bilgisi merkez katalog üzerinden bütün kurulumlara gidiyor;
1.1.31'den eski bir katalog dosyası ise "tam tarih" olarak okunuyor, yani
eski davranış aynen korunuyor.

**Bir eksik kapandı: bitiş tarihi artık gerçekten senkronlanıyor.** Merkez
katalog bitiş tarihini 1.1.14'ten beri *gönderiyordu* ama istemci tarafı onu
hiç kaydetmiyordu — alan sessizce düşüyordu. Bu boşluk kapandı.

> **Davranış değişikliği:** katalogdan gelen bir kayıtta elle girdiğin bitiş
> tarihi, bundan sonraki senkronda katalogun değeriyle değişebilir. Aynı
> kaydın başlığı, durumu, konusu ve yayın tarihi için bu kural zaten
> geçerliydi; bitiş tarihinin korunması bir kural değil, gözden kaçmaydı.

## Ay kutusu ve özel açılır liste

Uzun açılır listeler (8'den fazla seçeneği olanlar) masaüstünde özel bir
widget'a dönüştürülüyor — bu 1.1.11'den beri böyle ve amacı listenin ekranı
kaplamasını önlemek. Kısmi tarihin ay kutusu 13 seçenekli olduğu için o da
dönüştürülüyor.

Bu iki özellik ilk denemede çakıştı: kutuyu gizleme kuralı ekranda görünen
widget'a değil, arkadaki asıl listeye uygulanıyordu. Sonuç, hassasiyet ne
seçilirse seçilsin ay kutusunun ekranda kalmasıydı — "Tam tarih" ve "Yalnız
yıl" seçiliyken bile. Tarih ve yıl kutuları birer metin kutusu olduğu, yani
dönüştürülmediği için doğru çalışıyordu; hata yalnız ay kutusunda görülüyordu.

Artık gizleme widget'ın kendisine uygulanıyor. Düzeltme geneldir: sayfanın
gizlediği her uzun açılır liste, dönüştürüldükten sonra da gizli kalır.

## Değişen dosyalar

**Yeni:**

```
files/functions/date_precision_helpers.php
files/migration/1.1.31/upgrade.sql
```

**Değişen:**

```
files/functions.php                    (yeni yardımcı dosyanın yüklenmesi)
files/functions/anime_helpers.php      (kısmi tarihte geri sayım yok)
files/functions/series_helpers.php      (yeni sütunlar sorgulara eklendi)
files/functions/anilist_import_helpers.php  (AniList kısmi tarihi korunuyor)
files/fetch_animeschedule.php          (Otomatik Doldur kısmi tarih taşır)
files/add_anime.php                    (form + kayıt)
files/edit_anime.php                    (form + kayıt)
files/js/anime_form.js                  (hassasiyet kutusu, alan değiştirme)
files/js/select_enhance.js              (gizlenen uzun listeler gizli kalır)
files/css/components.css                (tarih alanının yerleşimi)
files/anime_details.php                (gösterim)
files/series_timeline.php              (Yayın Tarihi sekmesi)
files/catalog_import.php                (hassasiyet + bitiş tarihi senkronu)
files/admin/catalog_push.php            (yeni sütunlar gönderiliyor)
files/admin/admin_catalog_requests.php  (öneri onayında hassasiyet taşınır)
files/list_settings.php                (yedek geri yükleme + öneri akışı)
files/schema.sql
files/lang/tr.php, files/lang/en.php    (9'ar yeni metin + yardım sayfası)
files/version.txt
catalog_server/catalog.php              (yeni sütunlar yayımlanıyor)
catalog_server/admin_push.php          (yeni sütunlar kaydediliyor)
```

## Dağıtım notu

- `files/functions.php` ile `files/functions/date_precision_helpers.php`
  **birlikte** yüklenmelidir. Yükleyici satırı olmadan dosya hiç okunmaz ve
  tarih basan her sayfa açılmaz.
- İki form (`add_anime.php`, `edit_anime.php`) ile `files/js/anime_form.js`
  de birlikte gitmelidir: eski betik yeni formdaki hassasiyet kutusunu
  tanımaz ve alan değiştirme çalışmaz. Sunucu tarafı yine doğru kaydeder,
  yalnızca üç kutu aynı anda görünür.
- `files/js/select_enhance.js`, `files/js/anime_form.js` ve
  `files/css/components.css` üçü birlikte gitmelidir; yalnız biri eskide
  kalırsa ay kutusu hassasiyet ne seçilirse seçilsin ekranda kalır.
- Dil dosyaları eski kalırsa seçenek etiketleri yerine anahtar adı görünür —
  zararsız ama çirkin.
- **Merkez katalog sunucusunda elle iki `ALTER` gerekir.** Migration orada
  çalışmaz; sütunlar eklenmeden yapılan gönderim hata verir. Sıra: önce
  merkez sunucuda `ALTER`, sonra uygulama dağıtımı, sonra gönderim. Komutlar
  `files/migration/1.1.31/upgrade.sql` dosyasının başında yazılı.
- **Dağıtım sunucusunda** iki işlevsel adım her zamanki gibi: yayımlanan
  `version.txt` 1.1.31'e çekilmeli — yoksa "Güncelleme Denetle" hâlâ 1.1.30'u
  son sürüm sanar — ve `updates/1.1.31/anime-tracker-1.1.31.zip` paketi
  yayımlanmalı, yoksa "Güncelle" düğmesi indirme adresinde 404 alır.