değişiklikler

ulufe projesinin ai tarafında oluşturulan değişiklik günlüğü kayıtları.

Tüm güncellemeler
Fatura Yönetim Sistemi
1 Ocak 2026 %16
Bu değişiklik günlüğü Claude tarafından oluşturuldu.

Kapsamlı bir fatura yönetim sistemi geliştirildi. Sistem, fatura oluşturma, düzenleme, e-posta ile gönderme, otomatik hesaplama ve kişi entegrasyonu özelliklerini içeriyor.

Tamamlanan işler

  • Tam CRUD operasyonları - Fatura oluşturma, listeleme, güncelleme ve silme endpoint’leri
  • E-posta entegrasyonu - React Email ile profesyonel fatura e-postaları gönderme
  • Otomatik hesaplama - Ara toplam, KDV ve toplam tutarların otomatik hesaplanması
  • Satır kalemleri (Line Items) - JSON tabanlı denormalize kalem yönetimi
  • Durum takibi - Taslak, gönderildi, ödendi ve iptal durumları
  • Kişi entegrasyonu - Müşteri bilgileri ile entegre fatura sistemi
  • Çok kiracılı güvenlik - Kullanıcıya özel veri izolasyonu
  • Bruno API testleri - 7 endpoint için hazır test senaryoları

Fatura özellikleri

Temel alanlar

  • contactId - Faturanın gönderildiği müşteri referansı
  • referenceNumber - Fatura numarası (INV-2025-001 gibi)
  • date - Fatura tarihi
  • dueDate - Son ödeme tarihi
  • currency - Para birimi (TRY, USD, EUR vb.)
  • status - Durum (taslak, gönderildi, ödendi, iptal)

Satır kalemleri (Line Items)

Her fatura birden fazla kalem içerebilir:

{
  description: "Web Tasarım Hizmeti",
  quantity: 1,
  rate: 15000,
  amount: 15000
}

Sistem, kalem tutarlarının quantity × rate = amount formülüne uygunluğunu otomatik doğruluyor.

Otomatik hesaplamalar

Fatura totalleri her işlemde otomatik hesaplanıyor:

  • Ara toplam (subtotal): Tüm kalem tutarlarının toplamı
  • KDV tutarı (taxAmount): (subtotal × taxRate) / 100
  • Genel toplam (total): subtotal + taxAmount

Tüm parasal değerler, hassasiyet hatalarını önlemek için Math.round(value * 100) / 100 ile yuvarlanıyor.

Opsiyonel alanlar

  • notes - Markdown destekli notlar (max 5000 karakter)
  • taxRate - KDV oranı (0-100, varsayılan: 0)
  • paymentTerms - Ödeme koşulları (banka bilgileri vb.)

E-posta sistemi

Profesyonel şablonlar

React Email kullanılarak modern, responsive fatura e-posta şablonu oluşturuldu:

  • Türkçe başlıklar ve içerik
  • Detaylı fatura bilgileri tablosu
  • Kalemler listesi (açıklama, miktar, birim fiyat, tutar)
  • Ara toplam, KDV ve genel toplam gösterimi
  • Notlar ve ödeme koşulları bölümleri
  • Özel mesaj desteği

Gönderim süreci

POST /invoices/:id/send endpoint’i ile:

  1. Fatura ID’si doğrulanıyor
  2. Müşteri bilgileri kontrol ediliyor
  3. E-posta adresi varlığı doğrulanıyor
  4. Fatura e-postası gönderiliyor
  5. Durum otomatik olarak “sent” (gönderildi) yapılıyor

Geliştirme ortamında e-posta göndermek yerine konsola loglama yapılıyor.

Kişi (Contact) güncellemeleri

Fatura gönderimi için contacts tablosuna email alanı eklendi:

  • Opsiyonel alan (null olabilir)
  • E-posta formatı validasyonu
  • Tüm contact CRUD işlemlerinde destekleniyor

API Endpoint’leri

1. POST /invoices - Fatura oluştur

Yeni fatura oluşturur. Müşteri sahipliği doğrulanır, kalem tutarları hesaplanır ve totaller otomatik oluşturulur.

Validasyon:

  • contactId zorunlu ve kullanıcıya ait olmalı
  • dueDate >= date olmalı
  • En az 1 kalem gerekli
  • Her kalemin amount değeri quantity × rate olmalı (±0.01 tolerans)

2. GET /invoices - Fatura listele

