Files
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

6.3 KiB
Raw Permalink Blame History

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 (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

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