Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Dev Database Patterns

ASecurity

Padrões de banco de dados para software complexo — migrations seguras, indexing strategy, N+1 detection, soft deletes, connection pooling.

3 stars
0 votes
0 copies
0 views
Added 9/20/2026
ai-agentstypescriptbashsqlnodedatabasesecurityperformance

Works with

cli

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add joaoguirunas/team-os --skill dev-database-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dev Database Patterns?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Dev Database Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/joaoguirunas-dev-database-patterns/badge)](https://www.skillsdirectory.com/skills/joaoguirunas-dev-database-patterns)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: dev-database-patterns
description: Padrões de banco de dados para software complexo — migrations seguras, indexing strategy, N+1 detection, soft deletes, connection pooling.
version: "1.1"
updated: "2026-04-21"
---

# Database Patterns — Software Complexo

## Migration Safety Protocol

**Nunca aplicar migration sem este protocolo:**

```bash
# 1. Snapshot — estado antes
pg_dump $DATABASE_URL --schema-only > backups/schema-$(date +%Y%m%d-%H%M%S).sql

# 2. Dry-run — verificar sem commitar (BEGIN + ROLLBACK)
psql $DATABASE_URL <<'EOF'
BEGIN;
\i migrations/001_add_users_table.sql
-- Verificar resultado sem commitar
SELECT COUNT(*) FROM users;
\d users
ROLLBACK;  -- Desfaz tudo — apenas verificação
EOF

# 3. Apply — executar de verdade
psql $DATABASE_URL -f migrations/001_add_users_table.sql

# 4. Smoke test — verificar integridade após apply real
psql $DATABASE_URL -c "SELECT COUNT(*) FROM users;"
psql $DATABASE_URL -c "\d users"

# 5. Rollback disponível (executar se smoke test falhar)
psql $DATABASE_URL -f migrations/001_add_users_table.rollback.sql
```

> **Nota:** PostgreSQL não tem flag `--dry-run` nativo. O dry-run correto é sempre via `BEGIN/ROLLBACK` — executa a migration em transação e faz rollback sem commitar.

## Migration Structure

Cada migration tem arquivo de rollback correspondente:

```
migrations/
├── 001_create_users.sql
├── 001_create_users.rollback.sql
├── 002_add_user_roles.sql
└── 002_add_user_roles.rollback.sql
```

### Template de migration

```sql
-- migrations/001_create_users.sql
-- Migration: create users table
-- Author: dev-data-engineer
-- Date: 2026-04-21

BEGIN;

CREATE TABLE users (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email       VARCHAR(255) NOT NULL UNIQUE,
  name        VARCHAR(100) NOT NULL,
  role        VARCHAR(50) NOT NULL DEFAULT 'member',
  created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  deleted_at  TIMESTAMPTZ  -- soft delete
);

CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_role ON users(role) WHERE deleted_at IS NULL;

COMMENT ON TABLE users IS 'Core user accounts';

COMMIT;
```

```sql
-- migrations/001_create_users.rollback.sql
BEGIN;
DROP TABLE IF EXISTS users;
COMMIT;
```

## Indexing Strategy

```sql
-- Index para lookup mais comum
CREATE INDEX idx_orders_user_id ON orders(user_id);

-- Index composto para queries frequentes
CREATE INDEX idx_orders_user_status ON orders(user_id, status);

-- Index parcial — apenas registros ativos (muito mais eficiente)
CREATE INDEX idx_users_active ON users(email) WHERE deleted_at IS NULL;

-- Index para full-text search
CREATE INDEX idx_products_search ON products
  USING GIN(to_tsvector('english', name || ' ' || description));
```

**Regras de indexing:**
- Todo campo usado em `WHERE`, `JOIN ON`, `ORDER BY` frequentemente deve ter index
- Índices compostos: ordem importa (campo mais seletivo primeiro)
- Índices parciais para tabelas com flag de soft delete
- Executar `EXPLAIN ANALYZE` antes de criar index em tabela grande

## N+1 Detection e Prevenção

```typescript
// ❌ N+1 — um query por usuário
const users = await db.user.findMany()
for (const user of users) {
  const orders = await db.order.findMany({ where: { userId: user.id } })
  // N queries para N usuários = N+1 total
}

// ✅ Sem N+1 — include para eager loading
const users = await db.user.findMany({
  include: { orders: true }
})

// ✅ Para casos complexos — query única com JOIN
const usersWithOrders = await db.$queryRaw`
  SELECT u.*, json_agg(o.*) as orders
  FROM users u
  LEFT JOIN orders o ON o.user_id = u.id
  GROUP BY u.id
`
```

**Detectar N+1:** Logar queries em desenvolvimento com `prisma.$on('query', ...)` ou usar `pg_stat_statements`.

## Soft Deletes

```sql
-- Coluna de soft delete
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMPTZ;

-- Deletar (soft)
UPDATE users SET deleted_at = NOW() WHERE id = $1;

-- Queries devem filtrar deletados
SELECT * FROM users WHERE deleted_at IS NULL;

-- View para simplificar
CREATE VIEW active_users AS
  SELECT * FROM users WHERE deleted_at IS NULL;
```

```typescript
// Prisma — middleware para soft delete automático
prisma.$use(async (params, next) => {
  if (params.model === 'User') {
    if (params.action === 'delete') {
      params.action = 'update'
      params.args.data = { deletedAt: new Date() }
    }
    if (['findMany', 'findFirst', 'count'].includes(params.action)) {
      params.args.where = { ...params.args.where, deletedAt: null }
    }
  }
  return next(params)
})
```

## Connection Pooling

```typescript
// Supabase / Postgres — configurar pool adequadamente
const db = new PrismaClient({
  datasources: {
    db: { url: process.env.DATABASE_URL }
  },
  log: process.env.NODE_ENV === 'development' ? ['query'] : ['error'],
})
```

**Para Supabase:**
- Transaction pooler (porta 6543) → serverless functions (sem estado de sessão)
- Session pooler (porta 5432) → aplicações persistentes (com estado de sessão)
- `pool_max=10` para produção, `pool_min=2` para manter conexões aquecidas

## RLS com Supabase

```sql
-- Habilitar RLS em todas as tabelas
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- Política básica de isolamento
CREATE POLICY "users_own_data" ON users
  FOR ALL USING (auth.uid() = id);

-- Política com role
CREATE POLICY "admin_full_access" ON users
  FOR ALL USING (auth.jwt() ->> 'role' = 'admin');

-- Política de insert com check
CREATE POLICY "users_insert_own" ON orders
  FOR INSERT WITH CHECK (auth.uid() = user_id);
```

**Testar RLS:**
```sql
-- Simular como usuário específico
SET LOCAL role = authenticated;
SET LOCAL request.jwt.claims = '{"sub": "user-uuid-here"}';
SELECT * FROM orders;  -- Deve retornar apenas os pedidos do usuário
```

## Query Performance

```sql
-- Analisar query lenta
EXPLAIN ANALYZE
SELECT u.*, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.deleted_at IS NULL
GROUP BY u.id
ORDER BY order_count DESC
LIMIT 20;
```

Interpretar:
- `Seq Scan` em tabela grande → precisa de index
- `Hash Join` → geralmente ok
- `Nested Loop` com muitas iterações → possível N+1

## Regras absolutas

- Nunca `DROP` sem backup confirmado
- Nunca migration sem rollback correspondente
- **Dry-run via `BEGIN/ROLLBACK`** — PostgreSQL não tem `--dry-run` nativo
- Nunca `SELECT *` em produção — selecionar colunas necessárias
- Nunca joins sem index nas colunas de join
- Sempre RLS em tabelas com dados de usuário
- Migrations são imutáveis após aplicação — criar nova migration para corrigir

Attribution

joaoguirunasjoaoguirunas
View sourceMore from joaoguirunas →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Caveman

Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.

1023331 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

686011 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3331 votes

catchup

Recovers prior coding-agent session context by running `catchup <agent> --since-compact`, which extracts a clean summary of a previous Codex, Claude Code, Antigravity, OpenCode, or Pi Agent session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", or asks to recover/summarize a previous session before continuing. Do NOT use for the current conversation, git history, or any non-agent log.

611 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →