← Chantiers · 02 Liste de naissance
Qu'est-ce qui fait qu'une liste remplit son rôle pour les parents et les contributeurs ?
| Étape | Listes | % de la base |
|---|---|---|
| ≥ 1 produit (base) | 59 376 | |
| ≥ 3 produits | 51 527 | |
| ≥ 10 produits (vraie liste) | 41 274 | |
| ≥ 20 produits | 28 690 | |
| Cagnotte activée | 36 515 | |
| ≥ 1 acquisition | 35 147 |
La construction n'est pas le point de friction. L'activation cagnotte arrive pendant ou après la construction (5 % seulement l'activent avant le premier produit) et grimpe avec l'engagement (81 % des listes 35+ produits).
9 605 listes sur 41 274 vraies listes (23 %) ne reçoivent jamais rien, soit environ 500 listes mortes par mois. Leur contenu est pourtant identique aux meilleures. Profil type : construite vite, jamais partagée.
| Listes mortes (9 605) | Listes excellentes, 75 %+ acquis (9 880) | |
|---|---|---|
| Produits (médiane) | 20 | 29 |
| Valeur (médiane) | 1 025 € | 1 408 € |
| €/produit (médiane) | 46 € | 47 € |
Le prédicteur propre : le rythme du premier mois. La durée totale de construction est biaisée (une liste qui reçoit des cadeaux reste entretenue, la durée est en partie une conséquence du succès). Pour neutraliser ça, on ne compte que les jours d'ajout distincts dans les 30 jours suivant le premier produit, avant l'arrivée des premiers cadeaux (médiane du premier paiement : ~5 semaines) :
| Sessions d'ajout dans le 1er mois | Listes | % mortes | % bonnes (≥ 50 % acquis) |
|---|---|---|---|
| 1 seul jour | 8 046 | 28 % | |
| 2 jours | 7 840 | 40 % | |
| 3-4 jours | 12 727 | 51 % | |
| 5 jours et + | 12 661 | 62 % |
Mesuré avant le résultat : une liste construite en une seule session a 4x plus de risque de mourir qu'une liste travaillée sur 5+ sessions le premier mois. Exploitable en détection précoce dès J+7 et relance.
| Réglage | Effet mesuré |
|---|---|
| 20 à 40 produits | Sous 20 : 37 % de mortes. À 20-59 : 15 à 20 % |
| 40 à 60 € par produit en moyenne | 53 % de bonnes listes, contre 26 % sous 20 €/produit |
| Créée 2 à 6 mois avant la naissance | 49 à 52 % de bonnes listes ; créée 8 mois+ avant : 39 % de mortes |
| Sections (organiser la liste) | +16 pts de couverture |
| 2-3 produits marqués "priorité" | +16 pts |
| Co-parent invité | +13 pts, mortalité divisée par 2 |
Côté contributeur : ticket médian 37 € (p25 : 20 €, p75 : 60 €). Une liste qui marche mobilise ~15 contributeurs, chacun paie ~1 produit : le total scale avec le nombre de personnes touchées, pas avec le panier.
Pas de taxonomie produit sur les ajouts par lien externe (57 % des lignes), mais les sections de liste sont une taxonomie globale posée par les parents eux-mêmes sur tous les types de produits. Sur les 31 669 listes vivantes :
| Section | % des listes | Items / liste | Taux d'acquisition | Prix moyen |
|---|---|---|---|---|
| 🛌 La Chambre | 69 % | 6,2 | 86 € | |
| 🚶 Les Sorties | 62 % | 4,0 | 150 € | |
| 🧴 L'hygiène et le soin | 66 % | 5,2 | 33 € | |
| 🍼 L'Allaitement | 25 % | 2,7 | 50 € | |
| 🥕 Le Repas | 67 % | 5,8 | 49 € | |
| 🧸 L'Éveil et le jeu | 70 % | 7,8 | 53 € | |
| 👕 Les Vêtements | 46 % | 5,0 | 31 € | |
| 📕 Les Livres | 13 % | 4,5 | 18 € |
Taux d'acquisition = part des items de la section effectivement acquis, mesuré au sein de chaque liste : peu sensible au biais de partage.
Parmi les vraies listes vivantes, celles sans cagnotte couvrent leurs besoins aussi bien (couverture médiane 64 % vs 59 % avec) : tout passe par l'achat direct hors plateforme, marqué sur la liste. La cagnotte déplace une partie des acquisitions vers le canal payé et ajoute : argent au lieu d'un cadeau raté, traçabilité des contributeurs, cagnotte libre (94 % des listes qui marchent reçoivent au moins un paiement libre).
L'intérêt business de pousser l'activation (marge supérieure à l'affiliation) reste entier, mais c'est un objectif plateforme, pas un critère de la liste idéale : il se traite en aval, une fois la liste construite.
L'achat groupé fonctionne quand il se déclenche (99 % du prix couvert en médiane) mais ne se déclenche presque jamais (2,4 % des produits acquis via cagnotte, uniquement sur les pièces 100 €+). Le levier est la découverte côté contributeur, pas l'éducation côté parent.
A · Faire revenir pendant la construction. Le prédicteur propre est le nombre de sessions du premier mois. Relance si liste inchangée 14-30 jours, détection du one-shot dès J+7.
B · Faire partager les listes construites. 9 605 listes construites pour rien sur la fenêtre : l'effort est fait, le retour est nul. Le guide "parfaite liste" s'adresse à ce segment : réglages des takeaways 3-4, cagnotte en étape finale (pas en prérequis), partage comme acte central répété.
Le scaffold /i/account/dashboard (330897dc4 + suivants, doc docs/user-dashboard.md) est exactement le chantier A : checklist + cercle de complétion = mécanique de retour. Ajustements suggérés, contenus de checklist uniquement :
-- via : docker exec minipouce-minipouce_db-1 psql -U minipouce -d minipouce
-- Surface : vraies listes matures
CREATE TABLE analysis_base AS
SELECT l.id AS liste_id, l.user_id, l.date_created, l.birthdate,
(SELECT count(*) FROM listeproducts lp WHERE lp.liste_id=l.id) AS n_products,
(SELECT min(lp.date_added) FROM listeproducts lp WHERE lp.liste_id=l.id) AS first_product_added,
(SELECT max(lp.date_added) FROM listeproducts lp WHERE lp.liste_id=l.id) AS last_product_added,
EXISTS (SELECT 1 FROM user_stripe_account usa
WHERE usa.user_id=l.user_id AND usa.disabled IS NOT TRUE) AS has_stripe,
u.partner_id IS NOT NULL AS has_partner
FROM liste l
JOIN "user" u ON u.id = l.user_id
WHERE l.kind='birth' AND l.demo=false
AND l.date_created >= '2024-06-01' AND l.date_created < '2026-01-01'
AND l.birthdate IS NOT NULL AND l.birthdate < '2026-02-28'
AND EXISTS (SELECT 1 FROM listeproducts lp WHERE lp.liste_id=l.id);
-- Funnel de construction (takeaway 1)
SELECT count(*) AS p1,
count(*) FILTER (WHERE n_products >= 3) AS p3,
count(*) FILTER (WHERE n_products >= 10) AS p10,
count(*) FILTER (WHERE n_products >= 20) AS p20,
count(*) FILTER (WHERE has_stripe) AS stripe,
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM contribution c
WHERE c.liste_id=analysis_base.liste_id
AND c.state IN ('paid_to_wallet','self_bought'))) AS any_acq
FROM analysis_base;
-- Vraies listes + couverture + sessions précoces (takeaway 2)
CREATE TABLE analysis_engaged AS
SELECT b.*,
agg.n_acquired,
round(agg.n_acquired::numeric / b.n_products, 3) AS coverage_any,
agg.early_add_days
FROM analysis_base b
JOIN LATERAL (
SELECT
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM contribution c
WHERE c.liste_id=lp.liste_id AND c.merchant_item_id=lp.merchant_item_id
AND c.state IN ('paid_to_wallet','self_bought'))) AS n_acquired,
count(DISTINCT lp.date_added::date)
FILTER (WHERE lp.date_added < b.first_product_added + interval '30 days')
AS early_add_days
FROM listeproducts lp WHERE lp.liste_id = b.liste_id
) agg ON true
WHERE b.n_products >= 10;
-- Sessions du 1er mois vs mortalité (takeaway 2, biais neutralisé)
SELECT
CASE WHEN early_add_days = 1 THEN '1 jour'
WHEN early_add_days = 2 THEN '2 jours'
WHEN early_add_days BETWEEN 3 AND 4 THEN '3-4 jours'
ELSE '5+ jours' END AS early_sessions,
count(*) AS n,
round(100.0 * count(*) FILTER (WHERE coverage_any = 0) / count(*),1) AS pct_mortes,
round(100.0 * count(*) FILTER (WHERE coverage_any >= 0.5) / count(*),1) AS pct_bonnes
FROM analysis_engaged GROUP BY 1 ORDER BY min(early_add_days);
-- Composition par section (takeaway 4) : listes vivantes
WITH alive AS (SELECT liste_id FROM analysis_engaged WHERE coverage_any > 0),
sec AS (
SELECT pc.name AS section, lp.liste_id,
count(*) AS n_items,
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM contribution c
WHERE c.liste_id=lp.liste_id AND c.merchant_item_id=lp.merchant_item_id
AND c.state IN ('paid_to_wallet','self_bought'))) AS n_acq,
avg(COALESCE(lp.frozen_price,0)) AS avg_price
FROM listeproducts lp
JOIN alive a ON a.liste_id = lp.liste_id
JOIN product_classification pc ON pc.id = lp.classification_id
GROUP BY pc.name, lp.liste_id
)
SELECT section,
round(100.0 * count(DISTINCT liste_id) / (SELECT count(*) FROM alive), 1) AS pct_lists,
round(avg(n_items),1) AS items_per_list,
round(100.0 * sum(n_acq) / sum(n_items), 1) AS acq_rate_pct,
round(avg(avg_price)/100, 0) AS avg_price_eur
FROM sec GROUP BY section
HAVING count(DISTINCT liste_id) > 500
ORDER BY acq_rate_pct DESC;
-- Nettoyage
DROP TABLE analysis_engaged; DROP TABLE analysis_base;