VRP - B300 - Diario di coding

Stato: APERTO 2026-07-05. Segue VRP_B200_architettura.

Registro cronologico degli interventi di CODIFICA: cosa si e' toccato, perche',

quali file, e come e' stato collaudato. Le decisioni di architettura restano nel

B200; qui il "cantiere" giorno per giorno. ASCII puro. Voci nuove in fondo.


2026-07-05 - Cruscotto Amministrazione + Sessioni/Log + timeout

Perche': dalla home ?p=home non c'era modo di raggiungere le pagine

riservate (utenti compariva in barra solo da LAN+admin; config era parcheggiata).

Serviva una porta unica per l'amministrazione, piu' due strumenti d'indagine.

Fatto:

voce in barra): atrio con 4 riquadri (Utenti, Configurazione, Sessioni, Log)

che aprono in nuova scheda (target=_blank + rel=noopener), cosi' la console

resta li'. Riusa .vrp-cards/.vrp-card. E' l'"Altezza 1" (admin di

PIATTAFORMA) della sez. 3b del B200, in piedi.

barra; users/config/sessioni/log con nav=false (fuori dalla barra,

raggiunte dal cruscotto). config RI-AGGANCIATA (era sganciata dal 03/07).

vrp_auth (storico del portinaio). Scelta colonne con caselle; whitelist viva

presa da SHOW COLUMNS (mai nomi arbitrari nella SQL). Sola lettura, ORDER BY

started_at DESC, LIMIT parametrico.

vv/vv_where_logs.php) su VRP_LOG_FILE + candidati di sistema in whitelist

(nginx / php-fpm / error_log). Filtro per livello (ERROR..DEBUG, riconosciuto

da ][LIVELLO][) e righe colorate.

.vrp-log-* (barra compatta + pannello). Pagine Log e Sessioni a tutta

finestra ~92% con scroll INTERNO del pannello e testata compatta: attivato SOLO

su queste due via body:has(.vrp-log-view) / body:has(.vrp-sess-table),

nessun flag nel FC. Intestazione tabella fissa (position:sticky).

'logout') timbra l'azione richiesta; vrp_session_check passa 'timeout'`;

logout.php passa 'timeout' se arriva dal meta-refresh (?t=1). Nelle

Sessioni si legge timeout invece di logout. Scrittura idempotente

(WHERE ended_at IS NULL): se scattano due vie, si timbra una volta sola.

(6 file di platform/lib/, 31 funzioni documentate).

Collaudo: php -l su tutti i file toccati OK. Da localhost (LAN):

?p=home 200; ?p=admin|config|sessioni|log -> 302 alla login (guardia

LAN+admin che funziona, nessun 500). Query sessions_h provata via PDO (colonne

+ righe reali, incluso un accesso da IP pubblico). Utenti admin: vitti / seneca /

lella (Elena e' editor, non vede il bottone).

Aperto: la UX vera per editare i JSON per-servizio (config e' ancora una

textarea); :has() richiede un browser recente (ok su Manjaro rolling,

altrimenti le due pagine ripiegano sulla resa normale).


2026-07-05 (pomeriggio) - Profilo self-service + auto-prepend + integrazione VRW

Perche': (1) un utente non-admin doveva poter modificare il PROPRIO profilo;

(2) far entrare il primo servizio (wiz_foto) nella piattaforma col metodo di

vitti: "la piattaforma fa tutto, i servizi ereditano l'ambiente". Obiettivo

dichiarato: nel codice delle pagine NON un solo require; se manca una funzione

la si aggiunge alla libreria di piattaforma (niente 'not defined' ne' 'already

defined').

Fatto - profilo e ruolo:

loggati, non LAN ne' admin): l'utente cambia SOLO i suoi dati (nome, email,

password vuota=invariata, foto). Username/ruoli restano all'admin. Riusa la

logica di users.php.

vrp_role_icon() in vrp_auth.php; il badge in barra e' ora un link a

?p=profilo con l'icona del ruolo (admin=corona, il "Cesare imperatore").

Ricognizione Nextcloud (mang3): due account vitti e lella; i telefoni

caricano in Photos/AAAA/MM/GG/. Estensioni reali: solo .jpg (+ .png per

lella) e VIDEO (.mp4/.mov) - NIENTE .heic (anche l'iPhone carica jpg). Dato

in /srv/dati/nextcloud/data (bind mount). DECISO: importare anche i video

(Elena decide poi). Il 13T (HyperOS) ritardava l'auto-upload: batteria "nessuna

restrizione" + avvio automatico.

Fatto - integrazione VRW (il metodo, rodato qui per i prossimi servizi):

intatto = backup). Diff confermato identico prima di lavorarci.

extensions/modes), registrata in env.json services -> compare e si

edita da ?p=config. Politica d'accesso nella targa: lan:true, admin:true.

piattaforma carica l'ambiente PRIMA di ogni pagina sotto /lab/public. Preso

al volo senza reload di php-fpm. Il loader usa require_once -> nessun

'already defined'.

per i servizi ospitati nel lab applica lan/admin/auth dalla loro targa,

SENZA guardie nel codice del servizio. wiz_foto era esposto sotto public ->

ora 302 se non LAN+admin.

+ vrp_load_service_libs() in vrp_services.php. Il loader NON nomina i

servizi: gira su env.json services, e ogni servizio che dichiara "lib"

nella targa viene caricato (config passata alla lib in $vrp_service).

Aggiungere un servizio = registrarlo + "lib", zero tocchi al loader.

rinominato vrw_/VRW_, percorsi dalla targa (VRW_STAGING_DEFAULT ecc.) e

VRW_DEST_BASE_DEFAULT = VRP_MEDIA_ROOT (leNostre dalla piattaforma).

heic_to_jpg, import_amazon, export_staging_csv): via TUTTI i require

