@malamute/ai-rules 1.0.0 → 1.3.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 (145) hide show
  1. package/README.md +272 -121
  2. package/bin/cli.js +5 -2
  3. package/configs/_shared/CLAUDE.md +52 -149
  4. package/configs/_shared/rules/conventions/documentation.md +324 -0
  5. package/configs/_shared/rules/conventions/git.md +265 -0
  6. package/configs/_shared/rules/conventions/npm.md +80 -0
  7. package/configs/_shared/{.claude/rules → rules/conventions}/performance.md +1 -1
  8. package/configs/_shared/rules/conventions/principles.md +334 -0
  9. package/configs/_shared/rules/devops/ci-cd.md +262 -0
  10. package/configs/_shared/rules/devops/docker.md +275 -0
  11. package/configs/_shared/rules/devops/nx.md +194 -0
  12. package/configs/_shared/rules/domain/backend/api-design.md +203 -0
  13. package/configs/_shared/rules/lang/csharp/async.md +220 -0
  14. package/configs/_shared/rules/lang/csharp/csharp.md +314 -0
  15. package/configs/_shared/rules/lang/csharp/linq.md +210 -0
  16. package/configs/_shared/rules/lang/python/async.md +337 -0
  17. package/configs/_shared/rules/lang/python/celery.md +476 -0
  18. package/configs/_shared/rules/lang/python/config.md +339 -0
  19. package/configs/{python/.claude/rules → _shared/rules/lang/python}/database/sqlalchemy.md +6 -1
  20. package/configs/_shared/rules/lang/python/deployment.md +523 -0
  21. package/configs/_shared/rules/lang/python/error-handling.md +330 -0
  22. package/configs/_shared/rules/lang/python/migrations.md +421 -0
  23. package/configs/_shared/rules/lang/python/python.md +172 -0
  24. package/configs/_shared/rules/lang/python/repository.md +383 -0
  25. package/configs/{python/.claude/rules → _shared/rules/lang/python}/testing.md +2 -69
  26. package/configs/_shared/rules/lang/typescript/async.md +447 -0
  27. package/configs/_shared/rules/lang/typescript/generics.md +356 -0
  28. package/configs/_shared/rules/lang/typescript/typescript.md +212 -0
  29. package/configs/_shared/rules/quality/error-handling.md +48 -0
  30. package/configs/_shared/rules/quality/logging.md +45 -0
  31. package/configs/_shared/rules/quality/observability.md +240 -0
  32. package/configs/_shared/rules/quality/testing-patterns.md +65 -0
  33. package/configs/_shared/rules/security/secrets-management.md +222 -0
  34. package/configs/_shared/skills/analysis/explore/SKILL.md +257 -0
  35. package/configs/_shared/skills/analysis/security-audit/SKILL.md +184 -0
  36. package/configs/_shared/skills/dev/api-endpoint/SKILL.md +126 -0
  37. package/configs/_shared/{.claude/commands/generate-tests.md → skills/dev/generate-tests/SKILL.md} +6 -0
  38. package/configs/_shared/{.claude/commands/fix-issue.md → skills/git/fix-issue/SKILL.md} +6 -0
  39. package/configs/_shared/{.claude/commands/review-pr.md → skills/git/review-pr/SKILL.md} +6 -0
  40. package/configs/_shared/skills/infra/deploy/SKILL.md +139 -0
  41. package/configs/_shared/skills/infra/docker/SKILL.md +95 -0
  42. package/configs/_shared/skills/infra/migration/SKILL.md +158 -0
  43. package/configs/_shared/skills/nx/nx-affected/SKILL.md +72 -0
  44. package/configs/_shared/skills/nx/nx-lib/SKILL.md +375 -0
  45. package/configs/angular/CLAUDE.md +24 -216
  46. package/configs/angular/{.claude/rules → rules/core}/components.md +69 -15
  47. package/configs/angular/rules/core/resource.md +285 -0
  48. package/configs/angular/rules/core/signals.md +323 -0
  49. package/configs/angular/rules/http.md +338 -0
  50. package/configs/angular/rules/routing.md +291 -0
  51. package/configs/angular/rules/ssr.md +312 -0
  52. package/configs/angular/rules/state/signal-store.md +408 -0
  53. package/configs/angular/{.claude/rules → rules/state}/state.md +2 -2
  54. package/configs/angular/{.claude/rules → rules}/testing.md +7 -7
  55. package/configs/angular/rules/ui/aria.md +422 -0
  56. package/configs/angular/rules/ui/forms.md +424 -0
  57. package/configs/angular/rules/ui/pipes-directives.md +335 -0
  58. package/configs/angular/{.claude/settings.json → settings.json} +3 -0
  59. package/configs/dotnet/CLAUDE.md +53 -286
  60. package/configs/dotnet/rules/background-services.md +552 -0
  61. package/configs/dotnet/rules/configuration.md +426 -0
  62. package/configs/dotnet/rules/ddd.md +447 -0
  63. package/configs/dotnet/rules/dependency-injection.md +343 -0
  64. package/configs/dotnet/rules/mediatr.md +320 -0
  65. package/configs/dotnet/rules/middleware.md +489 -0
  66. package/configs/dotnet/rules/result-pattern.md +363 -0
  67. package/configs/dotnet/rules/validation.md +388 -0
  68. package/configs/dotnet/settings.json +29 -0
  69. package/configs/fastapi/CLAUDE.md +144 -0
  70. package/configs/fastapi/rules/background-tasks.md +254 -0
  71. package/configs/fastapi/rules/dependencies.md +170 -0
  72. package/configs/{python/.claude → fastapi}/rules/fastapi.md +61 -1
  73. package/configs/fastapi/rules/lifespan.md +274 -0
  74. package/configs/fastapi/rules/middleware.md +229 -0
  75. package/configs/fastapi/rules/pydantic.md +433 -0
  76. package/configs/fastapi/rules/responses.md +251 -0
  77. package/configs/fastapi/rules/routers.md +202 -0
  78. package/configs/fastapi/rules/security.md +222 -0
  79. package/configs/fastapi/rules/testing.md +251 -0
  80. package/configs/fastapi/rules/websockets.md +298 -0
  81. package/configs/fastapi/settings.json +35 -0
  82. package/configs/flask/CLAUDE.md +166 -0
  83. package/configs/flask/rules/blueprints.md +208 -0
  84. package/configs/flask/rules/cli.md +285 -0
  85. package/configs/flask/rules/configuration.md +281 -0
  86. package/configs/flask/rules/context.md +238 -0
  87. package/configs/flask/rules/error-handlers.md +278 -0
  88. package/configs/flask/rules/extensions.md +278 -0
  89. package/configs/flask/rules/flask.md +171 -0
  90. package/configs/flask/rules/marshmallow.md +206 -0
  91. package/configs/flask/rules/security.md +267 -0
  92. package/configs/flask/rules/testing.md +284 -0
  93. package/configs/flask/settings.json +35 -0
  94. package/configs/nestjs/CLAUDE.md +57 -215
  95. package/configs/nestjs/rules/common-patterns.md +300 -0
  96. package/configs/nestjs/rules/filters.md +376 -0
  97. package/configs/nestjs/rules/interceptors.md +317 -0
  98. package/configs/nestjs/rules/middleware.md +321 -0
  99. package/configs/nestjs/{.claude/rules → rules}/modules.md +26 -0
  100. package/configs/nestjs/rules/pipes.md +351 -0
  101. package/configs/nestjs/rules/websockets.md +451 -0
  102. package/configs/nestjs/settings.json +31 -0
  103. package/configs/nextjs/CLAUDE.md +69 -331
  104. package/configs/nextjs/rules/api-routes.md +358 -0
  105. package/configs/nextjs/rules/authentication.md +355 -0
  106. package/configs/nextjs/{.claude/rules → rules}/components.md +52 -0
  107. package/configs/nextjs/rules/data-fetching.md +249 -0
  108. package/configs/nextjs/rules/database.md +400 -0
  109. package/configs/nextjs/rules/middleware.md +303 -0
  110. package/configs/nextjs/rules/routing.md +324 -0
  111. package/configs/nextjs/rules/seo.md +350 -0
  112. package/configs/nextjs/rules/server-actions.md +353 -0
  113. package/configs/nextjs/{.claude/rules → rules}/state/zustand.md +6 -6
  114. package/configs/nextjs/{.claude/settings.json → settings.json} +7 -0
  115. package/package.json +24 -9
  116. package/src/cli.js +218 -0
  117. package/src/config.js +63 -0
  118. package/src/index.js +4 -0
  119. package/src/installer.js +414 -0
  120. package/src/merge.js +109 -0
  121. package/src/tech-config.json +45 -0
  122. package/src/utils.js +88 -0
  123. package/configs/dotnet/.claude/settings.json +0 -9
  124. package/configs/nestjs/.claude/settings.json +0 -15
  125. package/configs/python/.claude/rules/flask.md +0 -332
  126. package/configs/python/.claude/settings.json +0 -18
  127. package/configs/python/CLAUDE.md +0 -273
  128. package/src/install.js +0 -315
  129. /package/configs/_shared/{.claude/rules → rules/domain/frontend}/accessibility.md +0 -0
  130. /package/configs/_shared/{.claude/rules → rules/security}/security.md +0 -0
  131. /package/configs/_shared/{.claude/skills → skills/dev}/debug/SKILL.md +0 -0
  132. /package/configs/_shared/{.claude/skills → skills/dev}/learning/SKILL.md +0 -0
  133. /package/configs/_shared/{.claude/skills → skills/dev}/spec/SKILL.md +0 -0
  134. /package/configs/_shared/{.claude/skills → skills/git}/review/SKILL.md +0 -0
  135. /package/configs/dotnet/{.claude/rules → rules}/api.md +0 -0
  136. /package/configs/dotnet/{.claude/rules → rules}/architecture.md +0 -0
  137. /package/configs/dotnet/{.claude/rules → rules}/database/efcore.md +0 -0
  138. /package/configs/dotnet/{.claude/rules → rules}/testing.md +0 -0
  139. /package/configs/nestjs/{.claude/rules → rules}/auth.md +0 -0
  140. /package/configs/nestjs/{.claude/rules → rules}/database/prisma.md +0 -0
  141. /package/configs/nestjs/{.claude/rules → rules}/database/typeorm.md +0 -0
  142. /package/configs/nestjs/{.claude/rules → rules}/testing.md +0 -0
  143. /package/configs/nestjs/{.claude/rules → rules}/validation.md +0 -0
  144. /package/configs/nextjs/{.claude/rules → rules}/state/redux-toolkit.md +0 -0
  145. /package/configs/nextjs/{.claude/rules → rules}/testing.md +0 -0
