← Officina Carli  ·  Piano tecnico del 6/9/2026, copiato dal lettore disegni. Attenzione: dal 15/9 dal sito non partono ordini (le richieste vanno a info@): la partenza del flusso va rivista. Vedi «Il piano dell’Officina».
Da mail a scadenza

Carlimetalli · Piano tecnico · Settembre 2026

Da mail a scadenza

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.

Il percorso

A monte, nessun codice: il form del sito manda a ordine@carlimetalli.it, che ha l'inoltro automatico verso la Gmail aziendale. È configurazione di posta, si fa una volta e basta.
1

Ingestione

nuovo posta.py

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.

2

Estrazione ordine

nuovo ordine.py

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.

3

Lettura disegni

già fatto app.py

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.

4

Scheda a regola d'arte

nuovo scheda.py

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.

5

Archivio

nuovo archivio.py

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.

6

Scadenza in calendario

nuovo calendario.py

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.

7

Coda di revisione

estende l'app apprendimento.py

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.

Cosa si riusa così com'è

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 esistenteCosa faNel flusso nuovo
files_to_parts()PDF e foto → immagini ridimensionate a 1600pxinvariato
call_gemini()lettura strutturata con schema, fallback del modello, 429 gestitoinvariato
normalizza()riallinea pieghe e tratti, confronta sviluppo dichiarato e calcolatoinvariato
contesto()vocabolario, convenzioni e regole appesi al promptinvariato
registra()archivia il diff fra lettura AI e distinta correttachiamato dalla coda
registra_consumo()token e costo per ogni chiamatainvariato
polilinea()geometria del profilo, oggi in JavaScript nel browserda portare in Python
export xlsx / jsondistinta in Excel, JSON per pressa_aiallegabili all'ordine

I nodi tecnici

Sono le sette cose che decidono se il flusso regge davvero. Il resto è lavoro di routine.

Non creare doppioni

È 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.

Il mittente vero dietro l'inoltro

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.

Da verificare su mail vere prima di scrivere una riga di codice. È il punto che più spesso fa saltare il banco, e si vede solo guardando come arrivano davvero le mail inoltrate sulla tua casella.

Capire la scadenza da un testo libero

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.

Ogni lavoro al suo modello

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:

  • Niente AI. Il mittente confrontato con i clienti già confermati nel vocabolario che l'app sta costruendo, e le date scritte per esteso lette da una libreria. Costo zero, tempo zero, e soprattutto non si rompe mai.
  • Modello di testo leggero. Solo quando la frase è vaga o il cliente è nuovo. Poche centinaia di token, e può stare su un modello diverso da quello dei disegni.
  • Gemini con la visione. Solo per i disegni, che è l'unico punto dove la potenza serve davvero.

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.

Le allocazioni gratuite dei vari fornitori cambiano spesso, anche di mese in mese. Vanno verificate al momento di scrivere il codice, non date per buone da un piano scritto oggi.

Ridisegnare il profilo senza browser

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:

  • Portarla in Python. polilinea() sono una ventina di righe di trigonometria: si riscrivono, si emette SVG, si converte in PDF. Veloce, prevedibile, e permette di fare un foglio A4 vero con il cartiglio. È la strada che consiglio.
  • Browser headless. Playwright apre la pagina che c'è già e stampa in PDF. Un solo disegno da mantenere, ma 300 MB di browser sul server e più cose che si possono inceppare.

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.

Dove finiscono i file

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.

Le credenziali di Google

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:

  • Un progetto su Google Cloud, un consenso dato una volta sola dal browser, e il token di rinnovo salvato sul server
  • Permessi minimi: leggere ed etichettare la posta, creare file su Drive, creare eventi sul calendario. Nient'altro
  • Se carlimetalli.it è su Google Workspace, si può usare un account di servizio con delega: nessun token da rinnovare, più pulito per una macchina che deve andare avanti da sola

Le fasi

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.

Fase 0

Guardare la realtà

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.

Criterio di uscita
Hai il campione vero davanti e sai su cosa stai lavorando. Tutto il resto va più veloce se parte da qui, e più lento se si salta.
Fase 1

Ingestione e archivio, senza AI

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.

Criterio di uscita
Tre giorni di fila senza un doppione e senza una mail saltata.
Fase 2

Estrazione e lettura

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.

Criterio di uscita
Su trenta mail: cliente giusto in almeno il 95% dei casi, scadenza giusta in almeno il 90%.
Fase 3

Scheda PDF e coda di revisione

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.

Criterio di uscita
Le schede si usano in reparto senza doverle ritoccare, nella maggior parte dei casi.
Fase 4

Drive e calendario

Upload dei tre file, evento sulla data di consegna con gli allegati attaccati, e aggiornamento dell'evento quando confermi l'ordine.

Criterio di uscita
Un ordine vero arriva in calendario, con scheda, disegno originale e mail allegati e apribili dal telefono.
Fase 5

Server e autonomia progressiva

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'.

Criterio di uscita
Rivedi solo i casi dubbi, non più tutti.

Quanto consuma

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.

250richieste al giorno a 100 ordini, contro un tetto di 1.500 per modello
~1.000ordini al giorno prima di toccare davvero il limite gratuito
~18 $al mese se un giorno passassi al pagamento a 100 ordini/giorno

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.

Cosa può rompersi

Risposta su un thread esistenteSpesso vuol dire "modifica l'ordine". Si aggancia con il Thread-ID all'ordine già aperto e si marca sempre da rivedere, mai auto-confermato.
Allegati zip, Word, ExcelSi estraggono se si può, altrimenti si scarta con un avviso. L'ordine si crea comunque: mai far fallire tutto per un allegato strano.
Foto storte o scureGià gestito: il motore abbassa la confidenza e l'ordine resta in coda per la revisione.
Nessun allegatoOrdine solo testuale: si crea lo stesso, si salta la scheda, l'evento nasce con una nota.
Mail non di ordinePubblicità e spam sulla casella. Filtro leggero prima della chiamata AI, per non spendere token su niente.
Il worker si piantaLog a ogni giro e avviso via mail dopo tre fallimenti di fila. Peggio di un errore è un errore silenzioso.

Le tre decisioni da prendere

1

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.

2

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à.

3

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à.