- Rust 58.4%
- TypeScript 22.1%
- Vue 19.2%
- Dockerfile 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .cargo | ||
| crates | ||
| docker | ||
| packages | ||
| .dockerignore | ||
| .env.example | ||
| .envrc | ||
| .gitignore | ||
| .taplo.toml | ||
| bun.lock | ||
| Cargo.lock | ||
| Cargo.toml | ||
| devbox.json | ||
| devbox.lock | ||
| docker-compose.yml | ||
| LICENSE | ||
| package.json | ||
| prek.toml | ||
| README.fr.md | ||
| README.md | ||
| Taskfile.yml | ||
GearTrack
Tauri desktop app + Actix HTTP backend + Vue/Vuetify frontend shared between the two runtimes. Same stack as mysecretsanta-rs.
Version française : README.fr.md.
Stack
- Rust — domain lib + Actix backend + Tauri wrapper
- Vue 3 + Vuetify — shared frontend (web mode talks to the HTTP backend, desktop mode uses Tauri invoke)
- Devbox — reproducible dev environment (Nix under the hood)
- Taskfile — command orchestration (
task <name>) - prek — pre-commit runner written in Rust (drop-in replacement for
pre-commit)
Initial setup
devbox shell # enter the env (or let direnv do it automatically)
task install # bun install + cargo build (when present) + prek hooks
If direnv is installed and enabled (direnv allow in this directory), the devbox env is loaded automatically on every cd into the folder.
The web tasks (lint:web, test:web, dev:web, tauri:*) run bun install first. It does nothing when node_modules already matches bun.lock, and catches up after pulling a merge that adds a dependency.
Commands
task # help
task lint # full lint (rust + web + toml)
task fmt # cargo fmt + taplo fmt
task test # all tests
task audit # known vulnerabilities in Rust and web dependencies
task precommit:run:all # run every hook against the whole repo
Docker deployment
Self-hosted stack in three containers (Postgres + Actix backend + Caddy
serving the SPA and reverse-proxying /api) :
cp .env.example .env # set POSTGRES_PASSWORD + JWT_SECRET at minimum
docker compose up -d --build
curl http://localhost:8081/api/config
The backend refuses to start without DATABASE_URL, with a JWT_SECRET
shorter than 32 characters or still set to the .env.example placeholder,
and in GEARTRACK_DEV_MODE on anything but a loopback address. Images are
named after DOCKER_HTTP_IMAGE / DOCKER_WEB_IMAGE / DOCKER_TAG, the
same as task docker:build and task docker:push.
Caddy sends a strict Content-Security-Policy plus the usual hardening
headers (docker/Caddyfile). The desktop app sends its remote API calls
from Rust, with the certificate pinned on the profile, so it needs no CORS
entry and its webview CSP only allows its own files and the Tauri IPC.
Pinning checks the server's public key and replaces the public roots. The
barcode decoder is served by the app, with no CDN.
The database volume is mounted on /var/lib/postgresql (PostgreSQL 18
layout). A volume that already holds a cluster from an older PostgreSQL
version must be migrated first, or the db container will not start: see
"Volume layout" in the operator guide.
Full operator guide lives out-of-tree at ../docs/DOCKER.md (project-root
technical wiki, not versioned in the repo).
Pre-commit (prek)
Configuration lives in prek.toml (prek's native format, more compact than the upstream YAML). Active hooks:
- Generic: trailing whitespace, end-of-file, YAML/JSON/TOML validity, large files, merge conflicts.
- Rust:
cargo fmt --check,cargo clippy -D warnings(triggered only when.rsfiles are staged). - TOML:
taplo fmt --check. - Frontend:
bun run lint+bun run type-check(triggered only when files underpackages/**/*.{ts,vue,js,json,scss}are staged).
The git hooks are installed automatically on the first devbox shell entry (via the init_hook). To reinstall manually: task precommit:install.