Proje: Okul Platform · Hub: Okul Platform — Architecture

Figma tasarımı (responsive/article/show.blade.php) uygulamasında FE’de render edilemeyen veya placeholder gösterdiğimiz alanlar. BE ekibinden geliştirme talep edilecek.

Ticket: OKUL-770 Branch: OKUL-770 (base: OKUL-responsive-layout) Tasarım: Figma Make — ZjhlXmOf4dvN9BHMPF6dfl · /makale/lise-sinav-hazirlik

1) Makale modeli alan eksikleri

AlanTasarımdaki kullanımıFE geçici çözüm
tags (string[])Header altında #etiket chip’leri; related article’ları tag kesişimiyle seçmeTag chipleri gösterilmiyor; related yalnız category_id bazlı
is_editor_pick (bool)Başlık üstünde “Editör Seçimi” yeşil rozetis_helpfull proxy olarak kullanılıyor — doğru semantik değil
reading_time_minutes (int)“X dk okuma” meta satırıstr_word_count(strip_tags($body))/200 ile FE’de hesaplanıyor (yaklaşık)
view_count formatted”24.5K görüntülenme”FE’de $view_count/1000 formatlamasıyla yaklaşık sunuluyor

İstek: articles tablosuna tags (JSON veya pivot), is_editor_pick (bool), reading_time_minutes (int, editor tarafında hesaplı); API response’ta expose edilecek.

2) Yazar (User) profil zenginleştirmesi

Tasarım “Yazar Hakkında” kartında tam profil bekliyor. Şu an yalnız name var.

AlanTasarımFE geçici
avatar_urlAvatar imajıİsim baş harfi gösteriliyor
title”Eğitim Psikoloğu”Statik “Okul.com.tr Yazarı”
bio2-3 satır biyografiKategori adına dayalı statik metin
expertise_tags (string[])Uzmanlık chip’leriGösterilmiyor
article_count”X makale” badgeGösterilmiyor
Yazar profil sayfası (/yazar/{id})“Tüm makalelerini gör” linkiKategori listesine yönlendiriliyor

İstek: users tablosunda author alanları (veya ayrı authors tablosu), article detail response’unda author object’i. Yazar profil route/sayfası ayrı bir feature olarak açılabilir.

3) Yorum sistemi

Tasarımdaki yorum deneyimi mevcut article_comments tablosuyla karşılanmıyor.

ÖzellikTasarımFE durumu
Beğeni (like) sayacıcomment.likes + toggleFE-only optimistic, persist yok
Doğrulanmış Veli rozetiisVerifiedParent boolGösterilmiyor
Uzman/Editör rozetiisEditor boolhtml_enabled proxy olarak kullanılıyor (hatalı olabilir)
Nested reply (iç içe yanıt)2 seviye derinlikTablo flat; reply input UI var ama submit BE bekliyor
Sıralama (en popüler / en yeni)BE destekli olabilirFE’de JS ile sıralanıyor (BE date ile geliyor)
Şikayet (report) butonuComment report akışıEndpoint yok; UI buton var, tıklanınca no-op

İstek: article_comments tablosuna likes (int), is_verified_parent (bool); ayrıca article_comment_likes pivot (user_id + comment_id unique). article_comment_replies ya da parent_comment_id FK. Report endpoint’i.

Not: Yorum oluşturma (composer → submit) mevcut BE endpoint’iyle bağlandıajax.article-comments.store (FormController@createArticleComment) JSON POST kabul ediyor, moderation sonrası listeye alıyor. Responsive composer bu endpoint’e Alpine fetch ile gidiyor; yalnızca like / reply / report / editor badge / verified-parent UI’ları yukarıdaki alan eksiklikleri nedeniyle blade’de comment-out.

4) Yer işareti (bookmark)

Tasarımdaki “Yer işareti” (bookmark) butonu sadece FE state tutuyor. Sayfa yenilendiğinde kaybolur.

İstek: Kullanıcı bazlı bookmarked_articles tablosu (user_id + article_id); POST/DELETE endpoint’leri.

5) Makale body zenginlik blokları

Figma tasarımında body içinde özel bloklar var: InfoBox, HighlightBox, QuoteBlock, StatBlock, CalloutCTA, FAQItem. Şu an {!! $article->body !!} CMS HTML’i doğrudan basıyor; prose typography genelde temel stil sağlıyor ama bu özel kutuları render etmiyor.

