# CLAUDE.md — VidiKid Kreş SaaS Platformu

Bu dosya, Claude'un proje hakkında kapsamlı bilgiye sahip olmasını sağlar.
Her yeni oturumda önce bu dosyayı oku; ardından değiştireceğin dosyaları oku.

---

## Proje Nedir?

**VidiKid** — Türkiye'deki kreş ve anaokulu işletmeleri için geliştirilmiş çok kiracılı (multi-tenant) SaaS yönetim platformu.

**Paydaşlar:** Kreş sahibi/admin, öğretmenler, personel, veliler.

**Ana özellikler:** Öğrenci kayıt/takip, yoklama, günlük log (yemek/uyku/ilaç/not), mesajlaşma, finans/fatura, yemek menüsü, sınıf etkinlikleri, platform yönetimi.

---

## Teknoloji Yığını

| Katman | Teknoloji | Versiyon |
|--------|-----------|---------|
| Backend | NestJS | 10.4.x |
| Runtime | Node.js | ≥ 20.0.0 |
| ORM | Prisma | 5 / 6.2.x |
| Veritabanı | Supabase PostgreSQL | 16 |
| Frontend | Next.js (App Router) | 15.2.x |
| UI Framework | React | 18.3.x |
| Stil | Tailwind CSS 4 + shadcn/ui + Radix UI | — |
| Form Yönetimi | React Hook Form + Zod | — |
| Tablolar | TanStack Table | 8.x |
| Grafikler | Recharts | 2.x |
| Takvim | FullCalendar | 6.x |
| Kimlik Doğrulama | JWT + Passport.js | — |
| Monorepo | Turborepo + npm workspaces | 2.3.x |
| Paket Yöneticisi | npm | 10.x |
| Dil | TypeScript (strict) | 5.7.x |

---

## Klasör Yapısı

