A high-performance, monolithic Rust API with a dynamic CRUD engine, query registry cache, JWT bitmask permissions, and a Vue 3 admin frontend.
Find a file
Matthew McPeak 10f6e3aebc
All checks were successful
ci / build-ui (push) Successful in 17s
ci / test (push) Successful in 4m1s
ci / publish (push) Successful in 3m29s
Merge pull request 'fix: cleanup' (#1) from worktree-disable-auth into main
Reviewed-on: #1
2026-08-10 08:47:57 -04:00
.forgejo/workflows Inital Commit 2026-07-16 12:36:14 -04:00
docs/superpowers fix: cleanup 2026-08-09 14:34:28 -04:00
pics Inital Commit 2026-07-16 12:36:14 -04:00
src style: fix rustfmt formatting 2026-08-10 08:41:37 -04:00
ui fix: cleanup 2026-08-09 14:34:28 -04:00
.env.example fix: cleanup 2026-08-09 14:34:28 -04:00
.gitignore Inital Commit 2026-07-16 12:36:14 -04:00
Cargo.lock Inital Commit 2026-07-16 12:36:14 -04:00
Cargo.toml fix: cleanup 2026-08-09 14:34:28 -04:00
dev.sh Inital Commit 2026-07-16 12:36:14 -04:00
docker-compose.dev.yml Inital Commit 2026-07-16 12:36:14 -04:00
docker-compose.yml fix: cleanup 2026-08-09 14:34:28 -04:00
Dockerfile Inital Commit 2026-07-16 12:36:14 -04:00
entrypoint.sh Inital Commit 2026-07-16 12:36:14 -04:00
README.md fix: cleanup 2026-08-09 14:34:28 -04:00

Mercury

A high-performance, monolithic Rust API with a dynamic CRUD engine, query registry cache, JWT bitmask permissions, and a Vue 3 admin frontend.

Login Permissions

Quick Start

cp .env.example .env          # set JWT_SECRET
docker compose up --build

API: http://localhost:3000/api
Admin UI: http://localhost:3000
Default credentials: admin / admin


API Contract

Authentication

POST /auth/login
Body: { "username": "...", "password": "..." }
Returns: { "token": "<JWT>" }

All admin routes require Authorization: Bearer <token>.


CRUD — Dynamic Table Access

Requests are mapped to the named PostgreSQL table. The SQL is generated, cached, and executed automatically.

GET    /api/{table}              List all rows (supports ?col=val filters)
GET    /api/{table}/{id}         Get row by id
POST   /api/{table}              Insert row (JSON body)
PUT    /api/{table}/{id}         Update row by id (JSON body)
DELETE /api/{table}/{id}         Delete row by id

Notes:

  • users and permissions tables are blacklisted from public CRUD — use the admin suite.
  • Filters are ANDed together: GET /api/orders?status=open&priority=high

Admin — Query Registry

Requires JWT with ADMIN_QUERY permission (bit 8).

GET    /admin/queries                          List all registered queries
POST   /admin/queries                          Register a raw SQL template
GET    /admin/queries/{identifier}             Get query by slug
PUT    /admin/queries/{identifier}             Update SQL template or description
DELETE /admin/queries/{identifier}             Remove query (evicts from cache)
GET    /admin/queries/{identifier}/execute     Execute query with ?param=val bindings

SQL templates use :param_name placeholders:

SELECT * FROM orders WHERE user_id = :user_id AND status = :status

Admin — Cache

Requires JWT with ADMIN_CACHE permission (bit 16).

GET    /admin/cache/stats    Cache size, hit count, miss count
DELETE /admin/cache          Flush entire cache

Admin — Users

Requires JWT with SUPER_ADMIN permission (bit 32).

GET    /admin/users                                   List users
POST   /admin/users                                   Create user
GET    /admin/users/{id}                              Get user
PUT    /admin/users/{id}                              Update user
DELETE /admin/users/{id}                              Delete user
POST   /admin/users/{id}/permissions/grant/{bit}      OR bit into permissions mask
DELETE /admin/users/{id}/permissions/revoke/{bit}     AND NOT bit from permissions mask

Admin — Permissions

Requires JWT with SUPER_ADMIN permission (bit 32).

GET    /admin/permissions          List permission definitions
POST   /admin/permissions          Create custom permission (auto-assigns next bit)
PUT    /admin/permissions/{id}     Update name/description
DELETE /admin/permissions/{id}     Remove permission

Admin — Route Blacklist

Requires JWT with SUPER_ADMIN permission (bit 32). Changes take effect immediately in memory.

GET    /admin/blacklist          List all entries
POST   /admin/blacklist          Add glob pattern
PUT    /admin/blacklist/{id}     Update entry (set active: false to disable)
DELETE /admin/blacklist/{id}     Remove entry

Pattern syntax: * matches one path segment, ** matches many.
Example: /api/sensitive/** blocks all methods under that path.


Permission Bitmask

Name Bit Value
READ 0 1
WRITE 1 2
DELETE 2 4
ADMIN_QUERY 3 8
ADMIN_CACHE 4 16
SUPER_ADMIN 5 32

Custom permissions are added via the admin suite and assigned the next available power-of-2 bit. Masks support up to 128 bits (u128).


Configuration

Variable Default Description
DATABASE_URL required PostgreSQL connection string
JWT_SECRET required HMAC-HS256 signing secret
JWT_EXPIRY_SECS 3600 Token lifetime in seconds
CACHE_MAX_CAPACITY 10000 Max query templates in memory
CACHE_IDLE_TIMEOUT_SECS 300 Evict after N seconds idle
CACHE_SWEEP_INTERVAL_SECS 60 Sweep interval for eviction task
DISABLE_AUTH false Dev only. When true, bypasses all authentication/permission checks — every request is treated as a super-admin and the admin UI skips login. Never enable in production.

Development

# API only (requires local Postgres)
cargo run

# UI dev server (proxies to local API)
cd ui && npm install && npm run dev

# Full stack
docker compose up --build

Stack

  • API: Rust, Axum, SQLx, PostgreSQL, DashMap, jsonwebtoken, bcrypt
  • Frontend: Vue 3, Vite, @nychthemeron/library (dark mode default)
  • Infra: Docker multi-stage build, docker compose