Aller au contenu

Modèle de données

Les tables fraza_feedback_* du module Rétroaction, ses migrations, ce qu'un rapport garde de son auteur et combien de temps.

Toutes les tables sont préfixées fraza_feedback_. Un compte est désigné par l'identifiant du compte du core, en texte, sans clé étrangère : supprimer un compte ne supprime pas les rapports qu'il a envoyés.

Les fiches vivent dans le module Projets. Un rapport pointe la fiche dans laquelle il a été lu, jamais l'inverse : plusieurs rapports, une fiche. Ce lien n'a pas de clé étrangère, puisque le module Projets peut être absent ou retiré.

fraza_feedback_project

Un projet, avec sa boîte de réception, son formulaire et ses étiquettes.

ChampContenu
slugSon adresse publique (/za/feedback/<slug>/nouveau), fixée à la création, unique. Jamais nouveau ni suivi.
nameSon nom, 60 caractères au plus.
positionSon rang dans la liste.
is_publicSon formulaire existe et accepte les envois.
is_defaultLe projet principal : un seul, celui des adresses sans slug de projet.
projects_project_idLe projet du module Projets dont ce projet est le reflet, et dont les fiches reçoivent ses rapports, ou NULL. Sans clé étrangère. Unique : un seul projet de la rétroaction par projet de Projets. Remis à NULL quand ce projet est supprimé dans Projets et que le projet de la rétroaction garde des rapports.
archived_atSon archivage, ou NULL. Reprend celui de son projet de Projets, sauf pour le projet principal, jamais archivé. Un projet archivé n'a plus de formulaire public et sort de la liste des projets publics.

createTables() crée le projet « Principal » (principal). Un projet ne se supprime que sans rapport, et ses étiquettes partent avec lui.

Avec le module Projets, les lignes de cette table suivent ses projets. Voir Avec le module Projets.

fraza_feedback_report

Ce qu'une personne envoie.

ChampContenu
project_idSon projet.
typebug, idea ou question.
title, bodyLa phrase (200 caractères au plus) et les détails (5000).
statusnew, linked (lu dans une fiche du module Projets) ou closed.
close_reasonresolved, duplicate, declined ou spam, pour un rapport fermé.
duplicate_ofPour un rapport fermé comme duplicate, le rapport original, ou NULL. Clé étrangère vers fraza_feedback_report, ON DELETE SET NULL : supprimer l'original laisse au doublon sa raison et efface le lien. L'original peut être d'un autre projet. Il n'est jamais lui-même un doublon : fermer un original comme doublon d'un autre emmène ses doublons vers ce nouvel original. Remis à NULL quand le rapport est rouvert, lié à une fiche, ou fermé pour une autre raison.
sensitiveTouche à la sécurité.
emailL'adresse donnée par une personne sans compte, ou NULL.
user_idLe compte qui l'a envoyé, ou NULL.
contextCe que la personne a laissé joint, parmi page, browser, system, screen, language et version, 300 caractères chacun au plus. Le formulaire du module joint la page, le navigateur, l'écran et la langue.
ipLe réseau de l'adresse : /24 en IPv4, /48 en IPv6. Jamais l'adresse complète.
item_idLa fiche du module Projets dans laquelle il a été lu, ou NULL. Toujours une fiche du projet que nomme projects_project_id.
tag_idSon étiquette, du même projet.
follow_nonceSert à signer le lien de suivi. L'effacer coupe le lien.
closed_at, anonymized_atSa première fermeture, et l'effacement de ses données personnelles. Fermer de nouveau un rapport fermé ne change que close_reason.

fraza_feedback_message

Les échanges d'un rapport : kind vaut internal (une note de l'équipe), public (une réponse à l'auteur) ou author (un message de l'auteur, depuis sa page de suivi ou son espace client). body fait 5000 caractères au plus. author_id et author_name disent qui l'a écrit : pour un message de l'auteur, author_id est son compte s'il en a un, et author_name reste NULL. Supprimés avec le rapport.

fraza_feedback_attachment

