Files
menulio/docs/PROGRESS.md
T

11 KiB
Raw Blame History

Progress Log

Faz tanımları için ROADMAP.md. Bu dosya ne yapıldığını, ne yapılmadığını ve bilinen sınırlamaları takip eder — faz atlarken buraya bakıp neyin gerçek neyin stub olduğunu hatırlamak için.

App Store Connect + RevenueCat kurulumu (2026-08-20)

App Store Connect (API ile, gerçek üretim hesabına karşı):

  • Store metinleri yazıldı: alt başlık, açıklama, anahtar kelimeler, tanıtım metni, destek/pazarlama/gizlilik URL'leri, telif hakkı
  • Kategori: Food & Drink
  • En son build (v10) versiyona bağlandı
  • Subscription group "Menulio Pro" + iki ürün oluşturuldu: menu_pro_monthly, menu_pro_yearly (Türkçe isim/açıklama ile)
  • Fiyatlandırma kullanıcı tarafından App Store Connect UI'dan girildi: aylık 250 TL, yıllık 2500 TL
  • Kullanıcının tamamlaması gereken: Yaş derecelendirmesi anketi, en az 1 ekran görüntüsü — API'nin güvenilir şekilde dolduramadığı/dolduramayacağı alanlar

RevenueCat (proje zaten proj0d3bc1c1 olarak mevcuttu, API ile tamamlandı):

  • Gerçek App Store ürünleri (menu_pro_monthly, menu_pro_yearly) "Menul.io (App Store)" app'ine eklendi
  • "Menulio Pro" entitlement'ına bağlandı
  • "default" offering'in Monthly/Yearly paketlerine iliştirildi

Backend: POST /subscription/webhook gerçek mantıkla yazıldı — Authorization header'ı (shared secret) doğruluyor, RevenueCat event tipini subscriptions.status'a çeviriyor (INITIAL_PURCHASE/RENEWAL/PRODUCT_CHANGE/UNCANCELLATION → active, BILLING_ISSUE → grace_period, EXPIRATION → suspended; CANCELLATION tek başına suspend etmiyor, sadece auto-renew kapanıyor). Gerçek Supabase'e karşı uçtan uca test edildi.

