cfsa-antigravity 2.0.0 → 2.2.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.
- package/README.md +14 -0
- package/package.json +1 -1
- package/template/.agent/instructions/commands.md +8 -32
- package/template/.agent/instructions/example.md +21 -0
- package/template/.agent/instructions/patterns.md +3 -3
- package/template/.agent/instructions/tech-stack.md +71 -23
- package/template/.agent/instructions/workflow.md +12 -1
- package/template/.agent/rules/completion-checklist.md +6 -0
- package/template/.agent/rules/security-first.md +3 -3
- package/template/.agent/rules/vertical-slices.md +1 -1
- package/template/.agent/skill-library/MANIFEST.md +6 -0
- package/template/.agent/skill-library/stack/devops/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/stack/devops/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/api-versioning/SKILL.md +44 -298
- package/template/.agent/skills/api-versioning/references/typescript.md +157 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +13 -13
- package/template/.agent/skills/bootstrap-agents/SKILL.md +151 -152
- package/template/.agent/skills/clean-code/SKILL.md +64 -118
- package/template/.agent/skills/clean-code/references/typescript.md +126 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +93 -317
- package/template/.agent/skills/database-schema-design/references/relational.md +228 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +62 -557
- package/template/.agent/skills/error-handling-patterns/references/go.md +162 -0
- package/template/.agent/skills/error-handling-patterns/references/python.md +262 -0
- package/template/.agent/skills/error-handling-patterns/references/rust.md +112 -0
- package/template/.agent/skills/error-handling-patterns/references/typescript.md +178 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +322 -224
- package/template/.agent/skills/logging-best-practices/SKILL.md +108 -767
- package/template/.agent/skills/logging-best-practices/references/go.md +49 -0
- package/template/.agent/skills/logging-best-practices/references/python.md +52 -0
- package/template/.agent/skills/logging-best-practices/references/typescript.md +215 -0
- package/template/.agent/skills/migration-management/SKILL.md +127 -311
- package/template/.agent/skills/migration-management/references/relational.md +214 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +34 -43
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +1 -1
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +2 -2
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +1 -1
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +2 -1
- package/template/.agent/skills/prd-templates/SKILL.md +23 -6
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +2 -2
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +2 -2
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +2 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +1 -1
- package/template/.agent/skills/prd-templates/references/fractal-cx-template.md +58 -0
- package/template/.agent/skills/prd-templates/references/fractal-feature-template.md +93 -0
- package/template/.agent/skills/prd-templates/references/fractal-node-index-template.md +55 -0
- package/template/.agent/skills/prd-templates/references/ideation-crosscut-template.md +26 -47
- package/template/.agent/skills/prd-templates/references/ideation-index-template.md +47 -31
- package/template/.agent/skills/prd-templates/references/operational-templates.md +1 -1
- package/template/.agent/skills/prd-templates/references/placeholder-workflow-mapping.md +50 -21
- package/template/.agent/skills/prd-templates/references/skill-loading-protocol.md +32 -0
- package/template/.agent/skills/prd-templates/references/slice-completion-gates.md +29 -0
- package/template/.agent/skills/prd-templates/references/spec-coverage-sweep.md +3 -3
- package/template/.agent/skills/prd-templates/references/tdd-testing-policy.md +39 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +8 -8
- package/template/.agent/skills/regex-patterns/SKILL.md +122 -540
- package/template/.agent/skills/regex-patterns/references/go.md +44 -0
- package/template/.agent/skills/regex-patterns/references/javascript.md +63 -0
- package/template/.agent/skills/regex-patterns/references/python.md +77 -0
- package/template/.agent/skills/regex-patterns/references/rust.md +43 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +1 -1
- package/template/.agent/skills/session-continuity/SKILL.md +11 -9
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +2 -2
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +57 -78
- package/template/.agent/skills/session-continuity/protocols/11-parallel-synthesis.md +1 -1
- package/template/.agent/skills/spec-writing/SKILL.md +1 -1
- package/template/.agent/skills/tdd-workflow/SKILL.md +94 -317
- package/template/.agent/skills/tdd-workflow/references/typescript.md +231 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +74 -687
- package/template/.agent/skills/testing-strategist/references/typescript.md +328 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +62 -154
- package/template/.agent/skills/workflow-automation/references/inngest.md +88 -0
- package/template/.agent/skills/workflow-automation/references/temporal.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +85 -143
- package/template/.agent/workflows/bootstrap-agents-provision.md +90 -107
- package/template/.agent/workflows/create-prd-architecture.md +23 -16
- package/template/.agent/workflows/create-prd-compile.md +11 -12
- package/template/.agent/workflows/create-prd-design-system.md +1 -1
- package/template/.agent/workflows/create-prd-security.md +9 -11
- package/template/.agent/workflows/create-prd-stack.md +10 -4
- package/template/.agent/workflows/create-prd.md +9 -9
- package/template/.agent/workflows/decompose-architecture-structure.md +4 -6
- package/template/.agent/workflows/decompose-architecture-validate.md +18 -1
- package/template/.agent/workflows/decompose-architecture.md +18 -3
- package/template/.agent/workflows/evolve-contract.md +11 -11
- package/template/.agent/workflows/evolve-feature-classify.md +14 -6
- package/template/.agent/workflows/ideate-discover.md +72 -107
- package/template/.agent/workflows/ideate-extract.md +84 -63
- package/template/.agent/workflows/ideate-validate.md +26 -22
- package/template/.agent/workflows/ideate.md +9 -9
- package/template/.agent/workflows/implement-slice-setup.md +25 -23
- package/template/.agent/workflows/implement-slice-tdd.md +73 -89
- package/template/.agent/workflows/implement-slice.md +4 -4
- package/template/.agent/workflows/plan-phase-preflight.md +6 -2
- package/template/.agent/workflows/plan-phase-write.md +6 -8
- package/template/.agent/workflows/remediate-pipeline-assess.md +2 -1
- package/template/.agent/workflows/resolve-ambiguity.md +2 -2
- package/template/.agent/workflows/update-architecture-map.md +22 -5
- package/template/.agent/workflows/validate-phase-quality.md +155 -0
- package/template/.agent/workflows/validate-phase-readiness.md +167 -0
- package/template/.agent/workflows/validate-phase.md +19 -157
- package/template/.agent/workflows/verify-infrastructure.md +10 -10
- package/template/.agent/workflows/write-architecture-spec-design.md +23 -14
- package/template/.agent/workflows/write-be-spec-classify.md +25 -21
- package/template/.agent/workflows/write-be-spec.md +1 -1
- package/template/.agent/workflows/write-fe-spec-classify.md +6 -12
- package/template/.agent/workflows/write-fe-spec-write.md +1 -1
- package/template/AGENTS.md +6 -2
- package/template/GEMINI.md +5 -3
- package/template/docs/README.md +10 -10
- package/template/docs/kit-architecture.md +126 -33
- package/template/docs/plans/ideation/README.md +8 -3
- package/template/.agent/skills/prd-templates/references/ideation-domain-template.md +0 -55
|
@@ -1,359 +1,133 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: database-schema-design
|
|
3
|
-
description: Design database schemas with normalization, relationships, and constraints. Use when creating new database schemas, designing tables, or planning data models for
|
|
3
|
+
description: Design database schemas with normalization, relationships, and constraints. Use when creating new database schemas, designing tables, or planning data models for any database paradigm.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Database Schema Design
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
Design scalable,
|
|
10
|
+
Design scalable, well-structured database schemas with proper relationships, constraints, and data types. This skill covers universal data modeling principles. For paradigm-specific patterns, see references.
|
|
11
11
|
|
|
12
12
|
## When to Use
|
|
13
13
|
|
|
14
14
|
- New database schema design
|
|
15
15
|
- Data model planning
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- Constraint and trigger planning
|
|
16
|
+
- Relationship design (1:1, 1:N, N:N, graph edges)
|
|
17
|
+
- Normalization or denormalization analysis
|
|
18
|
+
- Constraint and validation planning
|
|
20
19
|
- Performance optimization at schema level
|
|
20
|
+
- Cross-store entity consistency
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
### First Normal Form (1NF)
|
|
25
|
-
|
|
26
|
-
**PostgreSQL - Eliminate Repeating Groups:**
|
|
27
|
-
|
|
28
|
-
```sql
|
|
29
|
-
-- NOT 1NF: repeating group in single column
|
|
30
|
-
CREATE TABLE orders_bad (
|
|
31
|
-
id UUID PRIMARY KEY,
|
|
32
|
-
customer_name VARCHAR(255),
|
|
33
|
-
product_ids VARCHAR(255) -- "1,2,3" - repeating group
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
-- 1NF: separate table for repeating data
|
|
37
|
-
CREATE TABLE orders (
|
|
38
|
-
id UUID PRIMARY KEY,
|
|
39
|
-
customer_name VARCHAR(255),
|
|
40
|
-
created_at TIMESTAMP DEFAULT NOW()
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
CREATE TABLE order_items (
|
|
44
|
-
id UUID PRIMARY KEY,
|
|
45
|
-
order_id UUID NOT NULL,
|
|
46
|
-
product_id UUID NOT NULL,
|
|
47
|
-
quantity INTEGER NOT NULL,
|
|
48
|
-
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE
|
|
49
|
-
);
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Second Normal Form (2NF)
|
|
53
|
-
|
|
54
|
-
**PostgreSQL - Remove Partial Dependencies:**
|
|
55
|
-
|
|
56
|
-
```sql
|
|
57
|
-
-- NOT 2NF: non-key attribute depends on part of composite key
|
|
58
|
-
CREATE TABLE enrollment_bad (
|
|
59
|
-
student_id UUID,
|
|
60
|
-
course_id UUID,
|
|
61
|
-
professor_name VARCHAR(255), -- depends on course_id only
|
|
62
|
-
PRIMARY KEY (student_id, course_id)
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
-- 2NF: separate tables
|
|
66
|
-
CREATE TABLE enrollments (
|
|
67
|
-
id UUID PRIMARY KEY,
|
|
68
|
-
student_id UUID NOT NULL,
|
|
69
|
-
course_id UUID NOT NULL,
|
|
70
|
-
FOREIGN KEY (student_id) REFERENCES students(id),
|
|
71
|
-
FOREIGN KEY (course_id) REFERENCES courses(id),
|
|
72
|
-
UNIQUE(student_id, course_id)
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
CREATE TABLE courses (
|
|
76
|
-
id UUID PRIMARY KEY,
|
|
77
|
-
name VARCHAR(255),
|
|
78
|
-
professor_id UUID NOT NULL,
|
|
79
|
-
FOREIGN KEY (professor_id) REFERENCES professors(id)
|
|
80
|
-
);
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### Third Normal Form (3NF)
|
|
84
|
-
|
|
85
|
-
**PostgreSQL - Remove Transitive Dependencies:**
|
|
86
|
-
|
|
87
|
-
```sql
|
|
88
|
-
-- NOT 3NF: transitive dependency (customer_city depends on customer_state)
|
|
89
|
-
CREATE TABLE orders_bad (
|
|
90
|
-
id UUID PRIMARY KEY,
|
|
91
|
-
customer_city VARCHAR(100),
|
|
92
|
-
customer_state VARCHAR(50),
|
|
93
|
-
state_tax_rate DECIMAL(5,3) -- depends on customer_state
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
-- 3NF: separate tables
|
|
97
|
-
CREATE TABLE states (
|
|
98
|
-
id UUID PRIMARY KEY,
|
|
99
|
-
code VARCHAR(2) UNIQUE,
|
|
100
|
-
name VARCHAR(100),
|
|
101
|
-
tax_rate DECIMAL(5,3)
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
CREATE TABLE orders (
|
|
105
|
-
id UUID PRIMARY KEY,
|
|
106
|
-
customer_city VARCHAR(100),
|
|
107
|
-
state_id UUID NOT NULL,
|
|
108
|
-
FOREIGN KEY (state_id) REFERENCES states(id)
|
|
109
|
-
);
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Table Design Patterns
|
|
113
|
-
|
|
114
|
-
### Entity-Relationship Patterns
|
|
115
|
-
|
|
116
|
-
**PostgreSQL - One-to-Many:**
|
|
117
|
-
|
|
118
|
-
```sql
|
|
119
|
-
-- One user has many orders
|
|
120
|
-
CREATE TABLE users (
|
|
121
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
122
|
-
email VARCHAR(255) UNIQUE NOT NULL,
|
|
123
|
-
name VARCHAR(255) NOT NULL,
|
|
124
|
-
created_at TIMESTAMP DEFAULT NOW()
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
CREATE TABLE orders (
|
|
128
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
129
|
-
user_id UUID NOT NULL,
|
|
130
|
-
order_date TIMESTAMP DEFAULT NOW(),
|
|
131
|
-
total DECIMAL(10,2),
|
|
132
|
-
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
133
|
-
INDEX idx_user_id (user_id)
|
|
134
|
-
);
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**PostgreSQL - One-to-One:**
|
|
138
|
-
|
|
139
|
-
```sql
|
|
140
|
-
-- One user has one profile
|
|
141
|
-
CREATE TABLE user_profiles (
|
|
142
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
143
|
-
user_id UUID UNIQUE NOT NULL,
|
|
144
|
-
bio TEXT,
|
|
145
|
-
avatar_url VARCHAR(500),
|
|
146
|
-
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
147
|
-
);
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**PostgreSQL - Many-to-Many:**
|
|
151
|
-
|
|
152
|
-
```sql
|
|
153
|
-
-- Students and courses (many-to-many)
|
|
154
|
-
CREATE TABLE students (
|
|
155
|
-
id UUID PRIMARY KEY,
|
|
156
|
-
name VARCHAR(255)
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
CREATE TABLE courses (
|
|
160
|
-
id UUID PRIMARY KEY,
|
|
161
|
-
title VARCHAR(255)
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
-- Junction table
|
|
165
|
-
CREATE TABLE course_enrollments (
|
|
166
|
-
id UUID PRIMARY KEY,
|
|
167
|
-
student_id UUID NOT NULL,
|
|
168
|
-
course_id UUID NOT NULL,
|
|
169
|
-
enrolled_at TIMESTAMP DEFAULT NOW(),
|
|
170
|
-
FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,
|
|
171
|
-
FOREIGN KEY (course_id) REFERENCES courses(id) ON DELETE CASCADE,
|
|
172
|
-
UNIQUE(student_id, course_id)
|
|
173
|
-
);
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## Constraint Strategy
|
|
177
|
-
|
|
178
|
-
**PostgreSQL - Data Integrity:**
|
|
179
|
-
|
|
180
|
-
```sql
|
|
181
|
-
-- NOT NULL constraints
|
|
182
|
-
CREATE TABLE products (
|
|
183
|
-
id UUID PRIMARY KEY,
|
|
184
|
-
name VARCHAR(255) NOT NULL,
|
|
185
|
-
sku VARCHAR(100) NOT NULL,
|
|
186
|
-
price DECIMAL(10,2) NOT NULL
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
-- UNIQUE constraints
|
|
190
|
-
ALTER TABLE products
|
|
191
|
-
ADD CONSTRAINT unique_sku UNIQUE(sku);
|
|
192
|
-
|
|
193
|
-
-- CHECK constraints
|
|
194
|
-
ALTER TABLE products
|
|
195
|
-
ADD CONSTRAINT price_positive CHECK (price > 0);
|
|
196
|
-
|
|
197
|
-
ALTER TABLE orders
|
|
198
|
-
ADD CONSTRAINT valid_status
|
|
199
|
-
CHECK (status IN ('pending', 'processing', 'completed', 'cancelled'));
|
|
200
|
-
|
|
201
|
-
-- DEFAULT values
|
|
202
|
-
CREATE TABLE audit_logs (
|
|
203
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
204
|
-
table_name VARCHAR(100) NOT NULL,
|
|
205
|
-
operation VARCHAR(10) NOT NULL,
|
|
206
|
-
user_id UUID,
|
|
207
|
-
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
208
|
-
);
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## Data Type Selection
|
|
212
|
-
|
|
213
|
-
**PostgreSQL - Optimal Data Types:**
|
|
214
|
-
|
|
215
|
-
```sql
|
|
216
|
-
CREATE TABLE users (
|
|
217
|
-
-- Identifiers
|
|
218
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
219
|
-
|
|
220
|
-
-- Text fields
|
|
221
|
-
email VARCHAR(255), -- Fixed length for emails
|
|
222
|
-
name TEXT, -- Unbounded text
|
|
223
|
-
bio TEXT,
|
|
224
|
-
|
|
225
|
-
-- Numeric data
|
|
226
|
-
age SMALLINT, -- 0-32767
|
|
227
|
-
balance DECIMAL(15,2), -- Financial data (precise)
|
|
228
|
-
rating NUMERIC(3,1), -- Range 0.0-9.9
|
|
229
|
-
|
|
230
|
-
-- Boolean
|
|
231
|
-
is_active BOOLEAN DEFAULT true,
|
|
232
|
-
email_verified BOOLEAN,
|
|
233
|
-
|
|
234
|
-
-- Dates and Times
|
|
235
|
-
birth_date DATE,
|
|
236
|
-
last_login TIMESTAMP WITH TIME ZONE,
|
|
237
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
238
|
-
|
|
239
|
-
-- JSON/Binary
|
|
240
|
-
metadata JSONB,
|
|
241
|
-
profile_image BYTEA,
|
|
242
|
-
|
|
243
|
-
-- Arrays (PostgreSQL specific)
|
|
244
|
-
tags TEXT[] DEFAULT ARRAY[]::TEXT[]
|
|
245
|
-
);
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**MySQL - Compatible Data Types:**
|
|
22
|
+
## Paradigm-Specific References
|
|
249
23
|
|
|
250
|
-
|
|
251
|
-
CREATE TABLE users (
|
|
252
|
-
id CHAR(36) PRIMARY KEY, -- UUID as CHAR
|
|
253
|
-
|
|
254
|
-
email VARCHAR(255),
|
|
255
|
-
name VARCHAR(255),
|
|
256
|
-
|
|
257
|
-
age TINYINT UNSIGNED,
|
|
258
|
-
balance DECIMAL(15,2),
|
|
259
|
-
|
|
260
|
-
is_active BOOLEAN DEFAULT true,
|
|
24
|
+
After reading the methodology below, read the reference matching your surface's Databases column in the surface stack map (`.agent/instructions/tech-stack.md`):
|
|
261
25
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
26
|
+
| Paradigm | Reference | Example Stores |
|
|
27
|
+
|----------|-----------|----------------|
|
|
28
|
+
| Relational | `references/relational.md` | PostgreSQL, MySQL, SQLite |
|
|
29
|
+
| Document | `references/document.md` | MongoDB, Firestore, CouchDB |
|
|
30
|
+
| Graph | `references/graph.md` | SurrealDB, Neo4j, ArangoDB |
|
|
31
|
+
| Key-Value | `references/key-value.md` | Redis, DynamoDB, Memcached |
|
|
265
32
|
|
|
266
|
-
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Universal Data Modeling Principles
|
|
267
36
|
|
|
268
|
-
|
|
269
|
-
);
|
|
270
|
-
```
|
|
37
|
+
### 1. Entity Identification
|
|
271
38
|
|
|
272
|
-
|
|
39
|
+
Start with the domain:
|
|
40
|
+
1. **Identify nouns** — these become entities/tables/collections
|
|
41
|
+
2. **Identify relationships** — how entities connect
|
|
42
|
+
3. **Identify attributes** — what data each entity holds
|
|
43
|
+
4. **Identify cardinality** — one-to-one, one-to-many, many-to-many
|
|
273
44
|
|
|
274
|
-
|
|
45
|
+
### 2. Normalization vs Denormalization
|
|
275
46
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
47
|
+
**Normalization** reduces data duplication at the cost of join complexity:
|
|
48
|
+
- **1NF** — Eliminate repeating groups (no arrays/CSVs in a single field)
|
|
49
|
+
- **2NF** — Remove partial dependencies (every non-key attribute depends on the WHOLE key)
|
|
50
|
+
- **3NF** — Remove transitive dependencies (non-key attributes don't depend on each other)
|
|
279
51
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
52
|
+
**Denormalization** trades storage for read performance:
|
|
53
|
+
- Embed frequently co-read data together
|
|
54
|
+
- Pre-compute aggregates for dashboards
|
|
55
|
+
- Duplicate data intentionally (with consistency strategy)
|
|
283
56
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
57
|
+
**Decision framework:**
|
|
58
|
+
- Write-heavy, consistency-critical → normalize
|
|
59
|
+
- Read-heavy, latency-sensitive → denormalize
|
|
60
|
+
- Mixed → normalize core, denormalize read models
|
|
287
61
|
|
|
288
|
-
|
|
289
|
-
ALTER TABLE users RENAME COLUMN old_field TO old_field_deprecated;
|
|
290
|
-
```
|
|
62
|
+
### 3. Relationship Patterns
|
|
291
63
|
|
|
292
|
-
|
|
64
|
+
| Pattern | Relational | Document | Graph |
|
|
65
|
+
|---------|-----------|----------|-------|
|
|
66
|
+
| **One-to-One** | Foreign key with UNIQUE | Embed subdocument | Edge with cardinality constraint |
|
|
67
|
+
| **One-to-Many** | Foreign key on child | Embed array OR reference | Edge from parent to children |
|
|
68
|
+
| **Many-to-Many** | Junction/join table | Array of references on both sides | Direct edges |
|
|
69
|
+
| **Hierarchical** | Self-referencing FK | Nested documents | Recursive graph traversal |
|
|
293
70
|
|
|
294
|
-
|
|
295
|
-
-- Add column with default
|
|
296
|
-
ALTER TABLE users ADD COLUMN phone VARCHAR(20) DEFAULT '';
|
|
71
|
+
### 4. Access Pattern Design
|
|
297
72
|
|
|
298
|
-
|
|
299
|
-
ALTER TABLE orders
|
|
300
|
-
ADD COLUMN notes TEXT DEFAULT '',
|
|
301
|
-
ADD COLUMN internal_status VARCHAR(50);
|
|
73
|
+
Schema design is driven by how data is **queried**, not just how it's structured:
|
|
302
74
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
75
|
+
1. **List your read queries** — what does the UI need to display?
|
|
76
|
+
2. **List your write queries** — what creates/updates data?
|
|
77
|
+
3. **Design schema to serve the reads** — not the other way around
|
|
78
|
+
4. **Index for query patterns** — not for every possible query
|
|
306
79
|
|
|
307
|
-
|
|
80
|
+
### 5. Constraint Strategy
|
|
308
81
|
|
|
309
|
-
|
|
82
|
+
Every schema must enforce:
|
|
83
|
+
- **Required fields** — NOT NULL / required validators
|
|
84
|
+
- **Uniqueness** — unique constraints on natural keys (email, SKU, slug)
|
|
85
|
+
- **Referential integrity** — foreign keys, references, or application-level checks
|
|
86
|
+
- **Domain constraints** — CHECK constraints, enums, value ranges
|
|
87
|
+
- **Cascade behavior** — what happens when parent is deleted (CASCADE, SET NULL, RESTRICT)
|
|
310
88
|
|
|
311
|
-
|
|
312
|
-
-- Partition by date range for time-series data
|
|
313
|
-
CREATE TABLE events (
|
|
314
|
-
id UUID PRIMARY KEY,
|
|
315
|
-
user_id UUID NOT NULL,
|
|
316
|
-
event_type VARCHAR(100),
|
|
317
|
-
created_at TIMESTAMP NOT NULL
|
|
318
|
-
) PARTITION BY RANGE (DATE_TRUNC('month', created_at));
|
|
89
|
+
### 6. ID Strategy
|
|
319
90
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
91
|
+
| Strategy | When to Use |
|
|
92
|
+
|----------|-------------|
|
|
93
|
+
| **UUID v4** | Default choice. No ordering, globally unique, no collision |
|
|
94
|
+
| **UUID v7** | When you need time-sortable UUIDs (better index performance) |
|
|
95
|
+
| **Auto-increment** | Simple cases, single-database, non-distributed |
|
|
96
|
+
| **ULID** | Time-sortable, lexicographically sortable, URL-safe |
|
|
97
|
+
| **Natural key** | When domain provides a unique identifier (ISBN, SSN) — use with caution |
|
|
98
|
+
|
|
99
|
+
---
|
|
323
100
|
|
|
324
101
|
## Schema Design Checklist
|
|
325
102
|
|
|
326
|
-
- Identify entities and relationships
|
|
327
|
-
-
|
|
328
|
-
-
|
|
329
|
-
-
|
|
330
|
-
-
|
|
331
|
-
-
|
|
332
|
-
-
|
|
333
|
-
-
|
|
334
|
-
-
|
|
335
|
-
-
|
|
103
|
+
- [ ] Identify entities and relationships
|
|
104
|
+
- [ ] Choose ID strategy
|
|
105
|
+
- [ ] Apply normalization rules (or consciously denormalize with rationale)
|
|
106
|
+
- [ ] Define primary keys for all entities
|
|
107
|
+
- [ ] Create foreign keys / references for relationships
|
|
108
|
+
- [ ] Add constraints for data integrity
|
|
109
|
+
- [ ] Select appropriate data types
|
|
110
|
+
- [ ] Plan indexes for common queries
|
|
111
|
+
- [ ] Design for scalability
|
|
112
|
+
- [ ] Document entity purposes and relationships
|
|
113
|
+
- [ ] Plan for schema evolution
|
|
336
114
|
|
|
337
115
|
## Common Pitfalls
|
|
338
116
|
|
|
339
117
|
❌ Don't skip normalization for convenience
|
|
340
|
-
❌ Don't use
|
|
341
|
-
❌ Don't forget
|
|
342
|
-
❌ Don't use natural keys as primary keys
|
|
343
|
-
❌ Don't store
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
✅ DO
|
|
347
|
-
✅ DO
|
|
348
|
-
✅ DO
|
|
349
|
-
✅ DO
|
|
118
|
+
❌ Don't use unbounded text types for all string fields
|
|
119
|
+
❌ Don't forget referential integrity constraints
|
|
120
|
+
❌ Don't use mutable natural keys as primary keys
|
|
121
|
+
❌ Don't store computed values without a cache invalidation strategy
|
|
122
|
+
❌ Don't design schema without knowing query patterns
|
|
123
|
+
|
|
124
|
+
✅ DO use UUIDs or equivalent for primary keys
|
|
125
|
+
✅ DO normalize data unless you have a measured performance reason not to
|
|
126
|
+
✅ DO add validation constraints at the schema level
|
|
127
|
+
✅ DO index foreign keys and common query fields
|
|
128
|
+
✅ DO use timestamps for audit trails
|
|
350
129
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
- [PostgreSQL Data Types](https://www.postgresql.org/docs/current/datatype.html)
|
|
354
|
-
- [MySQL Data Types](https://dev.mysql.com/doc/refman/8.0/en/data-types.html)
|
|
355
|
-
- [Database Normalization Guide](https://en.wikipedia.org/wiki/Database_normalization)
|
|
356
|
-
- [Draw.io](https://draw.io/) - Schema diagram tool
|
|
130
|
+
---
|
|
357
131
|
|
|
358
132
|
## Persistence Map Interview
|
|
359
133
|
|
|
@@ -392,7 +166,7 @@ For each confirmed store, fire bootstrap with its specific sub-key:
|
|
|
392
166
|
|
|
393
167
|
- e.g., `DATABASE_PRIMARY=PostgreSQL`, `DATABASE_VECTOR=Qdrant`
|
|
394
168
|
- One bootstrap call per sub-key.
|
|
395
|
-
- Each confirmation
|
|
169
|
+
- Each confirmation adds a database skill to the Databases column of the relevant surface row in the surface stack map.
|
|
396
170
|
|
|
397
171
|
### Sub-step E — Write Persistence Map
|
|
398
172
|
|
|
@@ -402,6 +176,8 @@ Must include:
|
|
|
402
176
|
- The feature-to-query table from Sub-step A
|
|
403
177
|
- A mapping of each query type to its canonical store with rationale
|
|
404
178
|
|
|
179
|
+
---
|
|
180
|
+
|
|
405
181
|
## Cross-Store Entity Consistency Protocol
|
|
406
182
|
|
|
407
183
|
### Triggering Rule
|
|
@@ -422,7 +198,7 @@ For each cross-store entity, answer the following in order:
|
|
|
422
198
|
|
|
423
199
|
### Skill Instruction
|
|
424
200
|
|
|
425
|
-
Read all skills in `
|
|
201
|
+
Read all database skills listed in the Databases column of the surface stack map (`.agent/instructions/tech-stack.md`) for advice on each store's transaction semantics and consistency guarantees before completing this step.
|
|
426
202
|
|
|
427
203
|
### Output
|
|
428
204
|
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Relational Database Schema Patterns
|
|
2
|
+
|
|
3
|
+
Paradigm-specific patterns for the `database-schema-design` skill. Read `SKILL.md` first for universal methodology.
|
|
4
|
+
|
|
5
|
+
Covers: **PostgreSQL**, **MySQL**, **SQLite**
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Normalization Examples
|
|
10
|
+
|
|
11
|
+
### First Normal Form (1NF) — Eliminate Repeating Groups
|
|
12
|
+
|
|
13
|
+
```sql
|
|
14
|
+
-- NOT 1NF: repeating group in single column
|
|
15
|
+
CREATE TABLE orders_bad (
|
|
16
|
+
id UUID PRIMARY KEY,
|
|
17
|
+
customer_name VARCHAR(255),
|
|
18
|
+
product_ids VARCHAR(255) -- "1,2,3" - repeating group
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
-- 1NF: separate table for repeating data
|
|
22
|
+
CREATE TABLE orders (
|
|
23
|
+
id UUID PRIMARY KEY,
|
|
24
|
+
customer_name VARCHAR(255),
|
|
25
|
+
created_at TIMESTAMP DEFAULT NOW()
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE TABLE order_items (
|
|
29
|
+
id UUID PRIMARY KEY,
|
|
30
|
+
order_id UUID NOT NULL,
|
|
31
|
+
product_id UUID NOT NULL,
|
|
32
|
+
quantity INTEGER NOT NULL,
|
|
33
|
+
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE
|
|
34
|
+
);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Second Normal Form (2NF) — Remove Partial Dependencies
|
|
38
|
+
|
|
39
|
+
```sql
|
|
40
|
+
-- 2NF: separate tables for partial deps
|
|
41
|
+
CREATE TABLE enrollments (
|
|
42
|
+
id UUID PRIMARY KEY,
|
|
43
|
+
student_id UUID NOT NULL,
|
|
44
|
+
course_id UUID NOT NULL,
|
|
45
|
+
FOREIGN KEY (student_id) REFERENCES students(id),
|
|
46
|
+
FOREIGN KEY (course_id) REFERENCES courses(id),
|
|
47
|
+
UNIQUE(student_id, course_id)
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TABLE courses (
|
|
51
|
+
id UUID PRIMARY KEY,
|
|
52
|
+
name VARCHAR(255),
|
|
53
|
+
professor_id UUID NOT NULL,
|
|
54
|
+
FOREIGN KEY (professor_id) REFERENCES professors(id)
|
|
55
|
+
);
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Third Normal Form (3NF) — Remove Transitive Dependencies
|
|
59
|
+
|
|
60
|
+
```sql
|
|
61
|
+
-- 3NF: separate lookup tables
|
|
62
|
+
CREATE TABLE states (
|
|
63
|
+
id UUID PRIMARY KEY,
|
|
64
|
+
code VARCHAR(2) UNIQUE,
|
|
65
|
+
name VARCHAR(100),
|
|
66
|
+
tax_rate DECIMAL(5,3)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
CREATE TABLE orders (
|
|
70
|
+
id UUID PRIMARY KEY,
|
|
71
|
+
customer_city VARCHAR(100),
|
|
72
|
+
state_id UUID NOT NULL,
|
|
73
|
+
FOREIGN KEY (state_id) REFERENCES states(id)
|
|
74
|
+
);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Relationship Patterns
|
|
80
|
+
|
|
81
|
+
### One-to-Many
|
|
82
|
+
|
|
83
|
+
```sql
|
|
84
|
+
CREATE TABLE users (
|
|
85
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
86
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
87
|
+
name VARCHAR(255) NOT NULL,
|
|
88
|
+
created_at TIMESTAMP DEFAULT NOW()
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
CREATE TABLE orders (
|
|
92
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
93
|
+
user_id UUID NOT NULL,
|
|
94
|
+
order_date TIMESTAMP DEFAULT NOW(),
|
|
95
|
+
total DECIMAL(10,2),
|
|
96
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
97
|
+
);
|
|
98
|
+
CREATE INDEX idx_orders_user_id ON orders(user_id);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### One-to-One
|
|
102
|
+
|
|
103
|
+
```sql
|
|
104
|
+
CREATE TABLE user_profiles (
|
|
105
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
106
|
+
user_id UUID UNIQUE NOT NULL,
|
|
107
|
+
bio TEXT,
|
|
108
|
+
avatar_url VARCHAR(500),
|
|
109
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
110
|
+
);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Many-to-Many (Junction Table)
|
|
114
|
+
|
|
115
|
+
```sql
|
|
116
|
+
CREATE TABLE course_enrollments (
|
|
117
|
+
id UUID PRIMARY KEY,
|
|
118
|
+
student_id UUID NOT NULL,
|
|
119
|
+
course_id UUID NOT NULL,
|
|
120
|
+
enrolled_at TIMESTAMP DEFAULT NOW(),
|
|
121
|
+
FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,
|
|
122
|
+
FOREIGN KEY (course_id) REFERENCES courses(id) ON DELETE CASCADE,
|
|
123
|
+
UNIQUE(student_id, course_id)
|
|
124
|
+
);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Constraint Strategy
|
|
130
|
+
|
|
131
|
+
```sql
|
|
132
|
+
-- NOT NULL, UNIQUE, CHECK, DEFAULT
|
|
133
|
+
CREATE TABLE products (
|
|
134
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
135
|
+
name VARCHAR(255) NOT NULL,
|
|
136
|
+
sku VARCHAR(100) NOT NULL UNIQUE,
|
|
137
|
+
price DECIMAL(10,2) NOT NULL CHECK (price > 0),
|
|
138
|
+
status VARCHAR(20) NOT NULL CHECK (status IN ('active', 'archived', 'draft'))
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
CREATE TABLE audit_logs (
|
|
142
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
143
|
+
table_name VARCHAR(100) NOT NULL,
|
|
144
|
+
operation VARCHAR(10) NOT NULL,
|
|
145
|
+
user_id UUID,
|
|
146
|
+
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
147
|
+
);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Data Type Selection
|
|
153
|
+
|
|
154
|
+
### PostgreSQL
|
|
155
|
+
|
|
156
|
+
```sql
|
|
157
|
+
CREATE TABLE users (
|
|
158
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
159
|
+
email VARCHAR(255),
|
|
160
|
+
name TEXT,
|
|
161
|
+
age SMALLINT,
|
|
162
|
+
balance DECIMAL(15,2), -- Financial data (precise)
|
|
163
|
+
is_active BOOLEAN DEFAULT true,
|
|
164
|
+
birth_date DATE,
|
|
165
|
+
last_login TIMESTAMP WITH TIME ZONE,
|
|
166
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
167
|
+
metadata JSONB,
|
|
168
|
+
tags TEXT[] DEFAULT ARRAY[]::TEXT[] -- PostgreSQL arrays
|
|
169
|
+
);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### MySQL
|
|
173
|
+
|
|
174
|
+
```sql
|
|
175
|
+
CREATE TABLE users (
|
|
176
|
+
id CHAR(36) PRIMARY KEY, -- UUID as CHAR
|
|
177
|
+
email VARCHAR(255),
|
|
178
|
+
name VARCHAR(255),
|
|
179
|
+
age TINYINT UNSIGNED,
|
|
180
|
+
balance DECIMAL(15,2),
|
|
181
|
+
is_active BOOLEAN DEFAULT true,
|
|
182
|
+
birth_date DATE,
|
|
183
|
+
last_login TIMESTAMP,
|
|
184
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
185
|
+
metadata JSON,
|
|
186
|
+
KEY idx_email (email)
|
|
187
|
+
);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Schema Evolution
|
|
193
|
+
|
|
194
|
+
```sql
|
|
195
|
+
-- Add column with default (backward compatible)
|
|
196
|
+
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
|
|
197
|
+
|
|
198
|
+
-- Add constraint on new column
|
|
199
|
+
ALTER TABLE orders ADD CONSTRAINT check_notes CHECK (LENGTH(notes) <= 500);
|
|
200
|
+
|
|
201
|
+
-- Deprecate column safely
|
|
202
|
+
ALTER TABLE users RENAME COLUMN old_field TO old_field_deprecated;
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Performance: Partitioning
|
|
208
|
+
|
|
209
|
+
```sql
|
|
210
|
+
-- PostgreSQL: Partition by date range for time-series data
|
|
211
|
+
CREATE TABLE events (
|
|
212
|
+
id UUID PRIMARY KEY,
|
|
213
|
+
user_id UUID NOT NULL,
|
|
214
|
+
event_type VARCHAR(100),
|
|
215
|
+
created_at TIMESTAMP NOT NULL
|
|
216
|
+
) PARTITION BY RANGE (DATE_TRUNC('month', created_at));
|
|
217
|
+
|
|
218
|
+
CREATE TABLE events_2024_01 PARTITION OF events
|
|
219
|
+
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Resources
|
|
225
|
+
|
|
226
|
+
- [PostgreSQL Data Types](https://www.postgresql.org/docs/current/datatype.html)
|
|
227
|
+
- [MySQL Data Types](https://dev.mysql.com/doc/refman/8.0/en/data-types.html)
|
|
228
|
+
- [Database Normalization Guide](https://en.wikipedia.org/wiki/Database_normalization)
|