docs: task cancellati e date dei pagamenti — STATUS, STATE, design system
STATUS.md: perché la pill sta su "Cancellata" e non su "Fatto" (sono entrambi barrati, e scambiarli significa credere consegnato ciò che non esiste), perché `due_date` è nullable, e le due verifiche che restano a mano — il riquadro "Prossimo pagamento" non compare finché nessuna rata ha una scadenza, e due `paid_at` storici valgono il primo del mese perché li ha scritti il vecchio selettore a mese. DESIGN-SYSTEM.md: la quinta forma, la regola della colonna Kanban che si nasconde solo da vuota, e la spec del box pagamenti. STATE.md: due decisioni nuove, e resta sotto le 100 righe accorpando le righe di tabella della stessa settimana. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -303,6 +303,80 @@ e «In revisione» (2) convivono, su 11 task, quindi l'unica dove si vede se ora
|
||||
distinguono davvero. Da guardare anche col tema scuro: è lì che l'icona «In corso» prima
|
||||
non aveva varianti.
|
||||
|
||||
### Task cancellati e date dei pagamenti (2026-08-22)
|
||||
|
||||
Due buchi che si vedevano solo aprendo il portale dalla parte del cliente.
|
||||
|
||||
**Un task tolto dal lavoro non aveva dove stare.** L'admin poteva solo cancellarlo dal DB
|
||||
— e allora il cliente non capiva perché una voce che aveva letto la settimana prima non
|
||||
c'era più — oppure lasciarlo lì a fingersi «Da fare» per sempre. Ora `cancelled` è il
|
||||
quinto stato: **X dentro il cerchio, titolo barrato**, e la pill «Cancellata».
|
||||
|
||||
È l'unico stato *chiuso* che porta la pill, e non è un'incoerenza: «Fatto» e «Cancellata»
|
||||
sono **entrambi barrati**, e scambiarli significa credere consegnato qualcosa che non
|
||||
esiste. La forma da sola non basta a coprire quel rischio.
|
||||
|
||||
Il lavoro vero, di nuovo, non era il nuovo stato ma i denominatori. Un task cancellato esce
|
||||
da **tutti**: percentuale di fase, percentuale globale, board delle consegne, riepilogo
|
||||
admin — attraverso un solo `countsTowardProgress()` in `src/lib/task-status.ts`, non cinque
|
||||
`!== "cancelled"` sparsi in giro. Contarlo terrebbe la fase sotto il 100% per un lavoro che
|
||||
nessuno farà mai; contarlo come fatto racconterebbe una consegna mai avvenuta.
|
||||
`recomputePhaseStatus` lo ignora allo stesso modo: senza, cancellare l'ultima voce di una
|
||||
fase la lasciava «In corso» per sempre. Se restano **solo** cancellati la fase torna «Da
|
||||
iniziare» — è degenere, ma «Completata» al cliente racconterebbe una consegna che non c'è
|
||||
stata.
|
||||
|
||||
Nel Kanban cliente la colonna «Cancellate» compare **solo se ha dentro qualcosa**, così le
|
||||
quattro che raccontano il lavoro si tengono la larghezza — ma mai se è piena, quindi nessun
|
||||
task sparisce dalla board: era esattamente il bug che aveva fatto nascere `TASK_STATUSES`.
|
||||
Nell'admin la colonna c'è sempre, ed è così che si cancella un task: trascinandocelo.
|
||||
|
||||
**Il box pagamenti non sapeva dire quando si paga.** `payments` aveva `paid_at` — quando una
|
||||
rata è stata incassata — e nient'altro: nessun campo per la scadenza. Il portale non poteva
|
||||
rispondere alla domanda più ovvia del cliente, e non c'era niente su cui agganciare il
|
||||
promemoria via email. **Migration `0023`**, additiva: `payments.due_date`, nullable senza
|
||||
default, più un indice parziale su cui girerà la query del promemoria («le non saldate in
|
||||
scadenza entro N giorni», che l'indice `(project_id, sort_order)` non copre).
|
||||
|
||||
Nullable è una scelta: una rata senza data concordata è normale, e un default inventerebbe
|
||||
una scadenza che nessuno ha pattuito. **Il portale mostra la data solo se c'è.**
|
||||
|
||||
Cosa vede il cliente:
|
||||
|
||||
- In cima al box, **«Prossimo pagamento»**: data lunga e conto alla rovescia in parole —
|
||||
«tra 12 giorni», «domani», «oggi». Se è passata, il riquadro diventa rosso e dice
|
||||
«Pagamento scaduto — scaduto da 3 giorni». Un arretrato batte sempre la rata del mese
|
||||
prossimo: se c'è, *quello* è il prossimo pagamento.
|
||||
- Su ogni riga, la sua data: **«Scade il…»** se aperta, **«Pagato il…»** se saldata.
|
||||
- **Nessun importo per riga.** LOCKED #2 resta dov'era: le date non sono cifre.
|
||||
|
||||
I giorni si contano in `src/lib/payment-dates.ts`, sui **giorni civili a Roma** e non sugli
|
||||
istanti: il container gira a UTC, e «manca una settimana» non deve cambiare risposta a
|
||||
seconda del fuso di chi renderizza. È lo stesso modulo che userà il promemoria email —
|
||||
scritto ora proprio perché la mail e il portale non si contraddicano su quanti giorni
|
||||
mancano. Le date si salvano a **mezzogiorno UTC**, non a mezzanotte: a mezzanotte UTC il
|
||||
giorno civile a Roma è già quello dopo, e la data tornerebbe indietro di un giorno appena
|
||||
riletta.
|
||||
|
||||
Lato admin ogni rata ha ora il campo **Scadenza**, e «Incassato nel mese» è diventato
|
||||
**«Incassato il»** — precisione al giorno, che le analytics non notano perché raggruppano
|
||||
con `extract(month from paid_at)`. Il warning sul cambio schema rate conta anche le
|
||||
scadenze: una rata «da saldare» con una data è già sotto gli occhi del cliente, e
|
||||
sparirebbe in silenzio.
|
||||
|
||||
**In produzione dal 2026-08-22** (`fe76789`). Migration `0023` applicata a prod **prima**
|
||||
del push, come da procedura: `ALTER TABLE` + `CREATE INDEX`, 12 righe in tabella, nessuna
|
||||
toccata. Build, typecheck e lint verdi — lint invariato, nessun problema nuovo nei file
|
||||
toccati.
|
||||
|
||||
⚠️ **Due cose da fare a mano.** (1) Il portale non l'ho visto a schermo: vale la stessa
|
||||
verifica `?preview=1` della sezione precedente, e finché nessuna rata ha una `due_date` il
|
||||
riquadro «Prossimo pagamento» **non compare per definizione** — va messa una scadenza dal
|
||||
tab Pagamenti per vederlo. (2) Due `paid_at` storici valgono il **primo del mese**
|
||||
(2026-03-01 e 2026-01-01): li ha scritti così il vecchio selettore a mese, e ora il cliente
|
||||
li legge come «Pagato il 1 mar 2026». Se il giorno vero era un altro, si corregge dal nuovo
|
||||
campo.
|
||||
|
||||
### v2.5 — Audit (Phases 27–30), in pausa
|
||||
|
||||
Il servizio di analisi sito (tre livelli: **Radiografia / Prima-Dopo / Rotta**) diventa
|
||||
|
||||
Reference in New Issue
Block a user