Vai al contenuto

Cestino e registro operazioni

Cestino

Eliminazione logica

I modelli che si possono ripristinare implementano SoftDeletable e usano SoftDeleteTrait:

  • softDelete() valorizza deleted_at e deleted_by con updateAttributes, quindi senza gli eventi di salvataggio;
  • restore() li azzera, ma non funziona più dopo lo svuotamento (purged_at);
  • find() restituisce una SoftDeleteQuery che esclude da sola gli elementi eliminati; withDeleted(), onlyDeleted() (esclusi gli svuotati) e onlyPurged() cambiano il filtro.

Tipi nel cestino (TrashService::TYPES): task, stato, vista, filtro, link, webhook, allegato, relazione, promemoria, ruolo personalizzato, bacheca, team. Non ci finiscono commenti, checklist, ore, cronologia, etichette, riunioni e assenze: si eliminano davvero.

Bacheche e team

Eliminare una bacheca o un team marca il contenitore e tutto il suo contenuto attivo con lo stesso trash_group (lo uuid del contenitore). Si ripristinano insieme, e un elemento del gruppo non si ripristina da solo. Le appartenenze ai team restano.

restoreBlocker() spiega perché un elemento non si può ripristinare: fa parte di un gruppo, il suo contenitore è nel cestino o svuotato, oppure è una task di una bacheca senza stati attivi.

Chi vede il cestino

TrashPolicy:

  • il super amministratore vede tutti i tipi, nei team che può vedere;
  • chi ha uno spazio personale vede solo le proprie task eliminate;
  • svuotare il cestino richiede di essere super amministratore e overseer.

Svuotamento ed eliminazione definitiva

  • purge() (un elemento) e emptyTrash() (tutto) non cancellano: valorizzano purged_at. Righe e file restano, e il super amministratore li vede nel pannello alla voce "Eliminati definitivamente".
  • php yii trash/purge [--days=N] fa lo stesso svuotamento per gli elementi nel cestino da più di N giorni, con purged_by nullo perché lo fa il sistema. Senza params['trash']['retentionDays'] (predefinito 30) e senza --days non fa nulla. Il worker Docker lo lancia ogni notte alle 03:30.
  • Nessun comando cancella righe del cestino dal database.

Registro operazioni

Il registro (AuditLog, tabella audit_log) dice chi ha fatto cosa, quando, da dove e con quale effetto.

Cosa si registra

AuditLogBootstrap ascolta tutti gli Active Record:

  • inserimento (valori nuovi), modifica (solo i campi cambiati, e nulla se non è cambiato niente), eliminazione (valori vecchi);
  • cestino e ripristino;
  • login (con password o con il cookie "ricordami") e logout.

Altre voci si scrivono esplicitamente con AuditLogger::record(): login falliti, assegnazione e revoca di ruoli, password reimpostate, svuotamenti del cestino, esportazioni CSV, download di allegati, operazioni di manutenzione.

Ogni voce porta actor, action, entità e uuid, modifiche in JSON, contesto (frontend, backend, api, console), rotta, metodo, IP e user agent. Le azioni "gravi" (SEVERE_ACTIONS) sono evidenziate nel pannello.

Regole di AuditLogger

  • Non lancia mai eccezioni: un problema del registro non deve far fallire l'operazione.
  • Gli attributi sensibili (password, hash, token, segreti, chiavi push…) sono sostituiti con •••.
  • id, uuid, created_at, updated_at non si registrano; i valori sono tagliati a 1000 caratteri.
  • Senza utente l'autore è console; con un token API master è utente via nome-token.

Configurazione e consultazione

  • params['audit']['enabled'] spegne il registro (solo per migrazioni massive).
  • ignoredModels esclude le tabelle che l'applicazione riempie da sola: stati di lettura, notifiche, consegne dei webhook, posizioni.
  • retentionDays (predefinito 365) e php yii audit/prune [--days=N] potano il registro; con null e senza --days non si cancella nulla. Il worker Docker lo lancia ogni notte alle 03:45. php yii audit mostra le statistiche.
  • Nel pannello il registro si consulta e si esporta, non si modifica. Serve essere super amministratore e overseer, perché il registro racconta i movimenti di tutti i team. Con la stessa regola si legge da GET /v1/admin/audit (ricerca in common/models/AuditLogSearch).
  • Le operazioni fatte da Claude con il connettore MCP risultano dell'utente che ha dato il consenso, come le chiamate con il suo token.