@el-j/magic-helix-plugins 4.0.0-beta.1 → 4.0.0-beta.3

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 (120) hide show
  1. package/dist/architecture/codeowners.md +123 -0
  2. package/dist/architecture/monorepo.md +146 -0
  3. package/dist/architecture/nx.md +122 -0
  4. package/dist/architecture/turborepo.md +114 -0
  5. package/dist/ci/github-actions.md +268 -0
  6. package/dist/ci/gitlab-ci.md +330 -0
  7. package/dist/containers/docker-multistage.md +120 -0
  8. package/dist/containers/kubernetes-deploy.md +210 -0
  9. package/dist/cpp/index.cjs +79 -0
  10. package/dist/cpp/index.mjs +209 -0
  11. package/dist/csharp/index.cjs +2 -2
  12. package/dist/csharp/{index.js → index.mjs} +17 -11
  13. package/dist/csharp/templates/framework-aspnetcore.md +205 -0
  14. package/dist/csharp/templates/framework-blazor.md +271 -0
  15. package/dist/csharp/templates/lang-csharp.md +162 -0
  16. package/dist/devops/docker-compose.md +111 -0
  17. package/dist/devops/docker-dockerfile.md +94 -0
  18. package/dist/devops/github-actions.md +160 -0
  19. package/dist/devops/gitlab-ci.md +210 -0
  20. package/dist/generic/lang-typescript.md +57 -0
  21. package/dist/generic/state-redux.md +21 -0
  22. package/dist/generic/state-rxjs.md +6 -0
  23. package/dist/generic/style-mui.md +23 -0
  24. package/dist/generic/style-tailwind.md +76 -0
  25. package/dist/generic/test-cypress.md +21 -0
  26. package/dist/generic/test-jest.md +20 -0
  27. package/dist/generic/test-playwright.md +21 -0
  28. package/dist/generic/test-vitest.md +131 -0
  29. package/dist/go/index.cjs +3 -3
  30. package/dist/go/{index.js → index.mjs} +18 -15
  31. package/dist/go/templates/lang-go.md +571 -0
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.mjs +24 -0
  34. package/dist/java/index.cjs +2 -2
  35. package/dist/java/{index.js → index.mjs} +25 -19
  36. package/dist/java/templates/build-gradle.md +102 -0
  37. package/dist/java/templates/build-maven.md +86 -0
  38. package/dist/java/templates/framework-spring-boot.md +179 -0
  39. package/dist/java/templates/lang-java.md +78 -0
  40. package/dist/java/templates/lang-kotlin.md +88 -0
  41. package/dist/meta/magic-helix-meta.md +213 -0
  42. package/dist/meta/meta-debug.md +459 -0
  43. package/dist/meta/meta-implement.md +450 -0
  44. package/dist/meta/meta-roadmap.md +265 -0
  45. package/dist/nodejs/templates/angular-core.md +19 -0
  46. package/dist/nodejs/templates/lang-typescript.md +57 -0
  47. package/dist/nodejs/templates/nestjs-core.md +7 -0
  48. package/dist/nodejs/templates/react-core.md +677 -0
  49. package/dist/nodejs/templates/react-zustand.md +7 -0
  50. package/dist/nodejs/templates/state-redux.md +21 -0
  51. package/dist/nodejs/templates/state-rxjs.md +6 -0
  52. package/dist/nodejs/templates/style-primevue.md +6 -0
  53. package/dist/nodejs/templates/style-quasar.md +22 -0
  54. package/dist/nodejs/templates/style-tailwind.md +76 -0
  55. package/dist/nodejs/templates/test-cypress.md +21 -0
  56. package/dist/nodejs/templates/test-jest.md +20 -0
  57. package/dist/nodejs/templates/test-playwright.md +21 -0
  58. package/dist/nodejs/templates/test-vitest.md +131 -0
  59. package/dist/nodejs/templates/vue-core.md +108 -0
  60. package/dist/nodejs/templates/vue-pinia.md +5 -0
  61. package/dist/patterns/architecture/clean-architecture.md +469 -0
  62. package/dist/patterns/architecture/dependency-injection.md +517 -0
  63. package/dist/patterns/architecture/domain-driven-design.md +621 -0
  64. package/dist/patterns/architecture/layered-architecture.md +382 -0
  65. package/dist/patterns/architecture/repository-pattern.md +408 -0
  66. package/dist/patterns/domain-expertise/nextjs-rules.md +115 -0
  67. package/dist/patterns/domain-expertise/react-patterns.md +181 -0
  68. package/dist/patterns/domain-expertise/server-components.md +212 -0
  69. package/dist/patterns/domain-expertise/shadcn-ui.md +52 -0
  70. package/dist/patterns/domain-expertise/tailwind-patterns.md +52 -0
  71. package/dist/patterns/environment/container-awareness.md +17 -0
  72. package/dist/patterns/environment/ide-features.md +17 -0
  73. package/dist/patterns/environment/os-commands.md +17 -0
  74. package/dist/patterns/organization/heading-hierarchy.md +103 -0
  75. package/dist/patterns/organization/sequential-workflows.md +102 -0
  76. package/dist/patterns/organization/xml-rule-groups.md +64 -0
  77. package/dist/patterns/reasoning/agent-loop.md +151 -0
  78. package/dist/patterns/reasoning/confirmation-gates.md +141 -0
  79. package/dist/patterns/reasoning/dependency-analysis.md +132 -0
  80. package/dist/patterns/reasoning/one-tool-per-iteration.md +152 -0
  81. package/dist/patterns/reasoning/preview-before-action.md +194 -0
  82. package/dist/patterns/reasoning/reflection-checkpoints.md +166 -0
  83. package/dist/patterns/reasoning/result-verification.md +157 -0
  84. package/dist/patterns/reasoning/subtask-breakdown.md +131 -0
  85. package/dist/patterns/reasoning/thinking-tags.md +100 -0
  86. package/dist/patterns/role-definition/capability-declarations.md +72 -0
  87. package/dist/patterns/role-definition/expert-identity.md +45 -0
  88. package/dist/patterns/role-definition/scope-boundaries.md +61 -0
  89. package/dist/patterns/safety/code-safety-rules.md +17 -0
  90. package/dist/patterns/safety/credential-handling.md +17 -0
  91. package/dist/patterns/safety/destructive-warnings.md +17 -0
  92. package/dist/patterns/safety/refusal-messages.md +17 -0
  93. package/dist/patterns/tone/adaptive-tone.md +17 -0
  94. package/dist/patterns/tone/concise-communication.md +17 -0
  95. package/dist/patterns/tone/forbidden-phrases.md +17 -0
  96. package/dist/patterns/tool-guidelines/function-schemas.md +143 -0
  97. package/dist/patterns/tool-guidelines/parameter-examples.md +137 -0
  98. package/dist/patterns/tool-guidelines/usage-policies.md +105 -0
  99. package/dist/php/index.cjs +2 -2
  100. package/dist/php/{index.js → index.mjs} +12 -6
  101. package/dist/php/templates/framework-laravel.md +112 -0
  102. package/dist/php/templates/lang-php.md +94 -0
  103. package/dist/python/index.cjs +4 -4
  104. package/dist/python/{index.js → index.mjs} +10 -7
  105. package/dist/python/templates/lang-python.md +508 -0
  106. package/dist/ruby/index.cjs +2 -2
  107. package/dist/ruby/{index.js → index.mjs} +16 -10
  108. package/dist/ruby/templates/framework-rails.md +309 -0
  109. package/dist/ruby/templates/framework-sinatra.md +227 -0
  110. package/dist/ruby/templates/lang-ruby.md +216 -0
  111. package/dist/rust/index.cjs +3 -3
  112. package/dist/rust/{index.js → index.mjs} +24 -18
  113. package/dist/rust/templates/lang-rust.md +89 -0
  114. package/dist/swift/index.cjs +32 -0
  115. package/dist/swift/index.mjs +112 -0
  116. package/dist/swift/templates/framework-vapor.md +352 -0
  117. package/dist/swift/templates/lang-swift.md +291 -0
  118. package/package.json +31 -21
  119. package/dist/index.js +0 -20
  120. /package/dist/nodejs/{index.js → index.mjs} +0 -0
@@ -0,0 +1,382 @@
1
+ # Layered Architecture Pattern
2
+
3
+ ## Purpose
4
+ Organize code into horizontal layers with clear responsibilities. Common in MVC and enterprise applications.
5
+
6
+ ## Layer Structure
7
+
8
+ ```
9
+ ┌─────────────────────────────────┐
10
+ │ Presentation Layer (UI/API) │ ← User interaction, HTTP/GraphQL
11
+ ├─────────────────────────────────┤
12
+ │ Application/Service Layer │ ← Business logic orchestration
13
+ ├─────────────────────────────────┤
14
+ │ Domain/Business Layer │ ← Core business rules
15
+ ├─────────────────────────────────┤
16
+ │ Data Access Layer (DAL) │ ← Database, external APIs
17
+ └─────────────────────────────────┘
18
+ ```
19
+
20
+ ## Layer Responsibilities
21
+
22
+ ### 1. Presentation Layer (Controllers, Views, Components)
23
+ **Handle user input, render UI, expose APIs.**
24
+
25
+ ```typescript
26
+ // ✅ Controller handles HTTP, delegates to service
27
+ @Controller('/api/products')
28
+ export class ProductController {
29
+ constructor(private productService: ProductService) {}
30
+
31
+ @Get()
32
+ async getAll(@Query() filters: ProductFilters): Promise<ProductDTO[]> {
33
+ const products = await this.productService.findAll(filters);
34
+ return products.map(p => this.toDTO(p));
35
+ }
36
+
37
+ @Post()
38
+ async create(@Body() dto: CreateProductDTO): Promise<ProductDTO> {
39
+ const product = await this.productService.create(dto);
40
+ return this.toDTO(product);
41
+ }
42
+
43
+ private toDTO(product: Product): ProductDTO {
44
+ return {
45
+ id: product.id,
46
+ name: product.name,
47
+ price: product.price.amount,
48
+ currency: product.price.currency,
49
+ };
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### 2. Service Layer (Business Logic)
55
+ **Orchestrate business operations, coordinate between domain and data layers.**
56
+
57
+ ```typescript
58
+ // ✅ Service contains business logic, uses repositories
59
+ export class ProductService {
60
+ constructor(
61
+ private productRepository: ProductRepository,
62
+ private inventoryService: InventoryService,
63
+ private eventBus: EventBus
64
+ ) {}
65
+
66
+ async create(dto: CreateProductDTO): Promise<Product> {
67
+ // Business validation
68
+ if (dto.price <= 0) {
69
+ throw new BusinessError('Price must be positive');
70
+ }
71
+
72
+ // Create domain object
73
+ const product = new Product(
74
+ generateId(),
75
+ dto.name,
76
+ new Money(dto.price, dto.currency)
77
+ );
78
+
79
+ // Persist
80
+ await this.productRepository.save(product);
81
+
82
+ // Business side effects
83
+ await this.inventoryService.initializeStock(product.id, dto.initialStock);
84
+ await this.eventBus.publish(new ProductCreatedEvent(product));
85
+
86
+ return product;
87
+ }
88
+
89
+ async findAll(filters: ProductFilters): Promise<Product[]> {
90
+ // Business logic for filtering
91
+ const products = await this.productRepository.findMany(filters);
92
+
93
+ // Business rule: filter out discontinued products unless explicitly requested
94
+ if (!filters.includeDiscontinued) {
95
+ return products.filter(p => !p.isDiscontinued);
96
+ }
97
+
98
+ return products;
99
+ }
100
+
101
+ async updatePrice(id: string, newPrice: Money): Promise<Product> {
102
+ const product = await this.productRepository.findById(id);
103
+ if (!product) {
104
+ throw new NotFoundError('Product not found');
105
+ }
106
+
107
+ // Business rule: price change audit
108
+ if (product.price.amount !== newPrice.amount) {
109
+ await this.auditLog.recordPriceChange(id, product.price, newPrice);
110
+ }
111
+
112
+ product.updatePrice(newPrice);
113
+ await this.productRepository.save(product);
114
+
115
+ return product;
116
+ }
117
+ }
118
+ ```
119
+
120
+ ### 3. Domain Layer (Business Models)
121
+ **Core business entities and rules. Framework-independent.**
122
+
123
+ ```typescript
124
+ // ✅ Domain model with business rules
125
+ export class Product {
126
+ constructor(
127
+ public readonly id: string,
128
+ private _name: string,
129
+ private _price: Money,
130
+ private _isDiscontinued: boolean = false
131
+ ) {}
132
+
133
+ get name(): string {
134
+ return this._name;
135
+ }
136
+
137
+ get price(): Money {
138
+ return this._price;
139
+ }
140
+
141
+ get isDiscontinued(): boolean {
142
+ return this._isDiscontinued;
143
+ }
144
+
145
+ updatePrice(newPrice: Money): void {
146
+ // Business rule: validate price
147
+ if (newPrice.amount <= 0) {
148
+ throw new Error('Price must be positive');
149
+ }
150
+
151
+ // Business rule: prevent large price changes
152
+ const changePercent = Math.abs(
153
+ (newPrice.amount - this._price.amount) / this._price.amount
154
+ );
155
+ if (changePercent > 0.5) {
156
+ throw new Error('Price change exceeds 50% threshold');
157
+ }
158
+
159
+ this._price = newPrice;
160
+ }
161
+
162
+ discontinue(): void {
163
+ // Business rule: cannot discontinue if already discontinued
164
+ if (this._isDiscontinued) {
165
+ throw new Error('Product already discontinued');
166
+ }
167
+ this._isDiscontinued = true;
168
+ }
169
+
170
+ rename(newName: string): void {
171
+ // Business rule: validate name
172
+ if (newName.trim().length < 3) {
173
+ throw new Error('Name must be at least 3 characters');
174
+ }
175
+ this._name = newName;
176
+ }
177
+ }
178
+
179
+ // ✅ Value object
180
+ export class Money {
181
+ constructor(
182
+ public readonly amount: number,
183
+ public readonly currency: string
184
+ ) {
185
+ if (amount < 0) {
186
+ throw new Error('Amount cannot be negative');
187
+ }
188
+ }
189
+
190
+ add(other: Money): Money {
191
+ if (this.currency !== other.currency) {
192
+ throw new Error('Cannot add different currencies');
193
+ }
194
+ return new Money(this.amount + other.amount, this.currency);
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### 4. Data Access Layer (Repositories)
200
+ **Database operations, external API calls, caching.**
201
+
202
+ ```typescript
203
+ // ✅ Repository handles data persistence
204
+ export class ProductRepository {
205
+ constructor(private db: Database) {}
206
+
207
+ async save(product: Product): Promise<void> {
208
+ await this.db.query(
209
+ `INSERT INTO products (id, name, price_amount, price_currency, is_discontinued)
210
+ VALUES ($1, $2, $3, $4, $5)
211
+ ON CONFLICT (id) DO UPDATE SET
212
+ name = $2,
213
+ price_amount = $3,
214
+ price_currency = $4,
215
+ is_discontinued = $5`,
216
+ [product.id, product.name, product.price.amount, product.price.currency, product.isDiscontinued]
217
+ );
218
+ }
219
+
220
+ async findById(id: string): Promise<Product | null> {
221
+ const row = await this.db.queryOne(
222
+ 'SELECT * FROM products WHERE id = $1',
223
+ [id]
224
+ );
225
+
226
+ if (!row) return null;
227
+
228
+ return this.toDomain(row);
229
+ }
230
+
231
+ async findMany(filters: ProductFilters): Promise<Product[]> {
232
+ const query = this.buildFilterQuery(filters);
233
+ const rows = await this.db.query(query.sql, query.params);
234
+ return rows.map(row => this.toDomain(row));
235
+ }
236
+
237
+ private toDomain(row: any): Product {
238
+ return new Product(
239
+ row.id,
240
+ row.name,
241
+ new Money(row.price_amount, row.price_currency),
242
+ row.is_discontinued
243
+ );
244
+ }
245
+
246
+ private buildFilterQuery(filters: ProductFilters): { sql: string; params: any[] } {
247
+ // Build dynamic SQL based on filters
248
+ // ...
249
+ }
250
+ }
251
+ ```
252
+
253
+ ## File Organization
254
+
255
+ ### Backend (Node.js/Express/NestJS)
256
+ ```
257
+ src/
258
+ ├── presentation/ # Controllers, DTOs, validators
259
+ │ ├── controllers/
260
+ │ │ ├── ProductController.ts
261
+ │ │ └── OrderController.ts
262
+ │ ├── dto/
263
+ │ │ ├── CreateProductDTO.ts
264
+ │ │ └── ProductDTO.ts
265
+ │ └── validators/
266
+ │ └── ProductValidator.ts
267
+
268
+ ├── application/ # Services, use cases
269
+ │ ├── services/
270
+ │ │ ├── ProductService.ts
271
+ │ │ └── OrderService.ts
272
+ │ └── interfaces/
273
+ │ └── IProductRepository.ts
274
+
275
+ ├── domain/ # Business models, value objects
276
+ │ ├── models/
277
+ │ │ ├── Product.ts
278
+ │ │ └── Order.ts
279
+ │ └── value-objects/
280
+ │ └── Money.ts
281
+
282
+ └── infrastructure/ # Repositories, database, external APIs
283
+ ├── repositories/
284
+ │ ├── ProductRepository.ts
285
+ │ └── OrderRepository.ts
286
+ ├── database/
287
+ │ └── connection.ts
288
+ └── external/
289
+ └── PaymentGateway.ts
290
+ ```
291
+
292
+ ### Frontend (React/Vue)
293
+ ```
294
+ src/
295
+ ├── presentation/ # Components (UI only)
296
+ │ ├── components/
297
+ │ │ ├── ProductCard.tsx
298
+ │ │ └── ProductList.tsx
299
+ │ └── pages/
300
+ │ └── ProductsPage.tsx
301
+
302
+ ├── application/ # Hooks/Composables (business logic)
303
+ │ ├── hooks/ # React
304
+ │ │ ├── useProducts.ts
305
+ │ │ └── useCart.ts
306
+ │ └── composables/ # Vue
307
+ │ ├── useProducts.ts
308
+ │ └── useCart.ts
309
+
310
+ ├── domain/ # Business models (client-side)
311
+ │ ├── models/
312
+ │ │ ├── Product.ts
313
+ │ │ └── Cart.ts
314
+ │ └── value-objects/
315
+ │ └── CartItem.ts
316
+
317
+ └── infrastructure/ # API clients, storage
318
+ ├── api/
319
+ │ └── ProductApiClient.ts
320
+ └── storage/
321
+ └── LocalStorageCart.ts
322
+ ```
323
+
324
+ ## Testing Strategy
325
+
326
+ ```typescript
327
+ // ✅ Test presentation layer (mock service)
328
+ describe('ProductController', () => {
329
+ it('returns all products', async () => {
330
+ const mockService = { findAll: jest.fn().mockResolvedValue([]) };
331
+ const controller = new ProductController(mockService);
332
+ const result = await controller.getAll({});
333
+ expect(result).toEqual([]);
334
+ });
335
+ });
336
+
337
+ // ✅ Test service layer (mock repository)
338
+ describe('ProductService', () => {
339
+ it('creates product and triggers events', async () => {
340
+ const mockRepo = { save: jest.fn() };
341
+ const mockEvents = { publish: jest.fn() };
342
+ const service = new ProductService(mockRepo, mockEvents);
343
+
344
+ await service.create({ name: 'Test', price: 100 });
345
+
346
+ expect(mockRepo.save).toHaveBeenCalled();
347
+ expect(mockEvents.publish).toHaveBeenCalled();
348
+ });
349
+ });
350
+
351
+ // ✅ Test domain layer (no mocks - pure logic)
352
+ describe('Product', () => {
353
+ it('prevents negative prices', () => {
354
+ const product = new Product('1', 'Test', new Money(100, 'USD'));
355
+ expect(() => product.updatePrice(new Money(-10, 'USD'))).toThrow();
356
+ });
357
+ });
358
+
359
+ // ✅ Test data layer (integration test with real DB)
360
+ describe('ProductRepository', () => {
361
+ it('persists and retrieves product', async () => {
362
+ const repo = new ProductRepository(testDb);
363
+ const product = new Product('1', 'Test', new Money(100, 'USD'));
364
+
365
+ await repo.save(product);
366
+ const retrieved = await repo.findById('1');
367
+
368
+ expect(retrieved?.name).toBe('Test');
369
+ });
370
+ });
371
+ ```
372
+
373
+ ## Rules Summary
374
+
375
+ - **ALWAYS** keep presentation logic separate from business logic
376
+ - **ALWAYS** put business rules in service or domain layer, not controllers
377
+ - **ALWAYS** make repositories responsible for data access only
378
+ - **ALWAYS** use DTOs to decouple API contracts from domain models
379
+ - **NEVER** access database directly from controllers
380
+ - **NEVER** put business logic in repositories
381
+ - **PREFER** thin controllers, fat services
382
+ - **PREFER** dependency injection for testability