@@ -0,0 +1,375 @@
1
+ ---
2
+ name: nx-lib
3
+ description: Generate an Nx library for any framework with proper structure and tags
4
+ argument-hint: <framework> <type> <scope>/<name>
5
+ ---
6
+
7
+ # Generate Nx Library
8
+
9
+ ## Syntax
10
+
11
+ ```
12
+ /nx-lib <framework> <type> <scope>/<name>
13
+ ```
14
+
15
+ ## Supported Frameworks
16
+
17
+ | Framework | Generator Package |
18
+ |-----------|-------------------|
19
+ | `angular` | `@nx/angular` |
20
+ | `react` | `@nx/react` |
21
+ | `next` | `@nx/next` |
22
+ | `nest` | `@nx/nest` |
23
+ | `node` | `@nx/node` |
24
+ | `js` | `@nx/js` (pure TypeScript) |
25
+ | `dotnet` | `@nx-dotnet/core` |
26
+ | `python` | `@nxlv/python` |
27
+
28
+ ## Library Types by Framework
29
+
30
+ ### Angular
31
+ | Type | Description | Generator |
32
+ |------|-------------|-----------|
33
+ | `feature` | Smart components, pages, routing | `@nx/angular:lib --standalone` |
34
+ | `ui` | Presentational components | `@nx/angular:lib --standalone` |
35
+ | `data-access` | NgRx store, services | `@nx/angular:lib` + NgRx files |
36
+ | `util` | Pure functions, types | `@nx/js:lib` |
37
+
38
+ ### React / Next.js
39
+ | Type | Description | Generator |
40
+ |------|-------------|-----------|
41
+ | `feature` | Pages, containers | `@nx/react:lib` or `@nx/next:lib` |
42
+ | `ui` | Presentational components | `@nx/react:lib` |
43
+ | `data-access` | Zustand/Redux, API hooks | `@nx/react:lib` |
44
+ | `util` | Pure functions, types | `@nx/js:lib` |
45
+
46
+ ### NestJS
47
+ | Type | Description | Generator |
48
+ |------|-------------|-----------|
49
+ | `feature` | Module with controller | `@nx/nest:lib` + controller |
50
+ | `data-access` | Repository, services | `@nx/nest:lib` |
51
+ | `util` | Pure functions, types | `@nx/js:lib` |
52
+
53
+ ### Node / JS
54
+ | Type | Description | Generator |
55
+ |------|-------------|-----------|
56
+ | `util` | Pure functions, types | `@nx/js:lib` |
57
+ | `data-access` | Services, repositories | `@nx/js:lib` |
58
+
59
+ ### .NET
60
+ | Type | Description | Generator |
61
+ |------|-------------|-----------|
62
+ | `webapi` | ASP.NET Core Web API | `@nx-dotnet/core:app --template webapi` |
63
+ | `classlib` | Class library | `@nx-dotnet/core:lib --template classlib` |
64
+ | `feature` | Feature library (CQRS) | `@nx-dotnet/core:lib` + MediatR handlers |
65
+ | `data-access` | EF Core repositories | `@nx-dotnet/core:lib` + DbContext |
66
+ | `util` | Shared utilities | `@nx-dotnet/core:lib --template classlib` |
67
+
68
+ ### Python
69
+ | Type | Description | Generator |
70
+ |------|-------------|-----------|
71
+ | `app` | FastAPI/Flask app | `@nxlv/python:poetry-project` |
72
+ | `lib` | Python library | `@nxlv/python:poetry-project --projectType=library` |
73
+ | `util` | Utility functions | `@nxlv/python:poetry-project --projectType=library` |
74
+
75
+ ## Examples
76
+
77
+ ```bash
78
+ # Angular feature library
79
+ /nx-lib angular feature users/list
80
+
81
+ # Angular data-access with NgRx
82
+ /nx-lib angular data-access users
83
+
84
+ # React UI component library
85
+ /nx-lib react ui shared/button
86
+
87
+ # NestJS feature module
88
+ /nx-lib nest feature orders
89
+
90
+ # Pure TypeScript utility
91
+ /nx-lib js util shared/format
92
+
93
+ # .NET class library
94
+ /nx-lib dotnet classlib shared/domain
95
+
96
+ # .NET Web API
97
+ /nx-lib dotnet webapi orders
98
+
99
+ # .NET data-access with EF Core
100
+ /nx-lib dotnet data-access users
101
+
102
+ # Python FastAPI app
103
+ /nx-lib python app api
104
+
105
+ # Python library
106
+ /nx-lib python lib shared/utils
107
+ ```
108
+
109
+ ## Execution Steps
110
+
111
+ ### Step 1: Parse Arguments
112
+
113
+ ```
114
+ /nx-lib angular data-access users/profile
115
+ │ │ │
116
+ │ │ └── scope: users, name: profile
117
+ │ └── type: data-access
118
+ └── framework: angular
119
+ ```
120
+
121
+ ### Step 2: Run Generator
122
+
123
+ Based on framework and type:
124
+
125
+ ```bash
126
+ # Angular feature/ui
127
+ nx g @nx/angular:lib <name> \
128
+ --directory=libs/<scope>/<type>-<name> \
129
+ --tags="scope:<scope>,type:<type>" \
130
+ --standalone \
131
+ --style=scss \
132
+ --changeDetection=OnPush
133
+
134
+ # Angular data-access
135
+ nx g @nx/angular:lib <name> \
136
+ --directory=libs/<scope>/data-access \
137
+ --tags="scope:<scope>,type:data-access"
138
+ # Then generate NgRx: actions, reducer, effects, selectors
139
+
140
+ # React/Next feature/ui
141
+ nx g @nx/react:lib <name> \
142
+ --directory=libs/<scope>/<type>-<name> \
143
+ --tags="scope:<scope>,type:<type>"
144
+
145
+ # NestJS feature
146
+ nx g @nx/nest:lib <name> \
147
+ --directory=libs/<scope>/feature-<name> \
148
+ --tags="scope:<scope>,type:feature"
149
+ # Then generate controller
150
+
151
+ # Pure JS/TS util
152
+ nx g @nx/js:lib <name> \
153
+ --directory=libs/<scope>/util-<name> \
154
+ --tags="scope:<scope>,type:util" \
155
+ --bundler=none
156
+
157
+ # .NET class library
158
+ nx g @nx-dotnet/core:lib <name> \
159
+ --directory=libs/<scope>/<type>-<name> \
160
+ --template=classlib \
161
+ --tags="scope:<scope>,type:<type>,framework:dotnet"
162
+
163
+ # .NET Web API
164
+ nx g @nx-dotnet/core:app <name> \
165
+ --directory=apps/<name> \
166
+ --template=webapi \
167
+ --tags="scope:<scope>,type:webapi,framework:dotnet"
168
+
169
+ # Python library
170
+ nx g @nxlv/python:poetry-project <name> \
171
+ --directory=libs/<scope>/<type>-<name> \
172
+ --projectType=library \
173
+ --tags="scope:<scope>,type:<type>,framework:python"
174
+
175
+ # Python app
176
+ nx g @nxlv/python:poetry-project <name> \
177
+ --directory=apps/<name> \
178
+ --projectType=application \
179
+ --tags="scope:<scope>,type:app,framework:python"
180
+ ```
181
+
182
+ ### Step 3: Generate Boilerplate by Type
183
+
184
+ #### Angular `data-access`
185
+ ```
186
+ libs/<scope>/data-access/src/lib/
187
+ ├── +state/
188
+ │ ├── <name>.actions.ts
189
+ │ ├── <name>.reducer.ts
190
+ │ ├── <name>.effects.ts
191
+ │ ├── <name>.selectors.ts
192
+ │ └── <name>.state.ts
193
+ ├── services/
194
+ │ └── <name>.service.ts
195
+ └── index.ts
196
+ ```
197
+
198
+ #### Angular `feature`
199
+ ```
200
+ libs/<scope>/feature-<name>/src/lib/
201
+ ├── <name>.component.ts
202
+ ├── <name>.component.html
203
+ ├── <name>.component.scss
204
+ ├── <name>.routes.ts
205
+ └── index.ts
206
+ ```
207
+
208
+ #### Angular `ui`
209
+ ```
210
+ libs/<scope>/ui-<name>/src/lib/
211
+ ├── <name>.component.ts
212
+ ├── <name>.component.html
213
+ ├── <name>.component.scss
214
+ └── index.ts
215
+ ```
216
+
217
+ #### React `data-access`
218
+ ```
219
+ libs/<scope>/data-access/src/lib/
220
+ ├── store/
221
+ │ └── <name>.store.ts # Zustand store
222
+ ├── hooks/
223
+ │ └── use-<name>.ts # Custom hooks
224
+ ├── api/
225
+ │ └── <name>.api.ts # API calls
226
+ └── index.ts
227
+ ```
228
+
229
+ #### NestJS `feature`
230
+ ```
231
+ libs/<scope>/feature-<name>/src/lib/
232
+ ├── <name>.module.ts
233
+ ├── <name>.controller.ts
234
+ ├── <name>.service.ts
235
+ ├── dto/
236
+ │ ├── create-<name>.dto.ts
237
+ │ └── update-<name>.dto.ts
238
+ └── index.ts
239
+ ```
240
+
241
+ #### JS/TS `util`
242
+ ```
243
+ libs/<scope>/util-<name>/src/lib/
244
+ ├── <name>.ts # Functions
245
+ ├── <name>.types.ts # Types/interfaces
246
+ ├── <name>.spec.ts # Tests
247
+ └── index.ts
248
+ ```
249
+
250
+ #### .NET `webapi`
251
+ ```
252
+ apps/<name>/
253
+ ├── Controllers/
254
+ │ └── <Name>Controller.cs
255
+ ├── Program.cs
256
+ ├── appsettings.json
257
+ ├── <Name>.Api.csproj
258
+ └── project.json
259
+ ```
260
+
261
+ #### .NET `classlib`
262
+ ```
263
+ libs/<scope>/<type>-<name>/
264
+ ├── src/
265
+ │ └── <Name>.cs
266
+ ├── <Scope>.<Type>.<Name>.csproj
267
+ └── project.json
268
+ ```
269
+
270
+ #### .NET `data-access`
271
+ ```
272
+ libs/<scope>/data-access/
273
+ ├── src/
274
+ │ ├── DbContext/
275
+ │ │ └── AppDbContext.cs
276
+ │ ├── Repositories/
277
+ │ │ ├── I<Name>Repository.cs
278
+ │ │ └── <Name>Repository.cs
279
+ │ └── Entities/
280
+ │ └── <Name>.cs
281
+ ├── <Scope>.DataAccess.csproj
282
+ └── project.json
283
+ ```
284
+
285
+ #### .NET `feature` (CQRS)
286
+ ```
287
+ libs/<scope>/feature-<name>/
288
+ ├── src/
289
+ │ ├── Commands/
290
+ │ │ ├── Create<Name>/
291
+ │ │ │ ├── Create<Name>Command.cs
292
+ │ │ │ └── Create<Name>Handler.cs
293
+ │ │ └── Update<Name>/
294
+ │ │ ├── Update<Name>Command.cs
295
+ │ │ └── Update<Name>Handler.cs
296
+ │ ├── Queries/
297
+ │ │ └── Get<Name>/
298
+ │ │ ├── Get<Name>Query.cs
299
+ │ │ └── Get<Name>Handler.cs
300
+ │ └── DependencyInjection.cs
301
+ ├── <Scope>.Feature.<Name>.csproj
302
+ └── project.json
303
+ ```
304
+
305
+ #### Python `app` (FastAPI)
306
+ ```
307
+ apps/<name>/
308
+ ├── src/
309
+ │ └── <name>/
310
+ │ ├── __init__.py
311
+ │ ├── main.py
312
+ │ ├── routers/
313
+ │ │ └── <name>_router.py
314
+ │ ├── schemas/
315
+ │ │ └── <name>_schema.py
316
+ │ └── services/
317
+ │ └── <name>_service.py
318
+ ├── tests/
319
+ │ └── test_<name>.py
320
+ ├── pyproject.toml
321
+ └── project.json
322
+ ```
323
+
324
+ #### Python `lib`
325
+ ```
326
+ libs/<scope>/<type>-<name>/
327
+ ├── src/
328
+ │ └── <name>/
329
+ │ ├── __init__.py
330
+ │ └── <name>.py
331
+ ├── tests/
332
+ │ └── test_<name>.py
333
+ ├── pyproject.toml
334
+ └── project.json
335
+ ```
336
+
337
+ ### Step 4: Configure project.json
338
+
339
+ ```json
340
+ {
341
+ "name": "<scope>-<type>-<name>",
342
+ "tags": ["scope:<scope>", "type:<type>", "framework:<framework>"]
343
+ }
344
+ ```
345
+
346
+ ### Step 5: Update Public API (index.ts)
347
+
348
+ Export all public items appropriately for the type.
349
+
350
+ ### Step 6: Verify
351
+
352
+ ```bash
353
+ nx lint <project-name>
354
+ nx test <project-name>
355
+ ```
356
+
357
+ ## Output Summary
358
+
359
+ ```
360
+ ✓ Created library: libs/<scope>/<type>-<name>
361
+
362
+ Import path: @<org>/<scope>/<type>-<name>
363
+ Project name: <scope>-<type>-<name>
364
+ Tags: scope:<scope>, type:<type>, framework:<framework>
365
+
366
+ Files created:
367
+ - libs/<scope>/<type>-<name>/src/index.ts
368
+ - libs/<scope>/<type>-<name>/src/lib/...
369
+ - libs/<scope>/<type>-<name>/project.json
370
+
371
+ Next steps:
372
+ - Add business logic
373
+ - Export public API from index.ts
374
+ - Run: nx test <scope>-<type>-<name>
375
+ ```
@@ -4,33 +4,32 @@
4
4
 