```
vd.acbilisim.com/
├── apps/
│   ├── api/                        # NestJS Backend (port 3001)
│   │   ├── src/
│   │   │   ├── app.module.ts       # Kök modül — tüm modüller buraya import edilir
│   │   │   ├── main.ts             # Bootstrap (CORS, Swagger, Pipe, Filter, Interceptor)
│   │   │   ├── modules/            # Feature modülleri
│   │   │   │   ├── auth/           # Giriş, JWT, refresh, forgot/reset password
│   │   │   │   ├── tenant/         # Tenant, branch, classroom CRUD
│   │   │   │   ├── school/         # Şube, sınıf, aktivite, yemek menüsü
│   │   │   │   ├── student/        # Öğrenci CRUD, veliler, yetkili alıcılar
│   │   │   │   ├── staff/          # Personel CRUD, izin talepleri (stub)
│   │   │   │   ├── parent/         # Veli paneli, çocuk listesi
│   │   │   │   ├── attendance/     # Yoklama kayıt/sorgulama
│   │   │   │   ├── daily-log/      # Günlük log (yemek/uyku/ilaç/not)
│   │   │   │   ├── finance/        # Fatura, ödeme (Iyzico stub)
│   │   │   │   ├── messaging/      # Mesajlaşma (REST; WebSocket yok)
│   │   │   │   ├── notification/   # Bildirim yönetimi
│   │   │   │   ├── school-dashboard/ # Okul istatistik dashboard
│   │   │   │   ├── platform-admin/ # Super admin yönetimi
│   │   │   │   └── health/         # Health check
│   │   │   └── shared/             # Yardımcı sınıflar
│   │   │       ├── prisma/         # PrismaService + tenant context
│   │   │       ├── guards/         # JwtAuthGuard, RolesGuard
│   │   │       ├── decorators/     # @Public(), @Roles(), @CurrentUser()
│   │   │       ├── filters/        # HttpExceptionFilter (Türkçe hata mesajları)
│   │   │       ├── interceptors/   # ResponseInterceptor
│   │   │       └── middleware/     # TenantMiddleware, LoggerMiddleware
│   │   └── prisma/
│   │       ├── schema.prisma       # Veritabanı şeması (23 model, 8 enum)
│   │       ├── migrations/         # 8 migration dosyası
│   │       └── seed/               # Super admin seed script
│   │
│   └── web/                        # Next.js Frontend (port 3000)
│       ├── app/
│       │   ├── (auth)/             # Login, register, forgot/reset password
│       │   ├── (marketing)/        # Landing page
│       │   ├── (platform)/         # Auth gerektiren tüm paneller
│       │   │   ├── layout.tsx      # Platform layout
│       │   │   ├── school/         # Okul personeli (dashboard, öğrenciler, yoklama, finans...)
│       │   │   ├── platform/       # Tenant admin (dashboard, okullar, abonelikler, raporlar...)
│       │   │   ├── parent/         # Veli paneli (çocuklar, faturalar, bildirimler)
│       │   │   └── teacher/        # Öğretmen paneli
│       │   └── admin/              # Super admin paneli
│       ├── components/             # UI bileşenleri (charts, forms, layout, modals, ui...)
│       ├── lib/
│       │   ├── auth.ts             # apiFetch, apiFetchJson, oturum yönetimi
│       │   ├── utils.ts            # Yardımcı fonksiyonlar
│       │   ├── constants.ts        # Sabitler
│       │   └── hooks/              # Custom React hooks
│       └── middleware.ts           # Route koruma (cookie'den token kontrolü)
│
├── packages/
│   ├── types/                      # @kres/types — Paylaşılan TypeScript tipleri
│   │   └── src/
│   │       ├── enums.ts            # Tüm enum tanımları
│   │       ├── tenant.ts           # Tenant, Subscription, PlatformAdmin
│   │       ├── user.ts             # User, JwtPayload, AuthTokens, AuthUser
│   │       ├── student.ts          # Student, Attendance, DailyLog
│   │       ├── staff.ts            # Staff, LeaveRequest
│   │       ├── finance.ts          # Invoice, Payment
│   │       └── api.ts              # ApiResponse, ApiError, PaginationMeta
│   └── validators/                 # @kres/validators — Zod şemaları
│       └── src/
│           ├── auth.schema.ts
│           ├── tenant.schema.ts
│           ├── student.schema.ts
│           ├── staff.schema.ts
│           ├── finance.schema.ts
│           └── pagination.schema.ts
│
└── infra/
    ├── docker-compose.dev.yml      # PostgreSQL + Redis
    └── nginx/nginx.conf            # Nginx reverse proxy yapılandırması
```

---

## Veritabanı Şeması

**Multi-tenancy stratejisi:** Her tabloda `tenantId` sütunu (schema bazlı izolasyon YOK).
`tenantId`, `TenantMiddleware` + `AsyncLocalStorage` ile otomatik enjekte edilir.

### Platform Modelleri (tenantId YOK)
| Model | Açıklama |
|-------|---------|
| `Tenant` | Kreş işletmesi; `slug` subdomain veya `X-Tenant-Slug` header'ı |
| `Subscription` | Abonelik planı; `Plan` enum: TRIAL / STARTER / GROWTH / ENTERPRISE |
| `PlatformAdmin` | Super admin kullanıcıları |

