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:
@@ -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 27–30), in pausa
|
||||
|
||||
Il servizio di analisi sito (tre livelli: **Radiografia / Prima-Dopo / Rotta**) diventa
|
||||
|
||||
Reference in New Issue
Block a user