Mercury/README.md
Matthew L McPeak dd700d02ad
All checks were successful
ci / build-ui (push) Successful in 14s
ci / test (push) Successful in 3m50s
ci / publish (push) Successful in 3m9s
Inital Commit
2026-07-16 12:36:14 -04:00

174 lines
4.7 KiB
Markdown

# 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](pics/Mercury-Login.png)
![Permissions](pics/Mercury.png)
## Quick Start
```bash
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:
```sql
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 |
---
## Development
```bash
# 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