ulufe projesinin ai tarafında oluşturulan değişiklik günlüğü kayıtları.
Tam özellikli bir müşteri (contacts) yönetim sistemi geliştirildi. Sistem, veritabanı şeması, API endpoint’leri, validasyon, tip güvenliği ve geliştirici araçlarını içeriyor.
Tip ve şemaların nerede yaşayacağına dair bilinçli kararlar alındı:
@ulufe/models - İstemci tarafı TypeScript interface’leri (sıfır bağımlılık)@ulufe/schema - Zod validasyon şemaları (istek/yanıt doğrulama)apps/api/src/db/schema.ts - Drizzle ORM şemaları (minimal tip export’u)Neden bu yaklaşım?
Müşteri yönetimi için 5 RESTful endpoint oluşturuldu. Tüm endpoint’ler kimlik doğrulama gerektiriyor ve kullanıcılar sadece kendi müşterilerine erişebiliyor. Oluşturma, listeleme (sayfalı), tekil getirme, güncelleme ve silme işlemleri destekleniyor. Güvenlik için sahiplik doğrulaması yapılıyor ve bilgi sızıntısını önlemek amacıyla yetkisiz erişimlerde 404 hatası dönülüyor.
Yeniden kullanılabilir sayfalama yardımcı fonksiyonu oluşturuldu:
Kullanım:
const contacts = await withPagination(
query.$dynamic(),
desc(contact.createdAt), // En yeniler önce
page,
limit
);
Özellikler:
@hono/standard-validator entegre edildi:
Öncesi:
const body = await c.req.json();
const validation = schema.safeParse(body);
if (!validation.success) {
return c.json({ error: "Doğrulama başarısız" }, 400);
}
Sonrası:
sValidator("json", SchemaRequestCreateContact),
async (c) => {
const data = c.req.valid("json"); // Zaten doğrulanmış!
}
Test için eksiksiz bir Bruno koleksiyonu oluşturuldu:
Kullanım:
.bruno klasörünü koleksiyon olarak aç@ulufe/models - İstemci tarafı tip tanımları (Contact, User)@ulufe/schema - Validasyon şemaları (create, update, list)apps/api/src/routes/contacts.ts - CRUD route handler’larıapps/api/src/helpers/pagination.ts - Sayfalama yardımcı fonksiyonuapps/api/src/db/schema.ts - Contact tablosu eklendi.bruno/ - Tam Bruno API koleksiyonu (6 endpoint)Toplam: 18 dosya oluşturuldu, 3 dosya değiştirildi
URL query parametreleri her zaman string’dir. z.coerce.boolean() ve z.coerce.number() kullanarak otomatik tip dönüşümü sağlandı.
Sayfa tabanlı yaklaşımı seçildi çünkü:
/contacts?page=2&limit=50Üç katmanlı tip sistemi:
Bu yaklaşım bağlantıyı önler ve her katmanın bağımsız gelişmesine izin verir.
Her sorgu kullanıcı kapsamı içerir:
// Yanlış: Tüm müşterileri döndürür
const contacts = await db.select().from(contact);
// Doğru: Sadece kullanıcının müşterileri
const contacts = await db
.select()
.from(contact)
.where(eq(contact.userId, user.id));
Mevcut şema şu indekslere sahip:
id (primary key - otomatik)userId (foreign key - otomatik)Gelecek optimizasyon: Yaygın sorgular için kompozit indeks düşünülebilir.
LIMIT ve OFFSET kullanımı büyük veri setleri için yavaş olabilir.
Gelecek optimizasyon: Cursor tabanlı sayfalama
Sayfalama metadata için ayrı count sorgusu çalıştırılıyor.
Gelecek optimizasyon: