Projet

Général

Profil

Development #62800

action "édition", historisation des valeurs

Ajouté par Frédéric Péters il y a environ 2 ans. Mis à jour il y a plus d'un an.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Version cible:
-
Début:
15 mars 2022
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

Du travail de spécification sur la tarification,

Ça peut amener la nécessité d'une historisation des données côté w.c.s., parce qu'on voudra pouvoir obtenir les critères au moment de la réservation et/ou l'événement.
Techniquement, on pourrait activer l'historisation sur les fiches, et après édition/donnée de traitement, on enregistrerait un snapshot.

(ce ticket limité à l'enregistrement de l'info, pour l'affichage ou l'exploitation dans l'API, ça sera ailleurs).


Fichiers

0003-formdata-look-at-files-in-history-when-deleting-unus.patch (8,52 ko) 0003-formdata-look-at-files-in-history-when-deleting-unus.patch Lauréline Guérin, 07 octobre 2022 11:37
0002-formdata-store-data-history-62800.patch (45,6 ko) 0002-formdata-store-data-history-62800.patch Lauréline Guérin, 07 octobre 2022 11:37
0001-misc-split-workflow-tests.patch (103 ko) 0001-misc-split-workflow-tests.patch Lauréline Guérin, 07 octobre 2022 11:37
0003-formdata-look-at-files-in-history-when-deleting-unus.patch (8,52 ko) 0003-formdata-look-at-files-in-history-when-deleting-unus.patch Lauréline Guérin, 14 octobre 2022 11:52
0002-formdata-store-data-history-62800.patch (49 ko) 0002-formdata-store-data-history-62800.patch Lauréline Guérin, 14 octobre 2022 11:52
0001-misc-split-workflow-tests.patch (103 ko) 0001-misc-split-workflow-tests.patch Lauréline Guérin, 14 octobre 2022 11:52
0003-formdata-look-at-files-in-history-when-deleting-unus.patch (11,8 ko) 0003-formdata-look-at-files-in-history-when-deleting-unus.patch Lauréline Guérin, 20 octobre 2022 11:01
0001-misc-split-workflow-tests.patch (103 ko) 0001-misc-split-workflow-tests.patch Lauréline Guérin, 20 octobre 2022 11:01
0002-formdata-store-data-history-62800.patch (49 ko) 0002-formdata-store-data-history-62800.patch Lauréline Guérin, 20 octobre 2022 11:01
0003-formdata-look-at-files-in-history-when-deleting-unus.patch (11,8 ko) 0003-formdata-look-at-files-in-history-when-deleting-unus.patch Lauréline Guérin, 21 octobre 2022 12:11
0001-misc-split-workflow-tests.patch (103 ko) 0001-misc-split-workflow-tests.patch Lauréline Guérin, 21 octobre 2022 12:11
0002-formdata-store-data-history-62800.patch (50,2 ko) 0002-formdata-store-data-history-62800.patch Lauréline Guérin, 21 octobre 2022 12:11

Demandes liées

Lié à w.c.s. - Development #63811: Historisation des fichesFermé11 avril 2022

Actions
Lié à w.c.s. - Development #70271: API formdata: récupérer les données à un instant tFermé14 octobre 2022

Actions
Lié à w.c.s. - Development #70868: Historisation des données, afficher les modifications dans l'historique d'une demande/ficheFermé31 octobre 2022

Actions
Lié à Publik - Development #70054: Mieux cadrer et tracer les modificationsFermé10 octobre 2022

Actions

Révisions associées

Révision 5fc369a0 (diff)
Ajouté par Lauréline Guérin il y a plus d'un an

formdata: store data history (#62800)

Révision b6b72033 (diff)
Ajouté par Lauréline Guérin il y a plus d'un an

formdata: look at files in history when deleting unused files (#62800)

Historique

#1

Mis à jour par Olivier Renard il y a environ 2 ans

Pour appui de la demande, cela permettrait de tracer l'historique de la demande

#3

Mis à jour par Frédéric Péters il y a environ 2 ans

#4

Mis à jour par Frédéric Péters il y a plus d'un an

Techniquement j'imaginerais au moment des actions qui peuvent modifier les données (édition, modification fiche, donnée de traitement), enregistrer une copie des données dans un objet type ContentSnapshotPart ajouté dans evolution (le plus simple étant de juste taper dedans une copie de formdata.data et laisser ça se pickler, je ne pense pas utile de faire intervenir ici de l'export/import JSON).

Petit moment d'attention à avoir par rapport à la suppression des fichiers inutilisés, et par rapport à l'anonymisation.

Ensuite pour ce que je notais pour d'autres tickets : la partie API, quand une date serait fournie il s'agirait juste de remonter dans l'historique de l'évolution voir s'il y a un ContentSnapshotPart à prendre plutôt que le formdata.data.

Et pour une partie affichage, il y aurait à pareil retrouver les données avant/après et faire un affichage basique des champs modifiés, façon redmine "Rustine proposée changé de Non à Oui".

#5

Mis à jour par Lauréline Guérin il y a plus d'un an

  • Assigné à mis à Lauréline Guérin
#6

Mis à jour par Lauréline Guérin il y a plus d'un an

des notes:

- on part sur une part ContentSnapshotPart, qu'on ajoute à la dernière évolution à chaque création de formdata/carddata (par une action de workflow, lors d'une saisie, d'un import json/csv, un appel api, ...), et à chaque modification (par une action de workflow, par un appel api, par une édition dans le BO, ...)
- au départ je pensais stocker des json old_data et new_data dans la part, pour avoir le avant/après à chaque enregistrement
- nouvelle piste: avoir une table dédiée pour ces données (un peu comme la table snapshot pour les formdef et carddef), y stocker formdef_type, formdef_id, formdata_id, old_data et new_data, et dans la part pointer sur une entrée de la table. (si on perd un formdef et sa table pour une raison X ou Y, on pourra ainsi retrouver la dernière version de chaque donnée)
- stocker aussi la date de chaque changement (timestamp auto now), et un type d'event (created, updated, deleted) ?

#7

Mis à jour par Lauréline Guérin il y a plus d'un an

nouvelle piste: avoir une table dédiée pour ces données ... (si on perd un formdef et sa table pour une raison X ou Y, on pourra ainsi retrouver la dernière version de chaque donnée)

Hésitations:
- si on ne stocke qu'une copie de formdata.data, ça n'est pas suffisant pour restaurer les données en cas de perte (il manque le user, les evolutions, ...)
- et puis je me heurte à des soucis de stockage pour les objets file, et je n'ai pas encore creusé suffisamment

Pour l'anonymisation:

    def anonymise(self):
        for field in self.formdef.get_all_fields():
            if field.anonymise:
                field.set_value(self.data, None)

        self.anonymised = datetime.datetime.now()
        self.user_id = None
        self.user_label = None
        self.editable_by = None
        self.workflow_data = None
        self.workflow_roles = None
        self.submission_context = None

        if self.evolution:
            for evo in self.evolution:
                evo.who = None
                evo.parts = None
                evo.comment = None
                evo.parts = None
        self.store()

Toutes les parts sont supprimées (2 fois même, on sait jamais), dans l'hypothèse où on ne fait pas de table dédiée, je laisse comme ça, ou je garde les SnapshotContentPart en anonymisant ce qui doit l'être ?

#8

Mis à jour par Lauréline Guérin il y a plus d'un an

pour discussion

(correspond à la branche wip/62800-formdata-snapshot-bis - version sans table dédiée)

0001: juste un split de tests
0002: les ContentSnapshotPart à la création et à la modification d'un form/carddata
0003: fichiers inutilisés & historisation (pas très sûre de moi là)

Rien de particulier pour l'anonymisation pour le moment

#9

Mis à jour par Lauréline Guérin il y a plus d'un an

  • Lié à Development #70271: API formdata: récupérer les données à un instant t ajouté
#10

Mis à jour par Lauréline Guérin il y a plus d'un an

nouvelle version de 0002, pour stocker aussi formdef_type et formdef_id dans ContentSnapshotPart, parce que ça peut servir.

#13

Mis à jour par Benjamin Dauvergne il y a plus d'un an

  • Statut changé de Solution proposée à En cours

Toutes les parts sont supprimées (2 fois même, on sait jamais), dans l'hypothèse où on ne fait pas de table dédiée, je laisse comme ça, ou je garde les SnapshotContentPart en anonymisant ce qui doit l'être ?

Je dirai qu'arriver à l'anonymisation l'historique des données du formulaire n'ont plus beaucoup d'intérêt, donc non on vire tout.

  • 0002:
    class ContentSnapshotPart(EvolutionPart):
        def __init__(self, formdata, old_data):
            self.formdef_type = formdata.formdef.xml_root_node
            self.formdef_id = formdata.formdef.id
            self.old_data = old_data
            self.new_data = copy.deepcopy(formdata.data)
    

Est-ce qu'on ne réduirait pas un poil ? Genre ne garder que ce qui a changé :

- self.old_data = old_data
- self.new_data = copy.deepcopy(formdata.data)
+ self.new_data = copy.deepcopy({key: value for key, value in formdata.data.items() if value != old_data.get(key)})

  • 0003: il me semble qu'il y manque le cas des champs fichiers dans les blocs qui est géré un peu plus haut pour formdata.data en commençant avec cette ligne :
                elif isinstance(field_data, dict) and isinstance(field_data.get('data'), list):
    
#14

Mis à jour par Lauréline Guérin il y a plus d'un an

0003: il me semble qu'il y manque le cas des champs fichiers dans les blocs qui est géré un peu plus haut pour formdata.data en commençant avec cette ligne :

exact, merci

Est-ce qu'on ne réduirait pas un poil ?

C'est quand même super pratique d'avoir un avant/après complet sur une part:
- pour afficher les changements dans l'historique d'une demande, il n'y a qu'à définir une méthode view sur ContentSnapshotPart, on a tout ce qu'il faut pour faire un diff. Sinon, pour chaque part, il faudrait loader les part précédentes, construire un data complet en compilant tout ça, puis vérifier les changements.
- pour récupérer les données à un instant t, il suffit de récupérer la part juste avant t, on a les données complètes dessus. Sinon, pareil, faut récupérer toutes les parts précédentes, etc.

#15

Mis à jour par Benjamin Dauvergne il y a plus d'un an

Lauréline Guérin a écrit :

C'est quand même super pratique d'avoir un avant/après complet sur une part:
- pour afficher les changements dans l'historique d'une demande, il n'y a qu'à définir une méthode view sur ContentSnapshotPart, on a tout ce qu'il faut pour faire un diff. Sinon, pour chaque part, il faudrait loader les part précédentes, construire un data complet en compilant tout ça, puis vérifier les changements.
- pour récupérer les données à un instant t, il suffit de récupérer la part juste avant t, on a les données complètes dessus. Sinon, pareil, faut récupérer toutes les parts précédentes, etc.

Ok.

Je rejette un coup d'oeil quand c'est vert.

#16

Mis à jour par Benjamin Dauvergne il y a plus d'un an

  • Statut changé de Solution proposée à Information nécessaire

Dans la modification à l'action edit_carddata pourquoi est-il nécessaire de créer une nouvelle evolution ce qui n'est pas le cas pour backoffice_field, l'édition en front ou la mise à jour par l'API ?

#17

Mis à jour par Lauréline Guérin il y a plus d'un an

  • Statut changé de Information nécessaire à Solution proposée

Dans la modification à l'action edit_carddata pourquoi est-il nécessaire de créer une nouvelle evolution ce qui n'est pas le cas pour backoffice_field, l'édition en front ou la mise à jour par l'API ?

Parce que edit_carddata est lancé par une action sur un autre workflow que celui de la fiche modifiée. Cette action ajoute bien une evolution et une part sur la demande initiale, mais rien sur la fiche modifiée. Pour avoir le bon horodatage il faut ajouter une evolution, et pour comprendre d'où viennent les modifs il y a #70000.

backoffice_field: on est dans un perform_workflow, qui gère déjà les evolutions et les ActionsTracingEvolutionPart et l'horodatage des actions.
édition en front: idem, on passe par un perform_workflow
api: juste avant l'ajout de la part, on a un perform_workflow.
Il me semble qu'on est bon.

En tout cas les tests ajoutés sur evolution et parts dans test_content_snapshots.py m'ont l'air plutôt cohérents, mais je veux bien une autre relecture pour confirmer.

#19

Mis à jour par Benjamin Dauvergne il y a plus d'un an

  • Statut changé de Solution proposée à Solution validée

Ok.

#20

Mis à jour par Lauréline Guérin il y a plus d'un an

Après discussion avec Fred: ajout d'une datetime sur ContentSnapshotPart, pour avoir la bonne date (avec tz) même si la part est posée sur la mauvaise evolution

#21

Mis à jour par Benjamin Dauvergne il y a plus d'un an

  • Statut changé de Solution proposée à Solution validée

Toujours ok.

#22

Mis à jour par Lauréline Guérin il y a plus d'un an

  • Lié à Development #70868: Historisation des données, afficher les modifications dans l'historique d'une demande/fiche ajouté
#23

Mis à jour par Lauréline Guérin il y a plus d'un an

  • Statut changé de Solution validée à Résolu (à déployer)
commit b6b7203358a355a950bde26deb96dd9166379b68
Author: Lauréline Guérin <zebuline@entrouvert.com>
Date:   Fri Oct 7 09:40:16 2022 +0200

    formdata: look at files in history when deleting unused files (#62800)

commit 5fc369a082124f334f5fcb609fe35417c2b31b08
Author: Lauréline Guérin <zebuline@entrouvert.com>
Date:   Sat Sep 24 18:43:55 2022 +0200

    formdata: store data history (#62800)

commit f293184fff301048fe9d21c5d552f5f1960ae080
Author: Lauréline Guérin <zebuline@entrouvert.com>
Date:   Sat Sep 24 18:35:59 2022 +0200

    misc: split workflow tests
#24

Mis à jour par Transition automatique il y a plus d'un an

  • Statut changé de Résolu (à déployer) à Solution déployée
#25

Mis à jour par Transition automatique il y a plus d'un an

Automatic expiration

#27

Mis à jour par Mikaël Ates (de retour le 29 avril) il y a environ un an

Formats disponibles : Atom PDF