### Tenant Modelleri (tenantId VAR)
| Model | Açıklama |
|-------|---------|
| `User` | Personel ve veliler; `Role`: ADMIN / TEACHER / PARENT |
| `Branch` | Şube |
| `Classroom` | Sınıf; `homeroomTeacherId` ile öğretmene bağlı |
| `ClassroomActivity` | Takvim etkinliği; `startsOn`/`endsOn` (Date) |
| `MealMenu` | Günlük yemek menüsü; `(tenantId, menuDate)` unique |
| `Student` | Öğrenci kaydı |
| `StudentGuardianContact` | Acil iletişim kişisi |
| `Parent` | Veli profili (`User`'a 1-1 bağlı) |
| `StudentParent` | Öğrenci-veli bağlantısı (many-to-many pivot) |
| `AuthorizedPickup` | Öğrenci almaya yetkili kişi |
| `Attendance` | Yoklama; `(tenantId, studentId, date)` unique |
| `DailyLog` | Günlük log; `data: Json` alanı logType'a göre yapılandırılır |
| `Message` | Mesaj (REST; real-time yok) |
| `AppNotification` | Uygulama bildirimi |
| `Invoice` | Fatura |
| `Payment` | Ödeme; `provider`: iyzico |
| `AuditLog` | Denetim kaydı (tenantId opsiyonel) |

### Enum'lar
```
Role              → ADMIN, TEACHER, PARENT
Plan              → TRIAL, STARTER, GROWTH, ENTERPRISE
SubscriptionStatus→ TRIAL, ACTIVE, SUSPENDED, CANCELLED
Gender            → MALE, FEMALE
AttendanceStatus  → PRESENT, ABSENT, LATE, EXCUSED
DailyLogType      → MEAL, SLEEP, MEDICINE, NOTE, OBSERVATION
InvoiceStatus     → PENDING, PAID, OVERDUE, CANCELLED
PaymentStatus     → PENDING, SUCCESS, FAILED, REFUNDED
```

---

## Geliştirme Ortamı Kurulumu

```bash
# 1. Bağımlılıkları yükle
npm install

# 2. API .env dosyasını oluştur
cp apps/api/.env.example apps/api/.env
# .env içindeki değerleri doldur

# 3. Prisma client oluştur
cd apps/api && npx prisma generate

# 4. Migration'ları çalıştır
cd apps/api && npx prisma migrate deploy

# 5. Seed çalıştır (super admin oluşturur)
cd apps/api && npx ts-node prisma/seed/index.ts

# 6. Tüm uygulamaları birlikte başlat (Turborepo)
npm run dev
# veya ayrı ayrı:
npm run api:dev   # sadece API
npm run web:dev   # sadece Web
```

---

## Build / Test Komutları

```bash
# Tüm workspace'leri build et
npm run build

# Lint (tüm workspace)
npm run lint

# Test (tüm workspace)
npm run test

# Format (Prettier)
npm run format

# Sadece API test
cd apps/api && npm test
cd apps/api && npm run test:e2e

# Prisma komutları
npm run db:generate   # Prisma client yenile
npm run db:migrate    # Migration'ları çalıştır (production)
npm run db:seed       # Seed çalıştır

# Migration oluştur (development)
cd apps/api && npx prisma migrate dev --name <migration_adi>
```

---

## Ortam Değişkenleri

### `apps/api/.env`
```bash
NODE_ENV=development
PORT=3001
CORS_ORIGINS=http://localhost:3000

# Supabase PostgreSQL
DATABASE_URL=postgresql://...?pgbouncer=true   # Transaction pooler (uygulama)
DIRECT_URL=postgresql://...                     # Direct connection (migration)

# JWT
JWT_SECRET=<min-32-karakter>
JWT_EXPIRES_IN=15m
JWT_REFRESH_SECRET=<min-32-karakter>
JWT_REFRESH_EXPIRES_IN=7d

# Entegrasyonlar (şu an eksik)
REDIS_URL=redis://localhost:6379
S3_BUCKET=kres-media
S3_REGION=eu-central-1
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_ENDPOINT=                                    # R2 için: https://ACCOUNT.r2.cloudflarestorage.com
RESEND_API_KEY=re_...
MAIL_FROM=noreply@vd.acbilisim.com
NETGSM_USER=
NETGSM_PASSWORD=
NETGSM_HEADER=KRESSAAS
IYZICO_API_KEY=
IYZICO_SECRET_KEY=
IYZICO_BASE_URL=https://sandbox-api.iyzipay.com
FIREBASE_PROJECT_ID=
FIREBASE_PRIVATE_KEY=
FIREBASE_CLIENT_EMAIL=
```

### `apps/web/.env.local`
```bash
NEXT_PUBLIC_API_URL=http://localhost:3001/api
```

---

## API Yapısı

- **Base URL:** `http://localhost:3001/api/v1`
- **Swagger:** `http://localhost:3001/api/docs`
- **Tüm yanıtlar** `ResponseInterceptor` üzerinden `{ success, data, statusCode }` formatında döner.
- **Hatalar** `HttpExceptionFilter` üzerinden `{ success, statusCode, message, details, requestId }` formatında döner.
- **Throttle:** Global 500 istek/dk (giriş endpoint'i sıkı limit kullanır).

### Tenant Belirleme
Her istekte `TenantMiddleware` çalışır:
1. `X-Tenant-Slug` header'ına bakar
2. Host subdomain'ine bakar (örn. `okul1.vd.acbilisim.com`)
3. Bulunan slug ile DB'den tenant çeker, `AsyncLocalStorage`'a yazar
4. `PrismaService.requireTenantId()` ile tüm sorguları filtreler

### Kimlik Doğrulama Akışı
- `POST /api/v1/auth/login` → `{ accessToken, refreshToken, user }`
- `POST /api/v1/auth/refresh` → Yeni token çifti
- `POST /api/v1/auth/logout`
- **Frontend:** `apiFetch()` her istekte `Authorization: Bearer <token>` ekler; 401 gelince `logout()` çağırır (refresh mekanizması **henüz yok** — eklenecek).

---

## Frontend Mimarisi

### Route Gruplaması
```
app/
├── (auth)/          → /login, /register, /forgot-password, /reset-password
├── (marketing)/     → / (landing page)
├── (platform)/      → Korunan tüm paneller
│   ├── school/      → Okul personeli
│   ├── platform/    → Tenant admin
│   ├── parent/      → Veliler
│   └── teacher/     → Öğretmenler
└── admin/           → Super admin
```

### Route Koruma
`middleware.ts` — `accessToken` cookie'si yoksa `/login`'e yönlendirir.

### API İletişim Katmanı
`lib/auth.ts` içindeki iki fonksiyon her yerde kullanılır:
```typescript
// Ham Response döner
apiFetch(path, options): Promise<Response>

// ApiResponse<T> döner — JSON parse + hata normalleştirme dahil
apiFetchJson<T>(path, options): Promise<ApiResponse<T>>
```

Her istek `X-Tenant-Slug` header'ını localStorage'daki kullanıcı verisinden alır.

---

## Kodlama Kuralları

### Genel
- **TypeScript strict mode** — `any` kullanma; tip belirt veya generic kullan.
- Hata mesajları **Türkçe**, kod (değişken/fonksiyon/sınıf isimleri) **İngilizce**.
- Her modül: `controller` / `service` / `dto` yapısına uyar.
- Yorum satırları iş mantığını açıklamak için kullanılır; trivial kodu açıklama.

### Backend (NestJS)
```typescript
// Multi-tenant sorgularda tenantId her zaman kullan:
const tenantId = this.prisma.requireTenantId();

// Rol kontrolü decorator ile:
@Roles(Role.ADMIN, Role.TEACHER)
@UseGuards(JwtAuthGuard, RolesGuard)

// Public endpoint için:
@Public()

// Mevcut kullanıcı için:
@CurrentUser() user: JwtPayload
```

- Input validasyonu: DTO class'larında `class-validator` decorator'ları kullan.
- Paylaşılan tip/şema için `@kres/types` ve `@kres/validators` paketlerini kullan.
- Yeni modül eklerken `app.module.ts`'e import etmeyi unutma.
- Yeni Prisma modeli eklerken `prisma migrate dev --name <ad>` ile migration oluştur; ardından `@kres/types`'a tip ekle.

### Frontend (Next.js)
```typescript
// API çağrıları için:
const { data, error } = await apiFetchJson<Student[]>('/v1/school/students');

// Form validasyonu için @kres/validators'ı kullan:
import { CreateStudentSchema } from '@kres/validators';
const form = useForm({ resolver: zodResolver(CreateStudentSchema) });

// Tüm sayfalar Server Component olarak başlar,
// interaktif kısımlar 'use client' ile işaretlenir.
```

- shadcn/ui bileşenlerini kullan; özel bileşen yazmadan önce mevcut bileşenleri kontrol et.
- Sayfa düzeyinde loading state için `loading.tsx` kullan.
- Hata durumları için `error.tsx` kullan.

---

## Mevcut Eksiklikler (Önemli)

Aşağıdaki özellikler **henüz implemente edilmemiş** veya **stub** durumdadır.
Bunları düzeltmeden/tamamlamadan sormadan değiştirme:

| Bileşen | Durum | Kritiklik |
|---------|-------|-----------|
| Email servisi (Resend) | **Yok** | Kritik |
| Parola sıfırlama | **Stub** — `auth.service.ts:261-271` | Kritik |
| Student detail sayfası `/school/students/[id]` | **Yok** | Kritik |
| Token refresh mekanizması | **Yok** — `auth.ts:147-150` | Kritik |
| File upload / S3 | **Yok** | Kritik |
| Staff izin talepleri | **Stub** — `staff.service.ts:122-134` | Yüksek |
| Iyzico ödeme entegrasyonu | **Stub** — `finance.service.ts:122-150` | Yüksek |
| Platform dashboard gerçek veri | **Hardcode** | Yüksek |
| Subscription/Users sayfaları | **"Yakında"** | Yüksek |
| Firebase push notification | **Yok** | Orta |
| SMS servisi (Netgsm) | **Yok** | Orta |
| WebSocket / Real-time | **Yok** | Düşük |
| BullMQ kuyruk sistemi | **Yok** | Düşük |

Detaylı plan: `.claude/plans/ethereal-brewing-rossum.md`

---

## Shared Paketler

### `@kres/types`
Prisma şemasıyla uyumlu TypeScript tipleri. **12 entity tipi eksik** (Branch, Classroom, Message, vb.). Yeni Prisma modeli eklendiğinde buraya da tip ekle.

### `@kres/validators`
Zod validasyon şemaları. Frontend form validasyonunda ve backend DTO'larında kullanılır. Validator güncellediğinde `pnpm build` ile `packages/` dizinini yeniden derle.

### `@kres/config` ve `@kres/ui`
**Boş** — henüz içerik yok.

---

## Sık Kullanılan Komutlar

```bash
# Yeni migration oluştur
cd apps/api && npx prisma migrate dev --name add_password_reset_token

# Prisma Studio (DB GUI)
cd apps/api && npx prisma studio

# Belirli bir workspace'de komut çalıştır
npm run dev --workspace=apps/api
npm run build --workspace=packages/types

# TypeScript derleme kontrolü (API)
cd apps/api && npx tsc --project tsconfig.build.json --noEmit

# TypeScript derleme kontrolü (Web)
cd apps/web && npx tsc --noEmit
```

---

## Önemli Notlar

1. **Prisma şeması değiştirildiğinde** mutlaka `prisma generate` çalıştır ve `@kres/types`'ı güncelle.
2. **`TenantMiddleware`** tüm rotalara uygulanır; platform admin rotaları `X-Tenant-Slug` göndermez, bu normal.
3. **`ThrottlerModule`** global 500 istek/dk limit uygular; login endpoint'i `@Throttle({ default: ... })` ile sıkı limit kullanır.
4. **Türkçe hata mesajları** zorunludur — `HttpExceptionFilter` Prisma hata kodlarını Türkçe'ye çevirir.
5. **Seed script** yalnızca bir kez çalıştırılmalı; tekrar çalıştırılırsa duplicate kontrolü yapılır.
6. **Frontend proxy:** Tarayıcıdan gelen `/api/...` istekleri Next.js rewrite ile backend'e yönlendirilir; SSR'da `NEXT_PUBLIC_API_URL` kullanılır.
