idea-analogist
想法群聊室 — 类比者角色。被 idea-team 主编排器调用,或用户单独说"类比一下"、"别的行业有没有"、"yes-and 扩展"、"X 让你想到什么"、"跨界启示"时触发。**专门做跨界类比 + yes-and 扩展——不评判、不挑刺、不要求事实证据**。Do NOT use when 用户要数据(用…
Use when designing PostgreSQL + Redis data models, indexes, caching strategies, JSONB usage, tiered storage, or cache consistency contracts.
$ npx -y skills add majiayu000/spellbook --skill database-patterns --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/database-patternsContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when designing PostgreSQL + Redis data models, indexes, caching strategies, JSONB usage, tiered storage, or cache consistency contracts.
name: database-patterns description: Use when designing PostgreSQL + Redis data models, indexes, caching strategies, JSONB usage, tiered storage, or cache consistency contracts.
---
| Use Case | Type | Avoid | |----------|------|-------| | Primary Key | `UUID` / `BIGSERIAL` | `INT` (range limits) | | Timestamps | `TIMESTAMPTZ` | `TIMESTAMP` (no timezone) | | Money | `NUMERIC(19,4)` | `FLOAT` (precision loss) | | Status | `TEXT` + CHECK | `INT` (unreadable) | | Semi-structured | `JSONB` | `JSON` (no indexing) | | Full-text | `TSVECTOR` | `LIKE '%..%'` |
-- Use UUID for distributed-friendly IDs
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active'
CHECK (status IN ('active', 'inactive', 'suspended')),
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Updated timestamp trigger
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();-- B-Tree: Equality, range, sorting (default)
CREATE INDEX idx_users_email ON users(email);
-- Composite: Leftmost prefix rule
-- Supports: (user_id), (user_id, created_at)
-- Does NOT support: (created_at) alone
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at DESC);
-- Partial: Reduce index size
CREATE INDEX idx_active_users ON users(email)
WHERE status = 'active';
-- GIN for JSONB: Containment queries
CREATE INDEX idx_metadata ON users USING GIN (metadata jsonb_path_ops);
-- Expression: Specific JSONB field
CREATE INDEX idx_user_role ON users ((metadata->>'role'));
-- Full-text search
CREATE INDEX idx_search ON products USING GIN (to_tsvector('english', name || ' ' || description));-- Good: Dynamic attributes, rarely queried fields
CREATE TABLE products (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC(19,4) NOT NULL,
category TEXT NOT NULL, -- Extracted: frequently queried
attributes JSONB DEFAULT '{}' -- Dynamic: color, size, specs
);
-- Query with containment
SELECT * FROM products
WHERE category = 'electronics' -- B-Tree index
AND attributes @> '{"brand": "Apple"}'; -- GIN index
-- Query specific field
SELECT * FROM products
WHERE attributes->>'color' = 'black'; -- Expression index
-- Update JSONB field
UPDATE products
SET attributes = attributes || '{"featured": true}'
WHERE id = '...';-- Always use EXPLAIN ANALYZE 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.status = 'active' GROUP BY u.id ORDER BY u.created_at DESC LIMIT 20; -- Watch for: -- ❌ Seq Scan on large tables → Add index -- ❌ Sort → Use index for ordering -- ❌ Nested Loop with many rows → Consider JOIN order -- ❌ Hash Join on huge tables → Add indexes
// PgBouncer or built-in pool
import { Pool } from 'pg';
const pool = new Pool({
max: 20, // Max connections
idleTimeoutMillis: 30000, // Close idle connections
connectionTimeoutMillis: 2000, // Fail fast
});
// Connection count formula:
// connections = (cores * 2) + effective_spindle_count
// Usually 10-30 is enough---
| Use Case | Structure | Example | |----------|-----------|---------| | Cache objects | String | `user:123` → JSON | | Counters | String + INCR | `views:article:456` | | Sessions | Hash | `session:abc` → {userId, ...} | | Leaderboards | Sorted Set | `scores` → {userId: score} | | Queues | List/Stream | `tasks` → LPUSH/RPOP | | Unique sets | Set | `online_users` | | Real-time | Pub/Sub/Stream | Notifications |
# Format: <entity>:<id>:<attribute> user:123:profile user:123:settings order:456:items session:abc123 # Use colons for hierarchy # Enables pattern matching with SCAN SCAN 0 MATCH "user:*:profile" COUNT 100
const TTL = {
SESSION: 24 * 60 * 60, // 24 hours
CACHE: 15 * 60, // 15 minutes
RATE_LIMIT: 60, // 1 minute
LOCK: 30, // 30 seconds
};
// Set with TTL
await redis.set(`cache:user:${id}`, JSON.stringify(user), 'EX', TTL.CACHE);
// Check TTL
const remaining = await redis.ttl(`cache:user:${id}`);---
async function getUser(id: string): Promise<User> {
const cacheKey = `user:${id}`;
// 1. Check cache
const cached = await redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// 2. Cache miss → Query database
const user = await db.user.findUnique({ where: { id } });
if (!user) {
throw new NotFoundError('User not found');
}
// 3. Populate cache
await redis.set(cacheKey, JSON.stringify(user), 'EX', 900);
return user;
}async function updateUser(id: string, data: UpdateInput): Promise<User> {
// 1. Update database
const user = await db.user.update({
where: { id },
data,
});
// 2. Update cache immediately
await redis.set(`user:${iCross-runtime skills for Claude Code, Codex, and multi-agent workflows.
Repo: majiayu000/spellbook
想法群聊室 — 类比者角色。被 idea-team 主编排器调用,或用户单独说"类比一下"、"别的行业有没有"、"yes-and 扩展"、"X 让你想到什么"、"跨界启示"时触发。**专门做跨界类比 + yes-and 扩展——不评判、不挑刺、不要求事实证据**。Do NOT use when 用户要数据(用…
想法群聊室 — 反方角色。被 idea-team 主编排器调用,或用户单独说"反方意见"、"挑这个想法的刺"、"为什么会失败"、"找漏洞 / 反例"、"devil's advocate"时触发。**专门挑漏洞、找隐藏假设、给反例——不安慰、不"也许可以这样"、不全盘否定**。Do NOT use when…
想法群聊室 — 调研员角色。被 idea-team 主编排器调用,或用户单独说"调研一下 X"、"X 的现状/竞品/数据"、"找 2026 数据"、"事实底"时触发。**用 WebSearch 拉真实 2026 数据、列竞品、引来源——只给事实,不评判,不建议**。Do NOT use when…
想法群聊室主持人 — 把一句话想法丢给多角色 AI 团队(调研员/反方/类比者)做查漏补缺。每个角色有自己的 voice,他们互相 @ 接话;你随时插话。**这是创意扩展工具,不打分、不否决、不堵路**。Use when 用户说"组个团队聊一下"、"开会讨论这个想法"、"找几个角度看看"、"群聊一下 X"、"team…
端到端产品教练 — 把一句话想法走到 PRD + 可点击 HTML 原型。会顶嘴、强制砍功能、用 Nielsen + Norman 做友好性硬检。Use when user 说"我有一个想法"、"想做一个产品"、"做 MVP"、"写 PRD"、"做用户友好的产品",或调用插件命令…
Mobile app UI design expert for iOS and Android. Use when designing app interfaces, creating design systems, ensuring accessibility, or following platform…