# Încărcări și mărimi

Cât de mare poate fi o cerere, cum se încarcă o poză sau un document, ce tipuri de fișier se acceptă și unde ajung fișierele.

## Pe scurt

| Ce trimiți | Rută | Cum | Mărime maximă | Tipuri |
| --- | --- | --- | --- | --- |
| Corp JSON obișnuit | orice rută | `application/json` | 1 MiB (1 048 576 octeți) | — |
| Poza de profil | `PUT /v1/profil/poza` | `multipart/form-data` | 5 MB | JPEG, PNG, WebP |
| Poza unui angajat | `PUT /v1/angajati/:id/poza` | `multipart/form-data` | 5 MB | JPEG, PNG, WebP |
| Poza unei fișe „Vânzare Produse SH” | `POST /v1/vanzare-sh/poze` | `multipart/form-data` | 15 MB | JPEG, PNG, WebP |
| Factură primită, de scanat | `POST /v1/facturi/scanare` | JSON, fișier în base64 | 9 000 000 de caractere base64 | JPEG, PNG, WebP, PDF |
| Document atașat unei tranzacții | `POST /v1/evidenta/tranzactii/:id/documente` | `multipart/form-data` | 10 MB | PDF, JPEG, PNG, WebP |

Un MB aici înseamnă 1 048 576 de octeți.

## Corpul JSON

Serverul nu își schimbă limita implicită a cadrului (Fastify): un corp mai mare de 1 MiB primește `413`. Doar rutele care au nevoie de mai mult își declară propria limită, ca în tabelul de mai sus.

```json title="Răspunsul la un corp prea mare"
{ "eroare": "cerere invalida" }
```

## Încărcări `multipart/form-data`

Pozele de profil, pozele angajaților, pozele „Vânzare Produse SH” și documentele din evidență se trimit ca formular `multipart/form-data`, cu **un singur fișier**. Serverul ia primul câmp care are `filename`; restul se ignoră.

```bash title="Poza de profil"
curl -X PUT https://app.ilustromania.com/nucleu/v1/profil/poza \
  -H "Cookie: __Host-sesiune=$JETON_SESIUNE" \
  -F "poza=@eu.jpg"
```

Tipul se recunoaște **după primii octeți ai fișierului**, nu după extensie și nici după tipul declarat în cerere. Un `.jpg` care nu e de fapt JPEG este refuzat.

| Răspuns | Când |
| --- | --- |
| `400 fara_poza` / `400 fara_fisier` | corpul nu are niciun fișier |
| `400 nu_e_imagine` / `400 tip_neacceptat` | fișierul nu e de un tip acceptat |
| `413 poza_prea_mare` / `413 prea_mare` | fișierul trece de limită |
| `403 interzis` | nu ai acces la firmă sau dreptul de scriere |

## Încărcări în base64

Pozele produselor și facturile de scanat se trimit în JSON, cu fișierul codat base64. Base64 crește mărimea cu o treime, de aceea limita corpului e mai mare decât a fișierului (21 MB de corp pentru 15 MB de poză).

```json title="Poza unui produs"
{ "continut": "<base64>", "nume": "ciorba.jpg" }
```

```json title="Factură de scanat"
{ "tip": "application/pdf", "date": "JVBERi0xLjcK...", "nume_fisier": "factura.pdf" }
```

- La scanare, `tip` trebuie să se potrivească cu octeții fișierului; altfel `415 tip_nepotrivit`. Un PDF trebuie să înceapă cu `%PDF` (în base64, `JVBERi0`).
- La pozele de produs, doar sloturile pozelor reale primesc fișier de mână; un slot AI dă `400 slot_fara_upload`.
- O poză de produs pe care serverul nu o poate citi dă `400 poza_refuzata`, cu motivul în `mesaj`.

## Ce face serverul cu poza

- **Poza de produs** se transformă în WebP (calitate 80), în două mărimi, cu fundal alb; originalul se păstrează separat.
- **Poza „Vânzare Produse SH”** se transformă în JPEG (calitate 85).
- Imaginile de peste 80 000 000 de pixeli sunt refuzate, oricât de mic ar fi fișierul.

## Unde se păstrează fișierele

| Fișier | Unde | Observații |
| --- | --- | --- |
| Poza de profil și a angajaților | pe disc, în dosarul pozelor de profil (`PROFIL_POZE_DIR`, implicit `/var/lib/platforma/profil-poze`) | nume aleator; la „Scoate poza” fișierul se mută în arhivă, nu se șterge |
| Poza „Vânzare Produse SH” | pe disc, `VANZARE_SH_POZE_DIR` (implicit `/var/lib/platforma/profil-poze/vanzare-sh`) | — |
| Pozele produselor | pe disc: dosarul servit, dosarul originalelor și coșul (`/srv/poze-produs`, `/srv/poze-produs-orig`, `/srv/poze-produs-cos`) | ștergerea mută în coș |
| Factura scanată | pe disc, sub `FACTURI_DOCUMENTE_DIR`: întâi temporar 2 ore, apoi la aprobare în `<firmă>/facturi_primite/<an>/` | calea o alege serverul, niciodată clientul |
| Documentele din evidență | în baza de date | fără ștergere: „scoate” doar le arhivează |

> [!NOTE]
> Pozele de profil și ale angajaților se scriu pe disc abia după ce serverul a verificat accesul la firmă. O cerere fără drept nu lasă niciun fișier în urmă.
