# CLAUDE.md

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

## Project Overview

**SpeedNet** — an internet service provider website with a public React SPA frontend and a server-rendered Blade admin panel, backed by a Laravel 11 REST API.

## Common Commands

### Development

```bash
# Start everything at once (Laravel server + Vite + queue + log tail)
composer run dev

# Individual processes
php artisan serve          # Laravel on :8000
npm run dev                # Vite dev server
php artisan queue:listen   # Queue worker
php artisan pail --timeout=0  # Tail logs
```

### Build

```bash
npm run build              # Vite production build → public/build/
php artisan config:cache   # Cache config for production
php artisan route:cache    # Cache routes for production
```

### Database

```bash
php artisan migrate        # Run pending migrations
php artisan migrate:fresh  # Drop all tables and re-run
php artisan tinker         # Interactive REPL
```

### Code Quality

```bash
./vendor/bin/pint          # Fix PHP code style (Laravel Pint)
```

### Testing

```bash
php artisan test                            # Run all tests
php artisan test --filter=ExampleTest       # Run a single test class
php artisan test tests/Feature/ExampleTest.php  # Run a specific file
./vendor/bin/phpunit                        # PHPUnit directly
```

## Architecture

### Dual-Frontend Pattern

The app serves two distinct frontends from one Laravel installation:

- **Admin panel** (`/admin/*`) — traditional Blade + server-side rendering with session auth
- **Public site** (`/{any?}`) — React SPA catch-all route, served from `resources/views/welcome.blade.php` as the root HTML shell

The React app lives entirely in `resources/js/` and is built by Vite to `public/build/`.

### API Layer

All public data endpoints are under `/api/v1/` (see `routes/api.php`). They are unauthenticated and return JSON. The React frontend reads from `VITE_API_URL` (default `http://localhost:8000/api/v1`). Sanctum token auth protects only the user profile endpoint.

### File Storage Strategy

`app/ResourceUpload.php` centralises all file upload logic. Files go to either:
- **Local** (`public/logos/`, `public/uploads/`) — dev default
- **Cloudflare R2** — production, credentials via `CLOUDFLARE_R2_*` env vars, public URL via `CLOUDFLARE_R2_PUBLIC_URL`

Use the helpers in `ResourceUpload.php` rather than calling `Storage::` directly so the storage target stays consistent.

### Response Helpers

`app/Helper.php` provides `sendSuccessResponse()` and `sendErrorResponse()` for all JSON API responses. All controllers should use these instead of constructing `response()->json()` manually.

### No Service/Repository Layer

Business logic lives directly in controllers under `app/Http/Controllers/Backend/`. There is no service or repository abstraction — keep new logic in controllers unless complexity clearly warrants extraction.

### Authentication

| Surface | Mechanism |
|---|---|
| Admin panel | Session (form login via `AuthController`) |
| API endpoints | Laravel Sanctum tokens |
| Public API | None (open) |

## Key Configuration

| Env var | Purpose |
|---|---|
| `VITE_API_URL` | React app's API base URL |
| `DB_CONNECTION` | `sqlite` (dev) or `mysql` (prod) |
| `CLOUDFLARE_R2_*` | R2 bucket credentials and public URL |
| `MAIL_MAILER` | `log` in dev; configure for prod email |
| `SESSION_DRIVER` / `QUEUE_CONNECTION` / `CACHE_STORE` | All `database` by default |

## Testing Notes

Test suites are in `tests/Feature/` and `tests/Unit/`. The `phpunit.xml` overrides env to use array drivers (cache, mail) and sync queue so tests don't need external services. Coverage is minimal — only Laravel's example tests exist currently.
