tribunal-kit 2.4.5 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.agent/agents/accessibility-reviewer.md +220 -134
  2. package/.agent/agents/ai-code-reviewer.md +233 -129
  3. package/.agent/agents/backend-specialist.md +238 -178
  4. package/.agent/agents/code-archaeologist.md +181 -119
  5. package/.agent/agents/database-architect.md +207 -164
  6. package/.agent/agents/debugger.md +218 -151
  7. package/.agent/agents/dependency-reviewer.md +136 -55
  8. package/.agent/agents/devops-engineer.md +238 -175
  9. package/.agent/agents/documentation-writer.md +221 -137
  10. package/.agent/agents/explorer-agent.md +180 -142
  11. package/.agent/agents/frontend-reviewer.md +194 -80
  12. package/.agent/agents/frontend-specialist.md +237 -188
  13. package/.agent/agents/game-developer.md +52 -184
  14. package/.agent/agents/logic-reviewer.md +149 -78
  15. package/.agent/agents/mobile-developer.md +223 -152
  16. package/.agent/agents/mobile-reviewer.md +195 -79
  17. package/.agent/agents/orchestrator.md +211 -170
  18. package/.agent/agents/penetration-tester.md +174 -131
  19. package/.agent/agents/performance-optimizer.md +203 -139
  20. package/.agent/agents/performance-reviewer.md +211 -108
  21. package/.agent/agents/product-manager.md +162 -108
  22. package/.agent/agents/project-planner.md +162 -142
  23. package/.agent/agents/qa-automation-engineer.md +242 -138
  24. package/.agent/agents/security-auditor.md +194 -170
  25. package/.agent/agents/seo-specialist.md +213 -132
  26. package/.agent/agents/sql-reviewer.md +194 -73
  27. package/.agent/agents/supervisor-agent.md +203 -156
  28. package/.agent/agents/test-coverage-reviewer.md +193 -81
  29. package/.agent/agents/type-safety-reviewer.md +208 -65
  30. package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
  31. package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
  32. package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
  33. package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
  34. package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
  35. package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
  36. package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
  37. package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
  38. package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
  39. package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
  40. package/.agent/skills/agent-organizer/SKILL.md +126 -132
  41. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +160 -0
  42. package/.agent/skills/api-patterns/SKILL.md +289 -257
  43. package/.agent/skills/api-security-auditor/SKILL.md +177 -0
  44. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +1 -1
  45. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +1 -1
  46. package/.agent/skills/appflow-wireframe/SKILL.md +107 -58
  47. package/.agent/skills/architecture/SKILL.md +331 -200
  48. package/.agent/skills/authentication-best-practices/SKILL.md +173 -0
  49. package/.agent/skills/bash-linux/SKILL.md +154 -215
  50. package/.agent/skills/brainstorming/SKILL.md +104 -210
  51. package/.agent/skills/building-native-ui/SKILL.md +174 -0
  52. package/.agent/skills/clean-code/SKILL.md +360 -206
  53. package/.agent/skills/config-validator/SKILL.md +141 -165
  54. package/.agent/skills/csharp-developer/SKILL.md +528 -107
  55. package/.agent/skills/database-design/SKILL.md +455 -275
  56. package/.agent/skills/deployment-procedures/SKILL.md +145 -188
  57. package/.agent/skills/devops-engineer/SKILL.md +332 -134
  58. package/.agent/skills/devops-incident-responder/SKILL.md +113 -98
  59. package/.agent/skills/edge-computing/SKILL.md +157 -213
  60. package/.agent/skills/extract-design-system/SKILL.md +134 -0
  61. package/.agent/skills/framer-motion-expert/SKILL.md +939 -0
  62. package/.agent/skills/game-design-expert/SKILL.md +105 -0
  63. package/.agent/skills/game-engineering-expert/SKILL.md +122 -0
  64. package/.agent/skills/geo-fundamentals/SKILL.md +124 -215
  65. package/.agent/skills/github-operations/SKILL.md +314 -354
  66. package/.agent/skills/gsap-expert/SKILL.md +901 -0
  67. package/.agent/skills/i18n-localization/SKILL.md +138 -216
  68. package/.agent/skills/intelligent-routing/SKILL.md +127 -139
  69. package/.agent/skills/llm-engineering/SKILL.md +357 -258
  70. package/.agent/skills/local-first/SKILL.md +154 -203
  71. package/.agent/skills/mcp-builder/SKILL.md +118 -224
  72. package/.agent/skills/nextjs-react-expert/SKILL.md +783 -203
  73. package/.agent/skills/nodejs-best-practices/SKILL.md +559 -280
  74. package/.agent/skills/observability/SKILL.md +330 -285
  75. package/.agent/skills/parallel-agents/SKILL.md +122 -181
  76. package/.agent/skills/performance-profiling/SKILL.md +254 -197
  77. package/.agent/skills/plan-writing/SKILL.md +118 -188
  78. package/.agent/skills/platform-engineer/SKILL.md +123 -135
  79. package/.agent/skills/playwright-best-practices/SKILL.md +162 -0
  80. package/.agent/skills/powershell-windows/SKILL.md +146 -230
  81. package/.agent/skills/python-pro/SKILL.md +879 -114
  82. package/.agent/skills/react-specialist/SKILL.md +931 -108
  83. package/.agent/skills/readme-builder/SKILL.md +42 -0
  84. package/.agent/skills/realtime-patterns/SKILL.md +304 -296
  85. package/.agent/skills/rust-pro/SKILL.md +701 -240
  86. package/.agent/skills/seo-fundamentals/SKILL.md +154 -181
  87. package/.agent/skills/server-management/SKILL.md +190 -212
  88. package/.agent/skills/shadcn-ui-expert/SKILL.md +206 -0
  89. package/.agent/skills/skill-creator/SKILL.md +68 -0
  90. package/.agent/skills/sql-pro/SKILL.md +633 -104
  91. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +78 -0
  92. package/.agent/skills/swiftui-expert/SKILL.md +176 -0
  93. package/.agent/skills/systematic-debugging/SKILL.md +118 -186
  94. package/.agent/skills/tailwind-patterns/SKILL.md +576 -232
  95. package/.agent/skills/tdd-workflow/SKILL.md +137 -209
  96. package/.agent/skills/testing-patterns/SKILL.md +573 -205
  97. package/.agent/skills/vue-expert/SKILL.md +964 -119
  98. package/.agent/skills/vulnerability-scanner/SKILL.md +269 -316
  99. package/.agent/skills/web-accessibility-auditor/SKILL.md +193 -0
  100. package/.agent/skills/webapp-testing/SKILL.md +145 -236
  101. package/.agent/workflows/api-tester.md +151 -279
  102. package/.agent/workflows/audit.md +138 -168
  103. package/.agent/workflows/brainstorm.md +110 -146
  104. package/.agent/workflows/changelog.md +112 -144
  105. package/.agent/workflows/create.md +124 -139
  106. package/.agent/workflows/debug.md +189 -196
  107. package/.agent/workflows/deploy.md +189 -153
  108. package/.agent/workflows/enhance.md +151 -139
  109. package/.agent/workflows/fix.md +135 -143
  110. package/.agent/workflows/generate.md +157 -164
  111. package/.agent/workflows/migrate.md +160 -163
  112. package/.agent/workflows/orchestrate.md +168 -151
  113. package/.agent/workflows/performance-benchmarker.md +123 -305
  114. package/.agent/workflows/plan.md +173 -151
  115. package/.agent/workflows/preview.md +80 -137
  116. package/.agent/workflows/refactor.md +183 -153
  117. package/.agent/workflows/review-ai.md +129 -140
  118. package/.agent/workflows/review.md +116 -155
  119. package/.agent/workflows/session.md +94 -154
  120. package/.agent/workflows/status.md +79 -125
  121. package/.agent/workflows/strengthen-skills.md +139 -99
  122. package/.agent/workflows/swarm.md +179 -194
  123. package/.agent/workflows/test.md +211 -166
  124. package/.agent/workflows/tribunal-backend.md +113 -111
  125. package/.agent/workflows/tribunal-database.md +115 -132
  126. package/.agent/workflows/tribunal-frontend.md +118 -115
  127. package/.agent/workflows/tribunal-full.md +133 -136
  128. package/.agent/workflows/tribunal-mobile.md +119 -123
  129. package/.agent/workflows/tribunal-performance.md +133 -152
  130. package/.agent/workflows/ui-ux-pro-max.md +143 -171
  131. package/README.md +11 -15
  132. package/package.json +1 -1
  133. package/.agent/skills/dotnet-core-expert/SKILL.md +0 -103
  134. package/.agent/skills/game-development/2d-games/SKILL.md +0 -119
  135. package/.agent/skills/game-development/3d-games/SKILL.md +0 -135
  136. package/.agent/skills/game-development/SKILL.md +0 -236
  137. package/.agent/skills/game-development/game-art/SKILL.md +0 -185
  138. package/.agent/skills/game-development/game-audio/SKILL.md +0 -190
  139. package/.agent/skills/game-development/game-design/SKILL.md +0 -129
  140. package/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
  141. package/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
  142. package/.agent/skills/game-development/pc-games/SKILL.md +0 -144
  143. package/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
  144. package/.agent/skills/game-development/web-games/SKILL.md +0 -150
