7f69f4019d
- app/ klasörü src/app altına taşındı, @/* alias'ı src/'yi gösteriyor - tsconfig: noUncheckedIndexedAccess - shadcn/ui (Radix, Nova) başlatıldı - Better Auth, MongoDB 7.7, Mongoose 9, zod 4, react-hook-form, next-themes, sonner, TanStack Table - next.config: standalone çıktı, poweredByHeader kapalı - Geçici /api/health, i18n/tr.ts, Türkçe layout - Prompt docs/PROMPT.md olarak taşındı ve Faz 0 kararları işlendi Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
339 lines
32 KiB
Markdown
339 lines
32 KiB
Markdown
Yeni proje: BÜTÇEM
|
||
|
||
# BÜTÇEM — Aile Bütçe, Cari, Birikim, Ev Stoğu ve Akıllı Alışveriş Uygulaması
|
||
|
||
> Bu dosya VSCode içindeki Claude Code'a verilecek ana prompttur. Proje boyunca `docs/PROMPT.md` olarak repoda saklanır; değişiklikler bu dosyada yapılır.
|
||
|
||
---
|
||
|
||
## 1. Rol ve Çalışma Şekli
|
||
|
||
`nextjs-developer` skill'ini kullan. Oradaki teknoloji yığını, zorunlu gereksinimler (açık/koyu tema, login/logout, kayıt kapalı, admin paneli, rol tabanlı erişim), faz/onay kuralları ve best practice'ler bu proje için de geçerlidir. Bu prompt skill'in **Faz 0 (Keşif)** sorularını cevaplar ve skill'e ek olarak alan (domain) fazlarını tanımlar. Çelişki olursa bu prompt önceliklidir.
|
||
|
||
- Kurulumu mevcut klasöre (`.`) yap. Klasörde `.git` ve uzak repo (Gitea) **önceden ayarlı** olacak: `git init` yapma, `git remote -v` ile `origin`'i doğrula.
|
||
- Her terminal komutundan önce ne yapacağını tek cümleyle söyle.
|
||
- Her fazın sonunda sırasıyla:
|
||
1. Ne yapıldığını kısaca özetle (yaptığın varsayımlar dahil).
|
||
2. Nasıl doğrulanacağını söyle (ör. `npm run dev` → `http://localhost:3000/login`).
|
||
3. `npm run lint`, `npm run typecheck`, `npm run test` ve `npm run build` hatasız geçsin.
|
||
4. Sürüm numarasını artır, `CHANGELOG.md`'yi güncelle, commit at, etiketle ve push et (bkz. Bölüm 3).
|
||
5. **"devam" demeden sonraki faza geçme.**
|
||
- Belirsiz ve geri alınması zor kararlarda önce sor. Küçük, geri alınabilir kararlarda makul varsayımı yap ve faz özetinde belirt.
|
||
- Kütüphane sürümlerini ve API'lerini hafızadan değil, kurulu sürümün resmi dokümanından doğrula.
|
||
- Bir faz çok büyürse alt fazlara böl (ör. 6a, 6b) ve onayımı al.
|
||
|
||
---
|
||
|
||
## 2. Ürün Tanımı
|
||
|
||
**BÜTÇEM**, bir hanenin (aile) gelir-giderini, banka/kart/cari hesaplarını, birikimlerini (altın, döviz, ziynet), aylık bütçesini, ev stoğunu ve alışveriş listelerini tek yerde yöneten, kişisel kullanıma yönelik, çok kullanıcılı bir web uygulamasıdır. İleride aynı backend'i kullanan bir mobil uygulama (React Native / Expo) yazılacaktır.
|
||
|
||
- **Açılış:** Uygulama her zaman login ekranıyla açılır. Oturum yoksa hiçbir sayfa ve API verisi görünmez; giriş sonrası dashboard'a yönlenir.
|
||
- **Arayüz dili:** Türkçe (tr-TR). Metinler tek yerde toplanır (`src/i18n/tr.ts`); şimdilik çok dil kurma.
|
||
- **Ana para birimi:** TRY. Tüm hesap bakiyeleri, bütçe ve raporlar TL'dir. Altın/döviz/ziynet yalnızca **varlık (birikim)** ve **aynî borç** olarak, miktar + TL karşılığıyla tutulur (Bölüm 6.5–6.6). Döviz cinsinden banka hesabı ileriki aşamadır; veri modelinde `currency: "TRY"` alanı bulunsun.
|
||
- **Saat dilimi:** Europe/Istanbul. Tarihler veritabanında UTC saklanır, ekranda İstanbul saatine göre gösterilir. Ay sınırı, hesap kesim ve günlük plan hesapları İstanbul saatine göre yapılır.
|
||
- **Biçimler:** `Intl.NumberFormat("tr-TR", { style: "currency", currency: "TRY" })`, tarih `dd.MM.yyyy`, ondalık ayırıcı virgül. Para giriş alanları Türkçe biçimi (`1.250,50`) doğru ayrıştırmalı.
|
||
|
||
---
|
||
|
||
## 3. Sürümleme ve Git Akışı
|
||
|
||
### 3.1 Semantic Versioning (X.Y.Z)
|
||
- Biçim **MAJOR.MINOR.PATCH** ([semver.org](https://semver.org)). Tek kaynak `package.json` içindeki `version`.
|
||
- Geliştirme süresince **0.Y.Z**: her tamamlanan faz MINOR'u artırır (`0.1.0`, `0.2.0` …), faz içi veya sonrası düzeltmeler PATCH'i artırır (`0.6.1`).
|
||
- İlk canlıya alma **`1.0.0`**. Sonrasında: geriye uyumlu yeni özellik → MINOR, hata düzeltme → PATCH, veri modelini veya API'yi kıran değişiklik → MAJOR.
|
||
- Her sürüm için annotated git etiketi: `git tag -a v0.6.0 -m "Faz 6: Hesaplar ve işlemler"`.
|
||
- `CHANGELOG.md`: [Keep a Changelog](https://keepachangelog.com/tr-TR/1.1.0/) biçimi, Türkçe başlıklar (Eklendi, Değişti, Düzeltildi, Kaldırıldı), en üstte `[Yayınlanmamış]`.
|
||
- Uygulama içinde sürüm görünür olsun: kullanıcı menüsünde ve `GET /api/health` cevabında (`version`, `commit`).
|
||
|
||
### 3.2 Commit ve push
|
||
- Commit mesajları **Conventional Commits** (İngilizce tip + Türkçe açıklama): `feat(transactions): bölünmüş işlem desteği`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:`.
|
||
- Her faz için dal: `faz/NN-kisa-ad` (ör. `faz/06-hesaplar-islemler`). Faz içinde mantıklı küçük commit'ler at.
|
||
- Faz onayından sonra:
|
||
```bash
|
||
git checkout main
|
||
git merge --no-ff faz/06-hesaplar-islemler -m "feat: Faz 6 - hesaplar ve işlemler"
|
||
git tag -a v0.6.0 -m "Faz 6: Hesaplar ve işlemler"
|
||
git push origin main --follow-tags
|
||
git branch -d faz/06-hesaplar-islemler
|
||
```
|
||
- Push'tan önce `git status` ve `git diff --cached` ile `.env*`, yüklenen dosyalar (`uploads/`) veya sır içeren bir şeyin commit'e girmediğini kontrol et.
|
||
- Canlı ortam (Dokploy) `main` dalını izler; otomatik deploy yalnızca canlıya alma fazında açılır.
|
||
|
||
---
|
||
|
||
## 4. Marka ve Tasarım
|
||
|
||
- Ad: **BÜTÇEM** (URL, paket adı ve kod içinde ASCII: `butcem`).
|
||
- Logo dosyaları `public/brand/` altında olacak (`logo.svg`, `logo-dark.svg`, `icon.png` 512×512). Yoksa yer tutucu koy ve beni uyar; logoyu kendin çizme.
|
||
- Renkler **mavi ve beyaz tonları**: `--primary` orta-koyu mavi (`oklch`), arka plan beyaz/çok açık mavi-gri; koyu temada lacivert arka plan, açık mavi vurgu. Sabit renk kodu yok, yalnızca CSS değişkenleri.
|
||
- Anlamsal renk değişkenleri: `--income` (yeşil), `--expense` (kırmızı), `--budget` (mavi), `--warning` (turuncu). Grafiklerde de bunlar kullanılır.
|
||
- Favicon, `manifest.webmanifest` ve uygulama ikonları logodan üretilir. Temel **PWA**: telefona "Ana ekrana ekle" ile kurulabilir.
|
||
- Mobil öncelikli: mobilde alt gezinme çubuğu, masaüstünde yan menü. **Hızlı ekle** butonu (gider / gelir / transfer) her ekranda erişilebilir.
|
||
- Form tasarımı: zorunlu alanlar önde, ileri seviye alanlar (etiket, ek dosya, bölme) katlanabilir bölümde. Formlar mobilde tam ekran Sheet/Drawer olarak açılır.
|
||
|
||
---
|
||
|
||
## 5. Kullanıcılar, Haneler ve Roller
|
||
|
||
- **Sistem rolleri (Better Auth admin plugin):** `admin`, `user`. Kayıt kapalı; kullanıcıları yalnızca admin oluşturur.
|
||
- **Hane (household):** Kullanıcılar bir veya daha fazla haneye üye olabilir; üst barda aktif hane seçilir. Tüm alan verisi `householdId` ile hanede tutulur.
|
||
- **Hane içi roller:** `owner` (hane ayarları, üyeler, hesaplar), `member` (işlem girer, liste ve stok günceller), `viewer` (yalnızca görüntüler).
|
||
- Admin panelinde: hane oluşturma, kullanıcıyı haneye atama, hane içi rol değiştirme.
|
||
- **Veri izolasyonu kritik:** Her sorgu, Server Action ve API, `requireHouseholdMember(householdId, minRole)` DAL fonksiyonundan geçer. Başka hanenin verisine erişim imkânsız olmalı; bunun için otomatik testler yaz.
|
||
- Her kayıtta `createdBy` / `updatedBy`; raporlarda kişi bazlı filtre.
|
||
- Kullanıcıya özel hesap gizliliği (opsiyonel bayrak): bir hesap "yalnızca ben" olarak işaretlenebilir; diğer üyeler bakiyesini görmez ama hane toplamlarına dahil edilip edilmeyeceği hane ayarıdır.
|
||
|
||
---
|
||
|
||
## 6. Modüller
|
||
|
||
### 6.1 Hesaplar
|
||
Hesap türleri:
|
||
- `cash` nakit, `bank` vadesiz banka, `savings` birikim/vadeli, `credit_card` kredi kartı, `meal_card` yemek kartı (Pluxee/Sodexo, Multinet, Edenred, Setcard vb. sağlayıcı alanı).
|
||
- Banka hesabında opsiyonel **esnek hesap (KMH)**: limit, faiz oranı bilgisi, hesap kesim günü.
|
||
- Alanlar: ad, tür, banka/kurum, açılış bakiyesi ve tarihi, renk/ikon, arşiv durumu, sıralama.
|
||
- Güncel bakiye işlemlerden hesaplanır; performans için önbellek alanı tutulabilir ama tek doğruluk kaynağı işlemlerdir ve tutarlılık testleri yazılır.
|
||
- **Mutabakat (reconciliation):** Kullanıcı banka/kart ekstresindeki bakiyeyi girer, fark varsa düzeltme işlemi önerilir; mutabakatı yapılmış işlemler işaretlenir.
|
||
|
||
### 6.2 Kategoriler
|
||
- Gelir ve gider ayrı ağaçlar; **sınırsız derinlik** (pratikte 3 seviye), ikon, renk, sıralama, arşivleme.
|
||
- Hane oluşturulunca varsayılan Türkçe kategori seti yüklenir (Market, Faturalar › Elektrik/Su/Doğalgaz/İnternet, Kira, Ulaşım, Sağlık, Eğitim, Giyim, Eğlence, Abonelikler, Maaş, Ek gelir …).
|
||
- Raporlar ve bütçe, alt kategorileri üst kategoriye toplayarak da gösterebilmeli.
|
||
|
||
### 6.3 İşlemler (gelir, gider, transfer)
|
||
- Türler: `income`, `expense`, `transfer` (hesap ↔ hesap, hesap ↔ cari; Bölüm 6.4).
|
||
- Alanlar: tutar, tarih, hesap, kategori, açıklama, satıcı/karşı taraf (payee), etiketler, ekleyen kişi, durum (`planned` | `posted` | `void`).
|
||
- **Bölünmüş işlem (split):** Bir işlem birden çok kaleme bölünebilir (ör. 1.200 TL market → Gıda 800, Temizlik 250, Kişisel bakım 150). Kalemlerin her biri kategori, tutar ve opsiyonel açıklama taşır; kalemler toplamı ana tutara eşit olmalı (zod + sunucu doğrulaması, kalan tutar göstergesi, "kalanı son kaleme ekle" kolaylığı). Listede **tek satır** (bölünmüş ikonu ile) görünür, detayda tüm kalemler listelenir. Bütçe ve kategori raporları kalemler üzerinden hesaplanır.
|
||
- **Ek dosyalar:**
|
||
- Gider: bir veya birden çok **görsel** (fiş, fatura fotoğrafı), zorunlu değil.
|
||
- Gelir: bir veya birden çok **görsel veya PDF** (ör. maaş bordrosu), zorunlu değil.
|
||
- Formda yalnızca küçük bir "Ek ekle" alanı ve küçük önizleme sayacı görünür; formu ve detay sayfasını şişirme. Görüntüleme **carousel** ile (sağ/sol oklar, kaydırma, klavye okları, tam ekran açma, "2 / 5" göstergesi). shadcn `Carousel` (Embla) kullan. PDF'ler carousel'de ikon + "Aç" butonu olarak görünür.
|
||
- Teknik kurallar Bölüm 7.4'te.
|
||
- **Akıllı giriş:** Aynı satıcı için son kullanılan kategori ve hesap otomatik önerilsin (satıcı kuralları). Son işlemi kopyala kısayolu.
|
||
- Listeleme: tarih aralığı, hesap, kategori, kişi, durum, tutar aralığı, etiket filtreleri; arama; sayfalama; CSV dışa aktarma.
|
||
- Silme: soft delete (`deletedAt`), geri al (undo) bildirimi.
|
||
|
||
### 6.4 Cari Hesaplar (Kişiler arası borç/alacak)
|
||
- **Kişiler (cari kartlar):** akraba, arkadaş veya üçüncü şahıs; ad, ilişki, telefon, not.
|
||
- Her cari için defter: verilen borç, alınan borç, geri ödeme alındı, geri ödeme yapıldı. Cari bakiye: "Bana borçlu" / "Ben borçluyum" ve net tutar.
|
||
- **Transfer:** Hesaptan cariye (borç verme / borç ödeme) ve cariden hesaba (borç alma / tahsilat) para transferi. Hesap bakiyesi değişir, gelir/gider raporlarına **girmez** (transferdir).
|
||
- Vade tarihi ve hatırlatma (opsiyonel), kısmi ödeme desteği, cari ekstresi (tarih sıralı hareketler ve yürüyen bakiye).
|
||
|
||
### 6.5 Aynî Borçlar (altın, döviz, ziynet ile borç)
|
||
Örnek senaryo: Bir şahıstan 5 gr altın borç aldım.
|
||
- Borç kaydı: cari kişi, varlık türü (gram altın, çeyrek, yarım, tam, cumhuriyet, 22 ayar bilezik gram, USD, EUR …), **miktar** (5 gr), borç tarihi, **o tarihteki birim fiyat ve TL karşılığı** (not olarak saklanır; fiyat elle girilir veya fiyat tablosundan önerilir).
|
||
- **Birikim planı:** Borca bağlı bir birikim hedefi (aylık ayrılacak tutar). Biriktirilen para seçilen bir hesaba (ör. birikim hesabı) aktarılır; borçla ilişkilendirilir ama borç **kapanmaz**.
|
||
- Borç ekranında: borç miktarı, borç tarihindeki TL değeri, güncel fiyatla TL değeri, biriken tutar, kalan ihtiyaç, tahmini kapanış ayı.
|
||
- **Kapanış yalnızca "Ödeme gerçekleşti" komutuyla:** Kullanıcı fiziksel ödemeyi yaptığında komutu verir; ödeme şekli (aynı varlıkla / TL karşılığıyla), tarih, ödenen miktar/tutar girilir. Kısmi ödeme miktarı düşürür; tam ödemede borç kapanır. Birikim hesabından ilgili çıkış işlemi oluşturulur.
|
||
- Aynı mantık **aynî alacaklar** için de çalışır (ben altın borç verdiysem).
|
||
|
||
### 6.6 Birikim ve Varlık Takibi (altın, döviz, ziynet)
|
||
- Varlık türleri tablosu (gram altın, çeyrek, yarım, tam, ata, 22 ayar gram, gümüş gram, USD, EUR, GBP …), birim (gr/adet/birim).
|
||
- **Alım lotları:** tarih, miktar, birim fiyat, toplam TL, kaynak hesap (para hesaptan çıkar), saklama yeri notu. Satış ve hediye/çıkış kayıtları.
|
||
- **Fiyat tablosu:** varlık × tarih × alış/satış fiyatı. İlk aşamada **elle giriş**; otomatik kaynak `AssetPriceProvider` arayüzüyle sonraki fazda (Bölüm 6.12).
|
||
- Hesaplamalar: toplam miktar, ağırlıklı ortalama maliyet, güncel değer, gerçekleşmemiş kâr/zarar (TL ve %), gerçekleşmiş kâr/zarar (satışlarda).
|
||
- **Dönemsel rapor:** "Son 6 ay" gibi bir aralıkta yatırılan toplam TL, dönem sonu değer, kâr/zarar ve aylık değer grafiği. (Örnek: 10 gr altını 25.000 TL'ye aldım, her ay ekledim; 6 ay sonra ne kadar kazandım?)
|
||
- Net varlık (net worth) özeti: hesap bakiyeleri + varlıkların güncel değeri − borçlar (TL ve aynî).
|
||
|
||
### 6.7 Planlı ve Düzenli İşlemler
|
||
- Tanım: tür (gelir/gider/transfer), tutar (sabit veya tahmini), hesap, kategori, başlangıç tarihi, sıklık (günlük/haftalık/aylık/yıllık, ayın N. günü, ayın son günü), **tekrar sayısı** (ör. 12) veya bitiş tarihi.
|
||
- Sistem her tekrar için `planned` durumunda **planlı kayıt** üretir. Planlı kayıtlar bakiyeyi etkilemez; plan/bütçe grafiklerinde ve "yaklaşan" listelerinde görünür.
|
||
- **"İşlemi onayla" komutu** ile `posted` olur; onaylarken tutar ve tarih düzenlenebilir (ör. fatura tutarı değişti). "Atla" ve "Ertele" seçenekleri.
|
||
- Vadesi geçmiş onaylanmamış planlı işlemler dashboard'da uyarı olarak görünür.
|
||
- Seri düzenleme: "yalnızca bu", "bu ve sonrakiler", "tümü".
|
||
|
||
### 6.8 Kredi Kartı ve Esnek Hesap (KMH) Dönemleri
|
||
- Kart tanımı: limit, **hesap kesim günü** (ör. 29), **son ödeme günü** (kesimden N gün sonra veya ayın sabit günü), varsayılan banka hesabı (ödeme için).
|
||
- **Dönem mantığı:** Son hesap kesim tarihine kadar (kesim günü dahil) olan işlemler **"Hesap Kesim Dönemi"**, kesim gününden sonraki işlemler **"Güncel Dönem"**. Kesim günü ayda yoksa (ör. 31) ayın son günü kullanılır. Dönemler `statements` koleksiyonunda saklanır (başlangıç, bitiş, son ödeme, dönem borcu, asgari tutar, ödenen).
|
||
- Faiz, ücret ve vergi kalemleri (ör. KKDF/BSMV) dönem kesiminden önce elle veya planlı işlem olarak girilebilir.
|
||
- **Taksitli harcama:** toplam tutar, taksit sayısı (ör. 9) → her dönem için taksit kalemi oluşur; listede "Hepsiburada 4/9" biçiminde görünür. Taksitlerin bütçe etkisi: tercih olarak "tamamını harcama ayına yaz" veya "her taksiti kendi ayına yaz" (hane ayarı; varsayılan her taksit kendi ayı).
|
||
- **Kart özeti ekranı:** anlık toplam borç, hesap kesim dönemi borcu ve son ödeme tarihi, güncel dönem harcamaları, kullanılabilir limit, yaklaşan taksitler (dönem dönem toplamlar) ve planlı harcamalar.
|
||
- Kart borcu ödemesi: banka hesabından karta transfer; dönem borcunu kapatır veya kısmi öder.
|
||
- Aynı dönem mantığı esnek hesaplı banka hesaplarında da çalışır (faiz tahakkuku kesim gününde).
|
||
|
||
### 6.9 Aylık Bütçe ve Günlük Plan
|
||
- **Bütçe:** ay bazlı, kategori başına limit; önceki aydan kopyala veya **önceki ayın gerçekleşen giderlerinden oluştur**.
|
||
- Gerçekleşen / limit / kalan, yüzde çubuğu, %80 ve %100 eşiklerinde uyarı, ay sonu tahmini (harcama hızına göre).
|
||
- **Gelir planı:** ay için beklenen gelirler (planlı gelir işlemlerinden otomatik + elle ek).
|
||
- **Günlük plan (dashboard'da):**
|
||
- Ayın toplam bütçesi ayın gün sayısına yayılır (ör. Aralık 31 gün). Varsayılan dağıtım: belirli tarihe bağlı giderler (kira, faturalar, planlı işlemler) kendi günlerine, kalan değişken bütçe günlere eşit yayılır. Alternatif: önceki ayın günlük harcama örüntüsüne göre dağıt (ayar).
|
||
- Her gün için: planlanan, gerçekleşen, kümülatif planlanan vs. kümülatif gerçekleşen, **yüzde** (ör. "Bugün ayın %42'si geçti, bütçenin %51'i harcandı").
|
||
- Planlanan ve gerçekleşen gider, **planlanan gelirle** karşılaştırılır ("Bu tempoda ay sonunda elde kalacak: X TL"). Sonraki ayın planlanan geliriyle karşılaştırma görünümü.
|
||
|
||
### 6.10 Ev Stoğu
|
||
**Yapı (üç kavram):**
|
||
1. **Stok kategorileri** — sınırsız derinlikte ağaç. Varsayılan set:
|
||
- Mutfak › Manav, Şarküteri, Bakliyat (Kuru Fasulye, Nohut, Kırmızı Mercimek, Yeşil Mercimek)
|
||
- Genel Temizlik › Bulaşık (Tablet Deterjan, Jel Deterjan, Elde Yıkama Deterjanı), Çamaşır (Toz Deterjan, Yumuşatıcı), Genel
|
||
- Kişisel Temizlik › Şampuan, Tıraş, Kişisel Bakım
|
||
2. **Ürün tipi (genel ürün)** — markadan bağımsız ihtiyaç: "Toz Deterjan", "Kırmızı Mercimek". Stok bu seviyede tutulur. Alanlar: kategori, temel ölçü birimi (kg, lt, adet, **özel birim** ör. "yıkama", "tablet"), **hedef (tam) stok miktarı**, kritik eşik yüzdesi (varsayılan **%20**), saklama yeri.
|
||
3. **Ürün (marka/varyant)** — "Ariel 5 kg / 50 yıkama". Fiyatlar bu seviyede (Bölüm 6.11).
|
||
|
||
**İşleyiş:**
|
||
- İlk kurulumda kullanıcı evdeki miktarları tahmini veya ambalaj üzerinden girer.
|
||
- Stok hareketleri ayrı koleksiyonda: `purchase` (alışveriş), `consume` (tüketim), `waste` (zarar/ziyan/fire, neden ile), `count_adjust` (sayım düzeltmesi). Mevcut miktar hareketlerden türetilir.
|
||
- **Periyodik sayım:** ürün tipi veya kategori bazında sayım sıklığı (ör. 15 günde bir). Sayım ekranı: liste halinde beklenen miktar → gerçek miktarı gir → fark otomatik `count_adjust` olur; kullanıcı farkın bir kısmını `waste` olarak işaretleyebilir. Sayımı gelen kategoriler dashboard'da hatırlatılır.
|
||
- **Eşik:** Mevcut miktar hedef stoğun **%20'sinin altına** düşerse ürün otomatik olarak aktif alışveriş listesine **öneri** olarak eklenir.
|
||
- **Önerilen alım miktarı:** `hedef − mevcut`, tüketim hızına göre yuvarlanır. Son dönemde **zarar/ziyan** kaydı varsa (ör. bozulan sebze) önerilen miktar fire oranı kadar **düşürülür** ve kullanıcıya nedeni gösterilir ("Son 2 alımda %30 fire, miktar azaltıldı").
|
||
- Son kullanma tarihi (opsiyonel) ve yaklaşanlar için uyarı; tek dokunuşla "1 azalt".
|
||
- Tüketim analizi: ürün tipi başına aylık ortalama tüketim ve maliyet.
|
||
|
||
### 6.11 Mağazalar, Ürün Fiyatları ve Birim Fiyat Karşılaştırma
|
||
- **Mağazalar:** ad, tür (fiziksel market / online platform / pazar), şube, **eve uzaklık (km)**, **taşıma güçlüğü puanı (1–5)**, online ise teslimat ücreti ve ücretsiz teslimat alt limiti, **"Yemek kartı geçerli mi?"** ve geçerli yemek kartı sağlayıcıları, not. Bu bilgilerden "en yakın / en uzak / en zahmetli" sıralaması ve mağaza **zahmet skoru** hesaplanır.
|
||
- **Ürün (varyant) kaydı:** ürün tipi, marka, tanım, **ürün görselleri** (bir veya birden çok), barkod (opsiyonel), **paket miktarı ve birimi** (1 paket = 500 g), opsiyonel **kullanım birimi dönüşümü** (5 kg = 50 yıkama; 1 kutu = 40 tablet).
|
||
- **Fiyat kaydı:** ürün × mağaza × fiyat × tarih; kampanya/indirim işareti ve geçerlilik tarihi; kaynak `manual` | `receipt` | `provider:<ad>`. Fiyat geçmişi grafiği.
|
||
- **Birim fiyat:** Her fiyat otomatik olarak birim fiyata dönüştürülür (TL/kg, TL/lt, TL/adet, TL/yıkama). Aynı ürün tipindeki farklı markalar ve mağazalar **birim fiyat** üzerinden sıralanır; en uygunu vurgulanır.
|
||
|
||
### 6.12 Alışveriş Listesi, Akıllı Öneri ve Alışveriş Sonrası Karşılaştırma
|
||
- **Listeler:** birden çok aktif liste; ürün tipi (genel) veya belirli ürün (marka) eklenir; serbest metin de olabilir; stok eşik önerileri onayla/reddet. Aile üyeleri aynı listeyi kullanır (sayfa odaklanınca ve periyodik yenileme yeterli).
|
||
- **Akıllı mağaza önerisi:** Listedeki her kalem için son bilinen fiyatlara göre en ucuz mağaza ve marka önerilir. Planlayıcı şu kuralları birlikte uygular:
|
||
1. Toplam maliyeti düşür (birim fiyat üzerinden).
|
||
2. Mümkünse **az sayıda mağazada topla** (aynı mağazadan alma tercihi); bir mağaza daha eklemek ancak tasarruf, kullanıcı ayarındaki eşiği (ör. 100 TL) aşıyorsa önerilir.
|
||
3. Uzaklık ve taşıma güçlüğü puanını maliyet cezası olarak hesaba kat (ağır/hacimli ürünler yakın veya online mağazaya).
|
||
4. **Yemek kartı önceliği:** Yemek kartı bakiyesi varsa, yemek kartı geçen mağazalardaki uygun kalemler önce bu karta yönlendirilir.
|
||
5. Online mağazada teslimat ücreti ve ücretsiz teslimat alt limitini hesaba kat.
|
||
- Çıktı: "Tek mağaza en iyi seçenek: X TL" vs "Önerilen dağılım: A marketten 7 ürün, B'den 3 ürün: Y TL (Z TL tasarruf)". Algoritmayı saf fonksiyon olarak yaz ve birim testlerle doğrula.
|
||
- **Alışverişe çıkış modu:** mağazaya göre gruplanmış, büyük dokunma alanlı kontrol listesi.
|
||
- **Alışveriş sonrası giriş ve karşılaştırma:**
|
||
- Eve dönünce kullanıcı alışveriş listesini açar ve aldığı ürünleri listeden tek tek seçer: gerçek ürün (aynı ürün veya **muadil**: aynı ürün tipinde farklı marka/paket), miktar, gerçek fiyat, mağaza.
|
||
- Listede olmayan ekstra ürünler de eklenebilir.
|
||
- **Karşılaştırma raporu:** planlanan vs. alınan (kalem bazında: aynı / muadil / alınmadı / plansız ekstra), planlanan tutar vs. gerçek tutar, fark ve nedenleri.
|
||
- "Alışverişi tamamla" tek **MongoDB transaction** içinde: (1) stok hareketleri (`purchase`), (2) fiyat kayıtları, (3) seçilen hesaptan (yemek kartı dahil) **bölünmüş gider işlemi** (kalemler stok kategorilerinden gider kategorilerine eşlenir), (4) fiş görselleri ek dosya olarak.
|
||
- **Otomatik fiyat kaynakları (son faz):** `PriceProvider` ve `AssetPriceProvider` arayüzleri. Adaylar: market fiyatları için marketfiyati.org.tr (TÜBİTAK), altın/döviz için TCMB ve açık JSON kaynakları. Entegrasyondan önce resmi API olup olmadığını ve kullanım şartlarını araştırıp bana raporla; izinli olmayan kaynağı tarama (scraping) yapma. O zamana kadar yalnızca elle giriş.
|
||
|
||
### 6.13 Dashboard
|
||
- Üst kartlar: bu ay gelir / gider / kalan, toplam hesap bakiyesi, kart borçları, net varlık.
|
||
- **Ana çizgi grafik:** Planlanan Gelir (**yeşil**), Planlanan Gider / Bütçe (**mavi**), Gerçekleşen Gider (**kırmızı**). Periyot seçici: **Haftalık, Aylık, Altı Aylık, Yıllık.** Kümülatif / dönemsel görünüm geçişi. Renkler `--income`, `--budget`, `--expense` değişkenlerinden.
|
||
- Günlük plan göstergesi (Bölüm 6.9), bütçe durum çubukları, onay bekleyen planlı işlemler, yaklaşan kart ödemeleri ve taksitler, azalan stoklar ve sayımı gelen kategoriler, aktif alışveriş listesi özeti, son işlemler.
|
||
|
||
### 6.14 Raporlar
|
||
- **Kategori dağılımı:** halka grafik + tablo; her kategorinin **toplam gidere oranı (%)** (ör. toplam 35.000 TL, faturalar 5.000 TL → %14,3). Üst kategori / alt kategori kırılımı, önceki aya göre değişim.
|
||
- Aylık trend (son 12 ay), gelir-gider-tasarruf oranı.
|
||
- Kişi bazlı harcama, hesap bazlı hareket.
|
||
- Bütçe vs. gerçekleşen (kategori ve ay bazında).
|
||
- Cari özet (kim kime ne kadar borçlu), aynî borçlar.
|
||
- Birikim kâr/zarar raporu (Bölüm 6.6).
|
||
- Alışveriş: liste vs. gerçekleşen, mağaza bazlı harcama, ürün tipi başına birim fiyat geçmişi, fire/zarar raporu.
|
||
- Grafikler shadcn charts (Recharts). Tüm raporlar CSV dışa aktarılabilir.
|
||
|
||
---
|
||
|
||
## 7. Veri ve Mimari Kuralları
|
||
|
||
### 7.1 Para ve miktar
|
||
- **Para tutarları tamsayı kuruş** (`amountMinor: number`, 125,50 TL → 12550). Float ile hesap yok. `lib/money.ts`: ayrıştırma (`"1.250,50"` → 125050), biçimlendirme, toplama, **oransal bölme** (kuruş kaybı olmadan; taksit ve split için) ve birim testler.
|
||
- Miktarlar (stok, gram altın) için `quantity` alanı: ölçü birimine göre sabit ölçek (ör. gram için 3 ondalık → miligram tamsayı) kullan; kuralı `lib/quantity.ts` içinde belgele ve test et.
|
||
- Fiyat/birim fiyat hesaplarında yuvarlama yalnızca gösterimde yapılır.
|
||
|
||
### 7.2 Veritabanı
|
||
- Tüm alan koleksiyonlarında `householdId` index'i ve sık sorgular için bileşik index'ler (ör. `{ householdId, date: -1 }`, `{ householdId, status, date }`).
|
||
- Çok adımlı yazmalar (transfer, alışverişi tamamla, aynî borç kapatma, kart ödemesi, planlı işlem onayı) **MongoDB transaction** ile.
|
||
- Soft delete (`deletedAt`) işlemler, ürünler ve cari kayıtlar için; hesaplar ve kategoriler için arşivleme.
|
||
- Şema değişiklikleri için basit migration mekanizması (`scripts/migrations/NNN-*.ts`, uygulanmış migration'lar `migrations` koleksiyonunda).
|
||
- Audit log: hane ayarları, üye değişiklikleri, silmeler, aynî borç kapatma ve mutabakat düzeltmeleri.
|
||
|
||
### 7.3 Katmanlar ve mobil hazırlığı
|
||
- İş mantığı `features/*/service.ts` içinde, framework'ten bağımsız saf fonksiyonlar/servisler. Hesaplama motorları (bütçe dağıtımı, kart dönemleri, taksit, mağaza önerisi, stok öneri miktarı, varlık kâr/zarar) ayrı ve **birim testli**.
|
||
- Web: Server Actions; mobil: `/api/v1/*` Route Handler'ları — ikisi **aynı servisleri** çağırır.
|
||
- zod şemaları ve türetilmiş tipler `src/shared/` altında (mobil projede yeniden kullanılacak).
|
||
- Mobil kimlik doğrulama: Better Auth bearer/Expo desteğini mobil API fazında araştır ve kur.
|
||
- `GET /api/health`: DB ping, sürüm, commit — Dokploy healthcheck için.
|
||
|
||
### 7.4 Ek dosyalar (uploads)
|
||
- Depolama soyutlaması `lib/storage/` (`put`, `get`, `delete`): ilk sürücü **yerel disk** (`UPLOAD_DIR`, canlıda Docker volume), ileride S3 uyumlu (MinIO) eklenebilir.
|
||
- İzinli türler: JPEG, PNG, WebP, HEIC (WebP'ye dönüştür), PDF. MIME türünü dosya içeriğinden doğrula (uzantıya güvenme). Dosya başına boyut sınırı (`MAX_UPLOAD_MB`, varsayılan 10), kayıt başına en fazla 10 dosya.
|
||
- Görseller `sharp` ile yeniden boyutlandırılır, EXIF (konum dahil) temizlenir, küçük resim (thumbnail) üretilir.
|
||
- Dosyalar **herkese açık klasörde değil**; yalnızca oturum + hane yetkisi kontrol eden bir route üzerinden servis edilir. Dosya adları rastgele ID.
|
||
- Dosyalar `attachments` koleksiyonunda meta veriyle tutulur (`ownerType`, `ownerId`, boyut, tür, yükleyen). Kayıt silinince dosya da (soft delete süresi sonunda) temizlenir.
|
||
- `uploads/` git'e ve Docker imajına girmez; canlıda yedeklemeye dahildir.
|
||
|
||
### 7.5 Güvenlik
|
||
- Skill'deki güvenlik kuralları + rate limit, güvenlik başlıkları, CSP (carousel ve grafik kütüphaneleriyle uyumlu).
|
||
- Sırlar yalnızca `.env.local` (lokal) ve Dokploy ortam değişkenleri (canlı). `.env.example` güncel tutulur.
|
||
|
||
---
|
||
|
||
## 8. Ortamlar ve Altyapı
|
||
|
||
### 8.1 Lokal geliştirme
|
||
- MongoDB, `docker-compose.yml` ile **tek düğümlü replica set** (`rs0`) olarak çalışır (transaction için zorunlu); kalıcı volume, healthcheck, replica set'i otomatik başlatan init.
|
||
- Lokal bağlantı: `mongodb://localhost:27019/butcem?replicaSet=rs0&directConnection=true` (bkz. 10.1).
|
||
- `env.ts` zod ile doğrular: `MONGODB_URI`, `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL`, `SEED_ADMIN_EMAIL`, `SEED_ADMIN_PASSWORD`, `UPLOAD_DIR`, `MAX_UPLOAD_MB`, `APP_VERSION` ve `APP_COMMIT` (build sırasında).
|
||
|
||
### 8.2 Canlı ortam (homeserver: "Atlas")
|
||
- Kaynak kod: Atlas üzerindeki **Gitea** reposu (`origin`).
|
||
- Yayın: **Dokploy**, Gitea reposunun `main` dalından build/deploy (Dockerfile ile).
|
||
- Domain: **`butcem.ta1sph.website`** (ASCII). HTTPS Let's Encrypt (Dokploy/Traefik).
|
||
- MongoDB: Dokploy veritabanı servisi, replica set açık, kimlik doğrulama açık, uygulamaya özel `butcem_app` kullanıcısı (yalnızca `butcem` veritabanında `readWrite`), **dışa port açılmadan** yalnızca Docker iç ağından erişim. Kurulumu ben `docs/MONGODB-KURULUM.md`'ye göre yapmış olacağım; bağlantı bilgisi Dokploy ortam değişkeninde.
|
||
- Yüklenen dosyalar için kalıcı volume (`/app/uploads`).
|
||
- Yedekleme: günlük `mongodump` (Dokploy backup veya cron), **uploads volume** yedeği, en az 7 günlük saklama, sunucu dışına kopya ve geri yükleme talimatı.
|
||
- `Dockerfile`: Next.js `output: "standalone"`, çok aşamalı build, root olmayan kullanıcı, `HEALTHCHECK`, `.dockerignore`. **Faz 1'de oluştur** ve her fazda `docker build` ile canlı build'in bozulmadığını doğrula.
|
||
- `docs/DEPLOY.md`: Dokploy uygulama kurulumu, ortam değişkenleri, domain, volume, yedekleme ve geri yükleme adım adım. Sunucu komutlarını ben çalıştıracağım; her komutu açıklamasıyla yaz.
|
||
|
||
---
|
||
|
||
## 9. Faz Planı ve Sürümler
|
||
|
||
Skill fazları (0–4) uygulanır, ardından alan fazları gelir. Her faz kendi seed verisini genişletir (gerçekçi Türk market ürünleri ve fiyatları, TL tutarlar, son 6 aylık işlemler, örnek cari ve altın kayıtları).
|
||
|
||
| Faz | İçerik | Sürüm |
|
||
|---|---|---|
|
||
| 0 | Keşif: kalan belirsizlikleri sor (en fazla 5), sayfa listesi, koleksiyonlar ve roller planını onayıma sun | — |
|
||
| 1 | Framework, klasör yapısı, Docker replica set MongoDB, Dockerfile iskeleti, CHANGELOG, sürümleme | 0.1.0 |
|
||
| 2 | Frontend iskeleti: marka/tema, login (açılış ekranı), layout (mobil alt menü), admin kullanıcı yönetimi, PWA temeli | 0.2.0 |
|
||
| 3 | Backend: Better Auth, DAL, güvenlik başlıkları, `/api/health` | 0.3.0 |
|
||
| 4 | Seed: admin, örnek hane ve aile üyeleri | 0.4.0 |
|
||
| 5 | Haneler ve hane içi roller, hane seçici, izolasyon testleri, audit log | 0.5.0 |
|
||
| 6 | Hesaplar (yemek kartı dahil), kategoriler, gelir/gider/transfer, **bölünmüş işlem**, **ek dosyalar + carousel**, mutabakat | 0.6.0 |
|
||
| 7 | Planlı/düzenli işlemler ve onay akışı; **kredi kartı ve KMH dönemleri, taksitler**, kart özeti | 0.7.0 |
|
||
| 8 | Cari hesaplar, hesap ↔ cari transferleri, **aynî borç/alacak** ve "Ödeme gerçekleşti" akışı | 0.8.0 |
|
||
| 9 | Birikim ve varlık takibi, fiyat tablosu (elle), kâr/zarar, net varlık | 0.9.0 |
|
||
| 10 | Aylık bütçe, gelir planı, **günlük plan** | 0.10.0 |
|
||
| 11 | Ev stoğu: kategori ağacı, ürün tipleri, hareketler, periyodik sayım, %20 eşik, fire ayarlı öneri | 0.11.0 |
|
||
| 12 | Mağazalar (uzaklık, taşıma, yemek kartı), ürün varyantları ve görselleri, fiyat geçmişi, **birim fiyat** | 0.12.0 |
|
||
| 13 | Alışveriş listeleri, akıllı mağaza önerisi, alışveriş modu, **alışveriş sonrası giriş ve karşılaştırma**, "alışverişi tamamla" transaction'ı | 0.13.0 |
|
||
| 14 | Dashboard (çizgi grafik + periyotlar) ve raporlar, CSV dışa aktarma | 0.14.0 |
|
||
| 15 | Canlıya alma: `docs/DEPLOY.md`, Dokploy + Gitea, domain, volume, yedekleme, smoke test | **1.0.0** |
|
||
| 16 | `/api/v1` mobil API ve mobil kimlik doğrulama | 1.1.0 |
|
||
| 17 | Otomatik fiyat sağlayıcıları (market ve altın/döviz) araştırması ve izinliyse entegrasyonu | 1.2.0 |
|
||
|
||
---
|
||
|
||
## 10. Faz 0'da netleştirilecek varsayılanlar
|
||
|
||
Aşağıdakileri varsayılan olarak kabul ettim. Faz 0'da yalnızca bunlardan emin olmadıklarını ve yeni çıkan belirsizlikleri sor:
|
||
- Kart hesap kesim günü **dahil** "Hesap Kesim Dönemi"ne girer.
|
||
- Taksitler bütçede her taksitin kendi ayına yazılır.
|
||
- Günlük planda sabit tarihli giderler kendi gününe, değişken bütçe günlere eşit dağıtılır.
|
||
- Stok eşiği hedef stoğun %20'si; ürün tipi bazında değiştirilebilir.
|
||
- Ek dosya sınırı: dosya başına 10 MB, kayıt başına 10 dosya.
|
||
|
||
### 10.1 Faz 0 kararları (2026-11-05, onaylandı)
|
||
- Yukarıdaki varsayılanların tümü kabul edildi.
|
||
- **Giriş:** kullanıcı adı **veya** e-posta + şifre (Better Auth `username` plugin). Kayıt yine kapalı.
|
||
- **Admin veri erişimi:** sistem admini kullanıcıları, haneleri ve üyelikleri yönetir; üyesi olmadığı hanenin finansal verisini **göremez**.
|
||
- **Bütçe ayı başlangıcı:** hane ayarı `budgetMonthStartDay` (1–28); varsayılan 1 (takvim ayı). Ay sınırı hesapları bu ayara göre yapılır.
|
||
- **Değerleme:** varlıklar ve aynî alacaklar **alış** fiyatıyla, aynî borçlar **satış** fiyatıyla değerlenir. Tek fiyat girilirse ikisine de yazılır.
|
||
- **URL'ler:** ekran yolları Türkçe ASCII (`/islemler`, `/butce`); kod, koleksiyon adları ve `/api/v1` İngilizce.
|
||
- **Canlı domain:** `butcem.ta1sph.website` (Gitea `gitea.ta1sph.info` üzerinde; fark kasıtlı).
|
||
- **Lokal MongoDB portu:** host'ta `27019` (27017 ve 27018 geliştirme makinesinde dolu). `BUTCEM_MONGO_PORT` ile değiştirilebilir.
|
||
|
||
---
|
||
|
||
## 11. Ek İstekler
|
||
|
||
<!-- Yeni isteklerimi buraya madde madde ekleyeceğim. Her maddeyi uygun faza yerleştir; gerekirse yeni faz öner ve onayımı al. -->
|
||
|
||
1. …
|
||
|
||
---
|
||
|
||
## 12. Başlangıç
|
||
|
||
Faz 0 ile başla:
|
||
1. `node -v` kontrolü (Active LTS değilse uyar).
|
||
2. `git status` ve `git remote -v` ile repo ve Gitea `origin` bağlantısını doğrula.
|
||
3. Bu promptu `docs/PROMPT.md` olarak kaydetmeyi öner.
|
||
4. Bölüm 10'daki varsayılanlar ve kalan belirsizlikler için en fazla 5 soru sor.
|
||
5. Sayfa listesi, koleksiyonlar (alanlarıyla) ve roller planını onayıma sun. |