Sayfalı fatura listesi döner. Müşteri ID ve duruma göre filtreleme destekleniyor.

Query parametreleri:

  • page - Sayfa numarası (varsayılan: 1)
  • limit - Sayfa başına kayıt (varsayılan: 50, max: 100)
  • contactId - Müşteriye göre filtrele
  • status - Duruma göre filtrele (draft, sent, paid, cancelled)

Response:

{
  "data": [...],
  "meta": {
    "total": 42,
    "page": 1,
    "limit": 50,
    "totalPages": 1
  }
}

3. GET /invoices/:id - Tekil fatura getir

Belirtilen ID’ye sahip faturayı döner. Sahiplik doğrulaması yapılır.

4. PATCH /invoices/:id - Fatura güncelle

Mevcut faturayı günceller. Kalemler veya KDV oranı değiştirildiğinde totaller otomatik yeniden hesaplanır.

Özel davranışlar:

  • contactId değiştirilirse yeni müşteri sahipliği doğrulanır
  • lineItems veya taxRate güncellenirse tüm totaller yeniden hesaplanır
  • updatedAt otomatik güncellenir

5. DELETE /invoices/:id - Fatura sil

Faturayı siler. Sahiplik doğrulaması yapılır.

6. POST /invoices/:id/send - Fatura gönder

E-posta ile fatura gönderir ve durumu “sent” yapar.

İşlem sırası:

  1. Fatura sahipliği doğrula
  2. Müşteri bilgilerini getir
  3. E-posta adresini kontrol et
  4. E-posta gönder (production’da Resend, dev’de log)
  5. Durumu “sent” yap

Validasyon:

  • Müşterinin e-posta adresi olmalı (yoksa 400 hatası)
  • Opsiyonel custom message (max 1000 karakter)

Veritabanı şeması

invoice tablosu