(_cfg/_pecore), vv_->vrw_, VV_->VRW_, e header-commento in testa

("questa pagina e' gestita dalla piattaforma...").

l'auto-prepend) + header-commento.

Collaudo: php -l su tutti i file OK. vrw.json valido. Da CLI il loader

definisce vrw_base_url/vrw_pecore_overlay e VRW_STAGING_DEFAULT/

VRW_DEST_BASE_DEFAULT -> lib caricata DAL REGISTRO. Rotte: home 200, admin 302,

wiz_foto 302 (guardia attiva, prima era esposto). Runtime vero:

wizard_import.php RENDE senza un solo require, ereditando l'ambiente. Nelle 6

pagine: zero require, zero residui vv_/VV_.

Aperto: (1) lenostre_index.php -> platform/lib/vrn_index.php (ultimo

require, in gestore_foto+popola); (2) orfani _cfg.php/_pecore.php nella

copia da cancellare; (3) rename CSS .vv- -> .vrw-; (4) nuovo Step "Scarica da

Nextcloud" (foto+video, un account per volta); (5) ruolo vrw a vitti/lella ->

compare la cartolina in home. Prossimo servizio previsto: VRS (`/srv/http/

share), policy "login + WAN" (targa: auth:required, senza lan`).


2026-07-05 (sera) - Rifiniture admin (leggibilita', tail -f) + fix identita' log

Perche': giro di feedback di vitti sulle paginette admin (leggibilita',

spazio, aggiornamento del log) e un baco scovato leggendo il log.

Fatto:

spaziatura. Tolto il newline nel loop.

ri-aggiorna ogni 3s e scende in fondo (follow=1 in URL, piccolo JS a fondo

pagina); spento -> si ferma (per ragionarci sopra).

testo bianco risalta sullo sfondo; header sticky piu' opaco.

(declutter); Righe/Applica/Reimposta restano visibili sotto.

Sessioni/Log).

valorizzato: il login salva vrp_uid) -> ogni riga usciva @ospite#0@guest.

Era un segnaposto pre-vrp_auth. Ora usa vrp_current_user() + vrp_role_top().

Verificato via CLI (sessione simulata): @vitti#1@admin, @lella#8@admin. Le

righe vecchie restano ospite (storia, non si riscrive).

non un servizio) ma VittRos Share; corretto VRP_acronimi.md.

Collaudo: php -l su tutti i file OK; rotte admin 302 (guardia). Identita'

log provata in CLI con $_SESSION['vrp_uid'] impostato (vitti/lella).

Aperto (coda UI): layout wide+fisso+scroll interno per Utenti e Config +

sezioni collassabili; tab riusati (login / amministrazione / un tab per

servizio); bottoni servizio in home (ruolo vrw + placeholder VRShare).


2026-07-05 (sera, 2) - Coda UI: Utenti/Config wide, Sessioni paginate/sortabili, VRW+VRS in home

Perche': chiudere la coda UI (punti 1 e 3) e un giro di rifiniture di vitti

provando le paginette in browser.

Fatto:

Introdotto un marcatore GENERICO e riusabile in vrp-lab.css: la testata sta

in .vrp-fixed-head (fissa), il corpo in .vrp-fixed-body (scorre). Le liste

di selettori :has() sono state ESTESE (non duplicate) per includere il nuovo

marcatore. Nuova classe .vrp-fold: una sezione collassabile (<details>) con

la testata resa come un vecchio <h2>.

Database aperte, Percorsi chiusa perche' sola lettura). Le sezioni collassate

restano nel form e continuano a inviare i loro campi al POST.

l'attributo HTML name="utenti-acc" sui due <details> (accordion nativo, zero

JS): apri uno -> l'altro si chiude. Tolto il bottone "Nuovo utente" ridondante.

