# CLAUDE.md

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

## Commands

### Setup
```bash
composer run setup
```

### Development (runs all servers concurrently)
```bash
composer run dev
```
This starts: Laravel server, queue worker, Pail log viewer, and Vite dev server.

To also exercise SSR locally (needed to see the real `<Head>` output — title, meta description, Open Graph, JSON-LD — that crawlers receive), run:
```bash
composer run dev-ssr
```
This builds the client + SSR bundles once, then starts the Laravel server, queue worker, and the Inertia SSR process together. **Production must run `php artisan inertia:start-ssr` as a persistent process** (e.g. under Supervisor, alongside php-fpm) — without it, Inertia silently falls back to client-only rendering (see `vendor/inertiajs/inertia-laravel/src/Ssr/HttpGateway.php`), and crawlers that don't execute JavaScript will see an empty page with none of the per-page SEO metadata.

### Testing
```bash
composer run test          # Run all tests
php artisan test --filter TestName   # Run a single test
./vendor/bin/pest tests/Feature/SomeTest.php  # Run a specific file
```
Tests use SQLite in-memory database (configured in `phpunit.xml`).

### Linting / Formatting
```bash
./vendor/bin/pint          # PHP code style (Laravel Pint)
npm run lint               # TypeScript/React ESLint + Prettier fix
```

### Frontend build
```bash
npm run build              # TypeScript check + Vite build (client + SSR)
npm run dev                # Vite dev server only
```

## Architecture

**Upepo Finance** is a Laravel 13 application with an Inertia.js + React + TypeScript frontend.

### Stack
- **Backend**: Laravel 13, PHP 8.3+
- **Frontend**: React 18, TypeScript, Tailwind CSS v4
- **Bridge**: Inertia.js v2 (no separate API — controllers return `Inertia::render()`)
- **Auth**: Laravel Breeze (session-based, with Sanctum)
- **SSR**: Enabled via `resources/js/ssr.tsx` and `npm run build --ssr`
- **Testing**: Pest v4 + pest-plugin-laravel
- **Routing (frontend)**: Ziggy (`@/` alias maps to `resources/js/`)

### Key conventions
- PHP namespace root: `App\` → `app/`
- TypeScript path alias: `@/*` → `resources/js/*`
- Pages live in `resources/js/Pages/` and map 1:1 to Inertia route renders
- Layouts: `AuthenticatedLayout.tsx` (auth'd pages), `GuestLayout.tsx` (guest pages)
- Route files: `routes/web.php` (main), `routes/auth.php` (Breeze auth routes), `routes/console.php`
- Database: SQLite by default (dev); migrations in `database/migrations/`
