tribunal-kit 3.0.0 → 4.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 (233) hide show
  1. package/.agent/ARCHITECTURE.md +99 -99
  2. package/.agent/GEMINI.md +52 -52
  3. package/.agent/agents/accessibility-reviewer.md +187 -220
  4. package/.agent/agents/ai-code-reviewer.md +199 -233
  5. package/.agent/agents/backend-specialist.md +215 -238
  6. package/.agent/agents/code-archaeologist.md +161 -181
  7. package/.agent/agents/database-architect.md +184 -207
  8. package/.agent/agents/debugger.md +191 -218
  9. package/.agent/agents/dependency-reviewer.md +103 -136
  10. package/.agent/agents/devops-engineer.md +218 -238
  11. package/.agent/agents/documentation-writer.md +201 -221
  12. package/.agent/agents/explorer-agent.md +160 -180
  13. package/.agent/agents/frontend-reviewer.md +160 -194
  14. package/.agent/agents/frontend-specialist.md +248 -237
  15. package/.agent/agents/game-developer.md +48 -52
  16. package/.agent/agents/logic-reviewer.md +116 -149
  17. package/.agent/agents/mobile-developer.md +200 -223
  18. package/.agent/agents/mobile-reviewer.md +162 -195
  19. package/.agent/agents/orchestrator.md +181 -211
  20. package/.agent/agents/penetration-tester.md +157 -174
  21. package/.agent/agents/performance-optimizer.md +183 -203
  22. package/.agent/agents/performance-reviewer.md +178 -211
  23. package/.agent/agents/precedence-reviewer.md +213 -0
  24. package/.agent/agents/product-manager.md +142 -162
  25. package/.agent/agents/product-owner.md +6 -25
  26. package/.agent/agents/project-planner.md +142 -162
  27. package/.agent/agents/qa-automation-engineer.md +225 -242
  28. package/.agent/agents/security-auditor.md +174 -194
  29. package/.agent/agents/seo-specialist.md +193 -213
  30. package/.agent/agents/sql-reviewer.md +161 -194
  31. package/.agent/agents/supervisor-agent.md +184 -203
  32. package/.agent/agents/swarm-worker-contracts.md +17 -17
  33. package/.agent/agents/swarm-worker-registry.md +46 -46
  34. package/.agent/agents/test-coverage-reviewer.md +160 -193
  35. package/.agent/agents/test-engineer.md +0 -21
  36. package/.agent/agents/type-safety-reviewer.md +175 -208
  37. package/.agent/patterns/generator.md +9 -9
  38. package/.agent/patterns/inversion.md +12 -12
  39. package/.agent/patterns/pipeline.md +9 -9
  40. package/.agent/patterns/reviewer.md +13 -13
  41. package/.agent/patterns/tool-wrapper.md +9 -9
  42. package/.agent/rules/GEMINI.md +63 -63
  43. package/.agent/scripts/append_flow.js +72 -0
  44. package/.agent/scripts/case_law_manager.py +525 -0
  45. package/.agent/scripts/compress_skills.py +167 -0
  46. package/.agent/scripts/consolidate_skills.py +173 -0
  47. package/.agent/scripts/deep_compress.py +202 -0
  48. package/.agent/scripts/minify_context.py +80 -0
  49. package/.agent/scripts/security_scan.py +1 -1
  50. package/.agent/scripts/skill_evolution.py +563 -0
  51. package/.agent/scripts/strip_tribunal.py +41 -0
  52. package/.agent/skills/agent-organizer/SKILL.md +100 -126
  53. package/.agent/skills/agentic-patterns/SKILL.md +0 -70
  54. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +134 -160
  55. package/.agent/skills/api-patterns/SKILL.md +123 -215
  56. package/.agent/skills/api-security-auditor/SKILL.md +143 -177
  57. package/.agent/skills/app-builder/SKILL.md +334 -50
  58. package/.agent/skills/app-builder/templates/SKILL.md +13 -15
  59. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +16 -16
  60. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +22 -22
  61. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +18 -18
  62. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +20 -20
  63. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +17 -17
  64. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +18 -18
  65. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +21 -21
  66. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +19 -19
  67. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +26 -26
  68. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +26 -26
  69. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +19 -19
  70. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +18 -18
  71. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +20 -20
  72. package/.agent/skills/appflow-wireframe/SKILL.md +95 -121
  73. package/.agent/skills/architecture/SKILL.md +169 -331
  74. package/.agent/skills/authentication-best-practices/SKILL.md +139 -173
  75. package/.agent/skills/bash-linux/SKILL.md +129 -154
  76. package/.agent/skills/behavioral-modes/SKILL.md +8 -69
  77. package/.agent/skills/brainstorming/SKILL.md +436 -104
  78. package/.agent/skills/building-native-ui/SKILL.md +152 -174
  79. package/.agent/skills/clean-code/SKILL.md +331 -360
  80. package/.agent/skills/code-review-checklist/SKILL.md +0 -62
  81. package/.agent/skills/config-validator/SKILL.md +115 -141
  82. package/.agent/skills/csharp-developer/SKILL.md +468 -528
  83. package/.agent/skills/database-design/SKILL.md +104 -369
  84. package/.agent/skills/deployment-procedures/SKILL.md +119 -145
  85. package/.agent/skills/devops-engineer/SKILL.md +295 -332
  86. package/.agent/skills/devops-incident-responder/SKILL.md +87 -113
  87. package/.agent/skills/doc.md +5 -5
  88. package/.agent/skills/documentation-templates/SKILL.md +27 -63
  89. package/.agent/skills/edge-computing/SKILL.md +131 -157
  90. package/.agent/skills/extract-design-system/SKILL.md +108 -134
  91. package/.agent/skills/framer-motion-expert/SKILL.md +111 -855
  92. package/.agent/skills/frontend-design/SKILL.md +151 -499
  93. package/.agent/skills/game-design-expert/SKILL.md +79 -105
  94. package/.agent/skills/game-engineering-expert/SKILL.md +96 -122
  95. package/.agent/skills/geo-fundamentals/SKILL.md +97 -124
  96. package/.agent/skills/github-operations/SKILL.md +279 -314
  97. package/.agent/skills/gsap-expert/SKILL.md +119 -826
  98. package/.agent/skills/i18n-localization/SKILL.md +113 -138
  99. package/.agent/skills/intelligent-routing/SKILL.md +167 -127
  100. package/.agent/skills/lint-and-validate/SKILL.md +16 -52
  101. package/.agent/skills/llm-engineering/SKILL.md +344 -357
  102. package/.agent/skills/local-first/SKILL.md +128 -154
  103. package/.agent/skills/mcp-builder/SKILL.md +92 -118
  104. package/.agent/skills/mobile-design/SKILL.md +213 -219
  105. package/.agent/skills/motion-engineering/SKILL.md +184 -0
  106. package/.agent/skills/nextjs-react-expert/SKILL.md +99 -698
  107. package/.agent/skills/nodejs-best-practices/SKILL.md +498 -559
  108. package/.agent/skills/observability/SKILL.md +293 -330
  109. package/.agent/skills/parallel-agents/SKILL.md +96 -122
  110. package/.agent/skills/performance-profiling/SKILL.md +217 -254
  111. package/.agent/skills/plan-writing/SKILL.md +92 -118
  112. package/.agent/skills/platform-engineer/SKILL.md +97 -123
  113. package/.agent/skills/playwright-best-practices/SKILL.md +137 -162
  114. package/.agent/skills/powershell-windows/SKILL.md +112 -146
  115. package/.agent/skills/project-idioms/SKILL.md +87 -0
  116. package/.agent/skills/python-patterns/SKILL.md +15 -35
  117. package/.agent/skills/python-pro/SKILL.md +148 -754
  118. package/.agent/skills/react-specialist/SKILL.md +123 -827
  119. package/.agent/skills/readme-builder/SKILL.md +23 -85
  120. package/.agent/skills/realtime-patterns/SKILL.md +269 -304
  121. package/.agent/skills/red-team-tactics/SKILL.md +18 -51
  122. package/.agent/skills/rust-pro/SKILL.md +623 -701
  123. package/.agent/skills/seo-fundamentals/SKILL.md +129 -154
  124. package/.agent/skills/server-management/SKILL.md +164 -190
  125. package/.agent/skills/shadcn-ui-expert/SKILL.md +181 -206
  126. package/.agent/skills/skill-creator/SKILL.md +24 -56
  127. package/.agent/skills/sql-pro/SKILL.md +579 -633
  128. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +35 -66
  129. package/.agent/skills/swiftui-expert/SKILL.md +151 -176
  130. package/.agent/skills/systematic-debugging/SKILL.md +92 -118
  131. package/.agent/skills/tailwind-patterns/SKILL.md +516 -576
  132. package/.agent/skills/tdd-workflow/SKILL.md +111 -137
  133. package/.agent/skills/test-result-analyzer/SKILL.md +33 -73
  134. package/.agent/skills/testing-patterns/SKILL.md +512 -573
  135. package/.agent/skills/trend-researcher/SKILL.md +30 -71
  136. package/.agent/skills/ui-ux-pro-max/SKILL.md +8 -41
  137. package/.agent/skills/ui-ux-researcher/SKILL.md +51 -91
  138. package/.agent/skills/vue-expert/SKILL.md +127 -866
  139. package/.agent/skills/vulnerability-scanner/SKILL.md +354 -269
  140. package/.agent/skills/web-accessibility-auditor/SKILL.md +168 -193
  141. package/.agent/skills/web-design-guidelines/SKILL.md +25 -61
  142. package/.agent/skills/webapp-testing/SKILL.md +119 -145
  143. package/.agent/skills/whimsy-injector/SKILL.md +58 -132
  144. package/.agent/skills/workflow-optimizer/SKILL.md +28 -68
  145. package/.agent/workflows/api-tester.md +151 -151
  146. package/.agent/workflows/audit.md +127 -138
  147. package/.agent/workflows/brainstorm.md +110 -110
  148. package/.agent/workflows/changelog.md +112 -112
  149. package/.agent/workflows/create.md +124 -124
  150. package/.agent/workflows/debug.md +165 -189
  151. package/.agent/workflows/deploy.md +180 -189
  152. package/.agent/workflows/enhance.md +128 -151
  153. package/.agent/workflows/fix.md +114 -135
  154. package/.agent/workflows/generate.md +13 -4
  155. package/.agent/workflows/migrate.md +160 -160
  156. package/.agent/workflows/orchestrate.md +168 -168
  157. package/.agent/workflows/performance-benchmarker.md +114 -123
  158. package/.agent/workflows/plan.md +173 -173
  159. package/.agent/workflows/preview.md +80 -80
  160. package/.agent/workflows/refactor.md +161 -183
  161. package/.agent/workflows/review-ai.md +101 -129
  162. package/.agent/workflows/review.md +116 -116
  163. package/.agent/workflows/session.md +94 -94
  164. package/.agent/workflows/status.md +79 -79
  165. package/.agent/workflows/strengthen-skills.md +138 -139
  166. package/.agent/workflows/swarm.md +179 -179
  167. package/.agent/workflows/test.md +189 -211
  168. package/.agent/workflows/tribunal-backend.md +94 -113
  169. package/.agent/workflows/tribunal-database.md +95 -115
  170. package/.agent/workflows/tribunal-frontend.md +96 -118
  171. package/.agent/workflows/tribunal-full.md +93 -133
  172. package/.agent/workflows/tribunal-mobile.md +95 -119
  173. package/.agent/workflows/tribunal-performance.md +110 -133
  174. package/.agent/workflows/ui-ux-pro-max.md +122 -143
  175. package/README.md +30 -1
  176. package/bin/tribunal-kit.js +175 -12
  177. package/package.json +25 -4
  178. package/.agent/skills/api-patterns/api-style.md +0 -42
  179. package/.agent/skills/api-patterns/auth.md +0 -24
  180. package/.agent/skills/api-patterns/documentation.md +0 -26
  181. package/.agent/skills/api-patterns/graphql.md +0 -41
  182. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  183. package/.agent/skills/api-patterns/response.md +0 -37
  184. package/.agent/skills/api-patterns/rest.md +0 -40
  185. package/.agent/skills/api-patterns/security-testing.md +0 -122
  186. package/.agent/skills/api-patterns/trpc.md +0 -41
  187. package/.agent/skills/api-patterns/versioning.md +0 -22
  188. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  189. package/.agent/skills/app-builder/feature-building.md +0 -53
  190. package/.agent/skills/app-builder/project-detection.md +0 -34
  191. package/.agent/skills/app-builder/scaffolding.md +0 -118
  192. package/.agent/skills/app-builder/tech-stack.md +0 -40
  193. package/.agent/skills/architecture/context-discovery.md +0 -43
  194. package/.agent/skills/architecture/examples.md +0 -94
  195. package/.agent/skills/architecture/pattern-selection.md +0 -68
  196. package/.agent/skills/architecture/patterns-reference.md +0 -50
  197. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  198. package/.agent/skills/brainstorming/dynamic-questioning.md +0 -360
  199. package/.agent/skills/database-design/database-selection.md +0 -43
  200. package/.agent/skills/database-design/indexing.md +0 -39
  201. package/.agent/skills/database-design/migrations.md +0 -48
  202. package/.agent/skills/database-design/optimization.md +0 -36
  203. package/.agent/skills/database-design/orm-selection.md +0 -30
  204. package/.agent/skills/database-design/schema-design.md +0 -56
  205. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  206. package/.agent/skills/frontend-design/color-system.md +0 -329
  207. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  208. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  209. package/.agent/skills/frontend-design/typography-system.md +0 -363
  210. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  211. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  212. package/.agent/skills/intelligent-routing/router-manifest.md +0 -65
  213. package/.agent/skills/mobile-design/decision-trees.md +0 -516
  214. package/.agent/skills/mobile-design/mobile-backend.md +0 -491
  215. package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
  216. package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
  217. package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
  218. package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
  219. package/.agent/skills/mobile-design/mobile-performance.md +0 -767
  220. package/.agent/skills/mobile-design/mobile-testing.md +0 -356
  221. package/.agent/skills/mobile-design/mobile-typography.md +0 -433
  222. package/.agent/skills/mobile-design/platform-android.md +0 -666
  223. package/.agent/skills/mobile-design/platform-ios.md +0 -561
  224. package/.agent/skills/mobile-design/touch-psychology.md +0 -537
  225. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
  226. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
  227. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
  228. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
  229. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
  230. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
  231. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
  232. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
  233. package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