Paginazione a 8 (?pg=N, prec/pagina X/Y/succ; pager nascosto se <=8).

$edit ora preso per id (vale anche se l'utente sta in un'altra pagina).

log): il ritorno resta la voce in barra. La testata piu' corta fa entrare 8

utenti senza scrollbar.

max 320, altezza allineata dalla riga); titolo .vrp-card b su una riga che

scorre (overflow-x:auto, scrollbar nascosta) invece di allargare la card.

?pg=N) e ordinamento cliccando l'intestazione (freccia su/giu' sulla

colonna attiva, ri-clic inverte). Colonna d'ordine sempre da whitelist

(SHOW COLUMNS). Chiusura $sess_url() (closure) costruisce i link preservando

lo stato (colonne/righe/sort) con override. Nuove classi CSS .vrp-pager* e

.vrp-sort.

Share, url:/share/, auth:required, NIENTE lib: e' un primo link al servizio

standalone, integrazione vera = poi) e registrata in env.json services. Dato a

vitti e lella il ruolo admin su vrw e vrs (in user_services), cosi'

le due cartoline compaiono. Home ora: VRV(pub), VRN, VRW, VRS.

che senza index.php dava 403 (autoindex off). Rinominato wizard_import.php

-> index.php e aggiornati gli 8 back-link "Torna al Wizard" nei passi. nginx

ha gia' index index.php ... -> la URL della cartella ora serve il wizard.

-> messo g+w, cosi' il web server puo' scrivere i backup di env.json al salva.

Collaudo: php -l su tutti i file toccati OK. Render CLI (utente vitti id 1):

Config = 4 fold + fixed-head/body; Utenti = fisarmonica esclusiva (default elenco

aperto; ?new=1 form aperto/elenco chiuso), paginazione provata a soglia 2 (pag

2/3 con prec/succ giusti); Sessioni = 1/2 default, sort username asc -> 1/7, pag 2

prec=1/succ=3, stato preservato nei link; home mostra le 4 card per vitti; wiz_foto

index.php rende il wizard.

Aperto (coda UI): resta solo il punto 2 - tab riusati (login /

amministrazione / un tab per servizio). Idea di vitti: "tutto wide" anche il

cruscotto admin (rimandato). Proliferazione tab del browser (da risolvere

domani): i riquadri del cruscotto admin usano target="_blank" (admin.php) -> ogni

clic apre una scheda nuova e si moltiplicano; da ripensare insieme al punto 2

(tab/aree interne riusate invece di schede del browser). Minori: orfani _cfg.php/_pecore.php in wiz_foto da

cancellare; rename CSS .vv- -> .vrw-; lenostre_index.php -> vrn_index;

integrazione VERA di VRS share (login+WAN) e Step "Scarica da Nextcloud".


2026-07-06 - Tab riusati, cruscotto wide, wallpaper configurabile, gateway accesso, fix timeout

Perche': giro di feedback di vitti provando la piattaforma: (1) i riquadri

del cruscotto admin aprivano ogni volta una scheda nuova del browser

(proliferazione, "veramente fastidioso"); (2) il cruscotto admin andava reso

"wide" come le altre; (3) lo sfondo di piattaforma non era editabile dalla

