Files
lab/CLAUDE.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

127 lines
6.3 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 — Dental Lab System
Diş klinikleri ↔ diş laboratuvarları arasında iş alışverişi, dosya paylaşımı ve finansal takip platformu. KovakSoft müşterileri ya **Klinik** ya da **Laboratuvar** olarak kayıt olur, "bağlantı kodu" ile karşı tarafla eşleşir, iş gönderir/alır ve ödeme akışını yönetir.
Baz: [isletmem-kovakcrm](https://git.kovaksoft.com/kovakmedya/isletmem-kovakcrm) (silicondeck/shadcn-dashboard-landing-template türevi). Auth + tenant katmanı + tema + server actions altyapısı aynen kullanılıyor; sadece domain modülleri DLS için yeniden yazıldı.
## Stack
- **Next.js 16** + **React 19** (App Router, TypeScript)
- **Tailwind CSS v4** + **shadcn/ui v3** (Radix primitives)
- **Zustand** — client state
- **TanStack Table**, **react-hook-form** + **Zod**, **Recharts**
- **Appwrite** — DB, Auth, Storage, Teams (tenant izolasyonu)
- **pnpm** — package manager
- **Coolify** — Gitea webhook ile auto-deploy
## Multi-tenancy modeli
| Concept | Appwrite primitive |
|---|---|
| Tenant | Appwrite **Team** (1 team = 1 klinik veya 1 lab) |
| Tenant türü (`kind`) | `tenant_settings.kind: 'lab' \| 'clinic'` |
| Tenant üyesi | Team membership (rol: `owner` / `admin` / `member`) |
| Bağlantı kodu | `tenant_settings.memberNumber` (6 hane unique) |
| Veri izolasyonu | Her doküman `tenantId` + `Permission.read/update/delete(Role.team(tenantId))` |
| Cross-tenant erişim | `jobs`, `job_files`, `job_status_history`, `finance_entries` ek olarak karşı tarafın team permission'ına açılır |
**Kural:** Tek shared tenant değil — her klinik ve her lab kendi Appwrite Team'idir, izolasyon CRM ile aynı. `kind` boyutu sadece UI/route koruması ve iş akışı için. `requireTenantKind(ctx, ['lab'])` route guard helper'ı kullanılır.
## Modüller
| Modül | Rol | Collection(lar) |
|---|---|---|
| Anasayfa | her ikisi | (özet kartlar) |
| Gelen İşler | her ikisi | `jobs` (lab tarafında baskın) |
| Giden İşler | her ikisi | `jobs` (klinik tarafında baskın) |
| Yeni İş Yayınla | sadece klinik | `jobs` + `job_files` |
| İş detay (durum stepper) | her ikisi | `jobs` + `job_status_history` (Ölçü → Alt Yapı → Üst Yapı → Cila/Bitim) |
| Ürünler | sadece lab | `prosthetics` |
| Finans | her ikisi | `finance_entries` |
| Bağlantı Kur | her ikisi | `connections` (bağlantı kodu ile eşleşme) |
| Ayarlar | her ikisi | `tenant_settings`, üye yönetimi |
Tüm collection'larda ortak: `tenantId` (sahip), `createdBy` (userId), `$createdAt`, `$updatedAt`. Cross-tenant collection'lar (jobs, job_files, finance_entries) ek olarak `clinicTenantId` + `labTenantId` taşır.
## Bağlantı (connections) akışı
1. Klinik karşı laboratuvarın `memberNumber`'ını girer → `connections` row oluşur (`status: pending`).
2. Lab kendi tarafında pending talebi görür, **Onayla** veya **Reddet**.
3. Onaylanan bağlantı `status: approved`, sonrasında `Yeni İş Yayınla` formunda klinik bağlı lab'lerden birini seçebilir.
4. İş oluştuğunda dokümana karşı tarafın `Role.team(<otherTenantId>)` read/update permission'ı eklenir → karşı taraf otomatik görür.
## Auth
Appwrite Auth — email/password. CRM'deki akış aynen geçerli.
- Register → onboarding → **Klinik / Laboratuvar** seçimi + şirket bilgileri → `tenant_settings.kind` atanır, `memberNumber` üretilir → dashboard.
- `lib/appwrite/server.ts` — server SDK (API key ile admin ops)
- `lib/appwrite/client.ts` — browser SDK (session JWT)
- Cookie: `lab-session`, `lab-tenant`. Middleware: korumalı `(dashboard)/*`, public `(auth)/*` + marketing.
## Klasör yapısı
```
src/
├── app/
│ ├── (auth)/ login, register, reset-password
│ ├── (dashboard)/ dashboard, jobs/{inbound,outbound,new,[id]}, products, finance, connections, settings
│ ├── d/[code]/ team davet kabul
│ ├── landing/ marketing
│ └── onboarding/ ilk workspace + kind seçimi
├── components/ shadcn/ui + custom (logo, sidebar, header)
├── lib/
│ ├── appwrite/ client.ts, server.ts, schema.ts, tenant-guard.ts, ...
│ └── validation/
├── middleware.ts
└── ...
```
## Komutlar
```bash
pnpm dev # localhost:3000
pnpm build
pnpm lint
pnpm typecheck # tsc --noEmit
```
## Appwrite — MCP üzerinden işlemler
`DATABASE_ID = "lab"` — isletmem-kovakcrm projesi (ID `69f27b51000a5bee46ce`) altında ayrı database. Tüm collection / attribute / index / permission CRUD'u **Appwrite MCP** ile yapılır. Migration mantığı: yeni collection / attribute eklendiğinde MCP komutu çalıştır + `lib/appwrite/schema.ts` güncellenir (tek source of truth).
## Gitea + Coolify deploy
- **Repo:** `ssh://git@git.kovaksoft.com:2222/kovakmedya/lab.git`
- **Coolify host:** `kovaksoft-coolify` (`ssh -p 22 root@194.31.52.65`)
- **Production domain:** `https://lab.kovakcrm.com`
- **Workflow:** `main` branch'e push → Gitea webhook → Coolify auto-deploy.
- **Webhook URL (Coolify Gitea handler):** `https://admin.kovaksoft.com/webhooks/source/gitea/events/manual`
## Environment variables
```
NEXT_PUBLIC_APPWRITE_ENDPOINT=https://db.kovaksoft.com/v1
NEXT_PUBLIC_APPWRITE_PROJECT_ID=69f27b51000a5bee46ce
NEXT_PUBLIC_APPWRITE_DATABASE_ID=lab
APPWRITE_API_KEY= # server-only
APP_URL=https://lab.kovakcrm.com
```
`.env.local` git'e gitmez. Coolify'da ayrı set edilir.
## Geliştirme prensipleri
- **Mevcut temayı koru, brand değiştir.** Sidebar / header / theme customizer aynen kalır; sadece içerik DLS modüllerine bağlı.
- **Tenant filtresi şart.** Server actions / route handlers'da `tenantId` (veya cross-tenant durumda `clinicTenantId`/`labTenantId`) her query'ye eklenmeden veri çekme.
- **Server actions tercih edilir** — client'tan direkt Appwrite write yerine, server action içinden server SDK ile.
- **Schema değişikliği = MCP çağrısı + `schema.ts` update + migration notu** (commit mesajına `db:` prefix).
- **Türkçe UI**, kod İngilizce.
## Faydalı referanslar
- Gitea CLI: `tea repos list --login git.kovaksoft.com`
- Coolify VPS SSH: `ssh kovaksoft-coolify`
- Appwrite docs: https://appwrite.io/docs
- Baz repo: https://git.kovaksoft.com/kovakmedya/isletmem-kovakcrm
- UI spec: `belgeler/dls-ui-tasarim.pdf` (orijinal Figma export)