Sylvain Duchesne 0c4f6b6650 Derive the participant count instead of incrementing it
Every Participation is readable by everyone — only the link to a person is
protected — so an event's count is obtained by counting its participations. No
privileged view, nothing to compensate for.

The stored counter is gone from the write path: joining writes a participation
and nothing else, leaving writes nothing else. Writing the participation IS
moving the count, so there is no second write to keep in step and no counter to
race. That race was measured, not supposed: the count sat on whatever the seed
had written, with no error anywhere, because each increment derived from a read
of the previous one.

Derived in BOTH providers, so demo and connected modes cannot disagree about
what a count means. fp:participantCount stays in the shape and the fixtures,
kept in step, but nothing reads it.

The fixtures become the source of truth and had to say something true: they
advertised 24, 12, 45, 16, 30 against five participation rows. Seventeen rows
now, counts aligned to them. Marie's three are untouched on purpose — the home
screen lists "my events" from exactly those, and the @ui tests render against
it. Small on purpose too: a plausible demo, not a hundred rows reproducing
figures nobody reads.

us-7-inscription-evenement.feature still sets a starting count and expects it
±1. Those steps encode the superseded counter and will need rewriting around
creating participations; they are @data, which is parked while no backend is
registered.
2026-10-01 18:35:24 +02:00
2026-01-18 11:53:42 +01:00
2026-01-18 11:53:42 +01:00
2026-01-18 11:53:42 +01:00
2026-01-18 11:53:42 +01:00
2026-01-18 11:53:42 +01:00
2026-01-18 11:53:42 +01:00
2026-01-18 11:53:42 +01:00

Festipod

Festipod permet aux utilisateurs de créer des points de rencontre qui viennent se « greffer » sur des événements publics existants. L'objectif est de favoriser les rencontres autour de ces événements.

L'événement public (festival, conférence, salon…) n'est qu'un prétexte et un point d'ancrage temporel et géographique : la valeur produite par l'app, c'est le point de rencontre que les utilisateurs viennent y greffer pour se retrouver.

Application web mobile-first. Stack : Bun + React + NextGraph (P2P, local-first, chiffré de bout en bout).

Modèle fonctionnel

Tous les utilisateurs sont authentifiés — il n'y a pas d'accès anonyme à l'app.

Acteurs

  • Utilisateur — toute personne ayant un compte (un wallet NextGraph). Tous les acteurs ci-dessous sont des spécialisations d'un utilisateur dans un contexte donné.
  • Connexion (« ami ») — un autre utilisateur avec qui je suis connecté. Sert à scoper les listes (« mes amis qui participent à… ») et la confiance.
  • Déclarant d'un événement — l'utilisateur qui a inséré l'événement dans Festipod. N'est pas (forcément) un organisateur de l'événement réel : c'est juste quelqu'un qui le référence pour que d'autres puissent y attacher des points de rencontre.
  • Hôte d'un point de rencontre — l'utilisateur qui a créé un point de rencontre rattaché à un événement.
  • Inscrit à un point de rencontre — un utilisateur qui s'est inscrit à un point de rencontre. De fait, il devient participant à l'événement parent.
  • Membre d'une communauté d'intérêt — un utilisateur abonné à une communauté pour découvrir les événements qu'elle référence.

Concepts métier

  • Point de rencontre — l'unité de valeur de l'app. Un moment de rencontre proposé par un hôte à un endroit et à un horaire donnés, greffé sur un événement public. C'est ce à quoi on s'inscrit (on ne s'inscrit pas à un événement). Sans points de rencontre, un événement Festipod n'a pas d'intérêt.
  • Événement — l'ancrage. Un événement public réel (festival, conférence, salon, exposition…) référencé dans Festipod pour servir de support à des points de rencontre. C'est simplement un prétexte (titre, dates, lieu, thèmes) ; le déclarant n'est pas l'organisateur officiel de l'événement, juste celui qui l'a inscrit dans Festipod.
  • Communauté d'intérêt — un groupement thématique d'utilisateurs. Sert principalement à découvrir des événements (via abonnement) et à délimiter les périmètres de référencement.
  • Liste curated — une liste d'événements éditorialisée (par un utilisateur ou une communauté), distincte de « les événements que j'ai déclarés » ou « les événements de la communauté ». Permet d'organiser/recommander.
  • Connexion — lien de confiance entre deux utilisateurs (équivalent « ami »).

Fonctionnalités actuelles

Implémentées dans le code (écrans visibles via le router) :

  • Authentification via wallet NextGraph
  • Cycle de vie d'événement (déclaration, consultation, mise à jour)
  • Cycle de vie de point de rencontre (rattaché à un événement)
  • Inscription / désinscription à un point de rencontre
  • Liste des participants à un événement
  • Profil utilisateur, mise à jour, partage de profil
  • Liste d'amis (connexions)
  • Profil d'un autre utilisateur

Voir l'inventaire des routes et des écrans dans le concept app-architecture.

Défis ouverts

  • Déduplication des événements en infra décentralisée. NextGraph étant P2P, rien n'empêche deux utilisateurs de déclarer indépendamment le même événement public (par ex. « Eurockéennes 2027 ») et de produire deux entrées distinctes. La dispersion qui en résulte fragmente les points de rencontre greffés et réduit leur visibilité — ce qui va à l'encontre de la fonction première de l'app. Pistes envisagées, non tranchées :
    • proposer à l'utilisateur, lors de la déclaration, les événements déjà déclarés dans son réseau / ses communautés qui correspondent à sa saisie (recherche avant création) ;
    • utiliser un identifiant externe canonique (URL officielle de l'événement, Wikidata, schema.org/Event) pour reconnaître les doublons et les présenter comme un seul événement à l'affichage ;
    • laisser des curators (humains ou communautaires) fusionner / vetter les entrées canoniques.

Évolutions à venir

Identifiées comme nécessaires (notamment pour la scalabilité et la découverte) mais pas encore implémentées :

  • Abonnement à une communauté d'intérêt pour découvrir ses événements (mécanisme de discovery distribué).
  • Abonnement à un utilisateur pour suivre les événements qu'il déclare (sans nécessairement être ami).
  • Listes curated — créer et partager des sélections d'événements éditorialisées.
  • Multi-utilisateurs collaboratif : aujourd'hui chaque utilisateur a ses données isolées dans son wallet. Le passage en mode collaboratif (un point de rencontre vu par plusieurs personnes) suppose un refactor de la couche données. Voir le concept nextgraph-platform (briefs multi-store, matrice d'autorisations, wallet partagé, fork inbox).

Quick Start

bun install
bun run dev              # Dev server avec HMR (port 3000)

Commandes utiles

bun run build            # Build production vers dist/
bun run storybook        # Parcourir écrans et composants
bun run test:cucumber    # Tests BDD
bun run features:parse   # Régénérer features.ts depuis les .feature
bun run steps:extract    # Extraire les step definitions pour les tooltips
bun run build:orm        # Régénérer l'ORM depuis les SHEX shapes

Documentation

  • AGENTS.md — cœur : but produit, invariants, carte des concepts
  • .project/concepts/ — toute la doctrine projet (savoir, règles, décisions, briefs), typée et livrée par hook au moment pertinent. 6 concepts : functional-domain, app-architecture, tech-stack, data-layer, bdd-testing, nextgraph-platform.
S
Description
No description provided
Readme GPL-3.0 11 MiB
Languages
TypeScript 78%
JavaScript 18%
Gherkin 3.1%
CSS 0.5%
Shell 0.2%
Other 0.1%