Metadata-Version: 2.4
Name: seogeo
Version: 0.2.0
Summary: SEO ve GEO (Generative Engine Optimization) denetim aracı
Author: Muhsin (mujo5)
License-Expression: MIT
Project-URL: Homepage, https://github.com/mujo5/seoGeo
Project-URL: Repository, https://github.com/mujo5/seoGeo
Project-URL: Issues, https://github.com/mujo5/seoGeo/issues
Project-URL: Changelog, https://github.com/mujo5/seoGeo/releases
Keywords: seo,geo,aeo,ai-visibility,llms-txt,site-audit,crawler
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: lxml>=5.0
Requires-Dist: typer>=0.12
Requires-Dist: rich>=13.0
Requires-Dist: jinja2>=3.1
Provides-Extra: google
Requires-Dist: google-api-python-client>=2.100; extra == "google"
Requires-Dist: google-auth>=2.23; extra == "google"
Requires-Dist: google-auth-oauthlib>=1.1; extra == "google"
Provides-Extra: web
Requires-Dist: fastapi>=0.110; extra == "web"
Requires-Dist: uvicorn>=0.29; extra == "web"
Requires-Dist: python-multipart>=0.0.9; extra == "web"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: mypy>=1.13; extra == "dev"
Provides-Extra: all
Requires-Dist: seogeo[google,web]; extra == "all"
Dynamic: license-file

# seoGeo — SEO ve GEO denetim aracı

[English](README.en.md) · Türkçe

Bir web sitesini tarayıp **teknik SEO** ve **GEO** (Generative Engine Optimization: ChatGPT,
Perplexity, Claude, Gemini, Google AI Overviews gibi yapay zeka cevap motorlarında görünürlük)
açısından inceler. Bağlanırsa **PageSpeed Insights**, **Google Search Console** ve **GA4**
verilerini de ekler. Sonuçta kural tabanlı, önceliklendirilmiş bir aksiyon planı ve HTML rapor üretir.

## Kurulum

```bash
python3 -m venv .venv
.venv/bin/pip install -e '.[all]'      # yalnızca tarama/denetim için: pip install -e .
cp .env.example .env                    # anahtarları buraya yazın
```

## Kullanım

```bash
# Tam denetim: tarama + (varsa) GSC/GA4/PageSpeed + aksiyon planı + HTML rapor
.venv/bin/seogeo audit ornek.com -n 100 --html rapor.html -o denetim.json --save

# Kayıtlı denetimi yeniden taramadan aç / filtrele
.venv/bin/seogeo audit -f denetim.json --only geo -s warning --all

# İki denetimi karşılaştır: yeni/çözülen sorunlar + skor değişimi
.venv/bin/seogeo diff -f denetim.json                     # önceki = geçmişteki son kayıt
.venv/bin/seogeo diff -f yeni.json -p eski.json           # açıkça karşılaştır

# Kayıtlı denetimden HTML rapor
.venv/bin/seogeo report -f denetim.json -o rapor.html

# PDF rapor (bilgisayardaki Chrome ile; --html de .pdf uzantısını tanır)
.venv/bin/seogeo report -f denetim.json -o rapor.pdf
.venv/bin/seogeo audit ornek.com --html rapor.pdf

# Denetimden düzeltme dosyaları: llms.txt, JSON-LD şemaları, meta önerileri
.venv/bin/seogeo audit ornek.com -o denetim.json && .venv/bin/seogeo fixes -f denetim.json -o fixes/

# Rakip karşılaştırma: aynı ölçütlerle yan yana
.venv/bin/seogeo compare sitem.com rakip.com -n 30

# İçerik brief: GSC sorularından yazar dosyası (rakip kıyası opsiyonel)
.venv/bin/seogeo brief -f denetim.json -c rakip.json -o briefs/

# Çok müşteri: sıralı denetim + rapor dosyaları + skor düşüşü bildirimi
.venv/bin/seogeo batch musteriler.json -o raporlar/

# Sunucu loglarında gerçek AI bot trafiği
.venv/bin/seogeo logs /var/log/nginx/access.log --days 28

# CI kapısı: SARIF/JUnit çıktısı + skor eşiği (GitHub Actions örneği aşağıda)
.venv/bin/seogeo audit ornek.com --format sarif -o denetim.sarif --fail-on warning

# Web paneli: denetim başlatma, raporlar, skor geçmişi, zamanlanmış denetim
.venv/bin/seogeo serve            # http://127.0.0.1:8000

# MCP sunucusu: Claude'a bağlayın → "sitemin GEO durumu ne?"
# claude mcp add seogeo -- /yol/.venv/bin/seogeo mcp
```