@@ -2,454 +2,189 @@
2
2
  name: database-design
3
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
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
5
+ version: 3.1.0
6
+ last-updated: 2026-04-07
7
+ applies-to-model: gemini-3-1-pro, claude-3-7-sonnet
8
8
  ---
9
9
 
10
10
  # Database Design — Schema & Architecture Mastery
11
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.
12
+ ## Hallucination Traps (Read First)
13
+ - `TIMESTAMP` Always `TIMESTAMPTZ` (with timezone). `TIMESTAMP` is ambiguous across timezones.
14
+ - ❌ UUID v4 as primary key → ✅ UUID v7 (time-ordered) or `BIGINT GENERATED ALWAYS AS IDENTITY`. UUID v4 is random — destroys B-tree index performance on high-insert tables.
15
+ - ❌ No index on foreign keys → ✅ PostgreSQL does NOT auto-index FK columns. Cascading deletes cause full table scans without them.
16
+ - ❌ Adding `NOT NULL` column directly to a large table → ✅ Locks the entire table. Add as nullable, backfill in batches, then add constraint.
17
+ - ❌ Soft delete without a partial index → ✅ Every query must filter `WHERE deleted_at IS NULL`. Add `CREATE INDEX ... WHERE deleted_at IS NULL` or use a view.
18
+ - ❌ Serverless functions without a connection pooler → ✅ Each Lambda/Vercel invocation opens a new connection. Use PgBouncer or Supabase Supavisor — without it, you'll hit `max_connections` instantly.
14
19
 
