Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Satış alanı detayı

Vitrin, müşteri mesajlaşması ve destek yetkilisi

Alan haritası'ndaki Satış alanı (catalog, basket, purchase, buyer, buyer-group, post, price-analytics) self-servis vitrini kapsıyor. Bu sayfa ek bir boyutu detaylandırıyor: müşteri ile satışa dair mesajlaşma — bugün message modülünde yaşıyor ama Satış'a ait mantığı barındırıyor.

Mesajlaşma mimarisi: context registry

message modülü tek başına hangi domain'e ait olduğunu bilmiyor — bunun yerine bir resolver registry kullanıyor: her domain, kendi ConversationContextType değeri için ConversationContextRegistry'ye bir resolver kaydediyor (onModuleInit ile). Bir konuşma başlatıldığında message modülü ilgili resolver'ı çağırıp yetkilendirme + katılımcı listesini alıyor, kendi modülünü domain'e import etmeden. Bu, döngüsel bağımlılığı önleyen iyi bir tasarım — Alan haritası'ndaki yoğun forwardRef sorununun tam tersi bir çözüm.

ConversationContextType kapsamı

TürResolver var mı?Durum
RETURNVar — order/services/return-conversation.resolver.tsİade talebiyle ilgili konuşma; BuyerOrderReturn.conversationId'ye geri yazıyor.
PRODUCTVar — catalog/services/product-conversation.resolver.tsAlıcı başına tek, kalıcı "Ürün Talepleri" konuşması; destek yetkilisine yönleniyor.
SUPPORTYok — registry'den değil, message.service.ts içinde doğrudan (hardcoded) işleniyorGenel destek hattı, herhangi bir domain'e bağlı değil.
TEAMYok — aynı şekilde message.service.ts içinde özel durumİç ekip sohbeti, muhtemelen customer-facing değil.
ORDERYok — hiçbir yerdeEnum'da tanımlı ama kodun hiçbir yerinde kullanılmıyor. Ölü değer.

Eksiklikler

  • ORDER context'i tamamen ölü. Bir alıcının belirli bir siparişi hakkında mesajlaşabileceği bir yol yok — sadece genel SUPPORT hattı var. Sipariş bazlı mesajlaşma (ör. "bu ürün eksik geldi", "teslimat ne zaman") bugün ya SUPPORT'a düşüyor ya da hiç yapılamıyor.
  • ProductRequest (katalog: "bu ürünü ekleyin" talebi) ile PRODUCT konuşması aynı isimde ama farklı iki şey, sadece servis çağrısı seviyesinde bağlı: product-request-buyer.service.ts, talep oluşunca PRODUCT konuşmasına bir sistem mesajı yazıyor (getOrCreateProductConversation + createSystemMessage) — ama ProductRequest şemasında conversationId gibi kalıcı bir alan yok. Konuşmayı bulmak için her seferinde alıcı id'siyle yeniden çözümleniyor.
  • Conversation.contextId bilinçli olarak string (registry deseni döngüsel bağımlılığı önlemek için böyle tasarlanmış) — ama bu da Sipariş taraf ilişkileri'ndeki Invoice/Financial'daki gevşek referans sorununun bir başka örneği. Farkı: burada en azından tek bir tutarlı desen (registry + resolver) var; Invoice ve Financial'da öyle bir desen bile yok, her biri kendi başına gevşek.
  • basket, purchase, post, price-analytics, buyer-group mesajlaşmayla hiç temas etmiyor. Sepette takılı kalan bir alıcıya proaktif mesaj, checkout sırasında soru sorma gibi bir akış bugün yok.

Çalışan (destek yetkilisi) tarafı

Buraya kadarki bölüm alıcının gördüğü tarafı anlatıyor. Konuşmayı gerçekten yürüten destek yetkilisi (officer/admin) tarafında da somut boşluklar var:

  • Atama bir kuyruk değil, kura. getSupportOfficersForBuyer: alıcının AdminBuyerOfficer üzerinden atanmış bir yetkilisi varsa o kullanılıyor; yoksa Math.random() ile pazarlama yetkilileri arasından rastgele bir kişi seçiliyor. Yük dengeleme, müsaitlik/online durumu, uzmanlık bazlı yönlendirme yok.
  • "Join" bir "claim" değil. POST conversation/:id/join herhangi bir officer/admin'in herhangi bir (private olmayan) konuşmaya katılmasına izin veriyor — sahiplenme/kilitleme yok. Birden fazla yetkili aynı konuşmaya girebilir, ya da hiçbiri girmeyebilir; zorlayıcı bir mekanizma yok.
  • Kuyruk/iş yükü görünürlüğü yok. GET conversations, notParticipant: true ile "içinde olmadığım konuşmaları" listeleyebiliyor, ama bir durum alanı (ör. "atanmadı", "işleniyor", "çözüldü") yok — sıralama sadece updatedAt. Yetkili, neyin dikkat beklediğini listeye bakıp gözle ayırt etmek zorunda.
  • Company/warehouse kapsaması yok. Officer/admin, platform genelindeki her private-olmayan konuşmayı görüp katılabiliyor — Şirket, depo, sipariş hiyerarşisi'nde planlanan çalışma izniyle hiç bağlantısı yok. Bugün B deposunda çalışan bir yetkili, A deposunun bir alıcısının SUPPORT konuşmasını da görüp katılabilir.
  • SLA/performans ölçümü yok. İlk yanıt süresi, çözüm süresi, yetkili başına açık konuşma sayısı gibi hiçbir metrik tutulmuyor (AdminBuyerFeedbackHistory alıcı ilişkisinin genel sağlığını tutuyor, ama mesajlaşmaya özgü değil).

Sınıflandırma gerilimi

message modülünün kendisi (Conversation/Message CRUD, registry, AI auto-reply) gerçekten ortak/çekirdek altyapı — Alan haritası'ndaki sınıflandırma doğru. Ama PRODUCT ve (kurulacaksa) ORDER resolver'ları satış mantığı — bunlar zaten catalog ve order modüllerinde yaşıyor (resolver dosyaları oradan registry'ye kayıt oluyor), message'ın kendisinde değil. Yani bu zaten doğru yerde: Satış'a ait mesajlaşma mantığı, Satış modüllerinin içinde; sadece ortak taşıyıcı altyapı (message) paylaşılıyor. admin/report gibi başka bir "hem ortak hem domain'e özel" gerilimi değil — burada zaten çözülmüş bir desen var.

Öneri

  • ORDER context'i için bir resolver eklenmeli (muhtemelen order modülünde, return-conversation.resolver.ts'e paralel) — ya da enum'dan tamamen kaldırılıp SUPPORT'a devredilmeli. İkisinden biri: ölü kod olarak kalmamalı.
  • ProductRequest'e conversationId alanı eklenmeli — bugünkü dolaylı (buyer id'sinden yeniden çözme) yaklaşım yerine doğrudan referans.
  • Konuşmaya bir atanan yetkili (assignedOfficerId) ve bir durum (ör. UNASSIGNED / IN_PROGRESS / RESOLVED) alanı eklenmeli — "join" kuralı bu ikisinin yerini tutmuyor.
  • Konuşma görünürlüğü, çalışma izni (Company/Warehouse kapsamı) devreye girince ona göre daraltılmalı.

Sıradaki adım

Bu bulgular hedef modül şeması planlanırken Alan haritası'ndaki Satış tablosuyla ve Sipariş taraf ilişkileri'ndeki gevşek referans temasıyla birlikte ele alınacak.