System boundaries
Kralis owns
- identity, school tenancy, authorization, and role resolution
- events, settings, grants, admissions, participants, and sessions
- expected rosters, provider presence evidence, and attendance results
- chat persistence and presentation state
- recording requests, publication state, and playback authorization
- whiteboard ownership, grants, editor leases, and immutable revisions
- operational limits, notices, audits, incidents, and retention metadata
LiveKit owns
- WebRTC media transport
- room and participant provider state
- camera, microphone, and screen-share tracks
- restricted data transport for trusted notifications and whiteboard scenes
- room-composite Egress
R2 owns
- private MP4 recording objects
- private Excalidraw JSON revision objects
Backend organization
classroom/services, not GraphQL resolvers, REST serializers, webhooks, or Celery tasks. Those surfaces resolve inputs and delegate to the same services so manual, scheduled, and provider-driven paths converge.
Frontend organization
Data model relationships
Every domain row inherits school scoping through the Kralis base model. A session is an execution of an event, not the event itself. A recording belongs to both the event and, when available, the session that produced it.API split
GraphQL
GraphQL is the application control plane. It covers:- event CRUD-like lifecycle mutations and cursor-paginated queries;
- access grants, collaboration groups, and membership;
- lobby requests and decisions;
- join credentials and recording-notice acknowledgement;
- participant moderation, live settings, chat, and presentation;
- attendance, sessions, recordings, playback, and publication;
- whiteboard creation, grants, attachments, revisions, and realtime access;
- school operational policy, usage, audit events, and issue resolution.
REST
Classroom REST resources are read-only and school-acronym scoped:Authentication and LiveKit authorization
Kralis users do not receive LiveKit accounts. The flow is:- authenticate the Kralis web request;
- load the event inside the user’s school;
- resolve the strongest event role;
- enforce event state, recording notice, removal state, admission, and capacity;
- create or update the Kralis participant;
- issue a short-lived LiveKit JWT for one opaque room.
Webhook inbox and presence
Accepted provider events are stored inProviderWebhookEvent using LiveKit’s event ID as an idempotency key. Duplicate processed events return success without applying the transition again.
Supported provider events include:
room_startedparticipant_joinedparticipant_leftroom_finishedegress_startedegress_updatedegress_ended
room_finished for a scheduled event ends only that session; the scheduler may create a replacement. An on-time/provider-driven completion uses the shared full event finalizer.
Realtime application data
The browser cannot publish arbitrary application commands in the media room. Chat, hand, settings, moderation, and presentation changes first pass through authenticated GraphQL and persistent services. After commit, the server sends a small trusted LiveKit packet prompting connected clients to refetch or apply the authoritative state. Separate topics exist for chat, participant state, admission, event settings, presentation, whiteboard scenes, and the active whiteboard cursor. Whiteboard editor tokens are the exception: exactly one leased editor may publish scene/cursor data in the board’s restricted data-only room. Durable state still comes from immutable R2 revisions.Recording architecture
Manual start creates aREQUESTED row synchronously and queues provider work. Celery starts room-composite Egress. Provider webhooks update normal state, and the minute reconciler repairs delayed or missed transitions.
Camera-grid recording uses LiveKit’s standard grid layout. Screen-share recording uses the public Kralis egress renderer at LIVEKIT_EGRESS_TEMPLATE_URL, the kralis-classroom custom layout, and the standard LiveKit egress query-token mechanism. The configured base URL must not contain a query or fragment. The renderer reads credentials through the LiveKit Egress SDK, removes them from browser history, and starts capture only after media is available.
Egress uploads H.264 720p MP4 directly to private R2 using S3-compatible credentials. Kralis validates the returned filename before marking the record ready.
R2 layout
R2 keys use immutable UUIDs rather than acronyms:R2_ENDPOINT must be an account endpoint such as:
/kralis, a bucket, path, query, or fragment. Configure the bucket independently.
Environment configuration
Celery and lifecycle convergence
Run an API process, Celery worker, and Celery Beat. The configured periodic work is:Operational safeguards
- per-school concurrent room, recording, and storage limits
- idempotent schedule and webhook transitions
- capacity reservations for concurrent joins
- mutation rate limits for admission, chat, hand, joins, whiteboard leases, heartbeats, and revisions
- recording and webhook retention
- append-only audit events for sensitive actions
- coalesced operational issues and support email alerts
- explicit publication before ordinary recording playback
- presigned private playback URLs
- role-aware GraphQL nested resolvers
The GraphQL error includes retry information so the frontend can disable the action temporarily and show a countdown instead of encouraging repeated calls.
Provider and staging checks
Verify configured providers with isolated temporary resources:Deployment position
The current product is designed for managed LiveKit Cloud first, with private Cloudflare R2 storage. This avoids operating TURN, SFU, Egress, autoscaling, and regional media capacity while Classroom usage is being established. The provider adapters preserve a path to self-hosted LiveKit later. That change requires capacity planning for signaling, Redis, TURN, regional bandwidth, Egress workers, observability, upgrades, and failure recovery; it is an infrastructure decision, not a frontend rewrite.LMS integration rule
When LMS requests a live class for a course:- the LMS course explicitly requests creation or attachment;
- Classroom creates or owns the event and its settings;
- LMS stores the association on the course side;
- Classroom remains independently visible and usable;
- Classroom remains authoritative for access, sessions, attendance, recordings, chat, and boards.

