# EcoFresh CRM — specifica e mockup

**28 ottobre 2026 · v1 · Gabi → Ifrim / EcoFresh Group Solutions SRL**

Un'app sola (PWA, quindi anche "app" sul telefono senza Play Store) dove Ifrim tiene clienti, interventi,
rapel-uri, PV, incassi e tutto quello che oggi scrive sul foglio *DDD Digital* e su WhatsApp.

Mockup navigabile: `mockup/index.html` · Tavola completa: `mockup/board.png`

---

## 0. In una riga

> Oggi il lavoro vive in **un foglio Google** (che si rompe), in **un'agenda Easy!Appointments**, in
> **WhatsApp** e su **PV di carta** numerati a mano. Il CRM mette insieme queste quattro cose in
> un'app da telefono, e in più fa da sola la cosa che oggi costa più tempo: **sa quando un cliente deve
> tornare** e gli scrive.

---

## 1. Cosa ho trovato (letto i dati veri, non solo il foglio)

### 1.1 Il foglio *DDD Digital*

- 13 schede: una per mese (gen–dic 2026) + `Test Firica` (riepilogo manuale) + `Sheet2`. Dati veri: **luglio → novembre**.
- **144 righe valide** (un intervento per riga), **63 clienti distinti** (per numero di telefono), 2 operatori:
  **Ifrim Damaris George (61 righe)** e **Mădălin Rotaru (78)**, 1 riga con entrambi.
- Servizi: Dezinsecție 134, Deratizare 5, Dezinsecție+Deratizare 4. Clienti: **Persoană Fizică 123 / Juridică 21**.
- Incassato dalla colonna *Sumă încasată* (solo righe `Efectuat`): **ago 14.514 · set 6.688 · oct 9.142 RON**.
  La scheda `Test Firica` riporta agosto **16.914 RON** (perché conta anche i programmati). Ordine di grandezza: **7–17k RON/mese**.
- Ticket: **media 320 RON, mediana 250 RON** (valori tipici 200 / 250 / 300 / 350).
- Stato: 107 `Efectuat`, 25 `Programat`, **7 `Anulat`**, 5 righe **senza stato**.
- Pagamenti nel foglio: **Cash 80**, **OP după intervenție 28**, `De setat` 7.

### 1.2 Il ciclo delle 3 visite (quello che si vede solo leggendo i dati)