5
5
  ## Stack
6
6
 
7
- - Angular 21+ (latest)
7
+ - Angular 21+ (Zoneless, Signals)
8
8
  - Nx monorepo
9
- - NgRx (store, effects, entity)
10
- - Vitest
9
+ - NgRx (Entity Adapter, Functional Effects)
10
+ - Vitest, Playwright
11
11
  - TypeScript strict mode
12
12
 
13
- ## Architecture - Nx Structure
13
+ ## Architecture - Nx
14
14
 
15
15
  ```
16
- apps/
17
- [app-name]/
16
+ apps/[app-name]/
18
17
 
19
18
  libs/
20
- [domain]/ # Ex: users, products, checkout
21
- feature/ # Smart components, pages, routing (lazy-loaded)
22
- data-access/ # Services API + NgRx state
19
+ [domain]/ # users, products, checkout
20
+ feature/ # Smart components, pages (lazy-loaded)
21
+ data-access/ # NgRx store, API services
23
22
  src/lib/+state/ # Actions, reducers, effects, selectors
24
23
  ui/ # Dumb/presentational components
25
- util/ # Domain-specific helpers
24
+ util/ # Domain helpers
26
25
 
27
26
  shared/
28
- ui/ # Reusable UI components
29
- data-access/ # Shared services (auth, http interceptors)
30
- util/ # Pure functions, helpers
27
+ ui/ # Design system components
28
+ data-access/ # Auth, interceptors
29
+ util/ # Pure functions
31
30
  ```
