Migrate to Rust (Axum/Tokio/sqlx) backend + SvelteKit frontend — full parity, decommission React/Laravel#20
Merged
billyribeiro-ux merged 15 commits intoJun 4, 2026
Conversation
- lean SigV4 presigner (reuses hmac/sha2) validated against AWS's documented
known-answer test; no aws-sdk-s3 dependency, files never proxied through the API
- endpoints: GET /v1/rooms/{id}/files, POST (presigned PUT + metadata),
GET /v1/files/{id} (presigned GET), DELETE /v1/files/{id} (soft delete)
- room_files domain/repo, 0006 migration, R2 config; 50MB cap; key sanitization
- room-membership authz on every operation
- gates: cargo fmt + clippy -D warnings clean; 6 tests pass
…CI + compose - Dockerfile.api-rs (multi-stage Rust release build -> debian-slim, ships migrations) - Dockerfile.frontend-svelte (adapter-node SSR server on node 24.16.0) - CI: api-rs-test (fmt/clippy -D warnings/test) + frontend-svelte-test (svelte-check + build); both gate the Docker build matrix (api-rs, frontend-svelte) - docker-compose: api-rs + frontend-svelte services wired to redis/signaling - stack.md: document the Rust backend crate stack + new images - verified: cargo build --locked succeeds; Cargo.lock tracked; YAML valid
- /settings/billing: lists plans with monthly/yearly toggle, shows current subscription, and drives Stripe Checkout + Billing Portal via the BFF - BFF client: listPlans/getSubscription/startCheckout/billingPortal - success/cancelled status banners; dashboard link - svelte-check 0/0 (444 files); component passes svelte-autofixer
- /settings/organization: org name/slug, workspace list, create-workspace form - dashboard link; svelte-check 0/0 (448 files); component passes svelte-autofixer
- users.is_admin flag (0007 migration); User/UserResponse + /me carry it - AdminUser authz-marker extractor (reuses AuthUser; 403 for non-admins) - GET /v1/admin/stats (platform counts), GET /v1/admin/users (paginated) - gates: cargo fmt + clippy -D warnings clean; 6 tests pass
- /admin (platform stat cards) and /admin/users (user table); API enforces 403 - SessionUser carries isAdmin (via /me); dashboard shows Admin link only to admins - BFF adminStats/adminUsers - svelte-check 0/0 (456 files); components pass svelte-autofixer
- tower_governor per-IP rate limit (SmartIpKeyExtractor, correct behind a proxy; 50 req/s, burst 100) with periodic stale-bucket eviction - tower-http RequestBodyLimitLayer (5 MiB) — JSON endpoints only; file bytes go straight to R2 via presigned URLs - gates: cargo fmt + clippy -D warnings clean; 6 tests pass
…Kit are the sole stack BREAKING: removes the legacy stacks now that backend-rs + frontend-svelte have full feature parity (auth, rooms, live WebRTC, chat/alerts/analytics, billing, files, admin). - remove React frontend/ and Laravel backend/ (+ Dockerfile.backend, Dockerfile.frontend, nginx backend/frontend confs, php/, supervisor/) - CI: drop backend-test + frontend-test jobs; build matrix = signaling, sfu, api-rs, frontend-svelte - docker-compose: drop backend/horizon/scheduler/frontend services; SvelteKit now serves on :80 - Makefile, README, stack.md, MIGRATION_PLAN updated to the Rust + SvelteKit stack
…ostgres - feature-gated integration tests (cargo test --features integration): each runs on a freshly-migrated database, exercising auth/orgs/workspaces/rooms-lifecycle/ tokens/participants-reconnect/chat/subscriptions end-to-end (6 tests) - proves all 7 migrations apply cleanly in order against a real Postgres - CI api-rs-test gains a postgres:18 service + runs the suite; clippy now --all-features so the test module is linted too - default 'cargo test' (no DB) still runs only unit tests, keeping the gate green without a database - verified locally: 12 passed (6 unit + 6 integration); clippy --all-features clean
- observability: when OTEL_EXPORTER_OTLP_ENDPOINT is set, bridge tracing spans to an OTLP/HTTP collector (opentelemetry 0.32 + tracing-opentelemetry 0.33, HTTP exporter over the existing reqwest stack — no tonic tree); otherwise JSON-to-stdout only. Init failure degrades gracefully. - compose: api-rs exports to the bundled Jaeger (OTLP/HTTP :4318) - gates: cargo fmt + clippy --all-features -D warnings clean; 12 tests pass (6 unit + 6 integration vs Postgres)
…d sqlx-macro optimization
…external SVGs)
- standardize on phosphor-svelte (bundled icon components — tree-shaken into the
build, zero external/CDN SVG fetch); drop the unused lucide-svelte dependency
- ControlsBar + VideoTile: replace hand-written inline <svg> paths with Phosphor
(Microphone/MicrophoneSlash, VideoCamera/VideoCameraSlash, Monitor, SignOut)
- modernize VideoTile media binding: use: actions -> {@Attach} attachments;
drop a stale svelte-ignore; add aria-labels on icon-only buttons
- audit confirms: 0 inline <svg>, 0 external svg/img references in src/
- svelte-check 0/0 (463 files); components pass svelte-autofixer
… glyphs - reusable BackLink (ArrowLeft) and ForwardLink (ArrowRight) components - replace every Unicode glyph (←, →, ✕) across dashboard/admin/rooms/settings and the live-room participant sidebar with Phosphor icon components - audit: 0 inline <svg>, 0 glyph icons, 0 external SVG/img refs in src/ - svelte-check 0/0 (468 files); components pass svelte-autofixer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Completes the migration: Rust + SvelteKit are now the sole stack, with full feature parity, the legacy React/Laravel apps removed, and real-DB integration tests.
Backend —
backend-rs/(Axum + Tokio + sqlx)Full Laravel parity (~50 endpoints): auth (Argon2id + legacy-bcrypt rehash, Sanctum-compatible tokens), organizations, workspaces, rooms (CRUD + lifecycle + signaling control-plane), chat, alerts, analytics, billing (lean Stripe REST + HMAC webhook verification — no
async-stripe), files (R2 via a KAT-tested SigV4 presigner — noaws-sdk-s3), admin, health/metrics. Per-IP rate limiting + body-size limit; RFC 7807 errors; soft-cancel rooms; opt-in OpenTelemetry OTLP export.Frontend —
frontend-svelte/(Svelte 5 / SvelteKit, adapter-node SSR)Cookie-based BFF auth (token never in client JS), dashboard, rooms (list/create/detail/live WebRTC), settings (profile/billing/org), admin console. Icons: Phosphor only — zero inline
<svg>, zero external SVGs.Infra
Both Dockerized; CI runs
clippy -D warnings+ unit and real-Postgres#[sqlx::test]integration tests +svelte-check/build; compose updated. Reactfrontend/and Laravelbackend/removed.Verification
cargo fmt+clippy --all-features -D warningsclean; 12 tests pass (6 unit + 6 integration vs Postgres).svelte-check0/0 (468 files); all components passsvelte-autofixer.Every increment went through the Svelte + Rust MCP gates. Details in
MIGRATION_PLAN.md/stack.md.https://claude.ai/code/session_01AMiTSxG8rB8FU8QgJ3Fnhs
Generated by Claude Code