From 09b5311596930fc29ff6368b10bfdc675e52a761 Mon Sep 17 00:00:00 2001 From: crrow Date: Tue, 31 Mar 2026 19:27:30 +0800 Subject: [PATCH 1/3] docs: add architecture decision summary for interview (#250) One-page summary of core design choices and trade-offs for reviewers who may not have time to read the full documentation site. Closes #250 --- ARCHITECTURE_DECISIONS.md | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 ARCHITECTURE_DECISIONS.md diff --git a/ARCHITECTURE_DECISIONS.md b/ARCHITECTURE_DECISIONS.md new file mode 100644 index 0000000..9641f00 --- /dev/null +++ b/ARCHITECTURE_DECISIONS.md @@ -0,0 +1,44 @@ +# Architecture Decisions + +Short summary of core design choices and their rationale. +For full documentation, run `just book` to view the rendered doc site. + +## System Shape + +**Microservice boundaries, single-process delivery.** +The system is split into four services — Gateway, MetaService, Ingestor, Streamer — each with its own crate and API surface. In the submitted build they all run inside one process (`stream-app`) backed by SQLite, an in-memory queue, and an in-memory object store. This keeps deployment trivial while preserving the ability to split services later without API changes. + +## Control Plane vs Data Plane + +**Gateway proxies metadata; streaming bypasses it.** +Gateway handles auth, rate limiting, and proxies requests to MetaService and Ingestor. Streamer is accessed directly by clients — video data should not pass through a reverse proxy. Access control for the data plane uses short-lived HMAC-signed connection tokens issued by MetaService, scoped by action (upload / stream) with a 5-minute TTL. + +## Upload & Processing + +**Async pipeline with crash recovery.** +Uploads land in object storage immediately; transmux to HLS happens asynchronously via a task queue. Processing state is persisted in the database so incomplete jobs resume after a crash instead of starting over. Transient errors (I/O timeout) retry with exponential backoff; permanent errors (corrupt file) fail fast. + +## Playback + +**Streamer is a pure cache layer.** +Streamer fetches HLS segments from object storage on first request and caches them locally. It does no transcoding — that responsibility belongs to Ingestor. This separation keeps playback latency low and lets Streamer scale independently on bandwidth. + +## Share Links & Access Control + +**Two-layer authorization: share link + connection token.** +Share links control *who can enter* (owner can revoke instantly). Connection tokens control *how long they stay* (5-min TTL limits replay window). If a link leaks, revocation cuts off access within one token lifetime. + +## Client + +**Rust/WASM core + Svelte UI shell.** +Core logic (hashing, token management, validation) lives in Rust compiled to WASM, shared with the backend to prevent divergence. The Svelte shell handles routing and UI. Client-side format validation is a UX fast-fail; the real security boundary is server-side codec probing in Ingestor. + +## Key Trade-offs + +| Decision | Trade-off | Why | +|----------|-----------|-----| +| Single-process mode | No horizontal scaling | Simplifies deployment for assignment; service boundaries are ready for split | +| In-memory object store | Data lost on restart | Avoids external infra dependency; swappable to S3 via config | +| No auth system | No real user identity | Assignment spec says auth not required; Gateway middleware slot is ready for JWT | +| WASM client | Larger initial bundle | Reuses Rust logic; avoids client/server divergence on hashing and validation | +| HLS (not DASH) | Apple-centric format | Broadest native browser support; simpler transmux pipeline with ffmpeg | From 16543999fb575e956999bf42b57ec7ac4c4e2ac4 Mon Sep 17 00:00:00 2001 From: crrow Date: Tue, 31 Mar 2026 19:29:22 +0800 Subject: [PATCH 2/3] docs: add MetaService section to architecture summary (#250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MetaService is the system brain — metadata CRUD, share lifecycle, token signing. Deserves its own section in the summary. Closes #250 --- ARCHITECTURE_DECISIONS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ARCHITECTURE_DECISIONS.md b/ARCHITECTURE_DECISIONS.md index 9641f00..e188d04 100644 --- a/ARCHITECTURE_DECISIONS.md +++ b/ARCHITECTURE_DECISIONS.md @@ -13,6 +13,11 @@ The system is split into four services — Gateway, MetaService, Ingestor, Strea **Gateway proxies metadata; streaming bypasses it.** Gateway handles auth, rate limiting, and proxies requests to MetaService and Ingestor. Streamer is accessed directly by clients — video data should not pass through a reverse proxy. Access control for the data plane uses short-lived HMAC-signed connection tokens issued by MetaService, scoped by action (upload / stream) with a 5-minute TTL. +## Metadata & Coordination + +**MetaService is the system brain.** +All video lifecycle operations — create, list, delete, status tracking — go through MetaService. It owns the share link lifecycle (create, revoke, resolve) and signs connection tokens that authorize data-plane access. Other services never talk to each other directly; MetaService is the single source of truth for "what exists and who can access it." + ## Upload & Processing **Async pipeline with crash recovery.** From e95a02535fa5c1cfac40d5f095adfe9d44cf8299 Mon Sep 17 00:00:00 2001 From: crrow Date: Tue, 31 Mar 2026 19:31:34 +0800 Subject: [PATCH 3/3] docs: revert MetaService section from architecture summary (#250) MetaService is already covered in Control Plane and Share Links sections. Closes #250 --- ARCHITECTURE_DECISIONS.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ARCHITECTURE_DECISIONS.md b/ARCHITECTURE_DECISIONS.md index e188d04..9641f00 100644 --- a/ARCHITECTURE_DECISIONS.md +++ b/ARCHITECTURE_DECISIONS.md @@ -13,11 +13,6 @@ The system is split into four services — Gateway, MetaService, Ingestor, Strea **Gateway proxies metadata; streaming bypasses it.** Gateway handles auth, rate limiting, and proxies requests to MetaService and Ingestor. Streamer is accessed directly by clients — video data should not pass through a reverse proxy. Access control for the data plane uses short-lived HMAC-signed connection tokens issued by MetaService, scoped by action (upload / stream) with a 5-minute TTL. -## Metadata & Coordination - -**MetaService is the system brain.** -All video lifecycle operations — create, list, delete, status tracking — go through MetaService. It owns the share link lifecycle (create, revoke, resolve) and signs connection tokens that authorize data-plane access. Other services never talk to each other directly; MetaService is the single source of truth for "what exists and who can access it." - ## Upload & Processing **Async pipeline with crash recovery.**