Il foglio ha una colonna **`Primul/Rapel`** che appare solo in *alcuni* mesi (83 righe su 144 non ce l'hanno).
Dentro ci sono: `Prima Interventie` (11), `Rapel 1` (8), `Rapel 2` (5), `Rapel 3` (4).

Incrociando telefono + date:

| Cosa | Numero |
|---|---|
| Clienti con **1 sola** visita | 22 |
| Clienti con **2 visite** | 16 |
| Clienti con **3 visite** | **19** |
| Clienti con 4+ visite | 6 |
| Intervallo mediano tra due visite dello stesso cliente | **7 giorni** |
| Di cui entro 7 giorni | 48 su 66 |
| Entro 8–14 giorni | 13 su 66 |

Tradotto: **un cliente non è un intervento, è un ciclo**. Di solito 3 passaggi a ~7 giorni (a volte
7 / 7 / 7, a volte 10–14), poi **garanzia 30 giorni**. Il sito lo conferma: "Ploșnițe — 3 ședințe, la
14–21 de zile, garanție scrisă". Nel WhatsApp Ifrim lo dice con i soldi: *"două lucrări 450 lei x 3 și 250 lei x 3"*.
Quindi il valore di un cliente è **3 × prezzo seduta** (600–1.350 RON), non una volta sola.

Il foglio questo **non lo sa**: la relazione "queste 3 righe sono lo stesso trattamento" esiste solo
nella testa di Ifrim. **Questo è il cuore del CRM.**

### 1.3 Cosa si perde nel foglio (verificato riga per riga)

| Problema | Quanto | Perché fa male |
|---|---|---|
| Data, ora **e indirizzo nella stessa cella** (`"28.10.2026 - 16:30/Strada Berzei 26K, Tunari"`) | 128 righe su 144 | Non puoi ordinare per ora, né mandare l'indirizzo al navigatore, né sincronizzare il calendario |
| `Sumă încasată` con testo libero: `free`, `GARANȚIE`, `PRIMA INTERVENTIE GRATIS`, `stabilesc la fata locului`, `6 apartamente` | 10 righe | Gli incassi non tornano, i conti a fine mese si fanno a mano |
| Superficie come testo: `2 CAMERE`, `60mp`, `40.0`, `zone comune` | 131 righe | Il prezzo non si può calcolare dal listino (200/250/300) |
| `Nr. contract` compilato | 33 su 144 | Per un controllo DSP o per un cliente PJ non hai il contratto collegato |
| `Data semnării` compilata | 4 su 144 | Idem |
| Colonna `Primul/Rapel` esiste solo in alcuni mesi | 83 righe senza | Il ciclo delle 3 visite non è un dato, è un'ipotesi |
| Stesso cliente scritto in modi diversi (`Ionescu Andreea`, `PF CIUREA MIHAELA`, `Marin Marius` / `Marin Marius garanție`) | vari | Doppioni, storico spezzato |
| Righe duplicate (es. SUGLETWO 3 volte, blocco 142 più volte) | alcune | Incassi e conteggi gonfiati |
| Nessuna colonna "pagato / neîncassat / bon fiscal" | — | Non sai chi ti deve soldi |

### 1.4 WhatsApp — com'è oggi il lavoro vero

Letto gruppo interno *EcoFresh Group SRL*, gruppo *PV - URI*, chat dirette con Ifrim:

- **Il capo assegna i task in chat**, non in un sistema:
  *"@Ifrim de făcut factura lu aleksandra de pe calea Griviței"*, *"de făcut procesul verbal la 5 to go"*,
  *"De programat ALEKSANDRA de la calea Griviței"*, *"la intervenția asta de dimineață, doamna dorește bon și proces verbal"*,
  *"@Ifrim când ai timp să faci pv-urile lu sabin și lu aia din Bd Ghencea"*.
  → **Task-uri care se pierd** e che trebuie ricopiati a mano nel foglio.
- **I PV si fotografiano e si postano in un gruppo** (`PV - URI`, creato la fine di ottobre: *"Aici se vor posta copiile proceselor verbale"*).
  Le foto mostrano il modulo cartaceo **seria EFG-DDD nr. 0001…0005**, compilato a mano: data, ore,
  agent, beneficiario, **CUI/CNP**, nr. contract, indirizzo, suprafață, servizio (Dezinsecție /
  Dezinfecție / Deratizare), **grad de infestare** (Scăzut / Mediu / Ridicat), tabella prodotti con
  **aviz/autorizzazione** (i14 Cytrol `4209BIO/18/12.26`, Cytrol Forte WP, Advion Gândaci Gel, Vertox
  Pasta Bait, Rodex, K-Othrine SC 25, Buglea, MaxForce IC Gel, Racumin Foam), concentrazione/doză,
  cantitate, osservazioni, **"redarea spațiului"** (quando il cliente può rientrare), firma agente + firma cliente.
  → È il documento che vale in un **controllo DSP**. Oggi esiste solo come foto su WhatsApp.
- **Pressione DSP reale**: *"Chineji au nevoie de contract mâine… peste 2 zile au control DSP… trebuie să mergem la ei"*.
- **Il cliente scrive su WhatsApp**: foto dell'infestazione, indirizzo in testo, *"doamna dorește bon și proces verbal"*.
- Ifrim manda anche screenshot di Ads, profili clienti, e **messaggi vocali** (0:36) — l'app non deve combattere WhatsApp: deve **scriverci dentro**.

### 1.5 Sito e ads

- `ecofresh-group.ro` ha **listino pubblico**: garsonieră 150–170, apartament 220, casă 320, spații mari 450 RON;
  **ploșnițe 600 / 750 / 900 / 1.050 RON per 3 ședințe**; asociații **16 lei/apartament** + **25 lei/stație**;
  igienizare tapițerii 30–400 lei. Garanție **30 giorni scritta**.
- Google Ads: **350 lei/zi** di budget su tutte le campagne (dichiarato), con giorni a **120 lei → 2 lavori**
  da 450×3 e 250×3. Il costo per cliente si può misurare solo se il CRM sa **da dove viene** il cliente.
- `/programari/` = **Easy!Appointments** (versione recente: ha API token, **webhook**, CalDAV, LDAP,
  data retention). Ha la lingua sbagliata (stringhe in italiano, titolo perfino in cinese): da sistemare in rumeno.

---

## 2. Cosa costruiamo

### 2.1 I moduli (MVP)

| # | Modulo | Cosa fa | Perché |
|---|---|---|---|
| 1 | **Clients** | anagrafica, PF/PJ, CUI/CNP, telefono, indirizzo **strutturato** (strada, nr, bloc, sc, ap, et, sector, località), m²/camere, listino, metodo di pagamento, fonte, note, tag | il foglio diventa un database |
| 2 | **Locații** | un cliente può avere più indirizzi (associazioni: 44 ap, 10 ap, zone comune) | oggi finisce tutto nel nome del cliente |
| 3 | **Tratamente (ciclu)** | 3 ședințe, intervallo configurabile (7/10/14 gg), prezzo a seduta o a pacchetto, garanzia 30 gg | **il cuore** |
| 4 | **Intervenții** | data/ora, agente, servizio, stato, prezzo, prodotti + avize + doze, grad de infestare, osservazioni, redarea spațiului, foto, firma | dati veri, non testo libero |
| 5 | **Agendă** | giorno/settimana, per agente, drag per riprogrammare, sync con Easy!Appointments | una sola agenda |
| 6 | **Rapel & restanțe** | chi devi richiamare oggi, chi è in ritardo, chi ha annullato, garanzie | il tempo che oggi si perde a memoria |
| 7 | **PV + Registru DDD** | PDF dal modulo reale, **numerazione seria EFG-DDD senza buchi**, registro per cliente, PACCHETTO DSP | il rischio più grosso (controllo DSP) |
| 8 | **Bani** | cash/OP, da incassare, factură, bon fiscal, segnalazione "PV fără document fiscal" | chi mi deve soldi |
| 9 | **Rapporti** | mensile: incassato, interventi, per agente, per servizio, ticket medio, costo/lead da Ads | decisioni, non sensazioni |
| 10 | **WhatsApp** | modelli pronti + un tap per aprire la chat col messaggio già scritto; (fase 3) invio automatico | è il canale di Ifrim |
| 11 | **Impostazioni** | listino, prodotti autorizzati, seria PV, **utenti e permessi**, backup, export GDPR | gestione senza Gabi |
| 12 | **Sarcini (task)** | task liberi con assegnazione, scadenza, stato; nascono anche da un messaggio WhatsApp | quello che oggi vive nel gruppo WhatsApp (§16) |
| 13 | **Onboarding e aiuto** | primo avvio guidato, un solo suggerimento alla prima visita di ogni schermata, „?" sempre disponibile | l'app si spiega da sola a ogni nuovo assunto (§15) |
| 14 | **Client din WhatsApp** | screenshot della conversazione → dati estratti → conferma | aggiungere un cliente in 10 secondi (§20) |

> **Come** sono fatte le schermate (le due velocità, le 12 regole, cosa fanno i concorrenti): vedi **§13**.

### 2.2 Cosa produce da sola (senza che Ifrim scriva niente)

1. **Il prossimo appuntamento** del ciclo, quando chiude quello di oggi (con l'ora abituale del cliente).
2. **La lista "de sunat azi"** (rapel in scadenza + garanzie) con il messaggio già scritto.
3. **Il PV in PDF** appena firma il cliente, con numero di serie progressivo e foto allegate.
4. **Il registro delle operazioni** per cliente e per periodo (quello che oggi è carta).
5. **Il pacco DSP**: ZIP con contract, tutti i PV, registro, schede tecniche dei prodotti usati, PV deșeuri periculoase.
6. **Il conto del mese**: incassato per agente/servizio, e quanto è costato un cliente da Google.

---

## 3. Come si usa (una giornata)

**07:30 — in macchina.** Apre l'app (icona sul telefono, come le altre). Vede: 5 interventi, 1.220 lei da incassare,
3 rapel da programmare. Tocca *Rapel* → Ionescu Andreea ședința 3/3 → *WhatsApp* → il messaggio è già scritto
("Ședința 3 din 3 este programată vineri 7 noiembrie, ora 13:00. Vă convine?") → invia. 20 secondi.

**11:20 — sul posto.** Apre il cliente, *Ședința 2/3*, mette il servizio, il grado di infestazione, i prodotti con
le dosi (i 10 prodotti autorizzati sono già in lista: sceglie, non scrive), due foto **înainte / după**,
scrive l'ora di **redarea spațiului**, il cliente firma col dito. *Finalizează* → PV 0007 pronto → *Trimite pe WhatsApp*.

**21:00 — a casa.** Apre *Bani*: cash di oggi, 3 fatture OP da incassare, 1 PV senza bon fiscal. Fine. Nessun foglio.

**Il cliente che sparisce** ("pleacă în vacanță, ne sună când se întorc" — successo davvero a Izabela L.):
l'intervento va in **Amânate**, non si perde, e ricompare in lista quando torna.

---

## 4. Easy!Appointments: 3 strade, una consigliata

| Opzione | Come | Pro | Contro |
|---|---|---|---|
| **A. EA resta, CRM si collega** ⭐ | la pagina pubblica `/programari/` resta EA; quando arriva una prenotazione, EA manda un **webhook** al CRM (o il CRM legge/scrive via **API token**) | zero lavoro sul lato clienti, niente doppio calendario | due sistemi da tenere vivi; i clienti esistono in due posti → li sincronizza il CRM |
| **B. EA solo come widget** | il CRM gestisce tutto, la pagina pubblica diventa una pagina del CRM | un solo sistema | da rifare il frontend di prenotazione |
| **C. Google Calendar in mezzo** | EA ↔ Google Calendar ↔ CRM (iCal) | Ifrim vede gli appuntamenti sul calendario del telefono | latenza, e la logica delle 3 sedute non ci sta |

**Consiglio: A.** EA ha già i webhook e l'API con token: sono 30 righe di codice, e Ifrim continua a
ricevere le prenotazioni online. In più correggiamo la lingua di EA (ora è in italiano).

---

## 5. WhatsApp: 3 livelli, partiamo dal più economico

| Livello | Cosa dà | Costo | Quando |
|---|---|---|---|
| **0 — link + modelli** ⭐ | `wa.me` con messaggio precompilato: conferma, promemoria, rapel, istruzioni+PV, richiesta recensione | **0** | MVP |
| **1 — WhatsApp Business App** | catalogo, risposte rapide, etichette, messaggi automatici fuori orario | 0 | subito, lo usa già |
| **2 — WhatsApp Cloud API (Meta)** | messaggi **automatici**: promemoria 24h prima, rapel, recensione post-ședința 3. Numero verificato | ~0,01–0,05 €/messaggio template | fase 3 |
| 3 — "inbox" dentro la PWA | leggere/rispondere alle chat dall'app | richiede API ufficiale | solo con il livello 2 |

**Cosa non facciamo:** bridge non ufficiali (whatsapp-web.js e simili). Rischio ban del numero di lavoro, e il
numero è il canale con cui arrivano i clienti.

---

## 6. Dove vive l'app — sì, sul server di EcoFresh

Ho controllato:

- `ecofresh-group.ro` → `91.200.122.103`, **LiteSpeed**, HTTPS attivo, **PHP 8.3** (Easy!Appointments gira lì: quindi PHP + MySQL ci sono già).
- Quindi: **sottodominio `app.ecofresh-group.ro`** (o cartella `/crm/`), stesso hosting, **costo aggiuntivo 0**.
- Cron dell'hosting per i promemoria; certificato SSL sul sottodominio; backup giornaliero su **Google Drive dell'account EcoFresh**.

Se l'hosting condiviso mette limiti (spazio foto, cron ogni 5 min, PHP lento): un VPS da ~5 €/mese (Hetzner/Contabo)
con PHP+MariaDB, e il backup lo stesso su Drive. Non serve altro.

**PWA**: si installa dal browser ("Aggiungi a schermata Home"). Funziona **offline** in cantina/sottoscala:
salva l'intervento in locale, sincronizza quando torna il segnale. Foto compresse a 1600px sul telefono (spazio).

---

## 7. Dati e architettura (in breve)

**Stack**: PHP 8.3 senza framework (come gli altri progetti), MySQL/MariaDB, HTML/CSS/JS, service worker per l'offline,
PDF lato server (dompdf/mPDF), niente dipendenze esotiche. Il frontend è la PWA.

```
clients            (id, tip, nume, cui_cnp, tel, email, sursa, note, creat)
locations          (id, client_id, eticheta, strada, nr, bloc, sc, ap, et, sector, oras, judet, mp, camere)
contracts          (id, client_id, nr, data, valabil_pana, tip: 3 sedinte / lunar / anual)
treatments         (id, client_id, location_id, serviciu, nr_sedinte, interval_zile, pret_sedinta, total, garantie_zile, stare)
interventions      (id, treatment_id, client_id, location_id, agent_id, start, end, serviciu, stare,
                    pret, grad_infestare, redare_spatiu, observatii, semnatura, pv_id, plata_id)
products           (id, nume, aviz, tip, unitate)          -- le 10 righe del PV cartaceo
intervention_products (intervention_id, product_id, doza, cantitate)
payments           (id, intervention_id, suma, metoda, data, bon_fiscal, factura_nr)
pv_documents       (id, serie, numar, intervention_id, pdf_path, creat)
photos             (id, intervention_id, client_id, tip: inainte/dupa/pv, path)
reminders          (id, client_id, intervention_id, tip: rapel/garantie/recenzie, data, stare)
messages_log       (id, client_id, tip_sablon, trimis_la, canal, stare)
users / roles      (admin / agent / marketing)
audit_log          (cine, ce, când)                        -- per DSP e per errori
```

**Sicurezza**: login con PIN/biometria del telefono, HTTPS obbligatorio, sessione con scadenza, ruoli
(agente vede solo i suoi clienti, admin tutto), log delle modifiche (chi ha cambiato un PV), backup cifrato.
**GDPR**: i dati dei clienti e le foto delle case sono dati personali → export e cancellazione per singolo cliente,
retention configurabile, informativa già presente sul sito da collegare.

---

## 8. Fasi e tempi (lavoro mio, indicativo)

| Fase | Cosa | Tempo | Risultato |
|---|---|---|---|
| **0** | decisioni + accessi (hosting, EA admin, account Google) + sottodominio | 2–3 h | si parte |
| **1 — MVP** | clienti/locații/interventi, agendă, **ciclu 3 ședințe + rapel**, **PV PDF numerato**, incassi base, PWA installabile, import del foglio | **2–3 settimane** | Ifrim lavora solo dall'app |
| **2** | foto + firma su schermo, garanzie, pachet DSP, rapporti, WhatsApp templates, sync EA (webhook) | 2 settimane | si stacca dal foglio |
| **3 — opzionale** | WhatsApp Cloud API (promemoria e recensioni automatiche), magazzino/consumo prodotti e costo per intervento, mappa/percorsi, preventivi online | 2 settimane | scala |

**Cosa serve da Ifrim** (mezz'ora, non di più): accesso hosting, admin Easy!Appointments, dire chi usa l'app e con che ruolo,
confermare il listino (sito vs foglio), dire chi fa le fatture oggi (e se `e-Factura` passa da un altro software).

---

## 9. Costi

| Voce | Costo |
|---|---|
| Hosting (stesso di ecofresh-group.ro) | **0** |
| Dominio | già pagato |
| Backup su Google Drive | 0 |
| VPS, solo se l'hosting non regge | ~5 €/mese |
| WhatsApp Cloud API (fase 3) | ~5–15 €/mese a questo volume |
| Sviluppo | il mio tempo |

---

## 10. Cosa **non** facciamo (per non fare un mostro)

- Niente contabilità completa: le fatture restano dove sono (e-Factura); il CRM traccia solo *se* e *quando* sono state fatte.
- Niente inbox WhatsApp non ufficiale.
- Niente app nativa / Play Store: PWA basta e si aggiorna da sola.
- Niente AI "che parla col cliente": le risposte se le scrive Ifrim, noi gli diamo il testo già pronto.
- Niente multi-azienda / multi-lingua. Una azienda, una lingua, e si fa bene.

---

## 11. Decisioni prese (29 ottobre) — e cosa resta da chiedere a Ifrim

Le sei domande sono chiuse, tranne due che **diventano parte dell'onboarding** (non bloccano lo sviluppo).

| # | Domanda | Risposta | Cosa cambia |
|---|---|---|---|
| 1 | Chi entra nell'app | **Ifrim + Mădălin + chiunque verrà assunto**, ognuno col suo ruolo. **Gli incassi li vede solo Ifrim**; da *Impostazioni → Utilizatori* decide lui chi vede cosa | serve un modello ruoli/permessi (§14), non un'app mono-utente |
| 2 | PV digitale o carta | **Cartaceo**: Ifrim li stampa ogni giorno, poi la copia va su WhatsApp. L'app genera il PDF, **stampa in blocco i PV del giorno** e archivia | la firma su schermo è un extra, non un sostituto del foglio (§18) |
| 3 | Easy!Appointments | **Opzione A** confermata: la pagina pubblica resta, il CRM riceve le prenotazioni via webhook | zero lavoro lato cliente |
| 4 | WhatsApp | **Livello 0 e 1 subito** (link + modelli + WhatsApp Business), Cloud API in fase 3 | nessun costo nella prima versione |
| 5 | Listino | **Lo decide Ifrim durante l'onboarding** (il sistema gli mostra sito vs foglio e lui sceglie) | non è più un blocco: è un passo guidato |
| 6 | Fatture / e-Factura | **Lo dice Ifrim a fine onboarding**, con un pulsante che gli apre WhatsApp verso Gabi | il flusso non si spezza: domanda alla fine, non all'inizio (§18) |

**Altre decisioni arrivare in questa conversazione:**

| Tema | Decisione |
|---|---|
| Origine cliente | **Google è il default**; Ifrim segna solo se il cliente è arrivato **da altro** (passaparola, Facebook, cliente storico) |
| Dati mancanti | Al primo accesso Ifrim ha **un task vero**: completare i dati che il sistema non conosce, guidato passo passo (§15) |
| Foto | **Non obbligatorie** (mai bloccare la chiusura di un intervento per una foto) |
| Documenti fiscali | **Non obbligatori**: può esistere un intervento senza bon fiscale o fattura. Il CRM lo segnala, non lo impedisce |
| Navigazione | un tocco → **Waze / Google Maps / Apple Maps** secondo il telefono e la preferenza dell'utente (§19) |
| Nuovo cliente | si può creare **da uno screenshot della conversazione WhatsApp**: il sistema estrae e lui conferma (§20) |
| Tono dei messaggi | formale, „dumneavoastră", mai „Vă convine?" → *„Este în regulă pentru dumneavoastră…?"* (§21) |
| Backup | **codice su GitHub privato di Gabi**, dati sul server + dump cifrato su Drive (§22) |
| Rischio "lo segno dopo" | **ritirato**: Ifrim è rigoroso. Il rischio vero è opposto — che l'app sia **meno precisa** della sua disciplina (§13.5) |

---

---

## 12. Allegati

| File | Cosa |
|---|---|
| `mockup/index.html` | mockup navigabile, 13 schermi (12 + `#captura` = mod rapid), in rumeno |
| `mockup/focus.html` | mockup **desktop** del mod Focus (tabella densa, pannello laterale, ⌘K) |
| `mockup/shots/onboarding • task • import • permisii.png` | le quattro schermate nuove: primo avvio, sarcini, client din screenshot, utenti e ruoli |
| `mockup/board.png` | tavola completa con tutti gli schermi |
| `mockup/shots/*.png` | i singoli schermi in PNG |
| `_wa_photos/img-07.jpg` | PV cartaceo reale (seria EFG-DDD 0005) usato come riferimento |
| `_data/*.tsv` | il foglio esportato scheda per scheda (base per l'import) |
| `_analysis/recs.json` | le 144 righe normalizzate (cliente, data, prezzo, agente) |

---

*Nota: i numeri di questa specifica vengono dal foglio `DDD Digital` al 28 ottobre 2026 e dal sito.
Le foto dei PV sono state lette dalla chat WhatsApp; le chat sono state aperte in sola lettura.*

---

# 13. Approfondimento UX — le due velocità (ricerca, regole, piano)

> Perché l'app deve essere **immediata sul campo** e **calma alla scrivania**, e come si progetta questa
> doppiezza senza fare due prodotti.

## 13.1 Come si chiama questa cosa

Non è "fare una bella interfaccia". Sono quattro discipline sovrapposte; il nome che le tiene insieme è
**interaction design a due regimi d'uso per lavoro sul campo**.

| Concetto | Cosa dice | Origine |
|---|---|---|
| **Minimal-attention UI (MAUI)** | chi lavora in piedi, in un sottoscala, con le mani occupate e una sola mano libera ha "attenzione minima": l'interfaccia deve chiedere il minimo sforzo cognitivo e **tollerare le interruzioni** (arriva una chiamata, si perde il contesto, si riprende) | ricerca HCI sul fieldwork (Pascoe, Ryan, Morse, *Using While Moving: HCI Issues in Fieldwork Environments*) |
| **Progressive disclosure** | mostra prima i 3–4 campi che servono nel 90% dei casi, il resto dietro un gesto chiaro e prevedibile. **Massimo 2 livelli**: oltre, l'usabilità crolla | NN/g, 1995 / 2006 |
| **Glanceable + defaults** | lo stato di una cosa si legge in 1 secondo; ogni campo ha un valore di default sensato, così il caso comune non si digita | NN/g (*Top 10 Application-Design Mistakes*: "No Default Values", "Meaningless Information") |
| **Job-centric, non data-centric** | l'unità di lavoro è "l'intervento di oggi", non "la tabella clienti". Il cliente è il contesto, il lavoro è il soggetto | pattern field service (Jobber, ServiceTitan, Housecall Pro) |

La parte opposta — il **lavoro profondo** — è il mondo delle *dense data apps*: tabella, tastiera, pannello
laterale, densità, filtri salvati, totali. Regole: NN/g (niente modali che coprono il contesto, niente ID
come prima colonna, niente menù "cassetto"), più i pattern resi standard da Gmail (densità
confortevole/compatta) e dalle palette ⌘K (Linear, Raycast, Vercel, con scope contestuale).

**La frase da tenere:** *due gusci, una verità*. Telefono = **fare**. Desktop = **capire**. Non
"responsive" (lo stesso schermo rimpicciolito): **due layout diversi** sulle stesse API, un solo codice
(PHP + HTML/CSS, CSS grid che cambia struttura sotto i 900px). Se sono due app, sono due manutenzioni.

## 13.2 Le 12 regole (operative, non poetiche)

| # | Regola | Come si verifica |
|---|---|---|
| **R1** | **Un solo livello 1 per schermata.** Una cosa sola urla (di solito: il prossimo gesto). Tutto il resto è livello 2 | guardando lo schermo da 1 metro si capisce cosa fare |
| **R2** | **Regola dei 3 tap.** Le 5 azioni quotidiane (intervento nuovo, chiudi+PV, incassa, rapel, cerca cliente) stanno in **≤3 tap** da qualsiasi schermata | conta i tap, cronometro |
| **R3** | **Zero tastiera nel caso comune.** Cliente, servizio, prezzo, prodotti dell'ultima volta, ora di rientro: già compilati. Si scrive solo quando c'è qualcosa di nuovo da dire | fai un intervento reale senza scrivere |
| **R4** | **Un dito, sotto il pollice.** Azione primaria nei 2/3 bassi, target ≥56px (guanti, mani bagnate, camminata), ≥8px tra "distruggi" e "conferma" | test in macchina, non in ufficio |
| **R5** | **Il contesto non si perde.** Ogni schermata mostra una riga *Chi · Dove · Cosa · Quanto · Stato*: si torna indietro senza ricostruire dove eri | interrompi a metà, riprendi: zero esitazione |
| **R6** | **Due livelli, mai tre.** Schermata → pannello/foglio. Modale **solo** per azioni distruttive. Niente menù "…" dove finiscono le cose importanti | cerca una funzione rara: max 2 passaggi |
| **R7** | **Ogni stato ha un aspetto:** vuoto, caricamento, offline, errore, "in coda". Barra offline con *"sei offline da 12 min · 3 in coda"* e coda visibile con `pending / uploading / failed` | metti la modalità aereo e lavora |
| **R8** | **Annulla invece di confermare.** Le azioni reversibili hanno "Undo" 5 secondi; la conferma si chiede solo per ciò che distrugge (PV, incasso, cancellazione) | nessun click su "Sei sicuro?" nel flusso normale |
| **R9** | **Riconoscere, non ricordare.** Suggerisci: prodotti dell'ultima volta, orario abituale del cliente, indirizzi recenti, "copia dall'ultima ședință" | dopo 20 interventi, l'app deve già sapere |
| **R10** | **Feedback concreto e ottimista.** Salva subito in locale, sincronizza dopo. Il messaggio dice la cosa vera: *"PV 0007 trimesso a Marin Marius"*, non *"Operazione completata"* | nessun "salvataggio in corso" che blocca |
| **R11** | **Numeri leggibili.** Cifre tabellari, valuta accanto al numero, allineamento a destra, ID (0007) **mai** in prima colonna | confronta due righe a occhio |
| **R12** | **Il modo Focus non è una skin.** Densità commutabile, tastiera, pannello laterale, filtri salvati, totali sticky, zero animazioni, zero pop-up | lavoraci un'ora senza chiudere niente |

## 13.3 Come lo fanno i concorrenti

| Prodotto | Cosa fa bene (da copiare) | Cosa insegna (da non copiare) |
|---|---|---|
| **Jobber** | lista "Today" con **status leggibile a colpo d'occhio** e filtro per stato; **banner offline con la durata** e una **Sync Queue** con `pending / uploading / failed`; clock in/out separato | — |
| **Housecall Pro** | **fotocamera rifatta**: le foto restano sul dispositivo finché non partono, la coda non blocca il lavoro; pagamento sul posto | — |
| **PestPac (WorkWave)** | offline "full native", scanner di codici e **stampa da telefono** (utile per il bon fiscale portatile) | recensito come **"dietro sull'esperienza utente e sullo scheduling dinamico"** ([recensione](https://connecteam.com/reviews/pestpac/), 6.8/10): la funzione non salva un prodotto scomodo |
| **ServiceTitan** | **dispatch board** drag&drop con **"Holding Area"** per i lavori non assegnati, filtri calendario/business unit/tipo/zona ([docs](https://help.servicetitan.com/docs/use-the-new-daily-and-weekly-dispatch-board)) | è la parte "ufficio": pesante, da usare con mouse. Al nostro volume sarebbe overkill da subito |
| **Pattern generali** | **densità commutabile** (Gmail confortevole/compatto), **palette ⌘K** con contesto (Linear/Raycast), densità e scorciatoie come "modalità esperto" | — |

**Il buco del mercato:** chi ha il back-office forte ha il mobile debole, e viceversa. I concorrenti
servono aziende con 10–50 tecnici e un ufficio che fa da tramite. EcoFresh è **2 persone, ~30 interventi al
mese, nessun ufficio**: possiamo permetterci di progettare bene **entrambi** i gusci, senza compromessi.
Questo è il vantaggio, ed è anche il motivo per cui non dobbiamo comprare un prodotto pronto.

## 13.4 Il piano

**Fase A — design (una settimana, già iniziata).**
Tre schermate chiave fatte: **mod rapid** (`mockup/index.html#captura`), **PV** (`#pv`),
**mod focus** (`mockup/focus.html`). Poi storyboard di 6 momenti reali (arrivo → durante → chiusura → PV →
incasso → rapel) e un **test "carta" con Ifrim da 10 minuti**: gli si mettono davanti i 3 schermi e si
chiede "cosa faresti qui?".

**Fase B — MVP.** Fast path completa (Start → *Am ajuns* → *Finalizează* → *Trimite PV*), **coda offline**,
PV PDF, incasso. Lato desktop, in MVP, solo **lettura + incasso** (niente tabelle complesse).

**Fase C — mod Focus completo.** Filtri salvati ("Neîncasate", "PV lipsă", "Rapel"), palette ⌘K, azioni in
massa (rimanda tutti i rapel al lunedì, manda PV a 5 clienti), densità.

**Criteri di accettazione (misurabili, non "mi sembra bello"):**

| Cosa | Target |
|---|---|
| Chiudere un intervento con PV (caso comune) | **≤ 45 s** e **0 caratteri digitati** |
| Trovare un cliente | ≤ 3 tap oppure ≤ 5 s digitando |
| Incassare | 1 tap dal pannello |
| Fast path con modalità aereo attiva | **100%** delle funzioni |
| A fine giornata: interventi con PV + foto + incasso | **≥ 80%** senza solleciti |
| Prezzo/servizio sbagliato | **0** (perché precompilato) |
| Apertura app su 3G | **< 1,5 s** |

**Come si misura (economico):** log eventi (apertura, tap, chiusura), tre numeri a settimana; un giro di
test guidato al mese **su un intervento reale** con Ifrim e tre domande ("cosa è stato lento?", "cosa hai
cercato?", "cosa hai fatto fuori dall'app?").

**Cosa non faremo (vietato):** tour/onboarding dentro l'app, più di 5 voci nella barra, campi obbligatori
non indispensabili, notifiche multiple, animazioni decorative, grafici in home, due app separate
telefono/desktop.

## 13.5 Rischio principale

Il doppio guscio può diventare **doppio prodotto** (due volte il lavoro, due volte i bug). Si evita con un
solo codice e due strutture CSS; i dati e le azioni sono gli stessi endpoint, cambia solo la messa in scena.

Il secondo rischio l'avevo scritto male. **Ifrim non è uno che "segna dopo": è rigoroso, si annota tutto.**
Il rischio vero è opposto — che l'app sia **meno precisa e meno comoda della sua disciplina attuale**, e che
quindi la usi a metà (foglio per i soldi, app per i PV). Per questo: (a) la fast path si prova **in macchina**
con il telefono in mano a lui, non in ufficio; (b) ogni funzione che lui fa già bene deve restare **più
veloce** nell'app, altrimenti non entra; (c) il primo task dell'app è **suo**: completare i dati mancanti
(§15), così la prima esperienza non è "compila un form", ma "l'app fa un lavoro per te".

---

# 14. Utenti, ruoli, permessi

L'app non è "di Ifrim": è **dell'azienda**, e ci entrano anche Mădălin e chi verrà assunto. Quindi i permessi
non sono un'aggiunta: sono la struttura.

## 14.1 Ruoli (modificabili da Ifrim)

| Ruolo | Chi | Cosa vede | Cosa può fare |
|---|---|---|---|
| **Admin** | Ifrim | tutto | tutto, compresi **incassi**, utenti, listino, serie PV |
| **Agent** | Mădălin, futuri tecnici | **solo i suoi clienti e i suoi interventi**, i suoi task | chiude interventi, genera PV, incassa (se abilitato), prende/cede task |
| **Birou** | Andreea | clienti, agenda, documenti | programma, crea clienti, manda PV, **non** vede gli incassi |
| **Marketing** | Gabi | clienti in sola lettura, **rapporti e dati Ads** | legge, esporta; nessun dato economico dei clienti |
| **Contabil** (futuro) | commercialista | fatture e documenti fiscali | legge/segna fatture; niente operativo |

**Regola d'oro:** *default = niente*. Ogni permesso è esplicito. I **dati di denaro** (incassi, costi,
margini, spesa Ads) sono un permesso separato da "vedere i clienti".

## 14.2 Come funziona in pratica

- **Matrice dei permessi** in *Impostazioni → Utilizatori*: righe = cose (incassi, prezzi, tutti i clienti, PV,
  rapporti Ads, eliminare, invitare), colonne = ruoli, pallini ✓/—. Ifrim cambia con un tocco (§ schermata
  `#permisii` del mockup).
- **Scope agenti:** un agente vede i clienti che gli sono assegnati o su cui ha un intervento. Può "passare"
  un cliente a un collega.
- **Invito:** link monouso, il nuovo utente sceglie password e PIN, poi parte il **suo** onboarding.
- **Audit:** chi ha modificato un PV/incasso e quando (`audit_log`). Serve per DSP e per i litigi interni.
- Se domani Ifrim vuole che Mădălin veda gli incassi: un toggle, 10 secondi, nessun intervento mio.

---

# 15. Onboarding "push" e aiuto contestuale

Il principio: **insegnare al momento giusto, non tutto prima**. Un tour forzato si dimentica; un aiuto nel
punto in cui serve si impara.

## 15.1 Tre livelli (dal più visibile al più discreto)

| Livello | Quando | Cosa | Dove |
|---|---|---|---|
| **1. Primo avvio** | una volta, al primo accesso | checklist di 4 passi (dati firma → listino → import clienti → come si fa un PV), interrompibile e riprendibile | schermata `#onboarding` |
| **2. Prima visita** | la prima volta che apre una schermata | **un solo** suggerimento in linea, una riga, dismissibile; se fa già l'azione giusta, sparisce da solo | in cima alla schermata |
| **3. „?" sempre** | quando vuole | pallino accanto ai campi non ovvi → pannello con 2-3 righe + esempio | ovunque nel form |

## 15.2 Regole

- Massimo **un** suggerimento per schermata, mai due.
- Nessun suggerimento **bloccante**: non copre mai l'azione principale, non chiede "ho capito".
- Ogni utente ha la sua memoria (`onboarding_state`: utente + passo + visto/non visto): Ifrim e Mădălin non
  vedono le stesse cose, e un assunto nuovo riparte dal livello 1 **solo per lui**.
- Se l'utente fa l'azione prima di arrivare al passo, il passo si segna fatto (**adaptive**).
- I testi dei suggerimenti stanno nel database, non nel codice: Ifrim li può riscrivere in rumeno senza di me.
- Tono: "te lo mostro una volta, poi lo trovi al „?"", mai paternalistico.

---

# 16. Sarcini: assegnare lavoro senza passare da WhatsApp

Oggi il lavoro si assegna nel gruppo: *"@Ifrim de făcut factura lu aleksandra"*, *"de făcut procesul verbal la 5 to go"*.
Quel messaggio è un task — solo che nessuno lo traccia. Quindi **il task è un oggetto di prima classe**, non
una nota dentro un intervento.

## 16.1 Cosa è un task

| Campo | Note |
|---|---|
| titolo | breve, imperativo: „Fă PV la 5 to go" |
| tipo | PV · factură · sună client · comandă produs · programare · verifică · altceva |
| legato a | cliente e/o intervento (facoltativo) |
| asignat | una persona (default: chi lo crea) |
| scadență | azi / mâine / săptămâna asta / data |
| stato | de făcut · în lucru · blocat · gata |
| extra | checklist, notă vocală, foto, promemoria |

## 16.2 Assegnazione in 2 tocchi

Scheda cliente o intervento → **„Asignează"** → scegli avatar (Mădălin / Andreea / George) → scadenza
(azi/mâine/săptămâna) → salva. Il task compare nella schermata **„Azi"** del destinatario e in *Sarcini*.

- Ifrim vede **tutti** i task, con un filtro per persona; ogni agente vede **solo i suoi**.
- Un task si **cede**: "nu ajung, ia-l tu" — un tocco, con traccia di chi l'ha passato.
- **Da WhatsApp**: in fase 3, il messaggio inoltrato all'app diventa un task (stesso estrattore degli
  screenshot, §21). In fase 1: si crea in 10 secondi, ed è comunque meglio del messaggio che si perde.
- Notifica: in-app subito; WhatsApp (template) in fase 3, non prima — non vogliamo due canali che litigano.

---

# 17. Google Ads dentro il CRM: cosa possiamo prendere e qual è il massimo teorico

## 17.1 Cosa sappiamo già (e va preso)

| Dato | Da dove | A cosa serve |
|---|---|---|
| spesa, click, impression, CPC, CTR | Google Ads (export o API) | costo reale del mese, per campagna e per giorno |
| campagne (Search per servizio, PMax) | Ads | capire **quale servizio** porta clienti |
| chiamate generate | Ads call reporting (se attivo) | lead telefonici attribuiti |
| lead / clienti nuovi | **il CRM** (Ifrim li segna) | il denominatore giusto: persone, non click |
| valore del cliente | CRM (3 ședințe × prezzo) | quanto vale un cliente, non solo quanto costa |
| fonte per cliente | **default Google**, corretto a mano se altro | attribution di base, onesta |

**Regola decisa:** nelle statistiche il numero di **clienti** è quello che Ifrim ha segnato nell'app. Ads
fornisce **spesa e traffico**, non "conversioni vere". Così i conti non si gonfiano.

## 17.2 I tre livelli

| Livello | Cosa si ottiene | Costo/sforzo | Quando |
|---|---|---|---|
| **1 — Attribuzione dichiarata** | CPL = spesa ÷ clienti nuovi segnati; CAC; ROAS = valore clienti ÷ spesa; per servizio e per mese | zero (solo il campo "sursă" nel cliente) | **MVP** |
| **2 — Call tracking** | un **numero dedicato per campagna** (o per servizio): il CRM sa quale chiamata veniva da quale campagna, e la abbina al cliente per numero | 2–5 €/mese per numero + 1 giorno di setup | fase 2 |
| **3 — Chiusura del cerchio** | conversione **offline** importata in Ads (Enhanced Conversions for Leads / import CSV con GCLID o telefono hashato) + **click-to-WhatsApp** con `ctwa_clid` da Cloud API | qualche giorno, serve Cloud API | fase 3 |

## 17.3 Il massimo teorico (e i suoi limiti)

**Massimo raggiungibile:** sapere, per ogni euro speso, **quanti clienti e quanti lei** ha prodotto — per
campagna, per servizio, per zona — e far ottimizzare a Google Ads il **cliente firmato**, non il click.
In pratica: ROAS per campagna, CPL per zona, CAC per servizio, e un export automatico che dice a Google
"questo lead è diventato un cliente da 750 lei".

**Quello che non si potrà mai avere:** il 100%. Restano fuori le chiamate da numero privato, chi chiama dal
telefono di un altro, il passaparola, chi vede il furgone per strada. Regola: nel report una voce
**"necunoscut / altă sursă"** sempre visibile, e la percentuale di copertura dichiarata (realistico: 85–90%).

**Con i numeri di oggi** (spesa dichiarata ~350 lei/zi ma non piena, ~26 lead/mese, 10 clienti nuovi):
CPL ≈ 230 lei, valore medio cliente ≈ 750 lei → **ROAS ≈ 3×**. Il numero vero lo dirà l'app; questo serve
solo a dire che la misura vale la pena.

## 17.4 Cosa vede Ifrim (e cosa no)

- **Ifrim**: spesa, clienti, CPL, ROAS — in una card del *Raport*, non in home (la home è per il lavoro di oggi).
- **Gabi (Marketing)**: il cruscotto completo, campagne e keyword; **non** i dati dei singoli clienti oltre il
  necessario.
- Il cruscotto **non** prende decisioni: suggerisce ("Search dezinsecție costa 80 lei per cliente, Deratizare
  400 lei per cliente").

---

# 18. WhatsApp: cosa significa «l'app deve scriverci dentro»

Questa frase ti ha fatto storcere il naso, e hai ragione a chiederlo. Significa **una cosa sola e concreta**:

> L'app **non** sostituisce WhatsApp e **non** costruisce un secondo inbox. L'app **prepara** il messaggio,
> il PDF e il link, e poi **passa la mano a WhatsApp** dove il cliente risponde.

Concretamente:

| Cosa fa l'app | Cosa *non* fa |
|---|---|
| apre `wa.me` con il testo già scritto e il numero giusto | non legge le conversazioni del cliente |
| allega il PDF del PV (link o download) | non fa "inbox unificato" |
| ricorda **chi** va contattato oggi e con **quale** testo | non manda messaggi in automatico (fase 3 sì, via Cloud API ufficiale) |
| registra che il messaggio è stato **preparato/inviato** | non finge di essere WhatsApp |

Quindi "scriverci dentro" = **il tap finale lo fa su WhatsApp**, dove Ifrim è già a suo agio. L'app è il
cervello; WhatsApp resta la bocca. In fase 3, con l'API ufficiale, i promemoria partono da soli — ma resta
sempre un canale Meta, non un clone.

---

# 19. Documenti: PV, stampa, fatture, e-Factura

## 19.1 Niente è obbligatorio tranne il PV (e anche lui ha uno stato)

| Documento | Obbligatorio? | Stati nel CRM |
|---|---|---|
| **PV D.D.D.** | sì (è il documento del controllo DSP) | de făcut · generat · **tipărit** · trimis pe WhatsApp · semnat |
| **Bon fiscal** | no — può non esserci | nu este cazul · de făcut · emis |
| **Factură** | no, solo se il cliente la chiede / è PJ | nu este cazul · de emis · emisă · **trimisă e-Factura** · acceptată · refuzată |
| **Contract** | per PJ e associazioni | draft · semnat · expirat |

Un intervento **si chiude anche senza** bon e senza fattura: il CRM lo mostra in un elenco "documente lipsă"
e lo ricorda, ma **non blocca niente**. La chiusura dell'intervento non dipende dalla carta.

## 19.2 Il PV: stampa quotidiana (come fa lui oggi)

- Ifrim stampa i PV **ogni giorno**. Quindi: bottone **„Printează PV-urile de azi (5)"** → un PDF A4, un PV
  per pagina, numero di serie già stampato, campi precompilati. Stampa da telefono (Google Print/AirPrint) o
  dal PC la sera.
- Il PV resta **cartaceo** finché il DSP non dice il contrario: la firma sullo schermo è un'opzione in più
  (utile per i clienti che chiedono subito la copia), non un sostituto.
- Dopo la stampa, due tocchi: `Trimite pe WhatsApp` (PDF) e `Copie în arhivă`. Il gruppo WhatsApp "PV - URI"
  non serve più come archivio — ma resta, se vogliono.

## 19.3 e-Factura: come lo tracciamo (3 livelli, dal più economico)

1. **Flag manuale (10 minuti di lavoro).** Un tocco sull'intervento: `trimisă în e-Factura` + data + numero.
   Copre l'80% del bisogno: sapere *se* è stata fatta e *quando*.
2. **Upload del file.** Ifrim carica l'XML/PDF scaricato dal software di fatturazione: il CRM legge numero e
   data dal file e lo allega. Zero integrazioni.
3. **Integrazione col software che usano** (SmartBill, Oblio, FGO, Contapps…): import automatico dello stato
   *transmis / acceptat / refuzat* + `index de încărcare`. Serve sapere che software usano → **domanda
   dell'onboarding** (§11, domanda 6).

Regola: il CRM **non fa** e-Factura e non parla con ANAF. Traccia lo stato, conserva il file, e se ANAF
risponde "refuzat" mette una bandierina rossa sull'intervento. Il commercialista resta il suo.

---

# 20. Mappe: Waze, Google Maps, Apple Maps

Un solo bottone **„Navighează"** su ogni indirizzo (cliente, intervento, agenda).

| Telefono | Cosa apre |
|---|---|
| Android | `geo:` → il sistema propone le app installate (Waze di solito è la prima) |
| iPhone | Apple Maps di default; `comgooglemaps://` o `waze://` se l'app è installata |
| senza app | fallback al link web di Google Maps |

- La preferenza si **ricorda per utente** (Ifrim usa Waze, Mădălin Google Maps).
- Il bottone **„Am ajuns"** (nella fast path) registra l'ora e ferma il timer: quell'ora finisce nel PV come
  "ora începerii" e serve a capire i ritardi.
- L'indirizzo **strutturato** (via, numero, blocco, scala, interno) è quello che rende utile la navigazione:
  è il motivo per cui il foglio va spezzato (§1.3).

---

# 21. Client nou din WhatsApp (screenshot → cliente)

Il tuo caso: arriva la conversazione, e per aggiungere un cliente **deve bastare caricare lo screenshot**.

**Flusso**
1. `+ Client` → **„Din conversație"** → allega 1–6 screenshot (o incolla dal telefono).
2. Il sistema estrae: nome, telefono, indirizzo, servizio, prezzo menzionato, esigenza ("ploșnițe", "blat
   bloc 4", "control DSP").
3. I campi arrivano **già compilati** e colorati: verde = sicuro, giallo = da verificare.
4. Ifrim conferma (5–10 secondi) o completa i gialli. Cliente creato, primo intervento proposto.
5. Se lo screenshot non basta: `Completează restul` con gli stessi passi guidati dell'onboarding.

**Tecnologia:** OCR + LLM lato server (costo quasi zero a questi volumi). **Privacy:** l'immagine si cancella
dopo l'estrazione (default), oppure resta come allegato del cliente se Ifrim vuole conservarla.

**Fase 3:** anche i **messaggi vocali** (0:36) → trascrizione → stesso estrattore → nota nel cliente.

---

# 22. Tono dei messaggi al cliente

Formale, rispettoso, mai confidenziale. „Dumneavoastră", sempre.

| Oggi / da evitare | Meglio |
|---|---|
| „Vă convine ora 13:00?" | „**Este în regulă pentru dumneavoastră** vineri, 7 noiembrie, ora 13:00?" |
| „Dați-mi un semn" | „Vă rugăm să ne răspundeți cu **DA** sau cu o altă oră care vă este convenabilă." |
| „Trebuie să fim acolo la 9" | „Echipa noastră va ajunge mâine la ora 09:00, la adresa…" |
| „Nu uitați să aerisiți!" | „Vă rugăm să aerisiți timp de 4 ore după intervenție." |

**Regole:** saluto + motivo + proposta concreta (2 opzioni) + cosa deve fare + firma „EcoFresh Group".
Vietati: maiuscole enfatiche, punti esclamativi multipli, "urgent", emoji, "grabă". Diacritiche sempre
(ș/ț con la virgola, „…" tipografiche). I testi stanno nel database e sono **gli stessi per tutti gli
operatori**: il tono è della ditta, non del tecnico.

---

# 23. Backup, repository, segreti

| Cosa | Dove | Frequenza |
|---|---|---|
| **Codice** (app, spec, mockup) | **repository GitHub privato di Gabi** | ogni push (git) |
| **Database** | dump **cifrato** (age/gpg) su Google Drive di EcoFresh | ogni notte |
| **Foto e PDF** | disco del server + sync incrementale su Drive | ogni notte |
| **Segreti** (DB, SMTP, chiavi API) | file `.env` fuori dal repo, permessi 600 | mai nel codice |
| **Ripristino di prova** | documentato in `README-BACKUP.md`, provato una volta al mese | mensile |

Perché il DB **non** su GitHub anche se il repo è privato: contiene nomi, telefoni e indirizzi di clienti
(dati personali GDPR). Il codice si può mettere, i dati no. Il deploy è `git pull` sul server.

---

# 24. Cosa cambia nel piano (fasi aggiornate)

| Fase | Aggiunte rispetto a §8 |
|---|---|
| **1 — MVP** | ruoli e permessi (con **incassi solo Ifrim**), **onboarding a 4 passi**, **task minimi** con assegnazione, campo „sursă" del cliente, „Navighează", stampa PV del giorno, WhatsApp livello 0+1 |
| **2** | import client da screenshot, cruscotto Ads livello 1 (CPL/CAC/ROAS), call tracking (livello 2), aiuto contestuale „?" su tutti i campi |
| **3** | Cloud API (promemoria e recensioni automatiche), conversione offline in Ads (livello 3), trascrizione vocali, task da messaggio inoltrato |

---

# 25. Stato dell'implementazione (29 ottobre, sera)

L'app in `app/` copre ora **tutto il MVP** tranne ciò che richiede accessi esterni.

| Funzione | Stato | Dove |
|---|---|---|
| Login, ruoli, **matrice permessi modificabile** | ✅ | `/setari` (pallini ✓/— cliccabili dall'admin) |
| Import del foglio (64 clienti, 144 interventi, 40 cicli, PV 0001→0107) | ✅ | `app/bin/import.php` |
| **Dati formattati** (indirizzi, nomi PJ, telefoni, servizi, metodi di pagamento) | ✅ | `app/src/format.php` |
| **Mod rapid / Start** (3 tap: apri → produs/foto/firma → Finalizează) | ✅ | `/rapid`, `/rapid/{id}` |
| **Foto** (opzionali, da fotocamera) e **firma** su schermo | ✅ | dentro il mod rapid; compaiono nel PV |
| **PV numerato + stampa singola e del giorno** | ✅ | `/interventie/{id}/pv`, `/pv/azi` |
| **e-Factura**: stato fattura (nu e cazul → de emis → emisă → trimisă → acceptată/refuzată) | ✅ | `/facturi` + blocco nella scheda intervento |
| **Ads livello 1**: spesa inserita a mano, clienti nuovi dal CRM, CPL/CAC/ROAS per mese | ✅ | `/ads` |
| **Client din conversație** (incolli il testo, campi già compilati, verde/giallo) | ✅ | `/import` |
| **Webhook Easy!Appointments** (opzione A) con secret condiviso | ✅ codice, 🔌 da attivare in EA | `/api/ea-webhook` |
| **Offline**: service worker + coda locale per la chiusura intervento | ✅ base | `public/sw.js`, `app.js` |
| **Backup cifrato** (AES-256, rotazione 14, ripristino verificato) | ✅ | `app/bin/backup.php`, `restore.sh` |
| **Deploy** | 📄 procedura pronta, mancano gli accessi | `DEPLOY.md` |
| PDF generato server-side | ❌ (si stampa dal browser) | fase 2 |
| WhatsApp Cloud API, conversione offline Ads (livello 3) | ❌ | fase 3 |

**Criteri §13.4 verificati a mano:** chiusura intervento con PV in 3 tap (test end-to-end su `/rapid/146` → PV 0109),
firma e prodotto presenti nel PDF, permessi che cambiano il comportamento (agent `/bani` 403 → 200 → 403),
webhook 403 senza secret e 201 con secret, backup ripristinato (66 clienti · 148 interventi · 109 PV).
