VRP B100 - Motto, avatar precedenti, playlist del JukeBox

Stato: 06/09/2026 - ✅ FATTO E COLLAUDATO in giornata. DDL lanciata da

vitti come root; codice, prove e resoconto in

VRP_B300 alla voce del 06/09.

Questo foglio resta come il DISEGNO: il perche' delle scelte, che nel B300 non

si ripete.

Riferimenti: VRP_B200_architettura,

VRP_DB_catalogo.


1. Cosa ha chiesto vitti

1. JukeBox - continuare: la *scelta dei brani* e le *playing list*,

*"quelle solo per i loggati!"* (detto il 05/09 andando in spiaggia).

2. Avatar - conservare i precedenti, non solo quello corrente.

3. Motto per utente, anche quello con lo storico. Il suo:

Vitti, Uto, Ubi, Elena, Seneca & Frida, nihil separatum est

Tre idee diverse che pero' fanno una domanda sola: dove si mettono le cose

di un utente che cambiano nel tempo.


2. Cosa dice il codice di OGGI (verificato il 06/09, non ricordato)

2.1 La tabella vrp_auth.users - 13 righe

id username email pass_hash display_name avatar is_active

created_at last_login_at

Non c'e' nessuna colonna per il motto e non c'e' nessuna tabella di storico

(le tabelle di vrp_auth sono: users, user_services, sessions,

sessions_h, vrw_import).

2.2 L'avatar oggi si SOVRASCRIVE, e il vecchio si butta

Il nome del file e' u<id>.<ext> - cioe' uno solo per persona:

dello stesso utente con altra estensione;

dell'avatar.

Quindi oggi lo storico degli avatar non e' possibile: caricando un .jpg

sopra un .jpg il precedente sparisce dal disco. Non e' un baco, e' una scelta

di allora; ma e' la prima cosa da cambiare, ed e' piccola.

Sul disco (lab/public/avatars/) ci sono 6 file per 13 utenti:

u1.jpg, u2.jpg, u5.jpg, u9.jpeg, u15.jpeg, u17.jpg.

2.3 Il motto viaggerebbe GRATIS

platform/lib/vrp_auth.php:69 (vrp_current_user) fa gia':

SELECT id, username, display_name, email, avatar, is_active FROM users ...

ed e' memoizzata. Aggiungere motto a quella SELECT costa una parola, e da

li' il motto e' in mano a chiunque: badge del VRV, profilo, pagina Utenti, i

post. Stessa strada gia' fatta il 05/09 per l'avatar del badge.

2.4 Il JukeBox e' PUBBLICO, e resta pubblico

platform/pages/jukebox.php non ha guardia e la voce e' 'lan' => false:

ci si ascolta la musica dalla spiaggia. Le playlist invece sono roba di chi ha

un nome: compaiono solo se vrp_current_user() c'e'. Non si chiude la

pagina per proteggere una funzione.

La pagina e' un cappello su vrp_explorer con ui.select = 'none' e

ui.picker = true (un clic accoda). Per "scegliere i brani" il motore ha gia'

la selezione multipla: si accende ui.select e si aggiunge un bottone.

2.5 Il separatore | e' gia' di casa

post.musica tiene piu' brani separati da |

(visualizza_post_draft.php:151-164 fa explode('|')). Una playlist e'

esattamente quella cosa: un elenco ordinato di brani. Non serve inventare un

formato nuovo, e nemmeno una seconda tabella di righe.

2.6 La DDL la deve lanciare ROOT

vrp_auth_app ha solo SELECT/INSERT/UPDATE/DELETE

(VRP_DB_catalogo). Ogni CREATE/ALTER qui sotto e' **una

riga che deve lanciare vitti da root**, e va lanciata quando Elena non sta

