docs: modifica messaggi e firma in chat — STATUS, STATE, design system

La cosa da rileggere fra sei mesi: propagare una modifica richiede
insieme il filtro allargato a edited_at e il watermark del client sul
massimo dei due timestamp. Una sola delle due e o la modifica non
arriva, o arriva a ogni giro per sempre.

Più il perché di due scelte che sembrano sviste: il non-letto resta su
created_at, e la foto è un URL esterno perché l'upload su volume non
esiste (la deroga LOCKED #5 è scritta ma mai costruita).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 22:44:30 +02:00
parent 94f4a54248
commit c3d2afa61f
3 changed files with 87 additions and 6 deletions
+65
View File
@@ -183,6 +183,71 @@ così. Deploy atterrato, immagine taggata `ac74a81` = HEAD.
**Da fare:** aprire il portale di un cliente, scrivere su una fase, rispondere da
`/admin/conversazioni` e verificare che la risposta torni **in quel tab**.
### Modifica dei messaggi + firma in chat (2026-08-21, in produzione)
Due mancanze emerse **provando la chat in produzione** — che è esattamente il tipo di
cosa che né il build né il lint possono dire.
**Modifica dei messaggi**, modello Slack/Discord: si corregge un proprio messaggio
**senza limite di tempo**, il testo precedente **non si conserva**, accanto all'ora
compare «modificato».
> ⚠️ **Scelta deliberata, non una svista.** Illimitato + nessuno storico significa che
> un messaggio scritto mesi fa resta riscrivibile, e l'unica difesa dell'altra parte è
> quell'etichetta. Il rischio è stato posto e accettato il 2026-08-21. Se un domani
> servisse dimostrare cosa era stato scritto, la strada è una tabella `comment_edits`:
> additiva, si aggiunge senza toccare niente di quanto c'è ora.
**Il punto difficile non era scrivere la modifica, era propagarla.** Il poll chiede i
messaggi con `created_at > since`, e una modifica **non cambia `created_at`** — quindi
l'altra parte avrebbe continuato a vedere il testo vecchio fino a un ricaricamento
completo. Il filtro ora guarda **anche `edited_at`**, e il watermark del client è il
**massimo fra i due su tutti i messaggi**: se restasse il `created_at` dell'ultimo, il
server rispedirebbe lo stesso messaggio modificato a ogni giro, per sempre. Le due cose
vanno insieme — una sola delle due e o la modifica non arriva, o arriva all'infinito.
Il merge per id era già in piedi, quindi nessun duplicato da temere.
**Il non-letto resta ancorato a `created_at`, di proposito**: correggere un refuso non
deve riaccendere il pallino di un canale già letto. Annotato nel codice, altrimenti al
prossimo refactor sembra una svista da "sistemare".
Autorizzazione: **si modifica solo ciò di cui si è autori** — il controllo è su
`author`, non solo sulla proprietà dell'entità, e lo rifà il server (il pulsante
nascosto non è una difesa). Migration `0022`, additiva, applicata a prod prima del push
e riletta a conferma: 11 messaggi, 0 marcati come modificati.
**Firma in chat.** Il nome era la stringa `iamcavalli` cablata nel pannello: il cliente
leggeva il marchio dove si aspetta una persona, e il monogramma diceva `IA`. Ora nome e
foto arrivano da `settings`**nessuna migration**, la tabella è già un key/value con i
suoi helper — e si impostano da `/admin/impostazioni`.
La foto è un **URL esterno**, e non è un ripiego: `/api/uploads/[...path]` **non esiste**.
La deroga al vincolo LOCKED #5 per le immagini dell'audit è scritta in CLAUDE.md ma il
codice non è mai stato costruito (Phase 27 è ferma allo schema). Un upload vero avrebbe
richiesto di modificare un vincolo LOCKED *e* costruire da zero volume persistente,
Server Action, rotta di lettura, whitelist MIME e limite di dimensione. Avatar assente o
rotto ricade sul monogramma, così un link che muore non lascia un buco.
Nell'inbox admin il nome **non** cambia: lì i propri messaggi dicono «Tu (Admin)», che è
già corretto. Il problema era solo come il cliente vede l'altra parte.
⚠️ **Buildata, non provata a mano** (`.env.local` scaduto). **Da fare, in quest'ordine:**
(1) con la chat del cliente **aperta**, modificare da `/admin/conversazioni` un messaggio
dell'admin in quel canale — entro ~20s il testo deve cambiare da solo, senza duplicarsi;
(2) verificare che il pallino **non** si riaccenda; (3) impostare nome e foto in
`/admin/impostazioni` e ricontrollare il portale; (4) da `?preview=1` il pulsante
«Modifica» non deve esserci.
**Rimandato, con la ragione scritta:** le **menzioni** con più persone invitate in un
portale. L'ostacolo non sono le notifiche ma l'attribuzione — `comments.author` contiene
solo `client`/`admin`, non *quale* persona, quindi oggi tre invitati sono tre «Tu»
identici. L'identità però esiste già: la sessione OTP porta l'email
(`ClientSession = { clientId, email, iat }`) e `client_emails` è la lista degli invitati.
Manca che le scritture della chat leggano la sessione invece del solo token — il lavoro
già annotato in `client-chat.ts` come «un lavoro a sé». Ordine giusto: **attribuzione**,
poi notifiche (Resend c'è già), poi eventualmente menzioni. Molto probabilmente vedere
*chi* ha scritto risolve gran parte del problema da solo.
### v2.5 — Audit (Phases 2730), in pausa
Il servizio di analisi sito (tre livelli: **Radiografia / Prima-Dopo / Rotta**) diventa