# Arquitetura ## Visão geral Aplicação self-hosted de processo único que: 1. importa trackers públicos de fontes externas; 2. normaliza e protege destinos; 3. sonda HTTP(S) e UDP; 4. persiste histórico em SQLite; 5. expõe HTML, TXT e JSON. Não é um tracker BitTorrent, não indexa torrents e não aceita magnets. ## Processo único e Uvicorn O site, a API e o APScheduler rodam no **mesmo processo**. O Uvicorn deve ser iniciado com **um único worker**. Múltiplos workers duplicariam jobs de importação e probe. Essa limitação é intencional na versão `0.1.0`. Locks em memória impedem sobreposição do mesmo job dentro do processo. ## Stack - Python 3.13, FastAPI, Jinja2, SQLAlchemy 2 async, Alembic, aiosqlite - SQLite com WAL - httpx, dnspython, APScheduler, orjson, pydantic-settings - Docker de um único serviço; reverse proxy TLS fica fora (Nginx/CloudPanel) ## Persistência Identidade histórica do tracker é preservada mesmo quando a URL some de uma origem. A limpeza automática remove apenas `probe_results` expirados (`RAW_RESULT_RETENTION_DAYS`). Datas no banco: UTC. API: ISO 8601. UI: apresentação humana com fuso indicado. ## Segurança de rede Endereços ingeridos são não confiáveis. Destinos loopback, privados, link-local, multicast, reservados e metadata são rejeitados. IPs do DNS são revalidados antes da conexão (mitigação de rebinding). Respostas têm limite de bytes e timeout. Não há endpoint público para testar URL arbitrária. ## Configuração Nome, descrição, versão, URL pública e repositório vêm de variáveis de ambiente (`APP_NAME`, etc.). O nome do produto não deve ser espalhado como literal no código de domínio. ## Degradação segura - Sem IPv6 no host: `ENABLE_IPV6=auto` marca IPv6 como não testado - Sem banco GeoIP: ASN/país ficam desconhecidos - Sem rede na primeira subida: site sobe vazio e registra o motivo ## Extensões futuras (não implementadas) Contas, admin, submit público, probes distribuídos, PostgreSQL, filas, mapa, notificações, protocolos WS/I2P/Yggdrasil.