[STD] Version-provenance sulle segnalazioni (feedback-version-provenance) — mig.062, v1.24.4

feedback_reports += client_surface/client_version/client_build; FeedbackController/Service li salvano; feedback.js li invia (surface web-v2 + version/build da version.json). Standard hub_standards id=30. Smoke verde (provenance salvata, test pulito). NB: il widget feedback.js è oggi dormiente (rimosso dall'iniezione 14/6) → plumbing pronto per la riattivazione.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-21 09:14:13 +02:00
co-authored by Claude Opus 4.8
parent 3b1d909e6e
commit 14c4c2a7d2
6 changed files with 39 additions and 4 deletions
@@ -0,0 +1,11 @@
<?php
/** migrate_062_feedback_provenance.php — version-provenance su feedback_reports (std feedback-version-provenance). IDEMPOTENTE. */
if (PHP_SAPI !== 'cli') { http_response_code(403); exit("CLI only\n"); }
require_once __DIR__.'/../config/env.php'; require_once __DIR__.'/../config/database.php';
$pdo=Database::getInstance(); $db=$pdo->query('SELECT DATABASE()')->fetchColumn();
function addc($p,$db,$t,$c,$ddl){ $s=$p->prepare("SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=? AND TABLE_NAME=? AND COLUMN_NAME=?"); $s->execute([$db,$t,$c]); if($s->fetchColumn()){echo " = $t.$c\n";return;} $p->exec("ALTER TABLE `$t` ADD COLUMN $ddl"); echo " + $t.$c\n"; }
echo "Mig 062 — version-provenance feedback_reports\n";
addc($pdo,$db,'feedback_reports','client_surface',"client_surface VARCHAR(16) NULL");
addc($pdo,$db,'feedback_reports','client_version',"client_version VARCHAR(32) NULL");
addc($pdo,$db,'feedback_reports','client_build', "client_build VARCHAR(64) NULL");
echo "FATTO. Prossima mig=063.\n";
@@ -40,6 +40,10 @@ class FeedbackController extends BaseController
$descrizione = trim($body['descrizione'] ?? ''); $descrizione = trim($body['descrizione'] ?? '');
$pageUrl = trim($body['page_url'] ?? ''); $pageUrl = trim($body['page_url'] ?? '');
$attachment = $body['attachment'] ?? null; // base64 string $attachment = $body['attachment'] ?? null; // base64 string
// version-provenance (std feedback-version-provenance): superficie + release REALE del prodotto + build
$clientSurface = substr(trim((string) ($body['client_surface'] ?? '')), 0, 16) ?: null;
$clientVersion = substr(trim((string) ($body['client_version'] ?? '')), 0, 32) ?: null;
$clientBuild = substr(trim((string) ($body['client_build'] ?? '')), 0, 64) ?: null;
if (strlen($descrizione) < 10) { if (strlen($descrizione) < 10) {
$this->jsonError('Descrizione troppo breve (minimo 10 caratteri).', 422); $this->jsonError('Descrizione troppo breve (minimo 10 caratteri).', 422);
@@ -67,6 +71,9 @@ class FeedbackController extends BaseController
'descrizione' => $descrizione, 'descrizione' => $descrizione,
'page_url' => $pageUrl, 'page_url' => $pageUrl,
'attachment' => $attachment, 'attachment' => $attachment,
'client_surface' => $clientSurface,
'client_version' => $clientVersion,
'client_build' => $clientBuild,
] ]
); );
+8 -3
View File
@@ -45,14 +45,19 @@ class FeedbackService
$descrizione = $data['descrizione'] ?? ''; $descrizione = $data['descrizione'] ?? '';
$pageUrl = $data['page_url'] ?? ''; $pageUrl = $data['page_url'] ?? '';
$attachment = $data['attachment'] ?? null; $attachment = $data['attachment'] ?? null;
$clientSurface = $data['client_surface'] ?? null;
$clientVersion = $data['client_version'] ?? null;
$clientBuild = $data['client_build'] ?? null;
Database::query( Database::query(
'INSERT INTO feedback_reports 'INSERT INTO feedback_reports
(organization_id, user_id, user_email, user_role, page_url, (organization_id, user_id, user_email, user_role, page_url,
tipo, priorita, descrizione, attachment) tipo, priorita, descrizione, attachment,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', client_surface, client_version, client_build)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[$orgId, $userId, $userEmail, $userRole, $pageUrl, [$orgId, $userId, $userEmail, $userRole, $pageUrl,
$tipo, $priorita, $descrizione, $attachment] $tipo, $priorita, $descrizione, $attachment,
$clientSurface, $clientVersion, $clientBuild]
); );
$reportId = (int) Database::lastInsertId(); $reportId = (int) Database::lastInsertId();
@@ -0,0 +1,5 @@
-- 062_feedback_version_provenance.sql — version-provenance sulle segnalazioni (std feedback-version-provenance v1.0)
-- Record DDL. Apply autoritativo idempotente: application/cli/migrate_062_feedback_provenance.php
ALTER TABLE feedback_reports ADD COLUMN client_surface VARCHAR(16) NULL; -- web-v1|web-v2|android|ios
ALTER TABLE feedback_reports ADD COLUMN client_version VARCHAR(32) NULL; -- release REALE del prodotto (NON la versione del widget)
ALTER TABLE feedback_reports ADD COLUMN client_build VARCHAR(64) NULL;
+7
View File
@@ -44,6 +44,7 @@
let _currentReportId = null; let _currentReportId = null;
let _attachmentBase64 = null; let _attachmentBase64 = null;
let _myReports = []; let _myReports = [];
let _appVer = null; // version-provenance: release REALE del prodotto (da /version.json)
// ── Init ────────────────────────────────────────────────────────────────── // ── Init ──────────────────────────────────────────────────────────────────
@@ -360,12 +361,18 @@
_setSubmitting(true); _setSubmitting(true);
// version-provenance: release REALE del prodotto + superficie + build (std feedback-version-provenance)
if (!_appVer) { try { _appVer = await (await fetch('/version.json?_=' + Date.now())).json(); } catch (e) { _appVer = {}; } }
const payload = { const payload = {
tipo, tipo,
priorita, priorita,
descrizione, descrizione,
page_url: pageUrl, page_url: pageUrl,
attachment: _attachmentBase64 || null, attachment: _attachmentBase64 || null,
client_surface: 'web-v2',
client_version: (_appVer && _appVer.version) || null,
client_build: (_appVer && _appVer.build) || null,
}; };
try { try {
+1 -1
View File
@@ -1 +1 @@
{"version": "1.24.3", "build": "2026-06-20-v1.24.3", "date": "2026-06-20", "changelog": "Allineamento help/traduzioni/AI per la gestione documentale SGSI: (1) Help contestuale — aggiunta in Impostazioni la sezione 'Permessi documentali (ciclo di vita SGSI)' e completata la guida del Modello SGSI su editor, download Word singolo/unico e ciclo di vita; (2) Traduzioni — matrice Permessi documentali resa bilingue IT/EN (azioni, ruoli, suggerimenti); (3) AI/KB — ingerito nella knowledge base RAG (nis2_kb, scope SYSTEM) il documento 'Gestione documentale SGSI' (ciclo di vita, export Word, editor, permessi), cosi' l'assistente puo' guidare l'utente su queste funzioni."} {"version": "1.24.4", "build": "2026-06-20-v1.24.4", "date": "2026-06-20", "changelog": "Version-provenance sulle segnalazioni (standard feedback-version-provenance): la tabella feedback_reports ora salva client_surface (web-v2), client_version (release reale del prodotto) e client_build; il backend (FeedbackController/FeedbackService) li persiste e il widget di segnalazione (feedback.js) li invia leggendo /version.json. Migrazione 062. Re-ingest nella KB della guida UI V2 corretta (sostituiti i chunk stale)."}