341 lines
13 KiB
Markdown
341 lines
13 KiB
Markdown
# 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.
|