32
31
 
33
- ### Dependency Rules (enforce via Nx tags)
32
+ ### Dependency Rules (Nx tags)
34
33
 
35
34
  | Type | Can import |
36
35
  |------|------------|
@@ -39,213 +38,22 @@ libs/
39
38
  | `data-access` | `data-access`, `util` only |
40
39
  | `util` | `util` only |
41
40
 
42
- ## Angular 21 - Core Principles
43
-
44
- ### Zoneless by Default
45
-
46
- - No zone.js - use signals for reactivity
47
- - Use `ChangeDetectionStrategy.OnPush` on all components
48
- - Never rely on zone.js for change detection
49
-
50
- ### Signals Everywhere
51
-
52
- ```typescript
53
- // State
54
- count = signal(0);
55
- items = signal<Item[]>([]);
56
-
57
- // Derived state
58
- doubleCount = computed(() => this.count() * 2);
59
- isEmpty = computed(() => this.items().length === 0);
60
-
61
- // Effects for side effects
62
- effect(() => {
63
- console.log('Count changed:', this.count());
64
- });
65
- ```
66
-
67
- ### Signal Forms (experimental but preferred)
68
-
69
- ```typescript
70
- // Use signal forms, NOT reactive forms
71
- import { SignalForm } from '@angular/forms';
72
-
73
- form = signalForm({
74
- name: '',
75
- email: '',
76
- });
77
-
78
- // Access values
79
- form.value(); // { name: '', email: '' }
80
- form.controls.name(); // ''
81
- form.valid(); // boolean signal
82
- ```
83
-
84
- ### Standalone Components (Default)
85
-
86
- - No NgModules for components
87
- - `standalone: true` is the default - don't add it
88
- - Import dependencies directly in component
89
- - Always use separate template files (`.html`)
90
-
91
- ```typescript
92
- @Component({
93
- selector: 'app-example',
94
- imports: [RouterModule],
95
- changeDetection: ChangeDetectionStrategy.OnPush,
96
- templateUrl: './example.component.html',
97
- styleUrl: './example.component.scss',
98
- })
99
- export class ExampleComponent {}
100
- ```
101
-
102
- ### Inject Function
103
-
104
- ```typescript
105
- // Preferred
106
- export class MyComponent {
107
- private readonly store = inject(Store);
108
- private readonly http = inject(HttpClient);
109
- }
110
-
111
- // Avoid constructor injection
112
- ```
113
-
114
- ### Signal Inputs/Outputs (not decorators)
115
-
116
- ```typescript
117
- // Inputs - use input() function, NOT @Input() decorator
118
- name = input<string>(); // Optional
119
- name = input('default'); // With default
120
- name = input.required<string>(); // Required
121
-
122
- // Outputs - use output() function, NOT @Output() decorator
123
- clicked = output<void>();
124
- selected = output<Item>();
125
-
126
- // Two-way binding - use model() function
127
- value = model<string>(''); // Creates input + output pair
128
- value = model.required<string>(); // Required two-way binding
129
- ```
130
-
131
- ## Component Architecture
132
-
133
- ### Smart Components (feature/)
134
-
135
- - Located in `feature/` libs
136
- - Inject store, dispatch actions
137
- - Handle routing logic
138
- - Pass data to UI components via inputs
139
-
140
- ```typescript
141
- // user-list-page.component.ts
142
- @Component({
143
- selector: 'app-user-list-page',
144
- imports: [UserListComponent],
145
- templateUrl: './user-list-page.component.html',
146
- changeDetection: ChangeDetectionStrategy.OnPush,
147
- })
148
- export class UserListPageComponent {
149
- private readonly store = inject(Store);
150
-
151
- users = this.store.selectSignal(selectAllUsers);
152
- loading = this.store.selectSignal(selectUsersLoading);
153
-
154
- onUserSelect(user: User): void {
155
- this.store.dispatch(UserActions.selectUser({ user }));
156
- }
157
- }
158
- ```
159
-
160
- ```html
161
- <!-- user-list-page.component.html -->
162
- <app-user-list
163
- [users]="users()"
164
- [loading]="loading()"
165
- (userSelected)="onUserSelect($event)"
166
- />
167
- ```
168
-
169
- ### UI Components (ui/)
170
-
171
- - Located in `ui/` libs
172
- - NO store injection - never!
173
- - Pure inputs/outputs only
174
- - Fully presentational
175
-
176
- ```typescript
177
- // user-list.component.ts
178
- @Component({
179
- selector: 'app-user-list',
180
- templateUrl: './user-list.component.html',
181
- styleUrl: './user-list.component.scss',
182
- changeDetection: ChangeDetectionStrategy.OnPush,
183
- })
184
- export class UserListComponent {
185
- users = input.required<User[]>();
186
- loading = input(false);
187
- userSelected = output<User>();
188
- }
189
- ```
190
-
191
- ```html
192
- <!-- user-list.component.html -->
193
- @for (user of users(); track user.id) {
194
- <div class="user-item" (click)="userSelected.emit(user)">
195
- {{ user.name }}
196
- </div>
197
- } @empty {
198
- <p>No users found</p>
199
- }
200
- ```
201
-
202
- ## Build & Commands
41
+ ## Commands
203
42
 
