mirror of
https://github.com/affaan-m/ECC.git
synced 2026-08-21 23:12:24 +02:00
* fix(skills): move version into metadata and normalize to semver 29 skills declared `version` at the top level of their frontmatter. The schema reads it from `metadata`, so tooling that follows the schema either misses it or has to special-case the top level. Three motion skills also declared `version: 1.0`, which is not a valid semantic version; normalized to `1.0.0`. No behavioral change — frontmatter metadata only. * fix(skills): state activation triggers in skill descriptions 148 skills described what they cover but never named the situation that should trigger them. Since the description is what Claude matches against to decide whether to load a skill, a description without a trigger makes activation guesswork — the skill is either missed or loaded at the wrong time. Added a "Use when ..." clause to each, derived from the skill's own body (most already stated the trigger under "## When to Use" or in the opening line; that intent is now reflected in the frontmatter where it is actually read from). Descriptions were only appended to; no existing wording was removed. * fix(skills): sync activation triggers into the Codex skill mirror 10 of the skills whose descriptions changed are also mirrored under `.agents/skills/`, where the description was previously a verbatim copy. Left alone, the two surfaces would disagree about when the skill applies. Only the description line is synced; the Codex copies keep their reduced frontmatter, since that validator accepts only name, description, metadata, license, and allowed-tools. * fix(skills): correct three activation clauses from review - autonomous-loops: the clause pulled new loop work into a skill that its own body marks as a compatibility shim retained for one release. It now points at the canonical continuous-agent-loop instead. - continuous-learning: the description carried the v1 routing directive twice; collapsed to one. - homelab-pihole-dns: the clause fired on any broken home DNS. Narrowed to tasks that actually involve Pi-hole. * chore: retain current main lockfile --------- Co-authored-by: Çağrı Solakoğlu <cagri.solakoglu@vtcenerji.com> Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
149 lines
3.8 KiB
Markdown
149 lines
3.8 KiB
Markdown
---
|
|
name: postgres-patterns
|
|
description: PostgreSQL database patterns for query optimization, schema design, indexing, and security. Based on Supabase best practices. Use when designing PostgreSQL schemas, indexes, or RLS policies, or when a query is too slow.
|
|
metadata:
|
|
origin: ECC
|
|
---
|
|
|
|
# PostgreSQL Patterns
|
|
|
|
Quick reference for PostgreSQL best practices. For detailed guidance, use the `database-reviewer` agent.
|
|
|
|
## When to Activate
|
|
|
|
- Writing SQL queries or migrations
|
|
- Designing database schemas
|
|
- Troubleshooting slow queries
|
|
- Implementing Row Level Security
|
|
- Setting up connection pooling
|
|
|
|
## Quick Reference
|
|
|
|
### Index Cheat Sheet
|
|
|
|
| Query Pattern | Index Type | Example |
|
|
|--------------|------------|---------|
|
|
| `WHERE col = value` | B-tree (default) | `CREATE INDEX idx ON t (col)` |
|
|
| `WHERE col > value` | B-tree | `CREATE INDEX idx ON t (col)` |
|
|
| `WHERE a = x AND b > y` | Composite | `CREATE INDEX idx ON t (a, b)` |
|
|
| `WHERE jsonb @> '{}'` | GIN | `CREATE INDEX idx ON t USING gin (col)` |
|
|
| `WHERE tsv @@ query` | GIN | `CREATE INDEX idx ON t USING gin (col)` |
|
|
| Time-series ranges | BRIN | `CREATE INDEX idx ON t USING brin (col)` |
|
|
|
|
### Data Type Quick Reference
|
|
|
|
| Use Case | Correct Type | Avoid |
|
|
|----------|-------------|-------|
|
|
| IDs | `bigint` | `int`, random UUID |
|
|
| Strings | `text` | `varchar(255)` |
|
|
| Timestamps | `timestamptz` | `timestamp` |
|
|
| Money | `numeric(10,2)` | `float` |
|
|
| Flags | `boolean` | `varchar`, `int` |
|
|
|
|
### Common Patterns
|
|
|
|
**Composite Index Order:**
|
|
```sql
|
|
-- Equality columns first, then range columns
|
|
CREATE INDEX idx ON orders (status, created_at);
|
|
-- Works for: WHERE status = 'pending' AND created_at > '2024-01-01'
|
|
```
|
|
|
|
**Covering Index:**
|
|
```sql
|
|
CREATE INDEX idx ON users (email) INCLUDE (name, created_at);
|
|
-- Avoids table lookup for SELECT email, name, created_at
|
|
```
|
|
|
|
**Partial Index:**
|
|
```sql
|
|
CREATE INDEX idx ON users (email) WHERE deleted_at IS NULL;
|
|
-- Smaller index, only includes active users
|
|
```
|
|
|
|
**RLS Policy (Optimized):**
|
|
```sql
|
|
CREATE POLICY policy ON orders
|
|
USING ((SELECT auth.uid()) = user_id); -- Wrap in SELECT!
|
|
```
|
|
|
|
**UPSERT:**
|
|
```sql
|
|
INSERT INTO settings (user_id, key, value)
|
|
VALUES (123, 'theme', 'dark')
|
|
ON CONFLICT (user_id, key)
|
|
DO UPDATE SET value = EXCLUDED.value;
|
|
```
|
|
|
|
**Cursor Pagination:**
|
|
```sql
|
|
SELECT * FROM products WHERE id > $last_id ORDER BY id LIMIT 20;
|
|
-- O(1) vs OFFSET which is O(n)
|
|
```
|
|
|
|
**Queue Processing:**
|
|
```sql
|
|
UPDATE jobs SET status = 'processing'
|
|
WHERE id = (
|
|
SELECT id FROM jobs WHERE status = 'pending'
|
|
ORDER BY created_at LIMIT 1
|
|
FOR UPDATE SKIP LOCKED
|
|
) RETURNING *;
|
|
```
|
|
|
|
### Anti-Pattern Detection
|
|
|
|
```sql
|
|
-- Find unindexed foreign keys
|
|
SELECT conrelid::regclass, a.attname
|
|
FROM pg_constraint c
|
|
JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = ANY(c.conkey)
|
|
WHERE c.contype = 'f'
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM pg_index i
|
|
WHERE i.indrelid = c.conrelid AND a.attnum = ANY(i.indkey)
|
|
);
|
|
|
|
-- Find slow queries
|
|
SELECT query, mean_exec_time, calls
|
|
FROM pg_stat_statements
|
|
WHERE mean_exec_time > 100
|
|
ORDER BY mean_exec_time DESC;
|
|
|
|
-- Check table bloat
|
|
SELECT relname, n_dead_tup, last_vacuum
|
|
FROM pg_stat_user_tables
|
|
WHERE n_dead_tup > 1000
|
|
ORDER BY n_dead_tup DESC;
|
|
```
|
|
|
|
### Configuration Template
|
|
|
|
```sql
|
|
-- Connection limits (adjust for RAM)
|
|
ALTER SYSTEM SET max_connections = 100;
|
|
ALTER SYSTEM SET work_mem = '8MB';
|
|
|
|
-- Timeouts
|
|
ALTER SYSTEM SET idle_in_transaction_session_timeout = '30s';
|
|
ALTER SYSTEM SET statement_timeout = '30s';
|
|
|
|
-- Monitoring
|
|
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
|
|
|
|
-- Security defaults
|
|
REVOKE ALL ON SCHEMA public FROM public;
|
|
|
|
SELECT pg_reload_conf();
|
|
```
|
|
|
|
## Related
|
|
|
|
- Agent: `database-reviewer` - Full database review workflow
|
|
- Skill: `clickhouse-io` - ClickHouse analytics patterns
|
|
- Skill: `backend-patterns` - API and backend patterns
|
|
|
|
---
|
|
|
|
*Based on Supabase Agent Skills (credit: Supabase team) (MIT License)*
|