15
20
  ---
16
21
 
17
- ## Database Selection Matrix
22
+ ## Database Selection
18
23
 
19
24
  ```
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
- └─────────────────────────────────────────────────────────────────────┘
25
+ Relational / Complex queries → PostgreSQL (primary choice)
26
+ Serverless PG → Neon, Supabase
27
+ Edge / Ultra-low latency → Turso (SQLite @ edge)
28
+ Simple / Embedded → SQLite
29
+ Global distribution (MySQL) PlanetScale (no FK support)
30
+
31
+ Key-value / Cache → Redis / Valkey / Upstash
32
+ Document store MongoDB / Firestore
33
+ Full-text search → PostgreSQL tsvector (built-in) or Meilisearch / Typesense
34
+ Time-series → TimescaleDB / ClickHouse
35
+ Vector (AI embeddings) → pgvector (PostgreSQL ext) / Pinecone / Weaviate
50
36
  ```
51
37
 
52
38
  ---
53
39
 
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
40
+ ## Standard Table Template
78
41
 
79
42
  ```sql
80
43
  CREATE TABLE users (
81
44
  id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
82
- -- OR: id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
83
-
84
- -- Core fields
45
+ -- OR: id UUID DEFAULT gen_random_uuid() PRIMARY KEY (use v7 for perf)
85
46
  email TEXT NOT NULL UNIQUE,
86
47
  name TEXT NOT NULL,
87
48
  role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('admin', 'user', 'moderator')),
88
-
89
- -- Status fields
90
49
  is_active BOOLEAN NOT NULL DEFAULT true,
91
-
92
- -- Metadata
93
50
  metadata JSONB DEFAULT '{}',
94
-
95
- -- Timestamps (ALWAYS include these)
96
51
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
97
- updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
52
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
53
+ deleted_at TIMESTAMPTZ -- soft delete
98
54
  );
99
55
 
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
56
+ -- Required: auto-update updated_at
57
+ CREATE OR REPLACE FUNCTION update_updated_at() RETURNS TRIGGER AS $$
58
+ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$ LANGUAGE plpgsql;
59
+ CREATE TRIGGER trg_users_updated_at BEFORE UPDATE ON users FOR EACH ROW EXECUTE FUNCTION update_updated_at();
60
+
61
+ -- Required indexes
115
62
  CREATE INDEX idx_users_email ON users (email);
116
- CREATE INDEX idx_users_role ON users (role) WHERE is_active = true;
63
+ CREATE INDEX idx_users_active ON users (email) WHERE deleted_at IS NULL; -- partial index for soft delete
117
64
  CREATE INDEX idx_users_created_at ON users (created_at DESC);
118
65
  ```
