# İşletmem KovakCRM

Multi-tenant CRM. KovakSoft müşterileri kendi şirketleri için müşteri / hizmet / yazılım / takvim / görev / finans yönetir. Her tenant kendi verilerini görür, çapraz erişim yok.

## 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**, **dnd-kit** (Kanban), **Recharts** (template'den)
- **Appwrite** — DB, Auth, Storage, Teams (tenant izolasyonu)
- **pnpm** — package manager
- **Coolify** — Gitea webhook ile auto-deploy

Template kaynağı: `silicondeck/shadcn-dashboard-landing-template` (MIT). `nextjs-version/` klonlandı, görsel tasarım ve mevcut dashboard davranışı korunacak — sadece data layer Appwrite'e bağlanıyor.

## Multi-tenancy modeli

| Concept | Appwrite primitive |
|---|---|
| Tenant | Appwrite **Team** (1 team = 1 şirket) |
| Tenant üyesi | Team membership (rol: `owner` / `admin` / `member`) |
| Veri izolasyonu | Her doküman `tenantId` attribute + `Permission.read/update/delete(Role.team(tenantId))` |
| Tenant onboarding | İlk login'de team yoksa "create workspace" akışı |
| Üye daveti | Appwrite `teams.createMembership` (email + role) → davet linki → kabul ile team'e dahil |

**Kural:** Tüm collection'larda `tenantId` zorunlu attribute, indexed. Server-side query'lerde her zaman tenant filtresi uygulanır. Client SDK'da row-level security Appwrite Permissions ile garantilenir — kod hatasında dahi başka tenant verisi görünmez.

## Modüller

| Modül | Collection | Notlar |
|---|---|---|
| Müşteriler | `customers` | name, email, phone, taxId, address, notes |
| Hizmetler | `services` | name, description, unitPrice, currency, customerId (FK) |
| Yazılımlarımız | `software` + `customer_software` | software (name, version, license); customer_software (many-to-many: customerId × softwareId, startDate, endDate, fee) |
| Takvim | `calendar_events` | title, start, end, allDay, customerId?, color |
| Görevler (Kanban) | `tasks` | title, description, status (`backlog`/`todo`/`in_progress`/`done`), priority, dueDate, assigneeId |
| Finans | `finance_entries` | type (`income`/`expense`/`debt`/`receivable`), amount, currency, date, customerId?, invoiceId?, note |
| Faturalar | `invoices` + `invoice_items` | number, customerId, issueDate, dueDate, status, totals; items (description, qty, unitPrice, vat) |
| Profil ayarları | Appwrite user prefs + `tenant_settings` | tenant logo, currency default, vat default |

Tüm collection'larda ortak: `tenantId`, `createdBy` (userId), `$createdAt`, `$updatedAt`.

## Auth

Appwrite Auth — email/password (başlangıçta). Sonrası: magic URL + Google OAuth.
- Login → team list çekilir → tek team varsa direkt dashboard, çoksa workspace switcher.
- `lib/appwrite/server.ts` — server SDK (API key ile admin ops, server actions).
- `lib/appwrite/client.ts` — browser SDK (session JWT, client components).
- Middleware: korumalı route'lar `(dashboard)/*`, public `(auth)/*` ve marketing.

## Klasör yapısı (template'den korunan)

```
src/
├── app/
│   ├── (auth)/         login, register, reset-password
│   ├── (dashboard)/    customers, services, software, calendar, tasks, finance, invoices, settings
│   └── landing/        marketing
├── assets/             SVG, images
├── components/         shadcn/ui + custom
├── config/             site config, nav
├── contexts/           React contexts
├── hooks/
├── lib/
│   ├── appwrite/       client.ts, server.ts, schema.ts (eklenecek)
│   └── tenant/         resolveTenant(), withTenant() (eklenecek)
├── middleware.ts       auth/route protection
├── types/
└── utils/
```

## Komutlar

```bash
pnpm dev           # localhost:3000
pnpm build
pnpm lint
pnpm typecheck     # tsc --noEmit
```

## Appwrite — MCP üzerinden işlemler

Database, collection, attribute, index, permission CRUD'u **Appwrite MCP** ile yapılır (manual console tıklaması yok). Migration mantığı: yeni collection / attribute eklendiğinde MCP komutu çalıştır + `lib/appwrite/schema.ts` güncellenir (tek source of truth, tipler oradan üretilir).

```
# MCP tool format
tool: tables_db_create | tables_db_create_table | tables_db_create_string_attribute | ...
```

## Gitea + Coolify deploy

- **Repo:** `ssh://git@git.kovaksoft.com:2222/kovakmedya/isletmem-kovakcrm.git`
- **Coolify host:** `kovaksoft-coolify` (`ssh -p 22 root@194.31.52.65`)
- **Production domain:** `https://isletmem.kovakcrm.com`
- **Workflow:** `main` branch'e push → Gitea webhook → Coolify auto-deploy.
- Coolify'a Appwrite ENV'leri girilir (aşağı bak), build command `pnpm build`, start `pnpm start`.

## Environment variables

```
NEXT_PUBLIC_APPWRITE_ENDPOINT=
NEXT_PUBLIC_APPWRITE_PROJECT_ID=
APPWRITE_API_KEY=                 # server-only
NEXT_PUBLIC_APPWRITE_DATABASE_ID=
APP_URL=https://isletmem.kovakcrm.com
```

`.env.local` git'e gitmez. Coolify'da ayrı set edilir.

## Geliştirme prensipleri

- **Template görselini bozma.** Sayfa layout, sidebar, theme, component'ler aynı kalır; sadece içerikteki demo data Appwrite'a bağlanır.
- **Tenant filtresi şart.** Server actions / route handlers'da `tenantId`'yi her query'ye eklemeden veri çekme.
- **Server actions tercih edilir** — client'tan direkt Appwrite write yerine, server action içinden server SDK ile (validation + audit kolay).
- **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
- Template repo: https://github.com/silicondeck/shadcn-dashboard-landing-template
