# CLAUDE.md

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

## Commands

```bash
# Development
npm start                    # Serve with local config
npm run start:develop        # Serve with develop environment
npm run start:recette        # Serve with recette (staging) environment

# Build & Watch
ng build                     # Production build
npm run watch                # Build with file watching (development)

# Testing
ng test                      # Run tests with Karma/Jasmine

# Formatting
npm run format               # Format all JS/TS/HTML files with Prettier
```

## Architecture Overview

Angular 19 standalone API project (no NgModules). All components use `standalone: true`. Lazy loading via `loadChildren`/`loadComponent` throughout routes.

### Path Alias
`@/*` maps to `src/app/*` — use this for all imports within the app.

### Key Structural Patterns

**Base Classes (`src/p_modules/`)** — The core reuse pattern:
- `@services/crud.service.ts` — `BaseCrudService<T, ID>`: Abstract generic CRUD service. All methods return `Observable<HttpResponse<T>>`. Includes `create`, `update`, `getById`, `getAll`, `delete`, `getAllPaginated`, `search<C>`, `patch`, `exportPdf`, `exportExcelFileTemplate`, `importDataFromExcel`. Auto-shows success/error toasts.
- `@bases/base-list.component.ts` — `BaseListComponent<T, ID>`: Abstract directive for list pages. Subclasses implement `getColumns()`, `getTableActions()`, `getGlobalActions()`. Provides `data[]`, `columns`, `actions`, `globalActions`, `deleteConfirm()`, `navigateToView/Create/Edit()`, `onPageChange()`.
- `@bases/base-create-or-update.component.ts` — `BaseCreateOrUpdateComponent<T, ID>`: Abstract directive for **dialog/modal** create+edit forms (PrimeNG DynamicDialog). Override `initializeForm()` to create `this.form`, declare `formFieldsConfig = (form) => SectionedFormField[]`. Edit mode auto-detected from `DynamicDialogConfig.data`. Default `onSubmitSuccess()` closes dialog — override to customize.
- `@bases/base-create-or-update-page.component.ts` — `BaseCreateOrUpdatePageComponent<T, ID>`: Abstract directive for **full-page route** create+edit forms. Reads `:id` from route params, provides `isLoading`, `isEditMode`, `pageTitle`, `submitButtonText`. Override `onCreateSuccess()`/`onUpdateSuccess()` to customize (default: `location.back()`).
- `@bases/base-details.component.ts` — `BaseDetailsComponent<T, ID>`: Abstract directive for detail/view pages. Loads entity by ID from URL params. Subclasses declare `detailsConfigStatic: DetailsConfig`.

**Dynamic UI (`src/app/shared/dynamics/`)** — Configuration-driven components:
- `TableComponent` — Accepts `columns`, row actions, global actions, pagination config
- `FormComponent` — Dynamic form builder with validators
- `DetailsComponent` — Generic entity detail display
- 10+ reusable input components (text, select, date, file, autocomplete, etc.) using `FieldTypes` enum

**Auth (Angular Signals)** — `AuthService` uses `signal()`/`computed()` for reactive state. Token stored in `sessionStorage.authToken`. JWT decoded via `jwt-decode`.

### HTTP Interceptors (registered in `app.config.ts`)
1. `authInterceptor` — Adds `Authorization: Bearer` header from `sessionStorage.authToken`
2. `errorInterceptor` — Catches `HttpErrorResponse`, extracts `ProblemDetailWithCause` chain, shows error toast
3. `loaderInterceptor` — Shows/hides `ngx-spinner` on every request

### Routing Structure
```
/auth           → Auth layout (login, register) — public
/               → AppLayout, protected by authGuard
  /users        → User CRUD (list, details, create)
  /profiles     → Profile management
  /ecommerce    → E-commerce module
  /apps         → Feature apps (blog, chat, kanban, mail, etc.)
  /uikit        → PrimeNG component showcase
```
`authGuard` checks `sessionStorage.authToken`, redirects to `/auth/login` if absent.

### Environments
Three environments (`local`, `develop`, `recette`) each define:
```typescript
{ production, identityBaseUrl, fileManagerBaseUrl, jobBaseUrl }
```

### Key Libraries
- **PrimeNG 19** — UI component library (MessageService for toasts, ConfirmationService, DialogService)
- **ngx-translate** — i18n, French default (`TranslateModule` imported globally)
- **ngx-spinner** — HTTP loading indicator
- **ngx-mask** — Input masking
- **TailwindCSS + PrimeUI** — Styling

### Creating a New Feature (typical pattern)
1. Create a service extending `BaseCrudService<Model, ID>` — declare `apiUrl` and `entityName`
2. Create a constants file with columns (`TableColumn[]`), form fields (`(form, data?) => SectionedFormField[]`), details config (`DetailsConfig`)
3. Create list component extending `BaseListComponent<Model, ID>` — implement `getColumns()`, `getTableActions()`, `getGlobalActions()`
4. Create form component extending `BaseCreateOrUpdateComponent<Model, ID>` — override `initializeForm()` to build `this.form`, declare `formFieldsConfig`. For async select data, call `super.ngOnInit()` first then load data and refresh `this.formFields`
5. Create details component extending `BaseDetailsComponent<Model, ID>` — declare `detailsConfigStatic`
6. Add lazy-loaded routes under `src/app/pages/` and register in `app.routes.ts`

### Async select data pattern (e.g. loading options for a select field)
```typescript
override ngOnInit(): void {
    super.ngOnInit(); // creates form, patches edit values
    this.loadOptions();
}
private loadOptions(): void {
    this.someService.getAll().subscribe(res => {
        this.options = res.body || [];
        this.formFields = this.formFieldsConfig(this.form); // refresh with loaded options
    });
}
```