Les captures d'écran d'un rapport : key (l'objet dans le stockage, sous feedback/<id du rapport>/), filename, size, content_type. content_type vient de l'extension que l'envoi a validée, jamais du type que déclare le navigateur. Supprimées avec le rapport.

fraza_feedback_tag

Les étiquettes d'un projet : project_id, name, unique dans son projet sans tenir compte de la casse, position, et is_public, vrai pour une étiquette que le formulaire public propose (depuis la migration 004-tag-public). Supprimer une étiquette la retire des rapports qui la portaient.

fraza_feedback_storage_deletion

La file des objets à retirer du stockage. Un déclencheur sur fraza_feedback_attachment y inscrit la clé de toute capture supprimée, dans l'instruction qui la supprime : depuis l'admin, par la conservation, en cascade avec son rapport, ou à la main en SQL. Il n'inscrit qu'une clé rangée sous le dossier de son propre rapport. Supprimer un rapport y inscrit aussi son dossier, qui emporte un objet qu'un envoi interrompu aurait laissé.

La tâche feedback-retention vide la file, et la suppression d'un rapport la vide pour lui dès la réponse envoyée. Un objet que le stockage refuse est retenté plus tard, avec une attente qui double à chaque échec, une journée au plus.

Migrations

createTables() crée le schéma courant, migrations comprises, et fraza-db init pose une ligne 000-baseline après lui. Les migrations numérotées passent ensuite, sur une base neuve comme sur une base déjà déployée. Sur une base neuve, elles ne trouvent rien à faire. Après une mise à jour, lancer npx fraza-db migrate.

MigrationEffet
001-close-reason-spamLa contrainte de close_reason accepte spam.
002-report-duplicate-ofAjoute duplicate_of et son index.
003-author-messagesLa contrainte de kind dans fraza_feedback_message accepte author.

Chacune se rejoue sans effet. 001 et 003 remplacent toute contrainte CHECK qui porte sur leur colonne par une seule, nommée fraza_feedback_report_close_reason_check et fraza_feedback_message_kind_check.

Conservation

Un rapport est terminé quand il est fermé, ou quand la fiche du module Projets à laquelle il est lié est dans une colonne terminée. FRAZA_MODULE_FEEDBACK_RETENTION_DAYS jours après sa première fermeture, ou après l'entrée de sa fiche dans cette colonne, la tâche feedback-retention efface ce qui dit qui l'a écrit et d'où : email, ip, context, follow_nonce, et ses captures. Le texte reste, avec le compte qui l'a envoyé, pour que la personne le retrouve dans son espace client. anonymized_at note l'effacement.

Deux cas s'ajoutent, avec le même effacement :

  • Un rapport fermé comme indésirable (spam) perd ces données un jour après sa fermeture, ou au bout du délai de conservation s'il est plus court. Ce jour laisse le temps de rouvrir un rapport fermé par erreur, ses données intactes.
  • Un rapport jamais traité, encore new, les perd FRAZA_MODULE_FEEDBACK_RETENTION_DAYS jours après sa réception. Garder l'adresse et le contexte d'un rapport que personne ne lit n'a pas de raison. Il reste dans la boîte de réception, son texte intact, et l'admin affiche « Effacé » à la place de son auteur. Son lien de suivi cesse de fonctionner.

Avec FRAZA_MODULE_FEEDBACK_RETENTION_DAYS=0, rien n'est effacé, ces deux cas compris. Sans le module Projets, un rapport lié n'est jamais effacé : l'état de sa fiche ne se lit plus.

Un rapport effacé ne reçoit plus de message de son auteur, ni de courriel de fermeture ou de réouverture.

Avant d'effacer, la tâche remet à jour les projets repris de Projets, puis renvoie dans la boîte de réception les rapports dont la fiche n'existe plus dans Projets : item_id repasse à NULL, un rapport linked redevient new, un rapport fermé le reste. Projets prévient la rétroaction de la suppression d'une fiche, mais un échec à ce moment, ou la rétroaction désactivée, laisserait sinon un rapport lié à rien, jamais terminé ni effacé. Ces deux étapes ne tournent qu'avec le module Projets. Leur échec est journalisé et n'empêche pas l'effacement. Voir Tâche planifiée.

Sur cette page