ulufe projesinin ai tarafında oluşturulan değişiklik günlüğü kayıtları.
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.
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.
Fatura totalleri her işlemde otomatik hesaplanıyor:
(subtotal × taxRate) / 100subtotal + taxAmountTüm parasal değerler, hassasiyet hatalarını önlemek için Math.round(value * 100) / 100 ile yuvarlanıyor.
React Email kullanılarak modern, responsive fatura e-posta şablonu oluşturuldu:
POST /invoices/:id/send endpoint’i ile:
Geliştirme ortamında e-posta göndermek yerine konsola loglama yapılıyor.
Fatura gönderimi için contacts tablosuna email alanı eklendi:
Yeni fatura oluşturur. Müşteri sahipliği doğrulanır, kalem tutarları hesaplanır ve totaller otomatik oluşturulur.
Validasyon:
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 filtrelestatus - Duruma göre filtrele (draft, sent, paid, cancelled)Response:
{
"data": [...],
"meta": {
"total": 42,
"page": 1,
"limit": 50,
"totalPages": 1
}
}
Belirtilen ID’ye sahip faturayı döner. Sahiplik doğrulaması yapılır.
Mevcut faturayı günceller. Kalemler veya KDV oranı değiştirildiğinde totaller otomatik yeniden hesaplanır.
Özel davranışlar:
Faturayı siler. Sahiplik doğrulaması yapılır.
E-posta ile fatura gönderir ve durumu “sent” yapar.
İşlem sırası:
Validasyon:
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:
ALTER TABLE contact ADD COLUMN email TEXT;
Tüm endpoint’ler için multi-tenancy kuralları:
userId ile filtreleniyoruserId atamasıZod şemaları ile katı validasyon:
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" }
)
Üç katmanlı mimari korundu:
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[];
}
// Zod ile runtime validation
export const SchemaRequestCreateInvoice = z.object({...});
export type RequestCreateInvoice = z.infer<typeof SchemaRequestCreateInvoice>;
// Drizzle ORM ile DB tipleri
export const invoice = pgTable("invoice", {...});
Fatura totallerini hesaplar:
const { subtotal, taxAmount, total } = calculateInvoiceTotals(
lineItems,
taxRate
);
Tüm değerler 2 ondalık basamağa yuvarlanır.
Kalem tutarlarını yeniden hesaplar:
const validatedItems = validateLineItems(lineItems);
// Her kalem için: amount = Math.round(quantity * rate * 100) / 100
payloads/invoices/ klasöründe 7 test dosyası:
Her dosya detaylı dokümantasyon ve örnek payload içeriyor.
Kullanıcı dostu Türkçe hatalar:
"Fatura bulunamadı" - 404"Kişi bulunamadı" - 404"Kişinin e-posta adresi bulunamadı" - 400packages/models/src/invoice.ts - Invoice ve InvoiceStatuspackages/models/src/line-item.ts - LineItem interfacepackages/models/src/contact.ts - email alanı eklendipackages/schema/src/invoice/line-item.tspackages/schema/src/invoice/request.create.tspackages/schema/src/invoice/request.update.tspackages/schema/src/invoice/request.list.tspackages/schema/src/invoice/request.send.tspackages/schema/src/contact/request.create.ts - email validasyonupackages/schema/src/contact/request.update.ts - email validasyonuapps/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 eklendiapps/api/emails/invoice.tsx - React Email şablonu (YENİ)apps/api/src/index.ts - Invoice routes mount edildiapps/api/src/db/schema.ts - invoice tablosu + contact email alanıpayloads/invoices/folder.brupayloads/invoices/Create Invoice.brupayloads/invoices/List Invoices.brupayloads/invoices/Get Invoice.brupayloads/invoices/Update Invoice.brupayloads/invoices/Delete Invoice.brupayloads/invoices/Send Invoice.bruFatura sistemi production-ready durumda. Gelecek geliştirmeler için fikirler:
İlk Sürüm: 1 Ocak 2026 Durum: ✅ Tamamlandı