Files
funman300 f6dd41fd41
CI / Build, lint & test (push) Successful in 2m21s
feat: Phase 4 — dev experience complete
Docs:
- .env.example: documents all environment variables with defaults
- CONTRIBUTING.md: dev setup, running tests, code style, design constraints
- MODDING.md: full schema reference for cards, packs, objectives, and SBCs
- .gitea/workflows/ci.yml: Gitea Actions CI (fmt check, clippy, build, test)

Middleware (#50-52):
- Body limit (256 KB) via DefaultBodyLimit on all routes (#50)
- Concurrency limit (256 concurrent requests) via semaphore middleware;
  returns 429 Too Many Requests when at capacity (#51)
- Correlation IDs via tower_http request_id layers; sets x-request-id
  UUID on every request and propagates it to the response headers (#52)

Layer order (outermost → innermost):
  CorsLayer → DefaultBodyLimit → concurrency limit → SetRequestId
  → TraceLayer → PropagateRequestId → routes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 15:53:28 -07:00

2.4 KiB

Contributing to OpenFUT Core

Prerequisites

  • Rust (stable, 1.80+) — install via rustup
  • SQLite 3 — usually pre-installed on Linux/macOS

Recommended tools:

rustup component add clippy rustfmt

Setup

git clone <repo-url>
cd openfut-core
cp .env.example .env
cargo build

Running locally

cargo run

The server starts at http://127.0.0.1:8080 by default. Logs appear in the terminal. On first run, the SQLite database is created and all migrations are applied automatically.

Running tests

cargo test

Tests spin up a full in-process server against an in-memory SQLite database — no setup required and nothing is written to disk.

Code style

All PRs must pass before merge:

cargo fmt --check    # formatting
cargo clippy -- -D warnings   # lints
cargo test           # full test suite

Auto-fix formatting with cargo fmt.

Adding card / pack / objective data

See MODDING.md for the data file schemas. No Rust code changes are needed to add new cards, packs, objectives, or SBC definitions.

Project layout

src/
  app.rs          router + middleware setup
  config.rs       Config struct (reads from env)
  db.rs           SQLite pool init + migrations
  error.rs        AppError enum
  middleware.rs   concurrency limit, request ID
  models/         Serde structs for DB rows and API payloads
  routes/         Axum handler functions (one file per domain)
  services/       Business logic (no HTTP types here)
  seed/           One-time startup seeds
  modding/        JSON data loader utilities
data/
  cards/          CardDefinition JSON arrays
  packs/          PackDefinition JSON arrays
  objectives/     ObjectiveDefinition JSON arrays
  sbcs/           SbcDefinition JSON arrays
migrations/       SQLite migration SQL files

Branching & pull requests

  • Create a branch from main: git checkout -b feat/my-feature
  • Keep PRs focused — one feature or fix per PR
  • PR description should explain why, not just what

Design constraints

  • No online multiplayer. This is an offline local backend only.
  • No copyrighted assets. All card data in data/ must be original.
  • No real EA services. Do not hardcode or reverse-engineer EA endpoints.
  • Game-independent core. openfut-core must stay game-agnostic; FIFA-specific logic belongs in openfut-bridge.