pagina Config (c'era in env.json ma nessuna voce nel form); (4) aprire un'area

riservata da sloggati saltava MUTO alla login; (5) il timeout buttava fuori vitti

MENTRE lavorava sul VRW.

Fatto:

dai riquadri. Ora Utenti/Config/Sessioni/Log si aprono nella STESSA scheda; si

torna dalla voce "Amministrazione" in barra. Fine proliferazione.

.vrp-fixed-body, cosi' scatta la macchina "wide+fisso+scroll interno" gia'

esistente (body:has(.vrp-fixed-body) in vrp-lab.css). Zero CSS nuovo.

(fold) con la voce "Sfondo (wallpaper)" che edita ui.wallpaper in env.json.

Salvataggio + validazione: se l'URL sta sotto la base (/lab/...) si mappa al

filesystem e si controlla che il file esista (ui.wallpaper (file non trovato)

fra gli errori). Messa in cartella la foto public/wallpapers/buddha.jpeg

(da /tmp, gruppo http, 664). NB: env.json NON toccato a mano su richiesta di

vitti: lo sfondo si sceglie dalla pagina (resta sfondo_spagna finche' non salva

buddha).

quando serve l'accesso non si salta piu' muti alla login. Splash "Riservato -

<SERVIZIO> richiede l'accesso", meta-refresh a 5s verso la login, bottone "Vai

subito". Porta con se' svc e next. Agganciato in DUE punti:

next=<rotta>`;

admin/auth:required ora vanno al gateway con next=REQUEST_URI (il ramo

lan resta 403 secco).

Solo percorsi same-origin sotto la base (strncmp base, niente // ne'

a-capo) -> NIENTE open-redirect; ostili -> home. Portato anche nel POST (campo

hidden) cosi' sopravvive all'invio del form.

causa era il meta-refresh di una scheda di piattaforma lasciata ferma che dopo

il TTL andava dritta a logout&t=1 e sloggava, anche se sul VRW eri

attivissimo (ogni pagina rinfresca vrp_last via vrp_session_check al boot,

ma la scheda immobile non lo sa). Ora logout.php?t=1 NON slogga se

time()-vrp_last <= TTL (sessione viva altrove): torna a ?p=home. Inoltre il

meta-refresh del FC ora usa il tempo RESIDUO (TTL - inattivita' + 5) invece

del TTL fisso.

Collaudo: php -l su tutti i 7 file OK. Contro nginx vivo (127.0.0.1 = LAN):

?p=home 200; ?p=admin da anonimo -> 302 al gateway `?p=accesso&svc=admin&

next=...`; gateway rende meta-refresh 5s + "<SVC> richiede l'accesso" + bottone;

login ?next= porta il campo hidden col target; login con next=//evil.com

RIFIUTA (0 campi next -> home). Render CLI come utente id 1 (stesso harness del

05/07): admin = 2 marcatori fixed-head/body e 0 target="_blank"; config = voce

"Aspetto" presente col valore wallpaper attuale.

Aperto: resta il punto 2 vero e proprio (tab/aree interne riusate: per ora

la proliferazione e' spenta tornando alla navigazione in-scheda, ma un vero

"tab per servizio" e' rimandato); "tutto wide" anche altrove se vitti vuole;

integrazione VERA di VRS share (login+WAN) e Step "Scarica da Nextcloud"; orfani

_cfg.php/_pecore.php in wiz_foto; rename CSS .vv- -> .vrw-;

lenostre_index.php -> vrn_index. Da provare da loggato in browser: cruscotto

wide e scelta buddha dal form Aspetto.


2026-07-06 (2) - Sfondi per-contesto + regia dei 3 tab (named target)

Perche': feedback di vitti provando in browser. (1) Ogni CONTESTO deve avere

il suo sfondo, riconoscibile e cambiabile SENZA codice (es. "se il buddha non

piace a Elena lo cambio in un attimo"). (2) La home doveva essere wide anch'essa.

(3) Sui tab avevo esagerato (tutto in una scheda): vitti vuole 3 schede a nome

fisso, riusate.

Modello sfondi deciso: piattaforma (tutte le sue pagine, incl. Config) =

spagna; ogni SERVIZIO = il suo (VRW = maloia); pagina di CORTESIA = buddha. La

cortesia NON e' un servizio: fa parte della piattaforma, quindi nel JSON di

piattaforma ci sono DUE voci (normale + cortesia).

Fatto:

pages/config.php): nuova costante VRP_WALLPAPER_CORTESIA da

ui.wallpaper_cortesia (vuoto = eredita quello di piattaforma). accesso.php usa

lo sfondo cortesia con fallback. La sezione Aspetto in Config ora ha DUE

voci: "Sfondo piattaforma" (ui.wallpaper) e "Sfondo cortesia"

(ui.wallpaper_cortesia); validazione file-esiste su entrambe (loop). env.json

NON toccato a mano: vitti sceglie dalle voci (buddha da salvare li').

maloia.jpeg (da /tmp, gruppo http 664) e valorizzato manifest.wallpaper`. La

cartolina VRW in home lo mostra gia' (.vrp-card-wp). Cambiabile dal riquadro

vrw in Config. (Dipingere anche le PAGINE interne del VRW resta da fare: e'

parte dell'integrazione VRW vera.)

body` (riusa la macchina wide). Come admin/config/utenti/sessioni/log.

o dell'unica scheda che collassava tutto:

Config e' PIATTAFORMA: spostata dal cruscotto admin ALLA barra (nav=true),

tolta dai riquadri di admin.php.

scheda condivisa (target="vr-servizi").

cruscotto (Utenti/Sessioni/Log) aprono in questa scheda condivisa

(target="vr-admin"). Aggiunto supporto target per-rotta nel FC

(public/index.php) e reso nella barra.

nativo del browser).

Collaudo: php -l su tutti i file OK. Render CLI (utente id 1): home = 1

fixed-head + fixed-body, 4 cartoline target="vr-servizi", maloia.jpeg sulla

VRW; admin = 3 riquadri target="vr-admin", niente "Configurazione", wide;

config Aspetto = due voci ("Sfondo piattaforma"=spagna, "Sfondo cortesia"=vuoto).

FC intero: barra = Piattaforma | Amministrazione (target vr-admin) |

Configurazione (_self). Cortesia via HTTP: eredita spagna finche' non si salva

buddha.

Aperto: dipingere le pagine INTERNE dei servizi col loro sfondo (VRW=maloia)

= integrazione VRW vera; integrazione vera VRS (login+WAN) + Step Nextcloud;

orfani _cfg.php/_pecore.php; rename CSS .vv- -> .vrw-; `lenostre_index ->

vrn_index`; "tab per servizio" ancora piu' fine se i named target non bastano.


2026-07-06 (3) - Permessi scrittura config + sfondo che veste le pagine del servizio

Perche': (1) salvando la config: `file_put_contents(env.json): Permission

denied - php-fpm gira come http` ma i JSON erano a sola lettura per il gruppo.

(2) vitti vuole lo sfondo del servizio (VRW=maloia) NON solo sulla cartolina ma

sulle PAGINE del servizio, e modificabile "come piattaforma e cortesia".

Fatto:

config/*.json -> 664 (gruppo http in scrittura); cartella config/ ->

2775 (setgid) cosi' "Aggiungi servizio" puo' creare il nuovo file col gruppo

giusto. env_backups/ e config/backups/ erano gia' g+w. NB: era proprio il

buco che mancava dopo aver reso editabile la config dalla pagina.

servizio** (lib/vrp_services.php + boot/3_2_1_Go.php): due funzioni nuove.

vrp_current_service() riconosce il servizio ospitato in cui cade la richiesta

(url targa vs SCRIPT_NAME, come la guardia). vrp_service_bg() (chiamata al

boot dopo la guardia) bufferizza l'output e, se c'e' un wallpaper nella targa,

inserisce un <style> PRIMA di </head> (o dopo il primo <link .css>) che

mette lo sfondo con un velo scuro (.58->.82) per la leggibilita'. Vince sul tema

perche' inserito per ultimo nella testata. Le pagine del wizard NON emettono

quasi mai <body>: per questo dipinge la PIATTAFORMA, non le pagine. CSV,

download e binari (senza </head> ne <link .css>) restano INTATTI (il

callback li lascia passare identici). Il velo forte + i pannelli opachi del tema

VRW tengono tutto leggibile; maloia incornicia ai lati del .vv-wrap (920px).

riquadro di OGNI servizio, sopra il JSON grezzo, una voce amichevole Sfondo

(id f-wp-<servizio>, univoco). Fonde nel manifest.wallpaper al salvataggio

(il campo e' la fonte di verita'), con la stessa validazione file-esiste.

Impostato config/vrw.json -> maloia.

Collaudo: php -l OK sui file toccati. Motore d'iniezione provato su 3

campioni: pagina con </head> -> style prima di </head>; pagina col solo

<link .css> -> style dopo il link; testo CSV -> intatto. Render CLI config:

voce Sfondo per ogni servizio, VRW prefillato con maloia. Permessi verificati

(664 gruppo http, config/ 2775). DA VEDERE IN BROWSER (loggato): una pagina del

wizard vestita di maloia.

Aperto: provare in browser il wizard vestito (e valutare se il gestore_foto,

UI ricca, sta bene o va escluso); poi integrazione VRS vera + Step Nextcloud;

orfani _cfg/_pecore; rename CSS .vv- -> .vrw-; lenostre_index -> vrn_index.


2026-07-06 (4) - VRW: sfondo senza velo, tema wide/translucido, menu cruscotto, rename import

Perche': feedback di vitti provando il wizard in browser (dal fiume). (1) maloia

troppo scuro = via il velo, foto originale; (2) heic_to_jpg + import "wide e pannelli

trasparenti/opachi come le altre pagine"; (3) il menu a 6 bottoni -> cruscotto con le

voci vive, i vecchi passi Amazon (Upload/Unzip/CSV) da parte; (4) import_amazon.php

-> togliere "amazon" dal nome (non si usera' piu').

Fatto:

linear-gradient scuro dall'iniezione; ora `body{background:url(<wp>) center/cover

fixed no-repeat}` = foto originale piena. La leggibilita' la garantiscono i pannelli

translucidi (sotto), non piu' un velo che scuriva la foto.

del wiz in un colpo: .vv-wrap max-width 920 -> 1100; .vv-card/.vv-banner/

details da colore pieno a rgba(.74) + backdrop-filter blur(4px) cosi' lo sfondo

del servizio traspare (stile pannelli di piattaforma). Aggiunte classi cruscotto

.vv-cards/.vv-tile (tessere translucide).

(Scarica da Nextcloud, Converti HEIC->JPG, Import in leNostre, Gestore foto); i vecchi

passi Amazon (Upload/Unzip/Esporta CSV) spostati in un <details> "Vecchi strumenti"

(declutter ma reversibile, niente cancellazioni).

puntavano: heic_to_jpg.php (x2), unzip_amazon.php (x1), e il menu. Header-commento

aggiornato. (Restano cosmetici interni: nome report import_amazon_v4_*.txt, _README.)

piano): la tessera non e' un clic a vuoto. La macchina vera (leggere

/data/<acct>/files/Photos, copiare in staging, poi Import) = prossimo giro.

Collaudo: php -l OK su index/nextcloud_import/import/heic_to_jpg/unzip_amazon e

vrp_services. Render CLI del menu: 4 .vv-tile giuste + "Vecchi strumenti", zero

residui import_amazon nei link. Iniezione senza velo confermata nel sorgente. DA

VEDERE IN BROWSER (loggato): maloia originale + pannelli translucidi + cruscotto.

Aperto (prossimo giro): la MACCHINA dello step 0 Nextcloud (usare le 2 foto del

fiume in Photos/2026/07/06 come cavie); valutare gestore_foto (UI ricca) con lo

sfondo; poi integrazione VRS; orfani _cfg/_pecore; rename CSS .vv- -> .vrw-;

lenostre_index -> vrn_index; report/README residui con "amazon".


2026-07-06 (5) - Step "Scarica da Nextcloud": import DIRETTO in leNostre (FATTO)

Perche': costruire la macchina vera dello step 0 (finora stub). Vitti al fiume,

su 5G (221 Mbit -> banda non e' il problema): auto-upload e meta-refresh RIMANDATI,

focus sull'import da Nextcloud.

Fatto:

funzioni-motore stavano SOLO in import.php (nessuna collisione). Aggiunte in vrw.php

con nomi vrw_* NUOVI (niente clash con le copie legacy di import.php, che resta

intatto): vrw_is_jpeg, vrw_exif_date, vrw_filename_date,

vrw_filename_year_hint, vrw_safe_target_path, vrw_is_duplicate_by_size, e

vrw_ingest() (importa UN file: data EXIF->nome->[mtime]->indecise;

dest AAAA/AAAA_da_archiviare/MMGG/AAAAMMGG-HHMMSS.jpg; niente sovrascritture;

doppioni per dimensione; ritorna un array esito, con flag dry). NB vrw_ingest

ha un nome diverso da import.php::vrw_import_file APPOSTA (entrambe caricate? no:

import.php e' una pagina; la lib gira ovunque -> nome diverso = zero redeclare).

DEBITO NOTO: migrare import.php a vrw_* e togliere le sue copie (TODO snello).

(nextcloud: data_dir=/srv/dati/nextcloud/data, photos_subdir=Photos,

accounts=[vitti,lella]); selezione account (whitelist); scansiona

data_dir/<acct>/files/Photos/AAAA/MM/GG e mostra le cartelle-giorno con conteggio

jpeg (checkbox, piu' recenti in cima); opzioni "solo anteprima" (default ON) e

"fallback mtime"; import in copy (gli originali restano su Nextcloud) via

vrw_ingest -> leNostre. Whitelist dei giorni dal set scansionato (no traversal).

Solo JPEG per ora (video = TODO). Livrea vv-theme (maloia + pannelli translucidi).

Collaudo: php -l OK (vrw.php + nextcloud_import.php). DRY-RUN reale (harness

CLI, utente 1, POST acct=vitti days=2026/07/06 dry_run=1): Lette 2, Importate 2,

Indecise/Doppioni/Errori 0; datazione [NOME] corretta (IMG_20260706_105246 ->

06/07 10:52:46); zero scritture su leNostre confermato. Permessi: leNostre +

leNostre/2026 = drwxrwsr-x gruppo http -> php-fpm(http) scrive. Manca solo la prova

REALE dal browser (vitti loggato) -> deseleziona "solo anteprima" e importa.

Aperto: import REALE dal browser (le 2 foto fiume) + vederle in Gestore foto ->

poi mostrare a ELENA; VIDEO (vrw_ingest fa solo jpg, i .mp4/.mov vanno gestiti a

parte, magari in una cartella video di leNostre); barra "pecore" per lotti grossi

(ora e' POST sincrono); migrare import.php al motore vrw_*; auto-upload app +

meta-refresh servizio (rimandati).


2026-07-06 (6) - Rifiniture flusso wiz + auto-HEIC nell'import

Perche': feedback di vitti dopo il dry-run. (1) gestore_foto senza ritorno al

wiz; (2) heic_to_jpg con rimandi vecchi "Step 2/Step 4"; (3) import.php ormai

inutile (l'import Nextcloud va dritto in leNostre); (4) pagina Nextcloud troppo

lunga; (5) HEIC: metterlo tra i vecchi e convertirlo AL VOLO nell'import.

Fatto:

testata (vitti: "poco visibile ma una volta imparato ok" - lasciato, si vedra' con

Elena).

nav + pannello pecore) -> resta solo "↑ Torna al Wizard".

Gestore foto). "Import da staging" e "Converti HEIC (manuale)" spostati in

"Vecchi strumenti".

overflow) + checkbox "seleziona tutti" (JS). Non allunga piu' la pagina.

vrw_heic_to_jpg() (heif-convert -> magick -> convert, il primo disponibile;

tool memoizzato; nomi NUOVI, niente clash con vrw_pick_converter/vrw_run_convert

di heic_to_jpg.php). In nextcloud_import: la scansione conta jpg+heic; nell'import

vero un HEIC viene convertito in un jpg temporaneo (sys_get_temp_dir, basename

conservato per la datazione dal nome), poi ingerito e il temp cancellato; in

anteprima e' solo segnalato. Tutti i tool presenti sul server (heif-convert,

magick, convert).

Collaudo: php -l OK. Dry-run 2026/07/06 ancora 2/2. Menu = 2 tessere.

Round-trip HEIC provato davvero: magick crea un .heic di prova ->

vrw_heic_to_jpg() lo riconverte in jpg (172 KB, rc 0). Manca solo l'import REALE

dal browser (vitti sta per farlo).

Aperto: import reale + demo Elena stasera; **svuota Nextcloud dopo import via

WebDAV** (destructive: serve app-password per non desincronizzare l'indice NC -

proposto, non ancora fatto); video; migrare import.php al motore vrw_*.

FIX 06/07 - banner "senza feedback": vitti fa l'import reale (funziona: 2 file

in leNostre/2026/2026_da_archiviare/0706 come 20260706-HHMMSS.jpg) ma "nessun

feedback". Causa: i .vv-banner.vv-ok/err/warn avevano sfondo a 14% (nati per

il fondo scuro pieno) -> su maloia sparivano. Reso opachi ~88% (dark tinto per

tipo, bordino colorato) in theme.css. Verificato riproducendo il POST reale

(harness): il banner c'era gia' nell'HTML (Lette 2 / Doppioni 2 al re-run = dedup

OK), era solo invisibile. Nota generale: i tint a bassa opacita' non reggono sopra

i wallpaper -> alzare l'alpha.


2026-07-07 - Motore img condiviso (vrp_img) + anteprime Nextcloud + Esci ovunque

Giornata nata dal collaudo dell'import con Elena (punch-list in memoria

project_vrw_demo_elena): rifiniture UX + il primo pezzo di piattaforma che serve

DAVVERO a piu' servizi (un motore immagini condiviso).

Rifiniture pagina import (nextcloud_import.php):

repeat(auto-fill,minmax(180px,1fr))), box piu' alto (poi 460px).

davvero. Elena vuole FARE, non guardare a vuoto.

**MOTORE IMMAGINI CONDIVISO - platform/lib/vrp_img.php (estratto da maps/img.php,

che resta INTATTO): pattern motore puro + cappelli**. Due funzioni pure, stile

di casa (@desc/@param, fail-loud): vrp_img_resolve($src,$bases) (web-prefix ->

path reale + guardia anti-traversal) e vrp_img_serve($fsPath,$w,$opt) (resize +

cache disco + orientamento EXIF + ETag; EMETTE ed esce). Costanti

VRP_IMG_ALLOWED_W/DEFAULT_W/QUALITY. Nessun gate nel motore (scelta chiave): chi

puo' vedere cosa lo decide il CAPPELLO; il motore ha i pomelli cache_dir e

visibility:public|private per gli alberi sensibili. Collaudo CLI: lint, traversal

-> NULL, ridotta una foto leNostre (480x328) *e* una Nextcloud (480x853) = serve

entrambe le radici; cache creata.

ANW nel nuovo schema: il motore non puo' esporre ANW (non gestisce accessi). La

regola odierna (path sotto /srv/http/leNostre/ANW/ -> LAN-only + cache privata)

diventa un WRAPPER esplicito nel futuro cappello maps; STESSA ricetta del cappello

Nextcloud (albero sensibile = LAN + private). In collaudo non renderizzata alcuna

foto ANW di proposito.

Cappello wiz_foto/nc_thumb.php (thumbnail SORGENTE su Nextcloud per l'anteprima

prima dell'import): require vrp_img.php, gate vrp_is_lan(), data_dir dalla targa

vrw, vrp_img_resolve($src,['/ncsrc'=>$dataDir]), DOPPIA CINTURA (anti-traversal

+ il path reale deve contenere /files/Photos/ -> note/BANCHE NON sbirciabili),

serve cache_dir=null (on-the-fly v1) + visibility:private.

Anteprime per-giorno in nextcloud_import.php: la scansione raccoglie i basename

jpeg per giorno ($dayJpegs; heic contati ma non sbirciabili). Ogni giorno ha 👁;

click -> pannello con griglia <img loading=lazy src="nc_thumb.php?..."> on-demand.

Selezione per-foto (richiesta di Elena): ogni thumbnail ha una casella (default

spuntata=importa); deselezioni le schifezze -> l'import le SALTA (JS Set ncExcluded

-> hidden exclude[]; PHP: $excl=array_flip($_POST['exclude']), skip su

$rel.'/'.basename). Multi-cartella GIA' possibile (esclusioni globali).

Rifiniture 2a-3a prova browser:

Sorgente/Destinazione.

anteprima si toglie ((!$didImport && $dryRun)), esclusioni preservate (JS

NC_EXCL_INIT seed).

l'handler per-foto via dispatchEvent).

tutte -> si dispunta. Risolve "seleziono la foto ma il giorno resta vuoto".

Esci in OGNI pagina-servizio - vrp_service_esci() in lib/vrp_services.php,

chiamata nel boot 3_2_1_Go.php dopo vrp_service_bg(). Gemella dello sfondo:

bufferizza l'output e inietta un "Esci" fisso (in alto a dx) SOLO nelle pagine-servizio

loggate (che non hanno la barra di piattaforma). Stessa guardia salva-binari dello

sfondo (inietta dopo <link .css> o prima di </head>; CSV/immagini/binari INTATTI ->

i JPEG di nc_thumb non si corrompono). URL assoluto vrp_url('public/?p=logout') (le

pagine-servizio sono fuori dal front controller).

Collaudo: php -l su tutti i file OK; ASCII puro, zero curly-quotes; cintura Photos

provata (Photos AMMESSO / Notes BLOCCATO); iniezione Esci provata su 3 output (pagina

wiz INIETTATO, con-head INIETTATO, binario JPEG INTATTO). NON verificato dal vivo nel

browser i pezzi che richiedono la sessione (render anteprime, comparsa Esci): li prova

vitti loggato.

Doc: B200 aggiornato (sez.0 strato meta-utility search+img; sez.3b la piattaforma

inietta cornice - sfondo+Esci - nelle pagine servizio). API rigenerate con

genera_doc.php.

Aperto/debito: cache privata su disco per nc_thumb (scegliere dir scrivibile+negata

da nginx); cappello maps ANW-aware quando si rifara' maps/img.php (originale ora intatto);

versione leNostre delle anteprime = riusa vrn_foto_search+vrp_img; svuota-Nextcloud

post-import (WebDAV, destructive); video; migrare import.php a vrw_ingest.


VRS - Port dello Share nella piattaforma (08/07/2026) - CHIUSO

Cosa: portato il servizio Share (VittRos Share) da /srv/http/share (standalone, core

VRV) a /lab/public/share nella piattaforma. Primo servizio ospitato "pieno" dopo il wizard.

Struttura: lib platform/lib/vrs.php (funzioni vrs_*, convenzione VRP); pagine

public/share/ (index, download, upload, create_dir, thumb, delete) + anw/verboten.php.

I dati share_dirs/share_files restano in vittrosviaggi, registrato come DB vrv

(secret stabile secrets/db_vrv.php). Identita' di piattaforma (vrp_current_user).

Feature: thumbnail immagini via vrp_img (thumb.php); anteprime VIDEO via fotogramma

ffmpeg (cache .vthumb) con badge play + fallback onerror; upload multi con PRG

(redirect in cartella + banner + overlay d'attesa col filmato pecore .mp4); cancella HARD

(unlink fs + DELETE riga + rmdir) con guardia vrs_can_manage (proprietario o admin);

griglia a mattonelle.

Permessi: ruoli VRS = admin + registrato (registrato = qualsiasi loggato, nessun

ruolo da assegnare). Fix home.php: la cartolina dei servizi auth:required la vede ogni

loggato (visibilita' = stessa regola della guardia d'accesso, non piu' per-ruolo).

Verboten (gag 403): pagina mockup con foto naturista gatata (LAN+login), 2 versioni

(full / purga: cartello FRECH! con ImageMagick sul petto + taglio basso), in share/anw/,

nessun link visibile.

Sessioni admin: filtri username (LIKE) + action (dropdown da valori distinti) + pulisci

filtri; sort su username gia' presente. Preparazione al registro azioni.

Generatore doc: genera_doc.php ora aggiunge "Usato in" (grep dei punti di chiamata,

file:riga) per ogni funzione. API rigenerate (83 funzioni).

Collaudo: php -l su tutti i file; giri HTTP autenticati (login bot usa-e-getta,

ripristinato): render share, thumb immagine+video JPEG puliti, upload PRG, delete hard,

verboten full+purga, cartolina home per utente senza ruolo vrs. nginx client_max_body_size

50M->2g (sudo vitti) per gli upload grossi.

Aperto: registro azioni (logging vrp_action, scelta A/B); VittExplorer -> vrp_explorer

(estrarre da share + media_popup VRV); leNostre50 sul vecchio /maps/img.php -> vrp_img;

unificazione utenti in vrp_auth (owner dei file vecchi).