Siber guvenlik haberleri, CVE zafiyetleri, Kubernetes ekosistemi, SRE (Site Reliability Engineering) haberleri, DevTools altyapi araclari guncellemeleri ve yapay zeka (AI) gelismelerini 47 farkli kaynaktan toplayan, Turkceye ceviren ve modern bir arayuzde sunan full-stack haber agregasyon uygulamasi.
Bu proje Vibe Coding yaklasimiyla, Claude Code (claude-opus-4-6) ile birlikte gelistirilmistir.
| Uygulama surumu | appVersion 2026.10.3 (CalVer; imaj etiketi) |
| Helm chart | 2.2.1 (SemVer; etiket chart-2.2.1) — CHANGELOG |
| Calisma zamani | Python 3.11, Django 5.2, Node 22, PostgreSQL 16, Redis 7 |
| Testler | 941 Django testi (news/tests/, PostgreSQL uzerinde CI'da kosar) ve 298 Vitest testi, 25 dosya (frontend/src/) |
| Dagitim | Docker Compose (canli, yerel) · Helm (generic) · Argo CD + Vault (yerel GitOps, ADR-0008) |
| Lisans | MIT |
Icindekiler: Mimari · Ozellikler · Veri Kaynaklari · Teknoloji Yigini · Kurulum · Gelistirme ve Test · Kullanim · API · Entegrasyon API v1 · Proje Yapisi · Ceviri Sistemi · Periyodik Cekim · Surumleme · Kubernetes / Helm · CI ve Guvenlik Hatti · Operasyon ve Sorun Giderme · Ortam Degiskenleri · Belgeler ve Yol Haritasi · ADR
Okunusu, yukaridan asagiya:
- GitHub:
tech-radarchart'ichart-<surum>etiketiyle sunar;yerel-gitopskumede ne calisacagini tutar. Gelistirici yalnizyerel-gitops'a push eder. - docker-desktop Kubernetes: Argo CD iki repoyu okur (chart HTTPS ile, GitOps reposu salt okunur SSH deploy key ile, 2 dakikada bir) ve
tech-radarnamespace'ini senkron tutar. Vault Secrets Operator Vault'tankv/tech-radar/uygulama'yi okuyupteknoloji-secret'i yazar; uygulama Secret'ienvolarak alir. Argo CD, VSO ve Vault'u Terraform kurar; Terraform ayrica Vault'u (KV, auth, politikalar) ve Argo CD'nin kok Application'ini ayarlar. - yerel-platform PostgreSQL: tek sunucu, iki veritabani. K8s uygulamasi
host.docker.internal:5432uzerindencybernews_k8s'e, composeyerel-platformagi uzerindencybernews'e baglanir. - Docker Compose: canli ortam. api/worker/scheduler Redis'i cache ve broker olarak, LibreTranslate'i cekim aninda ceviri icin kullanir; 35 harici kaynagi ve Gemini API'yi disaridan ceker.
Gorsel Archify ile uretildi; etkilesimli HTML surumu repo disinda tutulur.
┌──────────────────────┐
│ React Frontend │ Vite dev server (compose) /
│ Vite + Bootstrap 5 │ Nginx (imaj, K8s)
│ :3000 │
└──────────┬───────────┘
│ /api proxy
┌──────────▼───────────┐ ┌───────────────────────┐
│ Django REST API │◄──────►│ PostgreSQL 16 │
│ Gunicorn, DRF │ │ yerel-platform │
│ /api/* (arayuz) │ │ (ayri repo, paylasilan│
│ /api/v1/* (dis API) │ │ yerel-postgres:5432) │
└───┬─────────────┬────┘ └───────────────────────┘
│ │
┌──────────▼──┐ ┌──────▼─────────────────────┐
│ Redis 7 │◄──┤ Celery Worker + Beat │
│ cache + │ │ cekim · ceviri · retranslate│
│ broker │ │ 6 saatte bir / saatlik tur │
└─────────────┘ └──────┬───────────────┬──────┘
│ │
┌────────────▼────┐ ┌──────▼──────────────┐
│ 35 harici kaynak│ │ Ceviri saglayicilari│
│ RSS · HTML · API│ │ LibreTranslate (yerel)│
└─────────────────┘ │ Gemini (yukseltme) │
└─────────────────────┘
Ayni kod uc bicimde calisir:
| Ortam | Ne icin | Nasil kurulur | Veritabani |
|---|---|---|---|
| Docker Compose | Canli yerel ortam (gunluk kullanim) | docker compose up -d --build |
yerel-postgres / cybernews |
| Helm (generic) | Herhangi bir Kubernetes kumesi | helm upgrade --install (bolum) |
chart ici PostgreSQL ya da harici |
| Argo CD + Vault (yerel GitOps) | Paralel deneme ortami, docker-desktop | yerel-gitops reposuna commit; platform yerel-platform Terraform'u (ADR-0008) |
yerel-postgres / cybernews_k8s |
- 47 farkli kaynak — 12 siber guvenlik, 5 CVE, 3 Kubernetes, 5 SRE, 13 DevTools, 9 Yapay Zeka; hepsi anahtarsiz ve ucretsiz (GitHub API icin istege bagli
GITHUB_TOKEN) - Asenkron cekim — "Getir" istegi Celery worker'a devredilir; arayuz 5 saniyede bir yeni kayitlari otomatik yansitir
- Periyodik cekim — Celery Beat tum bolumleri 6 saatte bir otomatik gunceller (sadece yeni kayitlar cevrilir)
- Yonetici korumali sifirlama — Veritabanini silen
clearendpoint'leri yalnizca Django admin oturumuyla calisir - Tam makale cevirisi — Kisaltma yok, tum icerik Turkceye cevrilir
- Teknik terim korumasi — 130+ terim (Kubernetes, Docker, Elasticsearch, CVE, CVSS, vb.) ceviri sirasinda bozulmaz
- Turkce imla post-processing — Cumle basi buyuk harf, noktalama duzeltme, URL/surum koruma
- Parca tabanli ceviri — Uzun makaleler cumle sinirlarindan 4500 karakterlik parcalara bolunerek cevrilir
- Genel Bakis — Ana sayfa (
/) zafiyet odaklidir: "Zafiyet Durumu · Son 24 Saat" basligi altinda kritik (24 sa), yuksek (7 gun) ve CISA KEV (7 gun) kutulari, son ziyaretten beri yeni kayit cumlesi, CVSS dagilim grafigi, "Oncelikli Zafiyetler" listesi, "Gundem" ve bir sonraki cekim saati; ozet sayilari yalnizGET /api/ozet/'ten, GundemGET /api/gundem/'den gelir (asagidaki madde) - Gundem — Genel Bakis'teki kart, bes bolumun (Siber Guvenlik, Kubernetes, SRE, DevTools, Yapay Zeka; CVE haric) son 72 saatini tarar ve cok kaynakta birden yer alan buyuk olaylari one cikarir (tasarim). Hesap sunucuda
news/gundem.pyicindedir; LLM ve dis istek yoktur:- Pencere:
created_atson 72 saat; ek olarak yayin tarihi 4 gunden eskiyse kayit disarida kalir (kaynak eski yazilari yeniden yayinlarsa sahte taze olay cikmaz) - Olay gruplama: Ingilizce orijinal basliklar uzerinden. Uydurma adlar (
PHP2Shellgibi) ve ayni CVE kimligi tek basina baglar; ortak nadir bir ozel ad + baslik benzerligi baglar; ayni kaynaktan iki makale ancak yuksek benzerlikte ayni olay sayilir. Secim aninda, ayni ozneyi tasiyan cok kaynakli olaylar birlestirilir (tek kaynakli satirlar bu birlestirmeye girmez) - Ozet basliklari: cok konulu bultenler (THN "ThreatsDay" / "Weekly Recap", Help Net Security "Week in review", SecurityWeek "In Other News", "+ N more", iki ayri haberi
;ile baglayan mansetler) iki olay arasinda kopru kurmaz; yalniz tek bir olaya uyuyorsa ona tekrar olarak katilir. Kaynak sayisina ve rozete girmez, temsilci olmaz; bir bulten tek kaynakli haberi "cok kaynakli" yapamaz - Puan: her kaynagin tazelik carpani (24 saat yari omur) toplanir (ayri kaynak sayisi) + 0,5 x tekrar makalesi + 1,5 x etki sozcugu (hack, breach, zero-day gibi); tum yaslar esitse eski "ayri kaynak sayisi" olcusuyle ayni sonucu verir
- Liste: en cok 6 oge; once cok kaynakli olaylar (puan sirasiyla), kalan yerler en yeni kayitlarla dolar. Cok kaynakli satirda "N kaynak" rozeti vardir; kaynak adlari rozetin ipucunda ve ekran okuyucu adinda yer alir
- Pencere:
- Ortak okuma paneli — Tum bolumler ayni panelde acilir: metin varsayilan olarak Turkce okunur, "Orijinali goster" ile ingilizce asil metin acilir; cevrilmemis kayit orijinal metinle ve "Cevrilmedi: orijinal metin" uyarisiyla gosterilir, cevrilemeyen paragraflar isaretlenir; CVE kayitlarinda CVSS, KEV satiri ve kaynak baglantilari yer alir
- Paylasilabilir baglanti — Panel acikken adres
?kayit=<id>alir (ornek/news?kayit=123); adres kopyalanip acilinca ayni kayit okunur, geri tusu paneli kapatir. Kayit acik sayfada yoksa (baska sayfa, filtre disi, eski) liste ucundan?id=ile istenir; silinmis/bilinmeyen kimlikte "Kayit bulunamadi" bildirimi cikar ve parametre adresten silinir - Karanlik tema — Yalnizca koyu tema (
<html data-bs-theme="dark">); tema dugmesi yoktur. Vurgu#7aa2ff→#b98bff, kritik#ff5d8f, yuksek#ffb35d; sistem yazi tipleri, harici font/CDN yok (CSP degismez),prefers-reduced-motionicin animasyonlar durur (tasarim) - DevTools takibi — Seq, Ceph, MongoDB, PostgreSQL, RabbitMQ, Elasticsearch+Kibana, Redis, Moodle, LiteLLM, LangGraph, Langfuse, GitLab, Keycloak release guncellemeleri
- CISA KEV — Aktif somurulen zafiyetler (Known Exploited Vulnerabilities) CVE bolumunde ayri kaynak; NVD API'sinin
hasKevfiltresiyle, eklenme tarihi ve federal son tarih bilgisiyle. Eklenme tarihiCVEEntry.kev_added_datealaninda (migration 0016) tutulur; NVD yolu bir KEV kaydini yeniden yazsa da bu tarihi ezmez; Genel Bakis'in KEV kutusu bu alana gore sayar - Filtre, siralama ve sayfalama — Alti bolumun hepsi ayni filtre cubugunu kullanir: Donem (1/3/7/14/30 gun veya Tumu, varsayilan 7), Siralama (yeni/eski; CVE'de CVSS), Kaynaklar, bolume ozel dugmeler (CVE: onem; Kubernetes: kategori) ve Arama kutusu (
?ara=; basliklarda ve aciklamalarda, CVE'de kimlikte de; 2 karakterden kisa arama suzmez). Liste 5 sn'de bir yalniz ilk sayfada sessizce yenilenir (sonraki sayfalar kaymasin); yeni sorgu hatayla biterse eski liste yerine "Yeniden dene" kutusu cikar. Bilinmeyen adreste "Sayfa bulunamadi" sayfasi gosterilir. Gercek kayit sayisi satiri, numarali sayfalar (sayfa basina 25) ve adrese yazilan durum (?gun=tumu&sirala=cvss&sayfa=2&onem=kritik&kaynak=...) vardir; adres kopyalanip acilinca ayni gorunum gelir. Filtre ve siralama sunucudacreated_atuzerinden, veritabanindan yapilir (tasarim) - Cekim penceresi — Cek dugmesi
min(gun, 15)gunluk kayit ceker (news/serializers.pysinirlari: 1-30 gun haberler, 1-90 CVE/Kubernetes/SRE/Yapay Zeka, 1-120 DevTools) - Yeniden denemeli cekim — Gecici 429/5xx ve baglanti hatalarinda 2 ek deneme, ussel bekleme,
Retry-After'a uyum (news/base_scraper.oturum_kur); onceden tek bir 503 kaynagi o tur bos birakiyordu - CVSS siddet filtresi — Kritik / Yuksek / Orta / Dusuk (CVE sayfasi); sunucuda CVSS araliklariyla (
onem) uygulanir, "Tumunu goruntule"/cve?sirala=cvssacar - HTML rapor disa aktarma — Her bolumden koyu temali, yazdirilabilir HTML rapor indirilebilir; rapor o anki filtre ve siralamayi kullanir, en fazla 500 kayit icerir ve fazlaysa raporda not duser (
utils/rapor.js). Okuma paneli, kaydi sayfadan cikmis olsa da acik kalir - Entegrasyon API (
/api/v1/) — Token'li, imlecli delta okuma; OpenAPI 3 semasi ve Swagger UI; manuel tetikleme ve is takibi (ADR-0003) - Cekim gorunurlugu — Her cekim
FetchRunolarak kaydedilir;GET /api/v1/status/bolum basina tazelik ve son durum verir (ADR-0006) - Ceviri rozetleri — Her kayit saglayicisini tasir (LibreTranslate / Gemini); bekleyen cevirilerde Ingilizce metin kaybolmaz
- Docker Compose — Tek komutla 6 container ayaga kalkar (PostgreSQL ayri
yerel-platformreposunda paylasilir) - Kubernetes — Surumlu Helm chart (SemVer + CHANGELOG, CI kapilari); Argo CD Sync hook modu ve harici Secret destegi
- GitOps + Vault — Yerel docker-desktop'ta Terraform ile kurulan Argo CD + HashiCorp Vault + Vault Secrets Operator zinciri; sirlar git'e ve state'e girmez (ADR-0008)
- Guvenlik hatti — 9 GitHub Actions is akisi: test/build/Helm kapisi, CodeQL, Trivy (kaynak + imaj + SBOM), gitleaks, ZAP DAST, Dependency Review, zizmor, OpenSSF Scorecard, chart etiketi kapisi (plan)
| Kaynak | Yontem | Aciklama |
|---|---|---|
| The Hacker News | HTML Scraping | Tam makale icerigi cekilir |
| Bleeping Computer | HTML Scraping | Sponsorlu icerik filtrelenir; Cloudflare Chrome UA'sini 403'ledigi icin Firefox UA, tur basina 10 makale ve 1 sn bekleme (429) |
| SecurityWeek | RSS + tam makale | RSS linkleri tasir, govde makale sayfasindan cekilir (ana sayfa HTML'inde link bos geliyordu) |
| Dark Reading | RSS Feed | HTML 403 dondugu icin RSS kullanilir |
| Krebs on Security | HTML Scraping | Brian Krebs'in guvenlik blogu |
| The Record | RSS + tam makale | Recorded Future'in haber sitesi |
| CyberScoop | RSS Feed | Tam metin content:encoded icinde gelir |
| Help Net Security | RSS + tam makale | Sektor haberleri, arastirma ozetleri |
| Infosecurity Magazine | RSS Feed | Kisa ozet; govde makale sayfasindaki paragraflardan tamamlanir |
| SANS ISC | RSS Feed | Internet Storm Center gunlukleri; tam metin RSS'te |
| The Register | RSS Feed | Security bolumu; tam metin RSS'te |
| Security Affairs | RSS Feed | Tam metin content:encoded icinde gelir |
Yeni RSS kaynaklari
scraper_multi.RSSNewsSourceile okunur: tur basina en fazla 15 haber,dayspenceresi, 200 karakterden kisa ozetler makale sayfasindan tamamlanir. Feed'den gelen linkler yalniz kaynagin kendi kok alaninda vehttpsise acilir (news/base_scraper.link_guvenli; SSRF korumasi, bkz. GUVENLIK-PLANI 3a).fetch_all_newstavani kaynak sayisiyla buyur (max(30, 3 x kaynak)), boylece seyrek yazan kaynaklar (Krebs, SANS) tarih siralamasinda dusmez.
| Kaynak | Yontem | Aciklama |
|---|---|---|
| CISA KEV | NVD REST API (hasKev) |
Son days gunde KEV katalogu'na eklenen, aktif somurulen CVE'ler; baslikta CISA'nin zafiyet adi, aciklamada eklenme ve son tarih. cisa.gov JSON akisi bot korumasi nedeniyle 403 dondugu icin NVD uzerinden |
| NVD (Yayinlanan) | REST API | Son days gunde yayinlanan CVE'ler; startIndex ile sayfalanir (sayfa 2000, tavan 4000) |
| NVD (Guncel) | REST API | Son 2 gunde degisen CVE'ler; yalniz guncelleme kaynagi: veritabanindaki CVE'lerin CVSS/KEV/aciklama alanlarini gunceller, yeni kayit olarak yalniz yayin tarihi pencerede ise alinir |
| GitHub Advisory | REST API | CVSS, CWE, etkilenen paketler dahil |
| Tenable | HTML Scraping | Severity bilgisi dahil; aciklamasi yer tutucu ("No description provided") olan kayitlar alinmaz |
Ayni CVE birden fazla kaynaktan gelirse tutulacak kayit cve_scraper.KAYNAK_ONCELIGI ile secilir: CISA KEV, NVD, NVD Guncel, GitHub Advisory, Tenable. Veritabaninda cevrilmis olan bir CVE yeniden cevrilmez, ama NVD ailesinden gelen veriyle ceviri disi alanlari guncellenir (news/cve_guncelleme.py): CVSS ve onem, KEV eklenme tarihi (kaynak CISA KEV olur), CWE ve referanslar; yer tutucu aciklama gercegiyle degisirse kayit ceviri kuyruguna doner. Degismeyen kayit yazilmaz (updated_at ilerlemez). Yeni kayitlar turda en fazla CVE_TUR_TAVANI (250) kadar islenir, KEV ve CVSS sirasiyla; kalanlar bir sonraki turda yine yenidir. Eski yer tutucu aciklamalar icin tek seferlik: python manage.py cve_aciklama_tamamla --uygula.
| Kaynak | Yontem | Aciklama |
|---|---|---|
| Kubernetes Blog | HTML Scraping | Resmi Kubernetes blog yazilari |
| Kubernetes GitHub | REST API | Release notlari, CHANGELOG formatinda |
| CNCF Blog | WordPress API | Cloud Native Computing Foundation haberleri |
| Kaynak | Yontem | Aciklama |
|---|---|---|
| SRE Weekly | RSS Feed | Haftalik bulten, bireysel makalelere ayristirilir |
| InfoQ SRE | RSS Feed | feed.infoq.com/sre/ konu akisi (HTML kartlari istemci tarafinda cizildigi icin RSS'e gecildi) |
| PagerDuty Eng | RSS Feed | Incident management ve SRE makaleleri |
| Google Cloud SRE | RSS Feed | SRE anahtar kelime filtresiyle |
| DZone DevOps | RSS Feed | feeds.dzone.com/devops-and-cicd (eski /devops adresi olu bir porta yonlendiriyordu) |
| Kaynak | Yontem | Aciklama |
|---|---|---|
| Seq | Datalust Blog RSS | Yapilandirilmis log arama motoru, release filtreli |
| Ceph | GitHub Releases Atom | Dagitik storage, version tag tabanli |
| MongoDB | GitHub Tags Atom + mongodb.com release notes | Stabil rX.Y.Z tag'leri; aciklama resmi surum notlari sayfasindaki surum basligindan (blog RSS'i Haziran 2026'da donmustu) |
| PostgreSQL | Resmi News RSS | Resmi haberler, release notlari, ekosistem |
| RabbitMQ | GitHub Releases API | Mesaj kuyrugu, tam changelog |
| Elasticsearch + Kibana | GitHub Releases API + elastic.co release notes | Resmi release notes sayfasindan detayli changelog |
| Redis | Blog RSS + tam makale | Blog sayfasindan tam icerik cekilir (blockContent) |
| Moodle | GitHub Tags API + moodledev.io | Resmi release notes sayfasindan gercek icerik |
| LiteLLM | GitHub Releases API | LLM gateway; yalniz vX.Y.Z stabil surumler (gunluk dev/rc/backport elenir) |
| LangGraph | GitHub Releases API | Ajan orkestrasyonu; cekirdek X.Y.Z, sdk== ve cli== paketleri (checkpoint/prebuilt elenir) |
| Langfuse | GitHub Releases API | LLM gozlemlenebilirlik; vX.Y.Z surumleri, changelog |
| GitLab | docs.gitlab.com surum Atom'u | Ay surumleri ve yama surumleri, tam surum notu (gitlab.com/api/v4 anonim istege 403 donuyor) |
| Keycloak | GitHub Releases API | Kimlik yonetimi; X.Y.Z surumleri (nightly elenir) |
LiteLLM, LangGraph, Langfuse ve Keycloak
devtools_scraper.GitHubReleasesScraperortak sinifiyla okunur (tag deseni + prerelease elemesi). GitHub API anonim limiti 60 istek/saat/IP'dir;GITHUB_TOKENverilirse yalnizapi.github.comisteklerine eklenir (bkz. Ortam Degiskenleri).fetch_alltavani kaynak sayisiyla buyur (max(30, 3 x kaynak)).
| Kaynak | Yontem | Aciklama |
|---|---|---|
| Hugging Face | RSS Feed | Model, dataset ve kutuphane duyurulari |
| MIT Tech Review AI | RSS Feed | Tam makale icerigi RSS icinde gelir |
| MarkTechPost | RSS Feed | Arastirma ve model haberleri |
| AWS ML Blog | RSS Feed | AWS makine ogrenmesi blogu |
| TechCrunch AI | RSS Feed | AI sektor haberleri |
| Google DeepMind | RSS Feed | DeepMind arastirma blogu |
| OpenAI Blog | RSS Feed | OpenAI duyurulari |
| Ars Technica AI | RSS Feed | Ars Technica yapay zeka bolumu (https://arstechnica.com/ai/feed/; 2026-10-14: KDnuggets yerine) |
| Import AI | RSS Feed | Jack Clark'in haftalik yapay zeka bulteni (https://importai.substack.com/feed) |
Tum AI kaynaklari
news/base_scraper.pyicindeki ortakBaseRSSScraperile okunur; RSS aciklamasi 200 karakterden kisaysa makale sayfasindan paragraf cekilir. Benchmark/leaderboard skorlari kapsam disidir (bkz. ADR-0002).
| Katman | Teknolojiler |
|---|---|
| Backend | Python 3.11, Django 5.2, Django REST Framework 3.18, drf-spectacular (OpenAPI 3), django-csp, Celery 5.6 + django-celery-beat, Gunicorn 22, Whitenoise |
| Frontend | React 18, Vite 6, React Bootstrap 2.9, React Router DOM 7, Axios, react-hot-toast; Node 22; yalniz koyu tema (sistem yazi tipleri, src/styles/tema.css) |
| Veri | PostgreSQL 16 (compose ve K8s; SQLite yalniz DEBUG=True ile hostta), Redis 7 (cache + Celery broker, django-redis) |
| Scraping | BeautifulSoup4, lxml, Requests |
| Ceviri | Cekim aninda yerel LibreTranslate 1.9.6 (aninda Turkce, rozetli); retranslate saatlik turlarla (gunde 20) bekleyen ve onemli LibreTranslate kayitlarini (CVE'de yalniz CVSS >= 7 ya da KEV) Gemini API (gemini-3.5-flash-lite, ucretsiz katman, kayit basina tek istek) ile yeniden eskiye dogru yukseltir + merkezi post-processing |
| Konteyner / dagitim | Docker Compose, cok asamali Dockerfile'lar (non-root, digest sabitli taban imajlar), Nginx 1.31 (frontend imaji), Helm chart tech-radar |
| Platform (ayri repolar) | yerel-platform: paylasilan PostgreSQL + Terraform (Argo CD, Vault, VSO); yerel-gitops: Argo CD Application'lari ve ortam degerleri |
| CI / guvenlik | GitHub Actions, CodeQL, Trivy, gitleaks, OWASP ZAP, Dependency Review, zizmor, OpenSSF Scorecard, Dependabot, kubeconform |
Tam surumler requirements.txt ve frontend/package.json dosyalarindadir; Dependabot bunlari haftalik gunceller.
- Docker ve Docker Compose
- Internet baglantisi (kaynak sitelere ve Gemini API'ye erisim icin; LibreTranslate yerel container'da calisir)
- Paylasilan yerel PostgreSQL (
yerel-platformreposu) ayakta vecybernewsveritabani olusturulmus
.env.example'i .env olarak kopyalayin. SECRET_KEY (openssl rand -hex 32) ve DB_PASSWORD (yerel-platform'daki cybernews kullanicisinin parolasi) zorunludur; GEMINI_API_KEY istege baglidir (bos birakilirsa Gemini hic denenmez, sistem LibreTranslate ile calisir); OPENROUTER_API_KEY, OPENROUTER_MODEL, DEEPL_API_KEY ve GEMINI_FALLBACK_MODEL ucretsiz yedek ceviri zincirini acar (bos = kapali, bkz. Ceviri Sistemi). Veritabani ayri yerel-platform reposundaki paylasilan PostgreSQL'dir; compose'dan once orada docker compose up -d calismis olmalidir:
git clone https://github.com/AdanedhelWrites/tech-radar.git
cd tech-radar/cybersecurity_news
cp .env.example .env
docker compose up -d --build| Servis | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API | http://localhost:8000/api/ |
| Container | Image | Port | Gorev |
|---|---|---|---|
teknoloji-api |
teknoloji-haberleri-api:latest |
8000 | Django REST API, scraping, ceviri |
teknoloji-frontend |
node:22-alpine |
3000 | React arayuz (Vite dev server, hot-reload; kaynak bind mount) |
teknoloji-translate |
libretranslate/libretranslate:v1.9.6 |
— (kume ici 5000) | Yerel ceviri; yalniz en,tr modelleri, ilk acilista ~258 MB indirir (volume teknoloji-translate-models); 4 CPU / 2 GB siniri |
teknoloji-redis |
redis:7-alpine |
6379 | Cache + Celery message broker (volume teknoloji-redis-data) |
teknoloji-worker |
teknoloji-haberleri-api:latest |
— | Arka plan scraping + ceviri (celery worker) |
teknoloji-scheduler |
teknoloji-haberleri-api:latest |
— | Periyodik gorev zamanlayici (celery beat) |
yerel-postgres (ayri repo: yerel-platform) |
postgres:16.15-alpine |
127.0.0.1:5432 | Paylasilan yerel PostgreSQL; CyberNews cybernews veritabanini ve kullanicisini kullanir |
Container'lar teknoloji-network bridge agi uzerinden haberlesir; api, worker ve scheduler ayrica yerel-platform adli dis aga baglanir (PostgreSQL oradadir). Compose kaynak kodu /app'e bind mount eder; api entrypoint.sh ile acilista migrate + collectstatic calistirir (RUN_STARTUP_TASKS=true). Ayni imaj Kubernetes'te salt okunur kok dosya sistemiyle ve bu adimlar kapali calisir.
# Baslat
docker compose up -d --build
# Durdur
docker compose down
# Loglari izle
docker compose logs -f teknoloji-api
docker compose logs -f teknoloji-worker
# Redis cache temizle
docker compose exec teknoloji-redis redis-cli FLUSHDB
# PostgreSQL shell
docker exec -it yerel-postgres psql -U cybernews -d cybernews
# Django shell
docker compose exec teknoloji-api python manage.py shell
# Sifirdan baslat (volume'lar dahil)
docker compose down -v && docker compose up -d --build2026-10'da canli veri SQLite'tan PostgreSQL'e tasindi (ADR-0007). Ayni araclar her iki yonde calisir:
# Tam hassasiyetli dump (mikrosaniye ve metin bosluklari korunur). Dosya HASSASTIR:
# parola hash'leri ve API token'lari icerir; commit etmeyin, is bitince silin.
python manage.py veri_tasi_dump .fazb/dump.json
# Hedefte: migrate, sonra standart loaddata
python manage.py loaddata .fazb/dump.json
# Iki veritabaninda calistirip ciktilari karsilastirin; fark yoksa tasima kayipsizdir
python manage.py veri_ozetiDjango'nun dumpdata komutu bu is icin kullanilmaz: JSON bicimi tarihleri milisaniyeye kirpar (v1 imleci mikrosaniye tasir), XML bicimi metin bosluklarini kaybeder.
"Sifirla" butonlari (POST /api/{bolum}/clear/) veritabanini sildigi icin yalnizca Django admin yetkisiyle calisir; oturum yoksa 403 doner. Ilk kurulumda bir yonetici olusturun:
docker compose exec teknoloji-api python manage.py createsuperuserArdindan http://localhost:8000/admin/ adresinden giris yapin. Oturum cerezi ayni tarayicidaki frontend isteklerinde de kullanilir; axios CSRF token'i csrftoken cerezinden otomatik ekler.
941 Django testi news/tests/ altindadir ve news/test_runner.py (GuvenliTestRunner) ile kosar. Calistirici uc garanti verir: hicbir test gercek LibreTranslate'e gitmez (LIBRETRANSLATE_URL bos), hicbir test gercek Gemini'ye gitmez (GEMINI_API_KEY bos), hicbir test canli Redis devre kesicisini okumaz veya acmaz (kapilar surec ici). Saglayici testleri adresi/anahtari override_settings ile kendileri verir ve HTTP'yi mock'lar.
# Canli compose yigininda (ayni PostgreSQL sunucusunda ayri test veritabani acilir)
docker compose exec teknoloji-api python manage.py test news --noinput
# Tek kullanimlik PostgreSQL + Redis ile, canli yigina dokunmadan (CI ile ayni yol)
scripts/pg_test.sh test news --noinput
# Hostta SQLite ile hizli deneme (DEBUG=True, DB_HOST bos)
scripts/pg_test.sh --sqlite test news.tests.test_cursorFrontend'de ESLint (flat config, frontend/eslint.config.js; npm run lint) CI'da build'den once kosar: @eslint/js onerilenleri, react-hooks/rules-of-hooks (hata) ve exhaustive-deps (uyari). Bolum sayfalarindaki 5 sn'lik liste yenileme hooks/useAraliklaYenile ile sekme arka plandayken durur.
Frontend birim testleri Vitest + Testing Library ile frontend/src/**/*.test.{js,jsx} altindadir (npm test); CI'da lint ile build arasinda kosar. 298 test, 25 dosya; kapsam: liste sorgusu hook'lari (useListeSorgusu), sayfa cubugu (SayfaCubugu), rapor olusturma (utils/rapor.js), HTML kacisi (utils/html.js), goreli zaman (utils/zaman), aralikli yenileme hook'u, ceviri rozeti, saglik seridi (SaglikSeridi), Genel Bakis (genel/), ortak okuma paneli (okuma/, utils/okuma*.js), ?kayit= baglantisi (useSeciliKayit), bolum sayfalari (bolum/), CVE listesi ve son ziyaret (utils/sonZiyaret.js, useZiyaretTabani). Worker baslatma zaman asimi gorulurse (Windows bind mount'ta yavas kurulum) npm test -- --maxWorkers=2 ile kosun; o da asarsa frontend'i konteynerin kendi dosya sistemine (or. /tmp) kopyalayip orada kosun (tum takim ~10 sn).
CI (Backend (Django testleri)) testleri PostgreSQL 16 servisiyle, DEBUG=False ve gercek bir SECRET_KEY ile kosar; migration'larin eksiksiz oldugu (makemigrations --check) ayni iste dogrulanir. Yeni bir test yazarken kodu gecici olarak bozup testin kirmiziya dondugunu gorun; mock'lanmis saglayici testlerinde "yesil ama hicbir seyi sinamiyor" tuzagi kolaydir.
| Test dosyasi grubu | Kapsam |
|---|---|
test_cursor, test_filters, test_refresh, test_jobs, test_status, test_schema, test_auth |
/api/v1/ sozlesmesi: imlec, parametreler, kilit/soguma, is takibi, status, OpenAPI, token |
test_translation*, test_gemini, test_retranslate |
Terim koruma, parca bolme, post-processing, saglayici zinciri, devre kesici, butce, yukseltme |
test_saklama, test_fetchrun, test_eski_fetch_kapisi |
RETENTION_DAYS sil/yeniden yaz dongusu, FetchRun kaydi, eski /api/*/fetch/ uclarinin v1 kapisindan gecmesi |
test_ayar_dogrulama, test_admin, test_cache, test_altyapi, test_modeller |
SECRET_KEY/DB_HOST korumalari, admin yetkisi, cache, model kisitlari |
test_migrations_*, test_veri_tasima |
Veri migration'lari ve SQLite -> PostgreSQL tasima araclari |
test_kaynak_sagligi, test_saglik |
Kaynak sagligi (kadans farkindalikli sessizlik), anonim /api/saglik/ |
DEBUG varsayilani False oldugu icin anahtarsiz python manage.py ... reddedilir. Yerelde iki secenek:
# Konteynerde (onerilen; ortam compose'tan gelir)
docker compose exec teknoloji-api python manage.py <komut>
# Hostta SQLite ile (yalniz deneme)
DEBUG=True python manage.py <komut>Frontend icin frontend/ altinda npm install && npm run dev yeterlidir; vite.config.js /api'yi localhost:8000'e proxy'ler. Compose'daki dev sunucusu calisirken hosttan npm install yapmayin (bind mount node_modules ve EACCES); once docker compose stop teknoloji-frontend.
| Komut / betik | Ne yapar |
|---|---|
manage.py veri_tasi_dump <dosya> |
Tam hassasiyetli (mikrosaniye koruyan) JSON dump; hassas icerik, commit edilmez |
manage.py veri_ozeti |
Model basina satir sayisi ve alan ozeti; iki veritabanini karsilastirmak icin |
manage.py bozuk_cevirileri_isaretle |
Turkce metninde XTRM yer tutucu kalintisi olan ya da Ingilizce kalmis (Turkce harf yok, kelimelerin %90'i orijinalde) 'cevrildi' kayitlari bulup needs_translation isaretler, deneme sayacini sifirlar; varsayilan rapor, --uygula yazar |
manage.py cve_baslik_cevir |
Basligi Ingilizce kalmis onemli (CVSS >= 7 / KEV) GHSA/KEV CVE basliklarini Gemini paketiyle bir kez cevirir; dusuk/orta ve reddedilen basliklar Ingilizce kalir; yalniz turkish_title yazilir; varsayilan rapor, --uygula yazar |
scripts/pg_test.sh |
Tek kullanimlik PostgreSQL + Redis'e karsi manage.py; canli yigina dokunmaz |
scripts/ornek_istemci.py |
/api/v1/ delta senkron ornegi (yalniz standart kutuphane) |
scripts/helm_yerel_dogrulama.sh imaj|kur|sok |
Chart'i yalniz docker-desktop'ta gercek kurulumla dogrular (S1-S7) |
scripts/chart_surum_kontrol.sh <taban-ref> |
Chart dizini degistiyse Chart.yaml version artmis ve CHANGELOG girdisi var mi (CI kapisi) |
scripts/imaj_etiket_kontrol.sh <render.yaml> |
Render'daki imajlar etiketli mi, latest yok mu, ucuncu taraf imajlar digest ile sabit mi (CI kapisi) |
scripts/chart_etiket_kontrol.sh chart-<surum> |
chart-* etiketi Chart.yaml ile ayni mi (etiket push'unda CI kapisi) |
scripts/zap_sarif.py <report_json.json> <cikti.sarif> |
ZAP JSON raporunu SARIF 2.1.0'a cevirir (DAST is akisi zap-baseline ve zap-api kategorileriyle Security sekmesine yukler) |
- Kod, yorum ve commit mesajlari ASCII Turkce (diakritiksiz).
mainkorumalidir: her degisiklik bir daldan PR ile gelir, bes zorunlu check (Backend,Frontend,Helm / Compose,dependency-review,gitleaks) yesil ve dalmainile guncel olmadan merge edilemez; dogrudan push kapalidir. - Her onemli karar bir ADR'dir (
docs/ADR-*.md); tasarim ve uygulama planlaridocs/superpowers/altindadir. - Sir degerleri (anahtar, parola, token) hicbir dosyaya, log'a veya ekrana yazilmaz;
.envve.fazb/gitignore'dadir, gitleaks her PR'da tarar. helm/tech-radar/altindaki her degisiklik chart surumunu artirir ve CHANGELOG girdisi ister (bkz. Surumleme).- Python:
ruff check .(yalniz F ve E9;pyproject.toml) ve coverage esigi (MIN_COVERAGE, CI) kapidir; yereldepy -3 -m venv .venv && .venv/Scripts/pip install -r requirements-dev.txt.
Her sayfa ayni duzeni takip eder:
- Sol panelden gun araligini (1-15 / DevTools ve Yapay Zeka icin 1-60) ve kaynaklari secin
- "Getir" butonuna tiklayin
- Cekim arka planda (Celery worker) baslar; cevrilen haberler orta panele birkac saniye icinde otomatik duser
- Bir habere tiklayarak sag panelde detayini goruntuleyin
Ek butonlar:
- Yenile — Mevcut verileri yeniden yukler
- Sifirla — Tum verileri temizler (yonetici girisi gerekir, bkz. Yonetici Hesabi)
- Indir — Koyu temali HTML rapor olarak disa aktarir
Her bolum (news, cve, k8s, sre, devtools, ai) ayni endpoint yapisini kullanir:
| Method | Endpoint Deseni | Aciklama |
|---|---|---|
| GET | /api/{bolum}/ |
Kayitli verileri listele (filtre, siralama ve sayfalama parametreleri asagida) |
| POST | /api/{bolum}/fetch/ |
Arka planda cekim baslat — Celery task (body: {"days": 7, "sources": [...]}) |
| POST | /api/{bolum}/clear/ |
Tum verileri sil (yonetici oturumu gerekir, aksi halde 403) |
| GET | /api/{bolum}/stats/ |
Istatistikleri getir: {success, total, by_source, last_update}; CVE'de ayrica by_severity, Kubernetes'te by_category, DevTools'ta by_type |
| GET | /api/saglik/ |
Bolum basina son basarili cekim, son durum, ceviri bekleyen/vazgecilen, yukseltmeden vazgecilen (upgrade_given_up), sessiz kaynaklar; ust duzeyde translation_budget.gemini (Gemini gunluk butcesi) (anonim, 60 sn cache) |
| GET | /api/gundem/ |
Gundem karti: son 72 saatin en cok 6 olayi, CVE haric (anonim, 120 sn cache). Yanit {success, olaylar[], hesaplandi}; her olay {bolum, kayit, kaynak_sayisi, kaynaklar[], diger_kaynaklar[], makale_sayisi, bolumler[], puan, ilk, son} (diger_kaynaklar: temsilcinin kaynagi disindaki her kaynaktan bir makale {kaynak, baslik, link, bolum, id}; okuma paneli bunlari "Ayni olayi yazan diger kaynaklar" olarak listeler) (kayit bolumun kendi serilestiricisinin ciktisidir). Hesap hatasinda 500 yerine 200 {success: false, olaylar: []} doner ve cache'e yazilmaz |
| GET | /api/ozet/ |
Genel Bakis ozeti: critical_count (CVSS >= 9.0, son 24 sa), high_count (7.0-8.9, son 7 gun), kev_count (kev_added_date son 7 gun), priority (en fazla 5 oncelikli CVE), chart (CVSS noktalari), unscored_count, sources{total,silent}, fetch{last_success_at,next_at}; ?since=<ISO tarih> ile ek olarak new_since_count (anonim, 60 sn cache; new_since_count cache'e girmez) |
Bolum isimleri: news (Siber Guvenlik, fetch endpoint: /api/fetch/), cve, k8s, sre, devtools, ai
Alti liste ucu (/api/news/, /api/cve/, /api/k8s/, /api/sre/, /api/devtools/, /api/ai/) sorguyu veritabanindan yapar; bolum basina liste cache'i yoktur (eski 100 kayitlik cache 2026-11-05'te kaldirildi). Filtre ve siralama created_at alanina gore calisir. Gecersiz deger hata vermez, varsayilana duser.
| Parametre | Degerler | Aciklama |
|---|---|---|
gun |
1, 3, 7, 14, 30 |
Son N gun; yoksa tum kayitlar |
sirala |
yeni (varsayilan), eski; CVE'de ayrica cvss |
Siralama |
sayfa |
1, 2, ... | Sayfa numarasi; son sayfayi asan deger son sayfaya indirilir |
boyut |
varsayilan 25, en fazla 100 | Sayfa boyutu |
kaynak |
virgulle ayrilmis liste | Kaynak adi tam eslesme |
ara |
metin (2-100 karakter) | Basliklarda ve aciklamalarda buyuk/kucuk harf duyarsiz arama; CVE'de cve_id'de de |
id |
kayit kimligi | Tekil kayit: diger parametreler yok sayilir, yanit ayni zarfla 0 ya da 1 kayit tasir (?kayit= paylasilan baglanti) |
onem |
CVE: kritik, yuksek, orta, dusuk |
CVSS araliklari |
kategori |
Kubernetes: kubernetes |
Kategori filtresi |
Yanit: {success, data, cached, count, toplam, sayfa, sayfa_sayisi, boyut}. cached geriye uyumluluk icin kalir ve her zaman false'tur; count sayfadaki kayit sayisi, toplam filtreye uyan tum kayit sayisidir. Ornek: /api/cve/?gun=30&sirala=cvss&onem=kritik&sayfa=2. /api/v1/ degismedi.
Not: Siber guvenlik bolumunun fetch, clear ve stats endpoint'leri
/api/news/altinda degil, dogrudan/api/altindadir:/api/fetch/,/api/clear/,/api/stats/Kaldirilan uclar (2026-11-05):
/api/{bolum}/export/(tum tabloyu tek yanitta donduruyordu). HTML rapor arayuzde liste ucundan kurulur (frontend/src/utils/rapor.js); toplu veri isteyen dis tuketiciler/api/v1/imlecli listesini kullanir.
Yukaridaki /api/* uc noktalari React arayuzune hizmet eder. Dis tuketici uygulamalar /api/v1/ kullanmalidir: token ister, cache'e hic bakmaz, imlecli delta ile hicbir kaydi atlamadan ve tekrar islemeden senkron yapilmasini saglar. Karar gerekcesi icin ADR-0003.
Calisan ornek: scripts/ornek_istemci.py — alti bolumu bastan sona ceker, imleci diske yazar, yalnizca standart kutuphane kullanir.
Token'lar Django admin'den uretilir ve iptal edilir:
# Kullanici olustur (yoksa) ve token uret
docker compose exec teknoloji-api python manage.py shell -c "
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
u, _ = User.objects.get_or_create(username='entegrasyon')
print(Token.objects.get_or_create(user=u)[0].key)
"Her istekte Authorization: Token <key> basligi gonderilir. Admin arayuzunde Auth Token → Tokens ekranindan da uretilebilir ve iptal edilebilir.
| Method | Uc nokta | Aciklama |
|---|---|---|
| GET | /api/v1/schema/ |
OpenAPI 3 semasi (token gerekir) |
| GET | /api/v1/docs/ |
Swagger UI — tarayicida admin oturumuyla acilir |
| GET | /api/v1/health/ |
Servis ayakta mi — tokensiz (Kubernetes probe'lari icin) |
| GET | /api/v1/status/ |
Bolum basina veri tazeligi: last_success_at, last_status, last_fetched_count, last_saved_count, pending_translation, translation_given_up, total; kaynak sagligi: sources{ad: last_record_at, last_fetched_count, zero_runs, expected_gap_days, days_since_record, silent} ve silent_sources[]; silent = zero_runs >= SOURCE_SILENT_RUNS VE (hic kayit yok VEYA days_since_record > expected_gap_days) |
| GET | /api/v1/{bolum}/ |
Imlecli delta okuma |
| POST | /api/v1/{bolum}/refresh/ |
Tek bolum icin manuel cekim tetikler |
| POST | /api/v1/refresh/ |
Alti bolumu birden tetikler |
| GET | /api/v1/jobs/{job_id}/ |
Manuel tetiklenen isin durumu |
Bolum isimleri: news, cve, kubernetes, sre, devtools, ai — dikkat: v1'de k8s degil kubernetes.
curl -H "Authorization: Token $CYBERNEWS_TOKEN" \
"http://localhost:8000/api/v1/cve/?limit=200&min_severity=high"Yanit zarfi:
{
"results": [ ... ],
"next_cursor": "eyJ1IjoiMjAyNi0wOS0yMFQyMjowODo1Mi43MDE4MzErMDA6MDAiLCJpIjoxMDM2NX0",
"has_more": true,
"count": 200
}Dongu: next_cursor'i sakla, bir sonraki istekte ?since_cursor=<deger> olarak gonder, has_more false olana kadar tekrarla. Imlec opaktir — (updated_at, id) ikilisinin kodlanmis halidir, ic bicimi haber verilmeden degisebilir; acma, yalnizca sakla ve geri gonder. next_cursor bos sonucta bile doner ki saklayacak bir degerin hep olsun. Siralama her zaman updated_at ASC, id ASC'dir; bu akis sirasidir, ekrana basma sirasi degildir.
Ilk senkronda tum kayitlar yeni gorunur. Daraltmak icin ?since=YYYY-MM-DD kullanilabilir (yalnizca imlec yokken gecerlidir).
| Parametre | Bolumler | Aciklama |
|---|---|---|
since_cursor |
hepsi | Opak imlec; verildiginde since yok sayilir |
since |
hepsi | YYYY-MM-DD — ilk senkronu daraltmak icin |
limit |
hepsi | Varsayilan 100, tavan 500 |
source |
hepsi | Virgulle ayrilmis kaynak adlari |
needs_translation |
hepsi | true / false — cevirisi bekleyenler |
min_severity |
cve |
low | medium | high | critical — esik ve uzeri |
severity |
cve |
Virgulle ayrilmis tam eslesme (critical,high) |
category |
kubernetes |
Virgulle ayrilmis kategori |
entry_type |
devtools |
Virgulle ayrilmis tur |
Gecersiz parametre sessizce yok sayilmaz; 400 invalid_parameter doner.
Tuketici tarafi upsert (idempotent) olmalidir; salt insert cift kayit uretir. updated_at icerik degismese de ilerleyebilir, yani ayni kayit akista birden fazla kez gorunur.
Birlestirme anahtari olarak id kullanilmamalidir. id kalici degildir: saklama penceresi (RETENTION_DAYS) disina dusen bir kayit silinir ve kaynak onu tekrar dondurdugunde yeni bir id ile geri gelir. Kararli anahtarlar:
| Bolum | Upsert anahtari |
|---|---|
cve |
cve_id |
news, kubernetes, sre, devtools, ai |
link |
Bunlar yazma yolunun da anahtarlaridir: news/tasks.py ayni alanlarla update_or_create yapar. Gerekce ve olcumler icin ADR-0005.
Uyari: Bes bolumden dordunde (
kubernetes,sre,devtools,ai)linkveritabanindaunique=True,cveicincve_idde oyle.newsbolumundelinkuzerinde benzersizlik kisiti yoktur — anahtar yazma yolunun sozlesmesidir, sema garantisi degildir. Tuketici kendi tarafinda benzersiz indeks tanimlamalidir.
Silmeler akista bildirilmez (tombstone yok); tuketici kendi saklama suresini uygular.
Baslik ve aciklama ic ice doner ve severity normalize edilir:
{
"title": { "original": "Critical RCE in ...", "tr": "... kritik RCE" },
"severity": { "code": "critical", "label": "Kritik" },
"needs_translation": false,
"translation_provider": "gemini"
}Tuketici title.tr || title.original yazarak cevirisi henuz hazir olmayan kayitta Ingilizceye duser — kayit kaybolmaz, Turkcesi hazir olunca updated_at ilerledigi icin ayni anahtar uzerine guncelleme gelir. Filtreler severity'nin code degeri uzerinden calisir.
curl -X POST -H "Authorization: Token $CYBERNEWS_TOKEN" \
http://localhost:8000/api/v1/cve/refresh/202 ile {"job_id", "section", "status", "status_url"} doner; durum /api/v1/jobs/{job_id}/ ile izlenir. Uc katman korur: bolum kilidi (REFRESH_LOCK_TTL) cift kazimayi onler, paylasilan bolum sogumasi (REFRESH_COOLDOWN) kaynak siteleri ve ceviri kotasini korur, token basina hiz siniri tek istemciyi sinirlar. Sogumadaki bolum 429 cooldown ve Retry-After basligi dondurur. Toplu /api/v1/refresh/ her zaman 202 doner; govdede started / already_running / skipped listeleri bulunur.
| Kapsam | Oran |
|---|---|
Okuma (v1_read) |
token basina 120/dk |
Tetikleme (v1_refresh) |
token basina 12/saat |
| Bolum sogumasi | REFRESH_COOLDOWN (900 sn) — tum token'lar arasinda paylasilir |
Tum v1 hatalari ayni bicimde doner:
{ "error": { "code": "invalid_cursor", "message": "Imlec cozulemedi: ..." } }| Kod | HTTP | Ne zaman |
|---|---|---|
unauthorized |
401 | Token yok, gecersiz veya iptal edilmis |
invalid_cursor |
400 | since_cursor cozulemedi |
invalid_parameter |
400 | Parametre bicimi veya degeri gecersiz |
not_found |
404 | refresh/ icin bilinmeyen bolum; bilinmeyen veya suresi dolmus job_id |
throttled |
429 | Hiz siniri asildi |
cooldown |
429 | Bolum sogumada (Retry-After basligi ile) |
internal |
500 | Beklenmeyen sunucu hatasi |
Not: Bu sozlesme yalnizca tanimli uc noktalar icin gecerlidir. Hic rotasi olmayan bir yol — ornegin
GET /api/v1/k8s/, cunku v1'de bolum adikubernetes'tir — DRF'e hic ulasmadan Django'nun duz HTML 404'unu dondurur, JSON gelmez. Tuketici yanit govdesini ayristirmadan onceContent-Type'i kontrol etmelidir. Buna karsilikPOST /api/v1/k8s/refresh/rotalidir ve duzgun{"error": {"code": "not_found", ...}}dondurur.
/api/v1/schema/ OpenAPI 3 dokumani dondurur ve yalnizca /api/v1/ uclarini
kapsar; eski /api/* uclari bilincli olarak disaridadir.
curl -H "Authorization: Token $CYBERNEWS_TOKEN" \
http://localhost:8000/api/v1/schema/ -o cybernews-v1.yamlSemadan istemci uretilebilir (openapi-generator vb.). /api/v1/docs/ ayni
semayi Swagger UI ile gosterir; tarayici Authorization basligi gondermedigi
icin bu sayfa admin'de oturum acmis bir kullaniciyla acilir.
Not: Sema yayimlandigi andan itibaren dis sozlesmedir. Bir alanin tipi degisirse bu artik "dokumantasyon hatasi" degil, tuketicinin istemcisini kiran bir degisikliktir.
cybersecurity_news/
├── cybernews/ # Django proje ayarlari
│ ├── settings.py # Env-var tabanli config (DB, Redis, CORS, CSP)
│ ├── guvenlik_basliklari.py # Permissions-Policy, CORP, COEP middleware'i
│ ├── urls.py # Root URL yapilandirmasi
│ ├── celery.py # Celery yapilandirmasi
│ └── wsgi.py
│
├── news/ # Ana Django uygulamasi
│ ├── models.py # NewsArticle, CVEEntry, KubernetesEntry, SREEntry, DevToolsEntry, AINewsEntry
│ ├── views.py # API endpoint'leri (6 bolum x 4 endpoint + saglik, ozet, gundem)
│ ├── tasks.py # Celery task'lari (cekim + ceviri)
│ ├── serializers.py # DRF serializer'lari
│ ├── urls.py # API URL pattern'leri
│ ├── translation_utils.py # Merkezi ceviri modulu (terim koruma + post-processing)
│ ├── translation_providers.py# Saglayici zinciri: LibreTranslate (cekim) + devre kesici
│ ├── gemini.py # Gemini API istemcisi, hiz siniri, gunluk butce, tur payi
│ ├── kayit_cevirmenleri.py # Ucretsiz yedek cevirmenler: Gemini 2. model, OpenRouter, DeepL Free + zincir
│ ├── retranslate.py # Bekleyenleri cevir + LibreTranslate kayitlarini Gemini'ye yukselt (yedek zincirle)
│ ├── liste_sorgusu.py # Liste ucleri icin filtre, siralama ve sayfalama sorgusu
│ ├── gundem.py # Gundem: olay gruplama ve puan (saf fonksiyonlar, /api/gundem/)
│ ├── veri_tasima.py # Tam hassasiyetli dump/ozet (SQLite -> PostgreSQL gecisi)
│ ├── test_runner.py # GuvenliTestRunner: testler gercek saglayiciya gitmez
│ ├── management/commands/ # veri_tasi_dump, veri_ozeti, bozuk_cevirileri_isaretle, cve_baslik_cevir, cve_aciklama_tamamla
│ ├── tests/ # 941 test (v1 sozlesmesi, ceviri, saklama, migration, ayar, gundem)
│ │ └── fixtures/gundem_basliklari.json # Gundem gruplama testlerinin gercek baslik ornekleri
│ ├── base_scraper.py # Ortak RSS okuyucu (BaseRSSScraper)
│ ├── ai_scraper.py # 9 Yapay Zeka kaynagi scraper'i
│ ├── cve_scraper.py # 5 CVE kaynagi scraper'i
│ ├── k8s_scraper.py # 3 Kubernetes kaynagi scraper'i
│ ├── sre_scraper.py # 5 SRE kaynagi scraper'i
│ ├── devtools_scraper.py # 13 DevTools kaynagi scraper'i
│ ├── fetch_runs.py # FetchRun satirlarini yazan Celery sinyalleri
│ ├── api_v1/ # Dis tuketici entegrasyon katmani (ADR-0003)
│ │ ├── views.py # Delta, refresh, jobs, status, health uc noktalari
│ │ ├── serializers.py # v1 serializer'lari (alanlar tek tek yazilir)
│ │ ├── cursor.py # (updated_at, id) keyset imleci
│ │ ├── filters.py # Query parametresi ayristirma
│ │ └── refresh.py # Bolum kilidi, soguma, job kaydi
│ └── admin.py # Django admin kayitlari
│
├── scripts/
│ ├── ornek_istemci.py # /api/v1/ delta senkron ornegi (stdlib-only)
│ ├── pg_test.sh # Tek kullanimlik PostgreSQL + Redis ile manage.py / testler
│ ├── helm_yerel_dogrulama.sh # Chart'i yalniz docker-desktop'ta dogrular (S1-S7)
│ ├── chart_surum_kontrol.sh # CI kapisi: chart degistiyse surum + CHANGELOG
│ ├── imaj_etiket_kontrol.sh # CI kapisi: render'da etiketsiz / latest imaj yok
│ ├── chart_etiket_kontrol.sh # CI kapisi: chart-<surum> etiketi Chart.yaml ile ayni
│ └── zap_sarif.py # ZAP JSON raporu -> SARIF (DAST bulgulari Security sekmesine)
│
├── scraper_multi.py # 12 siber guvenlik kaynagi scraper'i
│
├── frontend/ # React SPA
│ ├── src/
│ │ ├── App.jsx # Router, Navbar (yalniz koyu tema), Genel Bakis rotasi
│ │ ├── App.css # Duzen stilleri
│ │ ├── styles/tema.css # Koyu tema token'lari ve bilesen stilleri
│ │ ├── components/
│ │ │ ├── NewsComponent.jsx # Siber guvenlik sayfasi
│ │ │ ├── CVEComponent.jsx # CVE sayfasi
│ │ │ ├── KubernetesComponent.jsx # Kubernetes sayfasi
│ │ │ ├── SREComponent.jsx # SRE sayfasi
│ │ │ ├── DevToolsComponent.jsx # DevTools sayfasi
│ │ │ ├── AINewsComponent.jsx # Yapay Zeka sayfasi
│ │ │ ├── CeviriEtiketi.jsx # Ceviri saglayici rozeti
│ │ │ ├── genel/ # Genel Bakis: durum kutulari, CVSS grafigi, oncelikli liste, gundem
│ │ │ ├── bolum/BolumSayfasi.jsx # Bolum sayfalari icin ortak liste + panel iskeleti
│ │ │ ├── bolum/HaberBolumu.jsx # Haber bolumleri icin ortak filtre cubugu + liste
│ │ │ ├── bolum/SayfaCubugu.jsx # Numarali sayfa cubugu
│ │ │ ├── bolum/secenekler.js # Donem, siralama ve onem secenekleri
│ │ │ ├── cve/CveSatiri.jsx # CVE liste satiri
│ │ │ └── okuma/OkumaPaneli.jsx # Ortak okuma paneli (Turkce varsayilan, orijinal istege bagli)
│ │ ├── hooks/useSeciliKayit.js # ?kayit= derin baglantisi
│ │ ├── hooks/useListeSorgusu.js # Filtre/siralama/sayfa durumu <-> adres
│ │ ├── hooks/useBolumVerisi.js # Bolum listesini sunucudan ceker (sayfali)
│ │ ├── utils/rapor.js # Mevcut filtrelerle HTML rapor (en fazla 500 kayit)
│ │ └── services/
│ │ └── api.js # Axios API servisleri
│ ├── Dockerfile # Production build: Node 22 + Nginx 1.31 (non-root)
│ ├── .dockerignore # node_modules bind mount'u build'i bozmasin
│ ├── nginx.conf # SPA routing + /api proxy
│ ├── vite.config.js # Dev proxy ayarlari
│ ├── index.html
│ └── package.json
│
├── docs/
│ ├── ADR-0001 ... ADR-0008 # Mimari karar kayitlari
│ ├── GUVENLIK-PLANI.md # Guvenlik hatti: hatlar, bulgu yerleri, bekleyen isler
│ └── superpowers/
│ ├── specs/ # Tasarim belgeleri (karar + gerekce + testler)
│ └── plans/ # Uygulama planlari (gorev gorev) ve devir notlari
│
├── .github/workflows/ # CI, codeql, trivy, gitleaks, dast-zap, dependency-review,
│ # zizmor, scorecard, chart-etiket (bkz. CI ve Guvenlik Hatti)
│
├── helm/tech-radar/ # Helm chart (tek dagitim kaynagi; surum: Chart.yaml)
│ ├── Chart.yaml # version (SemVer) + appVersion (imaj etiketi)
│ ├── CHANGELOG.md # Chart surumleri ve yukseltme notlari
│ ├── values.yaml # Varsayilan degerler (gizli deger icermez)
│ ├── ci/yerel-values.yaml # Yerel docker-desktop dogrulamasi
│ ├── ci/argocd-values.yaml # CI'da Argo CD + VSO modunda render
│ ├── .helmignore
│ └── templates/
│ ├── _helpers.tpl # Imaj, guvenlik baglami, ortam, ALLOWED_HOSTS yardimcilari
│ ├── configmap.yaml
│ ├── secret.yaml # secretKey ve dbPassword zorunlu
│ ├── postgresql.yaml # postgresql.enabled
│ ├── redis.yaml # redis.enabled
│ ├── libretranslate.yaml # libretranslate.enabled
│ ├── backend.yaml
│ ├── frontend.yaml
│ ├── celery.yaml # Worker + Beat
│ ├── migration-job.yaml # helm: teknoloji-migrate-r<N>; argocd: sabit adli Sync hook
│ ├── ingress.yaml # ingress.enabled
│ └── NOTES.txt
│
├── docker-compose.yml # 6 servis (PostgreSQL ayri: yerel-platform)
├── Dockerfile # Backend multi-stage build (non-root, digest sabitli taban)
├── entrypoint.sh # Startup: wait-for-db + migrate + collectstatic (compose)
├── requirements.txt # Python bagimliliklari (surumler sabit)
├── SECURITY.md # Zafiyet bildirimi: GitHub private vulnerability reporting
├── .env.example # SECRET_KEY, DB_PASSWORD (zorunlu), GEMINI_API_KEY, yedek ceviri anahtarlari, GITHUB_TOKEN
├── .gitleaksignore # Gecmis commit'lere sabitli placeholder baseline'i (silinmez)
├── .gitignore # .env, .fazb/, db.sqlite3*, staticfiles/, node_modules
├── .dockerignore # .env ve .env.* imaja girmez
└── manage.py
Depo kokundeki
scraper*.py,gui*.pyverequirements_*.txtdosyalari projenin ilk masaustu/CLI surumunden kalmadir; web uygulamasi bunlari kullanmaz.
Tum scraper'lar news/translation_utils.py merkezi modulunu kullanir. 3 katmanli mimari:
Ceviri oncesinde 130+ teknik terim XTRM####X formatiyla placeholder'lara donusturulur. Ceviri sonrasi geri yerlestirilir. Ek olarak:
- URL'ler (
https://...) otomatik korunur - Surum numaralari (
v1.2.3,9.3.1) otomatik korunur - CVE numaralari (
CVE-2024-12345) otomatik korunur - Backtick kod parcalari (
`kubectl get pods`) otomatik korunur - SIG etiketleri (
[SIG Node]) otomatik korunur - GitHub URL'leri ve paket isimleri otomatik korunur
Terimler uzunluktan kisaya siralanarak islenir — kisa terimlerin kelime icinde eslesmesin onlenir.
Uzun metinler cumle sinirlarindan 4500 karakterlik parcalara bolunur (saglayici istek boyutu sinirlarini asmamak icin). Her parca icin ayri terim koruma uygulanir. LibreTranslate bu parcalari kendi icinde ayrica 160 karakterlik alt parcalara boler (LIBRETRANSLATE_CHUNK_CHARS); Gemini yukseltmesi ise birden cok kaydi tek istekte paketler (bkz. Retranslate ve Gemini Yukseltme).
Ceviri sonrasi otomatik duzeltmeler:
- Cumle basi ve satir basi buyuk harf
- Noktalama duzeltmeleri (noktadan sonra bosluk, parantez temizligi)
- URL/email/dosya uzantisi korumasi (post-processing'in
.co->. Coyapmasi engellenir) - Ingilizce ay isimlerinin Turkceyecevirisi
- Bozuk Turkce karakter encoding duzeltmesi
- K8s kisaltmasinin korunmasi
- LibreTranslate (cekim aninda) — Baglanti hatasi, zaman asimi veya 5xx gelirse kendi Redis devre kesicisi
LIBRETRANSLATE_COOLDOWN(60 sn, varsayilan) boyunca acilir; 4xx devre kesiciyi acmaz. Yeniden deneme ve ayri bir hiz siniri yoktur, eszamanlilik compose CPU siniriyla dogal olarak sinirlanir. - Gemini (retranslate yukseltmesi) — Istekler arasi en az
GEMINI_MIN_INTERVALsaniye (Redis uzerinden tum worker'lar icin ortak), gunlukGEMINI_DAILY_BUDGETistek tavani (retranslate turlarina yayilir, bkz. Retranslate ve Gemini Yukseltme), gecici 500/502/503/504 ve baglanti kopmasi onceGEMINI_GECICI_BEKLEMELER(varsayilan5,15sn) ile yeniden denenir; 429/5xx ve 401/403/404 sonrasiGEMINI_COOLDOWNsaniye devre kesici. - Kayip yok — Hicbir saglayici cevirmezse haber tam Ingilizce metniyle kaydedilir ve
needs_translation=Trueisaretlenir; sonraki cekimde veyaretranslate_pendingturunde otomatik olarak yeniden denenir.
retranslate_pending Celery Beat gorevi (retranslate-pending-hourly) saatlik calisir: dakika 05, saatler 1-5, 7-11, 13-17 ve 19-23; cekim saatleri (00/06/12/18) atlanir, yani gunde 20 tur. Her tur iki isi yapar: bekleyen (needs_translation=True) kayitlari LibreTranslate ile cevirir (bolum basina imlec sirasiyla), ardindan translation_provider='libretranslate' kayitlari Gemini API (gemini-3.5-flash-lite) ile yukseltir; birden cok kayit tek istekte (paket) cevrilir.
- Onem sinifi: CVE'lerde yalniz CVSS >= 7.0 ya da CISA KEV'deki kayitlar Gemini adayidir; digerleri (dusuk/orta skorlu ya da skoru olmayan) kalici olarak LibreTranslate cevirisiyle kalir, ne bekleyen ne yukseltme asamasinda Gemini'ye gitmez. Diger bolumlerde butun kayitlar adaydir.
- Yeni kayit once: Yukseltme asamasinin imleci yoktur; her tur bolum basina en fazla
RETRANSLATE_UPGRADE_BATCH(CVE'deRETRANSLATE_UPGRADE_BATCH_CVE) kaydicreated_atazalan sirayla (en yeniden eskiye) alir. Eski LibreTranslate birikimi butce kaldikca geriye dogru erir. - Bolum onceligi: Sira CVE, haber, AI, SRE, DevTools, Kubernetes'tir ve katidir: ustteki bolumun adaylari bitmeden alttaki Gemini payi almaz. Bolumler icin ayrilmis bir pay yoktur (
GEMINI_CVE_RESERVEkaldirildi, bkz. ADR-0005). - Paketleme: Yukseltme asamasi adaylari siraya sadik kalarak paketler; paket
GEMINI_BATCH_CHARS(varsayilan 10000) karakteri ya daGEMINI_BATCH_MAX(varsayilan 15) kaydi asmaz. Yapili Kubernetes degisiklik kayitlari paketlenmez, tek basina gider. Paket cevirisi kayit basina dogrulanir; ek olarak capa capraz denetimi (CVE/GHSA numarasi, URL, kod parcasi, 3+ parcali surum) cevirisi baska kaydin capasini tasiyan kaydi reddeder (ayni bicimli yer degisimi onlenir); capasiz kayitlar etkilenmez. Paketli K8s cevirileri de ayni yapi isareti denetiminden gecer. - Bolme: Kesilen (MAX_TOKENS), bozuk yanitli (SAFETY vb. tamamlanmamis ya da cozulemeyen JSON,
yanit_bozuk) ya da kayda ozgu 4xx alan paket ikiye bolunup ayni turda yeniden denenir; yalniz hala basarisiz olan tek kayit deneme sayacini artirir. Bekleyen asama kayit basina calismaya devam eder. - Tur payi: Gunluk butce (
GEMINI_DAILY_BUDGET, varsayilan 450) gune yayilir. Bir turun Gemini payiceil(kalan gunluk butce / Pasifik gece yarisina kadar kalan tur sayisi)'dir ve istek (paket) basina sayilir, kayit basina degil; kullanilmayan pay sonraki turlara kalir. Pay biterse yukseltme asamasistopped_reason='gemini_tur_payi'ile durur, bekleyen kayitlar LibreTranslate ile surer; gunluk butce bitmisse sebepgemini_budgetolur. - Deneme sayaci: Icerik hatasi (Gemini cevirmedi ya da dogrulama gecmedi)
translation_attempts'i artirir;RETRANSLATE_MAX_ATTEMPTS'a ulasan kayit yukseltme adayi olmaktan cikar (/api/saglik/sections[ad].upgrade_given_up). Aktarim ve kota hatalari (zaman asimi, baglanti, 429, 5xx) sayaci artirmaz. Gemini 401/403/404 (anahtar, yetki ya da model adi hatasi) ve anahtar/hesap sorunu bildiren 400 (error.details[].reason=API_KEY_INVALIDya daerror.statusFAILED_PRECONDITION / PERMISSION_DENIED / UNAUTHENTICATED) devre kesiciyi acar ve butceyi geri verir; sayac artmaz. Diger 400'ler kayda ozgu icerik hatasidir. Beklenmeyen istisna (kod hatasi) da devre kesiciyi acar. Savunma katmani: bir bolumde ayni turda 5 ardisik icerik hatasi (ARDISIK_HATA_SINIRI) gelirse o bolumun yukseltmesi o tur durur, kalan adaylar sayilmaz (tur sonucundasections[ad].stopped_reason='ardisik_icerik_hatasi'). - Tekil tur kilidi: Tur, Redis kilidi
retranslate:kilitile korunur (sahip jetonu, TTLmin(RETRANSLATE_TIME_BUDGET + 600, CELERY_TASK_TIME_LIMIT + 60)sn; olu worker'in kilidi sonraki saatlik turu atlatmaz). Onceki tur surerken baslayan tur{'skipped': 'locked'}doner veFetchRunsatiri birakmaz. - Gorunurluk:
/api/saglik/translation_budget.gemini(used,limit,period,available,cooldown) dondurur; ana sayfa saglik seridi "Gemini kullanilan/sinir" gosterir. Bekleyen var ve son 6 bitmis tur (~6 saat) hic kayit cevirmediyse bolumstalledsayilir.
Eski google etiketli kayitlar yukseltilmez, etiketli kalir. 2026-10-21'den once ASCII'ye kaymis Gemini cevirileri (en az 10 kelime, hic Turkce harf yok; Gemini dogrulamasinin turkce harf yok kuraliyla ayni olcut, retranslate._ascii_gemini_cevirisi) de yukseltme adayidir; onem sinifi kurali onlara da uygulanir.
Saglamlastirma (2026-11-07): Scraper turunun sonundaki yazim, tur suresince retranslate'in yazdigi daha iyi ceviriyi ezmez (tasks._kaydet: cevrilmis kaydin ceviri alanlari yalniz en az ayni kalitede basarili ceviriyle yazilir). Gemini kapi ve butce sayaci Redis'e ulasamayinca kurulan yerel yedek 60 sn'de bir Redis'i yeniden dener; donuste yedegin saydigi istekler paylasilan sayaca eklenir. Haber tarihleri metnin icinden ayiklanir (base_scraper.ay_tarihi_coz; The Hacker News tarihindeki ikon karakteri yuzunden butun THN kayitlarina cekim gunu yaziliyordu, goc 0019 duzeltir), okunamayan tarih loga yazilir. RSS akisi HTTP hata kodunu loga yazar (403 artik bos akis gibi gorunmez).
Ceviri dogrulugu (2026-11-07): Son islem (turkish_post_process) yer tutucular geri konmadan once calisir; noktali ve alt cizgili tanimlayicilar (os.environ.get, blazer_usb.c) ve kod parcalari hem terim korumasinda hem son islemde korunur. Gemini her alanin capalarini (CVE/GHSA numarasi, URL, kod parcasi, surum) cevirisinde aynen arar, eksikse reddeder (tek kayit ve paket yolu); talimat bir terim sozlugu tasir (vulnerability -> guvenlik acigi, exploit -> istismar...; commit/branch/pipeline gibi terimler Ingilizce kalir). GHSA ozeti ve KEV zafiyet adi tasiyan CVE basliklari yalniz kayit cevirmeni (Gemini) yolunda cevrilir, yani onem sinifindaki kayitlarda; LibreTranslate kisa teknik basligi orijinalinden kotu cevirdigi icin (11-07 olcumu) dusuk/orta kayitlarin basligi Ingilizce kalir. Scraper'in ceviri istisnasi dali kaydi needs_translation olarak yazar. Etkinlik reklami paragraflari (TechCrunch, KubeCon kayit cagrisi) ceviriden once atilir (metin_temizle._reklam_mi).
Anahtar alma: Google AI Studio (aistudio.google.com) → Get API key → Create API key; cybersecurity_news/.env icine GEMINI_API_KEY=... (gitignore'da). Kart gerekmez; kota asilirsa 429 doner, sistem LibreTranslate ile surer.
Rozetler: Her kayit translation_provider tasir; arayuzde Makine çevirisi: LibreTranslate (sari), Çeviri: Gemini, Çeviri: OpenRouter, Çeviri: DeepL, Çeviri: Google (eski kayitlar).
Kuyruktan dusen kayitlar (translation_attempts >= RETRANSLATE_MAX_ATTEMPTS) arayuzde "Cevrilmedi: orijinal metin" rozetiyle gosterilir (rozet kosulu: needs_translation ve saglayici bos ve translation_attempts >= 1; hic denenmemis taze kayit rozet almaz); admin'de "Ceviri denemelerini sifirla" eylemi secili kayitlari yeniden kuyruga alir. GEMINI_MAX_CHARS (12.000) ustu kayitlar bilerek Ingilizce kalir (2026-10-14 karari).
Gemini'nin ucretsiz kotasi (gunde ~450 istek) yetmedigi ya da Gemini kapali oldugu gunlerde retranslate, ek ucretsiz saglayicilara duser. Zincir sirasi: Gemini birincil (GEMINI_MODEL) → Gemini ikinci model (GEMINI_FALLBACK_MODEL) → OpenRouter (ucretsiz model) → DeepL API Free. Anahtarlari/modeli bos olan halka zincirde yoktur; hepsi bossa davranis yedeksiz kurulumla aynidir (LibreTranslate ile surer).
- Ne zaman devreye girer: Yalniz birincil Gemini gercekten kullanilamazken: gunluk butcesi bitmis, devre kesicisi acik ya da anahtari yok. Bir turun payi (
gemini_tur_payi) bitmesi yedegi tetiklemez; kayit sonraki turu bekler. Yedekler tur payina tabi degildir, kendi sayac ve devre kesicileriyle sinirlidir. Istek duzeyi bir hata secilen yedegi kapatirsa ayni paket/kayit siradaki halkayla yeniden denenir (deneme sayaci artmaz). Bir yedegin ciktisi dogrulamadan gecmezse kayit ayni turda onu denememis siradaki hazir yedege gider; yalniz boyle yedek kalmadiginda deneme sayaci bir kez artar (ardisik hata serisine de bir kez girer; bekleyen asamada LibreTranslate yine son caredir). Birincil Gemini'nin reddi hemen sayilir, cunku birincil hazirken yedekler kullanilmaz. Yeniden secim paket basina sinirlidir (1 + yedek sayisi), yani bir paket sonsuza dek donmaz. - Kimler gider: Onem sinifi aynen gecerlidir: CVE'de yalniz CVSS >= 7 ya da KEV adaydir; CVSS < 7, skorsuz ve KEV disi CVE hicbir cevirmene (yedekler dahil) gitmez, LibreTranslate cevirisiyle kalir. Dogrulama (alan, yapi isareti, capa capraz denetimi) tum saglayicilara ayni uygulanir.
- Yazilan etiket: Basarili ceviride
translation_providersecilen saglayicinin adidir:gemini(birincil ve ikinci model),openrouterya dadeepl.libretranslateetiketli kayitlar yukseltme adayidir; OpenRouter/DeepL ile cevrilmis kayitlar sonradan tekrar yukseltilmez. - Yalniz ucretsiz garantileri: OpenRouter model adi
:freeile bitmiyorsa (ya da bossa) hazir degil sayilir ve istek atilmaz; anahtar girilmis ama model bos ya da ucretli ise surec basina bir kez uyari loglanir. DeepL yalnizapi-free.deepl.comucuna gider (Pro ucu kodda yoktur);:fxile bitmeyen (Free olmayan)DEEPL_API_KEYkullanilmaz, surec basina bir kez uyari loglanir (anahtar loga yazilmaz). Gemini ikinci model ayni anahtarin ayri ucretsiz kotasini kullanir. Gemini birincil ve ikinci model yalniz Google projesinde faturalandirma hesabi (billing) yoksa ucretsiz kalir; faturalandirma acik projede ucretsiz katmani olmayan bir model ucretlendirilir. Hicbir halka ucretli moda gecmez; kota bitince durur. - Sayaclar ve donemler: Gemini ve ikinci model gunluk (Pasifik gunu;
gemini,gemini2onekleri); OpenRouter gunluk (UTC;OPENROUTER_DAILY_BUDGET, aralikOPENROUTER_MIN_INTERVAL); DeepL aylik karakter sayaci (UTC ayi,DEEPL_MONTHLY_CHARS). DeepL 456 (kota doldu) dondurur ya da kalan karakter bir istegi karsilamiyorsa sayac ay tavanina doldurulur ve DeepL ay sonuna kadar kapanir (ay degisince sayac kendiliginden sifirlanir). - Gorunurluk:
/api/saglik/translation_budgetbirincilgemini'ye ek olarak yalniz ayarli yedekleri listeler (gemini2,openrouter,deepl); anahtar degerleri hicbir ozette yer almaz. Ana sayfa saglik seridi, kullanimi 0'dan buyuk olan yedegi gosterir. Rozetler:Çeviri: OpenRouter,Çeviri: DeepL(Gemini ikinci modeliÇeviri: Geminigosterir). - Anahtarlar:
OPENROUTER_API_KEYveDEEPL_API_KEYdegerlerini kullanici kendisi alir ve kendi.envdosyasina yazar (gitignore'da); depoya, imaja ve ornek dosyaya gercek deger girmez. Docker Compose bu degiskenleriteknoloji-apiveteknoloji-worker'a gecirir; Helm'desecrets.openrouterApiKey/secrets.deeplApiKey(chart 3.2.0). - Dagitim sirasi: Migration
0017(translation_providersecenekleriopenroutervedeepl) yalniz secenek listesini degistirir, PostgreSQL'de islem yapmaz; yine de oncemigrate, sonra yeni kod dagitilir.
teknoloji-scheduler container'i, cybernews/settings.py icindeki CELERY_BEAT_SCHEDULE ile tum bolumleri 6 saatte bir (Europe/Istanbul 00:00, 06:00, 12:00, 18:00) otomatik gunceller. Worker ve ceviri yukunu dagitmak icin bolumler 10 dakika arayla kaydirilir:
| Bolum | Task | Dakika | Gun araligi |
|---|---|---|---|
| Siber Guvenlik | fetch_news_task |
:00 | 7 |
| CVE | fetch_cve_task |
:10 | 7 |
| Kubernetes | fetch_k8s_task |
:20 | 30 |
| SRE | fetch_sre_task |
:30 | 30 |
| DevTools | fetch_devtools_task |
:40 | 30 |
| Yapay Zeka | fetch_ai_news_task |
:50 | 30 |
Tum cekimler (manuel "Getir" dahil) skip_existing=True ile calisir: veritabaninda zaten cevrilmis kayitlar tekrar cevrilmez; yalnizca yeni haberler ve ceviri bekleyen (needs_translation) kayitlar LibreTranslate'e gonderilir. Gun araligi task varsayilanidir; her cekim (manuel "Getir" dahil) bu araligin disinda kalan eski kayitlari siler. Bekleyen ve LibreTranslate kayitlarinin Gemini ile yukseltilmesi ayri bir Beat gorevidir (bkz. Retranslate ve Gemini Yukseltme): retranslate_pending_task, saatlik, dakika 05 (cekim saatleri 00/06/12/18 atlanir; gunde 20 tur).
Her cekim bir FetchRun satiri birakir (bolum, baslangic/bitis, fetched_count, saved_count, durum, hata ozeti, kaynak basina by_source). Son durumlar GET /api/v1/status/ ile okunur; Beat'in gercekten calistigini kontrol etmenin en kisa yolu budur (ADR-0006).
Loglar (2026-10-08): Scraper ve ceviri katmani print yerine logging kullanir; kaynak hatalari WARNING seviyesinde, modul adiyla (news.devtools_scraper, scraper_multi) gelir. docker compose logs teknoloji-worker | grep WARNING bir turda hangi kaynaklarin hata verdigini gosterir; LOG_FORMAT=json ile satirlar Loki/ELK'ye dogrudan gider. Worker Django LOGGING ayarini kullanir (CELERY_WORKER_HIJACK_ROOT_LOGGER=False).
Takili turlar (2026-10-09): Worker yeniden basladiginda ya da sert sure siniri (CELERY_TASK_TIME_LIMIT) alt sureci oldurdugunde task_postrun hic gelmez ve satir suresiz running kalirdi (canlida 4 satir, biri 5 gunluk). Ayni bolumun yeni turu acilirken eski running satirlari failure + stopped_reason=interrupted ile kapatilir.
Kaynak sagligi (2026-10-08): 8 kaynak aylarca sessizce olmustu (Bleeping Computer 403, SecurityWeek bos link, MongoDB/InfoQ/DZone donmus akislar); bolum toplami "success" gorundugu icin fark edilmedi. Artik her tur secili her kaynak icin kaynaktan gelen sayiyi (_drop_existing'den onceki) FetchRun.by_source'a yazar. /api/v1/status/ her kaynak icin zero_runs (ardisik 0 donen tamamlanmis tur) ve silent verir; SOURCE_SILENT_RUNS (varsayilan 4 = Beat'te 24 saat) esigi asan kaynaklar silent_sources listesindedir. Admin'deki FetchRun listesinde "0 donen kaynaklar" sutunu ayni bilgiyi tur basina gosterir. Seyrek yazan kaynaklar (Krebs, PagerDuty) kendi days penceresinde yine kayit dondurdugu icin yanlis pozitif vermez; yeni kayit olmamasi degil, kaynaktan hic kayit gelmemesi sessizliktir. Haftalik kontrol: curl .../api/v1/status/ | jq '.sections[].silent_sources'. 2026-10-14: sessizlik kadans farkindalikli — seyrek yayinlayan kaynak (RabbitMQ, Moodle, Ceph...) icin kaynak basina beklenen aralik (news/kaynaklar.py BEKLENEN_ARALIK_GUN), digerleri icin bolum penceresi; status ucu expected_gap_days ve days_since_record verir.
Uc ayri sayi vardir ve birbirine karistirilmamalidir:
| Ne | Nerede | Kural | Kim degistirir |
|---|---|---|---|
| Uygulama surumu | helm/tech-radar/Chart.yaml appVersion; imaj etiketi teknoloji-haberleri-{api,frontend}:<appVersion> |
CalVer YYYY.M.N |
Yeni uygulama surumunde gelistirici |
| Chart surumu | Chart.yaml version + git etiketi chart-<version> |
SemVer: uyumsuz values/sablon MAJOR, yeni istege bagli deger MINOR, duzeltme PATCH; her surum CHANGELOG.md'de ## [surum] basligi |
Chart dizinine dokunan her PR |
| Kumede calisan surum | yerel-gitops reposunda Application'in targetRevision'i |
Degismez chart-* etiketi; yukseltme = etiketi degistir, geri alma = git revert |
GitOps reposuna commit |
CI bu kurallari zorlar:
scripts/chart_surum_kontrol.sh: chart dizini degistiyseversionartmis ve CHANGELOG girdisi var mi (CI,Helm / Compose dogrulama).scripts/imaj_etiket_kontrol.sh: render'da etiketsiz veyalatestimaj yok, ucuncu taraf imajlar digest ile sabit.scripts/chart_etiket_kontrol.sh:chart-*etiketi push edilinceChart.yamlile ayni surumu gosteriyor mu (chart etiketiis akisi).- Dockerfile'lardaki taban imajlar digest ile sabittir; Dependabot digest guncellemelerini PR olarak acar.
Etiket yalniz chart icin vardir (git tag chart-2.1.0 && git push origin chart-2.1.0); uygulama icin GitHub Release veya registry yayini yoktur, imajlar yerelde appVersion etiketiyle derlenir.
Tek dagitim kaynagi helm/tech-radar/ chart'idir; ham manifest isteyen helm template ciktisini kullanir. Chart surumu Chart.yaml'dadir ve SemVer'e uyar (uyumsuz degisiklik MAJOR, yeni istege bagli deger MINOR, duzeltme PATCH); her surumun degisiklikleri ve yukseltme notlari helm/tech-radar/CHANGELOG.md'dedir ve CI bunu zorlar. appVersion uygulama imajinin etiketidir. Kararlar: ADR-0007.
Guvenlik: Asagidaki komutlar sablondur;
<...>alanlarini kendi ortaminizla doldurun ve her komutta hedef baglami acikca verin (--kube-context/--context). Aktifkubectlbaglamina guvenmeyin. Gizli degerleri values dosyasina yazmayin.
- Kubernetes kumesi,
kubectlve Helm 3 - Kumenin cekebilecegi bir registry'de backend ve frontend imajlari
- Ingress kullanilacaksa bir Ingress Controller (
ingress.className, varsayilannginx)
docker build -t <registry>/teknoloji-haberleri-api:<surum> .
docker build -t <registry>/teknoloji-haberleri-frontend:<surum> ./frontend
docker push <registry>/teknoloji-haberleri-api:<surum>
docker push <registry>/teknoloji-haberleri-frontend:<surum>image.tag verilmezse chart appVersion'i kullanir.
helm upgrade --install tech-radar ./helm/tech-radar \
--kube-context <hedef-baglam> -n <namespace> --create-namespace \
--set secrets.secretKey="<openssl rand -hex 32>" \
--set secrets.dbPassword="<guclu-sifre>" \
--set ingress.host=<alan-adi> \
--set backend.image.repository=<registry>/teknoloji-haberleri-api \
--set backend.image.tag=<surum> \
--set frontend.image.repository=<registry>/teknoloji-haberleri-frontend \
--set frontend.image.tag=<surum> \
--wait --wait-for-jobs --timeout 15msecrets.secretKey ve secrets.dbPassword zorunludur (bos birakilirsa render reddedilir); PostgreSQL ve uygulama ayni dbPassword'u kullanir. secrets.geminiApiKey istege baglidir; ucretsiz yedek ceviri anahtarlari secrets.openrouterApiKey ve secrets.deeplApiKey ile modeller/butceler config.app.geminiFallbackModel, openrouterModel, openrouterDailyBudget, deeplMonthlyChars vb. (chart 3.2.0) de bos/kapali gelir. Uretimde harici secret yonetimi (external-secrets, sealed-secrets, vault) tercih edin: Secret'i chart disinda yonetiyorsaniz secrets.existingSecret=<ad> verin; chart Secret olusturmaz, secrets.* zorunlu olmaz. Secret SECRET_KEY, DB_USER, DB_PASSWORD, GEMINI_API_KEY anahtarlarini icermelidir; GITHUB_TOKEN ve NVD_API_KEY istege baglidir (pod'a optional: true ile baglanir, yoksa ozellik kapali kalir). Chart 2.2.0'dan itibaren config.app.logLevel/logFormat, sourceSilentRuns, celeryTaskSoftTimeLimit/celeryTaskTimeLimit, axesFailureLimit/axesCooloffMinutes degerleri ConfigMap'e yazilir (CHANGELOG).
migration.mode=helm(varsayilan): her revizyondateknoloji-migrate-r<revizyon>Job'u migration'lari uygular.migration.mode=argocd: Argo CDhelm templatekullandigi icin Job sabit adli (teknoloji-migrate) bir Sync hook'udur ve her senkronda yeniden olusturulur. Iki modda da api, worker ve schedulermigrasyon-bekleinitContainer'indamigrate --checkgecene kadar bekler. Geri alma sema geri almaz.- Backend probe'lari
/api/v1/health/'eHost: localhostile gider.ALLOWED_HOSTSsablonda kurulur:localhost,teknoloji-api(kume ici tuketici), ingress host'u veconfig.django.extraAllowedHosts. - Statik dosyalar imajdadir; pod'lar
RUN_STARTUP_TASKS=falseile acilir ve kok dosya sistemi salt okunurdur. - LibreTranslate (
libretranslate.enabled) ilk acilista ~258 MB model indirir (internet gerekir); modeller PVC'de kalir. - Redis
emptyDirkullanir: pod yeniden baslarsa bolum kilitleri, soguma, cache ve kuyruk kaybolur; Beat bir sonraki slotta yeniden planlar. backend.namefrontend/nginx.conf'a baglidir (teknoloji-api); degistirirseniz frontend imajini yeniden derleyin.
helm upgrade tech-radar ./helm/tech-radar --kube-context <hedef-baglam> -n <namespace> --reuse-values \
--set backend.image.tag=<yeni-surum> --set frontend.image.tag=<yeni-surum> --wait --wait-for-jobs
helm history tech-radar --kube-context <hedef-baglam> -n <namespace>
helm rollback tech-radar <revizyon> --kube-context <hedef-baglam> -n <namespace>
helm uninstall tech-radar --kube-context <hedef-baglam> -n <namespace>
kubectl --context <hedef-baglam> delete namespace <namespace> # PVC'ler (veri) de silinirYeni bir chart surumune gecmeden once CHANGELOG.md'deki yukseltme notunu okuyun (ornek: 2.0.0'da postgresPassword ve global.namespace kalkti).
helm template tech-radar ./helm/tech-radar -n <namespace> \
--set secrets.secretKey=<...> --set secrets.dbPassword=<...> > tech-radar.yamlCiktida secret degerleri acik metindir; commit etmeyin.
Chart yalniz yerel docker-desktop baglaminda gercek kurulumla dogrulanir (S1-S7: kurulum, HTTP, uctan uca cekim, upgrade, PostgreSQL kaliciligi, zorunlu degerler, sokum):
scripts/helm_yerel_dogrulama.sh imaj # :fazb-yerel imajlari
scripts/helm_yerel_dogrulama.sh kur # S1-S6
scripts/helm_yerel_dogrulama.sh sok # S7Betik baglami degistirmez, yerel olmayan bir kumeyi reddeder, gizli degerleri calisma aninda uretir ve helm/tech-radar/ci/yerel-values.yaml'i kullanir.
Kisisel deneme ortami Argo CD ile git'ten kurulur (ADR-0008, tasarim: spec). Uc repo is bolusur:
| Repo | Rol | Icerik |
|---|---|---|
tech-radar (bu repo, public) |
Uygulama ve chart | helm/tech-radar, her chart surumu icin degismez chart-<surum> etiketi |
yerel-platform (private) |
Platform | Paylasilan PostgreSQL; terraform/kume (Argo CD, Vault, VSO) ve terraform/yapilandirma (Vault KV/auth/politikalar, AppProject'ler, kok Application); scripts/tf.sh baglami docker-desktop'a kilitler |
yerel-gitops (private) |
"Kumede ne calissin" | apps/tech-radar.yaml (uc kaynakli Application), tech-radar/values-yerel.yaml (sir yok), tech-radar/manifests/ (ServiceAccount, VaultAuth, VaultStaticSecret) |
Nasil calisir:
- Argo CD chart'i bu reponun
chart-<surum>etiketinden (su anchart-2.2.1), degerleri ve VSO nesneleriniyerel-gitops'tan okur; hedef namespacetech-radar,automated: {prune, selfHeal}. migration.mode=argocd(Job sabit adli Sync hook) vesecrets.existingSecret=teknoloji-secretkullanilir; Secret'i Vault Secrets Operatorkv/tech-radar/uygulama'dan yazar ve deger degisince api/worker/scheduler Deployment'larini yeniden baslatir.- K8s ortami paralel denemedir: ayri veritabani
cybernews_k8s, Gemini ve Beat kapali, imajlar yerel (pullPolicy: Never); compose canli ortam olarak kalir. - Kumede calisan surum
yerel-gitops'takitargetRevision'dir; yukseltme orada etiketi degistirmek, geri almagit revert. Argo CD arayuzundeki Rollback auto-sync altinda kapalidir. - Vault kilitliyse (Docker Desktop yeniden baslayinca) uygulama calismaya devam eder; yalniz sir yenilemesi bekler. Acmak:
yerel-platform/scripts/vault_kilit_ac.sh.
Dogrulama senaryolari T1-T12 (kurulum, en az yetki, repo erisimi, yukseltme, rollback, sapma, sir rotasyonu, Vault yeniden baslatma, sifirdan kurulum) yerel-platform/scripts/k8s_dogrulama.sh ile kosar; sonuclar ADR-0008'dedir.
| Parametre | Varsayilan | Aciklama |
|---|---|---|
secrets.secretKey |
"" |
Zorunlu. openssl rand -hex 32 |
secrets.dbPassword |
"" |
Zorunlu. PostgreSQL ve uygulamanin ortak parolasi |
secrets.geminiApiKey |
"" |
Istege bagli; bos -> Gemini kapali |
secrets.existingSecret |
"" |
Doluysa chart Secret olusturmaz, bu Secret'i kullanir (or. Vault Secrets Operator) |
migration.mode |
helm |
argocd: Job sabit adli Argo CD Sync hook'u (helm template ile kurulum) |
backend.image.tag / frontend.image.tag |
"" |
Bos -> appVersion |
backend.replicas / frontend.replicas |
2 |
Replika sayisi |
postgresql.enabled |
true |
false = harici PostgreSQL (config.database.host) |
postgresql.storage.size |
5Gi |
PVC boyutu |
redis.enabled |
true |
false = harici Redis (config.redis.*) |
libretranslate.enabled |
true |
Yerel ceviri servisi |
ingress.enabled / ingress.host |
true / teknoloji.example.com |
Ingress ve alan adi (ALLOWED_HOSTS'a girer) |
ingress.tls.enabled |
false |
TLS/HTTPS |
config.django.extraAllowedHosts |
"" |
Ek host'lar (virgulle) |
config.app.* |
koddaki varsayilanlar | RETENTION_DAYS, REFRESH_COOLDOWN, GEMINI_*, LIBRETRANSLATE_* ... |
Dokuz GitHub Actions is akisi vardir. CI, Dependency Review, PR'da gitleaks ve etiket push'unda chart etiketi kapidir (kirmiziysa merge/etiket gecmez), digerleri rapor uretir: bulgu varsa hat yesil kalir ve bulgu Security sekmesine duser; hat yalniz taramanin kendisi yapilamadiysa kirmizi olur. Ayrintili okuma rehberi ve bekleyen isler: docs/GUVENLIK-PLANI.md.
| Is akisi | Tetik | Mod | Ne yapar |
|---|---|---|---|
CI |
PR, push, elle | Kapi | Backend (Django testleri): ruff (F, E9), PostgreSQL 16 ile 941 test + coverage kapisi (MIN_COVERAGE) + makemigrations --check; Frontend (Vite build): ESLint, Vitest (298 test), build; Helm / Compose dogrulama: helm lint, helm template (varsayilan + Argo CD modu), kubeconform, chart surum/imaj etiket kapilari, docker compose config |
Dependency Review |
PR | Kapi | HIGH/CRITICAL zafiyetli bagimlilik getiren PR'i durdurur |
gitleaks |
PR, push, Pazartesi | PR'da kapi | Commit'lerde sir tarar; baseline .gitleaksignore |
trivy |
PR, push, Carsamba | Rapor | Kaynak agaci (vuln + secret + misconfig), backend ve frontend imajlari; CycloneDX SBOM artefakti |
CodeQL Advanced |
PR, push, Pazar | Rapor | Python ve JavaScript statik analiz |
DAST (ZAP baseline) |
PR, push, Pazartesi | Rapor | Uygulamayi PostgreSQL ile ayaga kaldirip OWASP ZAP baseline taramasi; JSON rapor scripts/zap_sarif.py ile SARIF'e cevrilip Code scanning'e yuklenir (kategori zap-baseline); gurultu kurallari .zap/rules.tsv ile IGNORE; HTML rapor artefakti; ayni iste /api/v1/ OpenAPI semasiyla token'li API taramasi (kategori zap-api) |
zizmor |
.github/ degisince, Persembe |
Rapor | Workflow dosyalarinin guvenlik denetimi |
OpenSSF Scorecard |
push, Sali | Rapor | Depo guvenlik puani |
chart etiketi |
chart-* etiketi push'u |
Kapi | Etiket Chart.yaml version ile ayni mi, CHANGELOG girdisi var mi |
Dependabot pip, npm, Docker (digest) ve GitHub Actions bagimliliklarini haftalik gunceller; major surumler filtrelidir. Dependabot PR'i gelince: eski bir main'den acildiysa Update branch (ruleset strict oldugu icin zaten zorunlu), bes zorunlu check yesilse merge; CI kirmiziysa merge etme, planlanmis yukseltme listesine ekle. main-koruma ruleset'i PR'siz push'u, silmeyi ve force-push'u engeller.
Bulgular nerede: kod ve imaj zafiyetleri, ZAP (DAST) bulgulari, sirlar ve workflow sorunlari Security → Code scanning (Tool filtresi); bagimlilik CVE'leri Security → Dependabot; ZAP'in HTML raporu ayrica ilgili Actions kosusunun artefaktinda. Zafiyet bildirimi icin SECURITY.md (GitHub private vulnerability reporting; ilk yanit 7 gun).
Uygulama tarafindaki korumalar: DEBUG=False iken bos, ornek, django-insecure onekli veya 32 karakterden kisa SECRET_KEY ile uygulama acilmaz (cybernews/ayar_dogrulama.py); DB_HOST bossa yalniz DEBUG=True ile SQLite; veritabanini silen uclar admin oturumu ister; /api/v1/ token + hiz siniri + paylasilan soguma; imajlar non-root, Kubernetes'te kok dosya sistemi salt okunur. Yanit basliklari: Content-Security-Policy (django-csp; script-src 'self' + nonce, inline script yok), Permissions-Policy, Cross-Origin-Resource-Policy, Cross-Origin-Embedder-Policy (cybernews/guvenlik_basliklari.py) ve Django varsayilanlari (nosniff, Referrer-Policy, COOP, X-Frame-Options DENY); WhiteNoise statik dosyalara Access-Control-Allow-Origin: * eklemez. Yeni inline <script> eklenmez; gerekirse nonce="{{ request.csp_nonce }}".
# Servis ayakta mi (tokensiz)
curl -s http://localhost:8000/api/v1/health/
# Bolum basina tazelik: son basarili cekim, son durum, bekleyen ceviri sayisi
curl -s -H "Authorization: Token $CYBERNEWS_TOKEN" http://localhost:8000/api/v1/status/
# Ana sayfa saglik seridinin kaynagi: bolum basina sessiz kaynaklar (tokensiz, 60 sn cache)
curl -s localhost:8000/api/saglik/ | jq '.sections[] | .silent_sources'
# Genel Bakis kutularinin kaynagi (tokensiz, 60 sn cache)
curl -s localhost:8000/api/ozet/ | jq '{critical_count, high_count, kev_count, fetch}'
# Loglar
docker compose logs -f --tail=100 teknoloji-worker # cekim ve ceviri
docker compose logs -f --tail=100 teknoloji-scheduler # Beat planlamasi
docker compose logs -f --tail=100 teknoloji-translate # LibreTranslate
# Celery kuyrugu ve worker durumu
docker compose exec teknoloji-worker celery -A cybernews inspect active
docker compose exec teknoloji-redis redis-cli -n 1 LLEN celery| Belirti | Sebep | Cozum |
|---|---|---|
teknoloji-api acilmiyor, logda SECRET_KEY hatasi |
.env'de anahtar yok, ornek deger ya da 32 karakterden kisa |
openssl rand -hex 32 ile uret, .env'e yaz, docker compose up -d |
DB_PASSWORD .env icinde tanimli olmali |
Compose degiskeni bos | yerel-platform/scripts/uygulama_ekle.sh cybernews ile olusturulan parolayi .env'e yaz |
| api PostgreSQL'e baglanamiyor | yerel-platform compose'u ayakta degil ya da yerel-platform dis agi yok |
Once yerel-platform'da docker compose up -d, sonra burada |
Ilk cekimde ceviri yok, teknoloji-translate unhealthy |
LibreTranslate modelleri iniyor (~258 MB, start_period 120 sn) |
Bekle; docker compose logs teknoloji-translate. Internet yoksa ve volume bossa servis acilmaz |
| Kayitlar Ingilizce kaldi, rozet "bekliyor" | Saglayici devre kesicisi acik ya da Gemini butcesi doldu | Kayip yok; retranslate_pending bir sonraki turda dener. Durum: /api/v1/status/ pending_translation |
/api/v1/*/refresh/ 429 cooldown |
Bolum sogumada (REFRESH_COOLDOWN, tum token'lar ortak) |
Retry-After kadar bekle; soguma bilincli bir koruma |
Hostta manage.py reddediliyor |
DEBUG varsayilani False, anahtar ve DB_HOST yok |
Konteynerde calistir ya da DEBUG=True ile SQLite |
npm install EACCES |
Compose dev sunucusu bind mount'ta node_modules tutuyor |
docker compose stop teknoloji-frontend, sonra docker compose run --rm --no-deps teknoloji-frontend npm install |
Git Bash'te docker ... /app/... yolu C:/Program Files/Git/app oluyor |
MSYS yol cevirisi | Komutun basina MSYS_NO_PATHCONV=1 |
compose run ... teknoloji-api manage.py migrate calistiriyor |
Entrypoint once migrate yapar | --entrypoint python ver |
K8s'te Secret yenilenmiyor, VSO Synced False, "Vault is sealed" |
Docker Desktop yeniden basladi, Vault kilitli | Uygulama calismaya devam eder; yerel-platform/scripts/vault_kilit_ac.sh |
| K8s'te elle yaptigin degisiklik geri aliniyor | Argo CD selfHeal |
Degisikligi yerel-gitops'a commit et; acil durumda once auto-sync'i kapat |
Canli veri yerel-platform'un PostgreSQL'indedir; yedek orada alinir (yerel-platform/scripts/yedekle.sh). Uygulama tarafinda tam hassasiyetli dump icin manage.py veri_tasi_dump, dogrulama icin manage.py veri_ozeti kullanilir; dump dosyasi parola hash'leri ve token'lar icerdigi icin .fazb/ altinda tutulur ve is bitince silinir. Redis yedeklenmez: kaybolursa cache, soguma ve kuyruk sifirlanir, Beat bir sonraki slotta devam eder.
Uygulama tamamen ortam degiskenleri ile yapilandirabilir. Docker Compose'da docker-compose.yml icinde, Kubernetes'te ConfigMap + Secret ile ayarlanir.
| Degisken | Varsayilan | Aciklama |
|---|---|---|
SECRET_KEY |
(yok) | Zorunlu (DEBUG=False iken). Bos, depodaki ornek degerler, django-insecure onekli veya 32 karakterden kisa anahtar uygulamayi acmaz. Compose .env'den okur. Uretmek icin openssl rand -hex 32 |
DEBUG |
False |
Django debug modu |
ALLOWED_HOSTS |
localhost,127.0.0.1 |
Virgulle ayrilmis izinli host listesi. Compose localhost,127.0.0.1,teknoloji-api verir. Helm chart'i bunu sablonda acik liste olarak kurar (probe'lar Host: localhost gonderir) |
CORS_ALLOWED_ORIGINS |
http://localhost:3000,... |
Frontend origin'leri |
CSRF_TRUSTED_ORIGINS |
http://localhost:3000,http://127.0.0.1:3000 |
Admin oturumuyla POST yapabilecek frontend origin'leri (Vite proxy changeOrigin kullandigi icin gerekli) |
GEMINI_API_KEY |
(bos) | Google AI Studio anahtari; bos ise Gemini hic denenmez |
GEMINI_FALLBACK_MODEL |
(bos) | Gemini ikinci model adi (ayni GEMINI_API_KEY, ayri Google kotasi); yalniz Gemini birincil kullanilamazken denenir. Bos: zincirde yok |
GEMINI_FALLBACK_DAILY_BUDGET |
450 |
Ikinci modelin gunluk istek butcesi (Pasifik gunu; sayac oneki gemini2) |
OPENROUTER_API_KEY |
(bos) | OpenRouter anahtari (openrouter.ai/keys); bos ise OpenRouter hic denenmez. Yalniz openrouter.ai'ye gider; log, ozet ve hata metnine yazilmaz |
OPENROUTER_MODEL |
(bos) | OpenRouter modeli. Adi :free ile bitmelidir; aksi halde (ve bossa) kullanilmaz, ucretli model yanlislikla secilemez |
OPENROUTER_DAILY_BUDGET |
50 |
Gunluk istek butcesi (UTC gunu); kredisiz hesapta ucretsiz modeller ~50 istek/gun |
OPENROUTER_MIN_INTERVAL |
4 |
Istekler arasi en az saniye (~20 istek/dk altinda) |
OPENROUTER_TIMEOUT |
60 |
Istek zaman asimi (sn) |
OPENROUTER_COOLDOWN |
600 |
Hata sonrasi devre kesici bekleme (sn) |
DEEPL_API_KEY |
(bos) | DeepL API Free anahtari (:fx ile biter); bos ise DeepL hic denenmez. Yalniz api-free.deepl.com'a gider |
DEEPL_MONTHLY_CHARS |
450000 |
Aylik karakter butcesi (UTC ayi); DeepL Free siniri 500.000, 50.000 guvenlik payi |
DEEPL_MIN_INTERVAL |
1 |
Istekler arasi en az saniye |
DEEPL_TIMEOUT |
30 |
Istek zaman asimi (sn) |
DEEPL_COOLDOWN |
600 |
Hata sonrasi devre kesici bekleme (sn) |
GITHUB_TOKEN |
(bos) | Istege bagli. GitHub Releases/Tags/Advisory isteklerinde Bearer baslik (anonim limit 60/saat/IP, token ile 5000). Yalniz api.github.com isteklerine eklenir; "Public repositories (read-only)" fine-grained token yeterlidir |
NVD_API_KEY |
(bos) | Istege bagli. NVD isteklerinde apiKey basligi (anonim 5 istek/30 sn, anahtarla 50). CVE turu 3 NVD istegi yapar (KEV, yayinlanan, guncel); 429'da kaynak bos doner. Ucretsiz, nvd.nist.gov/developers'tan e-posta ile; yalniz services.nvd.nist.gov'a gider |
CELERY_TASK_SOFT_TIME_LIMIT |
1500 |
Cekim gorevi bu sureyi asinca task icinde SoftTimeLimitExceeded yukselir; gorev failure ile kapanir, kilit serbest kalir |
CELERY_TASK_TIME_LIMIT |
1800 |
Sert sinir: worker alt sureci oldurulur, FetchRun running kalir, bolum kilidi REFRESH_LOCK_TTL sonunda duser. Soft'tan en az 60 sn buyuk tutulur |
CELERY_WORKER_MAX_TASKS_PER_CHILD |
50 |
Bu kadar gorevden sonra worker alt sureci yenilenir (bellek/baglanti birikimi) |
LOG_LEVEL |
INFO |
Uygulama loglarinin seviyesi (DEBUG cekim ayraclarini da gosterir); Django/Celery kendi gurultusu WARNING'de kalir |
LOG_FORMAT |
text |
text: 2026-10-08 17:05:32 WARNING news.devtools_scraper: [GitLab] Atom hatasi: ...; json: satir basina bir JSON nesnesi (ts, level, logger, msg, exc) — Loki/ELK icin (cybernews/loglama.py) |
GEMINI_MODEL |
gemini-3.5-flash-lite |
Model |
GEMINI_DAILY_BUDGET |
450 |
Gunluk istek butcesi (Pasifik gunu; ucretsiz katman 500 RPD). Retranslate turlarina yayilir: tur payi = kalan butce / Pasifik gece yarisina kadar kalan tur. Bolumler butceyi paylasir; Gemini adayi kayit siniri: CVE'de CVSS >= 7 ya da KEV, digerlerinde hepsi; bolum sirasi CVE, haber, AI, SRE, DevTools, Kubernetes (kati) |
GEMINI_MIN_INTERVAL |
5 |
Istekler arasi saniye (15 RPM'in altinda) |
GEMINI_COOLDOWN |
600 |
429/5xx sonrasi bekleme (sn) |
GEMINI_GECICI_BEKLEMELER |
5,15 |
Gecici 5xx / baglanti kopmasinda devre kesiciden once yeniden deneme beklemeleri (sn, virgulle); bos = yeniden deneme yok |
GEMINI_TIMEOUT |
60 |
Istek zaman asimi (sn) |
GEMINI_MAX_CHARS |
12000 |
Bu uzunlugun ustundeki kayit Gemini'ye gitmez |
GEMINI_BATCH_CHARS |
10000 |
Yukseltme paketinin toplam karakter siniri (bir istekte birden cok kayit) |
GEMINI_BATCH_MAX |
15 |
Yukseltme paketindeki en fazla kayit sayisi |
RETRANSLATE_BATCH |
100 |
Retranslate turunda bolum basina taranan bekleyen kayit sayisi |
RETRANSLATE_UPGRADE_BATCH |
40 |
Tur ve bolum basina yukseltme siniri (en yeni kayittan baslar) |
RETRANSLATE_UPGRADE_BATCH_CVE |
150 |
CVE bolumunun tur basina yukseltme siniri (gunde ~600 yeni onemli CVE; 40'lik tavan eski adaylara sira birakmiyordu) |
RETRANSLATE_MAX_ATTEMPTS |
5 |
Bir kaydin icerik hatasiyla (saglayici reddetti / dogrulama gecmedi) kac kez denenecegi; esige ulasan kayit kuyruktan duser (needs_translation kalir) ve /api/v1/status/ translation_given_up ile sayilir. Basarili cevirinin sayaci sifirlar. Sayaci elle sifirlamak (admin ya da shell) kaydi yeniden kuyruga alir |
TRANSLATE_MIN_RATIO |
0.4 |
Ceviri kirpilma esigi: 80+ karakterlik metinde cikti/girdi orani bunun altindaysa ceviri reddedilir, kayit needs_translation kalir |
RETENTION_DAYS |
90 |
Saklama penceresi; updated_at bundan eski kayitlar cekim basinda silinir (cekim penceresinden ayridir) |
REFRESH_COOLDOWN |
900 |
/api/v1/*/refresh/ sonrasi bolum sogumasi (sn) — tum token'lar arasinda paylasilir |
AXES_FAILURE_LIMIT |
5 |
Admin girisinde ayni (kullanici adi, IP) ciftinden bu kadar basarisiz denemeden sonra kilit (django-axes); kilit AXES_COOLOFF_MINUTES (30) sonra acilir, basarili giris sayaci sifirlar. Acmak icin admin > Axes > Access attempts ya da manage.py axes_reset |
SOURCE_SILENT_RUNS |
4 |
Bir kaynak bu kadar ardisik tamamlanmis turda 0 kayit dondurur VE son kaydi beklenen araliktan eskiyse (ya da hic kaydi yoksa) /api/v1/status/ onu silent isaretler (4 tur = Beat'te 24 saat). Beklenen aralik: news/kaynaklar.py BEKLENEN_ARALIK_GUN (seyrek kaynaklar) ya da bolum cekim penceresi |
REFRESH_LOCK_TTL |
3600 |
Bolum cekim kilidinin omru (sn); worker olurse kilit bu surede kendiliginden duser |
DB_HOST |
(bos) | Doluysa PostgreSQL kullanilir. Bossa yalniz DEBUG=True iken SQLite (db.sqlite3); DEBUG=False iken uygulama acilmaz. Compose yerel-postgres verir |
DB_PORT |
5432 |
PostgreSQL port |
DB_NAME |
cybernews |
Veritabani adi |
DB_USER |
cybernews |
Veritabani kullanicisi |
DB_PASSWORD |
(bos) | Veritabani sifresi. Compose: .env'deki DB_PASSWORD (yerel-platform cybernews kullanicisi) |
REDIS_URL |
redis://127.0.0.1:6379/0 |
Redis baglantisi (cache) |
CELERY_BROKER_URL |
redis://127.0.0.1:6379/1 |
Redis baglantisi (Celery broker) |
Hostta
manage.pycalistirmak:DEBUGvarsayilaniFalseoldugu icin anahtarsizpython manage.py ...artik reddedilir. YereldeDEBUG=True python manage.py ...kullanin ya da komutu konteynerde calistirin (docker compose exec teknoloji-api ...).DB_HOSTvermezseniz hosttaDEBUG=Trueile yereldb.sqlite3kullanilir.
- LibreTranslate cevirileri Gemini'ye gore daha dusuk kalitede olabilir (ozel ad/guvenlik terimi hatalari otomatik dogrulamayla yakalanmaz); rozetten ayirt edilir,
retranslate_pendingGemini ile yukseltene kadar boyle kalir. Gemini gunluk butcesi (GEMINI_DAILY_BUDGET, varsayilan 450) asilirsa yukseltme bir sonraki gune kalir; CVE'lerden CVSS < 7 ve KEV disi olanlar ise butce ne olursa olsun kalici olarak LibreTranslate'te kalir (bkz. Hiz Siniri ve Devre Kesici) - Dark Reading HTML scraping'e 403 doner, bu yuzden RSS feed kullanilir
- Gunicorn timeout 300 saniye — cok fazla kaynak secilirse zaman asimi olabilir
- Her fetch'te toplam makale sayisi 30 ile sinirlidir (Gunicorn timeout'undan kacinmak icin)
- Redis blog sayfasi JS-rendered —
blockContentdiv'inden icerik cekilir, eger site yapisi degisirse guncelleme gerekebilir - Elastic 8.x serisi release notes farkli URL'de (
/guide/en/...), sadece 9.x serisi icin detayli changelog cekilir - Yapay Zeka bolumu yalnizca haber RSS'lerini kapsar; benchmark/leaderboard skorlari ertelenmistir (ADR-0002)
artificialintelligence-news.comRSS'i 403 dondugu icin yerine MIT Technology Review AI kullanilirnewsbolumundelinkuzerinde veritabani benzersizlik kisiti yoktur; v1 tuketicisi kendi tarafinda benzersiz indeks tanimlamalidir (bkz. Upsert anahtari)- Yerel GitOps ortami bilinerek sinirlidir: Vault tek anahtar ve elle unseal, kok token yerel dosyada, Kubernetes Secret'lari etcd'de sifresiz, tek dugum, SSO yok, Argo CD polling (webhook yok). Uretim esdegerleri spec bolum 10'dadir
- Compose ve K8s ayni PostgreSQL sunucusunda farkli veritabanlari (
cybernews,cybernews_k8s) kullanir; ayni veritabanina ayni anda baglanmazlar
| Belge | Icerik |
|---|---|
docs/ADR-*.md |
Mimari kararlar: baglam, karar, elenen alternatifler, sonuc ve canli dogrulama olcumleri |
docs/GUVENLIK-PLANI.md |
Guvenlik hatti nasil okunur, bulgular nereye duser, haftalik rutin, bekleyen isler (P3-P5), gecmis |
docs/superpowers/specs/ |
Tasarim belgeleri: her buyuk isin "neden, ne, nasil dogrulanir" metni (A1-A5b, guvenlik temizligi, Faz B, B3) |
docs/superpowers/plans/ |
Uygulama planlari ve devir notlari; gorev gorev komutlar, beklenen ciktilar |
helm/tech-radar/CHANGELOG.md |
Chart surumleri ve yukseltme notlari |
SECURITY.md |
Zafiyet bildirimi |
| Tarih | Asama | Kayit |
|---|---|---|
| 2026-09-11 | Yapay Zeka bolumu (8 kaynak) | ADR-0001, ADR-0002 (benchmark ertelendi) |
| 2026-09-12 → 09-21 | Entegrasyon API /api/v1/ A1-A5b: token, imlecli delta, refresh/jobs, FetchRun + status, OpenAPI |
ADR-0003, ADR-0006 |
| 2026-09-14 → 09-18 | Ceviri saglayici zinciri; Google kaldirildi, Gemini yukseltme; saklama olcusu updated_at, CVE'ye butce onceligi |
ADR-0004, ADR-0005 |
| 2026-09-13 → 09-30 | Guvenlik hatti (8 is akisi), Django 4.2 → 5.2, Dependabot 14 → 0, SECRET_KEY/ALLOWED_HOSTS korumalari |
GUVENLIK-PLANI P0-P2, P4 (kismi) |
| 2026-10-02 | Faz B1: SQLite → paylasilan yerel PostgreSQL, kayipsiz gecis (ozet birebir) | ADR-0007 |
| 2026-10-03 | Faz B2: Helm chart 2.0.0 docker-desktop'ta S1-S7 ile dogrulandi; CI chart kapilari | ADR-0007 |
| 2026-10-04 | B3: Terraform + Argo CD + Vault/VSO ile yerel GitOps; chart 2.1.0; T1-T12 gecti | ADR-0008 |
| 2026-10-08 | Kaynak turu: 35 → 48 kaynak (7 haber, CISA KEV, LiteLLM/LangGraph/Langfuse/GitLab/Keycloak); olu kaynak onarimi (Bleeping Computer 403, SecurityWeek bos link, MongoDB/InfoQ/DZone akislari); GITHUB_TOKEN |
news/tests/test_kaynaklar.py |
| 2026-10-14 | Kaynak turu 2: 48 → 47 (KDnuggets/MinIO/CIRCL cikti, Ars Technica AI/Import AI girdi); kadans farkindalikli sessizlik | news/tests/test_kaynak_sagligi.py |
| 2026-10-13 → 10-14 | Guvenlik plani P5-b (haftalik ozet Issue) ve P5-c (/api/v1/ ZAP API taramasi); bakim dalgasi (yedek dongusu, saglik seridi, Vitest, ruff/coverage) | GUVENLIK-PLANI, docs/superpowers/specs/2026-10-14-bakim-dalgasi-design.md |
Guvenlik plani (GUVENLIK-PLANI) P0-P5 tamamlandi (2026-10-14); siraya konmus guvenlik isi yok.
Aday (henuz tasarlanmadi; kapsam notlari ADR-0002 ve B3 spec bolum 13):
- Vault dinamik PostgreSQL kimlikleri (database secrets engine +
VaultDynamicSecret) ile statikDB_PASSWORD'un kalkmasi. - Argo CD ApplicationSet (kok uygulamanin yerine) ve ikinci bir ortam klasoruyle terfi akisi; Argo CD Image Updater.
- AI benchmark/leaderboard bileseni (ADR-0002, ertelendi).
- Diger kisisel uygulamalarin ayni zincire eklenmesi (yeni uygulama =
uygulamalarlistesine bir eleman +yerel-gitops/apps/<ad>.yaml).
Kapsam disi (bilincli): gercek bir kumeye kurulum, imaj registry'si ve release yayini, SSO, cok dugum, K8s ortaminin canli olmasi.
| ADR | Konu | Durum |
|---|---|---|
| ADR-0001 | AI News bileseni | Accepted |
| ADR-0002 | AI Benchmark / Leaderboard bileseni | Proposed (ertelendi) |
| ADR-0003 | Dis tuketiciler icin /api/v1/ entegrasyon katmani (imlecli delta, token, refresh, ceviri dogrulugu) |
Accepted (A1–A5b uygulandi, canlida dogrulandi) |
| ADR-0004 | Ceviri saglayici zinciri (LibreTranslate yedek; 2026-09-15: Google kaldirildi, Gemini yukseltme) | Accepted (degisiklik 2026-09-15) |
| ADR-0005 | Saklama olcusu updated_at (sil/yeniden yaz dongusu) ve CVE'ye Gemini butce onceligi |
Accepted (uygulandi 2026-09-18, canlida dogrulandi; 2026-11-02: CVE rezervi kaldirildi, yerine onem sinifi) |
| ADR-0006 | FetchRun gorunurlugu, durum semantigi ve dar GET /api/v1/status/ ucu (ADR-0003 bolum 11'in yerine gecer) |
Accepted (uygulandi 2026-09-21, canlida dogrulandi) |
| ADR-0007 | SQLite'tan paylasilan yerel PostgreSQL'e kayipsiz gecis ve Helm chart dogrulamasi (Faz B) | Accepted (B1 2026-10-02 ve B2 2026-10-03 uygulandi; docker-desktop'ta dogrulandi) |
| ADR-0008 | Yerel GitOps: iki asamali Terraform, Argo CD "app of apps", Vault + Vault Secrets Operator, chart 2.1.0 (B3) | Accepted (B3a + B3b 2026-10-04 uygulandi; T1-T12 docker-desktop'ta gecti) |
Bu proje MIT lisansi ile yayimlanmistir. Tam metin icin LICENSE dosyasina bakin.