119
66
 
120
- ### ID Strategy
67
+ ---
121
68
 
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
- ```
69
+ ## Schema Patterns
141
70
 
142
71
  ### Relationships
143
-
144
72
  ```sql
145
- -- One-to-Many: foreign key on the "many" side
73
+ -- One-to-Many: FK on the "many" side + INDEX
146
74
  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()
75
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
76
+ author_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
77
+ ...
152
78
  );
153
- CREATE INDEX idx_posts_author_id ON posts (author_id);
79
+ CREATE INDEX idx_posts_author_id ON posts (author_id); -- REQUIRED in Postgres
154
80
 
155
- -- Many-to-Many: junction table
81
+ -- Many-to-Many: junction table with composite PK
156
82
  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(),
83
+ post_id BIGINT NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
84
+ tag_id BIGINT NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
160
85
  PRIMARY KEY (post_id, tag_id)
161
86
  );
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();
87
+ CREATE INDEX idx_post_tags_tag_id ON post_tags (tag_id); -- index the non-PK side
247
88
  ```
248
89
 
249
- ---
250
-
251
- ## Multi-Tenancy Patterns
252
-
90
+ ### Multi-Tenancy
253
91
  ```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)
92
+ -- Pattern 1: tenant_id column (simplest enforce via RLS)
265
93
  ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
