-
Notifications
You must be signed in to change notification settings - Fork 0
Home
L'application permet à un groupe d'amis d'organiser un voyage collectif sans friction. Elle agrège des annonces de location depuis des sources externes (Airbnb, LeBonCoin pour le MVP), les filtre selon les besoins consolidés du groupe, et facilite la prise de décision collective via un système de vote par tier list. L'app ne gère pas les conflits humains — elle fournit un outil clair pour que le groupe décide ensemble.
- Stateless sur les annonces : L'application ne stocke jamais le contenu des annonces (photos, textes, prix). Elle appelle les APIs sources à la volée selon les critères courants du groupe. Seuls les identifiants des annonces sélectionnées sont persistés en base.
- Recalcul des critères avec debouncing : Les critères consolidés sont recalculés à chaque modification (nouveau membre, réponse au questionnaire, départ d'un membre). Les appels aux APIs sources ne sont pas déclenchés en temps réel à chaque frappe ou modification — un mécanisme de debouncing ou de cache côté backend est requis pour éviter l'explosion des quotas API. L'implémentation technique de ce mécanisme (durée du cache, stratégie de debouncing) est laissée à l'appréciation de l'équipe technique.
- Sources MVP : Airbnb et LeBonCoin. L'intégration des sources est découplée et extensible. Les destinations multiples impliquent des requêtes parallèles côté backend, agrégées et dédoublonnées avant restitution au client.
- Annonces indisponibles : Si une annonce shortlistée n'est plus retournée par l'API source, elle reste visible avec un badge d'état explicite (Indisponible, Hors budget, Dates incompatibles). Elle n'est jamais retirée silencieusement.
- Authentification par email + mot de passe, sécurisée par JWT avec refresh token. Pas d'OAuth tiers dans le MVP.
- Un compte utilisateur est global et indépendant des voyages — un utilisateur peut participer à plusieurs voyages et en organiser plusieurs simultanément.
- Trois niveaux d'accès sur un voyage :
| Niveau | Accès | Condition |
|---|---|---|
| Visiteur read-only | Consulte les critères consolidés, les annonces compatibles, les annonces sélectionnées et le podium (dernier snapshot révélé). Ne peut pas voter, commenter, ni sélectionner. | Accès via lien d'invitation email sans compte connecté |
| Membre | Accès complet : questionnaire, sélection, vote, commentaires | Compte connecté + questionnaire du voyage complété |
| Organisateur | Tous les droits membre + configuration du voyage, révélation du podium, gestion des membres | Créateur du voyage |
Le mode read-only est un avant-goût destiné à convertir le visiteur : l'interface affiche un CTA visible invitant à créer un compte ou se connecter pour participer activement.
Le mode Explorer est accessible sans compte, avec une limite à 3 annonces visibles (voir section 4).
Permettre à un utilisateur de consulter des annonces de location agrégées depuis plusieurs sources, selon des critères qu'il renseigne manuellement. C'est un mode de découverte individuel, sans logique collective.
- Localisation (ville ou région — champ libre avec autocomplete géographique)
- Dates de séjour (date d'arrivée / date de départ)
- Nombre de personnes
- Budget total maximum pour la location uniquement (transport et activités hors périmètre)
Les résultats s'affichent sous forme de cartes. Chaque carte contient :
- Photo principale
- Titre
- Localisation
- Prix total pour le séjour
- Source (icône ou label Airbnb / LeBonCoin)
- Deux actions : Voir l'annonce (lien vers le site source) et Ajouter aux favoris
Les favoris sont liés au compte de l'utilisateur. Ils ne sont pas partagés dans le contexte du mode Explorer.
Un visiteur non connecté ne voit que les 3 premières annonces retournées par l'API. Le reste de la liste est remplacé par des cartes fantômes générées côté front avec des données fictives — aucune donnée réelle n'est envoyée au client au-delà des 3 premières. Un utilisateur inspectant les requêtes réseau ne peut pas récupérer les annonces masquées.
Les cartes fantômes sont accompagnées d'un CTA invitant à créer un compte ou se connecter pour accéder à l'ensemble des résultats.
Un voyage est fluide, sans étapes bloquantes. Deux statuts simples :
| Statut | Déclencheur |
|---|---|
| En cours | Dès la création du voyage |
| Terminé | L'organisateur clôture manuellement |
À tout moment : les critères évoluent, les annonces se rafraîchissent, les membres peuvent voter ou sélectionner de nouvelles annonces. Le podium ne se met à jour que sur action explicite de l'organisateur.
L'organisateur renseigne :
- Titre (obligatoire)
- Description libre (optionnelle)
- Nombre de personnes attendu (indicatif)
-
Mode budget :
- Pot commun : somme des budgets individuels
- Budget plancher : le budget le plus bas parmi les membres
- Anonymisation des budgets individuels : l'organisateur peut masquer les montants individuels aux autres membres. Le budget total consolidé reste toujours visible par tous les membres.
L'organisateur invite via un unique point d'entrée : un champ de recherche par username ou email.
Cas 1 — Utilisateur trouvé en base Si le compte existe, il est ajouté directement au voyage. Il est invité à compléter le questionnaire à sa prochaine visite du voyage.
Cas 2 — Email inconnu en base Si l'email n'est pas trouvé, l'app envoie automatiquement une invitation par email à cette adresse. Le mail contient un lien unique rattaché au voyage. Ce lien :
- Est réutilisable (pas d'expiration) — la personne peut revenir plus tard
- Donne accès au voyage en read-only sans compte
- Invite explicitement à créer un compte pour devenir membre actif
Dès que la personne crée son compte, elle est automatiquement rattachée au voyage. Le questionnaire se déclenche immédiatement.
Le lien d'invitation est rattaché à l'adresse email spécifique — le rattachement au voyage ne s'effectue que si l'email du compte créé correspond à l'email invité.
Il n'existe pas de lien de partage générique public. Tout accès passe par une invitation nominative.
Le questionnaire est propre à chaque voyage — un utilisateur participant à plusieurs voyages remplit un questionnaire distinct pour chacun, ses disponibilités et son budget pouvant varier.
Il se déclenche à la première arrivée sur la page du voyage, qu'il s'agisse d'un compte existant ajouté par l'organisateur ou d'un nouveau compte créé via lien d'invitation. Il s'affiche en modal ou en écran dédié, avant tout accès au contenu du voyage.
Le questionnaire est obligatoire : un membre ne peut pas accéder au voyage sans l'avoir complété. Il n'y a pas de membre "fantôme" dans le calcul des critères.
Questions posées une par une, séquentiellement :
| # | Question | Format UI |
|---|---|---|
| 1 | Quel est ton budget maximum pour la location ? (Le transport et les activités ne sont pas pris en compte ici) | Curseur avec valeur affichée en temps réel |
| 2 | Quelle destination te vient en tête en premier ? | Champ texte libre avec autocomplete géographique (ville ou région) |
| 3 | Sur quelles périodes es-tu disponible ? | Sélecteur de fourchettes sur calendrier mensuel : un début et une fin de période en deux clics, plusieurs fourchettes possibles |
Règles :
- Le questionnaire peut être modifié à tout moment par le membre depuis sa page de profil dans le voyage.
- Chaque modification déclenche un recalcul des critères consolidés (avec debouncing sur les appels API).
| Critère | Logique |
|---|---|
| Budget | Somme (pot commun) ou minimum (budget plancher) des budgets de tous les membres actifs |
| Destinations | Union de toutes les destinations citées — aucun filtre, toutes sont prises en compte |
| Dates | Choix manuel de l'organisateur, éclairé par la vue des disponibilités agrégées (voir 5.6) |
| Nombre de personnes | Nombre de membres actifs ayant complété leur questionnaire |
Périmètre du budget : uniquement le coût de la location. Transport et activités explicitement hors scope.
L'organisateur dispose d'une vue dédiée présentant un calendrier mensuel agrégé indiquant pour chaque jour le nombre de membres disponibles. C'est un outil d'aide à la décision — l'organisateur choisit manuellement la plage de dates, l'app ne la détermine pas automatiquement.
Visibilité :
- Organisateur : vue détaillée par membre
- Membres connectés : vue synthétique uniquement (ex. : 8/10 membres disponibles sur cette période)
- Visiteurs read-only : pas d'accès
Rafraîchissement automatique à chaque mise à jour des critères consolidés, avec debouncing côté backend.
Chaque carte affiche :
- Photo principale
- Titre
- Localisation
- Prix total pour le séjour
- Source
- Badge d'état si pertinent (Indisponible, Hors budget, Dates incompatibles)
- Action Voir l'annonce (lien source)
- Action Sélectionner (ajouter aux annonces intéressantes)
Tous les membres connectés ayant complété leur questionnaire. Les visiteurs read-only ne peuvent pas sélectionner.
Chaque membre peut sélectionner 10 annonces maximum. Lorsqu'il atteint cette limite, il doit désélectionner une annonce existante pour en ajouter une nouvelle. L'interface indique le compteur en temps réel (ex. : 7/10 annonces sélectionnées).
La shortlist est collective : une annonce sélectionnée par un membre est visible et votable par tous les autres membres, sans compter dans leur quota de 10.
Regroupe toutes les annonces sélectionnées par les membres. Affichage en cartes accordéon.
État fermé :
- Photo, titre, prix, localisation, source
- Badge d'état si pertinent
- Indicateur de votes (affiché uniquement après la dernière révélation du podium)
État ouvert :
- Détail complet de l'annonce (récupéré depuis la source à la volée)
- Zone de commentaires
Chaque membre peut placer n'importe quelle annonce de la shortlist dans sa tier list personnelle — qu'il l'ait sélectionnée lui-même ou non. Voter sur une annonce ne consomme pas le quota de sélection.
| Tier | Label |
|---|---|
| 5 | Coup de cœur |
| 4 | J'aime bien |
| 3 | Pourquoi pas |
| 2 | Pas convaincu |
| 1 | Non |
Règles :
- Le vote est personnel et privé jusqu'à la révélation du podium par l'organisateur.
- Les votes des autres membres ne sont pas visibles avant révélation — ce qui évite le biais d'alignement social.
- Un membre peut modifier son vote à tout moment. Les modifications restent privées jusqu'à la prochaine révélation.
- Un membre n'est pas obligé de noter toutes les annonces.
Dans l'accordéon d'une annonce, chaque membre peut laisser un commentaire texte libre, visible par tous les membres connectés. Pas de réponses imbriquées, pas de mentions, pas de temps réel.
Chaque commentaire peut recevoir un 👍 ou 👎 — une seule réaction par membre par commentaire. C'est le seul niveau d'interaction sociale sur les commentaires.
Le podium affiche les 3 annonces les mieux notées selon la moyenne des votes du groupe.
- L'organisateur appuie sur "Révéler le podium" pour publier un snapshot des résultats à l'instant T.
- Entre deux révélations, les membres votent librement sans voir les résultats agrégés.
- À chaque révélation, le podium se met à jour avec les votes courants.
- Pas de limite au nombre de révélations.
- Départage en cas d'égalité : l'annonce ayant reçu le plus grand nombre de votes Tier 5 (Coup de cœur) est prioritaire.
- Les annonces avec un badge Indisponible ou Hors budget restent dans le podium avec leur badge visible.
- Le podium (dernier snapshot révélé) est visible par les visiteurs read-only.
Un membre peut quitter un voyage à tout moment. Conséquences :
| Élément | Traitement |
|---|---|
| Réponses au questionnaire | Retirées du calcul des critères consolidés |
| Votes (tier list) | Supprimés — la moyenne des annonces est recalculée |
| Commentaires | Supprimés |
| Annonces sélectionnées | Conservées dans la shortlist — elles appartiennent au groupe |
L'organisateur ne peut pas quitter son voyage. Il peut le clôturer (statut Terminé).
| Action | Visiteur read-only | Membre | Organisateur |
|---|---|---|---|
| Voir les critères consolidés | ✅ | ✅ | ✅ |
| Voir les annonces compatibles | ✅ | ✅ | ✅ |
| Voir les annonces sélectionnées | ✅ | ✅ | ✅ |
| Voir le podium (dernier snapshot) | ✅ | ✅ | ✅ |
| Voir les disponibilités synthétiques | ❌ | ✅ | ✅ |
| Voir les disponibilités détaillées par membre | ❌ | ❌ | ✅ |
| Compléter le questionnaire | ❌ | ✅ | ✅ |
| Sélectionner une annonce (quota 10) | ❌ | ✅ | ✅ |
| Voter sur n'importe quelle annonce shortlistée | ❌ | ✅ | ✅ |
| Commenter une annonce | ❌ | ✅ | ✅ |
| Réagir à un commentaire (👍👎) | ❌ | ✅ | ✅ |
| Quitter le voyage | ❌ | ✅ | ❌ |
| Inviter un membre (compte existant) | ❌ | ❌ | ✅ |
| Envoyer une invitation email | ❌ | ❌ | ✅ |
| Choisir les dates finales | ❌ | ❌ | ✅ |
| Configurer le mode budget | ❌ | ❌ | ✅ |
| Anonymiser les budgets individuels | ❌ | ❌ | ✅ |
| Révéler le podium | ❌ | ❌ | ✅ |
| Clôturer le voyage | ❌ | ❌ | ✅ |
Indicateurs visuels uniquement (badges) — pas d'email de notification, pas de push. L'email est utilisé uniquement pour les invitations.
| Événement | Destinataire |
|---|---|
| Nouveau membre a rejoint | Organisateur |
| Un membre a complété ou modifié son questionnaire | Organisateur |
| Un membre a quitté le voyage | Organisateur |
| Une annonce shortlistée change d'état | Organisateur |
| Nouvelle annonce sélectionnée | Tous les membres |
| Podium révélé | Tous les membres |
- Messagerie ou chat global entre membres
- Réponses imbriquées sur les commentaires
- Gestion des paiements ou pot commun financier réel
- Notifications email (hors invitations)
- Notifications push
- Application mobile native
- Transfert du rôle d'organisateur
- Export PDF ou partage du podium
- Sources d'annonces autres qu'Airbnb et LeBonCoin
- Prise en compte du transport ou des activités dans le budget
- OAuth tiers (Google, Apple)
- Limite globale sur la shortlist (remplacée par limite individuelle de 10 par membre)
| Terme | Définition |
|---|---|
| Voyage | Projet de voyage collectif créé par un organisateur |
| Organisateur | Membre créateur du voyage, avec droits de configuration étendus |
| Membre | Utilisateur connecté ayant rejoint un voyage et complété son questionnaire |
| Visiteur read-only | Utilisateur accédant au voyage via lien d'invitation email sans être connecté |
| Questionnaire | 3 questions posées à chaque membre à sa première arrivée sur un voyage, propres à ce voyage |
| Critères consolidés | Agrégation des réponses de tous les membres actifs (budget location, dates, destinations, nombre de personnes) |
| Annonces compatibles | Annonces retournées par les APIs sources selon les critères consolidés courants |
| Shortlist | Ensemble des annonces sélectionnées par les membres — collective et indépendante de qui les a sélectionnées |
| Tier list | Système de notation personnelle de 1 à 5 sur les annonces de la shortlist |
| Podium | Snapshot des 3 annonces les mieux notées, révélé manuellement par l'organisateur |
| Révélation | Action de l'organisateur qui publie le snapshot courant des votes au groupe |
| Budget plancher | Mode où le budget applicable est celui du membre le plus bas |
| Pot commun | Mode où les budgets de tous les membres sont additionnés |
| Debouncing | Mécanisme technique limitant la fréquence des appels API lors de modifications rapides des critères |