@aicgen/aicgen 1.0.0-beta.1
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/.claude/agents/architecture-reviewer.md +88 -0
- package/.claude/agents/guideline-checker.md +73 -0
- package/.claude/agents/security-auditor.md +108 -0
- package/.claude/guidelines/api-design.md +645 -0
- package/.claude/guidelines/architecture.md +2503 -0
- package/.claude/guidelines/best-practices.md +618 -0
- package/.claude/guidelines/code-style.md +304 -0
- package/.claude/guidelines/design-patterns.md +573 -0
- package/.claude/guidelines/devops.md +226 -0
- package/.claude/guidelines/error-handling.md +413 -0
- package/.claude/guidelines/language.md +782 -0
- package/.claude/guidelines/performance.md +706 -0
- package/.claude/guidelines/security.md +583 -0
- package/.claude/guidelines/testing.md +568 -0
- package/.claude/settings.json +98 -0
- package/.claude/settings.local.json +8 -0
- package/.env.example +23 -0
- package/.eslintrc.json +28 -0
- package/.github/workflows/release.yml +180 -0
- package/.github/workflows/test.yml +81 -0
- package/.gitmodules +3 -0
- package/.vs/ProjectSettings.json +3 -0
- package/.vs/VSWorkspaceState.json +16 -0
- package/.vs/aicgen.slnx/FileContentIndex/5f0ce2a3-fd68-4863-9e23-e428cf1794e3.vsidx +0 -0
- package/.vs/aicgen.slnx/v18/.wsuo +0 -0
- package/.vs/aicgen.slnx/v18/DocumentLayout.json +54 -0
- package/.vs/slnx.sqlite +0 -0
- package/AGENTS.md +121 -0
- package/CLAUDE.md +36 -0
- package/CONTRIBUTING.md +821 -0
- package/LICENSE +21 -0
- package/README.md +199 -0
- package/assets/icon.svg +34 -0
- package/assets/logo.svg +41 -0
- package/bun.lock +848 -0
- package/data/LICENSE +21 -0
- package/data/README.md +203 -0
- package/data/api/basics.md +292 -0
- package/data/api/index.md +8 -0
- package/data/api/pagination.md +142 -0
- package/data/api/rest.md +137 -0
- package/data/api/versioning.md +60 -0
- package/data/architecture/clean-architecture/index.md +7 -0
- package/data/architecture/clean-architecture/layers.md +111 -0
- package/data/architecture/ddd/index.md +8 -0
- package/data/architecture/ddd/strategic.md +89 -0
- package/data/architecture/ddd/tactical.md +132 -0
- package/data/architecture/event-driven/index.md +7 -0
- package/data/architecture/event-driven/messaging.md +242 -0
- package/data/architecture/event-driven/patterns.md +129 -0
- package/data/architecture/feature-toggles/index.md +7 -0
- package/data/architecture/feature-toggles/patterns.md +73 -0
- package/data/architecture/gui/index.md +7 -0
- package/data/architecture/gui/patterns.md +132 -0
- package/data/architecture/hexagonal/ports-adapters.md +132 -0
- package/data/architecture/index.md +12 -0
- package/data/architecture/layered/index.md +7 -0
- package/data/architecture/layered/layers.md +100 -0
- package/data/architecture/microservices/api-gateway.md +56 -0
- package/data/architecture/microservices/boundaries.md +80 -0
- package/data/architecture/microservices/communication.md +97 -0
- package/data/architecture/microservices/data.md +92 -0
- package/data/architecture/microservices/index.md +11 -0
- package/data/architecture/microservices/resilience.md +111 -0
- package/data/architecture/modular-monolith/boundaries.md +133 -0
- package/data/architecture/modular-monolith/structure.md +131 -0
- package/data/architecture/serverless/best-practices.md +322 -0
- package/data/architecture/serverless/index.md +7 -0
- package/data/architecture/serverless/patterns.md +80 -0
- package/data/architecture/solid/index.md +7 -0
- package/data/architecture/solid/principles.md +187 -0
- package/data/database/basics.md +365 -0
- package/data/database/design-patterns.md +68 -0
- package/data/database/index.md +8 -0
- package/data/database/indexing.md +136 -0
- package/data/database/nosql.md +223 -0
- package/data/database/schema.md +137 -0
- package/data/devops/ci-cd.md +66 -0
- package/data/devops/index.md +8 -0
- package/data/devops/observability.md +73 -0
- package/data/devops/practices.md +77 -0
- package/data/error-handling/basics.md +222 -0
- package/data/error-handling/index.md +7 -0
- package/data/error-handling/strategy.md +185 -0
- package/data/guideline-mappings.yml +1077 -0
- package/data/index.md +3 -0
- package/data/language/csharp/basics.md +210 -0
- package/data/language/csharp/testing.md +252 -0
- package/data/language/go/basics.md +158 -0
- package/data/language/go/testing.md +192 -0
- package/data/language/index.md +14 -0
- package/data/language/java/basics.md +184 -0
- package/data/language/java/testing.md +273 -0
- package/data/language/javascript/basics.md +217 -0
- package/data/language/javascript/testing.md +269 -0
- package/data/language/python/async.md +100 -0
- package/data/language/python/basics.md +100 -0
- package/data/language/python/index.md +10 -0
- package/data/language/python/testing.md +125 -0
- package/data/language/python/types.md +99 -0
- package/data/language/ruby/basics.md +227 -0
- package/data/language/ruby/testing.md +267 -0
- package/data/language/rust/basics.md +175 -0
- package/data/language/rust/testing.md +219 -0
- package/data/language/typescript/async.md +103 -0
- package/data/language/typescript/basics.md +87 -0
- package/data/language/typescript/config.md +95 -0
- package/data/language/typescript/error-handling.md +98 -0
- package/data/language/typescript/generics.md +85 -0
- package/data/language/typescript/index.md +14 -0
- package/data/language/typescript/interfaces-types.md +83 -0
- package/data/language/typescript/performance.md +103 -0
- package/data/language/typescript/testing.md +98 -0
- package/data/patterns/base-patterns.md +105 -0
- package/data/patterns/concurrency.md +87 -0
- package/data/patterns/data-access.md +83 -0
- package/data/patterns/distribution.md +86 -0
- package/data/patterns/domain-logic.md +81 -0
- package/data/patterns/gof.md +109 -0
- package/data/patterns/index.md +12 -0
- package/data/performance/async.md +148 -0
- package/data/performance/basics.md +324 -0
- package/data/performance/caching-strategies.md +68 -0
- package/data/performance/caching.md +152 -0
- package/data/performance/index.md +8 -0
- package/data/practices/code-review.md +52 -0
- package/data/practices/documentation.md +260 -0
- package/data/practices/index.md +11 -0
- package/data/practices/planning.md +142 -0
- package/data/practices/refactoring.md +91 -0
- package/data/practices/version-control.md +55 -0
- package/data/security/auth-jwt.md +159 -0
- package/data/security/headers.md +143 -0
- package/data/security/index.md +10 -0
- package/data/security/injection.md +119 -0
- package/data/security/secrets.md +148 -0
- package/data/style/index.md +8 -0
- package/data/style/naming.md +136 -0
- package/data/style/organization.md +162 -0
- package/data/templates/agents/architecture-reviewer.md +88 -0
- package/data/templates/agents/guideline-checker.md +73 -0
- package/data/templates/agents/security-auditor.md +108 -0
- package/data/templates/antigravity/rules/architecture.md.hbs +5 -0
- package/data/templates/antigravity/rules/code-style.md.hbs +5 -0
- package/data/templates/antigravity/rules/language.md.hbs +5 -0
- package/data/templates/antigravity/rules/performance.md.hbs +5 -0
- package/data/templates/antigravity/rules/security.md.hbs +5 -0
- package/data/templates/antigravity/rules/testing.md.hbs +5 -0
- package/data/templates/antigravity/workflows/add-documentation.md.hbs +23 -0
- package/data/templates/antigravity/workflows/generate-integration-tests.md.hbs +17 -0
- package/data/templates/antigravity/workflows/generate-unit-tests.md.hbs +20 -0
- package/data/templates/antigravity/workflows/performance-audit.md.hbs +24 -0
- package/data/templates/antigravity/workflows/refactor-extract-module.md.hbs +17 -0
- package/data/templates/antigravity/workflows/security-audit.md.hbs +20 -0
- package/data/templates/hooks/formatting.json +26 -0
- package/data/templates/hooks/security.json +35 -0
- package/data/templates/hooks/testing.json +17 -0
- package/data/testing/basics.md +151 -0
- package/data/testing/index.md +9 -0
- package/data/testing/integration.md +159 -0
- package/data/testing/unit-fundamentals.md +128 -0
- package/data/testing/unit-mocking.md +116 -0
- package/data/version.json +49 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +46 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/config/profiles.d.ts +4 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +30 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/config/settings.d.ts +7 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +7 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58489 -0
- package/dist/index.js.map +1 -0
- package/dist/models/guideline.d.ts +15 -0
- package/dist/models/guideline.d.ts.map +1 -0
- package/dist/models/guideline.js +2 -0
- package/dist/models/guideline.js.map +1 -0
- package/dist/models/preference.d.ts +9 -0
- package/dist/models/preference.d.ts.map +1 -0
- package/dist/models/preference.js +2 -0
- package/dist/models/preference.js.map +1 -0
- package/dist/models/profile.d.ts +9 -0
- package/dist/models/profile.d.ts.map +1 -0
- package/dist/models/profile.js +2 -0
- package/dist/models/profile.js.map +1 -0
- package/dist/models/project.d.ts +13 -0
- package/dist/models/project.d.ts.map +1 -0
- package/dist/models/project.js +2 -0
- package/dist/models/project.js.map +1 -0
- package/dist/services/ai/anthropic.d.ts +7 -0
- package/dist/services/ai/anthropic.d.ts.map +1 -0
- package/dist/services/ai/anthropic.js +39 -0
- package/dist/services/ai/anthropic.js.map +1 -0
- package/dist/services/generator.d.ts +2 -0
- package/dist/services/generator.d.ts.map +1 -0
- package/dist/services/generator.js +4 -0
- package/dist/services/generator.js.map +1 -0
- package/dist/services/learner.d.ts +2 -0
- package/dist/services/learner.d.ts.map +1 -0
- package/dist/services/learner.js +4 -0
- package/dist/services/learner.js.map +1 -0
- package/dist/services/scanner.d.ts +3 -0
- package/dist/services/scanner.d.ts.map +1 -0
- package/dist/services/scanner.js +54 -0
- package/dist/services/scanner.js.map +1 -0
- package/dist/utils/errors.d.ts +15 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +27 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/file.d.ts +7 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +32 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +17 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path.d.ts +6 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +14 -0
- package/dist/utils/path.js.map +1 -0
- package/docs/planning/memory-lane.md +83 -0
- package/package.json +64 -0
- package/packaging/linux/aicgen.spec +23 -0
- package/packaging/linux/control +9 -0
- package/packaging/macos/scripts/postinstall +12 -0
- package/packaging/windows/setup.nsi +92 -0
- package/planning/BRANDING-SUMMARY.md +194 -0
- package/planning/BRANDING.md +174 -0
- package/planning/BUILD.md +186 -0
- package/planning/CHUNK-IMPLEMENTATION-PLAN.md +87 -0
- package/planning/CHUNK-TAXONOMY.md +375 -0
- package/planning/CHUNKS-COMPLETE.md +382 -0
- package/planning/DESIGN.md +313 -0
- package/planning/DYNAMIC-GUIDELINES-DESIGN.md +265 -0
- package/planning/ENTERPRISE-UX-COMPLETE.md +281 -0
- package/planning/IMPLEMENTATION-PLAN.md +20 -0
- package/planning/PHASE1-COMPLETE.md +211 -0
- package/planning/PHASE2-COMPLETE.md +350 -0
- package/planning/PHASE3-COMPLETE.md +399 -0
- package/planning/PHASE4-COMPLETE.md +361 -0
- package/planning/PHASE4.5-CHUNKS.md +462 -0
- package/planning/STRUCTURE.md +170 -0
- package/scripts/add-categories.ts +87 -0
- package/scripts/build-binary.ts +46 -0
- package/scripts/embed-data.ts +105 -0
- package/scripts/generate-version.ts +150 -0
- package/scripts/test-decompress.ts +27 -0
- package/scripts/test-extract.ts +31 -0
- package/src/__tests__/services/assistant-file-writer.test.ts +400 -0
- package/src/__tests__/services/guideline-loader.test.ts +281 -0
- package/src/__tests__/services/tarball-extraction.test.ts +125 -0
- package/src/commands/add-guideline.ts +296 -0
- package/src/commands/clear.ts +61 -0
- package/src/commands/guideline-selector.ts +123 -0
- package/src/commands/init.ts +645 -0
- package/src/commands/quick-add.ts +586 -0
- package/src/commands/remove-guideline.ts +152 -0
- package/src/commands/stats.ts +49 -0
- package/src/commands/update.ts +240 -0
- package/src/config.ts +82 -0
- package/src/embedded-data.ts +1492 -0
- package/src/index.ts +67 -0
- package/src/models/profile.ts +24 -0
- package/src/models/project.ts +43 -0
- package/src/services/assistant-file-writer.ts +612 -0
- package/src/services/config-generator.ts +150 -0
- package/src/services/config-manager.ts +70 -0
- package/src/services/data-source.ts +248 -0
- package/src/services/first-run-init.ts +148 -0
- package/src/services/guideline-loader.ts +311 -0
- package/src/services/hook-generator.ts +178 -0
- package/src/services/subagent-generator.ts +310 -0
- package/src/utils/banner.ts +66 -0
- package/src/utils/errors.ts +27 -0
- package/src/utils/file.ts +67 -0
- package/src/utils/formatting.ts +172 -0
- package/src/utils/logger.ts +89 -0
- package/src/utils/path.ts +17 -0
- package/src/utils/wizard-state.ts +132 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# SOLID Principles
|
|
2
|
+
|
|
3
|
+
## Single Responsibility Principle (SRP)
|
|
4
|
+
|
|
5
|
+
A class should have only one reason to change.
|
|
6
|
+
|
|
7
|
+
**Bad:**
|
|
8
|
+
```typescript
|
|
9
|
+
class UserService {
|
|
10
|
+
createUser(data: UserData): User { /* ... */ }
|
|
11
|
+
sendWelcomeEmail(user: User): void { /* ... */ }
|
|
12
|
+
generateReport(users: User[]): Report { /* ... */ }
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Good:**
|
|
17
|
+
```typescript
|
|
18
|
+
class UserService {
|
|
19
|
+
createUser(data: UserData): User { /* ... */ }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class EmailService {
|
|
23
|
+
sendWelcomeEmail(user: User): void { /* ... */ }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class ReportService {
|
|
27
|
+
generateUserReport(users: User[]): Report { /* ... */ }
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Open/Closed Principle (OCP)
|
|
32
|
+
|
|
33
|
+
Open for extension, closed for modification.
|
|
34
|
+
|
|
35
|
+
**Bad:**
|
|
36
|
+
```typescript
|
|
37
|
+
class PaymentProcessor {
|
|
38
|
+
process(payment: Payment): void {
|
|
39
|
+
if (payment.type === 'credit') { /* credit logic */ }
|
|
40
|
+
else if (payment.type === 'paypal') { /* paypal logic */ }
|
|
41
|
+
// Must modify class to add new payment types
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Good:**
|
|
47
|
+
```typescript
|
|
48
|
+
interface PaymentHandler {
|
|
49
|
+
process(payment: Payment): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class CreditCardHandler implements PaymentHandler {
|
|
53
|
+
process(payment: Payment): void { /* credit logic */ }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class PayPalHandler implements PaymentHandler {
|
|
57
|
+
process(payment: Payment): void { /* paypal logic */ }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class PaymentProcessor {
|
|
61
|
+
constructor(private handlers: Map<string, PaymentHandler>) {}
|
|
62
|
+
|
|
63
|
+
process(payment: Payment): void {
|
|
64
|
+
this.handlers.get(payment.type)?.process(payment);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Liskov Substitution Principle (LSP)
|
|
70
|
+
|
|
71
|
+
Subtypes must be substitutable for their base types.
|
|
72
|
+
|
|
73
|
+
**Bad:**
|
|
74
|
+
```typescript
|
|
75
|
+
class Bird {
|
|
76
|
+
fly(): void { /* flying logic */ }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class Penguin extends Bird {
|
|
80
|
+
fly(): void {
|
|
81
|
+
throw new Error("Penguins can't fly!"); // Violates LSP
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Good:**
|
|
87
|
+
```typescript
|
|
88
|
+
interface Bird {
|
|
89
|
+
move(): void;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
class FlyingBird implements Bird {
|
|
93
|
+
move(): void { this.fly(); }
|
|
94
|
+
private fly(): void { /* flying logic */ }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
class Penguin implements Bird {
|
|
98
|
+
move(): void { this.swim(); }
|
|
99
|
+
private swim(): void { /* swimming logic */ }
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Interface Segregation Principle (ISP)
|
|
104
|
+
|
|
105
|
+
Clients shouldn't depend on interfaces they don't use.
|
|
106
|
+
|
|
107
|
+
**Bad:**
|
|
108
|
+
```typescript
|
|
109
|
+
interface Worker {
|
|
110
|
+
work(): void;
|
|
111
|
+
eat(): void;
|
|
112
|
+
sleep(): void;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
class Robot implements Worker {
|
|
116
|
+
work(): void { /* ... */ }
|
|
117
|
+
eat(): void { throw new Error("Robots don't eat"); }
|
|
118
|
+
sleep(): void { throw new Error("Robots don't sleep"); }
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Good:**
|
|
123
|
+
```typescript
|
|
124
|
+
interface Workable {
|
|
125
|
+
work(): void;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface Eatable {
|
|
129
|
+
eat(): void;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
interface Sleepable {
|
|
133
|
+
sleep(): void;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
class Human implements Workable, Eatable, Sleepable {
|
|
137
|
+
work(): void { /* ... */ }
|
|
138
|
+
eat(): void { /* ... */ }
|
|
139
|
+
sleep(): void { /* ... */ }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
class Robot implements Workable {
|
|
143
|
+
work(): void { /* ... */ }
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Dependency Inversion Principle (DIP)
|
|
148
|
+
|
|
149
|
+
Depend on abstractions, not concretions.
|
|
150
|
+
|
|
151
|
+
**Bad:**
|
|
152
|
+
```typescript
|
|
153
|
+
class UserService {
|
|
154
|
+
private database = new MySQLDatabase();
|
|
155
|
+
|
|
156
|
+
getUser(id: string): User {
|
|
157
|
+
return this.database.query(`SELECT * FROM users WHERE id = '${id}'`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Good:**
|
|
163
|
+
```typescript
|
|
164
|
+
interface Database {
|
|
165
|
+
query(sql: string): any;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class UserService {
|
|
169
|
+
constructor(private database: Database) {}
|
|
170
|
+
|
|
171
|
+
getUser(id: string): User {
|
|
172
|
+
return this.database.query(`SELECT * FROM users WHERE id = '${id}'`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Can inject any database implementation
|
|
177
|
+
const userService = new UserService(new MySQLDatabase());
|
|
178
|
+
const testService = new UserService(new InMemoryDatabase());
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Best Practices
|
|
182
|
+
|
|
183
|
+
- Apply SRP at class, method, and module levels
|
|
184
|
+
- Use interfaces and dependency injection for flexibility
|
|
185
|
+
- Prefer composition over inheritance
|
|
186
|
+
- Design small, focused interfaces
|
|
187
|
+
- Inject dependencies rather than creating them internally
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Database Basics
|
|
2
|
+
|
|
3
|
+
## CRUD Operations
|
|
4
|
+
|
|
5
|
+
CRUD = Create, Read, Update, Delete
|
|
6
|
+
|
|
7
|
+
These are the four basic operations for working with data.
|
|
8
|
+
|
|
9
|
+
## CREATE - Inserting Data
|
|
10
|
+
|
|
11
|
+
### SQL
|
|
12
|
+
|
|
13
|
+
```sql
|
|
14
|
+
-- Insert single record
|
|
15
|
+
INSERT INTO users (name, email)
|
|
16
|
+
VALUES ('Alice', 'alice@example.com');
|
|
17
|
+
|
|
18
|
+
-- Insert multiple records
|
|
19
|
+
INSERT INTO users (name, email)
|
|
20
|
+
VALUES
|
|
21
|
+
('Bob', 'bob@example.com'),
|
|
22
|
+
('Carol', 'carol@example.com');
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### With Code
|
|
26
|
+
|
|
27
|
+
```pseudocode
|
|
28
|
+
// Using SQL directly
|
|
29
|
+
database.execute(
|
|
30
|
+
"INSERT INTO users (name, email) VALUES (?, ?)",
|
|
31
|
+
['Alice', 'alice@example.com']
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
// Using ORM/Model
|
|
35
|
+
user = User.create({
|
|
36
|
+
name: 'Alice',
|
|
37
|
+
email: 'alice@example.com'
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## READ - Querying Data
|
|
42
|
+
|
|
43
|
+
### Select All
|
|
44
|
+
|
|
45
|
+
```sql
|
|
46
|
+
-- Get all records
|
|
47
|
+
SELECT * FROM users;
|
|
48
|
+
|
|
49
|
+
-- Get specific columns
|
|
50
|
+
SELECT id, name FROM users;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Filter with WHERE
|
|
54
|
+
|
|
55
|
+
```sql
|
|
56
|
+
-- Find by ID
|
|
57
|
+
SELECT * FROM users WHERE id = 123;
|
|
58
|
+
|
|
59
|
+
-- Find by condition
|
|
60
|
+
SELECT * FROM users WHERE age > 18;
|
|
61
|
+
|
|
62
|
+
-- Multiple conditions
|
|
63
|
+
SELECT * FROM users
|
|
64
|
+
WHERE age > 18 AND status = 'active';
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### With Code
|
|
68
|
+
|
|
69
|
+
```pseudocode
|
|
70
|
+
// Get all
|
|
71
|
+
users = database.query("SELECT * FROM users")
|
|
72
|
+
|
|
73
|
+
// Get by ID
|
|
74
|
+
user = database.query(
|
|
75
|
+
"SELECT * FROM users WHERE id = ?",
|
|
76
|
+
[userId]
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
// Using ORM/Model
|
|
80
|
+
user = User.findById(123)
|
|
81
|
+
activeUsers = User.findAll({
|
|
82
|
+
where: { status: 'active' }
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## UPDATE - Modifying Data
|
|
87
|
+
|
|
88
|
+
### SQL
|
|
89
|
+
|
|
90
|
+
```sql
|
|
91
|
+
-- Update single field
|
|
92
|
+
UPDATE users
|
|
93
|
+
SET email = 'newemail@example.com'
|
|
94
|
+
WHERE id = 123;
|
|
95
|
+
|
|
96
|
+
-- Update multiple fields
|
|
97
|
+
UPDATE users
|
|
98
|
+
SET name = 'Alice Smith',
|
|
99
|
+
email = 'alice.smith@example.com'
|
|
100
|
+
WHERE id = 123;
|
|
101
|
+
|
|
102
|
+
-- Update with condition
|
|
103
|
+
UPDATE users
|
|
104
|
+
SET status = 'inactive'
|
|
105
|
+
WHERE last_login < '2023-01-01';
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### With Code
|
|
109
|
+
|
|
110
|
+
```pseudocode
|
|
111
|
+
// Using SQL
|
|
112
|
+
database.execute(
|
|
113
|
+
"UPDATE users SET email = ? WHERE id = ?",
|
|
114
|
+
['newemail@example.com', 123]
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
// Using ORM/Model
|
|
118
|
+
User.update(
|
|
119
|
+
{ email: 'newemail@example.com' },
|
|
120
|
+
{ where: { id: 123 } }
|
|
121
|
+
)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## DELETE - Removing Data
|
|
125
|
+
|
|
126
|
+
### SQL
|
|
127
|
+
|
|
128
|
+
```sql
|
|
129
|
+
-- Delete by ID
|
|
130
|
+
DELETE FROM users WHERE id = 123;
|
|
131
|
+
|
|
132
|
+
-- Delete with condition
|
|
133
|
+
DELETE FROM users WHERE status = 'banned';
|
|
134
|
+
|
|
135
|
+
-- Delete all (be careful!)
|
|
136
|
+
DELETE FROM users;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### With Code
|
|
140
|
+
|
|
141
|
+
```pseudocode
|
|
142
|
+
// Using SQL
|
|
143
|
+
database.execute("DELETE FROM users WHERE id = ?", [userId])
|
|
144
|
+
|
|
145
|
+
// Using ORM/Model
|
|
146
|
+
User.destroy({ where: { id: userId } })
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Sorting Results
|
|
150
|
+
|
|
151
|
+
```sql
|
|
152
|
+
-- Sort ascending (A-Z, 0-9)
|
|
153
|
+
SELECT * FROM users ORDER BY name ASC;
|
|
154
|
+
|
|
155
|
+
-- Sort descending (Z-A, 9-0)
|
|
156
|
+
SELECT * FROM users ORDER BY created_at DESC;
|
|
157
|
+
|
|
158
|
+
-- Sort by multiple columns
|
|
159
|
+
SELECT * FROM users
|
|
160
|
+
ORDER BY status ASC, name ASC;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Limiting Results
|
|
164
|
+
|
|
165
|
+
```sql
|
|
166
|
+
-- Get first 10 records
|
|
167
|
+
SELECT * FROM users LIMIT 10;
|
|
168
|
+
|
|
169
|
+
-- Skip first 20, get next 10
|
|
170
|
+
SELECT * FROM users LIMIT 10 OFFSET 20;
|
|
171
|
+
|
|
172
|
+
-- Most recent 5 users
|
|
173
|
+
SELECT * FROM users
|
|
174
|
+
ORDER BY created_at DESC
|
|
175
|
+
LIMIT 5;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Counting Records
|
|
179
|
+
|
|
180
|
+
```sql
|
|
181
|
+
-- Count all users
|
|
182
|
+
SELECT COUNT(*) FROM users;
|
|
183
|
+
|
|
184
|
+
-- Count by condition
|
|
185
|
+
SELECT COUNT(*) FROM users WHERE status = 'active';
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Common Patterns
|
|
189
|
+
|
|
190
|
+
### Check if Record Exists
|
|
191
|
+
|
|
192
|
+
```pseudocode
|
|
193
|
+
user = database.query(
|
|
194
|
+
"SELECT * FROM users WHERE email = ?",
|
|
195
|
+
[email]
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
if user is empty:
|
|
199
|
+
print("User not found")
|
|
200
|
+
else:
|
|
201
|
+
print("User exists")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Get One or Return Default
|
|
205
|
+
|
|
206
|
+
```pseudocode
|
|
207
|
+
user = database.query(
|
|
208
|
+
"SELECT * FROM users WHERE id = ?",
|
|
209
|
+
[userId]
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
return user[0] or null
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Update if Exists, Create if Not
|
|
216
|
+
|
|
217
|
+
```pseudocode
|
|
218
|
+
existing = database.query(
|
|
219
|
+
"SELECT * FROM users WHERE email = ?",
|
|
220
|
+
[email]
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
if existing.length > 0:
|
|
224
|
+
// Update
|
|
225
|
+
database.execute(
|
|
226
|
+
"UPDATE users SET name = ? WHERE email = ?",
|
|
227
|
+
[name, email]
|
|
228
|
+
)
|
|
229
|
+
else:
|
|
230
|
+
// Create
|
|
231
|
+
database.execute(
|
|
232
|
+
"INSERT INTO users (name, email) VALUES (?, ?)",
|
|
233
|
+
[name, email]
|
|
234
|
+
)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Always Use Parameterized Queries
|
|
238
|
+
|
|
239
|
+
```pseudocode
|
|
240
|
+
// ❌ DANGEROUS: SQL Injection risk
|
|
241
|
+
email = userInput
|
|
242
|
+
database.query("SELECT * FROM users WHERE email = '" + email + "'")
|
|
243
|
+
// If email = "'; DROP TABLE users; --" 😱
|
|
244
|
+
|
|
245
|
+
// ✅ SAFE: Parameterized query
|
|
246
|
+
database.query(
|
|
247
|
+
"SELECT * FROM users WHERE email = ?",
|
|
248
|
+
[email]
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Basic WHERE Conditions
|
|
253
|
+
|
|
254
|
+
```sql
|
|
255
|
+
-- Equals
|
|
256
|
+
WHERE status = 'active'
|
|
257
|
+
|
|
258
|
+
-- Not equals
|
|
259
|
+
WHERE status != 'banned'
|
|
260
|
+
|
|
261
|
+
-- Greater than / Less than
|
|
262
|
+
WHERE age > 18
|
|
263
|
+
WHERE price < 100
|
|
264
|
+
|
|
265
|
+
-- NULL checks
|
|
266
|
+
WHERE deleted_at IS NULL
|
|
267
|
+
WHERE email IS NOT NULL
|
|
268
|
+
|
|
269
|
+
-- IN list
|
|
270
|
+
WHERE status IN ('active', 'pending')
|
|
271
|
+
|
|
272
|
+
-- Pattern matching
|
|
273
|
+
WHERE email LIKE '%@gmail.com'
|
|
274
|
+
|
|
275
|
+
-- Multiple conditions
|
|
276
|
+
WHERE age > 18 AND status = 'active'
|
|
277
|
+
WHERE role = 'admin' OR role = 'moderator'
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Basic Data Types
|
|
281
|
+
|
|
282
|
+
```sql
|
|
283
|
+
-- Text
|
|
284
|
+
name VARCHAR(255)
|
|
285
|
+
description TEXT
|
|
286
|
+
|
|
287
|
+
-- Numbers
|
|
288
|
+
age INTEGER
|
|
289
|
+
price DECIMAL(10, 2)
|
|
290
|
+
|
|
291
|
+
-- Dates
|
|
292
|
+
created_at TIMESTAMP
|
|
293
|
+
birth_date DATE
|
|
294
|
+
|
|
295
|
+
-- Boolean
|
|
296
|
+
is_active BOOLEAN
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Best Practices
|
|
300
|
+
|
|
301
|
+
1. **Always use parameterized queries** - Prevents SQL injection
|
|
302
|
+
2. **Add WHERE to UPDATE/DELETE** - Avoid accidentally modifying all records
|
|
303
|
+
3. **Use LIMIT for testing** - Prevent fetching too much data
|
|
304
|
+
4. **Check query results** - Handle empty results gracefully
|
|
305
|
+
|
|
306
|
+
```pseudocode
|
|
307
|
+
// ✅ Good practices
|
|
308
|
+
async function getUser(id):
|
|
309
|
+
result = database.query(
|
|
310
|
+
"SELECT * FROM users WHERE id = ? LIMIT 1",
|
|
311
|
+
[id]
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
if result.length == 0:
|
|
315
|
+
return null // Handle not found
|
|
316
|
+
|
|
317
|
+
return result[0]
|
|
318
|
+
|
|
319
|
+
async function updateUserEmail(id, email):
|
|
320
|
+
// Validate first
|
|
321
|
+
if not email.contains('@'):
|
|
322
|
+
throw Error("Invalid email")
|
|
323
|
+
|
|
324
|
+
// Update with WHERE
|
|
325
|
+
database.execute(
|
|
326
|
+
"UPDATE users SET email = ? WHERE id = ?",
|
|
327
|
+
[email, id]
|
|
328
|
+
)
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Common Mistakes
|
|
332
|
+
|
|
333
|
+
```pseudocode
|
|
334
|
+
// ❌ String concatenation (SQL injection!)
|
|
335
|
+
database.query("SELECT * FROM users WHERE id = " + userId)
|
|
336
|
+
|
|
337
|
+
// ❌ No WHERE clause (updates everything!)
|
|
338
|
+
database.query("UPDATE users SET status = 'banned'")
|
|
339
|
+
|
|
340
|
+
// ❌ Not handling empty results
|
|
341
|
+
user = result[0] // Crashes if empty
|
|
342
|
+
print(user.name) // undefined error
|
|
343
|
+
|
|
344
|
+
// ✅ Correct
|
|
345
|
+
database.query("SELECT * FROM users WHERE id = ?", [userId])
|
|
346
|
+
database.query("UPDATE users SET status = ? WHERE id = ?", ['banned', userId])
|
|
347
|
+
user = result[0] or null
|
|
348
|
+
if user is not null:
|
|
349
|
+
print(user.name)
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Testing Queries
|
|
353
|
+
|
|
354
|
+
```pseudocode
|
|
355
|
+
// Start with SELECT to verify
|
|
356
|
+
usersToDelete = database.query(
|
|
357
|
+
"SELECT * FROM users WHERE status = ?",
|
|
358
|
+
['inactive']
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
print("Would delete " + usersToDelete.length + " users")
|
|
362
|
+
|
|
363
|
+
// If correct, change to DELETE
|
|
364
|
+
// database.execute("DELETE FROM users WHERE status = ?", ['inactive'])
|
|
365
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Database Design Patterns
|
|
2
|
+
|
|
3
|
+
## Schema Design
|
|
4
|
+
|
|
5
|
+
### Normalization
|
|
6
|
+
Reduce redundancy, maintain integrity.
|
|
7
|
+
|
|
8
|
+
```sql
|
|
9
|
+
-- Normalized
|
|
10
|
+
CREATE TABLE users (id, name, email);
|
|
11
|
+
CREATE TABLE orders (id, user_id REFERENCES users(id), total);
|
|
12
|
+
CREATE TABLE order_items (id, order_id REFERENCES orders(id), product_id, qty);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Denormalization
|
|
16
|
+
Trade redundancy for read performance.
|
|
17
|
+
|
|
18
|
+
```sql
|
|
19
|
+
-- Denormalized for read performance
|
|
20
|
+
CREATE TABLE order_summary (
|
|
21
|
+
id, user_id, user_name, user_email,
|
|
22
|
+
total, item_count, created_at
|
|
23
|
+
);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Common Patterns
|
|
27
|
+
|
|
28
|
+
### Soft Deletes
|
|
29
|
+
```sql
|
|
30
|
+
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP NULL;
|
|
31
|
+
|
|
32
|
+
-- Query active users
|
|
33
|
+
SELECT * FROM users WHERE deleted_at IS NULL;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Audit Trail
|
|
37
|
+
```sql
|
|
38
|
+
CREATE TABLE audit_log (
|
|
39
|
+
id SERIAL PRIMARY KEY,
|
|
40
|
+
table_name VARCHAR(100),
|
|
41
|
+
record_id VARCHAR(100),
|
|
42
|
+
action VARCHAR(20),
|
|
43
|
+
old_values JSONB,
|
|
44
|
+
new_values JSONB,
|
|
45
|
+
changed_by VARCHAR(100),
|
|
46
|
+
changed_at TIMESTAMP DEFAULT NOW()
|
|
47
|
+
);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Polymorphic Associations
|
|
51
|
+
```sql
|
|
52
|
+
CREATE TABLE comments (
|
|
53
|
+
id SERIAL PRIMARY KEY,
|
|
54
|
+
body TEXT,
|
|
55
|
+
commentable_type VARCHAR(50), -- 'post', 'image', 'video'
|
|
56
|
+
commentable_id INTEGER,
|
|
57
|
+
created_at TIMESTAMP
|
|
58
|
+
);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Best Practices
|
|
62
|
+
|
|
63
|
+
- Use appropriate data types
|
|
64
|
+
- Add indexes for frequently queried columns
|
|
65
|
+
- Use foreign keys for referential integrity
|
|
66
|
+
- Consider partitioning for large tables
|
|
67
|
+
- Plan for schema migrations
|
|
68
|
+
- Document schema decisions
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Database Guidelines
|
|
2
|
+
|
|
3
|
+
This directory contains database design and optimization patterns.
|
|
4
|
+
|
|
5
|
+
## Available Chunks
|
|
6
|
+
|
|
7
|
+
- **schema.md** - Naming conventions, data types, constraints, normalization
|
|
8
|
+
- **indexing.md** - When to index, composite indexes, query optimization
|