İstek: CMS editörüne bu blokları ekleme seçeneği (shortcode veya custom class convention); örn. <div class="article-infobox" data-title="...">...</div> FE’de CSS ile stilize edilir. Blok convention’ı kararlaştırılmalı.

6) GA paylaşım eventleri

gaSendEventShare helper’ı mevcut; ama whatsapp, linkedin, mail, copyLink platformları için GA label standart değil. WhatsApp tracking gaSendEventWhatsapp ile zaten farklı akışta.

İstek: Paylaşım eventleri için GA4 taxonomy tanımı (data ekibiyle): share_platform parametresi (whatsapp/x/facebook/linkedin/mail/copy_link).

7) Related article tag-intersection

Tasarımda related articles “aynı kategori VEYA ortak tag” kriteriyle seçiliyor. Şu an yalnız aynı kategoride ve random. Tag yok (bkz. §1).

İstek: tags alanı eklendikten sonra related articles query’si “category OR tag overlap” kriterine geçirilecek.

8) Soft CTA — kişiselleştirme

Tasarımdaki “Okul mu arıyorsunuz?” CTA’sı genel; ideal olarak kullanıcının session('city') ve makalenin school_type_id bilgisine göre deep-link’lenir (/lise/istanbul/ozel-okullar gibi).

İstek: (opsiyonel) CTA URL üretimini kişiselleştirme için helper.

9) Listeleme sayfası (article list) eksikleri

ÖzellikTasarımFE durumu
Sort pill’lerimost-read / newest / editor-pick / recently-updatedAPI 500 atıyor: sort whitelist’i yalnız id/-id/name/-name/sorting/-sorting kabul ediyor, -view_count/-created_at/-updated_at/-is_helpfull → “Seçilen Sıralama geçersiz”. Şimdilik FE yalnızca newest → -id yolluyor (yaklaşık), diğer pill’ler visual-only.
Query param adı?sort=X?sort=X IndexArticleRequest’teki HasPagination trait’inin whitelist’ine çarpıyordu; FE ?order=X kullanıp 422’den kaçınıyor.

9a) API sort whitelist’ine eklenmesi gerekenler

API (/articles GET) sort param için desteklenmesi gereken kolonlar:

DeğerFE pillKullanım
-view_countEn Çok Okunanmost-read
-created_atEn Yeninewest (şu an -id approximation)
-updated_atSon Güncellenenrecently-updated
-is_helpfull veya -is_editor_pickEditör Seçimieditor-pick (bkz §1 — ideal is_editor_pick alanı açılınca)

BE HasPagination trait’inin sortables array’ine bu kolonlar eklenip Article modelinin sort-safe alanlarına erişim açılmalı. Eklenince FE ArticleController@listByCategory’deki $orderMap güncellenecek.

10) Medya spec talepleri

Responsive tasarımda görseller mevcut spec klasörlerinden daha büyük/detaylı görünüyor. Aşağıdaki spec’lerin eklenmesi (veya mevcutlarının boyutunun artırılması) lazım:

Hero slider (listeleme sayfası) — ihtiyaç duyulan spec

  • Konum: responsive.article.list$heroArticles{$path}article_page_content/{$name}
  • Aspect: 21:9 desktop, 16:9 tablet/mobile
  • Min boyut: 1920 × 820 px (retina için 2× de ideal)
  • Öneri spec adı: article_hero_1920x820 veya mevcut article_page_content güncellenebilir
  • Gerekçe: Hero full-bleed container. Küçük spec (ör. 480x320) upscale edilince blur olur.

Show sayfası cover — ihtiyaç duyulan spec

  • Konum: responsive.article.show → cover image → {$path}article_page_content/{$name}
  • Aspect: 21:9
  • Max container genişliği: 1100px (desktop)
  • Min boyut: 1600 × 686 px (retina için 2×)
  • Öneri spec adı: article_cover_1600x686 veya article_page_content güncellemesi
  • Gerekçe: Şu an detay sayfasında cover çok küçük kalıyor, aspect-ratio container’da blur var.
  • Konum: kart görselleri
  • Aspect: 4:3 desktop, 16:9 mobile
  • Min boyut: 640 × 480 px (desktop card ~320px geniş, retina için 2×)
  • Öneri spec adı: mevcut article_page_content yeterli görünüyor, ama netlik için 800x600 olabilir.

İstek BE’den: Hero ve show cover için 1920×820 ve 1600×686 boyutlarında spec üretilsin (media pipeline’ına yeni crop preset’i olarak eklensin). FE tarafında sonra sadece spec adı değişecek.

Lighthouse bulguları (listing page)

/makaleler sayfası Lighthouse auditinde tespit edilen, FE’nin çözemediği infra/BE odaklı sorunlar:

  1. Image oversizing — Card grid (378×270 display) için article_page_content spec’i 700×394 JPEG dönüyor. Lighthouse ~105 KB savings kaldırabileceğimizi söylüyor. Card’a özel daha küçük spec gerek (önerilen: 480×320 retina için 960×640 — mevcut 700×394’ten daha uygun oran).
  2. Modern format (WebP/AVIF) — Mevcut pipeline yalnız JPEG üretiyor. CloudFront/image service WebP negotiation (Accept: image/webp) desteği eklenmeli; FE tarafında <picture> source tag’leri gerekirse eklenir ama BE spec üretimi önce gerekiyor.
  3. Cache-Control — Tüm static asset’lerde (*.js, *.css, *.svg, *.png, cdn.okul.com.tr/*.jpg) Cache-TTL: None. Nginx/CloudFront config’de immutable asset’ler için 1yr cache (Cache-Control: public, max-age=31536000, immutable) set edilmeli. Mix pipeline zaten hash’li URL üretiyor (mix-manifest.json), bu güvenli.

İstek BE/infra’dan:

  • Card-spec (ör. article_card_480x320) eklensin + media service WebP/AVIF response’u.
  • Nginx/CloudFront cache headers immutable assets için 1yr.

11) Alt lokasyon listesi (responsive/components/location-list)

Responsive listeleme/profil sayfalarında altta kullanılan ortak component resources/views/responsive/components/location-list.blade.php — Figma DistrictLinks.tsx (Mikro kategori sayfası) tasarımından adapte.

Üniversiteler

Figma’daki tasarımda “Özel Üniversiteler” entry’si yok ama tasarımın ilkeleri gereği olacağı bekleniyor. Mevcut SchoolsTypes tablosu anaokulu, ilkokul, ortaokul, lise + ana kategori barındırıyor; üniversite yok. Eklendiğinde Locations::bottomSchoolsTypesLinks otomatik olarak üniversite kategorisini de ekleyecek — FE tarafında değişiklik gerekmez.

İstek: school_types tablosuna universite slug’lı row (p_name = “Üniversiteleri”) eklensin.

Kategori-başına ilçe chip’leri

Figma’da her kategori başlığının (“İstanbul Özel Okulları”) altında ilgili ilçelerin chip listesi bulunuyor. Mevcut bottomSchoolsTypesLinks çıktısında county flat bir dizi — hangi ilçe hangi kategoride gösterilecek diye kırılımı yok. FE geçici olarak tüm ilçe chip’lerini kategori listesinin altında ortak gösteriyor.

İstek: bottomSchoolsTypesLinks response’unu nested yapıya alma — city.{id}.categories.{type_slug}.counties şeklinde. FE bunu görünce kategori başlığının altında ilçe chip’lerini Figma 1:1 render edecek. | comment_count per article | Kartta “N yorum” rozeti | Listeleme API’sinde comment_count join’i yok; FE render atlıyor | | Hero slider için featured article set | is_featured: true olanlar | Yok; FE ilk sayfadaki ilk 5 article ile besleniyor | | Reading time | reading_time_minutes | Kartta body word count’tan tahmin ediliyor (performans: body payload’ı eksik olabilir) | | Listeleme sayfasında client-side filter (Kademe/OkumaSüresi) | FilterBar popover | Şu an kategori + sort + search var; kademe & okuma süresi backlog |

İstek:

  • articles.list / articles.list.category endpoint’lerinde sort query desteği (most-read / newest / editor-pick / recently-updated).
  • Listeleme item’ında comment_count (aggregate) ve reading_time_minutes.
  • is_featured + is_editor_pick → hero slider beslemesi.

Öncelik önerisi

  1. P0 — Launch blocker: tags, is_editor_pick, comment likes, reading_time. Bunlar tasarımın birincil etkilerini veriyor.
  2. P1 — Etkileşim tamlığı: nested reply, bookmark persist, verified-parent rozet, author avatar + article_count.
  3. P2 — Nice-to-have: body rich blocks convention, report comment, author profil sayfası, kişiselleştirilmiş CTA.