Önemli seçenekler (`seogeo audit --help`):

| Seçenek | Açıklama |
|---|---|
| `-n`, `-d` | En fazla sayfa ve link derinliği |
| `--pagespeed N`, `--strategy` | PageSpeed ile ölçülecek sayfa sayısı (0 = kapalı), `mobile`/`desktop` |
| `--google-credentials`, `--gsc-property`, `--no-gsc` | Search Console bağlantısı |
| `--ga4-property` | GA4 mülk kimliği |
| `--inspect N` | GSC URL Denetimi yapılacak sayfa sayısı (günlük kota 2000) |
| `--no-ai-probe` | Ana sayfayı AI bot kimlikleriyle test etmeyi kapatır |
| `--ai-visibility N` | AI görünürlük testi: N örnek soru sorulur (ücretli API; bkz. aşağıda) |
| `--save` | Web panelinin geçmişine kaydeder (`~/.seogeo/audits`) |

Periyodik takip için paneldeki **"Zamanlanmış denetim"** formunu kullanabilirsiniz (panel açık
kaldığı sürece çalışır) ya da `seogeo audit ... --save` komutunu cron ile koşturabilirsiniz;
panelde site sayfası skorların zaman içindeki değişimini gösterir. İki kayıt arasındaki farkı
panelde rapor üstündeki **"Öncekiyle farkı"** bağlantısından veya `seogeo diff` ile görürsünüz.

## Veri kaynaklarını bağlama

PageSpeed, Search Console ve GA4 entegrasyonları **ücretsizdir** ve faturalandırma hesabı /
kredi kartı gerektirmez (PageSpeed: 25.000 sorgu/gün; Search Console ve GA4 Data API: kota
dahilinde ücretsiz). Bunların dışındaki **AI görünürlük testi** isteğe bağlıdır ve kendi
anahtarınızla ücretli bir LLM API'si kullanabilir.

### Performans ölçümü (iki seçenek)
- **Anahtarsız — yerel Lighthouse:** `PAGESPEED_API_KEY` yoksa araç bilgisayarınızdaki Chrome ile
  Lighthouse çalıştırır (Node.js gerekir; ilk kullanımda `npx` resmi `lighthouse` paketini indirir).
  Yalnızca laboratuvar verisi üretir. Zorlamak için: `--psi-engine local`.
- **PageSpeed Insights API (önerilir):** gerçek kullanıcı Core Web Vitals verisini de getirir.
  Google anahtarsız kullanım kotasını kaldırdı; ücretsiz anahtar gerekir:
  1. [Google Cloud Console](https://console.cloud.google.com/) → yeni proje (faturalandırma gerekmez)
  2. "API'ler ve Hizmetler" → Kitaplık → **PageSpeed Insights API** → Etkinleştir
  3. Kimlik bilgileri → Kimlik bilgisi oluştur → **API anahtarı** → anahtarı yalnızca bu API ile
     sınırlayın → `.env` içinde `PAGESPEED_API_KEY=`

Ölçüm sayfa başına ~20-40 sn sürer. Sayfalar trafiğe (GSC/GA4) göre, yoksa ana sayfa ve sığ
sayfalar arasından seçilir.

### Google Search Console ve GA4
Aynı Cloud projesinde **Google Search Console API** ve **Google Analytics Data API**'yi etkinleştirin.
Sonra iki yöntemden birini seçin:

**A) Servis hesabı (otomasyon / sunucu için önerilir)**
1. IAM → Servis hesapları → hesap oluştur → Anahtarlar → JSON indir
2. Search Console → Ayarlar → Kullanıcılar ve izinler → servis hesabının e-postasını ekleyin
3. GA4 → Yönetici → Mülk erişim yönetimi → aynı e-postayı **Görüntüleyen** olarak ekleyin
4. `.env`: `SEOGEO_GOOGLE_CREDENTIALS=/yol/servis-hesabi.json`

