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

145 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`
### `audit_logs`, `invite_links`, `password_resets`, `user_preferences`
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 Al**`status: 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