@malamute/ai-rules 1.0.0 → 1.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.
Files changed (133) hide show
  1. package/README.md +270 -121
  2. package/bin/cli.js +5 -2
  3. package/configs/_shared/.claude/rules/conventions/documentation.md +324 -0
  4. package/configs/_shared/.claude/rules/conventions/git.md +265 -0
  5. package/configs/_shared/.claude/rules/{performance.md → conventions/performance.md} +1 -1
  6. package/configs/_shared/.claude/rules/conventions/principles.md +334 -0
  7. package/configs/_shared/.claude/rules/devops/ci-cd.md +262 -0
  8. package/configs/_shared/.claude/rules/devops/docker.md +275 -0
  9. package/configs/_shared/.claude/rules/devops/nx.md +194 -0
  10. package/configs/_shared/.claude/rules/domain/backend/api-design.md +203 -0
  11. package/configs/_shared/.claude/rules/lang/csharp/async.md +220 -0
  12. package/configs/_shared/.claude/rules/lang/csharp/csharp.md +314 -0
  13. package/configs/_shared/.claude/rules/lang/csharp/linq.md +210 -0
  14. package/configs/_shared/.claude/rules/lang/python/async.md +337 -0
  15. package/configs/_shared/.claude/rules/lang/python/celery.md +476 -0
  16. package/configs/_shared/.claude/rules/lang/python/config.md +339 -0
  17. package/configs/{python/.claude/rules → _shared/.claude/rules/lang/python}/database/sqlalchemy.md +6 -1
  18. package/configs/_shared/.claude/rules/lang/python/deployment.md +523 -0
  19. package/configs/_shared/.claude/rules/lang/python/error-handling.md +330 -0
  20. package/configs/_shared/.claude/rules/lang/python/migrations.md +421 -0
  21. package/configs/_shared/.claude/rules/lang/python/python.md +172 -0
  22. package/configs/_shared/.claude/rules/lang/python/repository.md +383 -0
  23. package/configs/{python/.claude/rules → _shared/.claude/rules/lang/python}/testing.md +2 -69
  24. package/configs/_shared/.claude/rules/lang/typescript/async.md +447 -0
  25. package/configs/_shared/.claude/rules/lang/typescript/generics.md +356 -0
  26. package/configs/_shared/.claude/rules/lang/typescript/typescript.md +212 -0
  27. package/configs/_shared/.claude/rules/quality/error-handling.md +48 -0
  28. package/configs/_shared/.claude/rules/quality/logging.md +45 -0
  29. package/configs/_shared/.claude/rules/quality/observability.md +240 -0
  30. package/configs/_shared/.claude/rules/quality/testing-patterns.md +65 -0
  31. package/configs/_shared/.claude/rules/security/secrets-management.md +222 -0
  32. package/configs/_shared/.claude/skills/analysis/explore/SKILL.md +257 -0
  33. package/configs/_shared/.claude/skills/analysis/security-audit/SKILL.md +184 -0
  34. package/configs/_shared/.claude/skills/dev/api-endpoint/SKILL.md +126 -0
  35. package/configs/_shared/.claude/{commands/generate-tests.md → skills/dev/generate-tests/SKILL.md} +6 -0
  36. package/configs/_shared/.claude/{commands/fix-issue.md → skills/git/fix-issue/SKILL.md} +6 -0
  37. package/configs/_shared/.claude/{commands/review-pr.md → skills/git/review-pr/SKILL.md} +6 -0
  38. package/configs/_shared/.claude/skills/infra/deploy/SKILL.md +139 -0
  39. package/configs/_shared/.claude/skills/infra/docker/SKILL.md +95 -0
  40. package/configs/_shared/.claude/skills/infra/migration/SKILL.md +158 -0
  41. package/configs/_shared/.claude/skills/nx/nx-affected/SKILL.md +72 -0
  42. package/configs/_shared/.claude/skills/nx/nx-lib/SKILL.md +375 -0
  43. package/configs/_shared/CLAUDE.md +52 -149
  44. package/configs/angular/.claude/rules/{components.md → core/components.md} +69 -15
  45. package/configs/angular/.claude/rules/core/resource.md +285 -0
  46. package/configs/angular/.claude/rules/core/signals.md +323 -0
  47. package/configs/angular/.claude/rules/http.md +338 -0
  48. package/configs/angular/.claude/rules/routing.md +291 -0
  49. package/configs/angular/.claude/rules/ssr.md +312 -0
  50. package/configs/angular/.claude/rules/state/signal-store.md +408 -0
  51. package/configs/angular/.claude/rules/{state.md → state/state.md} +2 -2
  52. package/configs/angular/.claude/rules/testing.md +7 -7
  53. package/configs/angular/.claude/rules/ui/aria.md +422 -0
  54. package/configs/angular/.claude/rules/ui/forms.md +424 -0
  55. package/configs/angular/.claude/rules/ui/pipes-directives.md +335 -0
  56. package/configs/angular/.claude/settings.json +1 -0
  57. package/configs/angular/.claude/skills/ngrx-slice/SKILL.md +362 -0
  58. package/configs/angular/.claude/skills/signal-store/SKILL.md +445 -0
  59. package/configs/angular/CLAUDE.md +24 -216
  60. package/configs/dotnet/.claude/rules/background-services.md +552 -0
  61. package/configs/dotnet/.claude/rules/configuration.md +426 -0
  62. package/configs/dotnet/.claude/rules/ddd.md +447 -0
  63. package/configs/dotnet/.claude/rules/dependency-injection.md +343 -0
  64. package/configs/dotnet/.claude/rules/mediatr.md +320 -0
  65. package/configs/dotnet/.claude/rules/middleware.md +489 -0
  66. package/configs/dotnet/.claude/rules/result-pattern.md +363 -0
  67. package/configs/dotnet/.claude/rules/validation.md +388 -0
  68. package/configs/dotnet/.claude/settings.json +21 -3
  69. package/configs/dotnet/CLAUDE.md +53 -286
  70. package/configs/fastapi/.claude/rules/background-tasks.md +254 -0
  71. package/configs/fastapi/.claude/rules/dependencies.md +170 -0
  72. package/configs/{python → fastapi}/.claude/rules/fastapi.md +61 -1
  73. package/configs/fastapi/.claude/rules/lifespan.md +274 -0
  74. package/configs/fastapi/.claude/rules/middleware.md +229 -0
  75. package/configs/fastapi/.claude/rules/pydantic.md +433 -0
  76. package/configs/fastapi/.claude/rules/responses.md +251 -0
  77. package/configs/fastapi/.claude/rules/routers.md +202 -0
  78. package/configs/fastapi/.claude/rules/security.md +222 -0
  79. package/configs/fastapi/.claude/rules/testing.md +251 -0
  80. package/configs/fastapi/.claude/rules/websockets.md +298 -0
  81. package/configs/fastapi/.claude/settings.json +33 -0
  82. package/configs/fastapi/CLAUDE.md +144 -0
  83. package/configs/flask/.claude/rules/blueprints.md +208 -0
  84. package/configs/flask/.claude/rules/cli.md +285 -0
  85. package/configs/flask/.claude/rules/configuration.md +281 -0
  86. package/configs/flask/.claude/rules/context.md +238 -0
  87. package/configs/flask/.claude/rules/error-handlers.md +278 -0
  88. package/configs/flask/.claude/rules/extensions.md +278 -0
  89. package/configs/flask/.claude/rules/flask.md +171 -0
  90. package/configs/flask/.claude/rules/marshmallow.md +206 -0
  91. package/configs/flask/.claude/rules/security.md +267 -0
  92. package/configs/flask/.claude/rules/testing.md +284 -0
  93. package/configs/flask/.claude/settings.json +33 -0
  94. package/configs/flask/CLAUDE.md +166 -0
  95. package/configs/nestjs/.claude/rules/common-patterns.md +300 -0
  96. package/configs/nestjs/.claude/rules/filters.md +376 -0
  97. package/configs/nestjs/.claude/rules/interceptors.md +317 -0
  98. package/configs/nestjs/.claude/rules/middleware.md +321 -0
  99. package/configs/nestjs/.claude/rules/modules.md +26 -0
  100. package/configs/nestjs/.claude/rules/pipes.md +351 -0
  101. package/configs/nestjs/.claude/rules/websockets.md +451 -0
  102. package/configs/nestjs/.claude/settings.json +16 -2
  103. package/configs/nestjs/CLAUDE.md +57 -215
  104. package/configs/nextjs/.claude/rules/api-routes.md +358 -0
  105. package/configs/nextjs/.claude/rules/authentication.md +355 -0
  106. package/configs/nextjs/.claude/rules/components.md +52 -0
  107. package/configs/nextjs/.claude/rules/data-fetching.md +249 -0
  108. package/configs/nextjs/.claude/rules/database.md +400 -0
  109. package/configs/nextjs/.claude/rules/middleware.md +303 -0
  110. package/configs/nextjs/.claude/rules/routing.md +324 -0
  111. package/configs/nextjs/.claude/rules/seo.md +350 -0
  112. package/configs/nextjs/.claude/rules/server-actions.md +353 -0
  113. package/configs/nextjs/.claude/rules/state/zustand.md +6 -6
  114. package/configs/nextjs/.claude/settings.json +5 -0
  115. package/configs/nextjs/CLAUDE.md +69 -331
  116. package/package.json +23 -9
  117. package/src/cli.js +220 -0
  118. package/src/config.js +29 -0
  119. package/src/index.js +13 -0
  120. package/src/installer.js +361 -0
  121. package/src/merge.js +116 -0
  122. package/src/tech-config.json +29 -0
  123. package/src/utils.js +96 -0
  124. package/configs/python/.claude/rules/flask.md +0 -332
  125. package/configs/python/.claude/settings.json +0 -18
  126. package/configs/python/CLAUDE.md +0 -273
  127. package/src/install.js +0 -315
  128. /package/configs/_shared/.claude/rules/{accessibility.md → domain/frontend/accessibility.md} +0 -0
  129. /package/configs/_shared/.claude/rules/{security.md → security/security.md} +0 -0
  130. /package/configs/_shared/.claude/skills/{debug → dev/debug}/SKILL.md +0 -0
  131. /package/configs/_shared/.claude/skills/{learning → dev/learning}/SKILL.md +0 -0
  132. /package/configs/_shared/.claude/skills/{spec → dev/spec}/SKILL.md +0 -0
  133. /package/configs/_shared/.claude/skills/{review → git/review}/SKILL.md +0 -0