**B) Kendi Google hesabınızla (OAuth)** — not: OAuth izin ekranı "Test" durumundayken Google
yenileme token'larını 7 günde geçersiz kılar; bu durumda haftada bir `seogeo google-login` gerekir.
Bu yüzden düzenli kullanım için servis hesabı daha pratiktir.
1. Kimlik bilgileri → OAuth istemci kimliği → uygulama türü **Masaüstü uygulaması** → JSON indir
2. `.env`: `SEOGEO_GOOGLE_CREDENTIALS=/yol/client_secret.json`
3. Bir kez giriş yapın: `.venv/bin/seogeo google-login` (token `~/.seogeo/` altına kaydedilir)

GA4 mülk kimliği: GA4 → Yönetici → Mülk ayarları → "Mülk kimliği" → `SEOGEO_GA4_PROPERTY=`

### AI görünürlük testi (isteğe bağlı)

Teknik GEO sinyallerinin ötesinde, sitenin cevap motorlarında gerçekten anılıp anılmadığını ölçer:
sayfa başlıklarınızdan örnek sorular üretilir, her soru temiz bir oturumda sorulur ve cevapta
alan adınız geçip geçmediğine bakılır. Sonuç raporda ve `ai-visibility-low` kuralında görünür.

OpenAI uyumlu herhangi bir sohbet API'si çalışır (OpenAI, OpenRouter, yerel sunucu…):

```bash
SEOGEO_AI_API_KEY=...
SEOGEO_AI_BASE_URL=https://api.openai.com/v1     # varsayılan
SEOGEO_AI_MODEL=gpt-4o-mini                      # varsayılan
SEOGEO_AI_QUESTIONS=3                            # anahtar varken soru sayısı (0: kapalı)
```

Anahtar tanımlıyken `audit` varsayılan olarak 3 soru sorar; `--ai-visibility 0` ile kapatıp
`--ai-visibility 5` ile artırabilirsiniz. Test, API anahtarınız olan bir servise soru başına
istek atar; maliyeti sağlayıcınız belirler.

**İkinci motor — Perplexity (gerçek alıntı):** `PERPLEXITY_API_KEY` tanımlarsanız her soru
iki motora sorulur. Perplexity, cevapta **hangi URL'lerin alıntılandığını** birebir
döndürür — raporda soru başına motor çipleri ve "alıntı ↗" bağlantıları görünür, kart
üstünde motor başına görünürlük yüzdesi listelenir.

### Skor düşüşü bildirimleri (isteğe bağlı)

Denetim kaydedilirken önceki kayıtla karşılaştırılır; bir alan skoru eşiği kadar düşerse
webhook'a JSON gönderilir ve/veya e-posta gider:

```bash
SEOGEO_NOTIFY_WEBHOOK=https://hooks.sirket.com/seogeo     # Slack/Discord/genel webhook
SEOGEO_NOTIFY_EMAIL=duyru@example.com                     # virgülle birden çok
SEOGEO_NOTIFY_SCORE_DROP=5                                # bildirim eşiği (puan)

# E-posta için SMTP (port 465: SSL, 587: STARTTLS)
SEOGEO_SMTP_HOST=smtp.example.com
SEOGEO_SMTP_USER=...  SEOGEO_SMTP_PASS=...  SEOGEO_SMTP_FROM=...
```

