Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Analytics] Le rapport looker studio ne correspond pas tout à fait à l'état de la BDD #558

Open
noancloarec opened this issue May 24, 2024 · 8 comments
Assignees
Labels
bug Something isn't working

Comments

@noancloarec
Copy link
Collaborator

Le 24 mai 2024 je peux voir 226 feedbacks avec un statut à "done" via l'url https://server.feedzback.znk.io/feedback-stats.
Le looker studio n'en affiche que 215.
Il faudrait voir ce qui explique le delta (peut-être que ce sont simplement les feedbacks pas encore traités par dataform mais ça m'étonne car ça voudrait dire qu'il y a eu 9 feedbacks depuis ce matin.)

@noancloarec noancloarec added the bug Something isn't working label May 24, 2024
@avine
Copy link
Contributor

avine commented Jun 19, 2024

En effet, en date du 19 juin 2024, aucun chiffre ne correspond à ceux fournis par l'API.

Sur toutes la période, l'API donne :

  • Nombre total des demandes de ​feedzbacks non répondues sur la période : 375
  • Nombre total de feedzbacks donnés sur la période : 313
  • 460 utilisateurs uniques de la plateforme (dont 423 donneurs et 110 receveurs)

Alors que le looker studio donne :

  • Nombre total des demandes de ​feedzbacks non répondues sur la période : 356
  • Nombre total de feedzbacks donnés sur la période : 301
  • 331 utilisateurs uniques de la plateforme (dont 250 donneurs et 118 receveurs)

@yasmineDoghri6
Copy link
Collaborator

Après avoir vérifié les données de l'environnement de dev, en comparant celles issues de Looker et celles provenant de l'API, voici les constats que j'ai faits :

  1. Calcul du nombre d'utilisateurs :

    Le calcul du nombre d'utilisateurs semble erroné. En effet, un utilisateur (giver) est comptabilisé plusieurs fois s'il a donné plusieurs feedbacks. En conséquence, si un giver soumet deux feedbacks, il est compté deux fois au lieu d'une seule, alors qu'il devrait être comptabilisé une seule fois.

  2. Nombre de feedbacks non répondus :

    • Sur Looker, le nombre de feedbacks non répondus est de 29.

    • En revanche, sur l'API, ce nombre est de 34.

    =>Cette différence s'explique par le fait que, dans Looker, seuls les feedbacks où le champ archived = 0 sont pris en compte, alors que l'API inclut également les feedbacks archivés.

  3. Nombre total de feedbacks :

    Le total des feedbacks est correct dans les deux systèmes.

    • Sur Looker, le total est de 28.

    • Sur l'API, en additionnant les feedbacks non demandés (24) et les feedbacks demandés et répondus (4), on obtient également 28, ce qui correspond.

@avine
Copy link
Contributor

avine commented Oct 1, 2024

  1. Calcul du nombre d'utilisateurs :
    Le calcul du nombre d'utilisateurs semble erroné. En effet, un utilisateur (giver) est comptabilisé plusieurs fois s'il a donné plusieurs feedbacks. En conséquence, si un giver soumet deux feedbacks, il est compté deux fois au lieu d'une seule, alors qu'il devrait être comptabilisé une seule fois.

Non, un giver n'est pas compté 2 fois.

Voici le code source commenté :
https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback-stats/feedback-stats.service.ts

export class FeedbackStatsService {
  // Dans un `Set` JavaScript, il n'y a pas de doublons...
  private giverEmailList = new Set<string>(); // ...il s'agit bien du nombre de personnes uniques ayant donné
  private receiverEmailList = new Set<string>(); // ...il s'agit bien du nombre de personnes uniques ayant reçu

  private allEmailList = new Set<string>(); // ...il s'agit bien du nombre total de personnes uniques ayant utilisé le service

  private history: Pick<FeedbackWithId, 'updatedAt' | 'requested'>[] = [];

