Commit Graph

5 Commits

Author SHA1 Message Date
kovakmedya 2c6c074a06 feat: job status/step flow, file upload, finance sync, notifications
Job lifecycle
  - acceptJobAction (lab): pending → in_progress + currentStep=olcu
  - advanceStepAction (lab): step ilerletir, son adım sonrası status=sent
  - markDeliveredAction (clinic): sent → delivered
  - cancelJobAction: pending iş iptali (her iki taraf)
  - job_status_history her step transition'da idempotent kayıt
  - Detay sayfası interactive panel + Aşama Geçmişi kartı

Job files (Appwrite Storage job-files bucket, 30MB/file)
  - uploadJobFilesAction: çoklu dosya, mimeType'tan kind sınıflandırma
    (scan/image/document), her iki team'e read permission, partial-fail
    rollback (storage + row temizliği)
  - deleteJobFileAction: yetkilendirilmiş silme, file + row birlikte
  - JobFilesPanel: client-side select + upload + liste + indir + sil
  - next.config bodySizeLimit 3mb → 100mb (toplu yükleme için)

Finance sync (idempotent)
  - syncFinanceForJob helper: sent/delivered transition'larında klinik
    payable + lab receivable rows (jobId+tenantId+type unique kontrolü,
    her tarafta tek satır garanti)
  - markFinancePaidAction / reopenFinanceAction: manuel ödendi/geri al
  - /finance sayfası: stat kartlar (bekleyen alacak/borç, aylık gelir/gider)
    + hareketler tablosu, role-aware kopyalar
  - Memory rule [[feedback_cross_entity_sync_helpers]]: best-effort, never
    re-throws

Notifications
  - createNotification helper, connection (request/approve) ve job
    (create/accept/sent/delivered) eventlerinde tetikleniyor
  - /notifications sayfası + tek tek / hepsi okundu işaretle
  - Header'a Bell ikonu + okunmamış count badge (layout SSR'de besler)
  - Middleware PROTECTED_PREFIXES'e /notifications ekli
2026-05-21 20:17:33 +03:00
kovakmedya 76e02754b8 feat(modules): connections, products, jobs (list/form/detail-placeholder)
Connections (clinic ↔ lab)
  - request via member number, approve/reject (counterparty), cancel pending,
    delete approved
  - permission rows opened to both teams; audit log for every mutation
  - /connections page: own code card, request form, pending inbound/outbound
    tables, approved connections table with delete confirm

Products (lab catalog)
  - createProstheticAction + update + archive/restore + delete (lab-only)
  - zod validation, dev-mode error surfacing
  - /products page: catalog table + add form + edit dialog. Hidden from
    clinic accounts via requireTenantKind.

Jobs (work orders)
  - createJobAction (clinic-only) — checks approved connection before write,
    permissions opened to both clinic and lab teams
  - listInboundJobs (lab perspective), listOutboundJobs (clinic perspective),
    listApprovedLabsForClinic for the new-job form
  - /jobs/inbound + /jobs/outbound tables with role-aware copy
  - /jobs/new full form (lab select, patient code, prosthetic type, member
    count, color, due date, price/currency, description)
  - /jobs/[jobId] placeholder detail page with stepper visualisation;
    status/step updates and file upload come next session

All new mutations follow the memory rules: schema-checked row payloads,
admin client behind requireTenant + requireRole/requireTenantKind, audit
log calls best-effort, no empty-string Radix Select values.
2026-05-21 19:59:23 +03:00
kovakmedya 7fb8288f79 auth: route tenant-less sign-in to onboarding instead of erroring out
Previously, signing in with a kind toggle when the account had no
tenant_settings row in the lab database returned 'Bu hesap için kayıt
bulunamadı'. For a freshly-imported isletmem user that has never opened
DLS, the right behaviour is onboarding — not a dead end.

resolveTenantOnLogin now distinguishes three states:
  - no_tenants  → redirect /onboarding?kind=<pill>  (session stays)
  - mismatch    → real error naming the existing kind, session rolled back
  - matched     → existing tenant set as active, /dashboard

Onboarding page accepts ?kind= and the workspace form pre-selects it, so
the user keeps their login pill choice without re-picking. Also fixed the
'teams.total > 0' redirect — it now requires a tenant_settings row before
sending users off to /dashboard, otherwise users with cross-app teams but
no DLS workspace would bounce.
2026-05-21 19:39:29 +03:00
kovakmedya 92c3b53e39 auth: login pill toggle for clinic/lab + server-side kind validation
Sign-in form now has a Klinik / Laboratuvar pill toggle (defaults to clinic).
The selected kind is posted alongside email+password; the server action
resolves the user's memberships, picks a tenant_settings row matching the
chosen kind, and sets it as active. If no matching tenant exists the session
is rolled back with a clear error.

Invite-flow logins skip the kind check — invite code drives team assignment.
2026-05-21 18:39:45 +03:00
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