Skip to content

Migrate to Rust (Axum/Tokio/sqlx) backend + SvelteKit frontend — full parity, decommission React/Laravel#20

Merged
billyribeiro-ux merged 15 commits into
mainfrom
claude/update-dependencies-stack-docs-nffxp
Jun 4, 2026
Merged

Migrate to Rust (Axum/Tokio/sqlx) backend + SvelteKit frontend — full parity, decommission React/Laravel#20
billyribeiro-ux merged 15 commits into
mainfrom
claude/update-dependencies-stack-docs-nffxp

Conversation

@billyribeiro-ux

Copy link
Copy Markdown
Owner

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 — no aws-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. React frontend/ and Laravel backend/ removed.

Verification

  • Rust: cargo fmt + clippy --all-features -D warnings clean; 12 tests pass (6 unit + 6 integration vs Postgres).
  • Svelte: svelte-check 0/0 (468 files); all components pass svelte-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

claude added 15 commits June 4, 2026 18:19
- 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)
…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
@billyribeiro-ux billyribeiro-ux merged commit cc4e04b into main Jun 4, 2026
3 of 6 checks passed
@billyribeiro-ux billyribeiro-ux deleted the claude/update-dependencies-stack-docs-nffxp branch June 5, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants