# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

GİSK Yönetim Paneli — a Turkish-language sports club management system. Manages players, attendance, membership fees (aidat), finances (kasa), and reporting. Includes a separate parent/guardian portal (`veli/`).

## Tech Stack

- **Backend**: Procedural PHP 7.0+ with PDO
- **Database**: MySQL 5.7+ (production) or SQLite 3 (development) — configured via `.env` `DB_DRIVER`
- **Frontend**: Bootstrap 5.3.3 CDN + vanilla JavaScript (no bundler, no npm)
- **Deployment**: cPanel/Apache with EA-PHP 7.0
- **No build system, no package manager, no test framework**

## Development

No build or install steps. Point a PHP 7.0+ Apache server at the project root.

### CLI tool (`cius`)

```bash
php cius migrate              # Run migrations
php cius migrate:fresh --seed  # Drop all, re-migrate, seed
php cius seed                 # Run seeders only
php cius serve                # Start PHP dev server
php cius db:reset             # Reset database
php cius db:import            # Import from SQL dump
```

### First-time setup

1. Copy `.env.example` → `.env`, configure DB credentials
2. Run `php cius migrate --seed` or use `kurulum_ilk_kullanici.php` to create the initial admin

## Architecture

### Module structure

```
cekirdek/              → Core: config, auth, template, helpers
  config.php           → DB connection (.env parsing), exports $db PDO instance
  config.local.php     → SQLite-specific setup (WAL mode, custom NOW())
  yetki_kontrol.php    → Auth guard — include at top of every protected page
  sablon.php           → Master template — wraps $icerik in nav/footer layout
  aidat_helper.php     → Fee debt generation, balance calculation
  devam_helper.php     → Attendance lookup, upsert (MySQL/SQLite compatible)
  kasa_helper.php      → Treasury balance and summary queries
moduller/
  oyuncular/           → Player CRUD, documents, PDF export, attendance
  aidat/               → Membership fees (borç/tahsilat)
  kasa/                → Financial transactions (gelir/gider)
  raporlar/            → Reports (monthly fees, debtors, collections)
  ayarlar/             → Club settings, groups, document types
  kullanicilar/        → User management
  public/              → Public attendance marking (no auth, via ?key= share links)
veli/                  → Parent portal (separate session, scoped to one player)
database/
  migrations/          → SQL schema files
  seeds/               → Sample data
```

### Request flow — page rendering

1. Module file includes `cekirdek/config.php` + `cekirdek/yetki_kontrol.php`
2. Calls `ob_start()`, generates HTML content
3. Captures with `$icerik = ob_get_clean()`
4. Includes `cekirdek/sablon.php` which renders `$icerik` inside the master layout

### Request flow — AJAX endpoints

Module `ajax/` subdirectories return JSON directly (no template). Pattern:
- Include `yetki_kontrol.php` for auth
- Set `Content-Type: application/json; charset=utf-8`
- Return `{"durum": "ok"|"hata", "mesaj": "...", ...}` with `JSON_UNESCAPED_UNICODE`
- Wrap in try-catch

### Parent portal (`veli/`)

Separate auth system with its own session (`session_name('VELI_SES')`), login page, and assets. Parents see only their child's data: fees, attendance, guardians, declarations, documents. Has its own `giris.php`, `index.php`, and `ajax/` handlers. Authenticated via `$_SESSION['veli_oyuncu_id']`.

## Key Conventions

- **Auth**: Session-based. Main panel: `$_SESSION['kullanici']`, role `yonetici` = admin. Parent portal: `$_SESSION['veli_oyuncu_id']`
- **CSRF**: `$_SESSION['_token']` verified on POST submissions
- **DB queries**: PDO prepared statements with named parameters (`:param`). Helper functions handle MySQL vs SQLite syntax differences (e.g., `ON DUPLICATE KEY` vs `ON CONFLICT`)
- **Naming**: Turkish identifiers throughout — `oyuncular` (players), `aidat` (dues), `kasa` (treasury), `devam` (attendance), `belge` (document)
- **File naming in modules**: `listele.php` (list), `ekle.php` (add), `duzenle.php` (edit), `sil.php` (delete), `detay.php` (detail)
- **Status values**: Players use integer status (1=active, 0=inactive). Attendance uses string: `var`/`yok`/`mazeret`/`gec`
- **Pagination**: 20–25 items per page, GET-based `?sayfa=` parameter
- **File uploads**: Stored in `uploads/oyuncu_belgeler/`, filename via `uniqid('belge_')`, allowed: pdf/jpg/jpeg/png/webp

## Domain Model (key tables)

- `oyuncular` — players, linked to groups via `oyuncu_grup_atama` junction table
- `oyuncu_veliler` — parent/guardian contacts per player
- `oyuncu_belgeler` — uploaded documents with file paths
- `oyuncu_beyanlar` — health/liability declarations (tracks IP + user agent)
- `aidat_borclar` — monthly fee debts per player, indexed by (oyuncu_id, yil, ay)
- `aidat_tahsilatlar` — payments received, linked to `kasa_hareketler` via `kasa_id`
- `kasa_hareketler` — income/expense transactions with `tur` (gelir/gider), `kategori_id`, optional link to aidat
- `kasa_kategoriler` — transaction category definitions
- `devam_kayitlari` — attendance records, unique on (oyuncu_id, tarih)
- `devam_paylasimlar` — shareable attendance links with `paylasim_key`, expiry, JSON `secili_gunler` (selected weekdays)
- `kulup_ayarlar` (id=1) — single-row club config (name, phone, address, logo, fee amounts)
- `kullanicilar` — users with `password_hash()` + SHA256→bcrypt auto-migration
- `belge_turleri` — document type definitions

## UI Language

All UI text, variables, comments, and database columns are in Turkish. Maintain Turkish naming when adding or modifying code.