266
-
267
94
  CREATE POLICY tenant_isolation ON projects
268
95
  USING (tenant_id = current_setting('app.current_tenant_id')::bigint);
269
96
 
270
- -- Pattern 2: Schema per tenant (better isolation)
271
- CREATE SCHEMA tenant_acme;
272
- CREATE TABLE tenant_acme.projects (...);
97
+ -- Pattern 2: Schema per tenant (better isolation, harder migrations)
98
+ -- CREATE SCHEMA tenant_acme;
273
99
 
274
- -- Pattern 3: Database per tenant (maximum isolation, hardest to manage)
275
- -- Only for compliance/regulatory requirements
100
+ -- Pattern 3: DB per tenant only for compliance/regulatory needs
276
101
  ```
277
102
 
278
103
  ---
279
104
 
280
105
  ## ORM Selection
281
106
 
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)
107
+ | ORM | Best For | Trade-offs |
108
+ |-----|----------|------------|
109
+ | **Drizzle** | Edge, TypeScript, bundle-size sensitive | Newer, fewer examples |
110
+ | **Prisma** | DX, schema management, Prisma Studio | Heavy, NOT edge-compatible |
111
+ | **Kysely** | Type-safe SQL builder, full control | Manual migrations |
112
+ | **Raw SQL** | Complex queries, performance-critical | Manual type safety |
113
+ | **SQLAlchemy 2.0** | Python async ecosystem | Python only |
320
114
 
321
115
  ```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)
