- app/tx/reconcile.py called the payout retry "a future payout-retry routine — still an open gap". It shipped as B-26: clearing payout_txid leaves the round in exactly the state _retry_payout_if_due picks up, so an abandoned payout rebuilds itself and the log line next to it is an alert, not the recovery path. Reading it the old way, an operator would go hand-fix a round the scheduler was already retrying. - app/db/base.py sized the SQLite busy timeout against "five concurrent background tasks" and then listed only the non-listener ones; the lifespan starts six. - The third item (app/auth/routes.py citing B-31 where it meant B-33) was already correct in the tree; the test pins it so it stays that way. tests/unit/test_code_comments.py derives the task count from the lifespan's own create_task calls rather than restating it, so the comment fails the next time a task is added or removed instead of quietly going stale again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
69 lines
3.2 KiB
Markdown
69 lines
3.2 KiB
Markdown
# PLM Lottery
|
|
|
|
A periodic-round lottery system built on PLM, a Bitcoin-like coin (mainnet).
|
|
Each user gets a dedicated server-derived P2WPKH address; they deposit PLM to
|
|
that address, place a fixed-cost bet to enter the current round, and when the
|
|
round closes a winner is drawn who receives 70% of the prize pool (the
|
|
remaining 30% goes to fees).
|
|
|
|
This is a **custodial** system: private keys are generated and held
|
|
server-side, encrypted at rest. See [CLAUDE.md](CLAUDE.md) for the full
|
|
architecture, domain decisions, and known gaps before treating this as
|
|
production-ready.
|
|
|
|
## Quick start
|
|
|
|
The server always runs via Docker (app + Caddy reverse proxy with automatic
|
|
TLS) — in dev and production alike, with only `SITE_ADDRESS` differing
|
|
between the two. There's no supported way to run `uvicorn` directly; the
|
|
venv is only for local tooling (tests, Alembic migrations, the one-time key
|
|
scripts) — see [CLAUDE.md](CLAUDE.md#commands).
|
|
|
|
```bash
|
|
cp .env.example .env # then fill in the generated secrets, see docs/setup.md
|
|
mkdir -p data/db data/keys data/logs
|
|
docker compose run --rm app python scripts/generate_master_key.py
|
|
docker compose up -d --build
|
|
```
|
|
|
|
Open `https://localhost/` for the test UI, `https://localhost/admin` for the
|
|
admin dashboard (a self-signed-certificate warning on first visit is
|
|
expected in dev — accept it, or use `curl -k`). The interactive API docs at
|
|
`/docs` are disabled by default (they'd otherwise expose the whole API
|
|
surface, admin endpoints included) — set `ENABLE_API_DOCS=true` in `.env` to
|
|
enable them.
|
|
|
|
See [docs/setup.md](docs/setup.md) and
|
|
[docs/running-the-server.md](docs/running-the-server.md) for the full
|
|
walkthrough (secrets, master key generation, production TLS with a real
|
|
domain).
|
|
|
|
## Documentation
|
|
|
|
- [CLAUDE.md](CLAUDE.md) — architecture, commands, domain decisions, known gaps (for anyone/anything working on the code)
|
|
- [flowchart/](flowchart/) — the source-of-truth flow diagrams the implementation follows node-by-node: [platform-overview.mmd](flowchart/platform-overview.mmd) (the 5-phase flow) and [round-lifecycle.mmd](flowchart/round-lifecycle.mmd) (the round/draw lifecycle)
|
|
- [docs/setup.md](docs/setup.md) — one-time setup (secrets, master key, migrations)
|
|
- [docs/running-the-server.md](docs/running-the-server.md) — how to launch it with Docker+Caddy (dev vs. production TLS)
|
|
- [docs/guida-utente.md](docs/guida-utente.md) — end-user guide to the test UI (Italian)
|
|
- [docs/guida-admin.md](docs/guida-admin.md) — admin dashboard guide (Italian)
|
|
|
|
## Tech stack
|
|
|
|
Python (FastAPI, SQLAlchemy async + Alembic, Argon2 + JWT auth), Electrum
|
|
protocol for PLM network access (no full node), Docker + Caddy for
|
|
deployment. See [CLAUDE.md](CLAUDE.md#tech-stack) for the complete list
|
|
and the reasoning behind each choice.
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
python -m pytest # all tests
|
|
python -m pytest tests/unit/test_hd.py # one file
|
|
```
|
|
|
|
349 unit tests cover HD derivation, PSBT building, the Electrum client, bets,
|
|
deposits, withdrawals, the round/draw engine, RBF fee-bumping, admin config,
|
|
the pending-inclusive balance calculation, and the SSE push channel. No
|
|
automated integration tests against a live Electrum connection — mainnet
|
|
verification so far has been manual (see CLAUDE.md's "Project status").
|