  constructor(private feedbackDbService: FeedbackDbService) {
    this.feedbackDbService.onFeedbackChanges((feedbacks) => { // Pour chaque entrée de la table `feedback`...
      feedbacks.forEach(({ giverEmail, receiverEmail }) => {
        this.giverEmailList.add(giverEmail); // ...on ajoute le donneur si pas déjà présent dans ce `Set`
        this.receiverEmailList.add(receiverEmail); // ...on ajoute le receveur si pas déjà présent dans ce `Set`

        this.allEmailList.add(giverEmail);
        this.allEmailList.add(receiverEmail);
      });

      this.history.push(
        ...feedbacks.map(({ createdAt, updatedAt, requested, status }) => ({
          createdAt,
          updatedAt,
          requested,
          status,
        })),
      );
    });
  }
}
  1. Nombre de feedbacks non répondus :

    • Sur Looker, le nombre de feedbacks non répondus est de 29.
    • En revanche, sur l'API, ce nombre est de 34.

    =>Cette différence s'explique par le fait que, dans Looker, seuls les feedbacks où le champ archived = 0 sont pris en compte, alors que l'API inclut également les feedbacks archivés.

Pourquoi ne pas compter les FeedZbacks archivés ?

Tous les FeedZbacks sont archivables :

  • un feedZback terminé (demandé ou spontané) peut être archivé immédiatement par son donneur, son receveur ou les deux
  • par contre, un feedZback demandé et en attente de réponse n'est archivable qu'à partir d'1 mois d'ancienneté sans réponse (pour laisser le temps au donneur de répondre). Après ce délai, le demandeur ou le donneur peuvent l'archiver.

En gros, archiver un feedZback signifie : "Je ne veux plus le voir dans mon interface".
Pourquoi ? Voici quelques raisons possibles :

  1. J'ai déjà échangé avec mon manager sur ce feedZback terminé ; donc il a joué son rôle et ne me sert plus maintenant
  2. Il s'agissait d'une demande de FeedZback importante pour moi ; j'espérai que la personne en face allait me donner son FeedZback mais elle ne l'a pas fait
  3. Il s'agissait d'une demande de FeedZback faite par erreur...

En quoi le fait que d'archiver un FeedZback pour cleaner mon interface utilisateur (simple préférence d'afficahge) devrait-il avoir un impact sur les statistiques ?
Dans les cas 1) et 2) cités plus haut, il n'y a pas de raison de sortir le FeedZback des stats.
Pour le cas 3), oui ça fait sens ; mais on ne peut pas savoir pourquoi la personne a archivé un feedZback non répondu...

  1. Nombre total de feedbacks :
    Le total des feedbacks est correct dans les deux systèmes.

Pour le calcul du nombre total de feedZbacks, vous comptez dans le Looker même ceux qui sont archivés ?
Pourquoi cette fois, les feedZbacks archivés sont pris en compte ?


Voici l'analyse des stats de l'API au 1er octobre 2024 à 23h57 (fichier source fourni en PJ) :

{
  "giverCount": 633,
  "receiverCount": 170,
  "allCount": 684,
  "history": [
    {
      "createdAt": 1719648677413,
      "updatedAt": 1719648677413,
      "requested": false,
      "status": "done"
    },
    {
      "createdAt": 1709911131172,
      "updatedAt": 1709911131172,
      "requested": true,
      "status": "pending"
    },
    ...
  ]
}

