Files
lab/belgeler/spec.md
T
kovakmedya cb150f7a24 init: lab project bootstrapped from isletmem-kovakcrm
- CRM domain modules removed (customers, services, software, calendar, tasks, invoices, leads, finance, etc.)
- DLS branding: package name=lab, logo wordmark, sidebar nav, header CTA
- Tenant layer extended with kind dimension (lab|clinic) + requireTenantKind helper
- Schema rewritten for DLS domain: jobs, job_files, job_status_history, prosthetics, connections, finance_entries, notifications
- Onboarding form: clinic/lab account-type selection + auto-generated memberNumber
- Placeholder routes for jobs/{inbound,outbound,new}, products, finance, connections
- PDF spec + spec.md under belgeler/
- db: lab database + 13 collections + indexes + storage bucket (job-files) provisioned via Appwrite MCP

Ref: belgeler/dls-ui-tasarim.pdf
2026-05-21 18:28:38 +03:00

7.7 KiB
Raw Blame History

DLS — Ürün Tasarım Spec'i

Bu dosya dls-ui-tasarim.pdf (orijinal Figma export) baz alınarak hazırlanmış geliştirilmiş ürün spec'idir. PDF UI mock'ları içerir; bu doküman akış, veri modeli, rol ayrımı ve karar gerektiren noktaları somutlaştırır.

Sistem özeti

DLS, diş klinikleri ile diş laboratuvarları arasındaki iş alışverişini dijitalleştirir:

  • Klinik bir hasta için protez işi açar (tür, üye sayısı, renk, ölçü taraması, görseller).
  • İşi bağlı bir laboratuvara yollar.
  • Laboratuvar gelen kutusundan görür, durum adımlarını işler (Ölçü → Alt Yapı → Üst Yapı → Cila/Bitim).
  • Tamamlandığında klinik gönderim aşamasına geçer.
  • Her iki taraf finansal akışı (ödenmiş/bekleyen) kendi tarafında izler.

Roller

Tek bir hesap modeli, iki tenant türü (kind):

kind İlgili eylemler
clinic İş yayınla, kendi gönderdiklerini takip et, lab bağlantısı talep et, ödeme yap
lab Ürün katalog yönet, gelen işleri al/onayla, durum güncelle, fatura kes

requireTenantKind(ctx, ['lab' \| 'clinic']) server-side route guard — sayfa render edilmeden önce yetki sorgular.

