docs: aggiungi README, PRD, progress e .gitignore con esclusione segreti

This commit is contained in:
Luca Sacchi Ricciardi
2026-04-24 13:06:36 +02:00
parent 29078c9db6
commit 96441e5e10
4 changed files with 769 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
# Segreti e configurazione locale
.env
connessione.md
# Python
__pycache__/
*.py[cod]
*.pyo
*.pyd
.Python
*.egg-info/
dist/
build/
.eggs/
*.egg
# Virtualenv
venv/
.venv/
env/
# Docker
.dockerignore
# OS
.DS_Store
Thumbs.db
# IDE
.idea/
.vscode/
*.swp
+130
View File
@@ -0,0 +1,130 @@
# Supabase Pinger
Tool Python dockerizzato pensato per mantenere "attivo" un database Supabase in free tier, evitando che venga spento e parcheggiato per inattivita'.
L'idea e' semplice: il container resta in esecuzione fino a quando non viene fermato esplicitamente e, a intervalli regolari, esegue un'operazione verso il database Supabase per generare attivita' sufficiente a non far decadere l'istanza.
## Obiettivo
I progetti Supabase in free tier possono diventare temporaneamente inaccessibili se rimangono inattivi troppo a lungo. Questo progetto serve a:
- mantenere raggiungibile il database nel tempo;
- centralizzare la configurazione in un file `.env`;
- fornire anche un file `.env.example` come modello;
- girare in un container Docker sempre attivo, finche' non viene arrestato manualmente.
## Come funziona
Il servizio viene eseguito all'interno di un container Docker e resta attivo in modo continuativo. A ogni ciclo:
1. legge la configurazione dal file `.env`;
2. apre una connessione al database Supabase/PostgreSQL;
3. esegue una query o un'operazione leggera di keep-alive;
4. attende l'intervallo configurato;
5. ripete il processo fino allo stop del container.
## Configurazione
La configurazione deve essere persistita in un file `.env`, non hardcoded nel codice o nel Dockerfile.
E' consigliato mantenere nel repository anche un file `.env.example` con le sole chiavi, senza valori reali, per documentare le variabili richieste.
### Esempio di `.env.example`
```env
SUPABASE_DB_HOST=
SUPABASE_DB_PORT=5432
SUPABASE_DB_NAME=
SUPABASE_DB_USER=
SUPABASE_DB_PASSWORD=
PING_INTERVAL_MINUTES=30
PING_QUERY=SELECT 1;
TZ=Europe/Rome
```
### Significato delle variabili
- `SUPABASE_DB_HOST`: hostname del database Supabase.
- `SUPABASE_DB_PORT`: porta del database PostgreSQL, normalmente `5432`.
- `SUPABASE_DB_NAME`: nome del database.
- `SUPABASE_DB_USER`: utente di connessione.
- `SUPABASE_DB_PASSWORD`: password di connessione.
- `PING_INTERVAL_MINUTES`: intervallo tra un keep-alive e il successivo.
- `PING_QUERY`: query leggera da eseguire per generare attivita'.
- `TZ`: timezone del container per logging e scheduling coerenti.
## Docker
Il container deve rimanere in esecuzione continua. In pratica, il processo Python non deve terminare dopo il primo ping, ma restare in loop fino a interruzione esplicita.
### Build
```bash
docker build -t supabase-pinger .
```
### Avvio con file `.env`
```bash
docker run -d \
--name supabase-pinger \
--env-file .env \
--restart unless-stopped \
supabase-pinger
```
L'opzione `--restart unless-stopped` e' la piu' adatta a questo caso: il container viene mantenuto attivo e riparte automaticamente dopo reboot o crash, ma si ferma se viene arrestato intenzionalmente.
### Arresto
```bash
docker stop supabase-pinger
```
## Esempio con Docker Compose
```yaml
services:
supabase-pinger:
build: .
container_name: supabase-pinger
env_file:
- .env
restart: unless-stopped
```
Avvio:
```bash
docker compose up -d
```
Stop:
```bash
docker compose down
```
## Struttura minima attesa del progetto
```text
.
|-- .env
|-- .env.example
|-- Dockerfile
|-- requirements.txt
|-- app.py
`-- README.md
```
## Note operative
- Non committare mai il file `.env` con credenziali reali.
- Committa solo `.env.example` con valori vuoti o fittizi.
- Usa query di keep-alive molto leggere, ad esempio `SELECT 1;`.
- Mantieni intervalli ragionevoli: troppo frequenti sono inutili, troppo lunghi rischiano di non prevenire il parcheggio del database.
- Se il progetto viene eseguito su un host sempre acceso, Docker con policy `unless-stopped` e' sufficiente per il requisito di esecuzione continua.
## Scopo del repository
Questo repository ospita un servizio minimale e operativo, pensato per un solo compito: impedire che un database Supabase free tier diventi temporaneamente non disponibile per inattivita'.
+340
View File
@@ -0,0 +1,340 @@
# PRD: Supabase Auto-Shutdown Prevention System
## 1. Executive Summary
Questo progetto definisce un servizio Python dockerizzato con il solo scopo di mantenere attivo un database Supabase in free tier, prevenendo la sospensione automatica dovuta a lunghi periodi di inattivita'.
La soluzione prevista e' un processo long-running eseguito in un container Docker che:
- carica la configurazione da file `.env`;
- si connette al database Supabase/PostgreSQL;
- esegue periodicamente una query leggera di keep-alive;
- registra esito e tempi di esecuzione;
- continua a funzionare finche' il container non viene fermato.
## 2. Problema
Nel piano gratuito di Supabase, un progetto puo' essere sospeso o parcheggiato dopo un periodo prolungato di inattivita'. Quando questo avviene:
- il database puo' diventare temporaneamente non raggiungibile;
- l'applicazione che lo usa puo' apparire guasta o lenta al primo accesso;
- l'esperienza di sviluppo, demo o staging peggiora sensibilmente.
Il problema da risolvere non e' l'alta disponibilita' in senso enterprise, ma la continuita' operativa minima per ambienti personali, prototipi, demo e staging leggeri.
## 3. Obiettivo di Prodotto
Garantire che Supabase rilevi attivita' reale sul database almeno una volta entro ogni finestra di 7 giorni, con un margine di sicurezza sufficiente a evitare la sospensione automatica nella pratica.
## 4. Obiettivi Specifici
- Eseguire automaticamente attivita' valida sul database senza intervento umano.
- Mantenere il processo attivo in modo continuativo tramite container Docker.
- Consentire configurazione interamente tramite `.env`.
- Rendere il comportamento osservabile con log chiari di successo e fallimento.
- Mantenere la soluzione minimale, portabile e facile da eseguire su qualsiasi host con Docker.
## 5. Non-Obiettivi
- Non e' un sistema di backup, replica o disaster recovery.
- Non e' un sistema di monitoraggio completo del database.
- Non deve gestire provisioning, creazione schema o migrazioni Supabase.
- Non deve introdurre traffico aggressivo o pattern assimilabili ad abuso del free tier.
- Non deve dipendere obbligatoriamente da GitHub Actions, servizi cron esterni o infrastrutture cloud aggiuntive.
## 6. Pubblico di Riferimento
- Sviluppatori individuali che usano Supabase free tier per prototipi.
- Team piccoli che usano Supabase come ambiente di staging leggero.
- Progetti personali o dimostrativi che devono restare pronti all'uso senza accessi frequenti.
## 7. User Stories
- Come sviluppatore, voglio che il mio database Supabase resti raggiungibile anche se non uso l'app per giorni.
- Come maintainer, voglio configurare il servizio con un semplice file `.env` senza modificare il codice.
- Come operatore, voglio eseguire il servizio in Docker e lasciarlo attivo finche' non decido di fermarlo.
- Come utente tecnico, voglio vedere nei log se il keep-alive sta funzionando oppure no.
## 8. Scope della Soluzione
La soluzione target per questo repository e':
- applicazione Python;
- esecuzione in container Docker;
- loop applicativo continuo;
- connessione diretta a PostgreSQL/Supabase;
- query di keep-alive configurabile;
- configurazione tramite file `.env` e `.env.example`.
Alternative come GitHub Actions, `pg_cron` o cron esterni restano opzioni comparabili, ma non rappresentano la soluzione primaria di questo repository.
## 9. Assunzioni di Prodotto
- Supabase considera una query SQL valida come attivita' sufficiente a evitare la sospensione per inattivita'.
- Un'attivita' 2 o 3 volte a settimana offre margine adeguato rispetto alla finestra di 7 giorni.
- L'host che esegue Docker resta normalmente acceso o comunque ripristina il container tramite restart policy.
- L'utente dispone delle credenziali di accesso al database Supabase.
## 10. Requisiti Funzionali
### RF1. Caricamento configurazione da `.env`
Il sistema deve caricare tutti i parametri necessari da file `.env`.
Parametri minimi richiesti:
- `SUPABASE_DB_HOST`
- `SUPABASE_DB_PORT`
- `SUPABASE_DB_NAME`
- `SUPABASE_DB_USER`
- `SUPABASE_DB_PASSWORD`
- `PING_INTERVAL_MINUTES`
- `PING_QUERY`
- `TZ`
### RF2. Presenza di `.env.example`
Il repository deve includere un file `.env.example` che documenti tutte le variabili necessarie senza contenere segreti reali.
### RF3. Connessione al database Supabase
Il sistema deve aprire una connessione verso il database PostgreSQL di Supabase usando le credenziali fornite.
### RF4. Esecuzione di attivita' reale
Il sistema deve eseguire un'operazione SQL reale che venga contabilizzata come attivita' dal database.
Comportamento previsto:
- default consigliato: query leggera come `SELECT 1;`;
- opzione futura: query custom o update su tabella tecnica di log;
- l'operazione deve essere configurabile tramite environment variable.
### RF5. Esecuzione periodica automatizzata
Il processo deve essere automatico e ciclico, senza intervento umano manuale dopo l'avvio del container.
Vincoli di frequenza:
- il sistema deve supportare un intervallo configurabile;
- l'intervallo operativo raccomandato deve garantire almeno 2 esecuzioni a settimana;
- il default di prodotto consigliato e' tra 72 e 96 ore;
- non devono essere usati intervalli inutilmente aggressivi come default.
### RF6. Processo long-running
Il processo Python non deve terminare dopo un singolo ping riuscito o fallito. Deve restare attivo e continuare a schedulare i cicli successivi finche' il container non viene fermato.
### RF7. Logging di esecuzione
Il sistema deve emettere log almeno per:
- avvio del servizio;
- lettura configurazione valida;
- tentativo di connessione;
- esecuzione query;
- successo dell'operazione;
- errore dell'operazione;
- attesa del prossimo ciclo.
### RF8. Gestione errori resiliente
In caso di fallimento di connessione o query, il processo non deve terminare immediatamente. Deve:
- loggare l'errore;
- chiudere in sicurezza eventuali risorse aperte;
- attendere il prossimo intervallo o un retry definito;
- riprovare automaticamente.
### RF9. Arresto controllato
Il processo deve supportare lo stop del container in modo ordinato, chiudendo connessioni e terminando il loop senza lasciare risorse sporche.
### RF10. Modalita' di esecuzione containerizzata
Il sistema deve essere eseguibile tramite Docker con restart policy adatta a mantenerlo operativo finche' non viene fermato esplicitamente.
Policy target:
- `unless-stopped` come impostazione raccomandata.
### RF11. Notifica di errore opzionale
La notifica all'utente in caso di fallimento e' opzionale in prima versione.
Per la V1, il requisito minimo e' il logging locale/STDOUT. In versioni successive, potranno essere introdotte integrazioni opzionali come email, webhook o Telegram.
## 11. Requisiti Non Funzionali
### RNF1. Semplicita'
La soluzione deve restare piccola, leggibile e con poche dipendenze.
### RNF2. Portabilita'
Il servizio deve poter girare su qualsiasi ambiente che supporti Docker: VPS, mini PC, NAS, server domestico o macchina di sviluppo.
### RNF3. Sicurezza
- Nessun segreto hardcoded nel codice.
- Nessun segreto committato nel repository.
- Tutti i segreti devono essere passati tramite `.env` o strumenti equivalenti.
### RNF4. Osservabilita' minima
I log devono essere sufficienti a diagnosticare se il job di keep-alive ha funzionato senza richiedere debugging interattivo.
### RNF5. Basso impatto
Il sistema deve usare query leggere e frequenza moderata per minimizzare costo computazionale e rischio di comportamento eccessivo verso il free tier.
## 12. Configurazione di Prodotto
### Variabili richieste
```env
SUPABASE_DB_HOST=
SUPABASE_DB_PORT=5432
SUPABASE_DB_NAME=
SUPABASE_DB_USER=
SUPABASE_DB_PASSWORD=
PING_INTERVAL_MINUTES=4320
PING_QUERY=SELECT 1;
TZ=Europe/Rome
```
### Note sulla configurazione
- `PING_INTERVAL_MINUTES=4320` equivale a 72 ore.
- Il valore effettivo puo' essere modificato, ma il default raccomandato deve restare prudente rispetto ai termini d'uso e al limite dei 7 giorni.
- Il file `.env.example` deve contenere le stesse chiavi, ma senza valori sensibili.
## 13. Flusso Operativo Atteso
1. L'utente crea il file `.env` partendo da `.env.example`.
2. L'utente avvia il container con `--env-file .env`.
3. Il processo Python parte e valida la configurazione.
4. Il servizio apre una connessione al database Supabase.
5. Il servizio esegue la query di keep-alive.
6. Il servizio registra esito e timestamp.
7. Il servizio attende fino al ciclo successivo.
8. Il loop continua finche' il container non viene fermato.
## 14. Architettura Logica
Componenti logici previsti:
- loader configurazione: valida e carica le variabili ambiente;
- scheduler loop: gestisce l'attesa fra i cicli;
- database client: apre connessione ed esegue la query;
- logger: stampa esiti ed errori su STDOUT/STDERR;
- runtime Docker: mantiene il processo eseguito come container persistente.
## 15. Soluzioni Tecniche Valutate
| Soluzione | Descrizione | Pro | Contro | Esito |
| --- | --- | --- | --- | --- |
| Python + Docker long-running | Processo residente che esegue query periodiche via connessione DB diretta. | Indipendente da servizi terzi, semplice da portare ovunque, coerente con il repository. | Richiede un host sempre acceso. | Scelta primaria |
| GitHub Actions | Workflow schedulato con chiamata HTTP o query indiretta. | Facile da configurare, economico. | Dipende da GitHub e da scheduling esterno. | Alternativa |
| pg_cron | Job schedulati internamente al database. | Soluzione interna a Postgres. | Affidabilita' e disponibilita' non sempre ideali su free tier. | Non primaria |
| External Cron | Servizi terzi che attivano un endpoint o una function. | Molto affidabile. | Dipendenza esterna aggiuntiva. | Alternativa |
## 16. Vincoli e Rischi
### Vincoli
- Uso del piano gratuito Supabase.
- Necessita' di rispettare termini e limiti del servizio.
- Presenza di un host Docker sempre disponibile o quasi sempre disponibile.
### Rischi
- Una frequenza troppo alta potrebbe essere interpretata come utilizzo artificiale o eccessivo.
- Una frequenza troppo bassa potrebbe non prevenire il parking.
- Credenziali esposte in repository o log rappresentano rischio di sicurezza.
- Cambiamenti futuri nelle policy Supabase potrebbero ridurre l'efficacia della soluzione.
### Mitigazioni
- Default conservativo a poche esecuzioni settimanali.
- Query molto leggere.
- Segreti solo in `.env`.
- Logging senza stampa delle credenziali.
## 17. Requisiti di Sicurezza
- Il sistema non deve stampare password o DSN completi nei log.
- Il file `.env` deve essere escluso dal versionamento.
- Il file `.env.example` deve essere versionato come riferimento.
- Eventuali errori devono essere sanitizzati per evitare leak accidentali di segreti.
## 18. Requisiti di Deployment
- Il progetto deve essere buildabile tramite `docker build`.
- Il progetto deve poter essere eseguito con `docker run --env-file .env`.
- Deve essere compatibile anche con `docker compose`.
- La restart policy raccomandata deve essere `unless-stopped`.
## 19. Metriche di Successo
- Il database Supabase non entra in stato paused durante normali periodi di mancato utilizzo dell'applicazione.
- Ogni esecuzione pianificata produce un log di successo oppure un log di errore esplicito.
- Il container resta in esecuzione senza terminare dopo il primo ciclo.
- La configurazione puo' essere modificata senza cambiare il codice applicativo.
## 20. Acceptance Criteria
### AC1. Configurazione
- Esiste un file `.env.example` completo con tutte le variabili richieste.
- Il servizio fallisce in modo chiaro se manca una variabile obbligatoria.
### AC2. Keep-alive riuscito
- A container avviato, il servizio esegue con successo almeno una query di keep-alive verso Supabase.
- I log mostrano chiaramente l'avvenuta esecuzione con timestamp.
### AC3. Continuita' del processo
- Dopo una query riuscita, il processo non termina.
- Il container rimane in stato attivo fino a stop manuale o errore esterno del runtime.
### AC4. Tolleranza ai fallimenti
- Se una query fallisce, il processo logga l'errore e continua a riprovare nei cicli successivi.
### AC5. Sicurezza di configurazione
- Nessuna credenziale reale compare nel repository tracciato.
- Le istruzioni d'uso spiegano chiaramente la differenza tra `.env` e `.env.example`.
### AC6. Coerenza con il free tier
- Il sistema consente una schedulazione moderata, raccomandata su 2-3 esecuzioni a settimana.
## 21. Roadmap Evolutiva
### V1
- Connessione diretta al database.
- Query di keep-alive configurabile.
- Loop continuo.
- Logging base.
- Container Docker con restart policy consigliata.
### V1.1
- Retry con backoff configurabile.
- Miglioramento dei messaggi di health e startup.
- Distinzione chiara tra errori di configurazione e di rete.
### V2
- Notifiche opzionali su webhook o email.
- Healthcheck Docker dedicato.
- Modalita' dry-run o startup check.
- Supporto a metriche esportabili.
## 22. Decisione di Prodotto
La soluzione da implementare in questo repository e' un servizio Python sempre attivo, eseguito in Docker, configurato via `.env`, con query di keep-alive leggera e frequenza moderata. Questa scelta massimizza semplicita', portabilita' e controllo operativo, riducendo dipendenze esterne rispetto alle alternative basate su scheduler di terze parti.
+266
View File
@@ -0,0 +1,266 @@
# Progress
## Stato Attuale
Data riferimento: 2026-04-24
Il progetto ha oggi:
- un README iniziale con obiettivo e modalita' d'uso target;
- un PRD esteso con requisiti funzionali e non funzionali;
- note di connessione tecniche da trattare con cautela;
- nessuna implementazione applicativa ancora presente.
## Obiettivo di Sviluppo
Realizzare un servizio Python dockerizzato che mantenga attivo un database Supabase free tier tramite query periodiche di keep-alive, con configurazione via `.env`, processo long-running e documentazione operativa essenziale.
## Principi di Esecuzione
- tenere il perimetro minimale e focalizzato;
- evitare dipendenze inutili;
- non esporre segreti nel repository;
- validare ogni fase con una verifica eseguibile;
- rilasciare una V1 utilizzabile prima di aggiungere feature opzionali.
## Roadmap di Sviluppo
### Fase 0. Messa in sicurezza del repository
Obiettivo:
Ridurre subito il rischio di esposizione credenziali e allineare il repository a una baseline di sicurezza minima.
Attivita':
- verificare quali file contengono credenziali o connection string reali;
- rimuovere i segreti dal contenuto versionato e sostituirli con placeholder;
- assicurare che `.env` sia ignorato da git;
- mantenere `.env.example` come unico riferimento versionabile;
- rivedere la documentazione per evitare esempi che inducano a committare segreti.
Deliverable:
- repository senza credenziali reali in chiaro;
- `.gitignore` corretto;
- linee guida documentate per la gestione dei segreti.
Verifica:
- ricerca testuale nel repository per individuare host, password, key e DSN;
- conferma che `.env` non sia tracciato;
- review manuale dei file documentali.
Stato:
- da fare
### Fase 1. Bootstrap del progetto Python
Obiettivo:
Creare la struttura minima eseguibile del servizio.
Attivita':
- creare `app.py` o entrypoint equivalente;
- definire `requirements.txt` con dipendenze minime;
- scegliere libreria di connessione PostgreSQL adatta al caso d'uso;
- predisporre struttura semplice senza over-engineering;
- definire convenzioni di logging e gestione errori.
Deliverable:
- scheletro applicativo Python avviabile;
- dipendenze dichiarate;
- entrypoint unico chiaro.
Verifica:
- avvio locale del processo Python;
- import delle dipendenze senza errori;
- controllo sintattico del file principale.
Stato:
- da fare
### Fase 2. Configurazione e validazione environment
Obiettivo:
Caricare e validare in modo affidabile tutte le variabili richieste dal PRD.
Attivita':
- implementare lettura delle env dal runtime;
- validare presenza di host, porta, database, user, password, query e intervallo;
- gestire messaggi di errore chiari per configurazioni incomplete;
- creare `.env.example` coerente con README e PRD;
- definire default prudenti solo dove sensato.
Deliverable:
- loader di configurazione affidabile;
- `.env.example` pronto all'uso;
- error handling per startup configuration.
Verifica:
- avvio con configurazione completa;
- fallimento atteso con env mancanti;
- coerenza tra `.env.example`, README e PRD.
Stato:
- da fare
### Fase 3. Connessione a Supabase/PostgreSQL
Obiettivo:
Stabilire la connessione al database e isolare il layer di accesso.
Attivita':
- implementare apertura connessione al database;
- eseguire una query di test controllata;
- gestire timeout, eccezioni e chiusura connessione;
- evitare logging di segreti o DSN completi;
- preparare una funzione dedicata al keep-alive.
Deliverable:
- client database funzionante;
- funzione di ping riusabile;
- logging tecnico minimo ma utile.
Verifica:
- esecuzione riuscita di `SELECT 1;`;
- simulazione di errore credenziali o host non raggiungibile;
- log chiari e privi di segreti.
Stato:
- da fare
### Fase 4. Loop di keep-alive e resilienza runtime
Obiettivo:
Trasformare il ping singolo in un servizio continuo e resiliente.
Attivita':
- implementare loop infinito controllato;
- usare `PING_INTERVAL_MINUTES` come scheduling applicativo;
- loggare avvio ciclo, esito e prossima esecuzione;
- mantenere il processo attivo anche in caso di errore operativo;
- gestire terminazione ordinata su stop del container.
Deliverable:
- runtime long-running stabile;
- gestione errori non distruttiva;
- shutdown ordinato.
Verifica:
- il processo resta attivo dopo un ping riuscito;
- il processo resta attivo dopo un ping fallito;
- stop manuale con chiusura ordinata.
Stato:
- da fare
### Fase 5. Containerizzazione Docker
Obiettivo:
Rendere il servizio distribuibile e persistente tramite Docker.
Attivita':
- scrivere `Dockerfile` minimale;
- configurare comando di avvio del processo Python;
- verificare passaggio variabili con `--env-file .env`;
- definire uso raccomandato di `--restart unless-stopped`;
- aggiungere eventuale supporto `docker compose`.
Deliverable:
- immagine Docker buildabile;
- esecuzione container funzionante;
- esempio compose essenziale.
Verifica:
- `docker build` completato con successo;
- container avviato e logs leggibili;
- persistenza del processo finche' non viene fermato.
Stato:
- da fare
### Fase 6. Documentazione operativa e rifinitura V1
Obiettivo:
Concludere la prima versione con documentazione e uso coerente.
Attivita':
- allineare README, PRD, `.env.example` e struttura reale del repository;
- documentare build, run, stop e troubleshooting base;
- rimuovere ambiguita' su intervallo di ping raccomandato;
- chiarire i limiti del tool rispetto ai termini del free tier;
- aggiungere checklist rapida di avvio.
Deliverable:
- documentazione finale coerente con il codice;
- repository pronto per primo utilizzo;
- baseline V1 chiusa.
Verifica:
- review incrociata documentazione vs file reali;
- onboarding test: un utente tecnico deve riuscire ad avviare il servizio dai documenti;
- lint markdown senza errori.
Stato:
- da fare
## Backlog Post-V1
- retry con backoff configurabile;
- healthcheck Docker dedicato;
- endpoint o comando di self-test;
- notifiche opzionali via webhook o Telegram;
- metriche esportabili;
- supporto a query alternativa di keep-alive con tabella di log.
## Ordine di Esecuzione Consigliato
1. Fase 0
2. Fase 1
3. Fase 2
4. Fase 3
5. Fase 4
6. Fase 5
7. Fase 6
## Definizione di Done per la V1
La V1 e' completata quando:
- il repository non contiene segreti reali;
- esiste `.env.example` completo;
- il servizio Python si avvia con configurazione valida;
- il servizio esegue la query di keep-alive verso Supabase;
- il processo resta attivo nel tempo;
- il container Docker funziona con `--env-file .env` e `--restart unless-stopped`;
- la documentazione corrisponde ai file realmente presenti nel repository.
## Prossima Attivita' Operativa
Task raccomandato immediato:
- eseguire la Fase 0 e poi creare lo scheletro minimo della V1 con `app.py`, `requirements.txt`, `.env.example` e `Dockerfile`.