Files
plm-lottery/docs/setup.md
T
davideandClaude Opus 5.5 61efbb0e37 Replace flowchart/ with a traceable specification in docs/
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>
2026-09-28 12:16:01 +02:00

6.3 KiB

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.

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):

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).

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.

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.

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. 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.