Sayfa haritası (PDF'e göre)

URL PDF sayfa İçerik
/dashboard 1 Anasayfa — özet kartlar (açık işler, işlem bekleyen, bildirimler, istatistik chart)
/jobs/inbound 2 Gelen İşler tablosu (Klinik / Hasta Kodu / Üye / Renk / Tür / Açıklama / İşlem)
/jobs/[id] 3 İş detay — bilgiler + durum stepper (Ölçü / Alt Yapı Prova / Üst Yapı Prova / Cila/Bitim) + Görselleri Görüntüle / Taranan Dosyalar / Kaydet
/jobs/outbound 4 Giden İşler tablosu (aynı sütunlar)
/jobs/new (header CTA) "Yeni İş Yayınla" formu — klinik tarafı
/products 5 Eklenen Ürünler (sadece lab) — Protez Türü / Fiyat tablo + ekleme formu
/finance 6 Finans (Bekliyor) — tahsilat/ödeme listesi
/connections 7 Bağlantı Kur — kendi bağlantı kodun + bekleyen talepler + onaylı bağlantılar
/settings/* 8 Ayarlar (workspace, üye, hesap, görünüm)
/sign-in, /sign-up 9 Giriş/kayıt — PDF "Labaratuvar Giriş" + "Klinik Giriş" iki ayrı form gösteriyor; biz tek form + onboarding'de kind seçimi yapıyoruz

PDF'teki "Üye Numarası" alanı login'de kullanılmıyor. Üye numarası tenant_settings.memberNumber olarak sistem tarafından üretiliyor ve bağlantı kodu olarak işlev görüyor (PDF'teki "Bağlantı Kodu" panelinin de aynısı).

Veri modeli (lib/appwrite/schema.ts)

Tüm collection'lar tenant_settings.tenantId = Appwrite Team.$id.

tenant_settings

  • tenantId (unique, indexed)
  • kind: 'lab' | 'clinic'
  • memberNumber: string (6 hane, unique, indexed) — bağlantı kodu
  • companyName, companyTaxId, companyAddress, companyEmail, companyPhone, logo
  • defaultCurrency (varsayılan TRY)

profiles

Kullanıcı başına ek bilgi (display name, telefon, ünvan). Auth identity Appwrite Auth'tadır; ek alanlar burada.

connections

İki tenant arası bağlantı.

  • clinicTenantId, labTenantId
  • status: 'pending' | 'approved' | 'rejected'
  • requestedBy, requestedAt, approvedAt?, rejectedAt?
  • Permission: Role.team(clinicTenantId) + Role.team(labTenantId) (her ikisi de görür)

jobs

  • clinicTenantId, labTenantId, createdBy
  • patientCode, prostheticType (metal_porselen, zirkonyum, implant_ustu_zirkonyum, gecici, e_max, diger)
  • memberCount (üye sayısı), color (Vita renk kodu örn. A2), description?, price?, currency?, dueDate?
  • status: 'pending' | 'in_progress' | 'sent' | 'delivered' | 'cancelled'
  • currentStep: 'olcu' | 'alt_yapi_prova' | 'ust_yapi_prova' | 'cila_bitim'
  • Permission: Role.team(clinicTenantId) + Role.team(labTenantId)

job_files

  • jobId, clinicTenantId, labTenantId, uploadedBy
  • kind: 'scan' | 'image' | 'document'
  • fileId (Appwrite Storage bucket: job-files), name, size, mimeType?
  • Permission: aynı job permission'ı

job_status_history

Stepper geçişleri — denetim izi.

  • jobId, clinicTenantId, labTenantId, step, completedBy, completedAt, note?

prosthetics (lab katalog)

  • tenantId (lab'in tenant id'si), createdBy
  • name, type, unitPrice, currency?, archived?
  • Permission: Role.team(tenantId) (sadece kendi tarafı)

finance_entries

  • tenantId, createdBy, jobId?, counterpartTenantId?
  • type: 'income' | 'expense' | 'receivable' | 'payable'
  • amount, currency?, status: 'pending' | 'paid' | 'cancelled', date, description?
  • Permission: Role.team(tenantId) (klinik ve lab kendi defterlerini görür; karşı taraf görmez)

notifications

  • tenantId, userId?, jobId?, connectionId?, message, read

CRM'den birebir kullanılıyor.

Bağlantı akışı (connections yaşam döngüsü)

  1. Klinik/connections → "Bağlantı talep et" → karşı tarafın memberNumber'ını gir.
  2. Server action connections row yaratır (status: pending), her iki team'e permission açar.
  3. Lab/connections → bekleyen talepler listesinde görür → Onayla veya Reddet.
  4. Onaylanırsa status: approved. Klinik artık /jobs/new formunda bu lab'i seçebilir.
  5. Reddedilirse status: rejected, tekrar talep edilebilir.

İş akışı (jobs yaşam döngüsü)

  1. Klinik /jobs/new formuyla iş açar (lab seçimi onaylı bağlantılardan), durum pending.
  2. Lab gelen kutusunda görür, İşleme Alstatus: in_progress, currentStep: olcu.
  3. Lab her aşamayı tamamlayınca job_status_history row eklenir + currentStep ilerler.
  4. Cila/Bitim sonrası status: sent. Klinik teslim alınca delivered.
  5. Tamamlandığında lab finance_entries (income, pending) açar; klinik tarafında (expense, pending) açılır (idempotent sync helper ile).

Onboarding akışı

/onboarding sayfası:

  1. Kayıt sonrası ilk girişte. Mevcut workspace'i yoksa zorunlu.
  2. Hesap türü seç (Klinik / Lab) → state.
  3. Şirket adı + opsiyonel vergi/telefon.
  4. Submit → createWorkspaceAction:
    • Appwrite Team yarat
    • tenant_settings row yarat (kind, memberNumber üretilmiş)
    • Active tenant cookie + user prefs
  5. Redirect /dashboard.

İmport akışı (cross-app team import) için de kind seçimi zorunlu.

Açık tasarım kararları

  • Login formunda "Üye Numarası" PDF'te var; biz e-posta+şifre kullanıyoruz. memberNumber register/login için kullanılmaz, sadece bağlantı kurmak için.
  • Cila/Bitim sonrası kargo/teslim alanı PDF'te yok; spec'te status: sent → delivered ile temsil edildi. Kargo takip eklenirse jobs.shipmentTracking? opsiyonel field eklenir.
  • Finans entegrasyonu PDF'te "Finans (Bekliyor)" başlığı dışında detay vermiyor. Spec'te finance_entries (income/expense/receivable/payable) ile başlattık; faturalama, ödeme provider entegrasyonu sonraki faz.
  • PDF'in "Bağlantı Kodu" tek bir kalıcı kod olarak modellendi (memberNumber). Her connection için ayrı OTP/kod istenirse connection_codes collection eklenir.

Yapılacaklar (oturum kapanışı sonrası)

  • Appwrite MCP ile lab database + collection'lar (bu commit'te schema TS hazır, fiziksel oluşturma bir sonraki adım)
  • jobs modülü (liste + form + detay)
  • connections modülü (request/approve akışı)
  • products modülü (lab katalog CRUD)
  • finance modülü (cross-tenant idempotent sync helper)
  • Coolify app + DNS lab.kovakcrm.com
  • Landing page DLS'e uyarla