Close residual audit P2: 5 MiB recording limit, opportunistic orphan board GC, and remove static/index.html.
2.7 KiB
Stork
Shareable baby-name boards: suggest names, vote, keep origin / meaning / pronunciation in English, Russian, and Hebrew, and optionally record how a name sounds.
Each board has a unique share link (/b/<uid>). Start a board with no password,
add names, share the link. Anyone with the link can edit.
Live read-only demo: stork.levkin.ca demo board.
Quick start (local)
cp .env.example .env # optional STORK_INVITE_TOKEN bootstraps a "Family" board
make install
make test
make run
Open http://127.0.0.1:8094 → Start new board → share /b/….
Visitors open the link and enter a display name.
Features
- Renamable columns (First is fixed;
+adds up to 4; ✕ removes extras) - Votes / ranking per board
- Locale notes (en / ru / he) + voice recordings (re-record overwrites)
- Paper UI at
/ - Optional read-only boards via
STORK_READONLY_BOARD_IDS
API sketch
| Method | Path | Notes |
|---|---|---|
| GET | /api/health |
Liveness |
| POST | /api/boards |
Start board {title} → {id, url, readonly} (rate-limited) |
| GET | /api/boards/{id} |
Public board title + url + readonly |
| GET | /api/resolve?invite= |
Legacy invite → board url |
| POST | /api/session |
{board_id, display_name} → cookies (rate-limited) |
| DELETE | /api/session |
Clear cookies |
| GET | /api/columns |
Columns for session board |
| POST/PATCH/DELETE | /api/columns… |
Add / rename / remove (not first; blocked if readonly) |
| GET/POST | /api/names |
List / add |
| PATCH | /api/names/{id} |
Locale notes |
| POST | /api/names/{id}/vote |
{value: 1|-1|0} |
| POST/GET/DELETE | /api/names/{id}/recording/{lang} |
Voice (magic sniff; max ~5 MiB) |
| DELETE | /api/names/{id} |
Admin header X-Stork-Admin |
Empty unused boards (no names) older than STORK_ORPHAN_BOARD_HOURS (default 48)
are removed when someone creates a new board. Readonly + invite Family boards are
kept.
Scripts
# Seed starter names onto a board (uses session cookies)
make seed STORK_BOARD_ID=b_…
# Demo set (Mira / Noa / Lior / Elena / Ezra):
STORK_SEED_FILE=data/demo-names.example.json make seed STORK_BOARD_ID=b_…
# Create an empty board and print share URL
.venv/bin/python scripts/create_board.py
Secrets
- Local: gitignored
.env - Deploy host:
.envnext to compose (never commit)
CI gates
Gitea Actions (.gitea/workflows/ci.yml): ruff and pytest are hard gates
(no || true). Gitleaks on PRs. Bandit is advisory.
Production
Public HTTPS at stork.levkin.ca. Homelab deploy lives in a
separate ansible repo (make deploy-stork).