lavorando (vedi la lezione del 27/07: un ALTER le inchiodo' la pagina).


3. La forma proposta

3.1 Il CORRENTE sta in users, lo STORICO in una tabella sola

Non due tabelle (una per gli avatar, una per i motti): una sola, con una

colonna che dice di che cosa si sta parlando. Sono la stessa cosa - "un valore

che questa persona portava fino a un certo giorno" - e separarle prima di

sapere che divergono e' una separazione prematura.

users.avatar il file di adesso <- nessun lettore cambia

users.motto il motto di adesso <- colonna nuova

user_storia quelli di prima <- tabella nuova

Cosi' niente di quello che esiste si accorge del cambiamento: chi legge

users.avatar continua a leggere l'avatar buono. Lo storico e' un registro che

si appende e non si rilegge mai per sapere "chi sono io adesso" - quindi non

puo' nascere una seconda verita'.

CREATE TABLE user_storia (

id INT UNSIGNED NOT NULL AUTO_INCREMENT,

user_id INT UNSIGNED NOT NULL,

cosa ENUM('avatar','motto') NOT NULL,

valore VARCHAR(255) NOT NULL,

ritirato_il DATETIME NOT NULL,

ritirato_da INT UNSIGNED NULL,

PRIMARY KEY (id),

KEY k_chi (user_id, cosa, ritirato_il),

CONSTRAINT fk_storia_user FOREIGN KEY (user_id)

REFERENCES users(id) ON DELETE CASCADE

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

due mestieri perche' la domanda e' la stessa: *cosa portavi*.

riga precedente: metterlo due volte vuol dire poterlo scrivere in due modi

diversi.

che gliel'ha cambiato dalla pagina Utenti). NULL per le righe vecchie.

3.2 I file degli avatar smettono di sovrascriversi

Nome nuovo: u<id>_<AAAAMMGGHHMMSS>.<ext> (esempio u1_20260906_101500.jpg).

in users.avatar, nessuno lo ricalcola. Niente migrazione.

users.php). Resta quello della cancellazione dell'utente, che pero' va

esteso: cancella l'avatar corrente e i suoi precedenti.

sui file. E il ritirato di adesso finisce nello storico. Uno scambio, non una

copia.

Nel profilo: sotto "Foto" una fila di miniature dei precedenti; un clic lo

rimette in carica; il visore vrp_zoom (gia' in casa dal 05/09) per guardarlo

intero. Nessuna cancellazione a mano in prima battuta - se un giorno la

cartella diventa grossa se ne riparla, ma 13 persone che cambiano foto due

volte l'anno fanno 26 file all'anno.

3.3 Il motto

ALTER TABLE users ADD COLUMN motto VARCHAR(255) NULL AFTER display_name;

di un altro), esattamente come display_name;

badge non e' un motto**;

Quello di vitti sta in 63 caratteri, sta comodo.

3.4 Le playlist del JukeBox

CREATE TABLE jukebox_playlist (

id INT UNSIGNED NOT NULL AUTO_INCREMENT,

user_id INT UNSIGNED NOT NULL,

nome VARCHAR(120) NOT NULL,

brani TEXT NOT NULL,

creata_il DATETIME NOT NULL,

cambiata_il DATETIME NOT NULL,

PRIMARY KEY (id),

UNIQUE KEY uq_pl (user_id, nome),

CONSTRAINT fk_pl_user FOREIGN KEY (user_id)

REFERENCES users(id) ON DELETE CASCADE

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

mus/Ci vuole un fiore.mp3|mp3/Radio.mp3. Stesso idioma di post.musica.

La chiave dice gia' lo scaffale, quindi una playlist puo' pescare da tutti e

due (Radio VV e Musica dei post) senza che serva altro.

suo. Il nome della tabella dice il servizio, come vrw_import.

permessi sui post): *l'autore comanda la sua roba, l'admin comanda tutto*.

Qui vuol dire: le playlist si vedono fra loggati di casa, ma le

cambia solo chi le ha fatte (e l'admin). Da confermare - punto 4.3.

3.5 Cosa cambia nella pagina JukeBox

1. si accende ui.select (il motore la sa gia' fare) -> le mattonelle si

spuntano. Il clic semplice deve restare "accoda": la spunta e' un gesto

in piu', non al posto di quello che c'e'. Da provare a video, e' l'unico

punto in cui posso rovinare qualcosa che gia' funziona.

2. un bottone "Salva la coda come playlist" - **si salva la CODA, non la

selezione**: la coda e' gia' l'elenco ordinato che si sta ascoltando, ed e'

il gesto naturale ("questa sequenza mi piace, tienimela").

3. a sinistra della console, un elenco delle playlist: un clic la mette in coda.

4. tutto il blocco compare solo se c'e' un utente. Chi non e' loggato vede il

JukeBox di oggi, identico.

3.6 Un solo script, una volta sola

Le tre DDL (una ALTER + due CREATE) vanno in un file solo da lanciare da

root in un momento solo, non tre volte in tre momenti diversi.


4. Le decisioni, come le ha prese vitti il 06/09

1. Il motto si vede in HOVER: sul badge del VRV e sulla barra di

piattaforma, *"anche nella lista utenti"*. Non sotto il nome a caratteri

cubitali: e' una cosa che si scopre, non un'insegna.

2. Le playing list: *"ogni loggato avrebbe le sue playing list, gli ospiti

potrebbero suonare la list di vitti, o di Elena, o farne una propria, ma non

salvarla!"*. Cioe': si LEGGONO tutte, anche da ospite; a mancare all'ospite

e' il solo bottone Salva. La cancella il padrone (o un admin).

📌 Il 05/09 aveva detto *"quelle solo per i loggati!"* e il 06/09 l'ha

precisato: e' il salvataggio a volere un nome, non l'ascolto.

3. La lista utenti: *"gli admin possono tutto, modificare se stessi e gli

altri; i loggati possono modificarsi, ma potrebbero vedere gli altri"*.

Da qui le DUE FACCE della pagina Utenti (vedi il B300).

4. La DDL: lanciata da lui la mattina del 06/09 (*"Elena non sta

lavorando, sta preparando da mangiare"*).

🐞 Ci si e' inciampati una volta: gli avevo suggerito sudo mysql, ma il

root di MariaDB qui non e' unix_socket - vuole la sua password, e il

sudo non c'entra. Comando giusto: mariadb -u root -p vrp_auth < file.sql.

4bis. Quello che il disegno non aveva previsto, e si e' visto facendo

del file arriva dal form: senza ricontrollarlo contro la soffitta VERA di

quell'utente, uno si prendeva l'avatar di un altro scrivendone il nome.

Provato: riprendi=u1.jpg (la foto di vitti) -> negato.

via le righe di user_storia, e con loro l'unico posto dove c'e' scritto

come si chiamavano le sue foto di prima: i nomi vanno raccolti PRIMA della

DELETE, se no restano file orfani per sempre.

pagina Utenti a chi non e' admin non e' una guardia: un form nascosto non e'

un form che non si puo' mandare.


5. Cosa NON si tocca