Statistiques et analytiques
Types d'événements trackés
L'application enregistre automatiquement 3 types d'événements utilisateur :
Type (event_type) |
Déclenché quand | Ce que ça mesure |
|---|---|---|
unlock_language |
Un joueur déverrouille une langue | Popularité / ventes par langue |
view_card |
Un joueur consulte une carte | Engagement par carte |
play_audio |
Un joueur écoute un audio | Utilisation des enregistrements |
Structure de la table statistics
CREATE TABLE statistics (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
language_id UUID REFERENCES languages(id) ON DELETE CASCADE,
card_id UUID REFERENCES cards(id) ON DELETE CASCADE,
item_id UUID REFERENCES items(id) ON DELETE CASCADE,
event_type VARCHAR(50) NOT NULL, -- 'unlock_language', 'view_card', 'play_audio'
count INTEGER DEFAULT 1,
event_date DATE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
Clé d'unicité : (language_id, card_id, item_id, event_type, event_date) — les événements sont agrégés par jour (upsert avec incrémentation de count).
Structure de la table quiz_sessions
CREATE TABLE quiz_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
language_id UUID REFERENCES languages(id) ON DELETE CASCADE,
category_slug VARCHAR(255) NOT NULL,
category_name VARCHAR(255),
total_questions INTEGER NOT NULL,
score INTEGER,
started_at TIMESTAMPTZ DEFAULT NOW(),
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
- Une session
quiz_sessionsest créée quand un joueur démarre un quiz scoreetcompleted_atsont renseignés quand le joueur termine le quiz- Si
completed_atest NULL, le quiz a été abandonné
Visualiser les statistiques dans le dashboard
La plupart des analyses sont accessibles directement dans le tableau de bord. Pour des analyses avancées, vous pouvez accéder directement à la base de données PostgreSQL.
Requêtes SQL utiles
Nombre total de déverrouillages
SELECT COUNT(*) AS total_unlocks
FROM statistics
WHERE event_type = 'unlock_language';
Déverrouillages par langue (période donnée)
SELECT l.name, SUM(s.count) AS unlocks
FROM statistics s
JOIN languages l ON s.language_id = l.id
WHERE s.event_type = 'unlock_language'
AND s.event_date >= '2026-01-01'
AND s.event_date <= '2026-05-31'
GROUP BY l.name
ORDER BY unlocks DESC;
Top 10 cartes les plus consultées (toutes langues)
SELECT c.card_number, c.type, l.name, SUM(s.count) AS views
FROM statistics s
JOIN cards c ON s.card_id = c.id
JOIN languages l ON c.language_id = l.id
WHERE s.event_type = 'view_card'
GROUP BY c.card_number, c.type, l.name
ORDER BY views DESC
LIMIT 10;
Audios les plus écoutés pour une langue
SELECT i.original_text, i.translation, SUM(s.count) AS plays
FROM statistics s
JOIN items i ON s.item_id = i.id
JOIN cards c ON i.card_id = c.id
WHERE s.event_type = 'play_audio'
AND c.language_id = 'UUID_DE_LA_LANGUE'
GROUP BY i.original_text, i.translation
ORDER BY plays DESC
LIMIT 10;
Activité quotidienne sur 30 jours
SELECT event_date, event_type, SUM(count) AS total
FROM statistics
WHERE event_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY event_date, event_type
ORDER BY event_date DESC;
Performances quiz — taux de complétion
SELECT
l.name AS language,
qs.category_name,
COUNT(*) AS sessions_started,
COUNT(qs.completed_at) AS sessions_completed,
ROUND(COUNT(qs.completed_at)::numeric / COUNT(*)::numeric * 100, 1) AS completion_rate,
ROUND(AVG(qs.score::numeric / qs.total_questions::numeric * 100), 1) AS avg_score_pct
FROM quiz_sessions qs
JOIN languages l ON qs.language_id = l.id
GROUP BY l.name, qs.category_name
ORDER BY l.name, qs.category_name;
Statistiques hors ligne
Les joueurs hors ligne accumulent des événements dans une queue locale (IndexedDB). Ces événements sont synchronisés automatiquement à la reconnexion.
Impact : - Les statistiques temps réel peuvent être légèrement en retard pour les utilisateurs hors ligne - Les données sont toujours cohérentes à terme (pas de perte de données) - Il n'y a pas de moyen de forcer la synchronisation côté admin
Exporter les statistiques
Via pg_dump (export complet)
# Sur le serveur ou via tunnel SSH
pg_dump -h localhost -U postgres -d racines \
--table=statistics --table=quiz_sessions \
-F c -f stats_backup.dump
Via psql (export CSV)
psql -h localhost -U postgres -d racines -c \
"\COPY (SELECT * FROM statistics WHERE event_date >= '2026-01-01') \
TO '/tmp/stats_2026.csv' WITH CSV HEADER;"
Via l'API admin
L'endpoint GET /api/admin/statistics retourne les statistiques agrégées en JSON :
GET /api/admin/statistics?period=30d&language_id=[UUID]
Il n'existe pas d'export CSV natif dans l'interface graphique. Pour des exports réguliers, mettez en place un script cron côté serveur.