Data Flow Architecture
This page describes how data moves through the iAm system, from user interaction to persistent storage and back.
High-Level Data Flow
Mobile/Web Client
│
│ GraphQL Queries/Mutations
▼
Apollo Server (Express)
│
│ Neo4j GraphQL OGM
▼
Neo4j Database
Additional paths:
- Real-time: Client connects via WebSocket for live session subscriptions
- Background jobs: Server dispatches to Redis/BullMQ for async processing
- Local storage: Client maintains a SQLite database for offline-first operation
- AI services: Server calls external AI APIs for analysis features
The Reporting Process
When an observer reports an experience during a session, the following sequence occurs:
- Observer begins a Session implementing a specific SessionTypeVersion
- As experiences arise, Experience Instances (
Manifestationnodes) are created with precise timestamps:beginInputTimestamp-- when the observer starts respondingendInputTimestamp-- when the observer finishes inputsubmitInputTimestamp-- when the experience instance is submitted
- Each Experience Instance links to a Unique Value (creating or finding existing)
- Each Unique Value links to the relevant ExperienceTypeVersion
- Aggregates may group simultaneous Experience Instances (
Manifestationnodes) that co-occur - Session ends with post-notes and metadata
GraphQL Flow Example
Client sends mutation:
mutation CreateManifestation($input: CreateManifestationInput!) {
createManifestation(input: $input) {
id
value
beginInputTimestamp
endInputTimestamp
abstract {
id
value
}
}
}
Server processes through layers:
Resolver (resolver.ts)
→ validates input
→ extracts context (user, observer, ogm)
│
Service (service.ts)
→ business logic
→ creates/finds Abstract
→ links Manifestation to Session
│
Neo4j OGM
→ translates to Cypher queries
→ persists to Neo4j
│
Returns typed output
Survey Data Flow
Surveys use a hybrid architecture combining SurveyJS for UI with Neo4j for storage:
- SurveyTypeVersion generates a SurveyJS model for UI rendering
- User interacts with the SurveyJS interface
- Survey entity stores serialized SurveyJS state for pause/resume
- On completion, individual Response entities are created in the graph
- Each Response links to its corresponding Question via a
TOrelationship
Observer completes Survey
│
▼
For each Question in SurveyTypeVersion
│
▼
Observer provides Response
│
▼
Response links to specific Question
│
▼
Question validates against QuestionScale (if applicable)
Sequence Orchestration
Sequences combine multiple sessions and surveys into ordered protocols:
- Sequence implements a SequenceTypeVersion
- SequenceTypeVersion defines ordered SequenceSteps
- Each step references either a SessionTypeVersion or SurveyTypeVersion
- As the observer progresses, Sessions and Surveys are created and linked
FOLLOWED_BYrelationships maintain temporal ordering between steps
Synchronous vs Asynchronous
Synchronous Workflows
- User authentication and authorization
- Session creation and CRUD operations
- Real-time experience reporting during active sessions
- Survey completion and response creation
Asynchronous Workflows
- Background data processing and analysis
- Email notifications and external API calls
- Data export and import operations
- Migration scripts and maintenance tasks
Type Generation Pipeline
When the GraphQL schema changes, types must be regenerated:
TypeGraphQL Models/Inputs/Outputs
│
▼ yarn build:types:all
│
Server Generated Types
│
▼ Shared via workspace
│
Client TypeScript Types
│
▼
Apollo Client typed queries
This pipeline ensures end-to-end type safety from the database schema through to the React component props.
Caching Strategy
| Layer | Technology | What's Cached |
|---|---|---|
| Client | Apollo Client Cache | GraphQL query results, optimistic updates |
| Client | SQLite / IndexedDB | Offline data, draft sessions |
| Server | Redis | Session tokens, temporary state |
| Server | BullMQ (Redis) | Background job queue state |