# CLAUDE.md

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

## Stack

- **Backend:** Laravel 11 / PHP 8.1+ / MySQL (InnoDB, utf8mb4)
- **Frontend:** Blade templates + Livewire 3, Bootstrap via Laravel UI
- **Build:** Vite 4 — assets output to `public/assets/`
- **Real-time:** Pusher + Laravel Echo
- **Auth:** Session-based (web guard) + Spatie `laravel-permission` (RBAC) + magic link auth
- **Queue:** Database driver, single worker via CRON (`queue:work --stop-when-empty`)

## Commands

```bash
# Install
composer install && npm install

# Frontend
npm run dev          # Development (Vite HMR)
npm run build        # Production

# Tests
php artisan test                    # all tests
php artisan test --filter TestName  # single test

# Code style
vendor/bin/pint

# Database
php artisan migrate
```

## Architecture

### Domain

Event/conference management platform (Mediknode). Key entities: **Event**, **User**, **Participant** (pivot between User and Event), **Abst** (abstracts), **Workshop**, **Document**.

### Multi-subdomain routing

Routes split by subdomain (`APP_FRONTEND_SUB_DOMAIN`, `APP_BACKEND_SUB_DOMAIN`):
- **Frontend** (`events.*`): Public event pages, 7-step registration forms, abstract submission, payments
- **Backend** (`my-events.*`): Admin dashboard, event/participant management, campaigns

Route groups in `routes/web.php` use domain-based grouping, with controllers in `Frontend/` or `Backend/` subdirectories.

### Multi-instance environments

Multiple `.env.*` files (`.env.mediknode`, `.env.corporatnode`, `.env.jpt`, etc.) loaded at bootstrap time based on server port in `bootstrap/app.php`. Never commit `.env` files.

### Key patterns

- **Meta pattern:** `User` and `Participant` have `hasMany(Meta)` for dynamic attributes — pending metas are collected then bulk-saved via `booted()` hook
- **Observer audit logging:** `UserObserver`, `ParticipantObserver`, `ParticipantWorkshopObserver`, `DocumentObserver` log create/update/delete to `audits` table with changed JSON
- **Service layer:** Business logic in `app/Services/` registered as singletons in `AppServiceProvider` (e.g., `ParticipantRegistrationService`, `PaymentService`, `PDFGenerationService`)
- **Export/Import:** `maatwebsite/excel` — exports in `app/Exports/`, imports in `app/Imports/`
- **PDF generation:** DomPDF (`barryvdh/laravel-dompdf`) + FPDF/FPDI for advanced manipulation

### Participants module (in migration)

Migrating from old `ManageController` to new `ParticipantController` + Livewire 3. Both coexist — old routes under `/manage/`, new under `/participants/`.

### Mailing module

Campaign-based email system with templates, recipient tracking, and rate limiting.

## Code Style

### PHP / Laravel

- **Validation:** Inline `$request->validate()` in controllers — no Form Request classes
- **Responses:** `return view('...', compact(...))` + redirect with flash messages for mutations
- **Relationships:** Standard Eloquent `hasMany`/`belongsTo` — always define both sides
- **Locale:** French (`Carbon::setLocale('fr')`) — user-facing text and dates in French
- **Soft deletes:** Used on `User` model; not universally applied
- **Database engine:** InnoDB forced globally via `AppServiceProvider`

### Views

- **Layout:** `resources/views/backend/layouts/master.blade.php` with partials (head-css, sidebar, topbar, vendor-scripts, etc.)
- **Naming:** Snake_case folders (`access_codes/`, `event_badges/`), standard CRUD files (`index`, `create`, `edit`, `show`)
- **Livewire:** `@livewireStyles` in head-css partial, `@livewireScripts` in vendor-scripts partial; Livewire views in `resources/views/livewire/backend/`
- **Pattern:** `@extends('backend.layouts.master')` + `@section('content')` / `@yield('content')`

## Conventions

- **Routes:** Always named (e.g., `participants.index`, `campaigns.show`); multi-step forms use `step1`–`step7` suffixes
- **Controllers:** `app/Http/Controllers/Backend/` and `app/Http/Controllers/Frontend/`
- **Models:** All in `app/Models/`, all use `HasFactory`
- **Scheduled tasks:** Defined in `app/Console/Kernel.php` — queue worker every minute, sitemap daily at 2 AM
- **Middleware:** `role` and `permission` from Spatie; standard Laravel `auth`, `guest`, `throttle`
