Files
marmarislocal/docs/prd.md
T
2026-07-12 20:18:55 +03:00

225 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD — Marmaris Local
**Domain:** marmarislocal.com
**Tarih:** 2026-07-12
**Durum:** MVP tanımı — geliştirme başka ortamda yapılacak
---
## 1. Proje Özeti
Marmaris Local, Marmaris'teki restoran, apart otel ve yerel işletmeleri (dalış merkezi, tekne kiralama, tur operatörü, transfer vb.) tek bir küratörlü rehberde toplayan, uluslararası turiste (öncelikle Rus ve İngiliz, ayrıca Türk) hitap eden çok dilli bir dizin/rehber sitesi.
Konumlandırma: "Turistin göremediği yerel bilgi." Genel bir Yelp/TripAdvisor klonu değil — her listelemenin bir kürasyon/onay katmanı var ("Yerel Onaylı" mührü), bu da markanın ana güven vaadi.
---
## 2. Marka Kimliği (özet — tam mockup ekte: `marmaris-local-brand.html`)
- **Palet:** Pine Night `#123238` (zemin/koyu), Bay Turquoise `#2E9C9A` (imza rengi), Shutter Blue `#4F7C93`, Golden Hour `#E8A23D` (puan/rozet), Bougainvillea `#E85D6E` (nadir vurgu, kategori etiketleri), Limestone `#EDEEE3` (açık zemin)
- **Tipografi:** Unbounded (başlık, 800/600 — Latin+Kiril), Golos Text (gövde — Latin+Kiril), IBM Plex Mono (fiyat/saat/telefon gibi pratik veri)
- **İmza öğe:** Dairesel "Yerel Onaylı" mührü — her kürasyona giren listelemenin yanında görünür, logo motifiyle aynı dil
---
## 3. Sayfa Envanteri / Site Haritası
```
/ → Anasayfa (öne çıkan listelemeler, kategori girişleri, arama)
/restoranlar → Restoran listesi (filtre: mahalle, mutfak, fiyat)
/apartlar → Apart/konaklama listesi
/isletmeler → Genel işletme listesi (dalış, tekne, tur, transfer, kiralama)
/[kategori]/[slug] → Tekil listeleme detay sayfası
/mahalle/[slug] → Mahalle bazlı liste (Yat Limanı, İçmeler, Armutalan vb.)
/isletme-ekle → İşletme sahibi başvuru formu
/hakkinda → Marka hikayesi, "Yerel Onaylı" nasıl çalışır
/iletisim → İletişim formu
/admin/* → Yönetim paneli (bkz. §8)
```
Tekil listeleme sayfası içeriği: galeri, açıklama (TR/EN/RU), adres + harita, çalışma saatleri, fiyat aralığı, telefon/WhatsApp, "Yerel Onaylı" rozeti (varsa), kategori etiketleri, benzer listelemeler.
---
## 4. Dil Seçenekleri
`next-intl` locale listesi: **tr, en, ru**
- Varsayılan: `tr` (yerel SEO ve Türk kullanıcı için)
- Öncelik sırası: TR → EN → RU (RU içerik girişi başta makine çevirisi + manuel düzeltme olabilir, MVP'de tüm içerik 3 dilde eksiksiz olmalı — Rus turist kitlesi ana hedef olduğu için RU içerik EN kadar özenli olmalı, "sonradan eklenmiş" hissi vermemeli)
- Fiyat/saat gibi sayısal veriler dil bağımsız (IBM Plex Mono ile gösterilir, çeviri gerektirmez)
---
## 5. İçerik Modelleri (Prisma)
| Model | Açıklama |
|---|---|
| `Listing` | Ana varlık — restoran/apart/işletme hepsi bu modelde, `category` alanıyla ayrılır |
| `Category` | Restoran, Apart, Dalış, Tekne Kiralama, Tur Operatörü, Transfer, Araç Kiralama vb. |
| `Neighborhood` | Yat Limanı, İçmeler, Armutalan, Siteler, Turunç vb. |
| `BusinessSubmission` | `/isletme-ekle` formundan gelen, admin onayı bekleyen başvurular |
| `ContactMessage` | `/iletisim` formundan gelen genel mesajlar |
| `Gallery` | Listeleme başına çoklu görsel (Cloudinary) |
### Listing alanları
```prisma
model Listing {
id String @id @default(cuid())
slug String @unique
categoryId String
neighborhoodId String
nameTr String
nameEn String
nameRu String
descriptionTr String
descriptionEn String
descriptionRu String
address String
phone String?
whatsapp String?
website String?
instagram String?
priceRange Int // 1-3 (₺ / ₺₺ / ₺₺₺)
rating Float? // 0-5, admin girişli (MVP'de kullanıcı yorumu yok)
isLocalApproved Boolean @default(false) // "Yerel Onaylı" mührü
latitude Float?
longitude Float?
openingHours Json? // gün bazlı saat aralıkları
images Gallery[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
category Category @relation(fields: [categoryId], references: [id])
neighborhood Neighborhood @relation(fields: [neighborhoodId], references: [id])
}
```
**Not:** MVP'de kullanıcı yorumu/puanlama yok — `rating` admin tarafından manuel giriliyor (küratörlü rehber mantığına uygun). Kullanıcı yorumları P2'de değerlendirilebilir (bkz. §11).
---
## 6. "İşletme Ekle" Başvuru Formu Alanları
`/isletme-ekle` — işletme sahiplerinin kendi mekanlarını öneri olarak gönderdiği form:
- İşletme adı
- Kategori (dropdown → `Category`)
- Mahalle (dropdown → `Neighborhood`)
- Adres
- Telefon / WhatsApp
- Kısa açıklama (tek dilde yeterli, admin çevirip yayınlıyor)
- İletişim eden kişinin adı + e-postası
- Görsel yükleme (opsiyonel, Cloudinary)
`BusinessSubmission` tablosuna düşer, admin panelden onaylanınca `Listing`'e dönüştürülür (manuel "Onayla ve Listeye Ekle" aksiyonu — otomatik değil, kürasyon burada gerçekleşiyor).
---
## 7. İletişim Formu Alanları (`/iletisim`)
- Ad Soyad
- E-posta
- Konu (dropdown: Genel, İşbirliği, Hata Bildirimi, Diğer)
- Mesaj
`ContactMessage` tablosu, admin panelden okunur/işaretlenir.
---
## 8. Admin / Yönetim İhtiyaçları
```
/admin → Dashboard (toplam listeleme, kategori bazlı sayı, bekleyen başvuru sayısı)
/admin/listings → Liste + CRUD (kategori, mahalle filtreli)
/admin/listings/[id] → Düzenleme formu (3 dilde içerik alanları, görsel yönetimi, "Yerel Onaylı" toggle)
/admin/submissions → Bekleyen işletme başvuruları → Onayla (Listing'e dönüştür) / Reddet
/admin/messages → İletişim mesajları
/admin/categories → Kategori yönetimi
/admin/neighborhoods → Mahalle yönetimi
/admin/users → Kullanıcı yönetimi (sabit)
```
Auth: NextAuth (credentials, default) — tek admin rolü yeterli, MVP'de çoklu yetki seviyesi gerekmiyor.
---
## 9. Arama & Filtreleme
- Anasayfa arama kutusu: isim + kategori + mahalle üzerinden basit metin araması
- Kategori sayfalarında filtre: mahalle, fiyat aralığı, sadece "Yerel Onaylı" olanlar
- Harita görünümü: MVP'de opsiyonel (P1) — Leaflet + OpenStreetMap (Google Maps API maliyeti yerine)
---
## 10. Sosyal Medya / 3rd Party — Env Değişkenleri
```env
CLOUDINARY_CLOUD_NAME=""
CLOUDINARY_API_KEY=""
CLOUDINARY_API_SECRET=""
NEXT_PUBLIC_INSTAGRAM_URL=""
NEXT_PUBLIC_WHATSAPP_NUMBER="" # site geneli iletişim WhatsApp
RESEND_API_KEY="" # iletişim formu bildirimleri için
```
Harita için P1'de `NEXT_PUBLIC_MAPBOX_TOKEN` veya Leaflet (ücretsiz, tercih edilir) değerlendirilecek.
---
## 11. SEO & Uluslararası Notlar
- `hreflang` etiketleri tr/en/ru için eksiksiz olmalı — Google'ın doğru dil versiyonunu doğru kullanıcıya göstermesi kritik
- RU içerik gerçek çeviri kalitesinde olmalı, otomatik çeviri kokan metin marka güvenini zedeler (bkz. marka notunda "sonradan çevrilmiş hissi vermemeli")
- Her `Listing` için yapılandırılmış veri (schema.org `LocalBusiness`/`Restaurant`) eklenmeli — Google'da zengin sonuç (rating, adres, fiyat) için
- Sayfa başlıkları ve meta açıklamalar 3 dilde ayrı üretilmeli, tek dilden otomatik türetilmemeli
---
## 12. Teknik Notlar
- Çok-şehirli genişleme ihtimaline karşı: `Listing` modelinde şimdiden bir `city` alanı (MVP'de sabit `"marmaris"`) bulunmalı — ileride Fethiye/Bodrum/Ören/Datça eklenirse migration basit olsun
- Görseller Cloudinary, klasörleme: `marmarislocal/{category}/{listingSlug}/`
- Mock data: MVP gösterimi için en az 3 restoran, 2 apart, 3 işletme — gerçekçi TR/EN/RU içerikle (Unsplash görselli, mevcut demo-site kuralına uygun)
- Standart: soft delete (`deletedAt`), `USE_MOCK` env flag, `requireAdmin()` tüm admin route'larında — mevcut altyapı kurallarıyla birebir uyumlu
---
## 13. MVP Kapsamı
**P0 (MVP'siz olmaz):**
- Listing/Category/Neighborhood modelleri + 3 dilli içerik
- Kategori ve mahalle bazlı listeleme sayfaları + tekil detay sayfası
- "Yerel Onaylı" rozet sistemi
- İşletme ekle formu + admin onay akışı
- İletişim formu
- Admin panel (CRUD + başvuru onayı)
- TR/EN/RU dil desteği
**P1 (hızlı takip):**
- Harita görünümü (Leaflet)
- Gelişmiş filtreleme (fiyat aralığı, açık/kapalı durumu)
- Instagram feed entegrasyonu (anasayfa)
**P2 (gelecek, mimariyi şimdiden zorlamasın):**
- Kullanıcı yorumu/puanlama sistemi
- Çok-şehir desteği (Fethiye Local, Bodrum Local vb. — aynı codebase, `city` filtresiyle)
- İşletme sahibi kendi paneline giriş yapıp kendi listesini güncelleyebilsin (şu an sadece admin düzenliyor)
---
## 14. Açık Sorular
- [ ] Harita için Leaflet/OSM mi yoksa Google Maps mi tercih edilecek? (maliyet vs. tanıdıklık — Rus/İngiliz turist Google Maps'e daha alışkın olabilir)
- [ ] RU içerik çevirisi kim yapacak — profesyonel çeviri mi, DeepSeek/Gemini ile üretim + manuel kontrol mü?
- [ ] "Yerel Onaylı" kriterleri net bir liste halinde tanımlanacak mı (editoryal tutarlılık için), yoksa şimdilik sübjektif admin kararı mı?
- [ ] İlk yayın için hedef listeleme sayısı ve hangi kategoriden başlanacağı (öneri: restoranla başlamak, en yüksek arama hacmi orada)