Capivara nasce — preciso de um hub pessoal seguro
🐷 Capivara·

Capivara nasce — preciso de um hub pessoal seguro

📖 5 min de leitura← Voltar para timeline

Com o Dogwalk no ar e o Arachne começando a tomar forma, percebi um problema: eu não tinha um lugar central pra gerenciar tudo. Cada projeto tinha seu próprio banco, suas próprias credenciais, seu próprio painel.

Foi assim que o Capivara nasceu — um hub pessoal seguro.

O problema

Eu precisava de:

  • Dashboard unificado — ver status de todos os projetos num lugar só
  • Gerenciamento de contatos — leads do Dogwalk, mensagens do Portfólio
  • Autenticação centralizada — não queria reimplementar login em cada projeto
  • API pública segura — endpoints que o frontend consome sem expor o banco

No começo cogitei usar o Supabase pra isso. Mas depois de configurar e usar por uns dias, vi que tarifário e latência não compensavam — especialmente com os dados trafegando por um servidor nos EUA quando eu e meus usuários estamos no Brasil.

A arquitetura

# FastAPI + JWT — o coração do Capivara
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

app = FastAPI(title="Capivara Hub")
security = HTTPBearer()

# Rotas públicas (sem auth)
@app.post("/api/portifolio/public/messages")
async def receive_contact(data: ContactForm):
    return await db.insert_message(data)

# Rotas admin (com auth JWT)
@app.get("/api/portifolio/messages")
async def list_messages(auth: HTTPAuthorizationCredentials = Depends(security)):
    payload = verify_jwt(auth.credentials)
    if not payload or payload.get("role") != "admin":
        raise HTTPException(status_code=403)
    return await db.get_all_messages()

A estrutura de rotas é simples: /public/ pra endpoints que o frontend chama sem token, e sem prefixo pros endpoints admin que exigem JWT.

JWT e segurança

Escolhi JWT em vez de sessions por ser stateless — não preciso de tabela de sessão, não preciso de Redis, e a verificação é rápida.

from datetime import datetime, timedelta
import jwt

JWT_CONFIG = os.getenv("CAPIVARA_JWT_CONFIG")  # via Bitwarden SM
JWT_ALGORITHM = "HS256"

def create_access_token(user_id: str) -> str:
    payload = {
        "sub": user_id,
        "role": "admin",
        "exp": datetime.utcnow() + timedelta(hours=2),
    }
    return jwt.encode(payload, JWT_CONFIG, algorithm=JWT_ALGORITHM)

O segredo JWT vive no Bitwarden Secrets Manager, nunca no código. O Hermes injeta via env var no systemd service.

Banco de dados

O Capivara usa PostgreSQL 18 local, com uma database separada pra cada projeto:

-- Database: capivara
CREATE TABLE messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT NOT NULL,
    email TEXT NOT NULL,
    message TEXT NOT NULL,
    source TEXT DEFAULT 'portifolio',
    created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE cv_downloads (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    ip_hash TEXT,
    user_agent TEXT,
    created_at TIMESTAMPTZ DEFAULT now()
);

Nada complexo — tabelas simples, sem ORM, só asyncpg. O backend é FastAPI puro com SQL raw.

Cloudflare Tunnel

O Capivara roda em localhost:8001 no WSL, exposto pro mundo via Cloudflare Tunnel:

cloudflared tunnel --url http://localhost:8001

O Tunnel resolve o problema de DNS, SSL, e firewall de uma vez. O domínio capivara.seu.pet aponta pro tunnel, e os frontends (Portfolio, Dogwalk) chamam https://capivara.seu.pet/api/....

Componente Local Público
PostgreSQL localhost:5432 ❌ (só local)
Capivara API localhost:8001 capivara.seu.pet
Dashboard Dev :5173 Em construção

Por que Capivara?

O nome veio naturalmente — capivara é o animal que integra o ecossistema. Ela não é o predador (Arachne), não é o animal de estimação (Dogwalk), mas está lá, no centro, mantendo tudo funcionando.

Assim como o roedor, o Capivara hub é discreto mas essencial. Todo projeto do ecossistema passa por ele de alguma forma — seja pra enviar um contato, registrar um download, ou buscar dados do dashboard.


Comandos úteis

~/lifelog — bash
$cat about.txt
╔══════════════════════════════════════╗
║  Samuel Medeiros                    ║
║  Senior Software Engineer           ║
║  Stack: Python · TypeScript · Rust  ║
║  Projetos: Arachne, Dogwalk,        ║
║            Capivara, TatuEngine      ║
╚══════════════════════════════════════╝
      
$