.claude/skills/postgresql/SKILL.md
PostgreSQL database design, queries, and management for INVOOPAY Use when: designing schemas, writing complex queries, optimizing database performance, managing migrations, or debugging database issues
npx skillsauth add kaxuna1/ecomsite postgresqlInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Provides guidance for PostgreSQL database operations using the pg library with connection pooling. This codebase uses raw SQL with parameterized queries rather than an ORM, requiring careful attention to SQL injection prevention and transaction management.
// backend/src/db/client.ts
import pg from 'pg';
const { Pool } = pg;
export const pool = new Pool({
host: env.dbHost,
port: env.dbPort,
database: env.dbName,
user: env.dbUser,
password: env.dbPassword,
max: 20, // Maximum connections
idleTimeoutMillis: 30000, // Close idle connections after 30s
connectionTimeoutMillis: 2000
});
export const query = async (text: string, params?: any[]) => {
return await pool.query(text, params);
};
// Read with parameterized query
const result = await pool.query(
'SELECT * FROM products WHERE id = $1',
[productId]
);
// Insert with RETURNING
const insertResult = await pool.query(
`INSERT INTO products (name, price, inventory)
VALUES ($1, $2, $3)
RETURNING *`,
[name, price, inventory]
);
// Update
await pool.query(
'UPDATE products SET inventory = inventory - $1 WHERE id = $2',
[quantity, productId]
);
| Concept | Usage | Example |
|---------|-------|---------|
| Parameterized Queries | Prevent SQL injection | $1, $2, $3 placeholders |
| JSONB | Flexible schema storage | categories JSONB NOT NULL |
| Connection Pooling | Reuse connections | pool.query() vs pool.connect() |
| Transactions | Multi-statement atomicity | BEGIN, COMMIT, ROLLBACK |
| COALESCE | Translation fallbacks | COALESCE(pt.name, p.name) |
When: Creating orders with inventory decrements
const client = await pool.connect();
try {
await client.query('BEGIN');
// Multiple operations...
await client.query('INSERT INTO orders...', [...]);
await client.query('UPDATE products SET inventory...', [...]);
await client.query('COMMIT');
} catch (error) {
await client.query('ROLLBACK');
throw error;
} finally {
client.release(); // CRITICAL: Always release
}
When: Create or update translations
await pool.query(
`INSERT INTO product_translations (product_id, language_code, name)
VALUES ($1, $2, $3)
ON CONFLICT (product_id, language_code)
DO UPDATE SET name = EXCLUDED.name, updated_at = CURRENT_TIMESTAMP
RETURNING *`,
[productId, languageCode, name]
);
tools
Zustand lightweight state management with persistence and middleware. Use when: managing client-side state (cart, auth, UI preferences), replacing React Context with simpler API, accessing state outside React components, implementing localStorage persistence
development
Zod schema validation and TypeScript integration for runtime type safety. Use when: Validating API payloads, form inputs, environment variables, or any external data boundaries where TypeScript types alone cannot guarantee safety.
tools
Configures Vite 5.x build tool, dev server, and frontend asset optimization for the Luxia e-commerce platform. Use when: configuring builds, adding environment variables, optimizing bundle size, setting up testing, debugging HMR issues, or adding Vite plugins.
development
Enforces strict TypeScript types across frontend and backend codebases. Use when: Writing new services, DTOs, interfaces, type guards, debugging type errors, or ensuring type safety at API boundaries.