@@ -1,275 +1,455 @@
1
- ---
2
- name: database-design
3
- description: Database design principles and decision-making. Schema design, indexing strategy, ORM selection, serverless databases.
4
- allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 1.0.0
6
- last-updated: 2026-03-12
7
- applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
- ---
9
-
10
- # Database Design Principles
11
-
12
- > A schema is cheap to design and expensive to migrate.
13
- > Design it right for the queries your app actually runs.
14
-
15
- ---
16
-
17
- ## Core Decision: What Database?
18
-
19
- Before schema design, the database type must be justified — not assumed.
20
-
21
- | Need | Consider |
22
- |---|---|
23
- | Relational data with integrity constraints | PostgreSQL (default choice for most apps) |
24
- | Horizontal write scaling, flexible schema | MongoDB, DynamoDB |
25
- | Sub-millisecond reads, ephemeral/session data | Redis, Upstash |
26
- | Full-text search as primary use case | Elasticsearch, Typesense |
27
- | Serverless, zero-ops, edge-deployable | Turso, PlanetScale, Neon |
28
- | Time-series events | InfluxDB, TimescaleDB |
29
- | Semantic / vector similarity search | pgvector (in PostgreSQL), Qdrant, Pinecone |
30
-
31
- **Default when uncertain:** PostgreSQL. It handles relational, JSON, full-text, and time-series use cases well enough that you rarely need to deviate for most applications.
32
-
33
- ---
34
-
35
- ## Vector Database Patterns
36
-
37
- AI applications need semantic search — finding documents by meaning, not keyword. Vector databases store high-dimensional embeddings and search them by similarity.
38
-
39
- ### pgvector Stay in PostgreSQL
40
-
41
- ```sql
42
- -- Enable extension once
43
- CREATE EXTENSION IF NOT EXISTS vector;
44
-
45
- -- Add embedding column to existing table
46
- ALTER TABLE documents ADD COLUMN embedding vector(1536); -- 1536 for text-embedding-3-small
47
-
48
- -- IVFFlat index for approximate nearest neighbor search
49
- CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
50
- -- lists = sqrt(num_rows) is a good starting point
51
-
52
- -- Query: find 5 most semantically similar documents
53
- SELECT id, content, 1 - (embedding <=> $1) AS similarity
54
- FROM documents
55
- ORDER BY embedding <=> $1 -- cosine distance operator
56
- LIMIT 5;
57
- ```
58
-
59
- ### Dedicated Vector DB: When pgvector Isn't Enough
60
-
61
- | Trigger to Upgrade | Recommended |
62
- |---|---|
63
- | > 1M vectors + sub-10ms p99 | Qdrant (self-hosted, Rust) or Pinecone (managed) |
64
- | Multimodal (text + images) | Weaviate |
65
- | Managed, predictable pricing | Pinecone |
66
- | Zero-ops prototype | ChromaDB (local) |
67
-
68
- ### Chunking + Storage Best Practice
69
-
70
- ```ts
71
- // Always store both the raw text AND the embedding — embeddings are not reversible
72
- await db.query(`
73
- INSERT INTO documents (content, source_url, chunk_index, embedding)
74
- VALUES ($1, $2, $3, $4)
75
- `, [chunkText, sourceUrl, chunkIndex, JSON.stringify(embedding)]);
76
- // embedding is float[] — serialize to JSON for parameterized query
77
- ```
78
-
79
- ---
80
-
81
- ## Schema Design Rules
82
-
83
- ### Model for queries, not for elegance
84
-
85
- The most normalized schema is not always the right schema. Ask: **what does the application actually read?**
86
-
87
- Design the schema to make the most frequent, performance-critical queries fast — even if that means some denormalization.
88
-
89
- ### Naming Conventions
90
-
91
- ```sql
92
- -- Tables: plural, snake_case
93
- CREATE TABLE user_sessions (...);
94
-
95
- -- Primary keys: always "id"
96
- id UUID PRIMARY KEY DEFAULT gen_random_uuid();
97
-
98
- -- Foreign keys: {referenced_table_singular}_id
99
- user_id UUID REFERENCES users(id);
100
-
101
- -- Timestamps: always include both
102
- created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
103
- updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
104
-
105
- -- Booleans: is_ prefix
106
- is_active BOOLEAN NOT NULL DEFAULT TRUE;
107
- ```
108
-
109
- ### Required on Every Table
110
-
111
- ```sql
112
- id UUID PRIMARY KEY -- or BIGSERIAL for high-insert tables
113
- created_at TIMESTAMPTZ -- immutable creation time
114
- updated_at TIMESTAMPTZ -- changes on every update (trigger or ORM)
115
- ```
116
-
117
- ---
118
-
119
- ## Indexing Strategy
120
-
121
- An index makes reads faster and writes slightly slower. Index on the columns you filter and sort — not every column.
122
-
123
- **Index when:**
124
- - Column appears in `WHERE` clauses frequently
125
- - Column is used for `JOIN` conditions
126
- - Column is used in `ORDER BY` on large result sets
127
- - Column is a foreign key that will be queried by relationship
128
-
129
- **Don't index when:**
130
- - Table has under a few thousand rows full scan is faster than index lookup overhead
131
- - Column has very low cardinality (e.g., a boolean field with 95% TRUE)
132
- - Column is rarely queried
133
-
134
- ```sql
135
- -- Composite index: order matters most selective first
136
- CREATE INDEX idx_orders_user_status ON orders(user_id, status);
137
-
138
- -- Partial index: only index what you query
139
- CREATE INDEX idx_active_users ON users(email) WHERE is_active = TRUE;
140
- ```
141
-
142
- ---
143
-
144
- ## N+1 Queries
145
-
146
- The most common ORM performance failure. N+1 happens when you fetch N records then make a separate query for each one.
147
-
148
- ```ts
149
- // N+1 — 1 query for posts + N queries for authors
150
- const posts = await Post.findAll();
151
- for (const post of posts) {
152
- post.author = await User.findById(post.userId); // N queries
153
- }
154
-
155
- // Eager load — 2 queries total
156
- const posts = await Post.findAll({ include: ['author'] });
157
- ```
158
-
159
- **Detection:** Enable query logging in development. If you see repetitive queries differing only by ID, you have N+1.
160
-
161
- ---
162
-
163
- ## Migration Rules
164
-
165
- - Every schema change is a migration never modify the database directly in production
166
- - Migrations are additive first: add the column, deploy code that uses it, then remove the old column later
167
- - Never drop a column in the same migration that deploys the code removing its references
168
- - Test migrations on a production-size dataset — a 10-second migration on dev can lock a table for hours on prod
169
-
170
- ---
171
-
172
- ## File Index
173
-
174
- | File | Covers | Load When |
175
- |---|---|---|
176
- | `schema-design.md` | Detailed schema patterns and relationship modeling | Designing or reviewing a schema |
177
- | `indexing.md` | When and how to index, partial indexes, covering indexes | Performance investigation |
178
- | `orm-selection.md` | Prisma vs Drizzle vs TypeORM vs raw SQL trade-offs | Choosing ORM |
179
- | `migrations.md` | Safe migration patterns, rollback strategy | Changing existing schema |
180
- | `optimization.md` | Query analysis, EXPLAIN output, common fixes | Slow query diagnosis |
181
- | `database-selection.md` | Detailed database selection framework | Architecture decision |
182
-
183
- ---
184
-
185
- ## Scripts
186
-
187
- | Script | Purpose | Run With |
188
- |---|---|---|
189
- | `scripts/schema_validator.py` | Validates schema for missing indexes, naming issues | `python scripts/schema_validator.py <project_path>` |
190
-
191
- ---
192
-
193
- ## Output Format
194
-
195
- When this skill produces a recommendation or design decision, structure your output as:
196
-
197
- ```
198
- ━━━ Database Design Recommendation ━━━━━━━━━━━━━━━━
199
- Decision: [what was chosen / proposed]
200
- Rationale: [why one concise line]
201
- Trade-offs: [what is consciously accepted]
202
- Next action: [concrete next step for the user]
203
- ─────────────────────────────────────────────────
204
- Pre-Flight: ✅ All checks passed
205
- or ❌ [blocking item that must be resolved first]
206
- ```
207
-
208
-
209
- ---
210
-
211
- ## 🏛️ Tribunal Integration (Anti-Hallucination)
212
-
213
- **Slash command: `/tribunal-database`**
214
- **Active reviewers: `logic` · `security` · `sql`**
215
-
216
- ### ❌ Forbidden AI Tropes in Database Design
217
-
218
- 1. **Blindly guessing column types** — e.g., using `VARCHAR(255)` for everything instead of precise types or `TEXT`.
219
- 2. **Missing `updated_at` triggers** — defining `updated_at` without a mechanism to actually update it.
220
- 3. **N+1 queries by default** — returning code that queries relations in a loop.
221
- 4. **Destructive migrations** dropping a column in the same migration that drops the code using it.
222
- 5. **Over-indexing** adding indexes to every single column regardless of cardinality or query patterns.
223
-
224
- ### Pre-Flight Self-Audit
225
-
226
- Review these questions before generating database schemas or queries:
227
- ```
228
- Did I design for the queries the application actually runs, rather than theoretical elegance?
229
- Are my suggested indexes selective and actually used in `WHERE` or `JOIN` clauses?
230
- ✅ Is this code safe from N+1 query performance problems?
231
- Did I rely on parameterized queries (no string concatenation)?
232
- Did I use the correct primary key strategy (e.g., UUID vs BIGSERIAL) for the scale?
233
- ```
234
-
235
-
236
- ---
237
-
238
- ## 🤖 LLM-Specific Traps
239
-
240
- AI coding assistants often fall into specific bad habits when dealing with this domain. These are strictly forbidden:
241
-
242
- 1. **Over-engineering:** Proposing complex abstractions or distributed systems when a simpler approach suffices.
243
- 2. **Hallucinated Libraries/Methods:** Using non-existent methods or packages. Always `// VERIFY` or check `package.json` / `requirements.txt`.
244
- 3. **Skipping Edge Cases:** Writing the "happy path" and ignoring error handling, timeouts, or data validation.
245
- 4. **Context Amnesia:** Forgetting the user's constraints and offering generic advice instead of tailored solutions.
246
- 5. **Silent Degradation:** Catching and suppressing errors without logging or re-raising.
247
-
248
- ---
249
-
250
- ## 🏛️ Tribunal Integration (Anti-Hallucination)
251
-
252
- **Slash command: `/review` or `/tribunal-full`**
253
- **Active reviewers: `logic-reviewer` · `security-auditor`**
254
-
255
- ### Forbidden AI Tropes
256
-
257
- 1. **Blind Assumptions:** Never make an assumption without documenting it clearly with `// VERIFY: [reason]`.
258
- 2. **Silent Degradation:** Catching and suppressing errors without logging or handling.
259
- 3. **Context Amnesia:** Forgetting the user's constraints and offering generic advice instead of tailored solutions.
260
-
261
- ### Pre-Flight Self-Audit
262
-
263
- Review these questions before confirming output:
264
- ```
265
- Did I rely ONLY on real, verified tools and methods?
266
- ✅ Is this solution appropriately scoped to the user's constraints?
267
- Did I handle potential failure modes and edge cases?
268
- Have I avoided generic boilerplate that doesn't add value?
269
- ```
270
-
271
- ### 🛑 Verification-Before-Completion (VBC) Protocol
272
-
273
- **CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
274
- - **Forbidden:** Declaring a task complete because the output "looks correct."
275
- - **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
1
+ ---
2
+ name: database-design
3
+ description: Database design mastery. Schema design with normalization, denormalization strategies, indexing, migration pipelines, ORM selection (Prisma/Drizzle/SQLAlchemy/EF Core), connection pooling, soft deletes, audit trails, multi-tenancy, and serverless database patterns. Use when designing schemas, choosing databases, planning migrations, or architecting data layers.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep
5
+ version: 2.0.0
6
+ last-updated: 2026-04-01
7
+ applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
+ ---
9
+
10
+ # Database Design — Schema & Architecture Mastery
11
+
12
+ > A schema is a contract. Every column name is an API. Every missing index is a production incident waiting to happen.
13
+ > Design for reads first. Normalize until it hurts, then denormalize until it works.
14
+
15
+ ---
16
+
17
+ ## Database Selection Matrix
18
+
19
+ ```
20
+ ┌─────────────────────────────────────────────────────────────────────┐
21
+ │ Which Database Do You Need? │
22
+ ├─────────────────────────────────────────────────────────────────────┤
23
+ │ │
24
+ │ What's the primary access pattern? │
25
+ │ ├── Relational queries (JOINs, transactions, reports) │
26
+ │ │ ├── High consistency + complex queries PostgreSQL │
27
+ │ │ ├── Simple CRUD + familiar MySQL / MariaDB │
28
+ │ │ └── Embedded / edge / serverless → SQLite / Turso │
29
+ │ │ │
30
+ │ ├── Key-value lookups (cache, sessions, counters) │
31
+ │ │ ├── In-memory speed Redis / Valkey │
32
+ │ │ └── Persistent KV → DynamoDB / Upstash │
33
+ │ │ │
34
+ │ ├── Document store (flexible schema, nested objects) │
35
+ │ │ └── MongoDB / Firestore │
36
+ │ │ │
37
+ │ ├── Full-text search
38
+ │ │ ├── Built-in (good enough) → PostgreSQL tsvector │
39
+ │ │ └── Dedicated search Elasticsearch / Meilisearch / Typesense│
40
+ │ │ │
41
+ │ ├── Time-series (metrics, IoT, logs) │
42
+ │ │ └── TimescaleDB (PostgreSQL ext) / ClickHouse / InfluxDB │
43
+ │ │ │
44
+ │ ├── Graph (relationships, social networks) │
45
+ │ │ └── Neo4j / Amazon Neptune │
46
+ │ │
47
+ │ └── Vector (AI embeddings, semantic search) │
48
+ │ └── pgvector (PostgreSQL ext) / Pinecone / Weaviate │
49
+ └─────────────────────────────────────────────────────────────────────┘
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Schema Design Patterns
55
+
56
+ ### Naming Conventions
57
+
58
+ ```sql
59
+ -- RULES:
60
+ -- Tables: plural, snake_case (users, order_items)
61
+ -- Columns: singular, snake_case (first_name, created_at)
62
+ -- Primary key: id (BIGINT or UUID)
63
+ -- Foreign key: {referenced_table_singular}_id (user_id, order_id)
64
+ -- Timestamps: created_at, updated_at (TIMESTAMPTZ, not TIMESTAMP)
65
+ -- Booleans: is_{adjective} or has_{noun} (is_active, has_paid)
66
+ -- Status/enum columns: status, role, type (not state, kind)
67
+
68
+ -- BAD naming:
69
+ -- tbl_Users, UserID, DateCreated, active, isdeleted, userId
70
+ -- ✅ GOOD naming:
71
+ -- users, id, created_at, is_active, is_deleted, user_id
72
+
73
+ -- HALLUCINATION TRAP: Always use TIMESTAMPTZ (with timezone), not TIMESTAMP
74
+ -- TIMESTAMP without timezone is ambiguous and causes bugs across timezones
75
+ ```
76
+
77
+ ### Standard Table Template
78
+
79
+ ```sql
80
+ CREATE TABLE users (
81
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
82
+ -- OR: id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
83
+
84
+ -- Core fields
85
+ email TEXT NOT NULL UNIQUE,
86
+ name TEXT NOT NULL,
87
+ role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('admin', 'user', 'moderator')),
88
+
89
+ -- Status fields
90
+ is_active BOOLEAN NOT NULL DEFAULT true,
91
+
92
+ -- Metadata
93
+ metadata JSONB DEFAULT '{}',
94
+
95
+ -- Timestamps (ALWAYS include these)
96
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
97
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
98
+ );
99
+
100
+ -- Auto-update updated_at trigger
101
+ CREATE OR REPLACE FUNCTION update_updated_at()
102
+ RETURNS TRIGGER AS $$
103
+ BEGIN
104
+ NEW.updated_at = now();
105
+ RETURN NEW;
106
+ END;
107
+ $$ LANGUAGE plpgsql;
108
+
109
+ CREATE TRIGGER trg_users_updated_at
110
+ BEFORE UPDATE ON users
111
+ FOR EACH ROW
112
+ EXECUTE FUNCTION update_updated_at();
113
+
114
+ -- Essential indexes
115
+ CREATE INDEX idx_users_email ON users (email);
116
+ CREATE INDEX idx_users_role ON users (role) WHERE is_active = true;
117
+ CREATE INDEX idx_users_created_at ON users (created_at DESC);
118
+ ```
119
+
120
+ ### ID Strategy
121
+
122
+ ```sql
123
+ -- Option 1: BIGINT auto-increment (recommended for most cases)
124
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
125
+ -- Pros: compact, sortable, fast joins, natural ordering
126
+ -- Cons: exposes record count, sequential guessing
127
+
128
+ -- Option 2: UUID v7 (recommended for distributed systems)
129
+ id UUID DEFAULT gen_random_uuid() PRIMARY KEY
130
+ -- Pros: globally unique, no coordination needed, safe to expose
131
+ -- Cons: larger (16 bytes), slower joins, random order (use UUIDv7 for time-ordering)
132
+
133
+ -- Option 3: ULID / NanoID (application-generated)
134
+ -- Pros: sortable, URL-safe, customizable length
135
+ -- Cons: requires application logic, not DB-native
136
+
137
+ -- ❌ HALLUCINATION TRAP: UUID v4 is randomly ordered — kills index performance
138
+ -- Use UUID v7 (time-ordered) if you need UUIDs
139
+ -- UUID v7 has a timestamp prefix sequential inserts → B-tree friendly
140
+ ```
141
+
142
+ ### Relationships
143
+
144
+ ```sql
145
+ -- One-to-Many: foreign key on the "many" side
146
+ CREATE TABLE posts (
147
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
148
+ author_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
149
+ title TEXT NOT NULL,
150
+ body TEXT NOT NULL,
151
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
152
+ );
153
+ CREATE INDEX idx_posts_author_id ON posts (author_id);
154
+
155
+ -- Many-to-Many: junction table
156
+ CREATE TABLE post_tags (
157
+ post_id BIGINT NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
158
+ tag_id BIGINT NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
159
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
160
+ PRIMARY KEY (post_id, tag_id)
161
+ );
162
+ CREATE INDEX idx_post_tags_tag_id ON post_tags (tag_id);
163
+
164
+ -- ❌ HALLUCINATION TRAP: Every foreign key column MUST have an index
165
+ -- Without it, cascading deletes on the parent do a full table scan on the child
166
+ -- PostgreSQL does NOT auto-index foreign keys (MySQL InnoDB does)
167
+
168
+ -- Self-referential (tree/hierarchy)
169
+ CREATE TABLE categories (
170
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
171
+ parent_id BIGINT REFERENCES categories(id) ON DELETE SET NULL,
172
+ name TEXT NOT NULL,
173
+ depth INT NOT NULL DEFAULT 0
174
+ );
175
+ CREATE INDEX idx_categories_parent_id ON categories (parent_id);
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Soft Deletes
181
+
182
+ ```sql
183
+ -- Soft delete pattern
184
+ ALTER TABLE users ADD COLUMN deleted_at TIMESTAMPTZ;
185
+
186
+ -- Partial index — queries against active records are fast
187
+ CREATE INDEX idx_users_active ON users (email) WHERE deleted_at IS NULL;
188
+
189
+ -- "Delete" = set timestamp
190
+ UPDATE users SET deleted_at = now() WHERE id = 42;
191
+
192
+ -- All queries must filter:
193
+ SELECT * FROM users WHERE deleted_at IS NULL;
194
+
195
+ -- OR: Use a view for convenience
196
+ CREATE VIEW active_users AS
197
+ SELECT * FROM users WHERE deleted_at IS NULL;
198
+
199
+ -- ❌ HALLUCINATION TRAP: Soft deletes add complexity to EVERY query
200
+ -- Every SELECT, JOIN, and COUNT must include WHERE deleted_at IS NULL
201
+ -- Consider using a view or audit_log table instead when possible
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Audit Trail
207
+
208
+ ```sql
209
+ -- Append-only audit log
210
+ CREATE TABLE audit_log (
211
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
212
+ table_name TEXT NOT NULL,
213
+ record_id BIGINT NOT NULL,
214
+ action TEXT NOT NULL CHECK (action IN ('INSERT', 'UPDATE', 'DELETE')),
215
+ old_data JSONB,
216
+ new_data JSONB,
217
+ changed_by BIGINT REFERENCES users(id),
218
+ changed_at TIMESTAMPTZ NOT NULL DEFAULT now()
219
+ );
220
+
221
+ -- Partition by month for performance
222
+ -- CREATE TABLE audit_log (...) PARTITION BY RANGE (changed_at);
223
+
224
+ CREATE INDEX idx_audit_log_table_record ON audit_log (table_name, record_id);
225
+ CREATE INDEX idx_audit_log_changed_at ON audit_log USING brin (changed_at);
226
+
227
+ -- Auto-audit trigger
228
+ CREATE OR REPLACE FUNCTION audit_trigger()
229
+ RETURNS TRIGGER AS $$
230
+ BEGIN
231
+ INSERT INTO audit_log (table_name, record_id, action, old_data, new_data, changed_by)
232
+ VALUES (
233
+ TG_TABLE_NAME,
234
+ COALESCE(NEW.id, OLD.id),
235
+ TG_OP,
236
+ CASE WHEN TG_OP IN ('UPDATE', 'DELETE') THEN to_jsonb(OLD) END,
237
+ CASE WHEN TG_OP IN ('INSERT', 'UPDATE') THEN to_jsonb(NEW) END,
238
+ current_setting('app.current_user_id', true)::bigint
239
+ );
240
+ RETURN COALESCE(NEW, OLD);
241
+ END;
242
+ $$ LANGUAGE plpgsql;
243
+
244
+ CREATE TRIGGER trg_users_audit
245
+ AFTER INSERT OR UPDATE OR DELETE ON users
246
+ FOR EACH ROW EXECUTE FUNCTION audit_trigger();
247
+ ```
248
+
249
+ ---
250
+
251
+ ## Multi-Tenancy Patterns
252
+
253
+ ```sql
254
+ -- Pattern 1: Shared table with tenant_id (simplest, most common)
255
+ CREATE TABLE projects (
256
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
257
+ tenant_id BIGINT NOT NULL REFERENCES tenants(id),
258
+ name TEXT NOT NULL,
259
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
260
+ );
261
+ CREATE INDEX idx_projects_tenant ON projects (tenant_id, created_at DESC);
262
+ -- ‼️ Every query MUST include WHERE tenant_id = ? — enforce via RLS
263
+
264
+ -- Row Level Security (PostgreSQL)
265
+ ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
266
+
267
+ CREATE POLICY tenant_isolation ON projects
268
+ USING (tenant_id = current_setting('app.current_tenant_id')::bigint);
269
+
270
+ -- Pattern 2: Schema per tenant (better isolation)
271
+ CREATE SCHEMA tenant_acme;
272
+ CREATE TABLE tenant_acme.projects (...);
273
+
274
+ -- Pattern 3: Database per tenant (maximum isolation, hardest to manage)
275
+ -- Only for compliance/regulatory requirements
276
+ ```
277
+
278
+ ---
279
+
280
+ ## ORM Selection
281
+
282
+ ### Prisma (TypeScript/Node.js)
283
+
284
+ ```prisma
285
+ // prisma/schema.prisma
286
+ generator client {
287
+ provider = "prisma-client-js"
288
+ }
289
+
290
+ datasource db {
291
+ provider = "postgresql"
292
+ url = env("DATABASE_URL")
293
+ }
294
+
295
+ model User {
296
+ id Int @id @default(autoincrement())
297
+ email String @unique
298
+ name String
299
+ posts Post[]
300
+ createdAt DateTime @default(now()) @map("created_at")
301
+ updatedAt DateTime @updatedAt @map("updated_at")
302
+
303
+ @@map("users")
304
+ }
305
+ ```
306
+
307
+ ```typescript
308
+ // Usage:
309
+ const user = await prisma.user.findUnique({
310
+ where: { email: "alice@test.com" },
311
+ include: { posts: { take: 10, orderBy: { createdAt: "desc" } } },
312
+ });
313
+
314
+ // ❌ HALLUCINATION TRAP: Prisma uses its own query engine
315
+ // It does NOT support raw SQL joins in the standard query API
316
+ // Use prisma.$queryRaw for complex queries Prisma can't express
317
+ ```
318
+
319
+ ### Drizzle (TypeScript — SQL-First)
320
+
321
+ ```typescript
322
+ import { pgTable, serial, text, timestamp, integer } from "drizzle-orm/pg-core";
323
+ import { eq, desc, and } from "drizzle-orm";
324
+
325
+ export const users = pgTable("users", {
326
+ id: serial("id").primaryKey(),
327
+ email: text("email").notNull().unique(),
328
+ name: text("name").notNull(),
329
+ createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
330
+ });
331
+
332
+ // Query (SQL-like, type-safe)
333
+ const result = await db
334
+ .select({ id: users.id, name: users.name })
335
+ .from(users)
336
+ .where(and(eq(users.role, "admin"), eq(users.isActive, true)))
337
+ .orderBy(desc(users.createdAt))
338
+ .limit(20);
339
+ ```
340
+
341
+ ---
342
+
343
+ ## Migration Best Practices
344
+
345
+ ```
346
+ Migration Rules:
347
+ 1. Every migration must be REVERSIBLE (include down/rollback)
348
+ 2. Never modify a migration that's been applied to production
349
+ 3. Use explicit column types — never rely on ORM defaults
350
+ 4. Add indexes in the SAME migration as the column
351
+ 5. Large table migrations: add column as NULLABLE first, backfill, then add NOT NULL
352
+ 6. Test migrations against a COPY of production data size
353
+ 7. Never DROP a column — first remove all code references, deploy, then drop
354
+ ```
355
+
356
+ ```sql
357
+ -- Safe column addition (zero-downtime deploy)
358
+ -- Step 1: Add nullable column
359
+ ALTER TABLE users ADD COLUMN phone TEXT;
360
+
361
+ -- Step 2: Backfill (in batches to avoid locking)
362
+ UPDATE users SET phone = '' WHERE phone IS NULL AND id BETWEEN 1 AND 10000;
363
+ UPDATE users SET phone = '' WHERE phone IS NULL AND id BETWEEN 10001 AND 20000;
364
+
365
+ -- Step 3: Add constraint (after deploy confirms all code writes phone)
366
+ ALTER TABLE users ALTER COLUMN phone SET NOT NULL;
367
+ ALTER TABLE users ALTER COLUMN phone SET DEFAULT '';
368
+
369
+ -- ❌ HALLUCINATION TRAP: Adding NOT NULL without a default locks the ENTIRE table
370
+ -- On large tables this can cause downtime. Always add as nullable first.
371
+ ```
372
+
373
+ ---
374
+
375
+ ## Connection Pooling
376
+
377
+ ```
378
+ Application → Connection Pool → Database
379
+
380
+ Without pooling: 100 requests = 100 DB connections → DB overwhelmed
381
+ With pooling: 100 requests = 10-20 reused connections → DB happy
382
+
383
+ Common poolers:
384
+ - PgBouncer (external, most common for PostgreSQL)
385
+ - Prisma Accelerate (managed, for Prisma)
386
+ - Supabase Supavisor (managed, for Supabase)
387
+ - Application-level (SQLAlchemy pool, Drizzle pool)
388
+
389
+ Sizing formula:
390
+ max_connections = (num_cpu_cores * 2) + num_disk_spindles
391
+ Typical: 25-50 connections for most applications
392
+
393
+ ❌ HALLUCINATION TRAP: Serverless functions need EXTERNAL pooling
394
+ Each Lambda/Vercel invocation opens a new connection
395
+ Without PgBouncer/Supavisor, you hit max_connections instantly
396
+ ```
397
+
398
+ ---
399
+
400
+ ## Output Format
401
+
402
+ ```
403
+ ━━━ Database Design Report ━━━━━━━━━━━━━━━━━━━━━━━
404
+ Skill: Database Design
405
+ Database: [PostgreSQL/MySQL/SQLite/etc.]
406
+ Scope: [N tables · N migrations]
407
+ ─────────────────────────────────────────────────
408
+ ✅ Passed: [checks that passed, or "All clean"]
409
+ ⚠️ Warnings: [non-blocking issues, or "None"]
410
+ ❌ Blocked: [blocking issues requiring fix, or "None"]
411
+ ─────────────────────────────────────────────────
412
+ VBC status: PENDING → VERIFIED
413
+ Evidence: [migration success / schema validation]
414
+ ```
415
+
416
+ ---
417
+
418
+ ## 🤖 LLM-Specific Traps
419
+
420
+ 1. **TIMESTAMP vs TIMESTAMPTZ:** Always use TIMESTAMPTZ (with timezone). TIMESTAMP without timezone is ambiguous.
421
+ 2. **UUID v4 for Primary Keys:** UUID v4 is randomly ordered — destroys B-tree index performance. Use UUID v7 or BIGINT.
422
+ 3. **Missing FK Indexes:** PostgreSQL does NOT auto-create indexes on foreign key columns. Always add them manually.
423
+ 4. **NOT NULL on Large Tables:** Adding NOT NULL to an existing column on a large table locks the entire table. Add as nullable first.
424
+ 5. **`SELECT *` in Application Code:** Always specify columns. Schema changes + `SELECT *` = broken application.
425
+ 6. **Shared Mutable State Without RLS:** Multi-tenant tables without Row Level Security = data leaks between tenants.
426
+ 7. **Hardcoded Connection Strings:** Database URLs must come from environment variables, never code.
427
+ 8. **Direct Production Writes:** Never run unreviewed SQL against production. Use migrations and review processes.
428
+ 9. **Ignoring Query Plans:** Design decisions without EXPLAIN ANALYZE evidence are guesses.
429
+ 10. **Serverless Without Pooling:** Every serverless invocation opens a new connection. Always use an external connection pooler.
430
+
431
+ ---
432
+
433
+ ## 🏛️ Tribunal Integration
434
+
435
+ **Slash command: `/tribunal-database`**
436
+
437
+ ### ✅ Pre-Flight Self-Audit
438
+
439
+ ```
440
+ ✅ Did I use TIMESTAMPTZ (not TIMESTAMP)?
441
+ ✅ Did I add indexes for all foreign keys?
442
+ ✅ Did I use BIGINT or UUID v7 for primary keys?
443
+ ✅ Are all table/column names snake_case?
444
+ ✅ Do all tables have created_at and updated_at?
445
+ ✅ Is the migration reversible?
446
+ ✅ Did I use parameterized queries (not string interpolation)?
447
+ ✅ Is connection pooling configured for serverless?
448
+ ✅ Is multi-tenant data isolated (RLS or schema)?
449
+ ✅ Did I run EXPLAIN ANALYZE on critical queries?
450
+ ```
451
+
452
+ ### 🛑 VBC Protocol
453
+
454
+ - ❌ **Forbidden:** Declaring a schema "optimized" without migration + EXPLAIN evidence.
455
+ - ✅ **Required:** Provide migration success logs or schema validation output.