@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
package/data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Lahiru Pathirage
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/data/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# aicgen Guidelines Repository
|
|
2
|
+
|
|
3
|
+
This repository contains coding guidelines and best practices that power aicgen configurations.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
data/
|
|
9
|
+
├── guideline-mappings.yml # Maps guideline IDs to files and filters
|
|
10
|
+
├── api/ # API design patterns
|
|
11
|
+
├── architecture/ # Architecture patterns (clean, DDD, etc.)
|
|
12
|
+
├── database/ # Database guidelines
|
|
13
|
+
├── devops/ # CI/CD and deployment
|
|
14
|
+
├── error-handling/ # Error handling strategies
|
|
15
|
+
├── language/ # Language-specific (typescript, python)
|
|
16
|
+
├── patterns/ # Design patterns
|
|
17
|
+
├── performance/ # Performance optimization
|
|
18
|
+
├── practices/ # Best practices
|
|
19
|
+
├── security/ # Security guidelines
|
|
20
|
+
├── style/ # Code style guidelines
|
|
21
|
+
├── templates/ # Reusable templates
|
|
22
|
+
└── testing/ # Testing strategies
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Contributing Guidelines
|
|
26
|
+
|
|
27
|
+
### Step 1: Create Your Guideline File
|
|
28
|
+
|
|
29
|
+
Create a markdown file in the appropriate category folder:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Example: Adding a new TypeScript guideline
|
|
33
|
+
data/language/typescript/my-guideline.md
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Guideline Format:**
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
# Guideline Title
|
|
40
|
+
|
|
41
|
+
Brief description of what this guideline covers.
|
|
42
|
+
|
|
43
|
+
## Section 1
|
|
44
|
+
|
|
45
|
+
Clear, actionable instructions with code examples:
|
|
46
|
+
|
|
47
|
+
\`\`\`typescript
|
|
48
|
+
// Good example
|
|
49
|
+
function goodExample(): string {
|
|
50
|
+
return "well-structured code";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Bad example - explain why
|
|
54
|
+
function badExample() { // Missing return type
|
|
55
|
+
return "unclear code";
|
|
56
|
+
}
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
## Section 2
|
|
60
|
+
|
|
61
|
+
More sections as needed...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Writing Tips:**
|
|
65
|
+
- Be concise and actionable
|
|
66
|
+
- Include both good and bad code examples
|
|
67
|
+
- Use language-appropriate code blocks
|
|
68
|
+
- Focus on the "why" not just the "what"
|
|
69
|
+
|
|
70
|
+
### Step 2: Add to Mappings
|
|
71
|
+
|
|
72
|
+
Add your guideline to `guideline-mappings.yml`:
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
my-guideline-id:
|
|
76
|
+
path: language/typescript/my-guideline.md
|
|
77
|
+
category: Language
|
|
78
|
+
languages:
|
|
79
|
+
- typescript
|
|
80
|
+
levels:
|
|
81
|
+
- standard
|
|
82
|
+
- expert
|
|
83
|
+
- full
|
|
84
|
+
tags:
|
|
85
|
+
- typescript
|
|
86
|
+
- relevant-tag
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Mapping Fields
|
|
90
|
+
|
|
91
|
+
| Field | Required | Description |
|
|
92
|
+
|-------|----------|-------------|
|
|
93
|
+
| `path` | Yes | Relative path to the guideline file |
|
|
94
|
+
| `category` | Yes | Display category (Language, Architecture, Testing, etc.) |
|
|
95
|
+
| `languages` | No | Which languages this applies to. Omit for all languages |
|
|
96
|
+
| `levels` | No | Instruction levels: `basic`, `standard`, `expert`, `full`. Omit for all |
|
|
97
|
+
| `architectures` | No | Architecture types. Omit for all |
|
|
98
|
+
| `tags` | No | Search/organization tags |
|
|
99
|
+
|
|
100
|
+
### Available Values
|
|
101
|
+
|
|
102
|
+
**Languages:**
|
|
103
|
+
- `typescript`, `python`, `go`, `rust`, `java`, `csharp`, `ruby`, `php`, `swift`, `kotlin`
|
|
104
|
+
|
|
105
|
+
**Levels:**
|
|
106
|
+
- `basic` - Essential guidelines only
|
|
107
|
+
- `standard` - Common best practices
|
|
108
|
+
- `expert` - Advanced patterns
|
|
109
|
+
- `full` - Comprehensive coverage
|
|
110
|
+
|
|
111
|
+
**Architectures:**
|
|
112
|
+
- `layered`, `clean-architecture`, `hexagonal`, `ddd`, `microservices`
|
|
113
|
+
- `modular-monolith`, `event-driven`, `serverless`, `other`
|
|
114
|
+
|
|
115
|
+
**Categories:**
|
|
116
|
+
- `Language`, `Architecture`, `Testing`, `Security`, `Performance`
|
|
117
|
+
- `Database`, `API Design`, `Code Style`, `Error Handling`, `DevOps`
|
|
118
|
+
- `Best Practices`, `Design Patterns`
|
|
119
|
+
|
|
120
|
+
## Examples
|
|
121
|
+
|
|
122
|
+
### Language-Specific Guideline
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
typescript-decorators:
|
|
126
|
+
path: language/typescript/decorators.md
|
|
127
|
+
category: Language
|
|
128
|
+
languages:
|
|
129
|
+
- typescript
|
|
130
|
+
levels:
|
|
131
|
+
- expert
|
|
132
|
+
- full
|
|
133
|
+
tags:
|
|
134
|
+
- typescript
|
|
135
|
+
- decorators
|
|
136
|
+
- metadata
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Universal Guideline (All Languages)
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
solid-principles:
|
|
143
|
+
path: architecture/solid/principles.md
|
|
144
|
+
category: Architecture
|
|
145
|
+
levels:
|
|
146
|
+
- standard
|
|
147
|
+
- expert
|
|
148
|
+
- full
|
|
149
|
+
tags:
|
|
150
|
+
- solid
|
|
151
|
+
- design-principles
|
|
152
|
+
- oop
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Architecture-Specific Guideline
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
ddd-aggregates:
|
|
159
|
+
path: architecture/ddd/aggregates.md
|
|
160
|
+
category: Architecture
|
|
161
|
+
architectures:
|
|
162
|
+
- ddd
|
|
163
|
+
- clean-architecture
|
|
164
|
+
levels:
|
|
165
|
+
- expert
|
|
166
|
+
- full
|
|
167
|
+
tags:
|
|
168
|
+
- ddd
|
|
169
|
+
- aggregates
|
|
170
|
+
- domain-model
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Testing Your Changes
|
|
174
|
+
|
|
175
|
+
After adding a guideline:
|
|
176
|
+
|
|
177
|
+
1. **Rebuild aicgen:**
|
|
178
|
+
```bash
|
|
179
|
+
bun run build
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
2. **Check it's loaded:**
|
|
183
|
+
```bash
|
|
184
|
+
bun run start stats
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
3. **Test generation:**
|
|
188
|
+
```bash
|
|
189
|
+
bun run start init --force
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Guideline Quality Checklist
|
|
193
|
+
|
|
194
|
+
- [ ] Clear, descriptive title
|
|
195
|
+
- [ ] Actionable instructions
|
|
196
|
+
- [ ] Code examples (good and bad)
|
|
197
|
+
- [ ] Appropriate language/level targeting
|
|
198
|
+
- [ ] Meaningful category and tags
|
|
199
|
+
- [ ] No duplicate content with existing guidelines
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT License - See LICENSE file
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# API Basics
|
|
2
|
+
|
|
3
|
+
## HTTP Methods
|
|
4
|
+
|
|
5
|
+
Use the right method for each operation:
|
|
6
|
+
|
|
7
|
+
| Method | Purpose | Example |
|
|
8
|
+
|--------|---------|---------|
|
|
9
|
+
| GET | Read data | Get list of users |
|
|
10
|
+
| POST | Create new resource | Create a new user |
|
|
11
|
+
| PUT | Replace entire resource | Update all user fields |
|
|
12
|
+
| PATCH | Update part of resource | Update user's email only |
|
|
13
|
+
| DELETE | Remove resource | Delete a user |
|
|
14
|
+
|
|
15
|
+
## GET - Reading Data
|
|
16
|
+
|
|
17
|
+
```pseudocode
|
|
18
|
+
// Get all items
|
|
19
|
+
route GET "/api/users":
|
|
20
|
+
users = getAllUsers()
|
|
21
|
+
return JSON(users)
|
|
22
|
+
|
|
23
|
+
// Get single item by ID
|
|
24
|
+
route GET "/api/users/:id":
|
|
25
|
+
user = getUserById(params.id)
|
|
26
|
+
if user is null:
|
|
27
|
+
return status 404, JSON({ error: "User not found" })
|
|
28
|
+
return JSON(user)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## POST - Creating Data
|
|
32
|
+
|
|
33
|
+
```pseudocode
|
|
34
|
+
route POST "/api/users":
|
|
35
|
+
name = request.body.name
|
|
36
|
+
email = request.body.email
|
|
37
|
+
|
|
38
|
+
// Validate input
|
|
39
|
+
if name is empty or email is empty:
|
|
40
|
+
return status 400, JSON({ error: "Name and email required" })
|
|
41
|
+
|
|
42
|
+
newUser = createUser({ name, email })
|
|
43
|
+
|
|
44
|
+
// Return 201 Created with new resource
|
|
45
|
+
return status 201, JSON(newUser)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## PUT - Replacing Data
|
|
49
|
+
|
|
50
|
+
```pseudocode
|
|
51
|
+
route PUT "/api/users/:id":
|
|
52
|
+
id = params.id
|
|
53
|
+
name = request.body.name
|
|
54
|
+
email = request.body.email
|
|
55
|
+
|
|
56
|
+
user = getUserById(id)
|
|
57
|
+
if user is null:
|
|
58
|
+
return status 404, JSON({ error: "User not found" })
|
|
59
|
+
|
|
60
|
+
updated = replaceUser(id, { name, email })
|
|
61
|
+
return JSON(updated)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## PATCH - Updating Data
|
|
65
|
+
|
|
66
|
+
```pseudocode
|
|
67
|
+
route PATCH "/api/users/:id":
|
|
68
|
+
id = params.id
|
|
69
|
+
updates = request.body // Only fields to update
|
|
70
|
+
|
|
71
|
+
user = getUserById(id)
|
|
72
|
+
if user is null:
|
|
73
|
+
return status 404, JSON({ error: "User not found" })
|
|
74
|
+
|
|
75
|
+
updated = updateUser(id, updates)
|
|
76
|
+
return JSON(updated)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## DELETE - Removing Data
|
|
80
|
+
|
|
81
|
+
```pseudocode
|
|
82
|
+
route DELETE "/api/users/:id":
|
|
83
|
+
id = params.id
|
|
84
|
+
|
|
85
|
+
user = getUserById(id)
|
|
86
|
+
if user is null:
|
|
87
|
+
return status 404, JSON({ error: "User not found" })
|
|
88
|
+
|
|
89
|
+
deleteUser(id)
|
|
90
|
+
|
|
91
|
+
// 204 No Content - successful deletion
|
|
92
|
+
return status 204
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## HTTP Status Codes
|
|
96
|
+
|
|
97
|
+
### Success Codes (2xx)
|
|
98
|
+
|
|
99
|
+
```pseudocode
|
|
100
|
+
// 200 OK - Request succeeded
|
|
101
|
+
return status 200, JSON(data)
|
|
102
|
+
|
|
103
|
+
// 201 Created - New resource created
|
|
104
|
+
return status 201, JSON(newResource)
|
|
105
|
+
|
|
106
|
+
// 204 No Content - Success with no response body
|
|
107
|
+
return status 204
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Client Error Codes (4xx)
|
|
111
|
+
|
|
112
|
+
```pseudocode
|
|
113
|
+
// 400 Bad Request - Invalid input
|
|
114
|
+
return status 400, JSON({ error: "Invalid email format" })
|
|
115
|
+
|
|
116
|
+
// 401 Unauthorized - Not authenticated
|
|
117
|
+
return status 401, JSON({ error: "Login required" })
|
|
118
|
+
|
|
119
|
+
// 403 Forbidden - Authenticated but not allowed
|
|
120
|
+
return status 403, JSON({ error: "Admin access required" })
|
|
121
|
+
|
|
122
|
+
// 404 Not Found - Resource doesn't exist
|
|
123
|
+
return status 404, JSON({ error: "User not found" })
|
|
124
|
+
|
|
125
|
+
// 409 Conflict - Resource already exists
|
|
126
|
+
return status 409, JSON({ error: "Email already registered" })
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Server Error Codes (5xx)
|
|
130
|
+
|
|
131
|
+
```pseudocode
|
|
132
|
+
// 500 Internal Server Error - Unexpected error
|
|
133
|
+
return status 500, JSON({ error: "Internal server error" })
|
|
134
|
+
|
|
135
|
+
// 503 Service Unavailable - Temporary issue
|
|
136
|
+
return status 503, JSON({ error: "Database unavailable" })
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## URL Structure
|
|
140
|
+
|
|
141
|
+
Use clear, hierarchical URLs:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
✅ Good
|
|
145
|
+
GET /api/users # List all users
|
|
146
|
+
GET /api/users/123 # Get user 123
|
|
147
|
+
POST /api/users # Create user
|
|
148
|
+
GET /api/users/123/posts # Get posts by user 123
|
|
149
|
+
|
|
150
|
+
❌ Bad
|
|
151
|
+
GET /api/getUsers
|
|
152
|
+
POST /api/createUser
|
|
153
|
+
GET /api/user?id=123
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Request and Response Format
|
|
157
|
+
|
|
158
|
+
### JSON Request Body
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
// Client sends
|
|
162
|
+
POST /api/users
|
|
163
|
+
Content-Type: application/json
|
|
164
|
+
|
|
165
|
+
{
|
|
166
|
+
"name": "Alice",
|
|
167
|
+
"email": "alice@example.com"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### JSON Response
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
// Server responds
|
|
175
|
+
HTTP/1.1 201 Created
|
|
176
|
+
Content-Type: application/json
|
|
177
|
+
|
|
178
|
+
{
|
|
179
|
+
"id": 123,
|
|
180
|
+
"name": "Alice",
|
|
181
|
+
"email": "alice@example.com",
|
|
182
|
+
"createdAt": "2024-01-15T10:30:00Z"
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Query Parameters
|
|
187
|
+
|
|
188
|
+
Use query parameters for filtering, sorting, and pagination:
|
|
189
|
+
|
|
190
|
+
```pseudocode
|
|
191
|
+
// Filter by status
|
|
192
|
+
// GET /api/orders?status=pending
|
|
193
|
+
route GET "/api/orders":
|
|
194
|
+
status = query.status
|
|
195
|
+
orders = getOrders({ status })
|
|
196
|
+
return JSON(orders)
|
|
197
|
+
|
|
198
|
+
// Sort by field
|
|
199
|
+
// GET /api/users?sort=name
|
|
200
|
+
|
|
201
|
+
// Pagination
|
|
202
|
+
// GET /api/users?page=2&limit=20
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Error Responses
|
|
206
|
+
|
|
207
|
+
Always return consistent error format:
|
|
208
|
+
|
|
209
|
+
```pseudocode
|
|
210
|
+
// ✅ Good: Structured error
|
|
211
|
+
return status 400, JSON({
|
|
212
|
+
error: {
|
|
213
|
+
code: "VALIDATION_ERROR",
|
|
214
|
+
message: "Invalid input",
|
|
215
|
+
details: {
|
|
216
|
+
email: "Email format is invalid"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// ❌ Bad: Inconsistent
|
|
222
|
+
return status 400, "Bad request"
|
|
223
|
+
return status 400, JSON({ msg: "Error" })
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Best Practices
|
|
227
|
+
|
|
228
|
+
1. **Use correct HTTP methods** - GET for reading, POST for creating, etc.
|
|
229
|
+
2. **Use appropriate status codes** - 200 for success, 404 for not found, etc.
|
|
230
|
+
3. **Return JSON** - Standard format for APIs
|
|
231
|
+
4. **Validate input** - Check data before processing
|
|
232
|
+
5. **Handle errors** - Return clear error messages
|
|
233
|
+
|
|
234
|
+
```pseudocode
|
|
235
|
+
// Complete example
|
|
236
|
+
route POST "/api/products":
|
|
237
|
+
name = request.body.name
|
|
238
|
+
price = request.body.price
|
|
239
|
+
|
|
240
|
+
// Validate
|
|
241
|
+
if name is empty or price is empty:
|
|
242
|
+
return status 400, JSON({
|
|
243
|
+
error: "Name and price are required"
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
if price < 0:
|
|
247
|
+
return status 400, JSON({
|
|
248
|
+
error: "Price cannot be negative"
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
// Check for duplicates
|
|
252
|
+
if productExists(name):
|
|
253
|
+
return status 409, JSON({
|
|
254
|
+
error: "Product already exists"
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
// Create
|
|
258
|
+
product = createProduct({ name, price })
|
|
259
|
+
|
|
260
|
+
// Return success
|
|
261
|
+
return status 201, JSON(product)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Common Mistakes
|
|
265
|
+
|
|
266
|
+
```pseudocode
|
|
267
|
+
// ❌ Wrong method for operation
|
|
268
|
+
route GET "/api/users/delete/:id" // Should be DELETE
|
|
269
|
+
|
|
270
|
+
// ❌ Wrong status code
|
|
271
|
+
route POST "/api/users":
|
|
272
|
+
user = createUser(body)
|
|
273
|
+
return status 200, JSON(user) // Should be 201
|
|
274
|
+
|
|
275
|
+
// ❌ Not handling missing resources
|
|
276
|
+
route GET "/api/users/:id":
|
|
277
|
+
user = getUserById(params.id)
|
|
278
|
+
return JSON(user) // What if user is null?
|
|
279
|
+
|
|
280
|
+
// ✅ Correct
|
|
281
|
+
route DELETE "/api/users/:id"
|
|
282
|
+
|
|
283
|
+
route POST "/api/users":
|
|
284
|
+
user = createUser(body)
|
|
285
|
+
return status 201, JSON(user)
|
|
286
|
+
|
|
287
|
+
route GET "/api/users/:id":
|
|
288
|
+
user = getUserById(params.id)
|
|
289
|
+
if user is null:
|
|
290
|
+
return status 404, JSON({ error: "User not found" })
|
|
291
|
+
return JSON(user)
|
|
292
|
+
```
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# API Pagination
|
|
2
|
+
|
|
3
|
+
## Always Paginate Collections
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// ✅ Paginated endpoint
|
|
7
|
+
app.get('/api/v1/books', async (req, res) => {
|
|
8
|
+
const page = parseInt(req.query.page as string) || 1;
|
|
9
|
+
const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);
|
|
10
|
+
|
|
11
|
+
const { data, total } = await bookService.findAll({ page, limit });
|
|
12
|
+
|
|
13
|
+
res.json({
|
|
14
|
+
data,
|
|
15
|
+
pagination: {
|
|
16
|
+
page,
|
|
17
|
+
limit,
|
|
18
|
+
total,
|
|
19
|
+
totalPages: Math.ceil(total / limit),
|
|
20
|
+
hasNext: page * limit < total,
|
|
21
|
+
hasPrevious: page > 1
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Offset-Based Pagination
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Simple but has issues with large datasets
|
|
31
|
+
GET /api/v1/books?page=1&limit=20
|
|
32
|
+
GET /api/v1/books?page=2&limit=20
|
|
33
|
+
|
|
34
|
+
// Implementation
|
|
35
|
+
const getBooks = async (page: number, limit: number) => {
|
|
36
|
+
const offset = (page - 1) * limit;
|
|
37
|
+
|
|
38
|
+
const [data, total] = await Promise.all([
|
|
39
|
+
db.query('SELECT * FROM books ORDER BY id LIMIT ? OFFSET ?', [limit, offset]),
|
|
40
|
+
db.query('SELECT COUNT(*) FROM books')
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
return { data, total };
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Cursor-Based Pagination
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// Better for large datasets and real-time data
|
|
51
|
+
GET /api/v1/books?cursor=eyJpZCI6MTIzfQ&limit=20
|
|
52
|
+
|
|
53
|
+
// Response includes next cursor
|
|
54
|
+
{
|
|
55
|
+
"data": [...],
|
|
56
|
+
"pagination": {
|
|
57
|
+
"nextCursor": "eyJpZCI6MTQzfQ",
|
|
58
|
+
"hasMore": true
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Implementation
|
|
63
|
+
const getBooks = async (cursor: string | null, limit: number) => {
|
|
64
|
+
let query = 'SELECT * FROM books';
|
|
65
|
+
|
|
66
|
+
if (cursor) {
|
|
67
|
+
const { id } = decodeCursor(cursor);
|
|
68
|
+
query += ` WHERE id > ${id}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
query += ` ORDER BY id LIMIT ${limit + 1}`;
|
|
72
|
+
const data = await db.query(query);
|
|
73
|
+
|
|
74
|
+
const hasMore = data.length > limit;
|
|
75
|
+
const items = hasMore ? data.slice(0, limit) : data;
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
data: items,
|
|
79
|
+
pagination: {
|
|
80
|
+
nextCursor: hasMore ? encodeCursor({ id: items[items.length - 1].id }) : null,
|
|
81
|
+
hasMore
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Keyset Pagination
|
|
88
|
+
|
|
89
|
+
```sql
|
|
90
|
+
-- Most efficient for large tables
|
|
91
|
+
-- First page
|
|
92
|
+
SELECT * FROM products
|
|
93
|
+
ORDER BY created_at DESC, id DESC
|
|
94
|
+
LIMIT 20;
|
|
95
|
+
|
|
96
|
+
-- Next page (using last item's values)
|
|
97
|
+
SELECT * FROM products
|
|
98
|
+
WHERE (created_at, id) < ('2024-01-15 10:00:00', 12345)
|
|
99
|
+
ORDER BY created_at DESC, id DESC
|
|
100
|
+
LIMIT 20;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## HATEOAS Links
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Include navigation links
|
|
107
|
+
{
|
|
108
|
+
"data": [...],
|
|
109
|
+
"pagination": {
|
|
110
|
+
"page": 2,
|
|
111
|
+
"limit": 20,
|
|
112
|
+
"total": 150
|
|
113
|
+
},
|
|
114
|
+
"links": {
|
|
115
|
+
"self": "/api/v1/books?page=2&limit=20",
|
|
116
|
+
"first": "/api/v1/books?page=1&limit=20",
|
|
117
|
+
"prev": "/api/v1/books?page=1&limit=20",
|
|
118
|
+
"next": "/api/v1/books?page=3&limit=20",
|
|
119
|
+
"last": "/api/v1/books?page=8&limit=20"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Pagination Best Practices
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// ✅ Set reasonable defaults and limits
|
|
128
|
+
const page = parseInt(req.query.page) || 1;
|
|
129
|
+
const limit = Math.min(parseInt(req.query.limit) || 20, 100);
|
|
130
|
+
|
|
131
|
+
// ✅ Include total count (when practical)
|
|
132
|
+
const total = await db.count('books');
|
|
133
|
+
|
|
134
|
+
// ✅ Use consistent response structure
|
|
135
|
+
{
|
|
136
|
+
"data": [],
|
|
137
|
+
"pagination": { ... }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ❌ Don't return unlimited results
|
|
141
|
+
// ❌ Don't allow page < 1 or limit < 1
|
|
142
|
+
```
|