Backend (server/src/google-calendar.js + endpoints):
- OAuth 2.0 authorization-code flow completo
- Endpoints: /api/google/{status,auth-url,callback,disconnect,sync-pending,pull}
- Auto-refresh de access_token quando expira (com retry 401→refresh→retry)
- Token storage em google_connections (better-sqlite3)
- syncToken pra delta sync eficiente do Google
- Pendência↔evento: ⚓/✅ no summary, dueDate→start.date all-day,
shivaoPendingId/shivaoCompleted em extendedProperties.private
- Graceful disable: 503 + flag isEnabled() se env vars não setadas
Frontend (Arquivo › Google Agenda):
- Card só aparece quando feature ativa no servidor
- Connect: abre OAuth em nova aba + polling 3s pra detectar sucesso
- Auto-sync na criação/edição/deleção de pendência (se conectada + tem dueDate)
- Botão "Sincronizar todas pendências" + "Buscar mudanças do Google"
- Pull automático ao abrir aba Pendências (se passou >2min do último)
- Pendências criadas direto no Google viram pendências locais
Pra ativar em produção, adicionar no Coolify shivao-cloud:
GOOGLE_CLIENT_ID=...apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=...
GOOGLE_REDIRECT_URI=https://shivao.pontualtech.work/api/google/callback
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BACKEND
- Nova tabela payments (user_id, asaas_payment_id, plan, cycle, value, billing_type, status, ...)
- Coluna users.asaas_customer_id (cache pra reaproveitar customer entre payments)
- server/src/billing.js: cliente Asaas v3 com getOrCreateCustomer, createPayment, getPixQrCode, status mapping
- Endpoint POST /api/billing/checkout — cria cobrança + retorna URL/QR PIX
- Endpoint GET /api/billing/payment/:id — verifica status, faz reconciliação se webhook falhou
- Endpoint POST /api/billing/asaas-webhook — ativa licença em RECEIVED/CONFIRMED, revoga em REFUNDED
- Endpoint GET /api/billing/payments — histórico do user
- 503 se ASAAS_API_KEY não configurado (graceful degradation)
- Webhook valida ASAAS_WEBHOOK_TOKEN (shared secret) se setado
FRONTEND (sincronizado app/ + server/public/)
- openUpgradeModal() — modal dinâmico com seleção plano (Pro/Captain) + ciclo (mensal/anual) + tipo (PIX/Cartão/Boleto)
- _doCheckout() — chama backend, exibe QR Code PIX OU link invoice
- checkPaymentStatus() — verifica e ativa licença quando pago
ENV VARS NECESSÁRIAS NO COOLIFY (próximo passo manual):
- ASAAS_API_KEY=$aact_prod_... (chave Asaas que Karlão já usa em outros projetos)
- ASAAS_API_URL=https://api.asaas.com/v3 (default)
- ASAAS_WEBHOOK_TOKEN=whsec_... (gere um valor aleatório, configure no painel Asaas → Integrações)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Importação inicial do projeto Shivão (Diário de Bordo do veleiro) em estado
pronto pra produção, já incluindo as 5 mudanças de hardening implementadas
pela squad shivao-melhoria em 2026-04-27.
Mudanças de hardening (HANDOFF.md seção "✅ Pronto"):
1. **Rate limiting nos 3 endpoints públicos de share**
- express-rate-limit ^8.4.1, 60 req/min/IP
- server/src/index.js linhas 38, 262, 271, 279
2. **Tamanho de upload reduzido pra 50MB** (era 200MB)
- multer linha 84
3. **Validação Zod nos endpoints autenticados** (POST /api/data e /zones)
- novo arquivo server/src/schemas/index.js
- middleware validate() retorna 400 com top 5 issues
4. **Audit log de ações sensíveis**
- nova tabela audit_log + funções db.audit() e db.recentAudit()
- 6 endpoints instrumentados (state_set, media_insert/delete, share_create/revoke/zones_update)
- novo endpoint GET /api/audit (autenticado)
5. **Catch silencioso de webhook em zona PROIBIDA tratado**
- app/diario-bordo.html + server/public/index.html linha 3280
- agora loga erro + exibe toast ao usuário
Status final do HANDOFF:
- 🔴 Críticos restantes: 1 (CORS — decisão consciente single-tenant, não-acionável)
- 🟡 Importantes: 4 itens (testes, vigia reconnect, refator frontend, demais catches)
- 🟢 Bom-ter: 5 itens
Stack: Node 20 ESM + Express + better-sqlite3 + Docker (Coolify)
Single-tenant pessoal · single-file frontend HTML · offline-first
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>