CREATE TABLE invoice (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL REFERENCES user(id) ON DELETE CASCADE,
  contact_id TEXT NOT NULL REFERENCES contact(id) ON DELETE RESTRICT,
  reference_number TEXT NOT NULL,
  date TIMESTAMP WITH TIME ZONE NOT NULL,
  due_date TIMESTAMP WITH TIME ZONE NOT NULL,
  notes TEXT,
  tax_rate NUMERIC(5, 2) NOT NULL DEFAULT 0,
  status TEXT NOT NULL DEFAULT 'draft',
  currency TEXT NOT NULL,
  payment_terms TEXT,
  line_items JSONB NOT NULL,
  subtotal NUMERIC(12, 2) NOT NULL,
  tax_amount NUMERIC(12, 2) NOT NULL,
  total NUMERIC(12, 2) NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

Önemli kararlar:

  • JSONB for line_items - Denormalize edilmiş yapı, performans ve basitlik için
  • NUMERIC for money - Floating-point hassasiyet hatalarını önlemek için
  • ON DELETE RESTRICT for contact_id - Faturası olan müşterilerin silinmesini engeller
  • ON DELETE CASCADE for user_id - Kullanıcı silindiğinde faturaları da sil

contact tablosuna eklenen alan

ALTER TABLE contact ADD COLUMN email TEXT;

Güvenlik

Tüm endpoint’ler için multi-tenancy kuralları:

  • ✅ Tüm sorgular userId ile filtreleniyor
  • ✅ Oluşturma işlemlerinde otomatik userId ataması
  • ✅ Güncelleme/silme öncesi sahiplik doğrulaması
  • ✅ Yetkisiz erişimlerde 404 döndürülüyor (403 değil, bilgi sızıntısını önlemek için)
  • ✅ contactId değişikliklerinde yeni müşteri sahipliği kontrol ediliyor

Validasyon

Zod şemaları ile katı validasyon:

LineItem şeması

z.object({
  description: z.string().min(1).max(500),
  quantity: z.number().positive(),
  rate: z.number().nonnegative(),
  amount: z.number().nonnegative(),
}).refine(
  (data) => Math.abs(data.amount - data.quantity * data.rate) < 0.01,
  { message: "Amount must equal quantity * rate" }
)

Create Invoice şeması

  • Tüm zorunlu alanlar kontrol ediliyor
  • dueDate >= date doğrulaması
  • En az 1 kalem zorunlu
  • taxRate 0-100 arası
  • Enum değerleri (InvoiceStatus) tip güvenli

Update Invoice şeması

  • Tüm alanlar opsiyonel
  • Tarih doğrulaması yalnızca her iki tarih de verilirse
  • Partial update desteği

Type System

Üç katmanlı mimari korundu:

1. @ulufe/models paketi

export enum InvoiceStatus {
  DRAFT = "draft",
  SENT = "sent",
  PAID = "paid",
  CANCELLED = "cancelled",
}

export interface LineItem {
  description: string;
  quantity: number;
  rate: number;
  amount: number;
}

export interface Invoice {
  id: string;
  userId: string;
  contactId: string;
  // ... tüm alanlar
  lineItems: LineItem[];
}

2. @ulufe/schema paketi

// Zod ile runtime validation
export const SchemaRequestCreateInvoice = z.object({...});
export type RequestCreateInvoice = z.infer<typeof SchemaRequestCreateInvoice>;

3. Database şeması

// Drizzle ORM ile DB tipleri
export const invoice = pgTable("invoice", {...});

Helper fonksiyonlar

calculateInvoiceTotals()

Fatura totallerini hesaplar:

const { subtotal, taxAmount, total } = calculateInvoiceTotals(
  lineItems,
  taxRate
);

Tüm değerler 2 ondalık basamağa yuvarlanır.

validateLineItems()

Kalem tutarlarını yeniden hesaplar:

const validatedItems = validateLineItems(lineItems);
// Her kalem için: amount = Math.round(quantity * rate * 100) / 100

Bruno API testleri

payloads/invoices/ klasöründe 7 test dosyası:

  1. folder.bru - Klasör konfigürasyonu
  2. Create Invoice.bru - Örnek kalemlerle fatura oluşturma
  3. List Invoices.bru - Filtreleme ve sayfalama testleri
  4. Get Invoice.bru - Tekil fatura getirme
  5. Update Invoice.bru - Durum ve not güncelleme
  6. Delete Invoice.bru - Fatura silme
  7. Send Invoice.bru - E-posta gönderme ve custom mesaj

Her dosya detaylı dokümantasyon ve örnek payload içeriyor.

Türkçe hata mesajları

Kullanıcı dostu Türkçe hatalar:

  • "Fatura bulunamadı" - 404
  • "Kişi bulunamadı" - 404
  • "Kişinin e-posta adresi bulunamadı" - 400

Oluşturulan/değiştirilen dosyalar

Yeni model tipleri

  • packages/models/src/invoice.ts - Invoice ve InvoiceStatus
  • packages/models/src/line-item.ts - LineItem interface

Güncellenmiş modeller

  • packages/models/src/contact.ts - email alanı eklendi

Yeni validation şemaları

  • packages/schema/src/invoice/line-item.ts
  • packages/schema/src/invoice/request.create.ts
  • packages/schema/src/invoice/request.update.ts
  • packages/schema/src/invoice/request.list.ts
  • packages/schema/src/invoice/request.send.ts

Güncellenmiş şemalar

  • packages/schema/src/contact/request.create.ts - email validasyonu
  • packages/schema/src/contact/request.update.ts - email validasyonu

API dosyaları

  • apps/api/src/routes/invoices.ts - 6 endpoint (YENİ)
  • apps/api/src/helpers/invoice-calculations.ts - Hesaplama fonksiyonları (YENİ)
  • apps/api/src/services/email.ts - sendInvoiceEmail eklendi
  • apps/api/emails/invoice.tsx - React Email şablonu (YENİ)
  • apps/api/src/index.ts - Invoice routes mount edildi

Database

  • apps/api/src/db/schema.ts - invoice tablosu + contact email alanı

Bruno testleri

  • payloads/invoices/folder.bru
  • payloads/invoices/Create Invoice.bru
  • payloads/invoices/List Invoices.bru
  • payloads/invoices/Get Invoice.bru
  • payloads/invoices/Update Invoice.bru
  • payloads/invoices/Delete Invoice.bru
  • payloads/invoices/Send Invoice.bru

Sonraki adımlar

Fatura sistemi production-ready durumda. Gelecek geliştirmeler için fikirler:

  • PDF export özelliği
  • Tekrarlayan faturalar (recurring invoices)
  • Ödeme entegrasyonu (Stripe, PayPal)
  • Fatura şablonları (customizable templates)
  • Multi-currency desteği
  • Dashboard istatistikleri (gelir, bekleyen ödemeler)
  • İndırım ve kupon kodu desteği

İlk Sürüm: 1 Ocak 2026 Durum: ✅ Tamamlandı

Ana sayfaya dön