Kalan (henüz yapılmadı):

  • Mobile'da react-native-purchases SDK'sı hiç kurulu değil — paywall ekranı, Purchases.configure({ appUserID: restaurantId }) çağrısı, satın alma akışı yazılmadı. Webhook'un app_user_id'yi restoran ID'si olarak eşleştirebilmesi için bu SDK entegrasyonu zorunlu.
  • RevenueCat Dashboard'da webhook URL'i (https://api.menul.io/subscription/webhook) ve Authorization header değeri (Bearer test_MoTphXMYyNDmzeBCbvYVhfrcCjl) henüz elle girilmedi.
  • API servisine REVENUECAT_WEBHOOK_SECRET env değişkeni henüz prod'a eklenmedi (local .env'de var, Coolify'a taşınmadı).

Faz 0 — Altyapı (2026-08-19)

  • pnpm monorepo: apps/api (Fastify), apps/web (Next.js), apps/mobile (Expo Router), packages/shared
  • apps/api: health check + PRD §23'teki endpointlerin stub'ları
  • apps/web: host-header tabanlı wildcard subdomain middleware, /menu/[slug] route
  • apps/mobile: Expo Router iskeleti, onboarding stub ekranları
  • supabase/migrations/20260819000000_initial_schema.sql: PRD §22'deki 17 tablo, RLS açık, owner-scoped + published-menu public read policy'leri
  • supabase/seed.sql: 5 başlangıç teması
  • Doğrulama: tsc --noEmit tüm app'lerde temiz, API /health gerçekten çalıştırılıp test edildi

Faz 1 — Manuel akış (2026-08-19)

Hedef: Restoran sahibi mobil uygulamada elle veri girip gerçek bir QR menüyü yayınlayabilsin. Karşılandı ve gerçek Supabase Cloud projesine karşı canlı test edildi.

  • API: auth middleware (Supabase JWT doğrulama, requireAuth/requireRestaurantMember) + restaurant CRUD
  • API: menu/category/item CRUD + publish/unpublish (menus, menu-categories, menu-items route'ları)
  • API: QR üretimi (PNG/SVG, /q/:id stabil redirect URL ile — PRD §12)
  • API: /me/restaurant — mobile cold-start rehydration için
  • Supabase: Faz 1 RLS policy migration'ı (20260819010000_public_menu_access.sql)
  • Web: gerçek public menü render (Supabase'ten canlı veri, 5 zengin tema desteği, canlı arama, sticky kategori barı, ürün detay modalı)
  • Web: /q/[id] QR redirect route'u
  • Mobile: auth ekranları (email login/register) + Supabase client (AsyncStorage session)
  • Mobile: restoran onboarding formu → API'ye bağlı
  • Mobile: menü editörü (kategori/ürün CRUD, yayınla butonu) — apps/mobile/src/app/menu/index.tsx
  • Mobile: QR ekranı (üret, göster, native share) — apps/mobile/src/app/menu/qr.tsx

Faz 2 — AI Menu Scanner (2026-08-19)

Hedef: Menü fotoğrafını çekip/yükleyip AI ile saniyeler içinde dijitalleştirmek, onaylayıp canlı menüye aktarmak.

  • Shared: AI çıkarma (AiExtractedCategory, AiExtractedItem), yanıt (AiImportResponse) ve uygulama (AiImportApplyPayload) veri sözleşmeleri.
  • API: apps/api/src/lib/ai-scanner.ts — Gemini 1.5 Flash Vision, OpenAI GPT-4o Vision ve akıllı mutfak sezgisel fallback motoru.
  • API: POST /menus/:id/import-ai — menü görselini analiz eder, ai_imports ve ai_import_items denetim loglarını oluşturur, confidence skorları hesaplar.
  • API: GET /ai-imports/:id — kaydedilmiş import durumunu döner.
  • API: POST /ai-imports/:id/apply — AI Review ekranından onaylanan/düzenlenen kategori ve ürünleri menüye (menu_categories, menu_items) topluca yazar.
  • Mobile: expo-image-picker entegrasyonu (kamera & galeri izinleri ve fotoğraf seçimi).
  • Mobile: apps/mobile/src/app/(onboarding)/scan.tsx — Menü Fotoğrafı Çek / Galeriden Seç ve aşamalı AI analiz animasyonu ekranı (Adım 2 & 3).
  • Mobile: apps/mobile/src/app/(onboarding)/ai-review.tsx — AI Review & Onay ekranı (Adım 4):
    • Kategori bazlı ürün listesi
    • Düşük güven skorlu öğeler için sarı uyarı rozeti (⚠️ Düşük Güven (Fiyatı Kontrol Edin))
    • Anında ürün adı, fiyat ve açıklama düzenleme
    • Kategori/ürün silme ve ekleme
    • "✓ Menüyü Onayla ve Kaydet" butonu ile menüye aktarma
  • Mobile: apps/mobile/src/app/menu/index.tsx içerisine " AI ile Menü Fotoğrafı Tara" tetikleyicisi.
  • Mobile: apps/mobile/src/app/account/index.tsx — Hesabım & Restoran Ayarları ekranı:
    • Kullanıcı profili ve aktif restoran durumu
    • Restoran adı, telefon ve adres güncelleme (PATCH /restaurants/:id)
    • Canlı menü linki kopyalama ve tarayıcıda açma
    • 5 Temadan birini seçip menüye anında uygulama (GET / PUT /restaurants/:id/theme)
    • Abonelik plan durumu
    • Çıkış yapma (Sign out) ve oturum temizleme

Faz 3 — Web Frontend & 5 Menü Şablonu Engine (2026-08-20)

  • Web: apps/web/src/app/page.tsx — Lüks Menulio SaaS Landing Page (Hero, 5 Şablon vitrini, Nasıl Çalışır, İstatistikler, Canlı Demo linkleri).
  • Web: apps/web/src/lib/theme.ts — 5 Ayrı Tasarım Şablonu Tanımları:
    1. 🌟 Elegant Gold (Fine dining & lüks restoranlar - Altın & Krem, serif tipografi)
    2. 💎 Modern Sapphire (Kafe & Fast-Casual - Mavi safir & beyaz, 2'li grid layout)
    3. 🌙 Luxury Dark (Gece kulübü & Kokteyl bar - Obsidian & Kehribar lüks mod)
    4. ❄️ Nordic Minimal (Butik kahveci & fırın - Sade monokrom liste mizanpajı)
    5. 🍷 Classic Bistro (Meyhane & Trattoria - Toskana bordo & rustik doku)
  • Web: apps/web/src/components/TemplateGalleryClient.tsx & /templates — İnteraktif şablon galerisi ve canlı telefon simülatörü.
  • Web: apps/web/src/app/demo/page.tsx — Tam ekran interaktif demo menü.
  • Mobil & API: Yerel geliştirme ortamına uyumlu URL ve QR mimarisi (http://localhost:3000/menu/[slug]).
  • Mobil: ThemeSelectorSheet.tsx — Menü editöründen tek tıkla 5 şablondan birini seçme ve anında aktifleştirme.
  • Mobil: Ürün Görseli Ekleme & Düzenleme (expo-image-picker ile AddItemModal ve ItemDetailSheet içinde galeri seçimi ve canlı önizleme).
  • Mobil: MenuItemCard.tsx — Menü ürün kartlarında görsel küçük resim (thumbnail) desteği.
  • Mobil: AccountScreen.tsx — Restoran Logosu yükleme/değiştirme ve detaylı restoran bilgileri güncelleme.
  • Mobil: Alt barda kalıcı "👁️ Önizle" butonu ile tek tıkla canlı menüyü tarayıcıda açma.
  • Web: apps/web/src/components/PublicMenuClient.tsx — Anında arama, masa numarası parametresi (?table=X), garson çağır / hesap iste floating barı, ürün detay modalı ve canlı tema değiştirici çekmecesi.

Kapsam dışı bırakılanlar (bilinçli, sonraki fazlara ertelendi):

  • Apple/Google login (V1.5+) — sadece email auth
  • Abonelik/RevenueCat (Faz 5) — bu fazda erişim kısıtı yok

Production altyapı + canlı hata ayıklama (2026-08-20)

Bu tarihte proje production'a alınmış halde bulundu: menul.io (Next.js public web), api.menul.io (Fastify API), Coolify (host: Traefik değil Caddy), Cloudflare (DNS/proxy), gerçek Supabase Cloud projesi (fwahdopsyvryvjaqande), git.ayris.tech (self-hosted Gitea, main'e push → Coolify otomatik deploy). Custom domain özelliği (ad.ayris.techmenul.io) canlıda kurulup test edildi ve çalışır hale getirildi. Bu süreçte bulunup düzeltilen gerçek prod bug'ları:

  • API SUPABASE_SERVICE_ROLE_KEY placeholder'dıapi.menul.io her auth isteğini 401'liyordu (mobilde sürekli login döngüsüne sokuyordu). Kullanıcı gerçek key'i env'e girdi.
  • Fastify default bodyLimit 1 MiB — AI menü fotoğrafı yüklerken "Request body is too large" hatası (model/key ile ilgisiz). apps/api/src/index.ts'te 20 MiB'e çıkarıldı.
  • domains.ts DNS-CNAME doğrulaması proxied domainlerde yapısal olarak asla çalışmaz — Cloudflare proxy (turuncu bulut) gerçek CNAME hedefini public DNS'ten gizliyor (ENODATA). /verify her çağrıldığında zaten doğrulanmış bir domain'i "pending"e geri düşürüyordu. Artık zaten verified olan bir domain bir daha downgrade edilmiyor. Kalıcı çözüm hâlâ eksik: gerçek doğrulama Cloudflare Custom Hostnames API'sinin ssl.status'una bakmalı — bunun için Cloudflare API token + zone ID gerekiyor (henüz alınmadı).
  • apps/web/src/middleware.ts trailing slash bug'ı — root path istekleri /menu/<slug>/ (sonda slash'lı) üretiyordu, [slug] route'u eşleştiremiyordu → her custom domain/subdomain kök isteği "Menü Bulunamadı" veriyordu. Düzeltildi.
  • PUT /restaurants/:id/theme crash'i — tanımsız themeData değişkeni kullanılıyordu (main'de önceden var olan tsc hatası, muhtemelen build type-check adımından geçmeden deploy edilmişti). Eksik themes sorgusu eklendi.
  • Coolify custom domain routing: her custom domain, ilgili Next.js servisine Coolify panelinden elle eklenmesi + redeploy gerektiriyor (otomasyon yok). Wildcard subdomain (*.menul.io) hiç kurulmadı çünkü gerekmiyor — restoran menüleri menul.io/menu/{slug} path'i üzerinden çalışıyor, alt-domain mimarisi kullanılmıyor.

Sonraki adım (otomasyon): Cloudflare API token + zone ID alınırsa, POST /restaurants/:id/domains restoran custom domain eklediğinde otomatik Custom Hostname oluşturup gereken DNS talimatlarını döndürecek, /verify de Cloudflare'in kendi SSL durumuna bakacak şekilde güncellenebilir — böylece bugünkü manuel Cloudflare dashboard adımları (Fallback Origin, TXT kayıtları, Coolify domain ekleme) her yeni restoran için tekrarlanmaz.