| name | deployment-guardian |
| description | Protege o CYPHER V3 em produção — checklist de deploy, environment variables, health checks, rollback automático, zero downtime |
| version | 4.0 |
| tags | ["deployment","production","safety","health-checks","environment","vercel","railway"] |
SKILL: Deployment Guardian — CYPHER V3
Princípio
Um deploy com bug em produção afeta traders com dinheiro real. Cada deploy passa por um checklist rigoroso antes de ir para produção.
Pre-Deploy Checklist (OBRIGATÓRIO)
1. Qualidade de Código
npm run type-check 2>&1 | grep -E "error TS" | wc -l
npm run lint 2>&1 | grep "error" | wc -l
npm run build 2>&1 | tail -5
npm run build 2>&1 | grep "First Load JS"
2. Segurança
git diff HEAD~1 --name-only | xargs grep -l "sk_\|pk_\|API_KEY\|SECRET" 2>/dev/null | \
grep -v ".env\|example\|test" | head -5
git diff HEAD~1 -- "*.ts" "*.tsx" | grep "^+" | grep "console\.log" | head -10
git diff HEAD~1 -- "*.ts" "*.tsx" | grep "^+" | grep "mockData\|MOCK_\|Math\.random" | head -5
npm audit --audit-level=high 2>&1 | grep -E "HIGH|CRITICAL" | wc -l
3. Environment Variables
node -e "
const required = [
'NEXT_PUBLIC_SUPABASE_URL',
'NEXT_PUBLIC_SUPABASE_ANON_KEY',
'SUPABASE_SERVICE_ROLE_KEY',
'ANTHROPIC_API_KEY',
'HIRO_API_KEY',
'COINGECKO_API_KEY',
'UNISAT_API_KEY',
'OKX_API_KEY',
'REDIS_URL',
'REDIS_TOKEN',
'STRIPE_SECRET_KEY',
'STRIPE_WEBHOOK_SECRET',
'AGENT_PRIVATE_KEY',
]
const missing = required.filter(k => !process.env[k])
if (missing.length > 0) {
console.error('❌ ENV VARS em falta:', missing.join(', '))
process.exit(1)
}
console.log('✅ Todas as env vars configuradas')
"
4. Testes de Saúde das APIs
STAGING_URL="https://cypher-v3-staging.vercel.app"
test_health() {
local url=$1 expected=$2 name=$3
local status=$(curl -sf -o /dev/null -w "%{http_code}" "$url" 2>/dev/null)
[ "$status" = "$expected" ] && echo "✅ $name ($status)" || echo "❌ $name — got $status, expected $expected"
}
test_health "$STAGING_URL/api/health" "200" "Health check"
test_health "$STAGING_URL/api/market/bitcoin" "200" "BTC Price"
test_health "$STAGING_URL/api/ordinals/collections" "200" "Ordinals"
test_health "$STAGING_URL/api/runes/market" "200" "Runes"
test_health "$STAGING_URL/api/fees" "200" "Bitcoin Fees"
API Health Endpoint (implementar se não existir)
import { NextResponse } from 'next/server'
import { cache } from '@/lib/cache'
export const dynamic = 'force-dynamic'
export const revalidate = 0
export async function GET() {
const checks: Record<string, 'ok' | 'error' | 'degraded'> = {}
try {
await cache.set('health:ping', 'pong', 10)
const pong = await cache.get<string>('health:ping')
checks.cache = pong === 'pong' ? 'ok' : 'degraded'
} catch {
checks.cache = cache.isUsingMemory() ? 'degraded' : 'error'
}
try {
const { createClient } = await import('@/lib/supabase/server')
const supabase = createClient()
await supabase.from('users').select('count').limit(1)
checks.database = 'ok'
} catch {
checks.database = 'error'
}
try {
const res = await fetch('https://api.hiro.so/extended/v1/status', { signal: AbortSignal.timeout(3000) })
checks.hiro = res.ok ? 'ok' : 'degraded'
} catch {
checks.hiro = 'error'
}
try {
const res = await fetch('https://api.coingecko.com/api/v3/ping', { signal: AbortSignal.timeout(3000) })
checks.coingecko = res.ok ? 'ok' : 'degraded'
} catch {
checks.coingecko = 'error'
}
const hasErrors = Object.values(checks).includes('error')
const hasDegraded = Object.values(checks).includes('degraded')
const overallStatus = hasErrors ? 'error' : hasDegraded ? 'degraded' : 'ok'
return NextResponse.json(
{
status: overallStatus,
timestamp: new Date().toISOString(),
version: process.env.VERCEL_GIT_COMMIT_SHA?.slice(0, 8) ?? 'local',
checks,
},
{ status: hasErrors ? 503 : 200 }
)
}
Rollback Guide
vercel rollback [deployment-url]
git revert [commit-sha] --no-edit
git push origin main
git checkout [commit-sha] -- src/lib/api/ordinals.ts
git commit -m "revert(ordinals): emergency rollback to working version"
git push origin main
Monitoring em Produção
vercel logs --follow --since 1h | grep -E "ERROR|error|500|timeout"
watch -n 30 'curl -s https://cypher-v3.vercel.app/api/health | node -e "
const d=JSON.parse(require(\"fs\").readFileSync(\"/dev/stdin\",\"utf8\"))
console.log(new Date().toLocaleTimeString(), d.status, JSON.stringify(d.checks))
"'
Conventional Commits para Deploy
git log staging..HEAD --oneline
git diff staging --stat
Checklist Final (copy-paste antes de cada deploy)
□ npm run type-check → 0 errors
□ npm run lint → 0 errors críticos
□ npm run build → compila sem erro
□ First Load JS < 300KB
□ npm audit → 0 HIGH/CRITICAL
□ Sem console.log no diff
□ Sem mock data no diff
□ Sem API keys hardcoded
□ ENV vars verificadas em staging
□ /api/health em staging → 200 OK
□ APIs principais testadas em staging
□ Commit message segue Conventional Commits
□ PR description explica "porquê" não só "o quê"