feat(ekstre): banka/kart ekstresi içe aktarma altyapısı (arşiv dönemleri, iade, öğrenen kurallar)

- Arşiv dönemi durumu: geçmiş aylar için; kapatılmaz, devir zincirinde atlanır, bütçe önerilerini besler
- POST /bank-import/preview ve /commit: harcama / iade (eksi) / gelir (plan) / yoksay
- Tekrar tespiti (import_key), açıklamadan öğrenen kategori kuralları, ödeme/virman ipuçları
- Kapalı dönem ve gelecek tarih satır hatası; iade düzenlemede eksi kalır

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-13 08:33:07 +03:00
parent 4d764689e2
commit d1a24afc3c
28 changed files with 1422 additions and 13 deletions
+11 -1
View File
@@ -81,7 +81,7 @@ Renkler ve ikonlar frontend tasarım token'larında.
```js
{ _id, household_id, name /* "Aralık 2026" */,
start_date: "2026-12-01", end_date: "2027-01-01", // bitiş HARİÇ
status: "open" | "closed" | "correcting",
status: "open" | "closed" | "correcting" | "archived",
savings_goal: 500000, // kuruş — birikim hedefi
reflection_md: "...", // "Nasıl daha iyi yapabilirim?"
to_savings: 450000, // kapanışta birikime aktarılan (Faz 8'de varlık hareketi)
@@ -93,6 +93,7 @@ Renkler ve ikonlar frontend tasarım token'larında.
- Hanede en fazla **bir** `open` dönem (servis kontrolü + kısmi benzersiz indeks).
- **Yeniden açma (karar 2026-11-12, "düzeltme modu"):** sahip kapalı dönemi açınca durum `correcting` olur; yazılabilir ama "açık dönem" sayılmaz → yeni dönem açık kalabilir (tek `open` kuralı korunur). Mevcut devir "yeniden kapat"a kadar yerinde kalır; yeniden kapatınca eskisi soft delete, yenisi hesaplanır. Ardından kapanmış dönem varsa açılamaz (zincirleme devirler bozulmasın).
- **Haftalar saklanmaz.** `start_date`/`end_date`'ten hesaplanır (Pazartesi başlangıçlı; ilk/son kısmi haftalar ayrı).
- **Arşiv (`archived`, karar 2026-11-13):** ekstre içe aktarımında dönemi olmayan aylar için takvim ayı kadar açılır (var olan dönemlerle çakışmayacak şekilde kırpılır). Yazılabilir (kayıt düzeltme), ama kapatılmaz, devir üretmez; devir zincirinde (yeni dönemin önceki dönemi, kapatmada sonraki dönem, yeniden açma engeli) **atlanır**. Bütçe önerileri ("önceki dönem", "son 3 ay") kapalı **ve** arşiv dönemleri kullanır.
### 3.5 `categories` — Alt kategoriler
```js
@@ -137,6 +138,15 @@ Renkler ve ikonlar frontend tasarım token'larında.
description: "Haftalık market",
created_by /* user_id */, created_at, ... }
```
- **İade** (ekstreden, karar 2026-11-13): aynı kategoride **eksi** `amount`; toplamlar net olur. Elle girişte tutar > 0; iade düzenlemede eksi kalır.
- `import_key` (isteğe bağlı): ekstreden gelen kayıtta `tarih|yön|tutar|sadeleştirilmiş açıklama` → aynı satır ikinci kez aktarılmaz (plan kalemlerinde de, gelir için).
### 3.9a `import_rules` — Ekstre öğrenilmiş kuralları
```js
{ _id, household_id, pattern /* açıklamanın ilk 2 anlamlı kelimesi, ASCII küçük: "migros istanbul" */,
kind: "expense" | "refund" | "income" | "ignore", category_id, uses, created_at, updated_at, version }
```
- Aktarmada her seçim kural olarak yazılır (upsert); sonraki ekstrede aynı `pattern` öneri olur.
### 3.10 `carryovers` — Devirler
```js