116
+ // Drizzle SQL-like, edge-compatible
117
+ const result = await db.select({ id: users.id, name: users.name }).from(users)
336
118
  .where(and(eq(users.role, "admin"), eq(users.isActive, true)))
337
- .orderBy(desc(users.createdAt))
338
- .limit(20);
119
+ .orderBy(desc(users.createdAt)).limit(20);
120
+
121
+ // Prisma — ❌ TRAP: can't express complex joins natively → use prisma.$queryRaw<Type>
122
+ const user = await prisma.user.findUnique({ where: { email }, include: { posts: { take: 10 } } });
339
123
  ```
340
124
 
341
125
  ---
342
126
 
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
- ```
127
+ ## Migrations (Zero-Downtime Strategy)
355
128
 
356
129
  ```sql
357
- -- Safe column addition (zero-downtime deploy)
358
- -- Step 1: Add nullable column
130
+ -- Safe column add on a large production table:
131
+ -- Step 1: Add nullable (no lock)
359
132
  ALTER TABLE users ADD COLUMN phone TEXT;
360
-
361
- -- Step 2: Backfill (in batches to avoid locking)
133
+ -- Step 2: Backfill in batches (non-blocking)
362
134
  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)
135
+ -- Step 3: Add constraint AFTER all code deploys write the column
366
136
  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
137
  ```
372
138
 
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
- ```
139
+ **Migration Rules:**
140
+ - Never modify a migration already applied to production — create a new one
141
+ - Remove column in 2 deploys: first remove all code references, then `DROP COLUMN`
142
+ - `CREATE INDEX CONCURRENTLY` to avoid table locks on existing data
143
+ - Test migrations against a copy of production data before running live
397
144
 
398
145
  ---
399
146
 
400
- ## Output Format
147
+ ## Indexing Reference
401
148
 
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
- ```
149
+ | Index Type | Use For |
150
+ |------------|---------|
151
+ | **B-tree** | General purpose — equality & range queries (default) |
152
+ | **Hash** | Equality-only lookups (faster than B-tree for =) |
153
+ | **GIN** | JSONB, arrays, full-text (`tsvector`) |
154
+ | **GiST** | Geometric, range types |
155
+ | **HNSW / IVFFlat** | Vector similarity (pgvector) |
156
+
157
+ **Composite index column order:** equality columns first → range columns last → most selective first
415
158
 
416
159
  ---
417
160
 
418
- ## 🤖 LLM-Specific Traps
161
+ ## Audit Trail
419
162
 
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.
163
+ ```sql
164
+ CREATE TABLE audit_log (
165
+ id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
166
+ table_name TEXT NOT NULL, record_id BIGINT NOT NULL,
167
+ action TEXT NOT NULL CHECK (action IN ('INSERT', 'UPDATE', 'DELETE')),
168
+ old_data JSONB, new_data JSONB,
169
+ changed_by BIGINT REFERENCES users(id),
170
+ changed_at TIMESTAMPTZ NOT NULL DEFAULT now()
171
+ );
172
+ CREATE INDEX idx_audit_log_table_record ON audit_log (table_name, record_id);
173
+ CREATE INDEX idx_audit_log_changed_at ON audit_log USING brin (changed_at); -- BRIN for time-ordered append-only tables
174
+ ```
430
175
 
431
176
  ---
432
177
 
433
- ## 🏛️ Tribunal Integration
434
-
435
- **Slash command: `/tribunal-database`**
436
-
437
- ### ✅ Pre-Flight Self-Audit
178
+ ## Connection Pooling
438
179
 
439
180
  ```
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
- ```
181
+ Without pooling: 100 concurrent requests 100 DB connections → overwhelms DB
182
+ With pooling: 100 concurrent requests 10–20 reused connections
451
183
 
452
- ### 🛑 VBC Protocol
184
+ Sizing formula: max_connections = (cpu_cores × 2) + disk_spindles (typically 25–50)
453
185
 
454
- - ❌ **Forbidden:** Declaring a schema "optimized" without migration + EXPLAIN evidence.
455
- - **Required:** Provide migration success logs or schema validation output.
186
+ Poolers:
187
+ PgBouncer → External, most common for self-hosted Postgres
188
+ Prisma Accelerate → Managed, for Prisma projects
189
+ Supabase Supavisor → Managed, for Supabase projects
190
+ ```