Carlimetalli · Piano tecnico · Settembre 2026
Il percorso completo di un ordine: dalla mail che arriva su ordine@, agli allegati passati al lettore disegni, alla scheda di produzione rigenerata, fino all'evento con la scadenza in calendario. Cosa c'è già, cosa va costruito, e in che ordine conviene farlo.
Un worker guarda la casella ogni 5 minuti: prende le mail non ancora etichettate, ne salva mittente, oggetto, corpo e allegati, e applica l'etichetta Gmail Processato.
Produce: la mail intatta in mail.eml e i file come sono arrivati.
Cliente, scadenza richiesta, riferimento e note di lavorazione. Si prova prima senza AI (mittente noto, data scritta per esteso) e si chiama un modello leggero solo quando il testo è vago.
Produce: numero ordine ORD-2026-0142 e la data di consegna normalizzata.
Gli allegati entrano nel motore che gira già oggi: files_to_parts → call_gemini → normalizza, con il contesto imparato dalle tue correzioni già appeso al prompt.
Produce: tratti, pieghe, sviluppo, materiale, spessore, RAL, quantità, confidenza e avvisi.
Un A4 con il profilo ridisegnato e quotato, la tabella dati (materiale, spessore, colore, sviluppo, lunghezza, quantità), il cliente e la scadenza in testata. Un pezzo per foglio.
Produce: scheda.pdf, quello che va in officina.
Una cartella per ordine sul server, e gli stessi tre file caricati su Drive — passaggio obbligato, perché il calendario può allegare solo file che stanno su Drive.
Produce: la cartella dell'ordine e i fileId di Drive.
Evento tutto-il-giorno sul calendario condiviso "Produzione", con in allegato scheda, disegno originale e mail. Nasce marcato da confermare e si aggiorna quando lo confermi.
Produce: l'evento, e il suo eventId salvato nell'ordine.
Una pagina "Ordini" nell'app con gli stati: da rivedere → confermato. Le correzioni che fai lì passano da registra() esattamente come oggi, quindi il ciclo di apprendimento si chiude da solo.
Metà del lavoro è già in casa. Del motore attuale non si tocca niente: viene solo richiamato da un worker invece che da un caricamento nel browser.
| Pezzo esistente | Cosa fa | Nel flusso nuovo |
|---|---|---|
| files_to_parts() | PDF e foto → immagini ridimensionate a 1600px | invariato |
| call_gemini() | lettura strutturata con schema, fallback del modello, 429 gestito | invariato |
| normalizza() | riallinea pieghe e tratti, confronta sviluppo dichiarato e calcolato | invariato |
| contesto() | vocabolario, convenzioni e regole appesi al prompt | invariato |
| registra() | archivia il diff fra lettura AI e distinta corretta | chiamato dalla coda |
| registra_consumo() | token e costo per ogni chiamata | invariato |
| polilinea() | geometria del profilo, oggi in JavaScript nel browser | da portare in Python |
| export xlsx / json | distinta in Excel, JSON per pressa_ai | allegabili all'ordine |
Sono le sette cose che decidono se il flusso regge davvero. Il resto è lavoro di routine.
È il modo numero uno in cui questi flussi si rompono: il worker riparte, rilegge le stesse mail e ti riempie il calendario di eventi ripetuti. Doppio presidio: ogni mail ha un Message-ID univoco che finisce in un registro locale, e appena processata la mail riceve un'etichetta in Gmail. Così il controllo lo puoi fare anche a occhio, aprendo la casella.
Con l'inoltro automatico il campo From a volte resta il cliente e a volte diventa l'indirizzo che inoltra, con in mezzo Reply-To e il blocco "Forwarded message" nel corpo. Si prova in ordine Reply-To, poi gli header di inoltro, poi il blocco nel corpo, e comunque il cliente viene riconfermato dall'estrazione sul testo.
Nessuno scrive "consegna: 2026-09-18". Scrivono "per venerdì", "entro fine mese", "urgente", "quando potete". Alla chiamata di estrazione va passata anche la data di ricezione, che è il riferimento per tutte le date relative, e torna una cosa così:
{
"cliente": "Rossi Coperture Srl",
"data_consegna": "2026-09-18",
"tipo": "relativa",
"frase_originale": "ci servirebbero per venerdi prossimo",
"confidenza": "media"
}
La frase originale si conserva sempre: è quella che guardi tu quando controlli, ed è quello che ti fa capire in due secondi se l'AI ha inteso bene. Se la scadenza non c'è, si applica un termine di default configurabile e l'evento nasce marcato come stimata.
Non tutto il flusso ha bisogno della stessa potenza. Leggere un disegno storto e capirci dentro tratti e pieghe è un lavoro difficile; capire che "per venerdì" vuol dire il 18 non lo è. Tre livelli, dal più stupido al più potente, e si sale solo quando serve:
Il guadagno vero non è tanto il costo, che è già basso: è che le quote gratuite si contano per modello. Dando il testo a un modello e le immagini a un altro, i due lavori non si mangiano la stessa quota. E se un giorno Gemini risponde 429, il pezzo "operaio" continua a girare lo stesso.
Oggi il profilo lo disegna JavaScript dentro la pagina. Per generare un PDF da solo su un server, la stessa geometria deve esistere in Python. Due strade:
Il rischio della prima strada è che le due versioni divergano nel tempo. Si copre con un test che confronta i punti calcolati da JavaScript e da Python sugli stessi tratti: se un giorno non coincidono più, lo scopri subito.
Una cartella per ordine, con dentro tutto quello che serve per ricostruire la storia:
/ordini/2026/09/ORD-2026-0142/
mail.eml la mail originale, intatta
allegati/disegno1.pdf i file come sono arrivati
scheda.pdf la scheda generata
dati.json distinta, scadenza, stato, eventId
Gli stessi file vanno anche su Drive, e non è una scelta estetica: gli allegati degli eventi di Google Calendar devono essere file di Drive. Un PDF grezzo non si può attaccare a un evento, serve il suo identificativo su Drive. Quindi prima l'upload, poi l'evento.
I connettori che usiamo qui in chat servono per guardare adesso: aprire mail vere, scaricare allegati veri, capire com'è fatta la realtà. Il servizio che poi gira da solo sul server ha bisogno di credenziali proprie, che non dipendono da nessuna chat aperta:
Ogni fase ha un criterio di uscita: finché non è soddisfatto non si passa alla successiva. È il modo per non ritrovarsi con sei pezzi a metà che non funzionano insieme.
Raccogliere venti o trenta mail di ordine vere con i loro allegati e leggerle. Come arriva il mittente dopo l'inoltro? Gli allegati sono PDF da CAD, foto scattate al volo, scansioni storte? Come scrivono le scadenze? Quanti pezzi ci sono per foglio? Mezza giornata, e si può fare da subito dalla chat con il collegamento a Gmail.
Il worker legge le mail nuove, crea la cartella dell'ordine, salva mail e allegati, etichetta in Gmail, scrive il registro. Nessuna intelligenza, solo idraulica: è la parte che deve essere noiosa e affidabile.
Cliente e scadenza dal corpo della mail, disegni dagli allegati con il motore che c'è già. Il risultato per ora finisce solo nel file dati: niente ancora di visibile, così puoi verificare la qualità senza rumore.
La geometria portata in Python, il foglio A4 con profilo e tabella, e la pagina "Ordini" nell'app dove rivedi e confermi. Da qui in poi il flusso produce qualcosa che si può portare in officina.
Upload dei tre file, evento sulla data di consegna con gli allegati attaccati, e aggiornamento dell'evento quando confermi l'ordine.
Tutto in un container su una macchina sempre accesa — un piccolo server in cloud sui 5-10 € al mese, oppure un mini PC in azienda. Poi si alza piano la soglia di auto-conferma: passa da solo soltanto ciò che ha confidenza alta e viene da un tipo di pezzo su cui le correzioni si sono azzerate da un po'.
Il piano gratuito non si conta a token mensili, come pensavo prima: si conta a richieste al giorno, e il conto è separato per ogni modello. Con 100 ordini al giorno e una media di un disegno e mezzo per ordine si fanno 150 chiamate sulle immagini e 100 sul testo.
Quindi al gratuito ci stai con un margine enorme, e dividendo testo e immagini su due modelli i due conti restano pure separati. L'unico vincolo che si sente davvero è quello al minuto: il worker deve smaltire in coda, non tutto insieme. Se resta fermo mezza giornata e si accumulano duecento mail, alla ripartenza deve andare piano invece di sparare tutte le chiamate in una volta.
La casella finale è una Gmail normale o su Workspace? Cambia il modo di dare le credenziali al server: token di rinnovo nel primo caso, account di servizio con delega nel secondo, che è più comodo da tenere in piedi.
La scheda: geometria portata in Python o browser headless? Consiglio Python — più leggero e più prevedibile — ma se vuoi arrivare prima al risultato, Playwright riusa il disegno che c'è già.
Dove gira: server in cloud o macchina in azienda? Il cloud costa pochi euro e non dipende dalla linea dell'officina; la macchina in azienda tiene tutto in casa e si integra con le cartelle di rete che usate già.