@@ -0,0 +1,275 @@
1
+ ---
2
+ paths:
3
+ - "**/Dockerfile"
4
+ - "**/docker-compose*.yml"
5
+ - "**/.dockerignore"
6
+ ---
7
+
8
+ # Docker Best Practices
9
+
10
+ ## Dockerfile Principles
11
+
12
+ ### Multi-stage Builds
13
+
14
+ Always use multi-stage builds to minimize image size:
15
+
16
+ ```dockerfile
17
+ # Stage 1: Build
18
+ FROM node:20-alpine AS builder
19
+ WORKDIR /app
20
+ COPY package*.json ./
21
+ RUN npm ci
22
+ COPY . .
23
+ RUN npm run build
24
+
25
+ # Stage 2: Production
26
+ FROM node:20-alpine AS runner
27
+ WORKDIR /app
28
+ ENV NODE_ENV=production
29
+ COPY --from=builder /app/dist ./dist
30
+ COPY --from=builder /app/node_modules ./node_modules
31
+ USER node
32
+ EXPOSE 3000
33
+ CMD ["node", "dist/main.js"]
34
+ ```
35
+
36
+ ### Layer Optimization
37
+
38
+ Order from least to most frequently changed:
39
+
40
+ ```dockerfile
41
+ # 1. Base image (rarely changes)
42
+ FROM node:20-alpine
43
+
44
+ # 2. System dependencies (rarely changes)
45
+ RUN apk add --no-cache dumb-init
46
+
47
+ # 3. App dependencies (changes with package.json)
48
+ WORKDIR /app
49
+ COPY package*.json ./
50
+ RUN npm ci --only=production
51
+
52
+ # 4. App code (changes frequently)
53
+ COPY . .
54
+
55
+ # 5. Build (if needed)
56
+ RUN npm run build
57
+ ```
58
+
59
+ ### Security
60
+
61
+ ```dockerfile
62
+ # Use specific version, not :latest
63
+ FROM node:20.10.0-alpine
64
+
65
+ # Run as non-root user
66
+ RUN addgroup -g 1001 appgroup && \
67
+ adduser -u 1001 -G appgroup -s /bin/sh -D appuser
68
+ USER appuser
69
+
70
+ # Don't expose unnecessary ports
71
+ EXPOSE 3000
72
+
73
+ # Use read-only filesystem where possible
74
+ # (set in docker-compose or runtime)
75
+ ```
76
+
77
+ ## .dockerignore
78
+
79
+ Always include:
80
+
81
+ ```
82
+ node_modules
83
+ npm-debug.log
84
+ .git
85
+ .gitignore
86
+ .env
87
+ .env.*
88
+ *.md
89
+ .vscode
90
+ .idea
91
+ coverage
92
+ dist
93
+ .nx
94
+ tmp
95
+ ```
96
+
97
+ ## Docker Compose
98
+
99
+ ### Development
100
+
101
+ ```yaml
102
+ # docker-compose.yml
103
+ services:
104
+ app:
105
+ build:
106
+ context: .
107
+ dockerfile: Dockerfile
108
+ target: development
109
+ volumes:
110
+ - .:/app
111
+ - /app/node_modules # Prevent overwriting
112
+ ports:
113
+ - "3000:3000"
114
+ environment:
115
+ - NODE_ENV=development
116
+ depends_on:
117
+ - db
118
+ - redis
119
+
120
+ db:
121
+ image: postgres:16-alpine
122
+ environment:
123
+ POSTGRES_USER: dev
124
+ POSTGRES_PASSWORD: dev
125
+ POSTGRES_DB: app_dev
126
+ volumes:
127
+ - postgres_data:/var/lib/postgresql/data
128
+ ports:
129
+ - "5432:5432"
130
+
131
+ redis:
132
+ image: redis:7-alpine
133
+ ports:
134
+ - "6379:6379"
135
+
136
+ volumes:
137
+ postgres_data:
138
+ ```
139
+
140
+ ### Production
141
+
142
+ ```yaml
143
+ # docker-compose.prod.yml
144
+ services:
145
+ app:
146
+ build:
147
+ context: .
148
+ dockerfile: Dockerfile
149
+ target: production
150
+ restart: unless-stopped
151
+ read_only: true
152
+ security_opt:
153
+ - no-new-privileges:true
154
+ environment:
155
+ - NODE_ENV=production
156
+ healthcheck:
157
+ test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
158
+ interval: 30s
159
+ timeout: 10s
160
+ retries: 3
161
+ start_period: 40s
162
+ deploy:
163
+ resources:
164
+ limits:
165
+ cpus: '1'
166
+ memory: 512M
167
+ ```
168
+
169
+ ## Framework-Specific Patterns
170
+
171
+ ### Node.js / NestJS / Next.js
172
+
173
+ ```dockerfile
174
+ FROM node:20-alpine AS base
175
+ RUN apk add --no-cache libc6-compat
176
+ WORKDIR /app
177
+
178
+ FROM base AS deps
179
+ COPY package*.json ./
180
+ RUN npm ci
181
+
182
+ FROM base AS builder
183
+ COPY --from=deps /app/node_modules ./node_modules
184
+ COPY . .
185
+ RUN npm run build
186
+
187
+ FROM base AS runner
188
+ ENV NODE_ENV=production
189
+ RUN addgroup --system --gid 1001 nodejs
190
+ RUN adduser --system --uid 1001 app
191
+ COPY --from=builder --chown=app:nodejs /app/dist ./dist
192
+ COPY --from=builder --chown=app:nodejs /app/node_modules ./node_modules
193
+ USER app
194
+ EXPOSE 3000
195
+ CMD ["node", "dist/main.js"]
196
+ ```
197
+
198
+ ### Python / FastAPI
199
+
200
+ ```dockerfile
201
+ FROM python:3.12-slim AS base
202
+ ENV PYTHONDONTWRITEBYTECODE=1 \
203
+ PYTHONUNBUFFERED=1 \
204
+ PIP_NO_CACHE_DIR=1
205
+
206
+ FROM base AS builder
207
+ RUN pip install poetry
208
+ WORKDIR /app
209
+ COPY pyproject.toml poetry.lock ./
210
+ RUN poetry export -f requirements.txt --output requirements.txt
211
+
212
+ FROM base AS runner
213
+ WORKDIR /app
214
+ COPY --from=builder /app/requirements.txt .
215
+ RUN pip install -r requirements.txt
216
+ COPY . .
217
+ RUN useradd -m appuser && chown -R appuser:appuser /app
218
+ USER appuser
219
+ EXPOSE 8000
220
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
221
+ ```
222
+
223
+ ### .NET
224
+
225
+ ```dockerfile
226
+ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
227
+ WORKDIR /src
228
+ COPY *.csproj ./
229
+ RUN dotnet restore
230
+ COPY . .
231
+ RUN dotnet publish -c Release -o /app/publish
232
+
233
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
234
+ WORKDIR /app
235
+ COPY --from=build /app/publish .
236
+ RUN useradd -m appuser && chown -R appuser:appuser /app
237
+ USER appuser
238
+ EXPOSE 8080
239
+ ENTRYPOINT ["dotnet", "App.dll"]
240
+ ```
241
+
242
+ ## Health Checks
243
+
244
+ Always implement health endpoints:
245
+
246
+ ```dockerfile
247
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
248
+ CMD curl -f http://localhost:3000/health || exit 1
249
+ ```
250
+
251
+ ## Environment Variables
252
+
253
+ ```dockerfile
254
+ # Build-time args
255
+ ARG NODE_ENV=production
256
+ ARG APP_VERSION
257
+
258
+ # Runtime environment
259
+ ENV NODE_ENV=${NODE_ENV} \
260
+ APP_VERSION=${APP_VERSION}
261
+
262
+ # Never put secrets in Dockerfile!
263
+ # Use: docker run -e SECRET=xxx or docker-compose with env_file
264
+ ```
265
+
266
+ ## Anti-patterns
267
+
268
+ - Using `:latest` tag
269
+ - Running as root
270
+ - Copying entire context before installing deps
271
+ - Not using multi-stage builds
272
+ - Hardcoding secrets in Dockerfile
273
+ - Not setting resource limits
274
+ - Missing health checks
275
+ - Not using .dockerignore
@@ -0,0 +1,194 @@
1
+ ---
2
+ paths:
3
+ - "libs/**/*"
4
+ - "apps/**/*"
5
+ - "nx.json"
6
+ - "project.json"
7
+ - "*.ts"
8
+ ---
9
+
10
+ # Nx Monorepo Rules
11
+
12
+ ## Project Structure
13
+
14
+ ```
15
+ workspace/
16
+ ├── apps/ # Deployable applications
17
+ │ ├── web/ # Main app
18
+ │ └── web-e2e/ # E2E tests
19
+ ├── libs/ # Reusable libraries
20
+ │ ├── shared/ # Cross-domain (ui, util)
21
+ │ └── [domain]/ # Domain-specific
22
+ │ ├── feature-*/ # Smart components, pages
23
+ │ ├── ui-*/ # Dumb/presentational components
24
+ │ ├── data-access-*/ # State, API services
25
+ │ └── util-*/ # Pure functions, helpers
26
+ ├── nx.json
27
+ └── tsconfig.base.json
28
+ ```
29
+
30
+ ## Library Types
31
+
32
+ | Type | Purpose | Can Import |
33
+ |------|---------|------------|
34
+ | `feature` | Smart components, routing, pages | ui, data-access, util |
35
+ | `ui` | Presentational components | util only |
36
+ | `data-access` | State management, API calls | util only |
37
+ | `util` | Pure functions, types, constants | util only |
38
+
39
+ ## Naming Convention
40
+
41
+ ```
42
+ libs/[scope]/[type]-[name]
43
+
44
+ # Examples
45
+ libs/users/feature-list # User list page
46
+ libs/users/ui-avatar # Avatar component
47
+ libs/users/data-access # User state/API
48
+ libs/users/util-permissions # Permission helpers
49
+ libs/shared/ui-button # Shared button
50
+ libs/shared/util-format # Format utilities
51
+ ```
52
+
53
+ ## Tags & Boundaries
54
+
55
+ ### nx.json
56
+
57
+ ```json
58
+ {
59
+ "targetDefaults": {
60
+ "build": { "dependsOn": ["^build"] },
61
+ "test": { "dependsOn": ["build"] }
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### project.json tags
67
+
68
+ ```json
69
+ {
70
+ "tags": ["scope:users", "type:feature"]
71
+ }
72
+ ```
73
+
74
+ ### .eslintrc.json boundaries
75
+
76
+ ```json
77
+ {
78
+ "rules": {
79
+ "@nx/enforce-module-boundaries": [
80
+ "error",
81
+ {
82
+ "depConstraints": [
83
+ { "sourceTag": "type:feature", "onlyDependOnLibsWithTags": ["type:ui", "type:data-access", "type:util"] },
84
+ { "sourceTag": "type:ui", "onlyDependOnLibsWithTags": ["type:util"] },
85
+ { "sourceTag": "type:data-access", "onlyDependOnLibsWithTags": ["type:util"] },
86
+ { "sourceTag": "type:util", "onlyDependOnLibsWithTags": ["type:util"] },
87
+ { "sourceTag": "scope:shared", "onlyDependOnLibsWithTags": ["scope:shared"] },
88
+ { "sourceTag": "scope:users", "onlyDependOnLibsWithTags": ["scope:users", "scope:shared"] }
89
+ ]
90
+ }
91
+ ]
92
+ }
93
+ }
94
+ ```
95
+
96
+ ## Dependency Flow
97
+
98
+ ```
99
+ ┌─────────────────────────────────────────────┐
100
+ │ apps/ │
101
+ │ (can import any lib) │
102
+ └─────────────────────────────────────────────┘
103
+
104
+
105
+ ┌─────────────────────────────────────────────┐
106
+ │ feature libs │
107
+ │ (pages, smart components, routing) │
108
+ └─────────────────────────────────────────────┘
109
+ │ │
110
+ ▼ ▼
111
+ ┌──────────────────┐ ┌──────────────────┐
112
+ │ ui libs │ │ data-access │
113
+ │ (presentational)│ │ (state, API) │
114
+ └──────────────────┘ └──────────────────┘
115
+ │ │
116
+ └───────┬────────┘
117
+
118
+ ┌─────────────────────────────────────────────┐
119
+ │ util libs │
120
+ │ (pure functions, types, constants) │
121
+ └─────────────────────────────────────────────┘
122
+ ```
123
+
124
+ ## Commands Reference
125
+
126
+ | Command | Description |
127
+ |---------|-------------|
128
+ | `nx affected -t test` | Test affected projects |
129
+ | `nx affected -t build` | Build affected projects |
130
+ | `nx affected -t lint` | Lint affected projects |
131
+ | `nx run-many -t test --all` | Test all projects |
132
+ | `nx graph` | Visualize dependency graph |
133
+ | `nx reset` | Clear cache |
134
+
135
+ ## Generator Commands
136
+
137
+ | Command | Description |
138
+ |---------|-------------|
139
+ | `nx g @nx/angular:lib [name]` | Generate Angular library |
140
+ | `nx g @nx/angular:component [name]` | Generate component |
141
+ | `nx g @nx/angular:service [name]` | Generate service |
142
+ | `nx g remove [name]` | Remove project |
143
+ | `nx g move --project [name] [dest]` | Move project |
144
+
145
+ ## Import Paths
146
+
147
+ Always use workspace paths, never relative imports across libs:
148
+
149
+ ```typescript
150
+ // GOOD - workspace path
151
+ import { UserService } from '@myorg/users/data-access';
152
+ import { ButtonComponent } from '@myorg/shared/ui-button';
153
+
154
+ // BAD - relative cross-lib import
155
+ import { UserService } from '../../../users/data-access/src';
156
+ ```
157
+
158
+ ## Anti-patterns
159
+
160
+ - Never import from `apps/` into `libs/`
161
+ - Never create circular dependencies between libs
162
+ - Never import `feature` into `ui` or `data-access`
163
+ - Never import domain-specific into `shared/` scope
164
+ - Never skip the public API (`index.ts`)
165
+
166
+ ## Caching
167
+
168
+ Nx caches build/test results. To leverage:
169
+
170
+ ```json
171
+ // nx.json
172
+ {
173
+ "tasksRunnerOptions": {
174
+ "default": {
175
+ "runner": "nx/tasks-runners/default",
176
+ "options": {
177
+ "cacheableOperations": ["build", "lint", "test", "e2e"]
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ ## Affected Commands
185
+
186
+ Always use `affected` in CI:
187
+
188
+ ```bash
189
+ # Only test what changed
190
+ nx affected -t test --base=main --head=HEAD
191
+
192
+ # Only build what changed
193
+ nx affected -t build --base=main --head=HEAD
194
+ ```
@@ -0,0 +1,203 @@
1
+ ---
2
+ paths:
3
+ - "**/controllers/**"
4
+ - "**/routes/**"
5
+ - "**/routers/**"
6
+ - "**/endpoints/**"
7
+ - "**/*.controller.ts"
8
+ - "**/*_router.py"
9
+ ---
10
+
11
+ # API Design Principles
12
+
13
+ ## REST Conventions
14
+
15
+ ### HTTP Methods
16
+
17
+ | Method | Usage | Idempotent | Response |
18
+ |--------|-------|------------|----------|
19
+ | `GET` | Read resource(s) | Yes | 200 + data |
20
+ | `POST` | Create resource | No | 201 + created resource |
21
+ | `PUT` | Full update | Yes | 200 + updated resource |
22
+ | `PATCH` | Partial update | Yes | 200 + updated resource |
23
+ | `DELETE` | Remove resource | Yes | 204 No Content |
24
+
25
+ ### URL Structure
26
+
27
+ ```
28
+ GET /api/v1/users # List users
29
+ GET /api/v1/users/:id # Get single user
30
+ POST /api/v1/users # Create user
31
+ PUT /api/v1/users/:id # Replace user
32
+ PATCH /api/v1/users/:id # Update user fields
33
+ DELETE /api/v1/users/:id # Delete user
34
+
35
+ # Nested resources (max 2 levels)
36
+ GET /api/v1/users/:id/orders
37
+ POST /api/v1/users/:id/orders
38
+
39
+ # Actions (when CRUD doesn't fit)
40
+ POST /api/v1/users/:id/activate
41
+ POST /api/v1/orders/:id/cancel
42
+ ```
43
+
44
+ ### Naming Rules
45
+
46
+ - Use **plural nouns**: `/users`, `/orders`, `/products`
47
+ - Use **kebab-case**: `/user-profiles`, `/order-items`
48
+ - Avoid verbs in URLs (use HTTP methods instead)
49
+ - Use query params for filtering: `/users?status=active&role=admin`
50
+
51
+ ## Response Format
52
+
53
+ ### Success Response
54
+
55
+ ```json
56
+ {
57
+ "data": { ... },
58
+ "meta": {
59
+ "timestamp": "2024-01-15T10:30:00Z",
60
+ "requestId": "abc-123"
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### List Response with Pagination
66
+
67
+ ```json
68
+ {
69
+ "data": [ ... ],
70
+ "meta": {
71
+ "total": 100,
72
+ "page": 1,
73
+ "pageSize": 20,
74
+ "totalPages": 5,
75
+ "hasNext": true,
76
+ "hasPrevious": false
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### Error Response (RFC 7807 Problem Details)
82
+
83
+ ```json
84
+ {
85
+ "type": "https://api.example.com/errors/validation",
86
+ "title": "Validation Error",
87
+ "status": 400,
88
+ "detail": "One or more fields failed validation",
89
+ "instance": "/api/v1/users",
90
+ "errors": [
91
+ { "field": "email", "message": "Invalid email format" },
92
+ { "field": "age", "message": "Must be at least 18" }
93
+ ],
94
+ "traceId": "abc-123"
95
+ }
96
+ ```
97
+
98
+ ## Status Codes
99
+
100
+ | Code | When to Use |
101
+ |------|-------------|
102
+ | `200` | Successful GET, PUT, PATCH |
103
+ | `201` | Successful POST (resource created) |
104
+ | `204` | Successful DELETE (no content) |
105
+ | `400` | Bad request (validation error) |
106
+ | `401` | Unauthorized (not authenticated) |
107
+ | `403` | Forbidden (authenticated but not allowed) |
108
+ | `404` | Resource not found |
109
+ | `409` | Conflict (duplicate resource) |
110
+ | `422` | Unprocessable entity (business rule violation) |
111
+ | `429` | Too many requests (rate limited) |
112
+ | `500` | Internal server error |
113
+
114
+ ## Pagination
115
+
116
+ ### Offset-based (simple, for small datasets)
117
+
118
+ ```
119
+ GET /api/v1/users?page=2&pageSize=20
120
+ ```
121
+
122
+ ### Cursor-based (performant, for large datasets)
123
+
124
+ ```
125
+ GET /api/v1/users?cursor=eyJpZCI6MTAwfQ&limit=20
126
+ ```
127
+
128
+ Response includes next cursor:
129
+ ```json
130
+ {
131
+ "data": [...],
132
+ "meta": {
133
+ "nextCursor": "eyJpZCI6MTIwfQ",
134
+ "hasMore": true
135
+ }
136
+ }
137
+ ```
138
+
139
+ ## Filtering & Sorting
140
+
141
+ ```
142
+ # Filtering
143
+ GET /api/v1/users?status=active&role=admin
144
+ GET /api/v1/orders?createdAt[gte]=2024-01-01&createdAt[lte]=2024-12-31
145
+
146
+ # Sorting
147
+ GET /api/v1/users?sort=createdAt:desc
148
+ GET /api/v1/users?sort=lastName:asc,firstName:asc
149
+
150
+ # Field selection (sparse fieldsets)
151
+ GET /api/v1/users?fields=id,name,email
152
+ ```
153
+
154
+ ## Versioning
155
+
156
+ ### URL Path (recommended)
157
+
158
+ ```
159
+ /api/v1/users
160
+ /api/v2/users
161
+ ```
162
+
163
+ ### Header-based (alternative)
164
+
165
+ ```
166
+ Accept: application/vnd.api+json; version=1
167
+ ```
168
+
169
+ ## Rate Limiting
170
+
171
+ Include headers in response:
172
+
173
+ ```
174
+ X-RateLimit-Limit: 100
175
+ X-RateLimit-Remaining: 95
176
+ X-RateLimit-Reset: 1640000000
177
+ Retry-After: 60 (when 429)
178
+ ```
179
+
180
+ ## HATEOAS (optional, for discoverability)
181
+
182
+ ```json
183
+ {
184
+ "data": {
185
+ "id": "123",
186
+ "name": "John"
187
+ },
188
+ "links": {
189
+ "self": "/api/v1/users/123",
190
+ "orders": "/api/v1/users/123/orders",
191
+ "profile": "/api/v1/users/123/profile"
192
+ }
193
+ }
194
+ ```
195
+
196
+ ## Anti-patterns
197
+
198
+ - Verbs in URLs: `/api/getUsers` → `/api/users`
199
+ - Singular nouns: `/api/user/123` → `/api/users/123`
200
+ - Deeply nested: `/api/users/1/orders/2/items/3` → `/api/order-items/3`
201
+ - Inconsistent casing: `/api/userProfiles` → `/api/user-profiles`
202
+ - Returning 200 for errors
203
+ - Exposing internal IDs or sensitive data