708cbeead8
- Add @e2e test layer: real app in broker iframe via Playwright - Fix broker redirect: conditional auto-init only when inside iframe - Fix seed data flash: empty data during 'connecting' phase - Fix Gallery button in iframe: explicit navigate instead of history.back - Add auth e2e feature scenarios and step definitions - Update docs: bdd-testing, data-layer-testing, data-layer, AGENTS.md - Add decision record for conditional NG init approach Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
Data Layer
NextGraph-backed local-first data with fallback to local state for demo/disconnected mode.
Overview
The app has two data modes:
- Connected — NextGraph ORM shapes (P2P, encrypted, local-first)
- Disconnected/Demo — Local React state seeded from
seedData.ts
All screens use useFestipodData() hook regardless of mode.
NextGraph Stack
@ng-org/web # Browser WASM runtime
@ng-org/orm # RDF shape-based ORM
@ng-org/shex-orm # SHEX → TypeScript code generation
@ng-org/alien-deepsignals # Reactive signals bridge
Packages installed from local tarballs in .ng-tarballs/.
SHEX Shapes
src/shared/shapes/shex/festipodShapes.shex defines:
- Event — title, description, dates, location, themes, participants
- UserProfile — name, username, bio, city, visibility
- Participation — links event + user, confirmation status
ORM bindings in src/shared/shapes/orm/:
festipodShapes.schema.ts— Schema registrationfestipodShapes.shapeTypes.ts— Shape type constantsfestipodShapes.typings.ts— TypeScript interfaces
Regenerate with bun run build:orm.
Context Providers
NextGraphContext (src/shared/context/NextGraphContext.tsx)
- Connection lifecycle:
disconnected→connecting→connected|error - Provides session with store IDs (private, protected, public)
- Conditional auto-init: Only auto-calls
initNg()when running inside the broker iframe (window.self !== window.top). Outside the iframe,initNgWeb()would redirect the page to the broker — so connection waits for explicitconnect()call. connect(): Called by user clicking "Se connecter". When outside broker, triggers the redirect flow.
@ng-org/web redirect behavior
initNgWeb() checks window.self === window.top. If the app is NOT in an iframe, it redirects to nextgraph.net/redir/ with the current URL encoded as a return parameter. The broker then loads the app back in an iframe after auth. This means the app must NOT auto-init NG when loaded standalone.
FestipodDataContext (src/shared/context/FestipodDataContext.tsx)
- Wraps NextGraph shapes with
useShapeWithDefaults()hook - CRUD:
createEvent(),updateEvent(),joinEvent(),leaveEvent(), etc. - Exposes
useFestipodData()hook consumed by all screens selectedEventIdstate for cross-screen event navigationloadTestData(): CallsbootstrapWallet()to seed test data into NG wallet — only triggered by explicit user action- Provider states based on NG status:
disconnected→LocalDataProviderwith seed data (demo mode)connecting→LocalDataProviderwith empty data (avoids flashing seed data before wallet loads)connected→NgDataProviderwith real wallet dataerror→LocalDataProviderwith seed data (graceful fallback)
Data Types
src/shared/data/types.ts:
FpEventData— id, title, date, location, distance, themes, etc.FpUserData— id, name, username, bio, city, countsFpParticipationData— eventId + userId + confirmedFpMeetingPointData— eventId, location, time, host (local-only)FpFriendshipData— userId + friendId (local-only)
Seed Data
src/shared/data/seedData.ts:
- 10 users (Marie Dupont = current user,
user-1) - Multiple events with dates, locations, themes
- Participations, meeting points, friendships
CURRENT_USER_ID = 'user-1'