Database (MongoDB)
All data is stored in MongoDB.
Core Collections
configs: Published experiment configurations.- Schema:
{ configId, owner, config, checksum, metadata, requireAuth, allowRetake, createdAt, updatedAt }
- Schema:
sessions: Participant experimentation sessions (application state).- Schema:
{ id, configId, config, currentPageId, session_state, prolific?, userId?, endedAt?, createdAt, updatedAt }
- Schema:
events: Audit events and telemetry.- Schema:
{ sessionId, configId, pageId, componentType, componentId, type, timestamp, data, createdAt }
- Schema:
chat_messages: Chat message history.- Schema:
{ messageId, groupId, sessionId, senderId, senderType, content, createdAt }
- Schema:
Authentication (Better Auth)
Managed by Better Auth.
user: Registered users.session: Authentication sessions (login state) - distinct from experimentsessions.account: Linked OAuth accounts.
Media (Storage Abstraction)
Media storage is handled by a StorageAbstraction layer that supports multiple backends based on the STORAGE_BACKEND environment variable.
Interface
The abstraction provides a unified interface:
- upload(path, data, options)
- list(bucket, prefix)
- delete(path)
- getUrl(path)
Backends
-
Local Filesystem (
local):- Used for development.
- Stores files in
./storage(mounted volume in Docker). - Serves files statically via Elysia.
-
Google Cloud Storage (
gcs):- Used for production.
- Stores files in a GCS bucket (configured via
STORAGE_PATH). - Requires
GOOGLE_APPLICATION_CREDENTIALSor Workload Identity.
Management
Manager endpoints interact with this abstraction layer.
- POST /media/upload -> storage.upload()
- GET /media -> storage.list()
- DELETE /media/:object -> storage.delete()