1058 feedZbacks au total (history)

  • dont 1018 sont des feedZbacks demandés (à l'initiative du receveur requested: true)
    • 543 d'entres-eux n'ont pas été répondus (requested: true et status:"pending")
    • et (par soustraction) 475 d'entres-eux ont été répondus (requested:true et status:"done")
  • et 40 seulement sont des feedZbacks spontanés (à l'initiative du donneur requested: false)

(note: un feedZback spontané ne peut pas avoir le status: "pending")

684 utilisateurs uniques du service (allCount)

  • 633 d'entre-eux ont été donneur de feedZback
  • et seulement 170 d'entre-eux ont été receveur de feedZback

En termes d'interprétation, on peut dire que :

  • le trafic de l'app est principalement généré par un corpus limité de personnes faisant de nombreuses demandes de FeedZback.
  • la moitié des demandes de FeedZback échouent

Ou l'API fait erreur ?

Demande de FeedZback

Quand une personne fait une demande de FeedZback, il y a le demandeur et le receveur.
Même si la demande n'est pas encore répondue, le donneur (potentiel) est déjà compté comme utilisateur unique (même s'il ne s'est jamais connecté à l'app).

S'il finit par répondre à la demande, l'erreur aura finalement été corrigée d'elle-même.
Par contre, si le FeedZback n'est jamais répondu, l'API aura donc compté un utilisateur de trop (celui qui n'a finalement jamais répondu à la demande de FeedZback).

Cette erreur de calcul n'est peut-être pas anodine compte tenu du fait qu'une demande sur 2 n'est pas répondue !
On peut donc en conclure que le nombre de donneurs uniques de FeedZbacks fourni par l'API est largement surévalué.

Action : modifier le calcul de l'API -> ne pas compter les donneurs des demandes de FeedZback en attente de réponse.
Et voici le code modifié en conséquence :

      feedbacks.forEach(({ giverEmail, receiverEmail, requested, status }) => {
        // For feedback requests, the `giverEmail` is not to be taken into account until he has replied.
        if (!requested || status === 'done') {
          this.giverEmailList.add(giverEmail);
          this.allEmailList.add(giverEmail);
        }

        this.receiverEmailList.add(receiverEmail);
        this.allEmailList.add(receiverEmail);
      });

FeedZback spontané

Et pour un feedZback spontané, le donneur et le receveur sont immédiatement comptés comme 2 utilisateurs uniques. Alors qu'en vérité, seul le donneur a interagit avec l'app.
Mais il y a fort à parier que le receveur va ultérieurement consulter le FeedZback qu'il a reçu et l'erreur sera donc corrigée d'elle-même.
Donc sur ce point, on peut dire que le compte des utilisateurs unique reste juste.

Le nombre d'entrées du tableau history est faux en théorie (mais vrai en pratique)

En effet, si une demande de FeedZback est faite par exemple lundi, elle est ajoutée dans l'history.
Si cette demande est répondue mardi, elle est à nouveau ajouté dans l'history.

Mais en pratique, après une période d'inactivité du serveur NestJS, Google Runs "éteins" le serveur.
Vu la fréquence du traffic de l'app, le serveur est éteins très souvent.

Quand on accède aux stats de l'API après une période d'inactivité, le calcul est refait de zéro et les stats sont parfaitement justes à cet instant.

@yasmineDoghri6
Copy link
Collaborator

1- pour le 1 er point, je parle des données affichées sur le looker (désolée de ne pas le précisier)
2- Nous avons calculées que les feedbacks non archivées car le visual à coté porte sur l'age des feedbacks non répondus. Mais aprés une discussion avec Lise, elle m'a dit d'enlever cette condition.
3- Je vois que si on va pas calculer les donneurs des feedbacks si le feedbacks sont encore non répondus. Il faut aussi ne pas calculé les demandeurs comme étant réceveurs vu que le feedback n'a pas encore eu lieu.

@avine
Copy link
Contributor

avine commented Oct 5, 2024

3- Je vois que si on va pas calculer les donneurs des feedbacks si le feedbacks sont encore non répondus. Il faut aussi ne pas calculé les demandeurs comme étant réceveurs vu que le feedback n'a pas encore eu lieu.

ça dépend de quoi on parle !

Si on parle du nombre d'utilisateurs uniques du service :

S'il y a demande de FeedZback, même si pas encore répondue, l'auteur de la demande (receveur potentiel) est bien compté comme utilisateur du service, puisqu'il a fait une demande.
Seul le donneur du FeedZback n'est pas compté à ce moment là.

L'API se concentre sur le nombre d'utilisateurs unique du service, donc le futur receveur est compté comme utilisateur du service dès la demande.

Si on parle du nombre de FeedZback :

S'il n'y a eu qu'une demande de FeedZback alors effectivement, ni le receveur (auteur de la demande) ni le donneur ne doivent être compté puisque le FeedZback n'a pas encore été donné.

@avine
Copy link
Contributor

avine commented Oct 5, 2024

Voici les stats de l'API mises à jour :

AVANT (calcul erroné) #558 (comment) :

{
  "giverCount": 633,
  "receiverCount": 170,
  "allCount": 684,
  "history": [
    {
      "createdAt": 1719648677413,
      "updatedAt": 1719648677413,
      "requested": false,
      "status": "done"
    },
    {
      "createdAt": 1709911131172,
      "updatedAt": 1709911131172,
      "requested": true,
      "status": "pending"
    },
    ...
  ]
}

MAINTENANT (calcul juste) :

{
  "numberOfUniqueGivers": 337,
  "numberOfUniqueReceivers": 174,
  "numberOfUniqueUsers": 415,
  "history": [
    {
      "createdAt": 1719648677413,
      "updatedAt": 1719648677413,
      "requested": false,
      "shared": true,
      "status": "done"
    },
    {
      "createdAt": 1709911131172,
      "updatedAt": 1709911131172,
      "requested": true,
      "shared": false,
      "status": "pending"
    },
    ...
  ]
}

Le nombre de donneurs uniques est passé de 633 à 337 puisque désormais on ne compte pas les donneurs de FeedZback en attente.

A noter que l'API retourne désormais le statut "shared" si besoin.
J'ai juste renommé certains champs :

  • giverCount --> numberOfUniqueGivers
  • receiverCount --> numberOfUniqueReceivers
  • allCount --> numberOfUniqueUsers

@avine
Copy link
Contributor

avine commented Oct 6, 2024

J'ai déployé une nouvelle version des stats agrégées par mois :)

Les stats au 7 octobre 2024 à 01:00

{
  "summary": {
    "uniqueGivers": 337,
    "uniqueReceivers": 174,
    "uniqueUsers": 415,
    "spontaneousFeedback": 40,
    "requestedFeedbackDone": 490,
    "requestedFeedbackPending": 547,
    "sharedFeedback": 703
  },
  "details": [
    {
      "month": "2024-01",
      "uniqueGivers": 25,
      "uniqueReceivers": 20,
      "uniqueUsers": 38,
      "spontaneousFeedback": 15,
      "requestedFeedbackDone": 16,
      "requestedFeedbackPending": 35,
      "sharedFeedback": 0
    },
    {
      "month": "2024-02",
      "uniqueGivers": 47,
      "uniqueReceivers": 34,
      "uniqueUsers": 64,
      "spontaneousFeedback": 6,
      "requestedFeedbackDone": 55,
      "requestedFeedbackPending": 76,
      "sharedFeedback": 12
    },
    {
      "month": "2024-03",
      "uniqueGivers": 50,
      "uniqueReceivers": 40,
      "uniqueUsers": 76,
      "spontaneousFeedback": 9,
      "requestedFeedbackDone": 54,
      "requestedFeedbackPending": 39,
      "sharedFeedback": 66
    },
    {
      "month": "2024-04",
      "uniqueGivers": 38,
      "uniqueReceivers": 26,
      "uniqueUsers": 60,
      "spontaneousFeedback": 1,
      "requestedFeedbackDone": 43,
      "requestedFeedbackPending": 41,
      "sharedFeedback": 46
    },
    {
      "month": "2024-05",
      "uniqueGivers": 47,
      "uniqueReceivers": 28,
      "uniqueUsers": 70,
      "spontaneousFeedback": 1,
      "requestedFeedbackDone": 49,
      "requestedFeedbackPending": 60,
      "sharedFeedback": 80
    },
    {
      "month": "2024-06",
      "uniqueGivers": 70,
      "uniqueReceivers": 34,
      "uniqueUsers": 95,
      "spontaneousFeedback": 1,
      "requestedFeedbackDone": 89,
      "requestedFeedbackPending": 103,
      "sharedFeedback": 167
    },
    {
      "month": "2024-07",
      "uniqueGivers": 20,
      "uniqueReceivers": 17,
      "uniqueUsers": 36,
      "spontaneousFeedback": 1,
      "requestedFeedbackDone": 21,
      "requestedFeedbackPending": 12,
      "sharedFeedback": 30
    },
    {
      "month": "2024-08",
      "uniqueGivers": 17,
      "uniqueReceivers": 23,
      "uniqueUsers": 38,
      "spontaneousFeedback": 1,
      "requestedFeedbackDone": 18,
      "requestedFeedbackPending": 37,
      "sharedFeedback": 53
    },
    {
      "month": "2024-09",
      "uniqueGivers": 123,
      "uniqueReceivers": 59,
      "uniqueUsers": 163,
      "spontaneousFeedback": 4,
      "requestedFeedbackDone": 130,
      "requestedFeedbackPending": 128,
      "sharedFeedback": 222
    },
    {
      "month": "2024-10",
      "uniqueGivers": 16,
      "uniqueReceivers": 15,
      "uniqueUsers": 29,
      "spontaneousFeedback": 1,
      "requestedFeedbackDone": 15,
      "requestedFeedbackPending": 16,
      "sharedFeedback": 27
    }
  ]
}

@avine
Copy link
Contributor

avine commented Oct 11, 2024

Sauf erreur de ma part, les stats fournies par l'API sont bien consolidées et peuvent servir de référence pour valider les stats du Looker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: To do
Development

No branches or pull requests

3 participants