İstanbul genelinde kaybolan eşyaların doğru sahibine güvenli teslimini sağlayan backend.
Lostify bir ilan panosu değil, bir güven & doğrulama ürünüdür. Kafe, AVM, metro, kütüphane, park, üniversite… şehrin herhangi bir yerinde bulunan bir eşyanın, "benim" diyen ilk kişiye değil, gerçekten sahibi olan kişiye ulaşmasını garanti etmeye çalışır. Tüm kurallar tek bir eksende tasarlanmıştır: yanlış kişi eşyayı alamasın.
Kayıp ilanı Bulunan eşya
│ │
└──────┬─────────────┘
▼
🔍 Eşleştirme motoru (konum + zaman + kategori + renk + metin skoru)
▼
✋ Sahiplik talebi (claim) — talep eden, eşyaya dair gizli bir ipucu girer
▼
⚖️ Adjudicator (eşyayı bulan kişi) ipucunu fiziksel eşyayla karşılaştırıp onaylar
▼
🔑 Tek kullanımlık teslim kodu + HMAC imzalı QR üretilir
▼
🤝 Güvenli buluşma noktasında kod doğrulanır → teslim tamamlanır, ilanlar kapanır
Sürecin her adımı bir güvenlik katmanından geçer:
- Telefon doğrulama (SMS OTP) — claim açarken ve teslimi onaylarken telefon doğrulaması zorunludur.
- Şifreli ipucu (
hint_text) — talep edenin girdiği ipucu AES-256-GCM ile şifrelenir; yalnızca karar verici (adjudicator) claim anında çözülmüş halini görür. API'de asla düz dönmez, loglara yazılmaz. - Kimlik maskeleme — doğrulama tamamlanana kadar tarafların adı ve iletişim bilgileri birbirine kapalıdır.
- Tek kullanımlık teslim kodu — hash'li saklanır, kısa TTL'lidir, sabit-zaman karşılaştırma ile doğrulanır; QR token HMAC imzalıdır.
- Deneme limiti + fraud tespiti — art arda reddedilen talepler eşyayı kilitler ve yüksek riskli rapor üretir; farklı eşyalarda tekrarlanan başarısız denemeler (cross-item fraud) kullanıcıyı otomatik olarak moderasyon kuyruğuna düşürür.
- Denetim izi — kritik tüm aksiyonlar append-only
audit_logstablosuna yazılır.
- 📝 Kayıp / bulunan ilanları — kategori, konum, tarih, renk, fotoğraf (S3 presigned URL ile yükleme), tam metin arama (
tsvector+pg_trgm) - 🤖 Otomatik eşleştirme motoru — yeni ilan aktif olunca BullMQ üzerinden asenkron tarama; ağırlıklı skor (konum 30, zaman 25, kategori 20, renk 10, metin 15) ve güven bantları (high / medium / low)
- 🔐 Sahiplik doğrulama (ürünün kalbi) — ipucu tabanlı claim + adjudicator kararı + durum makinesi
- 📦 Self-handoff teslim — güvenli buluşma noktası önerisi, tek kullanımlık kod / QR ile kapanış
- 🔔 Bildirimler — in-app bildirimler + Socket.IO ile gerçek zamanlı olaylar (JWT/JWKS ile doğrulanan handshake, kanal bazlı yetki)
- 🛡️ Moderasyon — raporlama, kullanıcı askıya alma / işaretleme, eşya kilidi ve kilit TTL'i
- ⚙️ Hardening — Redis tabanlı rate limiting, Idempotency-Key desteği, TTL cron'ları (ilan/teslim süresi dolumu), Swagger dokümantasyonu
| Katman | Teknoloji |
|---|---|
| Framework | NestJS + TypeScript (strict) |
| Veritabanı | PostgreSQL + Prisma (schema-first, migration) |
| Kuyruk & cache | Redis + BullMQ |
| Gerçek zamanlı | Socket.IO (JWT/JWKS handshake) |
| Kimlik | Better Auth (Prisma adapter, session/JWT + refresh rotation) |
| Dosya depolama | S3 uyumlu storage + presigned URL |
| E-posta | Resend |
| SMS / OTP | Sağlayıcı soyutlaması (Netgsm / Twilio) |
- Node.js ≥ 24, pnpm ≥ 11
- Docker (Postgres + Redis için)
# 1. Bağımlılıkları kur
pnpm install
# 2. Postgres + Redis'i ayağa kaldır
docker compose up -d
# 3. Ortam değişkenlerini hazırla
cp .env.example .env
# Şifreleme anahtarlarını üret ve .env'e yaz:
# CLAIM_HINT_ENCRYPTION_KEY / DELIVERY_CODE_ENCRYPTION_KEY → openssl rand -hex 32
# BETTER_AUTH_SECRET → openssl rand -base64 32
# 4. Veritabanını hazırla
pnpm prisma migrate dev
pnpm prisma db seed
# 5. Geliştirme sunucusunu başlat
pnpm start:devAPI artık http://localhost:3000/api/v1 altında, Swagger dokümantasyonu ise http://localhost:3000/api/docs adresinde.
Not:
RESEND_API_KEYve SMS ayarları boş bırakılabilir — geliştirme ortamında e-posta içerikleri ve OTP kodları gönderilmek yerine loglanır.
| Komut | Açıklama |
|---|---|
pnpm start:dev |
Geliştirme sunucusu (watch mode) |
pnpm build / pnpm start:prod |
Production build & çalıştırma |
pnpm test |
Birim testleri |
pnpm test:e2e |
Uçtan uca testler |
pnpm lint |
ESLint (otomatik düzeltme ile) |
pnpm prisma:migrate |
Veritabanı migration'ları |
pnpm prisma:seed |
Örnek veri (kategoriler, konumlar, kullanıcılar) |
Tüm uçlar /api/v1 öneki altındadır; liste uçları cursor pagination kullanır, hatalar { error: { code, message, details? } } formatında döner.
| Alan | Uçlar |
|---|---|
| Auth | register / login / refresh / logout, e-posta doğrulama, telefon OTP |
| Items | ilan CRUD, arama & filtreleme, fotoğraf yükleme (presigned), kapatma |
| Matches | eşleşme listesi & detayı, dismiss |
| Claims | sahiplik talebi, onay / red (adjudication) |
| Deliveries | teslim kodu & QR, doğrulama, zaman çizelgesi |
| Notifications | liste, okundu işaretleme, okunmamış sayısı |
| Reports & Users | raporlama, moderasyon, kullanıcı durumu |
Uçların tam sözleşmesi için çalışan sunucudaki Swagger arayüzüne bakın.
src/
├── auth/ # Better Auth entegrasyonu, guard'lar (RBAC, ownership, phone)
├── items/ # Kayıp/bulunan ilanları
├── matching/ # Eşleştirme motoru (BullMQ match.scan, skorlama)
├── matches/ # Eşleşme HTTP yüzeyi (list / detail / dismiss)
├── claims/ # Sahiplik talebi + adjudication + hint şifreleme
├── deliveries/ # Teslim kodu, QR, doğrulama, buluşma noktası
├── notifications/ # In-app bildirim + Socket.IO gateway
├── reports/ # Raporlama & moderasyon
├── users/ # Kullanıcı durumu (suspend / flag)
├── uploads/ # S3 presigned URL
├── sms/ mail/ # OTP ve e-posta sağlayıcı soyutlamaları
├── audit/ # Append-only denetim kaydı
├── maintenance/ # TTL cron'ları (item.expire, delivery.expire)
└── settings/ # Çalışma zamanı ayarları (eşikler, limitler)
docs/
├── SPEC.md # Teknik şartname
├── DECISIONS.md # Mimari & ürün kararları (tek doğruluk kaynağı)
└── BACKLOG.md # Ticket listesi
- Güven > kolaylık. Her kritik geçiş (claim, onay, teslim) bir doğrulama kapısından geçer.
- Durum makineleri. İlan, talep ve teslim yaşam döngüleri açıkça tanımlı geçişlerle yönetilir; geçersiz geçişler
409döner. - Asenkron işler kuyruğa. Eşleştirme taraması ve süre dolumu işleri BullMQ'da; senkron HTTP'de uzun iş yapılmaz.
- En az bilgi sızıntısı. Var olmayan/yetkisiz kaynaklar ayrım yapılmadan
404döner; kimlikler doğrulamaya kadar maskelidir. - Kararlar belgelenir. Mimari ve ürün kararlarının gerekçeleri docs/DECISIONS.md içinde tutulur.
UNLICENSED — özel proje.