The two Mermaid diagrams under flowchart/ described the intended flow but had drifted from the code and carried no link back to it. docs/ now holds the specification instead: 15 Italian documents (flows, architecture, data model, API, security, audit log, operations, decisions and limits, bug history) with 472 numbered requirements, each pointing at the function that implements it and the test that covers it. docs/processo-di-modifica.md defines the ID convention and the spec -> code -> test change workflow, and CLAUDE.md now names docs/ as authoritative. Writing the spec from the code also corrected stale claims in CLAUDE.md (B-41's get_history check, BUGS.md still tracking B-71/B-72, Cache-Control scope, the error contract's bare-string exceptions) and in the operator guides (payouts do retry, only `drawing` fails to resume, rounds do not open without fee_address). The B-70 doc test now pins the prose in docs/scommesse-e-prelievi.md instead of the deleted diagram. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
132 lines
6.3 KiB
Markdown
132 lines
6.3 KiB
Markdown
# Setup
|
|
|
|
Passaggi da eseguire una tantum per preparare un'istanza di PLM Lottery, prima di
|
|
poterla avviare (in locale o via Docker). Per come avviarla poi ogni volta, vedi
|
|
[running-the-server.md](running-the-server.md).
|
|
|
|
## 1. Prerequisiti
|
|
|
|
- Python 3.12+ (serve solo per il workflow locale/venv — puoi saltarlo se usi solo Docker)
|
|
- Docker + Docker Compose (serve solo per il workflow a container)
|
|
- Un server Electrum raggiungibile per la rete PLM. Il server di bootstrap per lo
|
|
sviluppo è `santantonio.sytes.net:50002` (SSL) — va bene per i test, ma in
|
|
produzione conviene usarne uno di cui ci si fida o gestirne uno proprio.
|
|
- **Consigliato in produzione: più di un server.** Tutto passa da questa singola
|
|
connessione (accredito depositi, invio transazioni, conferme, altezza della
|
|
catena su cui si basa l'estrazione), quindi un solo server è il principale
|
|
punto di rottura della piattaforma. Elencane altri in
|
|
`ELECTRUM_FALLBACK_SERVERS` (vedi sotto): l'app li prova a rotazione, così un
|
|
server irraggiungibile costa un solo tentativo di riconnessione invece di un
|
|
disservizio.
|
|
|
|
## 2. Creare il file `.env`
|
|
|
|
Copia `.env.example` in `.env` e compila i segreti. Ogni valore sotto viene
|
|
generato una volta e non cambia più (ruotarlo invalida sessioni/dati cifrati
|
|
esistenti):
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
| Variabile | Scopo | Come generarla |
|
|
|---|---|---|
|
|
| `XPRV_ENCRYPTION_KEY` | Chiave simmetrica che cifra a riposo la master xprv del server. **Perdere questa chiave significa perdere per sempre l'accesso ai fondi di tutti gli utenti.** | `python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"` |
|
|
| `JWT_SECRET` | Firma i token di sessione degli utenti. | `python -c "import secrets; print(secrets.token_urlsafe(32))"` |
|
|
| `ADMIN_TOKEN` | Token bearer richiesto sugli endpoint admin (header `X-Admin-Token`). | `python -c "import secrets; print(secrets.token_urlsafe(32))"` |
|
|
|
|
Le chiavi Electrum (`ELECTRUM_HOST`/`PORT`/`USE_SSL`) hanno default sensati in
|
|
`.env.example`. `DATABASE_URL` e `MASTER_KEY_PATH` non sono elencate lì:
|
|
hanno un default in `app/config.py`, e dentro il container vengono comunque
|
|
sovrascritte da `docker-compose.yml` per puntare a `./data/` (elenco completo
|
|
delle variabili in [architettura.md](architettura.md)).
|
|
|
|
`ENABLE_API_DOCS` (default `false`) controlla Swagger/ReDoc/l'OpenAPI JSON grezzo
|
|
su `/docs`, `/redoc` e `/openapi.json`: espongono l'intera superficie dell'API,
|
|
endpoint admin inclusi, quindi restano disattivati a meno di non impostarlo
|
|
esplicitamente a `true` — utile in locale, da evitare in produzione.
|
|
|
|
`ELECTRUM_FALLBACK_SERVERS` elenca i server di riserva, separati da virgola, nel
|
|
formato `host:porta` (TLS, il caso normale) oppure `host:porta:notls`. Esempio:
|
|
|
|
```
|
|
ELECTRUM_FALLBACK_SERVERS=nodo2.example.net:50002,nodo3.example.net:50001:notls
|
|
```
|
|
|
|
Vengono provati a rotazione dopo il primario. Attenzione: un valore scritto male
|
|
**blocca l'avvio** dell'app — è voluto, meglio accorgersene subito che durante il
|
|
disservizio in cui il fallback serve davvero.
|
|
|
|
`JWT_SECRET` e `XPRV_ENCRYPTION_KEY` vengono verificati all'avvio: se sono vuoti
|
|
(o `JWT_SECRET` è più corto di 32 caratteri) il container si rifiuta di partire con
|
|
un errore esplicito, invece di avviarsi e rompersi al primo login. Nota: `.env`
|
|
contiene solo segreti e configurazione di infrastruttura — i parametri di
|
|
business (bet amount, durata round, fee, ecc.) si configurano dal pannello
|
|
admin dopo l'avvio, non qui — vedi [guida-admin.md](guida-admin.md).
|
|
|
|
**Non committare mai `.env`.** È già escluso da `.gitignore`.
|
|
|
|
## 3. Generare la master key
|
|
|
|
Il server deriva l'indirizzo di deposito di ogni utente (e l'indirizzo pool) da
|
|
un'unica master xprv, generata una volta e cifrata a riposo con
|
|
`XPRV_ENCRYPTION_KEY`. Questo passaggio va eseguito esattamente una volta per
|
|
ogni deployment, dopo aver impostato `XPRV_ENCRYPTION_KEY` in `.env`:
|
|
|
|
- **Locale/venv**: `PYTHONPATH=. python scripts/generate_master_key.py`
|
|
- **Docker**: `docker compose run --rm app python scripts/generate_master_key.py`
|
|
|
|
Questo scrive un file cifrato (`MASTER_KEY_PATH`, default `./master.xprv.enc` in
|
|
locale o `./data/keys/master.xprv.enc` con Docker). **Fai il backup di questo
|
|
file insieme a `XPRV_ENCRYPTION_KEY`** — uno dei due da solo è inutile, ma
|
|
perderli entrambi insieme significa perdere i fondi di tutti gli utenti senza
|
|
possibilità di recupero.
|
|
|
|
### Recuperare o portare una xprv esistente
|
|
|
|
Due script, entrambi manuali/una tantum, per lo scenario di disaster recovery
|
|
o per usare una xprv generata altrove (es. offline/air-gapped) invece di
|
|
farla generare al server:
|
|
|
|
- **`scripts/decrypt_master_key.py`**: decifra e stampa a schermo la xprv
|
|
già presente in `MASTER_KEY_PATH` (con fallback automatico su
|
|
`./data/keys/master.xprv.enc` se il path di `.env` non esiste in locale).
|
|
Chiede conferma esplicita prima di stampare.
|
|
- **`scripts/encrypt_master_key.py`**: cifra una xprv esterna e la scrive in
|
|
`MASTER_KEY_PATH` con lo stesso identico schema (Fernet +
|
|
`XPRV_ENCRYPTION_KEY`) usato da `generate_master_key.py`. La xprv va
|
|
incollata con input nascosto (non appare a schermo). Si rifiuta di
|
|
sovrascrivere un file esistente a meno di passare `--overwrite`.
|
|
|
|
Entrambi vanno eseguiti localmente (o dentro il container via
|
|
`docker compose run --rm app ...`), mai esposti da un endpoint API o dal
|
|
pannello admin: chi ottiene questa xprv ottiene il controllo dei fondi di
|
|
tutti gli utenti e del pool.
|
|
|
|
## 4. Installare le dipendenze (solo workflow locale/venv)
|
|
|
|
Salta questo passaggio se usi solo Docker — l'immagine installa le proprie
|
|
dipendenze durante la build.
|
|
|
|
```bash
|
|
python3 -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -e ".[dev]"
|
|
```
|
|
|
|
## 5. Applicare le migrazioni del database
|
|
|
|
- **Locale/venv**: `alembic upgrade head`
|
|
- **Docker**: le migrazioni vengono eseguite automaticamente all'avvio del
|
|
container (vedi il `CMD` del `Dockerfile`) — nessun passaggio manuale.
|
|
|
|
## 6. Impostare l'indirizzo delle fee
|
|
|
|
Prima che si possa aprire il primo round, un admin deve impostare
|
|
`fee_address` tramite il pannello admin o l'API — vedi
|
|
[guida-admin.md](guida-admin.md). Finché non è impostato **nessun round si
|
|
apre**, perché il pagamento non si potrebbe costruire.
|
|
|
|
A questo punto l'istanza è pronta per essere avviata — continua con
|
|
[running-the-server.md](running-the-server.md).
|