Rust backend for skins.sulej.net (backend for osc_dev/osc-skins-ui)
  • Rust 98.9%
  • Shell 0.5%
  • PLpgSQL 0.3%
  • Dockerfile 0.3%
Find a file
oscbot a484d3effa
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
PR Check (osc-api) / cargo clippy -D warnings (pull_request) Successful in 2m28s
Build and Push osc-api / Release & build osc-api (push) Successful in 5m27s
deps: update rust crate uuid to v1.23.5
2026-07-15 20:01:15 +00:00
.forgejo/workflows deps: update actions/checkout action to v7 2026-07-07 17:18:31 +02:00
migrations feat(db): community management schema 2026-07-07 17:22:27 +02:00
scripts test: cover community media 404s and rate-limit DB-fault fallback 2026-07-07 17:22:26 +02:00
src feat(users): flag hidden osu accounts, drop their stale country and rank 2026-07-08 17:35:49 +02:00
tests feat(users): flag hidden osu accounts, drop their stale country and rank 2026-07-08 17:35:49 +02:00
.gitignore chore: commit source-derived openapi.json and stop ignoring it 2026-06-08 18:52:40 +02:00
.releaserc.cjs ci: skip changelog on beta prereleases via per-branch release config 2026-06-08 22:09:33 +02:00
Cargo.lock deps: update rust crate uuid to v1.23.5 2026-07-15 20:01:15 +00:00
Cargo.toml chore(release): 5.1.0 [skip ci] 2026-07-08 15:36:12 +00:00
CHANGELOG.md chore(release): 5.1.0 [skip ci] 2026-07-08 15:36:12 +00:00
Dockerfile ci: pin the Rust base image to 1.96 2026-06-08 18:34:56 +02:00
LICENSE chore: add AGPL-3.0 license 2026-05-19 11:57:06 +02:00
openapi.json chore: update openapi.json snapshot [skip ci] 2026-07-08 15:37:35 +00:00
README.md feat: rewrite the backend in Rust (axum + sea-orm) 2026-06-02 22:29:49 +02:00
renovate.json ci(renovate): use fast-forward automerge (repos disallow rebase-merge) 2026-07-03 16:20:26 +02:00
rust-toolchain.toml deps: update rust to v1.97.0 2026-07-12 00:01:03 +00:00

osc-api

Rust backend (axum) for skins.sulej.net. The UI lives in osc_dev/osc-skins-ui.

Stack

  • Rust 2024, axum 0.8 (tokio / tower)
  • sea-orm 1.1 + sqlx (Postgres)
  • reqwest (osu! API + Forgejo)
  • aws-sdk-s3 (Garage S3 for media + CI log fallback)
  • utoipa + utoipa-axum (OpenAPI generated from the code)

Local dev

cargo build

# minimum env to boot; see src/config.rs for the full list
export DATABASE_URL='postgres://osc:osc@localhost:5432/oscweb' \
       SESSION_SECRET=x FORGEJO_TOKEN=x OSU_CLIENT_ID=1 OSU_CLIENT_SECRET=x \
       GARAGE_ACCESS_KEY=x GARAGE_SECRET_KEY=x WEBHOOK_SECRET=x BOT_TOKEN=x \
       ADMIN_OSU_IDS='[]'

cargo run                     # serves on 0.0.0.0:8000
cargo run -- --dump-openapi   # print the OpenAPI spec and exit (no DB needed)

Schema: production Postgres is owned by Alembic on the Python side through cutover, so the Rust binary never migrates prod — it attaches to the existing schema. migrations/0001_schema.sql reproduces that schema only to bootstrap fresh/test databases.

Tests

scripts/test.sh              # full suite, safely (recommended)
scripts/test.sh --coverage   # + merged llvm-cov report (target/llvm-cov/html)
cargo test --lib             # unit tests only — no containers, instant
cargo test --test health     # a single integration binary

Each tests/*.rs binary boots the app in-process against an ephemeral Postgres + MinIO (testcontainers, fresh DB per test), with Forgejo and the osu! API faked at the HTTP boundary (wiremock). Plain cargo test launches every binary's containers at once and will exhaust the host — scripts/test.sh runs the binaries one at a time (set JOBS=N for bounded concurrency) and reaps containers between them. cargo clippy -- -D warnings and cargo fmt --check are the lint gates.

Deployment

CI on push to main builds the image, validates the generated OpenAPI spec, and pushes git.sulej.net/osc_dev/osc-api:latest (:beta on the beta branch). The server at /home/arlind/docker/oscbot/ runs docker compose pull && up -d to roll forward.

Traefik routes skins.sulej.net/api/*osc-web-backend:8000.

OpenAPI

The spec is generated from the code (utoipa) and served live at /api/openapi.json, rendered at /api/docs (Scalar). It is not committed — the code is the single source of truth. osc-skins-ui runs npm run sync-types to generate matching TypeScript types from the live spec.

Permissions

Action Anyone Owner Admin
Browse
Edit own repo
Edit any repo

License

Licensed under AGPL-3.0-only. The LICENSE file was added in 2026; all prior versions, releases, and container images (which predate the LICENSE file in the source tree) are also offered under AGPL-3.0 at the discretion of the copyright holder.