204
43
  ```bash
205
- # Development
206
- nx serve [app-name]
207
-
208
- # Build
209
- nx build [app-name]
210
- nx build [app-name] --configuration=production
211
-
212
- # Test
213
- nx test [lib-name] # Single lib
214
- nx run-many -t test # All tests
215
- nx affected -t test # Only affected
216
-
217
- # Lint
218
- nx lint [project-name]
219
- nx run-many -t lint
220
-
221
- # Generate
44
+ nx serve [app] # Dev server
45
+ nx build [app] --configuration=production
46
+ nx test [lib] # Unit tests
47
+ nx affected -t test # Test affected
48
+ nx e2e [app]-e2e # E2E tests
222
49
  nx g @nx/angular:component [name] --project=[lib]
223
50
  nx g @nx/angular:library [name] --directory=libs/[domain]
224
51
  ```
225
52
 
226
53
  ## Code Style
227
54
 
228
- - Prefix: configurable per project (default: `app`)
229
- - File structure: folder-based (`user-list/user-list.component.ts`)
230
- - Always explicit return types on public methods
231
- - Use `readonly` for injected services
232
- - Use `track` in `@for` loops
233
-
234
- ## RxJS Guidelines
235
-
236
- - Prefer signals over observables when possible
237
- - Use `toSignal()` to convert observables
238
- - Clean subscriptions with `takeUntilDestroyed()`
239
- - Avoid nested subscribes - use operators
240
-
241
- ```typescript
242
- // Convert observable to signal
243
- data = toSignal(this.http.get<Data[]>('/api/data'), { initialValue: [] });
244
-
245
- // If you must use observables
246
- private readonly destroyRef = inject(DestroyRef);
247
-
248
- this.source$.pipe(
249
- takeUntilDestroyed(this.destroyRef)
250
- ).subscribe();
251
- ```
55
+ - Folder-based structure: `user-list/user-list.component.ts`
56
+ - Explicit return types on public methods
57
+ - `readonly` for injected services
58
+ - `track` required in `@for` loops
59
+ - Prefix configurable per project (default: `app`)