908f7ea973
Participation privacy (decision_2026-10-29_participation-privacy-mechanism): a sign-up is a private Join naming the meeting point, addressed to nobody, handled by the backend on emission. Attendee lists hold member URNs hashed from (WebID, event, a secret kept in the participant's profile), so counts stay public and only contacts recognise anyone; the creator has no read right and is notified anonymously. Each person's participations collection, created by the backend at the first sign-up, is readable by their /contacts WAC group only, never world-readable. The member URN is sticky per (meeting point, participant) and every collection write is verified by reading back, so a refused write leaves the act unrecorded and retryable. The EventRef mechanism and its browser-side provisioning are gone. The backend now runs with WebACL on, as the reference apps do, on its own secure datasets festipod / settings-festipod instead of the pod provider's settings dataset; pod-notifications needs it. The compose header and the deployment leaf say how to reset a stack whose datasets predate this. The rights matrix covers the new mechanism live (148 hard lines), including a forged contact Accept between throwaway accounts: the stranger enters the contacts list (platform defect, reported upstream) but is refused the profile and the participations. Tests may attack as long as they never break the dev environment (rule_tests-never-break-the-dev-environment). Also lands the coherence-pass work that was still uncommitted: contacts as the Pod's social graph and invite links, image upload to the Pod, the meeting-point form, profile completion gate, and the doctrine for them. Superseded briefs and decisions are deleted rather than annotated.
45 lines
3.4 KiB
Markdown
45 lines
3.4 KiB
Markdown
# Festipod
|
|
|
|
Web app mobile-first où les utilisateurs créent des **points de rencontre** qui se *greffent* sur des **événements publics** existants, pour favoriser les rencontres. L'événement n'est qu'un prétexte/ancrage ; la valeur, c'est le point de rencontre — **on s'inscrit à un point de rencontre, pas à un événement**. Stack : Bun + React + NextGraph (P2P, local-first, chiffré).
|
|
|
|
## Invariants à toujours garder
|
|
|
|
- **Architecture feature-based** : le code est organisé par domaine métier, pas par couche technique.
|
|
```
|
|
src/modules/{event,user,home,auth,workshop,meeting,notification}/
|
|
src/shared/ # Composants, context, data — importable par tous les modules
|
|
src/app/ # App shell (router, providers, entrée)
|
|
src/screens/index.ts # Registre d'écrans (utilisé par Storybook)
|
|
```
|
|
- **Un module n'importe QUE depuis `shared/` — jamais d'un autre module.** C'est l'invariant qui rend l'archi réelle.
|
|
- **Bun-first** : `bun` / `bun install` / `bun test` / `bun build`, jamais node/npm/vite/jest. `bun run dev` (portless, port dynamique ; défaut servi par `bun run start` : 4000).
|
|
|
|
## Frontière SDK
|
|
|
|
Le SDK de données de Festipod est **`@ng-eventually/polyfill`**, injecté une seule fois via `ngSession.configure(...)`.
|
|
|
|
**L'engagement que le fournisseur publie est tiré dans ce repo et épinglé** : `data-layer`, fiche `contract_polyfill-surface`. **C'est la seule référence.** On n'ouvre jamais les sources du fournisseur ni sa copie dans `node_modules`, pas même pour vérifier une signature. Ce que le contrat ne dit pas, ce repo ne le sait pas : **un manque est remonté au fournisseur**, jamais contourné ici ni documenté ici. Vaut aussi pour les tests, qui valident **Festipod** et jamais le SDK (`bdd-testing`, `rule_tests-validate-festipod-not-the-sdk`).
|
|
|
|
Le contrat se re-tire à chaque montée de version : `python3 ~/projects/skills/concept/contracts.py pull` (dérive : `… check`). Sa surface **rétrécit** — un symbole retiré est du code que l'app supprime, pas une régression à amortir.
|
|
|
|
**Ne jamais décrire dans ce repo comment la couche de données est implémentée.** La doctrine Festipod décrit uniquement *le contrat* + *comment Festipod l'utilise* + le domaine + l'architecture + le contrat BDD.
|
|
|
|
## Doctrine du projet — concepts (livrée automatiquement)
|
|
|
|
La connaissance détaillée vit dans `.project/concepts/` (système *concept*) : fiches courtes, typées, **livrées par un hook quand tu touches leur territoire** — tu n'as pas à les charger d'avance. Les 6 concepts :
|
|
|
|
| Concept | Couvre |
|
|
|---|---|
|
|
| `functional-domain` | Modèle produit : point de rencontre, acteurs, concepts métier, périmètres public/protected/private par entité, découverte, défi déduplication |
|
|
| `app-architecture` | Modules, invariant d'imports, app shell, routing path-based, écrans |
|
|
| `tech-stack` | Bun-first, APIs Bun, build pipeline, commandes |
|
|
| `data-layer` | Persistance via le SDK `@ng-eventually/polyfill` : entités-documents par scope, shapes SHEX/ORM, modes connected/demo, pièges |
|
|
| `bdd-testing` | Cucumber multi-couches FR, contrat `@ui`/`@data`/`@e2e`, harness broker, cookbook |
|
|
| `app-security` | Isolation déléguée au SDK (pas de contrôle d'accès dans les écrans), auth wallet, matrice d'autorisations cible |
|
|
|
|
Pour **documenter** un fait projet : `/concept document <sujet>` (ne pas écrire en libre dans `.project/`).
|
|
|
|
## Rules
|
|
|
|
@.project/rules/INDEX.md
|