# Cosa è cambiato Tutte le modifiche importanti all'app WeGrocery sono elencate qui. Il formato segue [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) e il versionamento è basato su [Semantic Versioning](https://semver.org/spec/v2.0.0.html): - **Major**: modifiche grosse che richiedono ai soci di reimparare qualcosa - **Minor**: funzionalità nuove, nessuna rottura - **Patch**: correzioni di bug, piccoli miglioramenti UI, documentazione Come si scrivono le voci: una tagline in corsivo sotto il titolo di versione, poi un punto per ogni modifica coerente: un'emoji a tema, un **titolo in grassetto** e al massimo due righe su cosa vede l'utente. I dettagli tecnici stanno nella PR. Una voce che conta solo per chi ospita, gestisce o sviluppa l'app (variabili, database, CI, dipendenze, monitoraggio) comincia con `[tecnico]` (`[tech]` in inglese, sulla stessa voce): la pagina nell'app la nasconde dietro "Mostra dettagli tecnici", la release su GitHub la tiene. > 🇬🇧 The English version of this file is [CHANGELOG.md](./CHANGELOG.md). > Le due versioni devono restare sincronizzate. --- ## [Unreleased] ## [1.45.1] - 9 novembre 2026 *Preparazione del trasferimento della repo a FlyLabs.* ### Modificato - [tecnico] 🔗 **Preparazione del trasferimento della repo**: release e controlli UI accettano il futuro proprietario FlyLabs mantenendo la repo attuale; default della Console e link di installazione puntano a `flylabs-ai/wegrocery`. Il trasferimento resta da fare. ## [1.45.0] - 9 novembre 2026 *Pronti ad aprire il gruppo a persone nuove: termini da accettare, iscrizione, pagina pubblica, import dei soci e quantità limitate, tutto spento finché un admin non lo accende.* ### Aggiunto - 📜 **Termini e privacy da accettare**: in Impostazioni > Gruppo un admin può chiedere a chi entra di accettare l'informativa privacy e i termini di servizio del gruppo (link alle pagine del gruppo) prima di usare l'app, e chiederlo di nuovo a tutti quando cambia i testi. Fino ad allora non si può ordinare né pagare. Spento di default. - 🔗 **Link ai termini di servizio** accanto all'informativa privacy, nella pagina di accesso e in fondo a ogni pagina. - [tecnico] 🗄️ **Migrazione 0051** (`terms_acceptance`): `app_settings.terms_required`, `app_settings.terms_version`, `members.terms_accepted_at`, `members.terms_accepted_version`. Additiva, da applicare prima del deploy. Nuovo campo facoltativo del brand `termsUrl`. - 🚪 **I nuovi soci possono entrare da soli**: in Impostazioni > Soci e guida, "Chi può entrare" offre "Su richiesta" (un modulo su /aderisci, un admin la approva in Soci e il nuovo socio riceve il link per entrare) o "Aperta" (chi conferma la propria email entra subito). Di default solo soci. - 💳 **I nuovi pagano prima di ordinare**: di default chi entra così non va mai sotto zero e paga ogni ordine con la carta o da un saldo già ricaricato. L'admin può dargli invece il credito del gruppo. - [tecnico] 🗄️ **Migrazione 0052** (`signup`): `app_settings.signup_mode`, `signup_role`, `signup_prepaid`, `members.joined_via`, tabella `membership_requests`. Additiva, da applicare prima del deploy. - 🪟 **Pagina pubblica del gruppo**: in Impostazioni > Gruppo un admin può accendere /gruppo, una vetrina per chi non è ancora dentro: il testo del gruppo, il prossimo ordine con le date e, se vuole, i prodotti, con i pulsanti per entrare o chiedere di aderire. Chi apre l'app senza aver fatto l'accesso arriva lì. Spenta di default, nascosta ai motori di ricerca se l'admin non sceglie diversamente. - [tecnico] 🗄️ **Migrazione 0053** (`public_page`): `app_settings.public_page_enabled`, `public_products_preview`, `public_page_indexable`, `public_intro`. Additiva, da applicare prima del deploy. `/` senza sessione ora porta a `/gruppo`, che rimanda a `/login` se la pagina è spenta. - 📥 **Importa i soci da un file**: in Soci, "Importa da file" legge un CSV da Excel o Google Fogli, mostra cosa succede a ogni riga (nuovo, già socio, ripetuto, email non valida) prima di importare, poi invita i nuovi soci 20 alla volta. I soci che ci sono già non vengono mai toccati. - 🧺 **Quantità limitate**: in Impostazioni > Gruppo un admin può accendere le quantità limitate e indicare su ogni prodotto del ciclo quante unità ci sono e quante ne può prendere un socio. I soci vedono solo "Esaurito"; se un prodotto finisce mentre ordinano, alla conferma vedono cosa resta con "Adatta alle disponibilità". Spente di default. Si possono impostare anche dal listino importato nel ciclo (colonne "Disponibili" e "Massimo per socio"), e la pagina pubblica segna "Esaurito" sui prodotti finiti. - [tecnico] 🗄️ **Migrazione 0054** (`stock_limits`): `products.max_quantity`, `products.max_per_member`, `app_settings.stock_limits_enabled`, indice parziale `payments_order_pending_cycle_idx`. Additiva, da applicare prima del deploy. Nuova invariante notturna `product_max_quantity`. ### Sicurezza - [tecnico] 🔒 **Better Auth aggiornato alla 1.7.18**, che corregge un avviso critico (lo stato di un accesso con Google accettato come link di accesso, GHSA-965c-763c-88jm) e due minori. Quello critico qui non era sfruttabile: i link di accesso sono salvati come hash, quindi uno stato di Google non ne coincide mai con uno. Gli altri riguardano l'OAuth Proxy, che qui non si usa, e una corsa sul limite dei tentativi con PostgreSQL. Un link inviato prima dell'aggiornamento smette di funzionare; il codice nella stessa email funziona ancora. ## [1.44.0] - 5 novembre 2026 *Il calendario degli ordini, i cicli in programma, una Home più chiara e le email con il volto del gruppo.* ### Aggiunte - 📦 **Ritiro da confermare.** Spesso la data di ritiro si sa davvero solo dopo la chiusura, sentito il fornitore: nel ciclo l'admin può spuntare **Ritiro da confermare**, e i soci leggono "Ritiro previsto ..., da confermare" in Home, nel calendario (il ritiro tratteggiato), nello Storico e nel calendario del telefono. Quando l'admin toglie la spunta, chi ha ordinato riceve **Ritiro confermato**; se cambia anche la data, l'avviso di sempre del ritiro cambiato. Finché il ritiro di un ciclo chiuso resta da confermare, **Da fare ora** lo ricorda con **Conferma il ritiro**. - 📅 **Calendario ordini.** Una nuova pagina, da Home (e da Ordine quando non c'è niente di aperto), mostra quando puoi ordinare e quando si ritira, per i cicli aperti, in programma e recenti. Scegli un ciclo con i pulsanti sopra il calendario (quello più urgente è già scelto): i giorni per ordinare sono una fascia colorata, l'ultimo giorno un quadrato pieno, il ritiro un pacchetto; **Tutti** mostra per ogni giorno le icone di cosa succede (apertura, ultimo giorno, ritiro); da telefono i pulsanti dei cicli scorrono di lato, così il calendario resta in alto. Toccando un giorno scegli il suo ciclo, e una scheda sotto dice quando apre, fino a quando ordinare e quando ritirare. - 🗓️ **Cicli in programma.** Creando un ciclo puoi scegliere **Più avanti** in "Quando aprono gli ordini": il ciclo entra nel calendario dei soci con le sue date (con "Date indicative" se possono ancora cambiare) e i prodotti come anteprima, aggiunti a mano o dal listino Excel del fornitore come sempre. Nessuno può ordinare finché un admin o un referente ordini non tocca **Apri gli ordini**; "Da fare ora" lo ricorda il giorno previsto, e un ciclo in programma si può eliminare. Il calendario in Home dice quando apre. - 🔔 **"Avvisami quando apre" e "Aggiungi al calendario".** Su un ciclo in programma nel calendario puoi chiedere un'email quando si aprono gli ordini (nessuno la riceve due volte se riceve già le email dei nuovi cicli). Ogni ciclo del calendario si può aggiungere al calendario del telefono: la scadenza con un promemoria tre ore prima, e il ritiro. - 🗄️ [tecnico] **Migrazione `0048_planned_cycles.sql`.** Nuova colonna `order_cycles.dates_tentative`, falsa per tutti i cicli, e il blocco delle spese di preparazione della 0026 ora lascia cambiare anche quelle di un ciclo in programma; da applicare prima del deploy. - 🗄️ [tecnico] **Migrazione `0049_cycle_open_alerts.sql`.** Nuova tabella `cycle_open_alerts` per le richieste "Avvisami quando apre"; da applicare prima del deploy. - 🗄️ [tecnico] **Migrazione `0050_pickup_tentative.sql`.** Nuova colonna `order_cycles.pickup_tentative`, falsa per tutti i cicli (ogni ritiro resta confermato come prima); da applicare prima del deploy. ### Modificato - ✉️ **Email con il volto del gruppo.** Le email dell'app (accesso, notifiche, inviti in famiglia, "Avvisami quando apre") mostrano in alto il logo e il nome del gruppo, nei suoi colori; il link all'app è un pulsante che dice dove porta ("Vai all'ordine", "Apri lo Storico", "Entra"), il codice d'accesso un riquadro grande, e la notifica ha il suo titolo. - 📅 **Legenda del calendario uguale per un ciclo e per Tutti.** Scegliendo un ciclo la legenda mostra anche **Apre**, come in Tutti. - 🏠 **Una Home più chiara: una sola lista di cicli.** Ogni ciclo compare una volta, nel gruppo di cosa devi fare: **Da ordinare** (la scadenza con il giorno della settimana per intero, "domani" o "Ultimo giorno", il tuo ordine raccolto in una riga, un piccolo pulsante "Ordina", "Modifica" o "Paga"), **Da ritirare** (i cicli chiusi con il tuo ordine e il ritiro ancora da fare) e **In arrivo** (i cicli in programma). Il riquadro con la data su ogni ciclo fa da calendario; il calendario completo è a un tocco, e da computer il mese corrente sta a destra. Il saldo è una riga piccola in fondo, e va in alto solo se è negativo. ## [1.43.0] - 1 novembre 2026 *Chi ha ritirato il suo ordine, e il nuovo "Referente ordini" per aiutare con i cicli.* ### Aggiunte - 📦 **Registro dei ritiri.** Un ciclo chiuso ha la nuova scheda **Ritiri**: spunti un socio quando ritira (vale l'orario di adesso) o tocchi il nome per un altro orario, chi ha ritirato e una nota per gli admin. Accanto al titolo del ciclo un contatore dice quanti hanno ritirato, per esempio "8/10 ritirati". - 🔔 **Promemoria per chi non ha ritirato.** Dal giorno di ritiro "Da fare ora" segnala i cicli con soci che devono ancora ritirare, e "Chiudi i conti" avvisa se qualcuno non ha ancora ritirato. Il socio vede "Ritirato il …" nello Storico; il nuovo avviso "Ordine ritirato" è spento finché non lo accende. - 👥 **"Referente ordini".** Un nuovo accesso per i soci che aiutano con gli ordini senza essere amministratori: aprono, modificano e chiudono i cicli che vedono, mandano l'ordine al fornitore, caricano la distinta, segnano i ritiri e gestiscono il catalogo; vedono i soci in sola lettura, senza cassa, conti o impostazioni. Il form del socio ora ha due voci: "Accesso all'app" e "Cicli che vede". - 🗄️ [tecnico] **Migrazione `0046_cycle_pickups.sql`.** Nuova tabella `cycle_pickups`; va applicata prima del deploy. - 🗄️ [tecnico] **Migrazione `0047_orders_referent.sql`.** Nuova colonna `members.orders_referent`, falsa per tutti; va applicata prima del deploy. ## [1.42.0] - 29 ottobre 2026 *Una scorciatoia per fissare il ritiro di un ciclo, anche dopo la chiusura.* ### Aggiunte - 🗓️ **"Aggiungi il ritiro" dalla panoramica del ciclo.** Un ciclo senza ritiro, aperto o chiuso, ora dice "Ritiro: non ancora fissato" nella Panoramica, con un pulsante che apre la modifica direttamente sul ritiro. Una nuova scheda nella guida per gli admin spiega che il ritiro si fissa o si cambia anche dopo la chiusura, e che chi ha ordinato riceve un avviso. ## [1.41.0] - 28 ottobre 2026 *Un avviso quando il ritiro di un ciclo in cui hai ordinato viene fissato o cambia.* ### Aggiunte - 📅 **Avviso quando cambia il ritiro.** Quando l'admin fissa, sposta o toglie la data o l'orario di ritiro di un ciclo, chi ha ordinato in quel ciclo riceve un avviso. Nelle Preferenze notifiche il nuovo gruppo "Data di ritiro" permette a ciascuno di scegliere app, email o entrambe. ## [1.40.0] - 28 ottobre 2026 *Una quota preventiva per le pesate nei cicli con carta, e le differenze delle pesate che passano al pagamento successivo invece di essere condonate.* ### Aggiunte - ⚖️ **Quota preventiva per le pesate.** Nei cicli con carta l'admin può aggiungere una percentuale (per esempio 3%) sui prodotti, pagata con l'ordine come riga a parte. Quando si chiudono i conti dopo le pesate, la parte non usata torna da sola sulla carta del socio. Si attiva per ciclo e si propone di default da Impostazioni, Pagamenti, Nuovi cicli. - [tecnico] 🗄️ **Migrazione `0045_weighing_deposit.sql`.** Aggiunge `order_cycles.weighing_deposit_pct` (vuota = nessuna quota, solo cicli con carta, al massimo 25%). Da applicare prima del deploy, rollback in `0045_weighing_deposit_down.sql`. ### Modificato - ⚖️ **Le differenze delle pesate passano al pagamento successivo.** Con "Saldo del borsellino nei pagamenti con carta" acceso, se a conti chiusi le pesate costano più di quanto pagato la differenza resta sul saldo e si aggiunge al prossimo pagamento con carta, anche sotto 0,50 € (prima veniva abbonata). Il socio riceve un avviso che lo spiega. ## [1.39.0] - 27 ottobre 2026 *Impostazioni più ordinate, "Nessuna" spesa di preparazione anche per i cicli con carta e le ricariche del borsellino che si possono spegnere.* ### Aggiunte - 🔒 **Ricariche del borsellino spegnibili.** Un gruppo che fa pagare ogni ordine con carta può spegnere le ricariche in Impostazioni, Pagamenti, Borsellino: i soci non vedono più Ricarica, IBAN e causale (in Home, Profilo, Storico e guida) e la ricarica online viene rifiutata. Saldi e movimenti restano, e in Cassa si può sempre registrare un versamento a mano. Di default le ricariche restano attive. - [tecnico] 🗄️ **Migrazione `0044_wallet_topups.sql`.** Aggiunge `app_settings.wallet_topups_enabled` (acceso di default) e allarga `app_settings_wallet_channel_check`: con le ricariche spente un gruppo col borsellino può non avere canali. Da applicare prima del deploy, rollback in `0044_wallet_topups_down.sql`. ### Modificato - 🗂️ **Impostazioni divise per argomento.** Una barra in alto porta a Pagamenti, Gruppo (nome, logo, colori e contatti), Soci e guida, Tecniche. Ogni riquadro resta chiuso e mostra in una riga com'è impostato; si apre con un tocco, o da solo se c'è qualcosa da sistemare. - 💳 **La carta in un solo riquadro.** Collegamento a Stripe, ricarica online e saldo nei pagamenti con carta stanno insieme in "Carta (Stripe)", e lo stato di Stripe non è più ripetuto in più punti. - 🧾 **Spese proposte più compatte.** Spedizione e preparazione si scelgono da un menu con l'importo accanto, uguali per i cicli col borsellino e per quelli con carta. - 🧾 **"Nessuna" spesa di preparazione anche per i cicli con carta.** In Impostazioni e in Nuovo ciclo i cicli con carta hanno ora l'opzione "Nessuna", come quelli col borsellino. ## [1.38.0] - 26 ottobre 2026 *I nuovi cicli possono partire con la carta, con le spese giuste già proposte, e il saldo del borsellino può entrare nel pagamento con carta.* ### Aggiunte - 💳 **Il saldo del borsellino entra nel pagamento con carta.** Con l'impostazione accesa, chi paga con carta un ciclo con carta paga anche il suo saldo negativo; se ha credito, il credito si scala (e se basta non paga nulla con carta). Prima di pagare il socio vede le voci separate, e in Storico e in Cassa ordine e saldo restano movimenti distinti. Si accende in Impostazioni, "Saldo del borsellino nei pagamenti con carta". - [tecnico] 🗄️ **Migrazione `0042_card_settles_wallet.sql`.** Aggiunge `app_settings.card_settles_wallet` (spento di default), `payments.balance_cents` e il tipo di movimento `wallet_transfer` (coppia legata da `counterpart`); tre controlli notturni nuovi: `order_payment_split`, `order_refund_cap`, `wallet_transfer_pairs`. Da applicare prima del deploy, rollback in `0042_card_settles_wallet_down.sql`. - 🧾 **I nuovi cicli possono partire con la carta.** In Impostazioni, "Nuovi cicli", scegli tra solo borsellino, borsellino con carta su richiesta, o carta con borsellino su richiesta. Si cambia anche con cicli aperti: quelli già creati restano come sono. - 🚚 **Spese proposte per ogni modalità.** Sempre in "Nuovi cicli" imposti spedizione e spesa di preparazione per i cicli col borsellino e per quelli con carta (per esempio 0 € e 2%): "Nuovo ciclo" le propone già compilate. - 🗂️ **Impostazioni dei pagamenti più ordinate.** Le opzioni sono divise in Nuovi cicli, Carta (Stripe), Bonifico, Borsellino e Avanzate, ognuna col suo Salva. - [tecnico] 🗄️ **Migrazione `0043_new_cycle_defaults.sql`.** Aggiunge `app_settings.new_cycle_payment_mode` e `app_settings.new_cycle_defaults` (jsonb), entrambe vuote di default (comportamento di prima). Da applicare prima del deploy, rollback in `0043_new_cycle_defaults_down.sql`. ### Modificato - 🗂️ **In Cassa i movimenti di un ordine stanno insieme.** Nei movimenti di un socio, addebito, spedizione, rettifiche e rimborsi dello stesso ciclo diventano una sola riga con il totale netto; un tocco la apre e li mostra uno per uno. ## [1.37.0] - 24 ottobre 2026 *Nomi veri per tutti i soci, e prezzi al kg affidabili quando si importa un listino.* ### Aggiunte - 🙋 **L'app chiede nome e cognome a chi non li ha.** Chi ha come nome la prima parte della sua email (per esempio chi è entrato col link via email) vede, dopo l'accesso, la domanda "Come ti chiami?". In Impostazioni gli admin scelgono se chiederlo, se si può rimandare o se è obbligatorio; in Soci il filtro "nomi da completare" mostra chi manca. - [tecnico] 🗄️ **Migrazione `0041_member_name_prompt.sql`.** Aggiunge `app_settings.member_name_prompt` (`off`, `optional`, `required`; `optional` di default); da applicare prima del deploy, rollback in `0041_member_name_prompt_down.sql`. - 🔎 **Ricerca nel Catalogo.** In Admin, Catalogo un campo di ricerca trova i prodotti per nome, varietà, formato, note, categoria o fornitore, insieme ai filtri. ### Modificato - 🖊️ **I prodotti di un ciclo si possono di nuovo modificare.** In Admin, Ciclo, Prodotti una matita accanto al cestino apre la scheda del prodotto subito sotto (nome, formato, prezzo, €/kg, categoria, note), e la lista mostra il €/kg. Gli ordini già fatti tengono il loro prezzo. - ✏️ **Un prodotto del catalogo si modifica dove si trova.** Modifica apre il modulo subito sotto il prodotto invece che in cima alla pagina, così anche i prodotti in fondo alla lista restano a portata. ### Risolto - ⚖️ **Prezzo al kg corretto nell'import del listino.** Una colonna non può più andare sia in Prezzo sia in Prezzo/kg; l'anteprima segnala un €/kg uguale al prezzo della confezione e propone quello calcolato dal peso scritto nel nome o nel formato ("cestello da 6 kg", "12 x 240 g"), e lo calcola anche quando il file non ha la colonna. Reimportando un file si aggiorna anche un €/kg cambiato. ## [1.36.0] - 24 ottobre 2026 *Gli admin possono scegliere l'ordine dei prodotti di un ciclo, e la pagina Ciclo è più ordinata.* ### Aggiunte - ↕️ **Prodotti nell'ordine che preferisci.** In Admin, Ciclo, Prodotti si sceglie tra **Alfabetico** (come prima) e **Personalizzato**: prodotti e categorie si spostano con le frecce o trascinandoli, e i soci li vedono in quell'ordine. **Usa l'ordine dell'ultimo ciclo** lo riprende dal ciclo precedente. - 🗑️ **Rimuovere un prodotto dal ciclo è più discreto.** Al posto del pulsante rosso c'è un cestino, rosso solo al passaggio. - [tecnico] **Migrazione `0040_cycle_product_order.sql`.** Aggiunge `order_cycles.product_order` (`alpha` di base) e `product_order_saved_at`; va applicata prima del deploy. Nuova dipendenza `@dnd-kit` per il trascinamento. ### Modificato - 🎨 **Pagina Admin → Ciclo più ordinata.** "+ Nuovo ciclo" ora è ben visibile in cima anche su telefono e tablet, accanto all'elenco dei cicli. "Da fare ora" usa schede bianche con una piccola etichetta "In ritardo" al posto dei blocchi rossi e gialli, così l'unico bottone colorato è l'azione principale del ciclo (Chiudi ciclo). ### Risolto - 🏷️ **"Altro" in fondo.** Nell'ordine alfabetico i prodotti senza categoria stanno dopo tutte le altre categorie. ## [1.35.0] - 22 ottobre 2026 *WeGrocery ora parla anche spagnolo e francese, e lo Storico dice quando un ordine è ancora da ritirare.* ### Aggiunte - 🌍 **L'app in spagnolo e francese.** Un gruppo può ora usare WeGrocery in spagnolo o in francese: schermate, guida dei soci e degli admin, email e distinta per il fornitore. La pagina "Novità" per questi gruppi resta in inglese. - [tecnico] **`brand.locale` accetta `"es"` e `"fr"`.** Nuovi pacchetti di lingua `lib/i18n/es.ts` e `fr.ts` e guide in `lib/guide`; date e importi usano es-ES e fr-FR, i campi decimali la virgola. ### Risolto - 🧺 **"Da ritirare" al posto di "Ritirato".** Nello Storico un ordine chiuso non risulta più già ritirato: resta "Da ritirare" fino alla fine dell'orario di ritiro, poi diventa "Concluso". - 🔢 **"1 movimento", non "1 movimenti".** In Cassa, un socio con un solo movimento non viene più indicato al plurale. ## [1.34.1] - 22 ottobre 2026 *La scritta "by flylabs.ai" sotto la scheda di accesso si legge meglio.* ### Risolto - 🔤 **"by flylabs.ai" leggibile nella pagina di accesso.** Sotto la scheda di accesso era troppo chiaro sullo sfondo della pagina; ora usa lo stesso grigio del link alla privacy. ## [1.34.0] - 20 ottobre 2026 *L'admin può aggiungere l'ordine di un socio prima di chiudere il ciclo, e la firma "by flylabs.ai" si fa più discreta.* ### Aggiunte - 🛒 **L'admin aggiunge l'ordine di un socio prima di chiudere il ciclo.** In Ordini di un ciclo, "+ Aggiungi ordine per un socio" e "✎ Modifica" funzionano ora anche con il ciclo aperto, pure dopo la scadenza: l'ordine viene addebitato alla chiusura come gli altri, senza correzioni, e il socio riceve un avviso. ### Modificato - 🧭 **L'ordine giusto dei passi dopo la scadenza.** "Da fare ora" ora dice "Controlla gli ordini" e apre Ordini; la Panoramica elenca i passi prima di chiudere (ordini, fornitore, chiusura) e la guida admin segue lo stesso ordine. La chiusura è l'ultimo passo, quello che addebita i soci. - ✍️ **Un "by flylabs.ai" più discreto.** Non c'è più in fondo a ogni pagina: ora è un piccolo testo accanto alla versione nel Profilo e sotto la pagina di accesso. Nelle email non cambia niente. ## [1.33.0] - 19 ottobre 2026 *Gli admin hanno la loro guida e il loro benvenuto, e in fondo all'app c'è la firma "by flylabs.ai".* ### Aggiunte - 🧭 **Una guida per gli admin.** Gli admin trovano ora la "Guida per gli admin" in Come funziona e in Admin (⋯ sul telefono, il menu a sinistra sul computer): 39 schede passo passo su come aprire e chiudere un ciclo, la distinta, la cassa, il catalogo, i soci e le impostazioni, con la ricerca. I soci non la vedono: le pagine rispondono "non trovata" e le sue parole non arrivano mai sul loro telefono. - 👋 **Un benvenuto per chi fa l'admin.** La prima volta in Admin un riquadro a passi spiega il lavoro (cosa c'è da fare, aprire e chiudere un ciclo, la cassa, i soci, la guida) e spunta quello che il gruppo ha già fatto. Si chiude con "Salta" o "Ho capito" e si rivede dalla guida admin. In ogni sezione di Admin "Come si fa?" apre la scheda giusta della guida. Nuova colonna `members.admin_welcome_dismissed_at` (migrazione 0039, solo aggiunta). - ✍️ **"by flylabs.ai" in fondo all'app.** In fondo alle pagine, sotto la pagina di accesso e sotto il logo nelle email c'è ora un piccolo "by flylabs.ai" con il link a flylabs.ai, mai in alto: l'app resta con il nome e il logo del gruppo. Gli admin possono toglierlo in Impostazioni, Nome, logo e colori. - [tecnico] 🧩 **FlyLabs Kit 0.12.** Modulo `firma` 1.0 (`components/by-flylabs.tsx`, token `--flylabs-ai` e `--flylabs-spark`, i colori del logo e non del gruppo) ed `email` 1.1 ("by flylabs.ai" minuscolo, link a `https://www.flylabs.ai/`, senza UTM). L'interruttore è `brand.flylabsSignature` (acceso di base) o una preferenza in `group_identity`; nessuna migrazione. README intitolato "WeGrocery by flylabs.ai". ## [1.32.0] - 17 ottobre 2026 *I gruppi possono tenere spenti i cicli pagati con carta finché non decidono di usarli.* ### Aggiunte - 💳 **I cicli con carta si possono spegnere.** In Impostazioni, "Cicli pagati con carta" decide se gli admin possono scegliere Carta quando creano un ciclo; da spento Carta resta visibile ma in grigio, con il link per attivarla. I cicli con carta già creati, le ricariche online e i rimborsi non cambiano. - [tecnico] 🗄️ **Migrazione `0038_card_cycles_switch.sql`.** Aggiunge `app_settings.card_cycles_enabled` (acceso di default, quindi nulla cambia finché un gruppo non lo spegne); da applicare prima del deploy, rollback in `0038_card_cycles_switch_down.sql`. ## [1.31.0] - 17 ottobre 2026 *Lo stile FlyLabs: campi dei moduli più chiari, email più curate, un solo set di icone e una pagina delle novità scritta per i soci.* ### Aggiunte - ✉️ **Email più curate.** Ogni email dell'app (accesso, notifiche, ordine al fornitore) ora arriva su una scheda pulita nei colori dell'app, con link da toccare e il logo di WeGrocery in fondo; le app di posta che mostrano solo il testo ricevono le stesse parole di prima. ### Modificato - ✨ **Icone più pulite, finestre più stabili.** La navigazione, gli argomenti della guida e i pulsanti per chiudere, modificare e "altro" usano un unico set di icone; dopo una conferma data da tastiera il cursore torna sul pulsante premuto invece che all'inizio della pagina. - 🔤 **Codici e importi nel carattere del testo.** L'IBAN, il codice di accesso e gli indirizzi email in Soci e Cassa usano ora lo stesso carattere del testo, e totali e saldi hanno le cifre allineate; il titolo della scheda di benvenuto non è più nel carattere stretto delle etichette. - 📰 **Le novità parlano ai soci.** La pagina mostra le modifiche che si notano nell'app; quelle per chi la gestisce (server, database, aggiornamenti) stanno dietro "Mostra dettagli tecnici", segnate "Tecnico". - [tecnico] 📊 **Le statistiche delle installazioni parlano la lingua della Console FlyLabs.** `/api/instance-stats` accetta anche la firma `x-flylabs-*` e allora risponde con la forma del FlyLabs Kit (`app`, `counts`); la Console WeGrocery manda entrambe e legge entrambe le forme, così le installazioni più vecchie continuano a funzionare. `/api/health` rinuncia dopo 3 secondi a un database che non risponde. - [tecnico] 🎨 **Token dei colori con i nomi FlyLabs.** I ruoli dei colori nel CSS usano ora i nomi shadcn del Playbook FlyLabs (`card`, `muted-foreground`, `primary-foreground`, `destructive`, `danger-bg`...), più `input`, `ring`, `success` e `warning-bg`; i colori del gruppo e i due temi restano come prima, e il test di contrasto copre i nuovi nomi. - [tecnico] 🧩 **Finestre su Base UI.** `Sheet` e `ConfirmDialog` passano da Radix a Base UI Dialog (`@base-ui/react`) e le icone dell'interfaccia a `lucide-react`; trascinare per chiudere, Esc e il ritorno del cursore funzionano come prima, e il controllo di stile rifiuta Radix e le icone d'interfaccia disegnate a mano. - [tecnico] 🧪 **I test di integrazione hanno il suffisso FlyLabs.** Ora si chiamano `*.integration.test.ts` (Playbook FlyLabs 5.2); `npm test` continua a escluderli, `npm run test:int` e la CI continuano a eseguirli. - [tecnico] 🗄️ **Le migrazioni rinunciano prima su una tabella occupata.** Ogni file di migrazione aspetta un lock al massimo 5 secondi (erano 10) e poi torna indietro per intero; un file con un'istruzione che Postgres non esegue in una transazione (`CREATE INDEX CONCURRENTLY`, `VACUUM`) viene rifiutato prima di eseguire qualsiasi cosa, e dalla 0036 in poi un test vuole il `_down.sql` di ogni migrazione. - ✏️ **Niente più trattini lunghi.** Un valore mancante nelle tabelle e negli elenchi ora compare come un semplice "-", e anche i titoli di versione nella pagina delle novità usano il trattino corto. - [tecnico] 🔘 **Pulsanti su shadcn e Base UI.** `Button` è ora il Button di shadcn su Base UI con `class-variance-authority` (`buttonVariants` sostituisce `buttonClass`; `neutral` diventa `default`, `danger` diventa `destructive`); i pulsanti hanno lo stesso aspetto e comportamento di prima. - [tecnico] 🗂️ **Card, Badge e Toaster nella forma di shadcn.** `CardBody` diventa `CardContent`, `Badge` prende `variant` (`default`, `brand`, `accent`, `destructive`) al posto di `tone`, e il Toaster passa in `components/ui/sonner.tsx`; schede, etichette e avvisi hanno lo stesso aspetto. - 📝 **Campi dei moduli più chiari.** I bordi dei campi sono più scuri, così le caselle in cui scrivi si vedono meglio, e gli elenchi a scelta mostrano la stessa freccia ovunque. - [tecnico] 🧾 **Campi su shadcn.** `Input` (su Base UI Input), `Textarea`, `NativeSelect` e `Label` in `components/ui/` sostituiscono gli `inputCls` e `labelCls` dei singoli moduli; i bordi dei campi passano da `border` al token `input` a 3:1, e il design guard rifiuta input di testo, textarea e select grezzi. ## [1.30.1] - 17 ottobre 2026 *Manutenzione: nessuna novità da imparare per i soci.* ### Modificato - [tecnico] 🔍 **Il controllo notturno dell'accessibilità guarda tutta la pagina.** Il controllo automatico che ogni notte verifica che l'app sia comoda da usare per tutti ora esamina la pagina intera, senza più falsi allarmi sulle righe nascoste dietro la barra in basso del telefono. ## [1.30.0] - 15 ottobre 2026 *Il menu passa di lato su tablet e computer, e l'ordine al fornitore parte anche prima della chiusura.* ### Aggiunte - 📧 **L'ordine al fornitore si invia anche prima di chiudere il ciclo.** Scaduti gli ordini, la scheda Fornitore compare già: scarichi la distinta e la mandi al fornitore, poi quando torna compilata chiudi il ciclo caricandola. ### Modificato - 🧭 **Menu di lato su tablet e computer.** Sul tablet il menu è una colonna a sinistra, sul computer un menu laterale con le sezioni admin sotto Admin; l'app usa tutto lo schermo. Sul telefono non cambia nulla. ## [1.29.0] - 15 ottobre 2026 *La distinta del fornitore si carica anche mentre chiudi il ciclo.* ### Aggiunte - ⚖️ **La distinta del fornitore si carica anche mentre chiudi il ciclo.** Nel foglio "Chiudi il ciclo" c'è "Carica la distinta": vedi prima le pesate e la spedizione, poi un solo pulsante chiude e addebita i costi veri. Ogni socio riceve un solo avviso con il costo finale. ### Risolto - 🚚 **La distinta scaricata prima della chiusura non azzera più la spedizione.** Ora parte già con la quota di spedizione di ogni socio, e le riduzioni nell'anteprima hanno il segno meno. ### Modificato - [tecnico] 🔐 **I gruppi nuovi partono con un ruolo database limitato.** Un gruppo installato dalla Console WeGrocery ora si collega con un ruolo che legge e scrive i dati ma non può mai cambiare la struttura del database, come fa già Porta Moneta. ## [1.28.0] - 14 ottobre 2026 *L'app ha un tema scuro, e gli aggiornamenti del database sono più sicuri.* ### Aggiunte - 📊 **L'uso dell'app a colpo d'occhio.** In Admin → Statistiche si vedono accessi, ordini, ricariche e cicli degli ultimi 30 giorni: conteggi anonimi, senza soci e senza testi, e nulla dalla demo. - 👋 **Il benvenuto si ricorda di te.** Riparte dal passo in cui eri rimasto, su qualsiasi dispositivo, e segna ciò che hai già fatto (una ricarica, un ordine, le scelte sulle notifiche, la famiglia). - 📧 **Disiscrizione con un tocco.** Le email di avviso mostrano il pulsante "Annulla iscrizione" della tua app di posta, che spegne le email di quel tipo (gli avvisi restano nell'app), e un doppio clic non manda mai due volte la stessa email. - [tecnico] 🔐 **Ruolo limitato per il database (facoltativo).** L'app può collegarsi con un ruolo che legge e scrive i dati ma non può cambiare lo schema; `scripts/create-app-role.mjs` lo crea e lo stato della configurazione lo mostra. - 🌙 **Tema scuro.** In Profilo → App c'è "Aspetto": come il telefono, sempre chiaro o sempre scuro. I colori del gruppo restano e si leggono bene. ### Modificato - 🔤 **Nuovi caratteri.** I testi usano Inter, i titoli Geist e le piccole etichette maiuscole JetBrains Mono; gli importi sono allineati in colonna. - [tecnico] 🗄️ **Aggiornamenti del database più sicuri.** Ogni aggiornamento si applica in un solo passo e si ferma se il database è occupato, così un errore non lascia nulla a metà. Per applicarlo in produzione serve una conferma esplicita. ### Risolto - [tecnico] 🐞 **Le segnalazioni di errore arrivano a chi mantiene l'app.** Alcuni errori (pagamenti, email di accesso) restavano solo nei registri del server e nessuno veniva avvisato: ora arrivano anche al servizio che li raccoglie, senza dati dei soci. ## [1.27.0] - 12 ottobre 2026 *Ogni nuovo gruppo si configura dall'app: nome, logo, colori e Stripe, con ogni impostazione tecnica spiegata.* ### Aggiunte - 🎨 **Nome, logo e colori si cambiano dall'app.** Gli admin cambiano nome del gruppo, logo, colori, indirizzi di contatto e link in Impostazioni, con anteprima e controllo di leggibilità: niente nuovo deploy, e l'icona sul telefono segue. - 🧭 **Configurazione guidata per un gruppo nuovo.** Il primo admin viene accompagnato passo per passo: identità, contatti, pagamenti, "Il nostro gruppo" e una verifica di email e Stripe (email di prova, eventi del webhook). Ai gruppi già attivi non viene proposta, e ogni admin può rifarla da Admin → Impostazioni. - [tecnico] 📊 **Statistiche anonime per chi gestisce più gruppi.** Con `INSTANCE_STATS_SECRET` impostato, una richiesta firmata restituisce solo conteggi (soci, cicli, ordini, versione, configurazione); senza, l'indirizzo non esiste. - 🛠️ **Impostazioni tecniche spiegate.** In Admin → Impostazioni lo stato della configurazione diventa "Impostazioni tecniche", divise in essenziali e facoltative, e ogni voce dice a cosa serve e come la attiva chi ospita l'app. - 💳 **Stripe si collega dall'app.** In Admin → Impostazioni un admin incolla una chiave con restrizioni dell'account Stripe del gruppo: l'app controlla i permessi e prepara da sola il webhook, e i pagamenti con carta arrivano sull'account del gruppo. Dove chi ospita l'app ha già messo le chiavi, resta tutto com'è. - [tecnico] 🚨 **Segnalazione degli errori con l'integrazione Sentry di Vercel.** Basta installare Sentry dal marketplace di Vercel: l'app ora usa da sola l'indirizzo che l'integrazione imposta, senza variabili da copiare a mano. ### Risolto - 🧾 **Il caricamento della distinta dice perché non c'è niente da applicare.** Al posto di due elenchi vuoti, l'anteprima dice quanti prodotti e soci ha riconosciuto e che gli importi sono già uguali, oppure che nel file non ha trovato niente da confrontare. Un CSV salvato da Excel su Windows non perde più gli accenti nei nomi. ## [1.26.0] - 9 ottobre 2026 *Un'app più ordinata su ogni schermo, il pagamento con carta per un singolo ciclo e la causale del bonifico già compilata.* ### Aggiunte - 💳 **Pagamento con carta per un singolo ciclo.** Un gruppo che usa il borsellino può scegliere, quando crea un ciclo, se i soci lo pagano dal saldo o con la carta quando confermano l'ordine. I cicli con carta sono segnalati in Admin, e i soldi pagati con la carta non toccano il saldo di nessuno fino a "Chiudi i conti". - 🏦 **La causale del bonifico, già compilata per ogni ordine.** Ricarica e ogni ordine nello Storico mostrano la causale da scrivere nel bonifico, con il pulsante Copia, e a chi mandare la contabile. Gli admin scelgono il testo e l'indirizzo in Impostazioni. ### Modificato - 🔒 **Un solo modo chiaro per chiudere un ciclo.** "Chiudi ciclo…" apre una finestra che dice quanti soci verranno addebitati e chiede conferma lì, al posto del messaggio del browser. Le rettifiche dei prezzi stanno dietro "Rettifica prezzi", e se esci dopo averle cambiate l'app chiede prima. Il recap ordini di un ciclo aperto è in sola lettura, perché le correzioni valgono solo dopo la chiusura. - 🛒 **Pulsanti dell'ordine più comodi.** Il "+" resta sotto il dito quando un prodotto passa da 0 a 1, e i lettori di schermo dicono quale prodotto cambia ogni pulsante e la nuova quantità. - 💬 **Messaggi che fai in tempo a leggere.** Errori e avvisi restano più a lungo e si possono chiudere, e un salvataggio non riuscito dice di controllare la connessione. Cancellare un ordine parte da "Annulla", così un Invio per sbaglio non cancella nulla. - ⌨️ **Più comoda con la tastiera.** Ogni pulsante e campo mostra un contorno ben visibile quando ci arrivi con Tab, il link "Vai al contenuto" salta il menu e ogni pagina ha il suo titolo nella scheda del browser. - 🧩 **Stesso aspetto per le stesse cose.** Le conferme in Admin (eliminare un socio, archiviare un prodotto, toglierlo da un ciclo...) usano la finestra dell'app al posto di quella del browser, e stati, link per tornare indietro e pulsanti hanno uno stile unico. - 📲 **Finestre a misura di telefono.** Tutte le finestre (ordine inviato, dettaglio di un ordine passato o di un movimento nello Storico, movimenti di un socio in Cassa, chiusura dei conti, annullamento di un ciclo, fornitore, unione di soci, importazione del listino) salgono dal basso sul telefono con i pulsanti vicino al pollice, si chiudono con Esc o con la ✕ e chiedono prima di buttare quello che hai scritto. - 💰 **Cassa e Soci più ordinati.** Ogni movimento in Cassa si legge allo stesso modo (nome e importo a destra, poi tipo e giorno, poi la nota) con "Modifica" ed "Elimina" sotto; in Soci il ruolo sta accanto al nome e le azioni stanno su una riga, con Invita, Unisci ed Elimina dietro ⋯ su telefono e tablet. Ogni campo e pulsante a icona in Admin ha un nome che i lettori di schermo sanno leggere. - 📱 **Barra in basso più leggera.** I soci vedono quattro voci (Home, Ordine, Storico, Guida) invece di un "Admin" grigio, campanella, cerchio delle iniziali e "?" si toccano più facilmente, e cambiare pagina non sembra più un ricaricamento. - 🔤 **Più facile da leggere.** I prezzi nell'ordine e il testo delle notifiche sono più grandi e nel carattere normale, e il Profilo non mostra più "Utenti" sotto il nome dei soci normali. - 🏠 **In Home prima l'ordine aperto.** Il ciclo in cui puoi ordinare viene prima del saldo, con una sola riga chiara sulla chiusura ("Chiude tra 5 giorni · lun 13 ott, 23:59") e i giorni di ritiro scritti una volta. Il conto alla rovescia compare solo l'ultimo giorno, e dopo la prima visita il benvenuto si riduce a una riga. - 🛒 **Più spazio per fare la spesa nella pagina Ordine.** La barra in basso è una riga sola (totale, saldo dopo e "Conferma"), con il dettaglio dietro "Dettagli"; un ordine rifiutato dice il perché anche sopra il pulsante. "Annulla modifiche" compare solo se hai cambiato qualcosa, i pulsanti + e − sono più grandi, e i prodotti senza un'emoji propria non mostrano più un carrello. - 🏷️ **Trovi i prodotti prima.** Nella pagina Ordine le categorie restano in alto come pulsanti che portano a ogni sezione, "Nel carrello (3)" mostra solo quello che hai scelto, e con più di 15 prodotti una casella di ricerca li trova per nome. - 👆 **Trascina giù per chiudere.** Su telefono le finestre che salgono dal basso (comprese le conferme) si chiudono trascinandole verso il basso; su una conferma vale sempre come "Annulla". La finestra che chiude un ciclo si chiude solo con i suoi pulsanti. - 🔄 **Sempre aggiornata.** Tornando nell'app dopo qualche minuto saldo, ciclo e notifiche si ricaricano, toccare la voce attiva della barra in basso torna in cima e aggiorna, e una riga avvisa quando sei offline. La pagina Ordine non si aggiorna mai mentre la modifichi. - 🔔 **Notifiche più chiare.** Raggruppate per giorno (Oggi, Ieri...), quelle non lette dicono "Nuova" a parole, e toccarne una apre subito la sua pagina. - 🧭 **Una barra Admin più corta.** Ciclo, Cassa, Soci e Catalogo stanno sul telefono senza scorrere, con Statistiche e Impostazioni dietro ⋯ (in fila da computer). Ordini ora è dentro Ciclo, Prodotti e Fornitori dentro Catalogo, e i vecchi link aprono ancora la pagina giusta. - 🗂️ **Un posto per ogni ciclo in Admin.** Scegli un ciclo dall'elenco (a sinistra da computer, "Tutti i cicli" da telefono), poi passa tra Panoramica, Prodotti e Ordini, o Fornitore e Conti quando è chiuso. Ci sono tutti i cicli passati con ricerca e filtri, non solo gli ultimi 15, così anche i più vecchi si possono ancora correggere. - 📋 **Gli ordini del ciclo in una pagina.** Ordini mostra "Per socio" e "Per prodotto" (affiancati da computer) con un solo "Scarica distinta"; a ciclo chiuso pesi e ordini si correggono lì. Lo storico ordini di un socio ora è in Soci, alla voce "Ordini", con il link ai suoi movimenti in Cassa. - 💳 **Prima i conti da chiudere.** In Admin → Ciclo l'elenco parte dai cicli con carta che chiedono ancora "Chiudi i conti" (mai chiusi, da aggiornare dopo una correzione, o con un rimborso non riuscito), poi gli aperti; da telefono stanno entrambi sopra "Tutti i cicli". - 🤝 **Fornitore in tre passi, Conti in un posto solo.** Fornitore mostra, numerati nella pagina, scarica la distinta, inviala, carica quella compilata. Conti mostra cosa il ciclo ha mosso sui saldi, la spedizione e le rettifiche fatte (in sola lettura), come si corregge un ciclo, "Chiudi i conti" per i cicli con carta e, in fondo, l'annullamento. - ✅ **"Da fare ora" in cima ad Admin.** Le tre caselle con i conteggi lasciano il posto al prossimo passo di ogni ciclo, con un solo pulsante: rivedere e chiudere un ciclo scaduto (in rosso, con da quanto), inviare l'ordine al fornitore, registrare i pesi, chiudere i conti; poi i rimborsi da ritentare e i possibili doppioni tra i soci. "Già inviato" e "Consegnato come ordinato" nascondono un passo solo su quel dispositivo. - 🧺 **Un solo catalogo, un solo modulo prodotto.** I prodotti si modificano solo in Catalogo → Prodotti; ogni fornitore in Fornitori porta ai suoi prodotti ("5 prodotti nel catalogo →"), e modificare un prodotto non gli toglie più l'icona. L'import guidato è la via principale per caricare un listino, con il modello e il caricamento diretto sotto "Altri formati". I moduli per aggiungere un socio o un fornitore restano chiusi finché non servono. - 🖥️ **Una vera versione da computer.** Da computer l'app usa lo stesso riquadro più largo su ogni pagina, con logo, menu, campanella e avatar su una riga. La Home è su due colonne (il ciclo e il tuo ordine a sinistra, saldo, ritiro e movimenti a destra); le pagine da leggere restano in una colonna comoda. Campanella, avatar e Home (per Ricarica) mostrano dove sei. - 📰 **Novità più corte, contatti più chiari, accesso con il logo.** "Cosa è cambiato" apre le ultime tre versioni e richiude le altre. I pulsanti dei contatti nella guida dicono a cosa servono ("Scrivi al gruppo", "Problemi tecnici") e compaiono una volta sola se l'indirizzo è lo stesso. La pagina di accesso mostra il logo del gruppo, e un errore viene letto dai lettori di schermo. - 🎨 **Lo stesso aspetto ovunque.** Il saldo ha lo stesso segno e formato in Home, Storico e Ricarica, e gli avvisi di rettifica non scrivono più "€ EUR". Gli ultimi movimenti in Home sono uguali a quelli dello Storico e lo aprono, la guida e le pagine vuote usano le icone dell'app al posto delle emoji, e le schede hanno tutte gli stessi angoli. - 🛒 **Ordine e Storico da computer.** Da computer la pagina Ordine tiene il carrello a destra (prodotti scelti, totale, saldo dopo e "Conferma"), accanto al catalogo. Lo Storico mostra l'elenco a sinistra e l'ordine o il movimento scelto a destra; le schede Ordini e Movimenti sono nell'indirizzo, così un link apre quella giusta. ## [1.25.0] - 7 ottobre 2026 *Un benvenuto per chi arriva, e la pagina del gruppo nella guida.* ### Aggiunte - 🏠 **Il nostro gruppo, in cima alla guida.** Gli admin scrivono in Impostazioni dove e quando si ritira, chi contattare e le regole del gruppo; i soci lo trovano per primo nella guida, e anche la ricerca lo trova. - 👋 **Un benvenuto per chi arriva.** La prima volta in Home una scheda in pochi passi spiega come funziona il gruppo, il saldo (o come si paga), l'ordine, il ritiro, gli avvisi, la famiglia, l'app sul telefono e dove trovare aiuto. I suoi link non fanno perdere il segno: una barra nella pagina aperta riporta al passo. Si chiude con un tocco e la Guida può mostrarla di nuovo. - 🔍 **Cosa i soci non trovano.** In Impostazioni l'elenco delle ricerche nella guida rimaste senza risultati (solo le parole e quante volte, mai chi ha cercato), per aggiungere quello che manca. ### Risolto - 📱 **Totale dell'ordine su iPhone, stavolta davvero.** Nell'app installata il totale poteva ancora mostrare la cifra vecchia sotto quella nuova; ora totale e saldo si ridisegnano a ogni modifica. ## [1.24.0] - 6 ottobre 2026 *Le tue impostazioni in un posto solo, e una guida in cui cercare.* ### Aggiunte - 👤 **Il tuo Profilo.** Tocca il cerchio con le tue iniziali, in alto a destra: il tuo nome (ora puoi cambiarlo), le email con cui entri, famiglia, notifiche, saldo, l'app da installare, la guida e il pulsante Esci, tutto in un posto. ### Modificato - 🧭 **Intestazione più pulita.** Email e pulsante Logout lasciano il posto al cerchio del Profilo; le preferenze delle notifiche e la Famiglia ora stanno dentro il Profilo (i vecchi link funzionano ancora). - 📖 **Una guida in cui cercare.** La Guida ora ha la ricerca e gli argomenti, con schede passo passo che aprono la pagina giusta dell'app. Il "?" accanto al titolo di Ordine, Ricarica, Famiglia e Notifiche apre la scheda giusta. Parla solo di ciò che il tuo gruppo usa, e le risposte sono aggiornate alle ultime novità. ## [1.23.0] - 6 ottobre 2026 *Ordini in famiglia, e un carrello che non perde le modifiche.* ### Aggiunte - 👯 **Account doppi più facili da trovare.** Gli admin vedono in Soci le persone che sembrano avere due account e possono unirli con un tocco. - 👨‍👩‍👧 **Ordinare in famiglia.** Si può invitare un familiare a condividere carrello, saldo e storico degli ordini, ognuno entrando con la propria email. Si attiva dalle impostazioni del gruppo; poi si invita da Notifiche → ⚙ → Famiglia. ### Modificato - 🔑 **Messaggio più chiaro quando la tessera non risulta.** Se la tessera è legata a un'altra email, l'app ti dice di entrare con quella. - 💶 **Cassa più ordinata per gli admin.** Il modulo delle ricariche si apre solo quando serve e i saldi sono divisi per ruolo. ### Risolto - 🛒 **Il carrello non perde più le modifiche.** Se lo cambi dal telefono e poi salvi dal computer, l'app ti mostra il carrello aggiornato invece di sovrascriverlo. - 📱 **Totale dell'ordine leggibile su iPhone.** Aggiungendo un prodotto, il totale e il saldo dopo l'ordine ora si aggiornano correttamente. ## [1.22.0] - 4 ottobre 2026 *Una persona, un account: i doppioni ora si possono unire.* ### Aggiunte - 🔗 **Unire due account dello stesso socio.** In Admin → Soci, "Unisci" porta un account doppione dentro quello che resta: ruolo ed email principale restano, l'altro indirizzo diventa la secondaria, e ordini aperti, notifiche e saldo passano. Lo stesso viene proposto se nel modulo di modifica si scrive l'indirizzo di un altro socio. Migrazione `0027_member_merge.sql`. ### Risolto - 🗑️ **Si può di nuovo eliminare un socio che non ha mai ordinato.** In Admin → Soci l'eliminazione falliva con un errore del database se l'account aveva ricevuto una notifica (quasi tutti i nuovi ricevono quella del ciclo aperto); ora l'account si elimina insieme alle sue notifiche. ## [1.21.1] - 4 ottobre 2026 *Note che i soci possono leggere, e un elenco soci che sta in un telefono.* ### Risolto - 📝 **Le note arrivano ai soci.** Le note che l'admin scrive su un ciclo ora compaiono in Home e in cima alla pagina Ordine, quelle di ogni prodotto sotto il nome nel modulo d'ordine e nel riepilogo. Prima le vedevano solo gli admin. - 📱 **Elenco soci leggibile da telefono.** In Admin → Soci gli indirizzi email non finiscono più sotto i pulsanti: l'elenco mostra nome, ultimo accesso e azioni, gli indirizzi sono nel modulo di modifica, e sugli schermi stretti i pulsanti stanno sotto il nome. ## [1.21.0] - 3 ottobre 2026 *Entrare con il codice dell'email, e l'app sulla schermata Home del telefono.* ### Aggiunte - 🔢 **Entra anche con un codice.** L'email di accesso ora contiene anche un codice di 6 cifre: scrivilo nella pagina di accesso quando il link si apre nel browser sbagliato o su un altro dispositivo. Vale 15 minuti come il link, tre tentativi per codice. - 📱 **Installa l'app sul telefono.** Da telefono la Home propone di aggiungere l'app alla schermata Home (il pulsante Installa su Android, i passaggi su iPhone), con icone ricavate dal logo del tuo gruppo; la Guida lo spiega. ### Risolto - 🧩 **La descrizione dell'app torna raggiungibile.** Stava dietro l'accesso: un browser che la chiedeva senza sessione (sempre, dalla pagina di accesso) riceveva la pagina di login, quindi l'app non si installava bene. ## [1.20.0] - 1 ottobre 2026 *Notifiche che dicono cosa coprono, una Cassa che dà un nome a ogni movimento e Next.js 16 sotto il cofano.* ### Modificato - 🔔 **Preferenze di notifica più chiare.** I quattro gruppi dicono cosa coprono: nuovo ciclo aperto, addebiti e pagamenti (compresi il conguaglio e le conferme dei pagamenti online), modifiche all'ordine (compreso un ciclo annullato) e saldo e rimborsi. Le tue scelte salvate restano; le conferme di pagamento ora seguono "Addebiti e pagamenti". - [tecnico] 🧰 **Next.js 16 e TypeScript 7.** Stessa app, fondamenta più nuove; a chi la installa da sé serve Node.js 20.19 o successivo, e il lint si lancia con `npm run lint`. - [tecnico] 🌙 **Controllo notturno più solido.** Il controllo dei conti non aspetta più il backup, e una notte fallita o bloccata apre una issue su GitHub. ### Risolto - 🏷️ **Cassa dà un nome a ogni movimento.** I vecchi rimborsi e pagamenti con carta, le spedizioni e le rettifiche mostravano nel badge un codice tecnico come `ORDER_REFUND`; ora si leggono "rimborso carta", "pagamento ordine", "spedizione" e così via, e un tipo sconosciuto mostra un semplice "movimento". - ✏️ **Modificare un ciclo dopo la chiusura.** Salvare titolo o ritiro di un ciclo da un modulo aperto prima della chiusura non fallisce più con "le spese non si possono più cambiare" quando le spese non sono state toccate. - 👥 **I dettagli del ciclo chiuso elencano ogni socio addebitato.** Un socio con spedizione o spese di preparazione ma senza più righe d'ordine ora compare nell'elenco, così i soci mostrati tornano con il totale. - 💬 **Messaggio sul credito più chiaro.** La scheda dei saldi dice ora che la differenza pagata è un tuo credito; in inglese due messaggi dell'admin indicano anche il tetto delle spese in euro. ## [1.19.0] - 1 ottobre 2026 *Installarla per il proprio gruppo in mezz'ora, e spese di preparazione che diventano un addebito vero e controllato.* ### Aggiunto - [tecnico] 🚀 **Installala per il tuo gruppo.** Una guida passo passo (`docs/self-hosting.md`, in inglese) con il pulsante Deploy to Vercel, che crea il progetto e il suo database Neon e applica tutte le migrazioni al primo build; `docs/brand.example.json` elenca tutti i campi del brand. - [tecnico] 👑 **Primo admin di un'installazione nuova.** L'indirizzo in `BOOTSTRAP_ADMIN_EMAIL` diventa admin al primo accesso, solo finché il gruppo non ha un admin; lo Stato della configurazione dice quando togliere la variabile. - 🧾 **Spese di preparazione ordine.** Un ciclo può addebitare una quota per commissioni bancarie e spese di gestione, in entrambe le modalità di pagamento: una percentuale dei prodotti o un importo fisso per socio, fino al 25% o a 10 €. I soci la vedono prima di ordinare; si addebita alla chiusura come movimento a sé e viene controllata ogni notte. Nota di aggiornamento: applica `drizzle/0026_handling_charge.sql` subito prima del deploy se `MIGRATE_ON_BUILD` è spento. ### Modificato - 💳 **Pagamento per ordine: la quota è un costo, non una stima.** Resta all'associazione; il conguaglio regola solo prodotti e spedizione. Con la spedizione proporzionale ogni socio paga la sua parte al conguaglio. - [tecnico] 🩹 **Le installazioni nuove non si rompono più nella home.** Tre colonne dei cicli mancavano nelle migrazioni; una migrazione in più le aggiunge (non fa nulla sulle installazioni esistenti). Un test in CI confronta tutto lo schema con un database vuoto migrato. Nota di aggiornamento: applica `drizzle/0025_schema_catch_up.sql`. - [tecnico] 🧭 **Lo Stato della configurazione trova gli errori del brand.** Un campo che l'app non conosce (un errore di battitura) o un brand che non si legge compaiono, con il motivo, in Impostazioni e in `npm run doctor`. - [tecnico] 🏗️ **Migrazioni al build solo in produzione.** Con `MIGRATE_ON_BUILD=true` i build di anteprima non migrano più: lo fanno solo quelli di produzione (e quelli fuori da Vercel). ## [1.18.0] - 1 ottobre 2026 *Pagare ogni ordine con la carta, chiudere i conti a fine ciclo, e un registro che non riscrive mai la storia.* ### Aggiunto - 💳 **Pagamento per ordine, selezionabile.** Gli admin possono passare il gruppo al pagamento di ogni ordine con la carta da Impostazioni, quando nessun ciclo è in corso; la card elenca cosa impedisce il cambio e i saldi prima di confermare. Nota di aggiornamento: applicare `drizzle/0024_settlement.sql` prima del deploy; il pagamento per ordine richiede l'euro e una chiave Stripe valida. - 🧮 **Chiudi i conti.** Su un ciclo pagato per ordine, chiuso o annullato, "Chiudi i conti" rimborsa sulla carta quello che ogni socio ha pagato oltre i costi definitivi, chiede quanto manca e abbuona le differenze sotto 0,50 €. Il ciclo mostra a che punto è: da conguagliare, rimborsi in corso, conti chiusi, da aggiornare, rimborso non riuscito. - 🔴 **Da saldare e credito.** Se i costi hanno superato quanto pagato, Home e la pagina dei saldi mostrano "Da saldare" con "Paga ora"; i nuovi pagamenti d'ordine aspettano che sia saldato. Un credito compare come denaro che l'associazione restituisce. - 🧾 **Paga fuori app.** Nel pagamento per ordine un admin può segnare chi paga in contanti: conferma gli ordini senza carta, il tesoriere registra i soldi e il conguaglio lo esclude. - 📚 **Storico e guida del pagamento per ordine.** Ogni ciclo nello Storico mostra pagato, costi, rimborsi e netto; guida e FAQ spiegano la quota, il conguaglio e i tempi dei rimborsi. ### Modificato - 🧾 **Le correzioni non riscrivono la storia.** Modificare o eliminare un movimento in Cassa, ricalcolare la spedizione di un ciclo chiuso o importare la distinta del fornitore ora annullano il movimento con uno storno e, se serve, aggiungono quello corretto; i soci vedono un solo movimento con "corretto il". Nota di aggiornamento: applicare `drizzle/0023_ledger_append_only.sql` subito prima del deploy (il database rifiuta da quel momento le modifiche ai movimenti passati). ## [1.17.0] - 30 settembre 2026 *Accesso con un link via email, e le basi per pagare ogni ordine.* ### Aggiunte - ✉️ **Accesso con un link via email.** Scrivi il tuo indirizzo e ricevi un link che ti fa entrare, senza bisogno di un account Google; Google resta per chi lo preferisce. Gli admin possono mandare il link come invito da Soci e vedono l'ultimo accesso di ogni socio. Nota di aggiornamento: applicare `drizzle/0022_auth_sessions.sql` prima del deploy; l'invio email (Resend) deve essere configurato; dopo l'aggiornamento tutti rientrano una volta; l'indirizzo di ritorno di Google non cambia. - [tecnico] 🧮 **Controllo notturno dei conti.** Dopo il backup, un controllo in sola lettura verifica che pagamenti, rimborsi e addebiti tornino, e segnala subito se non tornano. - 🧭 **Stato della configurazione.** In Impostazioni si vede cosa è collegato in questa installazione (database, accesso, email, pagamenti...) e cosa manca, solo per nome; `npm run doctor` stampa lo stesso. Le note di aggiornamento per versione stanno in `docs/upgrading.md`, e `MIGRATE_ON_BUILD=true` applica le migrazioni a ogni build di produzione (facoltativo). - 💳 **Pagamento per ordine, le basi.** L'app ora sa incassare il pagamento di un ordine con Stripe, rimborsarlo se l'ordine viene annullato o se il pagamento arriva a ordini chiusi, e riprovare un rimborso dalla Cassa. Non ancora selezionabile: diventa un'opzione in Impostazioni insieme al conguaglio. Nota di aggiornamento: applicare `drizzle/0021_pay_per_order.sql` prima del deploy; nessuna variabile nuova, nessun evento Stripe nuovo. ### Modificato - 🔕 **Niente email predefinita all'apertura del ciclo.** Chi non ha scelto riceve l'avviso "ciclo aperto" solo nell'app e può accendere l'email nelle preferenze; chi aveva già scelto mantiene la sua scelta. ## [1.16.1] - 30 settembre 2026 *Un layout da computer, e le basi per tenere d'occhio la salute dell'app.* ### Aggiunte - [tecnico] 🩺 **Controllo di stato e segnalazione degli errori facoltativa.** `/api/health` dice se l'app e il suo database rispondono, e gli errori del server possono arrivare a Sentry. Nota di aggiornamento: nessuna migrazione; `SENTRY_DSN` è facoltativa, senza non cambia nulla. ### Modificato - 🖥️ **Un vero layout da computer.** Da computer il menu passa in alto e le pagine tengono una larghezza comoda da leggere; solo Admin usa la finestra larga, e in Cassa i form stanno accanto ai saldi dei soci. - 🔤 **Testi di lettura un po' più grandi.** Descrizioni ed elenchi nelle pagine dei soci passano da 13 a 14 px. - ✉️ **La tua email, senza ingombro.** Da telefono non occupa più una riga sotto il logo: la trovi nella pagina Notifiche. ## [1.16.0] - 30 settembre 2026 *Testi che si leggono, con i colori di qualsiasi gruppo.* ### Modificato - 👓 **Testi che si leggono.** Pulsanti, link, etichette e importi hanno ora abbastanza contrasto in ogni schermata: testo scuro sui pulsanti colorati, tonalità più scure per i testi colorati e grigi, un rosso più profondo per gli importi negativi. - 🎨 **Colori che seguono la palette del gruppo.** I colori dei testi si calcolano dai colori del brand, così un gruppo con un'altra palette resta leggibile. Nota di aggiornamento: nessuna azione richiesta; i colori del tema devono essere esadecimali (`#rgb` o `#rrggbb`), altrimenti si usa la palette di default con un avviso `[brand]` nei log. - 🔎 **Niente sotto i 12 px.** Etichette, badge e didascalie che erano a 10 o 11 px sono ora a 12 px, e da telefono i campi dei form non ingrandiscono più la pagina quando li tocchi. ### Risolto - 💶 **Saldo su una riga.** In Home il saldo non va più a capo dopo il segno nei formati inglesi. ## [1.15.0] - 30 settembre 2026 *Rimborsi sulla carta che puoi seguire.* ### Aggiunte - ⚠️ **Rimborsi non andati a buon fine.** Se un rimborso sulla carta fallisce dopo l'invio, l'importo torna sul saldo, lo Storico mostra "Rimborso non riuscito", e il socio e gli admin vengono avvisati di come verrà restituito. ### Modificato - 💳 **Rimborsi sulla carta registrati uno per uno.** Ogni rimborso di una ricarica online viene registrato una volta sola, appena Stripe lo accetta, anche quando arriva in più passaggi (migrazione `0020`). ## [1.14.1] - 30 settembre 2026 *Importi più ordinati nelle Impostazioni.* ### Risolto - ⚙️ **Saldo massimo con i centesimi.** Le Impostazioni mostrano un importo salvato come 35,20 € con entrambe le cifre dei centesimi, non più 35,2. ## [1.14.0] - 29 settembre 2026 *Le impostazioni dei pagamenti in app, e l'ordine che ti aspetta.* ### Aggiunte - ⚙️ **Impostazioni dei pagamenti per gli admin.** Una nuova tab Impostazioni (icona a ingranaggio) fissa lo scoperto massimo del gruppo, un saldo massimo e i canali di ricarica che vedono i soci: bonifico (intestatario e IBAN) e pagamento online. Finché un admin non salva non cambia nulla (migrazione `0019`). - 🛒 **L'ordine ti aspetta.** Le modifiche all'ordine si salvano mentre le fai: esci dalla pagina e rientra, anche da un altro dispositivo, e le ritrovi, segnate come "Modifiche non ancora confermate" finché non le confermi o le annulli. - 🧾 **Dettaglio dei movimenti.** Tocca un movimento nello Storico per vedere data e ora, ciclo, nota, metodo e riferimento, lo stato del pagamento online e chi l'ha registrato. ### Modificato - 💶 **Le ricariche rispettano il saldo massimo.** La ricarica online propone solo quanto ci sta, il bonifico dice quanto puoi ancora ricaricare, e chi ha un debito trova come prima scelta l'importo esatto per saldarlo. - 🏦 **La Cassa segnala i saldi sopra il massimo.** Una ricarica registrata in Cassa non viene mai rifiutata, ma l'admin viene avvisato se porta il saldo oltre il massimo, e un nuovo filtro elenca quei soci. ## [1.13.0] - 29 settembre 2026 *Una Cassa più completa, e uno storico che torna con il saldo.* ### Aggiunte - 💸 **Movimenti in uscita in Cassa.** Gli admin possono registrare la restituzione del saldo a un socio (mai oltre il saldo), un addebito manuale o la quota associativa, ognuno con una causale che il socio legge nella notifica. - 🏦 **Ricarica manuale con metodo e riferimento.** Si cerca il socio per nome o email, si sceglie il metodo (bonifico, contanti, Satispay, altro) e si indica il CRO/TRN: un riferimento già usato viene rifiutato, una ricarica simile negli ultimi giorni chiede conferma, e prima di salvare c'è un riepilogo (migrazione `0018`). - 🧺 **Scelta del ciclo quando ce n'è più di uno aperto.** "Ordine" elenca i cicli aperti con il fornitore invece di aprire il primo, e il pulsante del countdown in home apre il suo ciclo. ### Modificato - 📒 **Lo storico torna con il saldo.** Ogni ciclo mostra prodotti (dopo le pesate), spedizione, correzioni e il totale addebitato sul saldo, e ogni movimento ha un nome chiaro e la sua icona: Ricarica, Spedizione, Rimborso, Rettifica, Restituzione saldo, Quota associativa. - ➕ **Importi con il segno.** Saldo e movimenti mostrano sempre + o -, e in home un saldo negativo si legge "Da ricaricare". - 🚚 **La spedizione segue le modifiche agli ordini chiusi.** Modificare l'ordine di un socio dopo la chiusura ridivide la spedizione di tutti sui totali effettivi (dopo le pesate), tranne quando arriva dalla distinta del fornitore; riceve una notifica solo chi vede cambiare la propria quota. - 🔐 **Un socio disattivato esce subito.** Disattivare un socio, admin compresi, chiude la sua sessione alla richiesta successiva invece che alla scadenza. ### Risolto - 📧 **Email e alias non si ripetono più tra soci.** Salvare un socio con un'email o un'email secondaria già usata da un altro, anche con maiuscole diverse, viene rifiutato indicando chi la usa (migrazione `0017`). - ⚠️ **Messaggi d'errore leggibili.** In produzione i rifiuti previsti (ciclo chiuso, campo mancante, ordine cambiato nel frattempo) mostrano il loro testo invece di un errore generico, e la pagina dell'ordine si ricarica da sola se il ciclo si è chiuso. ## [1.12.2] - 29 settembre 2026 *Ricariche online più piccole.* ### Modificato - 💶 **Ricariche online da 0,50 €**, l'importo minimo accettato da Stripe (prima 20 €). ## [1.12.1] - 28 settembre 2026 *Dati per la ricarica più chiari.* ### Modificato - 🏦 **IBAN a gruppi di quattro** nella pagina Ricarica, più facile da ricontrollare a occhio; il pulsante Copia lo copia comunque senza spazi. - 📖 **Guida e FAQ rimandano alla pagina Ricarica** per il bonifico e il pagamento online. ## [1.12.0] - 28 settembre 2026 *Ricarica il saldo online.* ### Aggiunte - 💳 **Ricarica online.** Una nuova pagina "Ricarica" (dalla card del saldo in home) permette di ricaricare con carta o con gli altri metodi attivati dal gruppo, tramite una pagina di pagamento Stripe. Il saldo si aggiorna da solo appena il pagamento è confermato, e i rimborsi fatti da Stripe compaiono nello storico. - 🏦 **Dati per il bonifico nella stessa pagina.** Se il gruppo li imposta, la pagina mostra anche intestatario, IBAN e causale per il bonifico, ognuno con il pulsante per copiarlo. ### Modificato - 🔒 **I pagamenti online restano legati a Stripe.** In Cassa le ricariche e i rimborsi arrivati da un pagamento online non si possono più modificare o eliminare: i soldi si sono mossi su Stripe, quindi si corregge con un rimborso lì o con una rettifica separata. ## [1.11.0] - 28 settembre 2026 *Aperta a tutti i soci con tessera attiva, con flussi di denaro più sicuri.* ### Aggiunte - 🪪 **I soci con tessera attiva possono entrare da soli.** Al primo accesso con Google, con la stessa email della tessera, l'app la verifica e crea l'account, senza che un admin debba abilitarlo. La tessera viene ricontrollata prima che un ordine aumenti, e la pagina di login spiega cosa fare se l'accesso viene negato. - 💳 **Limite di credito.** Un ordine che porterebbe il saldo (contando gli ordini ancora aperti su altri cicli) sotto il limite del gruppo viene rifiutato, indicando l'importo ancora disponibile; ridurre o cancellare un ordine funziona sempre. - 🔐 **Link all'informativa privacy** nella pagina di login e nel footer. ### Modificato - 👥 **Ruoli e accesso ai cicli usano gli stessi tre nomi: Admin, Attivi, Utenti.** Gli admin vedono tutti i cicli, gli Attivi i cicli standard e quelli privati, gli Utenti solo quelli standard. La scheda socio non propone più Admin per un ruolo non riconosciuto, e "membri abilitati" indica ora l'interruttore che abilita un account. ### Risolto - 🕰️ **Gli orari seguono Roma ovunque.** Chiusura e ritiro non si spostano più di due ore tra card, moduli ed email, un ciclo smette di accettare ordini all'ora che mostra, e il passaggio all'ora solare del 25 ottobre è gestito. - 🧾 **Modificare un movimento in Cassa ne conserva il segno.** Cambiare solo la nota di un rimborso non lo trasforma più in un addebito, e un importo vuoto viene rifiutato invece di corrompere il saldo. Addebiti ordine e spedizione si correggono con un nuovo movimento, non modificandoli. - ⚖️ **Modificare un ordine chiuso conserva le quantità pesate**, così una nuova pesata non può più rimborsare due volte un socio. - 🚚 **Salvare un ciclo chiuso conserva la spedizione importata dalla distinta**, invece di azzerare la quota di tutti e inviare notifiche sbagliate. - 🔒 **La chiusura di un ciclo è tutto-o-niente.** Addebiti, spedizione e cambio di stato vengono scritti insieme, e il database rifiuta un secondo addebito per lo stesso ciclo. ### Sicurezza - [tecnico] ⚡ **Next.js aggiornato alla 15.5.25**, che corregge due vulnerabilità critiche di esecuzione di codice da remoto. Una richiede un server ospitato su Windows (noi giriamo su Vercel/Linux); l'altra riguardava l'ottimizzazione delle immagini, già limitata al solo host del logo del brand. Anche `sharp` è passato alla 0.35.4. - [tecnico] 📤 **Un file fornitore malevolo non poteva più bloccare un'importazione distinta.** Ri-importare un file `.ods` (es. da un salvataggio con LibreOffice) usava un parser XML con un bug di denial-of-service su lunghe sequenze di spazi, ora corretto. - [tecnico] 📊 **Una vulnerabilità dormiente nella libreria dei fogli di calcolo, corretta comunque.** `exceljs` include una versione vecchia e vulnerabile di `uuid`; non sfruttabile qui perché l'unico punto in cui viene usata non tocca il percorso vulnerabile, ma fissata comunque alla versione corretta. - [tecnico] 🧹 **Una dipendenza di sviluppo** (`js-yaml`) con una vulnerabilità di denial-of-service aggiornata. Non ha mai raggiunto gli utenti. --- ## [1.10.3] - 6 settembre 2026 *Stesso prodotto, stesso scaffale.* ### Correzioni - 🥕 **Un prodotto non si spezza più tra categorie diverse.** "Cicoria" (o qualsiasi altro prodotto) finisce sempre nella stessa categoria, qualunque sia la varietà o il lotto d'importazione da cui arriva — il riconoscimento dal nome vince sulla colonna categoria del fornitore, incoerente da un file all'altro, ovunque i prodotti vengano caricati in un ordine. - 🔤 **I prodotti sono finalmente ordinati per davvero.** La schermata dell'ordine (e ogni altro elenco prodotti) è in ordine alfabetico per prodotto, poi varietà, poi formato e prezzo, invece di seguire l'ordine casuale dell'ultima importazione. --- ## [1.10.2] - 30 agosto 2026 *Meno verdure perse dentro "Altro".* ### Correzioni - 🥬 **I prodotti finiscono più spesso nella categoria giusta.** Un file fornitore che etichetta quasi tutto come "Altro"/"Varie" non sovrascrive più un riconoscimento sicuro — una zucchina, una melanzana, una patata finiscono ora in Verdura anche se il foglio del fornitore non si è preso la briga di specificarlo. - 🌿 **Più prodotti ottengono un'icona automatica.** Basilico, prezzemolo e altre erbe aromatiche — anche in nomi composti come "Basilico viola da trapiantare" — ottengono ora un'icona coerente invece del carrello generico. Vengono riconosciuti anche i plurali (zucchine, carote, funghi, asparagi...) e alcuni prodotti prima senza icona (pancetta, gamberi, calamari, mandarino, olive) ora ne hanno una. --- ## [1.10.1] - 27 agosto 2026 *Fare in modo che la casella del fornitore la veda davvero.* ### Correzioni - 📬 **L'email dell'ordine al fornitore finisce meno spesso nello spam.** Le risposte arrivano ora direttamente all'admin che l'ha inviata, l'oggetto parte dal nome della tua cooperativa invece che dall'app, e il messaggio viene inviato in HTML oltre che in testo semplice — tre segnali che i filtri antispam usano per fidarsi di un messaggio. --- ## [1.10.0] - 27 agosto 2026 *Una via d'uscita quando un ciclo va storto dopo che è già stato chiuso.* ### Aggiunte - 🚫 **Annulla un ciclo chiuso e rimborsa tutti.** Quando un fornitore non consegna un ordine già addebitato, un admin può ora annullare quel ciclo: ogni socio addebitato viene riaccreditato per intero (prodotti, e spedizione a meno che tu non la escluda), con un motivo obbligatorio e una traccia completa — un badge "annullato" sul ciclo, un movimento segnalato nello storico di ogni socio, una riga di audit log e una notifica a ogni socio rimborsato. --- ## [1.9.0] - 7 agosto 2026 *Una notifica in meno, e un ingranaggio in meno dietro le quinte.* ### Rimosse - 🔕 **Il promemoria "il ciclo sta per chiudere" non c'è più.** Arrivava nelle notifiche quando un ciclo stava per chiudere e non avevi ancora ordinato; la notifica di apertura ciclo dice già la data di chiusura, quindi era in gran parte la stessa informazione ripetuta. - ⚙️ **Il suo interruttore è sparito dalle impostazioni notifiche.** Una riga in meno da leggere; i promemoria ricevuti in passato restano nell'elenco delle notifiche. --- ## [1.8.1] - 28 luglio 2026 *Aggiornamenti di sicurezza per il login e per la gestione delle immagini.* ### Sicurezza - [tecnico] 🔒 **Auth.js aggiornato alla versione che corregge quattro vulnerabilità**, due delle quali critiche (`next-auth` 5.0.0-beta.32, `@auth/core` 0.41.3). Nessuna era sfruttabile qui — l'app non ha login via link email, non chiama mai `getToken()`, ha un solo provider OAuth senza collegamento di account, e ogni controllo di accesso legge `session.user.email` invece della semplice esistenza dell'oggetto di sessione — ma la correzione è un aggiornamento minimo, quindi non c'era motivo di rimandare. - [tecnico] 🖼️ **L'endpoint delle immagini non accetta più qualsiasi indirizzo su internet.** Prima consentiva `https://**`, che in un'installazione self-hosted trasforma `/_next/image` in un proxy aperto: chiunque poteva far scaricare al server immagini arbitrarie e darle in pasto alla libreria di elaborazione. Ora è ammesso esattamente l'indirizzo del logo del gruppo, preso dalla configurazione del deploy stesso. - [tecnico] ⚡ **Next.js aggiornato alla 15.5.22** per una correzione su un blocco del servizio nell'ottimizzazione delle immagini, e la libreria di elaborazione forzata a una versione con `libvips` corretto (`sharp` 0.35.3), che a monte non è ancora stata adottata. - [tecnico] 🧹 **Due dipendenze di solo sviluppo** con vulnerabilità di blocco del servizio (`js-yaml`, `brace-expansion`) aggiornate. Non sono mai arrivate agli utenti. --- ## [1.8.0] - 20 luglio 2026 *Confermare un ordine ora si vede, e puoi ripensarci fino alla chiusura del ciclo.* ### Aggiunte - ✅ **Confermare un ordine apre una conferma vera.** Un riquadro riepiloga cosa è stato inviato e fino a quando puoi cambiarlo, al posto del messaggino che spariva dopo un secondo. - 📋 **Al rientro trovi il tuo ordine confermato.** La pagina ordine si apre sul riepilogo di quello che hai in archivio — prodotti, quantità, totale, saldo dopo — invece di riportarti nella lista prodotti. - ✏️ **Modifica o cancella quando vuoi, fino alla chiusura del ciclo.** Entrambe le azioni stanno sotto il riepilogo; la cancellazione chiede conferma e rimuove l'ordine, così alla chiusura non ti viene addebitato nulla. ### Modificato - 📰 **Il changelog si legge come delle note di rilascio, non come un rapporto.** Punti brevi con emoji a tema, una riga di sintesi per ogni versione e categorie a colpo d'occhio. - 🔔 **Il promemoria di chiusura può arrivare fino a ~3 ore prima** (prima erano esattamente 2). Il job schedulato non gira a intervalli perfettamente regolari, e la finestra più larga evita che salti un ciclo. - 🤝 **Scegliere un fornitore è obbligatorio all'apertura del ciclo**, così un ciclo non può più chiudersi senza. - 🔤 **Niente testo sotto i 10px.** 55 micro-etichette nelle viste admin e socio sono state alzate. Verificato a 375px: nessuno sbordo. ### Risolto - 🤝 **Il fornitore ora si può impostare o correggere su un ciclo chiuso.** Il campo spariva alla chiusura, lasciando bloccato per sempre un ciclo creato senza. - 🔒 **Un ordine confermato nell'istante in cui l'admin chiude il ciclo non può più passare senza addebito.** Il salvataggio blocca il ciclo nella stessa transazione: o la chiusura aspetta il salvataggio, o il salvataggio viene rifiutato in modo pulito. - 🛡️ **Gli account disattivati non possono più agire con una sessione ancora aperta.** Ordini e azioni admin ricontrollano il flag attivo a ogni richiesta, e le quantità sono validate prima di scrivere. - 🌍 **Il riquadro "Novità" nella Guida segue la lingua dell'app.** Sui deploy inglesi mostrava il teaser italiano. - 🎨 **La pagina 404 è tradotta e usa i colori del gruppo.** Entrambe le pagine di errore avevano colori fissi, proprio sulle pagine che saltano il layout tematizzato. - 🗣️ **Le ultime stringhe italiane sui deploy inglesi** — la notifica di rettifica ordine e l'avviso di saldo negativo — ora seguono la lingua dell'app. --- ## [1.7.0] - 10 luglio 2026 *Preferenze notifiche con canale email, e import guidato del listino del fornitore.* ### Aggiunte - 🔔 **Preferenze notifiche per socio, con l'email come canale opzionale.** Campanella → ⚙ permette a ognuno di scegliere app e/o email per categoria. Arrivano due eventi nuovi: apertura del ciclo e promemoria prima della chiusura per chi non ha ancora ordinato. - 📥 **Import guidato del listino fornitore.** Una procedura in tre passi legge l'`.xlsx` o il `.csv` del fornitore, riconosce la riga di intestazione e il fornitore, ti fa mappare quello che non ha capito e mostra un'anteprima riga per riga prima di scrivere. - 📦 **Stato "Catalogo in preparazione" nel form ordine**, così un ciclo aperto senza prodotti non sembra più rotto. - 🔒 **Limite di 10 MB sugli upload admin**, controllato prima ancora di decodificare il file, più una protezione contro le bombe di decompressione sui `.ods`. - [tecnico] 🗄️ **Indici unici su righe d'ordine e prodotti per ciclo**, così import concorrenti non possono infilare duplicati oltre i controlli applicativi (migrazione `0008`). - [tecnico] 🧪 **Test sulle funzioni pure che toccano i soldi** — riparto spedizione, parser del changelog, euristiche di intestazione, lettura numeri da foglio. Suite a 78 test. ### Modificato - 📅 **Ritiri più facili da inserire.** Il secondo ritiro è opzionale dietro un interruttore, e gli orari si scelgono da un menu a slot di 15 minuti: le 19:30 sono sempre selezionabili invece di essere rifiutate come non valide. - 📤 **La distinta compilata si può caricare anche in `.ods` o `.csv`.** Con il `.csv`, che non può portare la mappatura nascosta, i nomi vengono abbinati e tutto ciò che è ambiguo viene segnalato e saltato, mai indovinato. - ✏️ **Le due strade di rettifica nel recap ordini ora sono distinte** — ✎ Prodotti per le quantità, una ✎ su ogni riga per peso o prezzo effettivo — con un suggerimento che funziona anche su telefono, dove non c'è il passaggio del mouse. - 🖥️ **Riga "Carica prodotti" più ordinata** in Admin → Prodotti: il menu del fornitore di destinazione ha una riga sua ed etichettata, e le tre azioni restano leggibili su mobile. ### Risolto - 🍆 **Emoji suggerite sbagliate** per melanzana, riso e peperoni — sovrapposizioni nella tabella "vince il primo che combacia", ora fissate da test di regressione. - 🛒 **Il salvataggio dell'ordine è atomico.** Cancellazione e inserimento erano due richieste separate: un'interruzione nel mezzo poteva lasciare l'ordine vuoto senza dirlo. - 🌍 **I file caricati corrotti mostrano un errore tradotto** invece del messaggio inglese della libreria, e le ultime tre stringhe italiane fisse nell'admin seguono la lingua. - 📱 **I pulsanti del ciclo aperto non escono più dallo schermo**, e le righe data/ora dei ritiri vanno a capo sui telefoni stretti. Verificato fino a 320px. --- ## [1.6.0] - 21 maggio 2026 *Distinte fornitore che fanno andata e ritorno, rettifiche riga per riga e statistiche vere.* ### Aggiunte - 🔄 **Una distinta fornitore che torna indietro.** 📧 Fornitore invia un `.xlsx` fatto come i fornitori già lavorano — prodotti in riga, soci in colonna, totali automatici — e 📤 Carica distinta rilegge il file restituito, mostra l'anteprima delle differenze e applica sia le correzioni di riga sia la spedizione per socio. - ⚖️ **Registra cosa è stato consegnato davvero, riga per riga.** Tocca una riga d'ordine per inserire quantità e costo reali (ordinato 1 kg, ricevuti 800 g): la differenza diventa una correzione e il socio viene avvisato. - 📊 **Filtri in Admin → Statistiche** per ciclo, fornitore o socio, combinabili, con azzeramento in un clic. - ✏️ **Modifica un ciclo dopo la chiusura** — titolo, note, date di ritiro, spedizione — senza riaprirlo. - 🚚 **La spedizione si ricalcola da sola sui cicli chiusi**, e ogni socio coinvolto riceve una notifica con la quota vecchia e nuova. - 📧 **Invia l'ordine al fornitore via email**, con l'admin che agisce e l'archivio GAS condiviso in CC e un CSV per prodotto allegato. - 🧾 **La spedizione è visibile nel recap ordini**, così i totali a schermo coincidono con quello che è stato addebitato ai soci. - [tecnico] 💾 **Backup settimanale del database su Google Drive**, a complemento delle 7 ore di storico point-in-time di Neon. ### Modificato - 🤝 **Tutte le azioni fornitore in un unico riquadro 🤝 Fornitore** — scarica, invia, carica — e da qui circola un solo file ufficiale invece di formati divergenti. - 💰 **Admin → Cassa si apre con tre schede riassuntive**, inclusa una "Saldo < 0" cliccabile che prima era sepolta in Admin → Ciclo. - 📈 **Le schede di Admin → Ciclo sono diventate una linea del tempo**: Aperti / In scadenza (≤7 giorni) / Chiusi (ultimi 7 giorni). - 📊 **I filtri delle statistiche sono a selezione multipla** con casella di ricerca, e una vista filtrata resta condivisibile via link. - 📄 **Il template prodotti è un file Excel** con un esempio già compilato per ogni categoria comune; l'import accetta ancora il `.csv`. - 🧾 **I totali in Admin → Ordini includono rettifiche e spedizione**, così la riga di ogni socio corrisponde a quanto gli è stato addebitato. - 📱 **"Ultimi cicli" più pulito su mobile** — la pillola di stato è passata a sinistra così si legge come etichetta, e le azioni vanno a capo sotto. - 🏷️ **"Fatturato" rinominato "Spesa"** in tutte le statistiche, e ora comprende anche la spedizione. - 📋 **Un solo formato riga `qta × prezzo = totale`** nel recap, con le righe rettificate che mostrano ordinato ed effettivo. ### Risolto - 📊 **Le statistiche andavano in errore filtrando per ciclo o fornitore.** Il driver HTTP di Neon non converte gli array JS in array Postgres, quindi il filtro non si legava mai; ora la query usa `inArray()` ovunque. - 🔤 **Le distinte fornitore sono in ordine alfabetico e senza distinzione tra maiuscole e minuscole**, ogni foglio ordinato con la chiave che rispecchia come viene letto. - 📋 **Le righe d'ordine non si leggono più `1 1 × €2,00`.** Il vecchio campo "Unità" salvato come stringa "1" ora è trattato come "nessuna unità". --- ## [1.5.0] - 17 maggio 2026 *Sistemare l'ordine di un socio dopo la chiusura del ciclo.* ### Aggiunte - ✏️ **Modifica l'ordine di un socio dopo la chiusura** — cambia quantità, aggiungi prodotti o crea da zero un ordine per chi non aveva partecipato. Pensata per il caso "mi sono dimenticato di metterti le uova". - 🧾 **Le correzioni non toccano l'addebito originale.** La differenza viene registrata come voce `correction` separata, così la tracciabilità resta intatta e ogni modifica è reversibile. - 🔔 **Il socio riceve una notifica** con la differenza leggibile e il nuovo saldo. --- ## [1.4.5] - 17 maggio 2026 *Una correzione mobile.* ### Risolto - 📱 **I pulsanti del ciclo aperto non sbordano più sui telefoni.** Sotto i 640px si dispongono sotto al titolo invece di far sparire l'ultima azione. --- ## [1.4.4] - 17 maggio 2026 *Una correzione estetica.* ### Risolto - 🏷️ **Tolto il "/1" appeso ai prezzi** ovunque. Veniva da un vecchio campo "Unità" nascosto dal form ma ancora stampato a schermo. --- ## [1.4.3] - 17 maggio 2026 *Un form prodotto più semplice e più spiegato.* ### Aggiunte - ⚖️ **Prezzo al kg di riferimento** su ogni prodotto (opzionale), mostrato ai soci accanto al prezzo unitario ovunque compaia un prezzo. - ❓ **Aiuto in linea su ogni campo del form prodotto**, una riga e un esempio ciascuno. ### Modificato - 📝 **Il form prodotto ha perso il campo "Unità".** Duplicava il formato e confondeva gli admin. - 🗂️ **La categoria ora è un menu a tendina** — categorie predefinite unite a quelle già usate dal fornitore, più un "aggiungi nuova" in linea. - 📄 **Il template CSV segue il nuovo ordine di colonne**; l'import accetta ancora il vecchio. --- ## [1.4.2] - 17 maggio 2026 *Scegli un'emoji, e parti dai saldi veri.* ### Aggiunte - 😀 **Un selettore di emoji con ricerca** per l'icona del prodotto, filtrabile con parole italiane, al posto del campo di testo libero. ### Modificato - 💰 **Saldi dei soci allineati al vecchio foglio CASSA** prima di andare in produzione, una voce iniziale per socio. --- ## [1.4.1] - 14 maggio 2026 *Il changelog entra nell'app.* ### Aggiunte - 📰 **Una pagina "Cosa è cambiato" su `/changelog`**, collegata dalla Guida, con il suo selettore IT/EN. - 👀 **Un'anteprima dell'ultima versione dentro la Guida**, con il link alla pagina completa. ### Modificato - 📄 **Il CSV fornitore è dettagliato per socio** e ordinato fornitore → prodotto → socio, così si può usare direttamente per preparare le borse. - 🧮 **Tolte le righe di subtotale dal CSV fornitore**, così non si può contare due volte sommando entrambe. --- ## [1.4.0] - 14 maggio 2026 *Numeri per l'admin.* ### Aggiunte - 📊 **Una dashboard di statistiche** nel pannello admin: prodotti più ordinati, andamento della spesa sugli ultimi 12 cicli chiusi, classifica fornitori, partecipazione dei soci e quattro schede di sintesi. - 📈 **Schede di sintesi sulla home admin** per i cicli in scadenza, i saldi negativi e il più venduto degli ultimi 30 giorni, ognuna collegata al tab giusto. - 📄 **Esportazione CSV fornitore** dal riquadro del ciclo chiuso, nel formato che Excel italiano si aspetta. - [tecnico] 📚 **Un README in inglese** con le note di architettura. --- ## [1.3.0] - 10 maggio 2026 *Riproponi l'ultimo ordine con un tocco.* ### Aggiunte - 🔁 **"Riproponi ultimo ordine"** riempie il carrello partendo dal tuo ordine più recente, abbinando i prodotti per identità. Compare solo a carrello vuoto, così non può sovrascrivere il lavoro in corso. - 📅 **Una scheda "Prossimo ritiro"** in home con giorno, fascia oraria, fornitore e conteggio dei giorni mancanti. ### Performance - [tecnico] ⚡ **Indici su `products.cycle_id` e `ledger_entries.cycle_id`**, interrogati a ogni caricamento delle pagine admin e ordine. --- ## [1.2.0] - 10 maggio 2026 *Riparto della spedizione e rettifiche a peso.* ### Aggiunte - 🚚 **Riparto proporzionale della spedizione** come alternativa alla quota fissa per socio, con lo scarto di arrotondamento assorbito in modo deterministico perché il totale resti esatto al centesimo. - ⚖️ **Chiudi un ciclo con rettifiche di prezzo** per i prodotti a peso: modifichi ogni prezzo finale e il sistema ricalcola tutte le righe e le voci di cassa prima di addebitare. - [tecnico] 📚 **SETUP.md**, la guida passo passo allo sviluppo locale con le insidie di `vercel env pull`. ### Risolto - [tecnico] 🗄️ **`drizzle-kit push` legge `.env.local`** tramite `--env-file` di Node. Prima caricava solo `.env` e falliva in silenzio con url vuoto. --- ## [1.1.0] - 10 maggio 2026 *Irrobustita la chiusura del ciclo.* ### Risolto - 🔒 **Race condition sulla chiusura del ciclo (critica).** La chiusura ora è un confronta-e-scambia atomico: due admin che cliccano insieme non possono più generare addebiti doppi. - 🛒 **Chiudere un ciclo mentre qualcuno ordina dà un riscontro.** Il form ordine si aggiorna con un messaggio invece di fallire in silenzio. - 🧾 **I saldi negativi sono rossi nel tab Movimenti**, come in home. - 🔔 **La notifica di chiusura ciclo cita la spedizione** e porta direttamente a quel ciclo nello storico. - 🖼️ **Il logo in alto riporta alla home.** - 📱 **La barra in basso rispetta l'area sicura del tasto home dell'iPhone.** - 🗂️ **I prodotti senza categoria finiscono sotto "Altro"** invece di formare una sezione senza titolo. --- ## [1.0.0] - 5 maggio 2026 *Primo rilascio in produzione della riscrittura Next.js.* ### Aggiunte - 🚀 **La riscrittura in Next.js 15 va in produzione**, portando il gruppo fuori da Apps Script. - 🛒 **L'app per i soci**: saldo, form ordine con contatori per prodotto, storico ordini e movimenti, notifiche in app, guida con le domande frequenti. - 🛠️ **Il pannello admin** con sei tab — cicli, prodotti, ordini, cassa, soci, fornitori. - 🔒 **Login Google via Auth.js**, con lista di email autorizzate sulla tabella soci. - [tecnico] 🗄️ **Neon Postgres e Drizzle ORM**, in produzione su Vercel con deploy automatico da `main`. --- [1.45.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.45.1 [1.35.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.35.0 [1.34.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.34.1 [1.34.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.34.0 [1.33.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.33.0 [1.32.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.32.0 [1.31.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.31.0 [1.30.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.30.1 [1.30.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.30.0 [1.29.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.29.0 [1.28.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.28.0 [1.27.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.27.0 [1.26.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.26.0 [1.25.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.25.0 [1.24.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.24.0 [1.23.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.23.0 [1.22.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.22.0 [1.21.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.21.1 [1.21.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.21.0 [1.20.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.20.0 [1.19.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.19.0 [1.18.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.18.0 [1.17.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.17.0 [1.16.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.16.1 [1.16.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.16.0 [1.15.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.15.0 [1.14.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.14.1 [1.14.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.14.0 [1.13.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.13.0 [1.12.2]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.12.2 [1.12.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.12.1 [1.12.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.12.0 [1.11.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.11.0 [1.9.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.9.0 [1.8.1]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.8.1 [1.8.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.8.0 [1.7.0]: https://github.com/federicodecillia/wegrocery/releases/tag/v1.7.0