CLI'da `audit --save --notify`, panelde zamanlanmış denetimler otomatik bildirim yapar.
Eşik aşılmadıysa hiçbir şey gönderilmez.

### PDF raporu

`--html` çıktısı `.pdf` ile bitince rapor, bilgisayarınızdaki Chrome/Chromium ile PDF'e
çevrilir (ek bağımlılık yok; Lighthouse'un kullandığı Chrome bulunur). Chrome yolu
standart konumlardan değilse `SEOGEO_CHROME=/yol/chrome` ile verin. Panelde rapor üstünde
"PDF indir" bağlantısı da aynı yöntemi kullanır.

### Varlık (entity) denetimi

Marka, bilgi grafiğinde var mı? Her denetimde marka adı çıkarılıp (kurum şeması > başlık >
host) Wikidata ve Vikipedi'de aranır; iki kaynakta da yoksa `entity-web-missing` bilgisi
üretir. Kapatmak için `--no-entity-probe` veya `SEOGEO_ENTITY_PROBE=0`.

### Render denetimi (diferansiyel)

AI tarayıcıları JS çalıştırmaz; Google çalıştırır. Chrome varsa ana sayfa + ilk içerik
sayfaları headless render edilir ve ham HTML ile karşılaştırılır:

- `js-render-empty` (kritik): ham HTML'de anlamlı metin yok — AI botlar sayfayı boş görüyor
- `js-render-gap` (uyarı): render edilmiş DOM belirgin şekilde daha zengin — ana içerik JS'e bağımlı

Raporda sayfa sayfa "ham kelime vs render kelime" tablosu çıkar. Kapatmak için
`--no-render-probe` veya `SEOGEO_RENDER_PROBE=0`; Chrome yolu için `SEOGEO_CHROME`,
sayfa başına JS bekleme süresi için `SEOGEO_RENDER_WAIT` (ms).

### Düzeltme üreteci

`seogeo fixes -f denetim.json -o fixes/` denetimden uygulanabilir dosyalar üretir:
**llms.txt** (tarama verisinden), eksik **Organization/Article/FAQPage JSON-LD** taslakları
(veriyle doldurulur, kalanlar yer tutucu) ve **meta-onerileri.md** (uzun/kısa/eksik title
ve description için sayfa sayfa somut öneriler). Yer tutucuları doldurup uygulayın.

### Rakip karşılaştırma

`seogeo compare sitem.com rakip.com -n 30` aynı kural motoruyla birden çok siteyi tarayıp
yan yana tablo verir: skorlar, AI bot engelleri, llms.txt, kurum şeması, şemasız sayfa %,
soru başlığı olmayan sayfa %. Panelde `/compare` sayfası kayıtlı sitelerin son durumunu
listeler.

### CI kapısı (SARIF / JUnit / GitHub Actions)

```yaml
# .github/workflows/geo.yml
- run: pip install -e '.[all,dev]'
- run: seogeo audit example.com -n 100 --format sarif -o denetim.sarif --fail-on warning
- uses: github/codeql-action/upload-sarif@v3   # isteğe bağlı: SARIF'i Security sekmesine yükle
  with: { sarif_file: denetim.sarif }
```

`--fail-on critical|warning` bu önemde sorun varsa, `--fail-under 60` herhangi bir alan
skoru düşükse komut 1 ile çıkar; `--format junit` Jenkins/GitLab'a, `--format github`
Actions günlüğüne `::error`/`::warning` satırları yazar.

### MCP sunucusu

`seogeo mcp` stdio üzerinden MCP konuşur; Claude gibi istemcilere üç araç verir:
`run_audit` (hızlı denetim), `list_audits`, `get_audit`. Kurulum:
`claude mcp add seogeo -- /yol/.venv/bin/seogeo mcp` → "sitemin GEO durumu ne, en üst
aksiyon ne?" sorularını doğrudan asistana sorabilirsiniz.

### Çok dil desteği (i18n)

`SEOGEO_LANG=en` ile tüm kural başlıkları, çözüm önerileri, kategoriler, önem etiketleri,
CLI durum/ilerleme mesajları ve rapor başlıkları İngilizce üretilir (103 kuralın tamamı
çevrilidir); varsayılan Türkçe'dir. Panel şablonları bu sürümde Türkçe kalır.

### Depolama: SQLite (ajans ölçeği)

Onlarca müşteri × haftalık denetimlerde JSON dosyaları yerine tek veritabanı:

```bash
SEOGEO_STORAGE=sqlite   # geçmiş ~/.seogeo/seogeo.db dosyasına yazılır
```

API/panel/diff/tüm komutlar aynı şekilde çalışır; JSON indirme ucu her iki modda da
aynı biçimi döndürür.

### Ajans modu (white-label)

Raporlarda "seoGeo" yerine kendi markanız: `SEOGEO_REPORT_BRAND=Ajans Adı`, alt nota
ek metin: `SEOGEO_REPORT_FOOTER=...`. HTML ve PDF çıktıları bunu kullanır.

### Lead magnet API (başka sistemle entegrasyon)

Panelde `/lead` sayfası ve programatik uç nokta: potansiyel müşterinin sitesine **10 sayfalık
hızlı denetim** (~40 sn) attırıp satışa hazır özet alın — harf notu, skorlar, ilk 3 hızlı
kazanç ve tek cümlelik değerlendirme:

```bash
curl -s http://localhost:8000/api/lead-audit \
  -H 'Content-Type: application/json' \
  -d '{"url": "musteri.com", "max_pages": 10}'
```

```json
{
  "url": "https://musteri.com/", "host": "musteri.com", "grade": "C",
  "scores": {"seo": 72, "geo": 41, "perf": null, "traffic": null},
  "critical": 2, "warning": 11, "pages": 10,
  "quick_wins": [{"title": "llms.txt yok", "effort": "Düşük", "affected": "site geneli",
                  "recommendation": "llms.txt, sitenin özetini…"}],
  "ai_bots": {"allowed": 9, "blocked": 4, "total": 13},
  "summary": "Siteniz teknik SEO'da iyileştirmeye açık (72/100) ama AI cevap motorlarında …",
  "audit_id": "musteri.com_20261006-…", "report_url": "/audits/musteri.com_20261006-…"
}
```

- `GET /api/lead-audit?url=…` varyantı no-code araçlar için; `save: false` ile geçmişi işgal etmez
- `SEOGEO_API_TOKEN` tanımlarsanız uç nokta `X-Api-Token` başlığı ister
- Eşzamanlı denetim 2 ile sınırlı, sayfa sayısı 5–25 aralığına sıkıştırılır
- `/lead` sayfası form + sonuç kartı biçiminde hazır landing demosudur; kendi
  landing sayfanıza `POST /api/lead-audit` çağrısıyla gömebilirsiniz

Ayrıca CLI'ı subprocess ile çalıştırıp `--format json` çıktısını kendi sisteminizde
işleyebilir, skor düşüşü webhook'larını CRM'inize bağlayabilirsiniz.

### REST API

Panelin tüm işlevleri JSON uç noktalarıyla da vardır (panelde `/api-docs` sayfası):

```
GET    /api/audits?host=&limit=    kayıtlı denetimler (meta)
GET    /api/audits/{id}            skorlar, sayılar, üst aksiyonlar
POST   /api/jobs                   arka planda denetim başlat → 202 {job_id}
GET    /api/jobs/{id}              iş durumu (running|done|error, audit_id)
GET    /api/sites                  her sitenin son denetim özeti
GET    /api/schedules              zamanlanmış denetimler
POST   /api/schedules              ekle/güncelle {"url", "interval_hours", ...}
DELETE /api/schedules/{id}         sil
```

Tümü `SEOGEO_API_TOKEN` tanımlıysa `X-Api-Token` başlığı ister (panel token'ından ayrıdır).

### AI görünürlük geçmişi

`--ai-visibility` ile çalıştırılan her denetim, soru bazlı alıntılanma sonucunu saklar.
Site geçmişi sayfasında soru × tarih matrisi (✓/✗) ve kolon başına görünürlük yüzdesi
gösterilir — müşteriye "3 ayda ş sorunlarında alıntılanmaya başladık" diyebileceğiniz
kanıt grafiği budur.

## Neler denetleniyor?

Skorlar dört alanda ayrı ayrı hesaplanır. Dış veriye dayanan alanlar ancak o veri bağlıysa puanlanır.

| Alan | Kapsam |
|---|---|
| **SEO** | Durum kodları, yönlendirme zincirleri, kırık iç linkler, noindex/canonical, title/description (eksik, uzun, kopya), H1 ve başlık hiyerarşisi, ince/kopya içerik, görsel alt/boyut, hreflang, robots.txt, sitemap tutarlılığı, yetim sayfalar, HTTPS, URL yapısı |
| **GEO** | AI botlarının robots.txt erişimi (arama ve eğitim botları ayrı), CDN/WAF engeli (bot kimliğiyle gerçek istek), bot doğrulama sayfaları, JS'e bağımlı içerik, nosnippet, llms.txt, schema.org (Organization+sameAs, Article, Product, FAQ, Breadcrumb), E-E-A-T (yazar, tarih, güncellik, hakkımızda/iletişim/KVKK), alıntılanabilirlik (soru başlıkları, kısa cevap paragrafı, liste/tablo, istatistik, kaynak, bölümleme), soru sorgularına cevap fırsatı (GSC), AI asistanlarından gelen trafik (GA4), örnek sorularla AI görünürlük testi (anahtar tanımlıysa) |
| **Performans** | Core Web Vitals saha verisi (LCP, INP, CLS; p75), saha verisi yoksa laboratuvar ölçümü, Lighthouse skorları, tasarruf miktarına göre iyileştirme fırsatları |
| **Arama Performansı** | Pozisyona göre düşük CTR, ilk sayfaya yakın (8-20. sıra) sorgular, anahtar kelime yamyamlığı, gösterim almayan sayfalar, URL Denetimi (indekslenmemiş, Google'ın farklı canonical seçmesi), düşük etkileşimli giriş sayfaları, trafik alan hata sayfaları |

**Aksiyon planı:** her sorun için `etki = önem × etkilenen sayfaların trafik ağırlığı`,
`öncelik = etki ÷ efor` hesaplanır. Böylece çok trafik alan sayfalardaki kolay düzeltilebilir
kritik sorunlar en üste çıkar. Rapor ayrıca "hızlı kazanımlar" ve sayfa bazında yapılacaklar listesi içerir.

## Proje yapısı

```
seogeo/
  crawler.py, parser.py, sitefiles.py   tarama, HTML ayrıştırma, robots/sitemap/llms.txt, AI bot testi
  aibots.py                             AI tarayıcı listesi (token, sahibi, amacı)
  checks/                               kurallar: technical, geo, performance, traffic (+ base: altyapı/skor)
  integrations/                         pagespeed, google_auth, search_console, analytics,
                                        ai_visibility (GSC sorulu), entity (Wikidata/Vikipedi),
                                        rendering (ham vs render DOM)
  pipeline.py                           tarama → varlık → GSC/GA4 → PageSpeed → AI görünürlük → kurallar
  plan.py                               önceliklendirme
  diff.py                               iki denetim arasındaki fark
  fixes.py                              düzeltme dosyaları: llms.txt, JSON-LD, meta önerileri
  compare.py                            rakip/site karşılaştırma tablosu
  ci.py                                 SARIF / JUnit / GitHub Actions çıktıları + skor kapısı
  mcp.py                                MCP sunucusu (run_audit, list_audits, get_audit)
  notify.py                             skor düşüşü bildirimleri (webhook + e-posta)
  pdf.py                                HTML raporu Chrome ile PDF'e çevirme
  report.py + templates/                HTML rapor ve panel şablonları
  storage.py, web/app.py                denetim geçmişi, işler/zamanlama ve FastAPI paneli
```

Yeni kural eklemek için `checks/` altındaki bir modülde `rule(...)` ile tanımlayıp
`@page_check`, `@content_check` veya `@site_check` ile kontrol fonksiyonu yazmanız yeterli.

## Testler

```bash
.venv/bin/pytest        # testler
.venv/bin/ruff check seogeo tests   # lint
.venv/bin/mypy seogeo   # tip kontrolü
```

Üçü de CI'da (GitHub Actions, `.github/workflows/ci.yml`) Python 3.11 ve 3.13 için koşar.

## Kurulum ve yayınlama

### Docker ile kurulum

```bash
docker compose up -d          # http://localhost:8000 (chromium dahil: PDF + render denetimi çalışır)
docker compose logs -f
```

İmaj otomatik yayınlanır: `ghcr.io/mujo5/seogeo:latest` (main push) ve sürüm tag'lerinde
sürüm numaralı imaj. Kalıcı veri `seogeo-data` volume'ünde (`/data` = ~/.seogeo karşılığı).

### Kurulum sihirbazı

Anahtarları elle .env'e yazmak yerine:

```bash
.venv/bin/seogeo setup          # etkileşimli: sorar → canlı doğrular → .env'e yazar
.venv/bin/seogeo setup --test   # mevcut ayarları sormadan canlı doğrular (durum tablosu)
```

Sihirbaz her anahtarı kaydetmeden önce gerçek API çağrısıyla test eder; geçersiz anahtar
uyarısıyla devam edip etmeme size kalmıştır. PageSpeed anahtarı için:
Google Cloud Console → yeni proje (faturalandırma gerekmez) → "PageSpeed Insights API"
etkinleştir → Kimlik bilgileri → API anahtarı. Google (GSC+GA4) için servis hesabı JSON'u
önerilir (adımlar README'de "Google" bölümünde). AI testi için OpenAI/OpenRouter anahtarı.

### Kaynak koddan kurulum yukarıda. PyPI'dan kurulum (yayınladıktan sonra):

```bash
pip install seogeo            # temel tarama/denetim
pip install 'seogeo[all]'     # Google + web paneli dahil
```

Yeni sürüm yayınlamak için (Trusted Publishing — PyPI token'ı gerekmez):
1. pypi.org → hesap → Publishing → pending publisher ekle: `mujo5/seoGeo`, workflow `release.yml`, environment `pypi`, project `seogeo`
2. `git tag v0.2.1 && git push --tags` → build + PyPI otomatik
3. Haftalık GEO denetimi: `.github/workflows/geo.yml` (cron/manuel, `--fail-on critical --fail-under 60`)

## Sınırlar

- JavaScript çalıştırılmaz; sayfa ham HTML'i üzerinden değerlendirilir. Bu, çoğu AI tarayıcısının
  gördüğüyle aynıdır, ancak tamamen JS ile render edilen sitelerde SEO kontrolleri eksik kalır.
- AI bot erişim testi bot kimliği taklit edilerek yapılır; botları IP ile doğrulayan sistemler
  gerçek botlara farklı davranabilir.
- Alıntılanabilirlik ve CTR eşikleri sezgiseldir (genel rehberlere dayanır); bu yüzden çoğu
  "bilgi" düzeyindedir ve site bağlamında yorumlanmalıdır.
- AI görünürlük testi cevapta alan adının geçmesine bakar; cevabın içeriği değil "hatırlanma"
  ölçülür ve tek koşuda rastlantısal değişkenlik olabilir.
- Web paneli tek kullanıcılı panel güvenliği için tasarlandı: `SEOGEO_PANEL_TOKEN` ile korunur,
  ama yine de yalnızca güvenilir ağlarda çalıştırın. Zamanlanmış denetimler panel açık kaldığı
  sürece çalışır (kalıcı değildir); kesintisiz takip için cron + `audit --save` kullanın.
