@mytechtoday/augment-extensions 1.3.0 → 1.3.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.
Files changed (95) hide show
  1. package/LICENSE +22 -22
  2. package/augment-extensions/domain-rules/software-architecture/README.md +143 -143
  3. package/augment-extensions/domain-rules/software-architecture/examples/banking-layered.md +961 -961
  4. package/augment-extensions/domain-rules/software-architecture/examples/ecommerce-microservices.md +990 -990
  5. package/augment-extensions/domain-rules/software-architecture/examples/iot-eventdriven.md +882 -882
  6. package/augment-extensions/domain-rules/software-architecture/examples/monolith-to-microservices-migration.md +703 -703
  7. package/augment-extensions/domain-rules/software-architecture/examples/serverless-imageprocessing.md +957 -957
  8. package/augment-extensions/domain-rules/software-architecture/examples/trading-eventdriven.md +747 -747
  9. package/augment-extensions/domain-rules/software-architecture/module.json +119 -119
  10. package/augment-extensions/domain-rules/software-architecture/rules/challenges-solutions.md +763 -763
  11. package/augment-extensions/domain-rules/software-architecture/rules/definitions-terminology.md +409 -409
  12. package/augment-extensions/domain-rules/software-architecture/rules/design-principles.md +684 -684
  13. package/augment-extensions/domain-rules/software-architecture/rules/evaluation-testing.md +1381 -1381
  14. package/augment-extensions/domain-rules/software-architecture/rules/event-driven-architecture.md +616 -616
  15. package/augment-extensions/domain-rules/software-architecture/rules/fundamentals.md +306 -306
  16. package/augment-extensions/domain-rules/software-architecture/rules/industry-architectures.md +554 -554
  17. package/augment-extensions/domain-rules/software-architecture/rules/layered-architecture.md +776 -776
  18. package/augment-extensions/domain-rules/software-architecture/rules/microservices-architecture.md +503 -503
  19. package/augment-extensions/domain-rules/software-architecture/rules/modeling-documentation.md +1199 -1199
  20. package/augment-extensions/domain-rules/software-architecture/rules/monolithic-architecture.md +351 -351
  21. package/augment-extensions/domain-rules/software-architecture/rules/principles.md +556 -556
  22. package/augment-extensions/domain-rules/software-architecture/rules/quality-attributes.md +797 -797
  23. package/augment-extensions/domain-rules/software-architecture/rules/scalability-performance.md +1345 -1345
  24. package/augment-extensions/domain-rules/software-architecture/rules/security-architecture.md +1039 -1039
  25. package/augment-extensions/domain-rules/software-architecture/rules/serverless-architecture.md +711 -711
  26. package/augment-extensions/domain-rules/software-architecture/rules/skills-development.md +568 -568
  27. package/augment-extensions/domain-rules/software-architecture/rules/tools-methodologies.md +961 -961
  28. package/augment-extensions/visual-design/CHANGELOG.md +132 -132
  29. package/augment-extensions/visual-design/README.md +255 -255
  30. package/augment-extensions/visual-design/__tests__/README.md +119 -119
  31. package/augment-extensions/visual-design/__tests__/style-selector.test.ts +172 -172
  32. package/augment-extensions/visual-design/__tests__/vendor-styles.test.ts +214 -214
  33. package/augment-extensions/visual-design/domains/other/ai-prompt-helper.ts +157 -157
  34. package/augment-extensions/visual-design/domains/other/dotnet-application.ts +156 -156
  35. package/augment-extensions/visual-design/domains/other/linux-platform.ts +156 -156
  36. package/augment-extensions/visual-design/domains/other/mobile-application.ts +157 -157
  37. package/augment-extensions/visual-design/domains/other/motion-picture.ts +156 -156
  38. package/augment-extensions/visual-design/domains/other/os-application.ts +156 -156
  39. package/augment-extensions/visual-design/domains/other/print-campaigns.ts +158 -158
  40. package/augment-extensions/visual-design/domains/other/web-app.ts +157 -157
  41. package/augment-extensions/visual-design/domains/other/website.ts +161 -161
  42. package/augment-extensions/visual-design/domains/other/windows-platform.ts +156 -156
  43. package/augment-extensions/visual-design/domains/web-page-styles/amazon-cloudscape.ts +506 -506
  44. package/augment-extensions/visual-design/domains/web-page-styles/google-modern.ts +615 -615
  45. package/augment-extensions/visual-design/domains/web-page-styles/microsoft-fluent.ts +531 -531
  46. package/augment-extensions/visual-design/examples/README.md +97 -97
  47. package/augment-extensions/visual-design/examples/ai-prompt-generation.md +233 -233
  48. package/augment-extensions/visual-design/examples/basic-usage.md +216 -216
  49. package/augment-extensions/visual-design/examples/domain-workflows.md +257 -257
  50. package/augment-extensions/visual-design/examples/vendor-comparison.md +247 -247
  51. package/augment-extensions/visual-design/module.json +78 -78
  52. package/augment-extensions/visual-design/style-selector.ts +177 -177
  53. package/augment-extensions/visual-design/types.ts +302 -302
  54. package/augment-extensions/visual-design/visual-design-core.ts +469 -469
  55. package/augment-extensions/workflows/adr-support/README.md +227 -227
  56. package/augment-extensions/workflows/adr-support/__tests__/adr-validator.test.ts +203 -203
  57. package/augment-extensions/workflows/adr-support/adr-validator.ts +162 -162
  58. package/augment-extensions/workflows/adr-support/examples/complete-lifecycle-example.md +449 -449
  59. package/augment-extensions/workflows/adr-support/examples/integration-example.md +580 -580
  60. package/augment-extensions/workflows/adr-support/examples/superseding-example.md +436 -436
  61. package/augment-extensions/workflows/adr-support/module.json +112 -112
  62. package/augment-extensions/workflows/adr-support/rules/adr-creation.md +372 -372
  63. package/augment-extensions/workflows/adr-support/rules/beads-integration.md +443 -443
  64. package/augment-extensions/workflows/adr-support/rules/conflict-detection.md +486 -486
  65. package/augment-extensions/workflows/adr-support/rules/decision-detection.md +362 -362
  66. package/augment-extensions/workflows/adr-support/rules/lifecycle-management.md +427 -427
  67. package/augment-extensions/workflows/adr-support/rules/openspec-integration.md +465 -465
  68. package/augment-extensions/workflows/adr-support/rules/template-selection.md +405 -405
  69. package/augment-extensions/workflows/adr-support/rules/validation-rules.md +543 -543
  70. package/augment-extensions/workflows/adr-support/schemas/adr-config.json +191 -191
  71. package/augment-extensions/workflows/adr-support/schemas/adr-metadata.json +172 -172
  72. package/augment-extensions/workflows/adr-support/templates/business-case.md +235 -235
  73. package/augment-extensions/workflows/adr-support/templates/madr-elaborate.md +197 -197
  74. package/augment-extensions/workflows/adr-support/templates/madr-simple.md +68 -68
  75. package/augment-extensions/workflows/adr-support/templates/nygard.md +84 -84
  76. package/augment-extensions/writing-standards/screenplay/rules/file-organization.md +213 -213
  77. package/augment-extensions/writing-standards/screenplay/utils/__tests__/file-organization.test.ts +169 -169
  78. package/augment-extensions/writing-standards/screenplay/utils/file-organization.ts +165 -165
  79. package/cli/dist/utils/auto-sync.js +19 -19
  80. package/package.json +5 -3
  81. package/augment-extensions/workflows/openspec/README.md +0 -96
  82. package/augment-extensions/workflows/openspec/examples/complete-change-example.md +0 -244
  83. package/augment-extensions/workflows/openspec/module.json +0 -54
  84. package/augment-extensions/workflows/openspec/rules/best-practices.md +0 -272
  85. package/augment-extensions/workflows/openspec/rules/manual-setup.md +0 -231
  86. package/augment-extensions/workflows/openspec/rules/spec-format.md +0 -236
  87. package/augment-extensions/workflows/openspec/rules/workflow.md +0 -214
  88. package/cli/dist/utils/__tests__/adr-validator.example.d.ts +0 -6
  89. package/cli/dist/utils/__tests__/adr-validator.example.d.ts.map +0 -1
  90. package/cli/dist/utils/__tests__/adr-validator.example.js +0 -148
  91. package/cli/dist/utils/__tests__/adr-validator.example.js.map +0 -1
  92. package/cli/dist/utils/adr-validator.d.ts +0 -65
  93. package/cli/dist/utils/adr-validator.d.ts.map +0 -1
  94. package/cli/dist/utils/adr-validator.js +0 -203
  95. package/cli/dist/utils/adr-validator.js.map +0 -1
@@ -1,990 +1,990 @@
1
- # E-Commerce Platform Architecture Example
2
-
3
- ## Overview
4
-
5
- This document provides a comprehensive example of an e-commerce platform built with microservices architecture, focusing on high availability, scalability, and resilience.
6
-
7
- ---
8
-
9
- ## System Context
10
-
11
- ### Business Requirements
12
-
13
- **Functional Requirements**
14
- - Product catalog with search and filtering
15
- - Shopping cart and checkout
16
- - Order processing and tracking
17
- - Payment processing
18
- - User authentication and profiles
19
- - Inventory management
20
- - Shipping and fulfillment
21
- - Customer reviews and ratings
22
-
23
- **Non-Functional Requirements**
24
- - **Availability**: 99.99% uptime (52 minutes downtime/year)
25
- - **Scalability**: Handle 10,000 concurrent users, 1M products
26
- - **Performance**: Page load < 2s, API response < 200ms
27
- - **Security**: PCI DSS compliance for payments
28
- - **Reliability**: Zero data loss, eventual consistency acceptable
29
-
30
- ### Scale Metrics
31
- - 1 million registered users
32
- - 100,000 daily active users
33
- - 10,000 orders per day
34
- - 1 million products in catalog
35
- - Peak traffic: Black Friday (10x normal load)
36
-
37
- ---
38
-
39
- ## Architecture Overview
40
-
41
- ### Microservices Decomposition
42
-
43
- **Service Boundaries (Domain-Driven Design)**
44
-
45
- ```
46
- ┌─────────────────────────────────────────────────────────────┐
47
- │ API Gateway (Kong) │
48
- │ Authentication, Rate Limiting, Routing │
49
- └─────────────────────────────────────────────────────────────┘
50
-
51
- ┌─────────────────────┼─────────────────────┐
52
- │ │ │
53
- ┌───────▼────────┐ ┌────────▼────────┐ ┌───────▼────────┐
54
- │ User Service │ │ Product Service │ │ Order Service │
55
- │ (Auth, Profile)│ │ (Catalog, Search│ │ (Checkout, │
56
- │ │ │ Inventory) │ │ Fulfillment) │
57
- └────────────────┘ └─────────────────┘ └────────────────┘
58
- │ │ │
59
- │ ┌────────▼────────┐ │
60
- │ │ Search Service │ │
61
- │ │ (Elasticsearch) │ │
62
- │ └─────────────────┘ │
63
- │ │
64
- ┌───────▼────────┐ ┌─────────────────┐ ┌───────▼────────┐
65
- │ Payment Service│ │ Review Service │ │ Shipping Svc │
66
- │ (Stripe, PayPal│ │ (Ratings, UGC) │ │ (Tracking, │
67
- │ PCI Compliant)│ │ │ │ Carriers) │
68
- └────────────────┘ └─────────────────┘ └────────────────┘
69
- │ │ │
70
- └─────────────────────┼─────────────────────┘
71
-
72
- ┌─────────▼─────────┐
73
- │ Event Bus (Kafka) │
74
- │ (Event Sourcing) │
75
- └────────────────────┘
76
- ```
77
-
78
- ### Service Responsibilities
79
-
80
- **1. User Service**
81
- - User registration and authentication (JWT)
82
- - Profile management
83
- - Address book
84
- - Preferences and settings
85
- - OAuth integration (Google, Facebook)
86
-
87
- **2. Product Service**
88
- - Product catalog CRUD
89
- - Category management
90
- - Product attributes and variants
91
- - Inventory tracking
92
- - Price management
93
-
94
- **3. Search Service**
95
- - Full-text search (Elasticsearch)
96
- - Faceted search and filtering
97
- - Search suggestions and autocomplete
98
- - Personalized search results
99
- - Search analytics
100
-
101
- **4. Order Service**
102
- - Shopping cart management
103
- - Order creation and processing
104
- - Order history and tracking
105
- - Order status updates
106
- - Saga orchestration for distributed transactions
107
-
108
- **5. Payment Service**
109
- - Payment processing (Stripe, PayPal)
110
- - PCI DSS compliance
111
- - Payment method management
112
- - Refund processing
113
- - Fraud detection integration
114
-
115
- **6. Review Service**
116
- - Product reviews and ratings
117
- - Review moderation
118
- - Helpful votes
119
- - Review analytics
120
-
121
- **7. Shipping Service**
122
- - Shipping rate calculation
123
- - Carrier integration (FedEx, UPS, USPS)
124
- - Shipment tracking
125
- - Delivery notifications
126
-
127
- ---
128
-
129
- ## Technology Stack
130
-
131
- ### Services
132
- - **Language**: Node.js (TypeScript) for most services
133
- - **Framework**: Express.js, NestJS
134
- - **API**: REST + GraphQL (BFF pattern)
135
-
136
- ### Data Storage
137
- - **User Service**: PostgreSQL (relational, ACID)
138
- - **Product Service**: PostgreSQL + Redis (caching)
139
- - **Search Service**: Elasticsearch
140
- - **Order Service**: PostgreSQL + Event Store
141
- - **Review Service**: MongoDB (document-based)
142
- - **Session Store**: Redis
143
-
144
- ### Infrastructure
145
- - **Container Orchestration**: Kubernetes (EKS)
146
- - **Service Mesh**: Istio (traffic management, security)
147
- - **API Gateway**: Kong
148
- - **Message Broker**: Apache Kafka
149
- - **Cache**: Redis Cluster
150
- - **CDN**: CloudFront
151
- - **Load Balancer**: AWS ALB
152
-
153
- ### Observability
154
- - **Monitoring**: Prometheus + Grafana
155
- - **Logging**: ELK Stack (Elasticsearch, Logstash, Kibana)
156
- - **Tracing**: Jaeger (distributed tracing)
157
- - **Alerting**: PagerDuty
158
-
159
- ### CI/CD
160
- - **Version Control**: GitHub
161
- - **CI/CD**: GitHub Actions + ArgoCD
162
- - **Container Registry**: ECR
163
- - **Infrastructure as Code**: Terraform
164
-
165
- ---
166
-
167
- ## Implementation Details
168
-
169
- ### 1. Product Service Implementation
170
-
171
- **Service Structure**
172
-
173
- ```typescript
174
- // src/product-service/domain/product.entity.ts
175
- export class Product {
176
- id: string;
177
- name: string;
178
- description: string;
179
- price: number;
180
- categoryId: string;
181
- inventory: number;
182
- images: string[];
183
- attributes: Record<string, any>;
184
- createdAt: Date;
185
- updatedAt: Date;
186
- }
187
-
188
- // src/product-service/application/product.service.ts
189
- export class ProductService {
190
- constructor(
191
- private readonly productRepo: ProductRepository,
192
- private readonly cache: CacheService,
193
- private readonly eventBus: EventBus
194
- ) {}
195
-
196
- async getProduct(productId: string): Promise<Product> {
197
- // Check cache first
198
- const cached = await this.cache.get(`product:${productId}`);
199
- if (cached) return cached;
200
-
201
- // Fetch from database
202
- const product = await this.productRepo.findById(productId);
203
- if (!product) throw new NotFoundException('Product not found');
204
-
205
- // Cache for 1 hour
206
- await this.cache.set(`product:${productId}`, product, 3600);
207
- return product;
208
- }
209
-
210
- async updateInventory(productId: string, quantity: number): Promise<void> {
211
- await this.productRepo.updateInventory(productId, quantity);
212
-
213
- // Invalidate cache
214
- await this.cache.delete(`product:${productId}`);
215
-
216
- // Publish event
217
- await this.eventBus.publish('product.inventory.updated', {
218
- productId,
219
- quantity,
220
- timestamp: new Date()
221
- });
222
- }
223
- }
224
-
225
- // src/product-service/infrastructure/product.controller.ts
226
- @Controller('products')
227
- export class ProductController {
228
- constructor(private readonly productService: ProductService) {}
229
-
230
- @Get(':id')
231
- @UseInterceptors(CacheInterceptor)
232
- async getProduct(@Param('id') id: string): Promise<Product> {
233
- return await this.productService.getProduct(id);
234
- }
235
-
236
- @Post()
237
- @UseGuards(AuthGuard)
238
- async createProduct(@Body() dto: CreateProductDto): Promise<Product> {
239
- return await this.productService.createProduct(dto);
240
- }
241
- }
242
- ```
243
-
244
- ### 2. Order Service with Saga Pattern
245
-
246
- **Distributed Transaction Handling**
247
-
248
- ```typescript
249
- // src/order-service/sagas/order-saga.ts
250
- export class OrderSaga {
251
- constructor(
252
- private readonly orderRepo: OrderRepository,
253
- private readonly eventBus: EventBus
254
- ) {}
255
-
256
- async createOrder(orderData: CreateOrderDto): Promise<Order> {
257
- const sagaId = uuidv4();
258
-
259
- try {
260
- // Step 1: Create order (pending)
261
- const order = await this.orderRepo.create({
262
- ...orderData,
263
- status: 'PENDING',
264
- sagaId
265
- });
266
-
267
- // Step 2: Reserve inventory
268
- await this.eventBus.publish('inventory.reserve', {
269
- sagaId,
270
- orderId: order.id,
271
- items: order.items
272
- });
273
-
274
- // Step 3: Process payment
275
- await this.eventBus.publish('payment.process', {
276
- sagaId,
277
- orderId: order.id,
278
- amount: order.total,
279
- paymentMethod: orderData.paymentMethod
280
- });
281
-
282
- // Step 4: Create shipment
283
- await this.eventBus.publish('shipment.create', {
284
- sagaId,
285
- orderId: order.id,
286
- address: orderData.shippingAddress
287
- });
288
-
289
- return order;
290
- } catch (error) {
291
- // Compensating transactions
292
- await this.compensate(sagaId);
293
- throw error;
294
- }
295
- }
296
-
297
- private async compensate(sagaId: string): Promise<void> {
298
- // Rollback in reverse order
299
- await this.eventBus.publish('shipment.cancel', { sagaId });
300
- await this.eventBus.publish('payment.refund', { sagaId });
301
- await this.eventBus.publish('inventory.release', { sagaId });
302
- await this.orderRepo.updateStatus(sagaId, 'CANCELLED');
303
- }
304
-
305
- // Event handlers
306
- @EventHandler('payment.completed')
307
- async onPaymentCompleted(event: PaymentCompletedEvent): Promise<void> {
308
- await this.orderRepo.updateStatus(event.orderId, 'PAID');
309
- }
310
-
311
- @EventHandler('payment.failed')
312
- async onPaymentFailed(event: PaymentFailedEvent): Promise<void> {
313
- await this.compensate(event.sagaId);
314
- }
315
- }
316
- ```
317
-
318
- ### 3. API Gateway Configuration
319
-
320
- **Kong Gateway Setup**
321
-
322
- ```yaml
323
- # kong.yml
324
- _format_version: "2.1"
325
-
326
- services:
327
- - name: product-service
328
- url: http://product-service:3000
329
- routes:
330
- - name: products-route
331
- paths:
332
- - /api/products
333
- methods:
334
- - GET
335
- - POST
336
- - PUT
337
- - DELETE
338
- plugins:
339
- - name: rate-limiting
340
- config:
341
- minute: 100
342
- policy: local
343
- - name: cors
344
- config:
345
- origins:
346
- - https://example.com
347
- - name: jwt
348
- config:
349
- secret_is_base64: false
350
-
351
- - name: order-service
352
- url: http://order-service:3000
353
- routes:
354
- - name: orders-route
355
- paths:
356
- - /api/orders
357
- plugins:
358
- - name: rate-limiting
359
- config:
360
- minute: 50
361
- - name: jwt
362
- config:
363
- secret_is_base64: false
364
- - name: request-transformer
365
- config:
366
- add:
367
- headers:
368
- - X-User-Id:$(jwt.claims.sub)
369
- ```
370
-
371
-
372
-
373
- ### 4. High Availability Setup
374
-
375
- **Kubernetes Deployment**
376
-
377
- ```yaml
378
- # k8s/product-service-deployment.yml
379
- apiVersion: apps/v1
380
- kind: Deployment
381
- metadata:
382
- name: product-service
383
- labels:
384
- app: product-service
385
- spec:
386
- replicas: 3
387
- strategy:
388
- type: RollingUpdate
389
- rollingUpdate:
390
- maxSurge: 1
391
- maxUnavailable: 0
392
- selector:
393
- matchLabels:
394
- app: product-service
395
- template:
396
- metadata:
397
- labels:
398
- app: product-service
399
- spec:
400
- containers:
401
- - name: product-service
402
- image: product-service:1.0.0
403
- ports:
404
- - containerPort: 3000
405
- env:
406
- - name: DATABASE_URL
407
- valueFrom:
408
- secretKeyRef:
409
- name: db-credentials
410
- key: url
411
- - name: REDIS_URL
412
- valueFrom:
413
- configMapKeyRef:
414
- name: redis-config
415
- key: url
416
- resources:
417
- requests:
418
- memory: "256Mi"
419
- cpu: "250m"
420
- limits:
421
- memory: "512Mi"
422
- cpu: "500m"
423
- livenessProbe:
424
- httpGet:
425
- path: /health
426
- port: 3000
427
- initialDelaySeconds: 30
428
- periodSeconds: 10
429
- readinessProbe:
430
- httpGet:
431
- path: /ready
432
- port: 3000
433
- initialDelaySeconds: 5
434
- periodSeconds: 5
435
- ---
436
- apiVersion: v1
437
- kind: Service
438
- metadata:
439
- name: product-service
440
- spec:
441
- selector:
442
- app: product-service
443
- ports:
444
- - protocol: TCP
445
- port: 80
446
- targetPort: 3000
447
- type: ClusterIP
448
- ---
449
- apiVersion: autoscaling/v2
450
- kind: HorizontalPodAutoscaler
451
- metadata:
452
- name: product-service-hpa
453
- spec:
454
- scaleTargetRef:
455
- apiVersion: apps/v1
456
- kind: Deployment
457
- name: product-service
458
- minReplicas: 3
459
- maxReplicas: 10
460
- metrics:
461
- - type: Resource
462
- resource:
463
- name: cpu
464
- target:
465
- type: Utilization
466
- averageUtilization: 70
467
- - type: Resource
468
- resource:
469
- name: memory
470
- target:
471
- type: Utilization
472
- averageUtilization: 80
473
- ```
474
-
475
- ### 5. Monitoring and Observability
476
-
477
- **Prometheus Metrics**
478
-
479
- ```typescript
480
- // src/common/metrics/metrics.service.ts
481
- import { Counter, Histogram, Registry } from 'prom-client';
482
-
483
- export class MetricsService {
484
- private readonly registry: Registry;
485
- private readonly httpRequestDuration: Histogram;
486
- private readonly httpRequestTotal: Counter;
487
- private readonly orderTotal: Counter;
488
-
489
- constructor() {
490
- this.registry = new Registry();
491
-
492
- this.httpRequestDuration = new Histogram({
493
- name: 'http_request_duration_seconds',
494
- help: 'Duration of HTTP requests in seconds',
495
- labelNames: ['method', 'route', 'status_code'],
496
- buckets: [0.1, 0.5, 1, 2, 5]
497
- });
498
-
499
- this.httpRequestTotal = new Counter({
500
- name: 'http_requests_total',
501
- help: 'Total number of HTTP requests',
502
- labelNames: ['method', 'route', 'status_code']
503
- });
504
-
505
- this.orderTotal = new Counter({
506
- name: 'orders_total',
507
- help: 'Total number of orders',
508
- labelNames: ['status']
509
- });
510
-
511
- this.registry.registerMetric(this.httpRequestDuration);
512
- this.registry.registerMetric(this.httpRequestTotal);
513
- this.registry.registerMetric(this.orderTotal);
514
- }
515
-
516
- recordHttpRequest(method: string, route: string, statusCode: number, duration: number): void {
517
- this.httpRequestDuration.observe({ method, route, status_code: statusCode }, duration);
518
- this.httpRequestTotal.inc({ method, route, status_code: statusCode });
519
- }
520
-
521
- recordOrder(status: string): void {
522
- this.orderTotal.inc({ status });
523
- }
524
-
525
- getMetrics(): Promise<string> {
526
- return this.registry.metrics();
527
- }
528
- }
529
- ```
530
-
531
- **Distributed Tracing**
532
-
533
- ```typescript
534
- // src/common/tracing/tracing.interceptor.ts
535
- import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
536
- import { Observable } from 'rxjs';
537
- import { tap } from 'rxjs/operators';
538
- import * as opentracing from 'opentracing';
539
-
540
- @Injectable()
541
- export class TracingInterceptor implements NestInterceptor {
542
- constructor(private readonly tracer: opentracing.Tracer) {}
543
-
544
- intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
545
- const request = context.switchToHttp().getRequest();
546
- const parentSpanContext = this.tracer.extract(
547
- opentracing.FORMAT_HTTP_HEADERS,
548
- request.headers
549
- );
550
-
551
- const span = this.tracer.startSpan(
552
- `${request.method} ${request.route.path}`,
553
- { childOf: parentSpanContext }
554
- );
555
-
556
- span.setTag('http.method', request.method);
557
- span.setTag('http.url', request.url);
558
- span.setTag('service.name', 'product-service');
559
-
560
- return next.handle().pipe(
561
- tap({
562
- next: () => {
563
- span.setTag('http.status_code', 200);
564
- span.finish();
565
- },
566
- error: (error) => {
567
- span.setTag('http.status_code', error.status || 500);
568
- span.setTag('error', true);
569
- span.log({ event: 'error', message: error.message });
570
- span.finish();
571
- }
572
- })
573
- );
574
- }
575
- }
576
- ```
577
-
578
- ---
579
-
580
- ## Scalability Patterns
581
-
582
- ### 1. Database Sharding (Product Service)
583
-
584
- **Shard by Product Category**
585
-
586
- ```typescript
587
- // src/product-service/infrastructure/sharding.service.ts
588
- export class ShardingService {
589
- private readonly shards = [
590
- { id: 'shard-1', categories: ['electronics', 'computers'] },
591
- { id: 'shard-2', categories: ['clothing', 'shoes'] },
592
- { id: 'shard-3', categories: ['home', 'garden'] }
593
- ];
594
-
595
- getShardForCategory(category: string): string {
596
- const shard = this.shards.find(s => s.categories.includes(category));
597
- return shard?.id || 'shard-1'; // Default shard
598
- }
599
-
600
- async getProduct(productId: string, category: string): Promise<Product> {
601
- const shardId = this.getShardForCategory(category);
602
- const connection = await this.getConnection(shardId);
603
- return await connection.query('SELECT * FROM products WHERE id = ?', [productId]);
604
- }
605
- }
606
- ```
607
-
608
- ### 2. Caching Strategy
609
-
610
- **Multi-Level Caching**
611
-
612
- ```typescript
613
- // src/common/cache/cache.service.ts
614
- export class CacheService {
615
- constructor(
616
- private readonly redis: Redis,
617
- private readonly cdn: CloudFront
618
- ) {}
619
-
620
- async get(key: string): Promise<any> {
621
- // Level 1: Application cache (in-memory)
622
- const memCached = this.memCache.get(key);
623
- if (memCached) return memCached;
624
-
625
- // Level 2: Redis cache
626
- const redisCached = await this.redis.get(key);
627
- if (redisCached) {
628
- this.memCache.set(key, redisCached, 60); // 1 minute
629
- return JSON.parse(redisCached);
630
- }
631
-
632
- return null;
633
- }
634
-
635
- async set(key: string, value: any, ttl: number): Promise<void> {
636
- // Set in both caches
637
- this.memCache.set(key, value, Math.min(ttl, 60));
638
- await this.redis.setex(key, ttl, JSON.stringify(value));
639
- }
640
-
641
- async invalidate(pattern: string): Promise<void> {
642
- // Invalidate in Redis
643
- const keys = await this.redis.keys(pattern);
644
- if (keys.length > 0) {
645
- await this.redis.del(...keys);
646
- }
647
-
648
- // Invalidate in CDN
649
- await this.cdn.createInvalidation({
650
- DistributionId: process.env.CDN_DISTRIBUTION_ID,
651
- InvalidationBatch: {
652
- Paths: { Quantity: 1, Items: [`/${pattern}*`] },
653
- CallerReference: Date.now().toString()
654
- }
655
- });
656
- }
657
- }
658
- ```
659
-
660
-
661
- ### 3. Circuit Breaker Pattern
662
-
663
- **Resilience Against Service Failures**
664
-
665
- ```typescript
666
- // src/common/resilience/circuit-breaker.ts
667
- import CircuitBreaker from 'opossum';
668
-
669
- export class ResilientHttpClient {
670
- private breakers: Map<string, CircuitBreaker> = new Map();
671
-
672
- async call(serviceName: string, fn: () => Promise<any>): Promise<any> {
673
- let breaker = this.breakers.get(serviceName);
674
-
675
- if (!breaker) {
676
- breaker = new CircuitBreaker(fn, {
677
- timeout: 3000, // 3 seconds
678
- errorThresholdPercentage: 50,
679
- resetTimeout: 30000, // 30 seconds
680
- rollingCountTimeout: 10000,
681
- rollingCountBuckets: 10
682
- });
683
-
684
- breaker.on('open', () => {
685
- console.error(`Circuit breaker opened for ${serviceName}`);
686
- });
687
-
688
- breaker.on('halfOpen', () => {
689
- console.log(`Circuit breaker half-open for ${serviceName}`);
690
- });
691
-
692
- this.breakers.set(serviceName, breaker);
693
- }
694
-
695
- return await breaker.fire();
696
- }
697
- }
698
-
699
- // Usage in Order Service
700
- export class OrderService {
701
- constructor(private readonly httpClient: ResilientHttpClient) {}
702
-
703
- async createOrder(orderData: CreateOrderDto): Promise<Order> {
704
- // Call payment service with circuit breaker
705
- const payment = await this.httpClient.call(
706
- 'payment-service',
707
- () => this.paymentClient.processPayment(orderData.payment)
708
- );
709
-
710
- return await this.orderRepo.create({ ...orderData, paymentId: payment.id });
711
- }
712
- }
713
- ```
714
-
715
- ---
716
-
717
- ## Security Implementation
718
-
719
- ### 1. Authentication & Authorization
720
-
721
- **JWT-Based Authentication**
722
-
723
- ```typescript
724
- // src/user-service/auth/auth.service.ts
725
- import * as jwt from 'jsonwebtoken';
726
- import * as bcrypt from 'bcrypt';
727
-
728
- export class AuthService {
729
- async login(email: string, password: string): Promise<{ accessToken: string; refreshToken: string }> {
730
- const user = await this.userRepo.findByEmail(email);
731
- if (!user) throw new UnauthorizedException('Invalid credentials');
732
-
733
- const isValid = await bcrypt.compare(password, user.passwordHash);
734
- if (!isValid) throw new UnauthorizedException('Invalid credentials');
735
-
736
- const accessToken = jwt.sign(
737
- { sub: user.id, email: user.email, roles: user.roles },
738
- process.env.JWT_SECRET,
739
- { expiresIn: '15m' }
740
- );
741
-
742
- const refreshToken = jwt.sign(
743
- { sub: user.id },
744
- process.env.JWT_REFRESH_SECRET,
745
- { expiresIn: '7d' }
746
- );
747
-
748
- await this.tokenRepo.saveRefreshToken(user.id, refreshToken);
749
-
750
- return { accessToken, refreshToken };
751
- }
752
-
753
- async refreshAccessToken(refreshToken: string): Promise<string> {
754
- const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
755
- const isValid = await this.tokenRepo.validateRefreshToken(payload.sub, refreshToken);
756
-
757
- if (!isValid) throw new UnauthorizedException('Invalid refresh token');
758
-
759
- const user = await this.userRepo.findById(payload.sub);
760
- return jwt.sign(
761
- { sub: user.id, email: user.email, roles: user.roles },
762
- process.env.JWT_SECRET,
763
- { expiresIn: '15m' }
764
- );
765
- }
766
- }
767
- ```
768
-
769
- ### 2. PCI DSS Compliance (Payment Service)
770
-
771
- **Secure Payment Processing**
772
-
773
- ```typescript
774
- // src/payment-service/payment.service.ts
775
- export class PaymentService {
776
- constructor(
777
- private readonly stripe: Stripe,
778
- private readonly encryptionService: EncryptionService,
779
- private readonly auditLog: AuditLogService
780
- ) {}
781
-
782
- async processPayment(paymentData: PaymentDto): Promise<Payment> {
783
- // Never store raw card data
784
- // Use Stripe tokenization
785
- const paymentIntent = await this.stripe.paymentIntents.create({
786
- amount: paymentData.amount * 100, // Convert to cents
787
- currency: 'usd',
788
- payment_method: paymentData.stripeToken,
789
- confirm: true,
790
- metadata: {
791
- orderId: paymentData.orderId,
792
- customerId: paymentData.customerId
793
- }
794
- });
795
-
796
- // Store only encrypted, tokenized reference
797
- const payment = await this.paymentRepo.create({
798
- orderId: paymentData.orderId,
799
- amount: paymentData.amount,
800
- status: paymentIntent.status,
801
- stripePaymentIntentId: paymentIntent.id,
802
- last4: paymentData.last4, // Only last 4 digits
803
- cardBrand: paymentData.cardBrand
804
- });
805
-
806
- // Audit log for compliance
807
- await this.auditLog.log({
808
- action: 'PAYMENT_PROCESSED',
809
- userId: paymentData.customerId,
810
- orderId: paymentData.orderId,
811
- amount: paymentData.amount,
812
- timestamp: new Date(),
813
- ipAddress: paymentData.ipAddress
814
- });
815
-
816
- return payment;
817
- }
818
- }
819
- ```
820
-
821
- ---
822
-
823
- ## Deployment Strategy
824
-
825
- ### 1. Blue-Green Deployment
826
-
827
- **Zero-Downtime Deployments**
828
-
829
- ```yaml
830
- # k8s/blue-green-deployment.yml
831
- apiVersion: v1
832
- kind: Service
833
- metadata:
834
- name: product-service
835
- spec:
836
- selector:
837
- app: product-service
838
- version: blue # Switch to 'green' for deployment
839
- ports:
840
- - protocol: TCP
841
- port: 80
842
- targetPort: 3000
843
- ---
844
- apiVersion: apps/v1
845
- kind: Deployment
846
- metadata:
847
- name: product-service-blue
848
- spec:
849
- replicas: 3
850
- selector:
851
- matchLabels:
852
- app: product-service
853
- version: blue
854
- template:
855
- metadata:
856
- labels:
857
- app: product-service
858
- version: blue
859
- spec:
860
- containers:
861
- - name: product-service
862
- image: product-service:1.0.0
863
- ---
864
- apiVersion: apps/v1
865
- kind: Deployment
866
- metadata:
867
- name: product-service-green
868
- spec:
869
- replicas: 3
870
- selector:
871
- matchLabels:
872
- app: product-service
873
- version: green
874
- template:
875
- metadata:
876
- labels:
877
- app: product-service
878
- version: green
879
- spec:
880
- containers:
881
- - name: product-service
882
- image: product-service:1.1.0 # New version
883
- ```
884
-
885
- ### 2. CI/CD Pipeline
886
-
887
- **GitHub Actions Workflow**
888
-
889
- ```yaml
890
- # .github/workflows/deploy.yml
891
- name: Deploy Product Service
892
-
893
- on:
894
- push:
895
- branches: [main]
896
- paths:
897
- - 'services/product-service/**'
898
-
899
- jobs:
900
- test:
901
- runs-on: ubuntu-latest
902
- steps:
903
- - uses: actions/checkout@v3
904
- - uses: actions/setup-node@v3
905
- with:
906
- node-version: '18'
907
- - run: npm ci
908
- - run: npm test
909
- - run: npm run test:e2e
910
-
911
- build:
912
- needs: test
913
- runs-on: ubuntu-latest
914
- steps:
915
- - uses: actions/checkout@v3
916
- - uses: docker/build-push-action@v4
917
- with:
918
- context: ./services/product-service
919
- push: true
920
- tags: |
921
- ${{ secrets.ECR_REGISTRY }}/product-service:${{ github.sha }}
922
- ${{ secrets.ECR_REGISTRY }}/product-service:latest
923
-
924
- deploy:
925
- needs: build
926
- runs-on: ubuntu-latest
927
- steps:
928
- - uses: actions/checkout@v3
929
- - uses: aws-actions/configure-aws-credentials@v2
930
- with:
931
- aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
932
- aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
933
- aws-region: us-east-1
934
- - run: |
935
- kubectl set image deployment/product-service-green \
936
- product-service=${{ secrets.ECR_REGISTRY }}/product-service:${{ github.sha }}
937
- kubectl rollout status deployment/product-service-green
938
- kubectl patch service product-service -p '{"spec":{"selector":{"version":"green"}}}'
939
- ```
940
-
941
- ---
942
-
943
- ## Key Takeaways
944
-
945
- ### Architecture Decisions
946
-
947
- 1. **Microservices over Monolith**: Enables independent scaling and deployment
948
- 2. **Event-Driven Communication**: Decouples services, improves resilience
949
- 3. **API Gateway**: Single entry point, centralized security and routing
950
- 4. **Saga Pattern**: Manages distributed transactions without 2PC
951
- 5. **Circuit Breaker**: Prevents cascade failures
952
- 6. **Multi-Level Caching**: Reduces database load, improves performance
953
- 7. **Database per Service**: Data ownership, independent scaling
954
-
955
- ### Trade-offs
956
-
957
- **Benefits**
958
- - ✅ Independent scaling of services
959
- - ✅ Technology diversity
960
- - ✅ Fault isolation
961
- - ✅ Faster deployments
962
- - ✅ Team autonomy
963
-
964
- **Challenges**
965
- - ❌ Increased operational complexity
966
- - ❌ Distributed transaction management
967
- - ❌ Network latency
968
- - ❌ Data consistency challenges
969
- - ❌ Testing complexity
970
-
971
- ### Performance Metrics
972
-
973
- - **Availability**: 99.99% (4 nines)
974
- - **API Response Time**: P95 < 200ms
975
- - **Order Processing**: 10,000 orders/day
976
- - **Concurrent Users**: 10,000
977
- - **Database Queries**: < 50ms (P95)
978
- - **Cache Hit Rate**: > 80%
979
-
980
- ---
981
-
982
- ## References
983
-
984
- - [Microservices Architecture](../rules/microservices-architecture.md)
985
- - [Scalability Patterns](../rules/scalability.md)
986
- - [Security Architecture](../rules/security.md)
987
- - [Event-Driven Architecture](../rules/event-driven-architecture.md)
988
- - [Saga Pattern](https://microservices.io/patterns/data/saga.html)
989
- - [Circuit Breaker Pattern](https://martinfowler.com/bliki/CircuitBreaker.html)
990
-
1
+ # E-Commerce Platform Architecture Example
2
+
3
+ ## Overview
4
+
5
+ This document provides a comprehensive example of an e-commerce platform built with microservices architecture, focusing on high availability, scalability, and resilience.
6
+
7
+ ---
8
+
9
+ ## System Context
10
+
11
+ ### Business Requirements
12
+
13
+ **Functional Requirements**
14
+ - Product catalog with search and filtering
15
+ - Shopping cart and checkout
16
+ - Order processing and tracking
17
+ - Payment processing
18
+ - User authentication and profiles
19
+ - Inventory management
20
+ - Shipping and fulfillment
21
+ - Customer reviews and ratings
22
+
23
+ **Non-Functional Requirements**
24
+ - **Availability**: 99.99% uptime (52 minutes downtime/year)
25
+ - **Scalability**: Handle 10,000 concurrent users, 1M products
26
+ - **Performance**: Page load < 2s, API response < 200ms
27
+ - **Security**: PCI DSS compliance for payments
28
+ - **Reliability**: Zero data loss, eventual consistency acceptable
29
+
30
+ ### Scale Metrics
31
+ - 1 million registered users
32
+ - 100,000 daily active users
33
+ - 10,000 orders per day
34
+ - 1 million products in catalog
35
+ - Peak traffic: Black Friday (10x normal load)
36
+
37
+ ---
38
+
39
+ ## Architecture Overview
40
+
41
+ ### Microservices Decomposition
42
+
43
+ **Service Boundaries (Domain-Driven Design)**
44
+
45
+ ```
46
+ ┌─────────────────────────────────────────────────────────────┐
47
+ │ API Gateway (Kong) │
48
+ │ Authentication, Rate Limiting, Routing │
49
+ └─────────────────────────────────────────────────────────────┘
50
+
51
+ ┌─────────────────────┼─────────────────────┐
52
+ │ │ │
53
+ ┌───────▼────────┐ ┌────────▼────────┐ ┌───────▼────────┐
54
+ │ User Service │ │ Product Service │ │ Order Service │
55
+ │ (Auth, Profile)│ │ (Catalog, Search│ │ (Checkout, │
56
+ │ │ │ Inventory) │ │ Fulfillment) │
57
+ └────────────────┘ └─────────────────┘ └────────────────┘
58
+ │ │ │
59
+ │ ┌────────▼────────┐ │
60
+ │ │ Search Service │ │
61
+ │ │ (Elasticsearch) │ │
62
+ │ └─────────────────┘ │
63
+ │ │
64
+ ┌───────▼────────┐ ┌─────────────────┐ ┌───────▼────────┐
65
+ │ Payment Service│ │ Review Service │ │ Shipping Svc │
66
+ │ (Stripe, PayPal│ │ (Ratings, UGC) │ │ (Tracking, │
67
+ │ PCI Compliant)│ │ │ │ Carriers) │
68
+ └────────────────┘ └─────────────────┘ └────────────────┘
69
+ │ │ │
70
+ └─────────────────────┼─────────────────────┘
71
+
72
+ ┌─────────▼─────────┐
73
+ │ Event Bus (Kafka) │
74
+ │ (Event Sourcing) │
75
+ └────────────────────┘
76
+ ```
77
+
78
+ ### Service Responsibilities
79
+
80
+ **1. User Service**
81
+ - User registration and authentication (JWT)
82
+ - Profile management
83
+ - Address book
84
+ - Preferences and settings
85
+ - OAuth integration (Google, Facebook)
86
+
87
+ **2. Product Service**
88
+ - Product catalog CRUD
89
+ - Category management
90
+ - Product attributes and variants
91
+ - Inventory tracking
92
+ - Price management
93
+
94
+ **3. Search Service**
95
+ - Full-text search (Elasticsearch)
96
+ - Faceted search and filtering
97
+ - Search suggestions and autocomplete
98
+ - Personalized search results
99
+ - Search analytics
100
+
101
+ **4. Order Service**
102
+ - Shopping cart management
103
+ - Order creation and processing
104
+ - Order history and tracking
105
+ - Order status updates
106
+ - Saga orchestration for distributed transactions
107
+
108
+ **5. Payment Service**
109
+ - Payment processing (Stripe, PayPal)
110
+ - PCI DSS compliance
111
+ - Payment method management
112
+ - Refund processing
113
+ - Fraud detection integration
114
+
115
+ **6. Review Service**
116
+ - Product reviews and ratings
117
+ - Review moderation
118
+ - Helpful votes
119
+ - Review analytics
120
+
121
+ **7. Shipping Service**
122
+ - Shipping rate calculation
123
+ - Carrier integration (FedEx, UPS, USPS)
124
+ - Shipment tracking
125
+ - Delivery notifications
126
+
127
+ ---
128
+
129
+ ## Technology Stack
130
+
131
+ ### Services
132
+ - **Language**: Node.js (TypeScript) for most services
133
+ - **Framework**: Express.js, NestJS
134
+ - **API**: REST + GraphQL (BFF pattern)
135
+
136
+ ### Data Storage
137
+ - **User Service**: PostgreSQL (relational, ACID)
138
+ - **Product Service**: PostgreSQL + Redis (caching)
139
+ - **Search Service**: Elasticsearch
140
+ - **Order Service**: PostgreSQL + Event Store
141
+ - **Review Service**: MongoDB (document-based)
142
+ - **Session Store**: Redis
143
+
144
+ ### Infrastructure
145
+ - **Container Orchestration**: Kubernetes (EKS)
146
+ - **Service Mesh**: Istio (traffic management, security)
147
+ - **API Gateway**: Kong
148
+ - **Message Broker**: Apache Kafka
149
+ - **Cache**: Redis Cluster
150
+ - **CDN**: CloudFront
151
+ - **Load Balancer**: AWS ALB
152
+
153
+ ### Observability
154
+ - **Monitoring**: Prometheus + Grafana
155
+ - **Logging**: ELK Stack (Elasticsearch, Logstash, Kibana)
156
+ - **Tracing**: Jaeger (distributed tracing)
157
+ - **Alerting**: PagerDuty
158
+
159
+ ### CI/CD
160
+ - **Version Control**: GitHub
161
+ - **CI/CD**: GitHub Actions + ArgoCD
162
+ - **Container Registry**: ECR
163
+ - **Infrastructure as Code**: Terraform
164
+
165
+ ---
166
+
167
+ ## Implementation Details
168
+
169
+ ### 1. Product Service Implementation
170
+
171
+ **Service Structure**
172
+
173
+ ```typescript
174
+ // src/product-service/domain/product.entity.ts
175
+ export class Product {
176
+ id: string;
177
+ name: string;
178
+ description: string;
179
+ price: number;
180
+ categoryId: string;
181
+ inventory: number;
182
+ images: string[];
183
+ attributes: Record<string, any>;
184
+ createdAt: Date;
185
+ updatedAt: Date;
186
+ }
187
+
188
+ // src/product-service/application/product.service.ts
189
+ export class ProductService {
190
+ constructor(
191
+ private readonly productRepo: ProductRepository,
192
+ private readonly cache: CacheService,
193
+ private readonly eventBus: EventBus
194
+ ) {}
195
+
196
+ async getProduct(productId: string): Promise<Product> {
197
+ // Check cache first
198
+ const cached = await this.cache.get(`product:${productId}`);
199
+ if (cached) return cached;
200
+
201
+ // Fetch from database
202
+ const product = await this.productRepo.findById(productId);
203
+ if (!product) throw new NotFoundException('Product not found');
204
+
205
+ // Cache for 1 hour
206
+ await this.cache.set(`product:${productId}`, product, 3600);
207
+ return product;
208
+ }
209
+
210
+ async updateInventory(productId: string, quantity: number): Promise<void> {
211
+ await this.productRepo.updateInventory(productId, quantity);
212
+
213
+ // Invalidate cache
214
+ await this.cache.delete(`product:${productId}`);
215
+
216
+ // Publish event
217
+ await this.eventBus.publish('product.inventory.updated', {
218
+ productId,
219
+ quantity,
220
+ timestamp: new Date()
221
+ });
222
+ }
223
+ }
224
+
225
+ // src/product-service/infrastructure/product.controller.ts
226
+ @Controller('products')
227
+ export class ProductController {
228
+ constructor(private readonly productService: ProductService) {}
229
+
230
+ @Get(':id')
231
+ @UseInterceptors(CacheInterceptor)
232
+ async getProduct(@Param('id') id: string): Promise<Product> {
233
+ return await this.productService.getProduct(id);
234
+ }
235
+
236
+ @Post()
237
+ @UseGuards(AuthGuard)
238
+ async createProduct(@Body() dto: CreateProductDto): Promise<Product> {
239
+ return await this.productService.createProduct(dto);
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### 2. Order Service with Saga Pattern
245
+
246
+ **Distributed Transaction Handling**
247
+
248
+ ```typescript
249
+ // src/order-service/sagas/order-saga.ts
250
+ export class OrderSaga {
251
+ constructor(
252
+ private readonly orderRepo: OrderRepository,
253
+ private readonly eventBus: EventBus
254
+ ) {}
255
+
256
+ async createOrder(orderData: CreateOrderDto): Promise<Order> {
257
+ const sagaId = uuidv4();
258
+
259
+ try {
260
+ // Step 1: Create order (pending)
261
+ const order = await this.orderRepo.create({
262
+ ...orderData,
263
+ status: 'PENDING',
264
+ sagaId
265
+ });
266
+
267
+ // Step 2: Reserve inventory
268
+ await this.eventBus.publish('inventory.reserve', {
269
+ sagaId,
270
+ orderId: order.id,
271
+ items: order.items
272
+ });
273
+
274
+ // Step 3: Process payment
275
+ await this.eventBus.publish('payment.process', {
276
+ sagaId,
277
+ orderId: order.id,
278
+ amount: order.total,
279
+ paymentMethod: orderData.paymentMethod
280
+ });
281
+
282
+ // Step 4: Create shipment
283
+ await this.eventBus.publish('shipment.create', {
284
+ sagaId,
285
+ orderId: order.id,
286
+ address: orderData.shippingAddress
287
+ });
288
+
289
+ return order;
290
+ } catch (error) {
291
+ // Compensating transactions
292
+ await this.compensate(sagaId);
293
+ throw error;
294
+ }
295
+ }
296
+
297
+ private async compensate(sagaId: string): Promise<void> {
298
+ // Rollback in reverse order
299
+ await this.eventBus.publish('shipment.cancel', { sagaId });
300
+ await this.eventBus.publish('payment.refund', { sagaId });
301
+ await this.eventBus.publish('inventory.release', { sagaId });
302
+ await this.orderRepo.updateStatus(sagaId, 'CANCELLED');
303
+ }
304
+
305
+ // Event handlers
306
+ @EventHandler('payment.completed')
307
+ async onPaymentCompleted(event: PaymentCompletedEvent): Promise<void> {
308
+ await this.orderRepo.updateStatus(event.orderId, 'PAID');
309
+ }
310
+
311
+ @EventHandler('payment.failed')
312
+ async onPaymentFailed(event: PaymentFailedEvent): Promise<void> {
313
+ await this.compensate(event.sagaId);
314
+ }
315
+ }
316
+ ```
317
+
318
+ ### 3. API Gateway Configuration
319
+
320
+ **Kong Gateway Setup**
321
+
322
+ ```yaml
323
+ # kong.yml
324
+ _format_version: "2.1"
325
+
326
+ services:
327
+ - name: product-service
328
+ url: http://product-service:3000
329
+ routes:
330
+ - name: products-route
331
+ paths:
332
+ - /api/products
333
+ methods:
334
+ - GET
335
+ - POST
336
+ - PUT
337
+ - DELETE
338
+ plugins:
339
+ - name: rate-limiting
340
+ config:
341
+ minute: 100
342
+ policy: local
343
+ - name: cors
344
+ config:
345
+ origins:
346
+ - https://example.com
347
+ - name: jwt
348
+ config:
349
+ secret_is_base64: false
350
+
351
+ - name: order-service
352
+ url: http://order-service:3000
353
+ routes:
354
+ - name: orders-route
355
+ paths:
356
+ - /api/orders
357
+ plugins:
358
+ - name: rate-limiting
359
+ config:
360
+ minute: 50
361
+ - name: jwt
362
+ config:
363
+ secret_is_base64: false
364
+ - name: request-transformer
365
+ config:
366
+ add:
367
+ headers:
368
+ - X-User-Id:$(jwt.claims.sub)
369
+ ```
370
+
371
+
372
+
373
+ ### 4. High Availability Setup
374
+
375
+ **Kubernetes Deployment**
376
+
377
+ ```yaml
378
+ # k8s/product-service-deployment.yml
379
+ apiVersion: apps/v1
380
+ kind: Deployment
381
+ metadata:
382
+ name: product-service
383
+ labels:
384
+ app: product-service
385
+ spec:
386
+ replicas: 3
387
+ strategy:
388
+ type: RollingUpdate
389
+ rollingUpdate:
390
+ maxSurge: 1
391
+ maxUnavailable: 0
392
+ selector:
393
+ matchLabels:
394
+ app: product-service
395
+ template:
396
+ metadata:
397
+ labels:
398
+ app: product-service
399
+ spec:
400
+ containers:
401
+ - name: product-service
402
+ image: product-service:1.0.0
403
+ ports:
404
+ - containerPort: 3000
405
+ env:
406
+ - name: DATABASE_URL
407
+ valueFrom:
408
+ secretKeyRef:
409
+ name: db-credentials
410
+ key: url
411
+ - name: REDIS_URL
412
+ valueFrom:
413
+ configMapKeyRef:
414
+ name: redis-config
415
+ key: url
416
+ resources:
417
+ requests:
418
+ memory: "256Mi"
419
+ cpu: "250m"
420
+ limits:
421
+ memory: "512Mi"
422
+ cpu: "500m"
423
+ livenessProbe:
424
+ httpGet:
425
+ path: /health
426
+ port: 3000
427
+ initialDelaySeconds: 30
428
+ periodSeconds: 10
429
+ readinessProbe:
430
+ httpGet:
431
+ path: /ready
432
+ port: 3000
433
+ initialDelaySeconds: 5
434
+ periodSeconds: 5
435
+ ---
436
+ apiVersion: v1
437
+ kind: Service
438
+ metadata:
439
+ name: product-service
440
+ spec:
441
+ selector:
442
+ app: product-service
443
+ ports:
444
+ - protocol: TCP
445
+ port: 80
446
+ targetPort: 3000
447
+ type: ClusterIP
448
+ ---
449
+ apiVersion: autoscaling/v2
450
+ kind: HorizontalPodAutoscaler
451
+ metadata:
452
+ name: product-service-hpa
453
+ spec:
454
+ scaleTargetRef:
455
+ apiVersion: apps/v1
456
+ kind: Deployment
457
+ name: product-service
458
+ minReplicas: 3
459
+ maxReplicas: 10
460
+ metrics:
461
+ - type: Resource
462
+ resource:
463
+ name: cpu
464
+ target:
465
+ type: Utilization
466
+ averageUtilization: 70
467
+ - type: Resource
468
+ resource:
469
+ name: memory
470
+ target:
471
+ type: Utilization
472
+ averageUtilization: 80
473
+ ```
474
+
475
+ ### 5. Monitoring and Observability
476
+
477
+ **Prometheus Metrics**
478
+
479
+ ```typescript
480
+ // src/common/metrics/metrics.service.ts
481
+ import { Counter, Histogram, Registry } from 'prom-client';
482
+
483
+ export class MetricsService {
484
+ private readonly registry: Registry;
485
+ private readonly httpRequestDuration: Histogram;
486
+ private readonly httpRequestTotal: Counter;
487
+ private readonly orderTotal: Counter;
488
+
489
+ constructor() {
490
+ this.registry = new Registry();
491
+
492
+ this.httpRequestDuration = new Histogram({
493
+ name: 'http_request_duration_seconds',
494
+ help: 'Duration of HTTP requests in seconds',
495
+ labelNames: ['method', 'route', 'status_code'],
496
+ buckets: [0.1, 0.5, 1, 2, 5]
497
+ });
498
+
499
+ this.httpRequestTotal = new Counter({
500
+ name: 'http_requests_total',
501
+ help: 'Total number of HTTP requests',
502
+ labelNames: ['method', 'route', 'status_code']
503
+ });
504
+
505
+ this.orderTotal = new Counter({
506
+ name: 'orders_total',
507
+ help: 'Total number of orders',
508
+ labelNames: ['status']
509
+ });
510
+
511
+ this.registry.registerMetric(this.httpRequestDuration);
512
+ this.registry.registerMetric(this.httpRequestTotal);
513
+ this.registry.registerMetric(this.orderTotal);
514
+ }
515
+
516
+ recordHttpRequest(method: string, route: string, statusCode: number, duration: number): void {
517
+ this.httpRequestDuration.observe({ method, route, status_code: statusCode }, duration);
518
+ this.httpRequestTotal.inc({ method, route, status_code: statusCode });
519
+ }
520
+
521
+ recordOrder(status: string): void {
522
+ this.orderTotal.inc({ status });
523
+ }
524
+
525
+ getMetrics(): Promise<string> {
526
+ return this.registry.metrics();
527
+ }
528
+ }
529
+ ```
530
+
531
+ **Distributed Tracing**
532
+
533
+ ```typescript
534
+ // src/common/tracing/tracing.interceptor.ts
535
+ import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
536
+ import { Observable } from 'rxjs';
537
+ import { tap } from 'rxjs/operators';
538
+ import * as opentracing from 'opentracing';
539
+
540
+ @Injectable()
541
+ export class TracingInterceptor implements NestInterceptor {
542
+ constructor(private readonly tracer: opentracing.Tracer) {}
543
+
544
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
545
+ const request = context.switchToHttp().getRequest();
546
+ const parentSpanContext = this.tracer.extract(
547
+ opentracing.FORMAT_HTTP_HEADERS,
548
+ request.headers
549
+ );
550
+
551
+ const span = this.tracer.startSpan(
552
+ `${request.method} ${request.route.path}`,
553
+ { childOf: parentSpanContext }
554
+ );
555
+
556
+ span.setTag('http.method', request.method);
557
+ span.setTag('http.url', request.url);
558
+ span.setTag('service.name', 'product-service');
559
+
560
+ return next.handle().pipe(
561
+ tap({
562
+ next: () => {
563
+ span.setTag('http.status_code', 200);
564
+ span.finish();
565
+ },
566
+ error: (error) => {
567
+ span.setTag('http.status_code', error.status || 500);
568
+ span.setTag('error', true);
569
+ span.log({ event: 'error', message: error.message });
570
+ span.finish();
571
+ }
572
+ })
573
+ );
574
+ }
575
+ }
576
+ ```
577
+
578
+ ---
579
+
580
+ ## Scalability Patterns
581
+
582
+ ### 1. Database Sharding (Product Service)
583
+
584
+ **Shard by Product Category**
585
+
586
+ ```typescript
587
+ // src/product-service/infrastructure/sharding.service.ts
588
+ export class ShardingService {
589
+ private readonly shards = [
590
+ { id: 'shard-1', categories: ['electronics', 'computers'] },
591
+ { id: 'shard-2', categories: ['clothing', 'shoes'] },
592
+ { id: 'shard-3', categories: ['home', 'garden'] }
593
+ ];
594
+
595
+ getShardForCategory(category: string): string {
596
+ const shard = this.shards.find(s => s.categories.includes(category));
597
+ return shard?.id || 'shard-1'; // Default shard
598
+ }
599
+
600
+ async getProduct(productId: string, category: string): Promise<Product> {
601
+ const shardId = this.getShardForCategory(category);
602
+ const connection = await this.getConnection(shardId);
603
+ return await connection.query('SELECT * FROM products WHERE id = ?', [productId]);
604
+ }
605
+ }
606
+ ```
607
+
608
+ ### 2. Caching Strategy
609
+
610
+ **Multi-Level Caching**
611
+
612
+ ```typescript
613
+ // src/common/cache/cache.service.ts
614
+ export class CacheService {
615
+ constructor(
616
+ private readonly redis: Redis,
617
+ private readonly cdn: CloudFront
618
+ ) {}
619
+
620
+ async get(key: string): Promise<any> {
621
+ // Level 1: Application cache (in-memory)
622
+ const memCached = this.memCache.get(key);
623
+ if (memCached) return memCached;
624
+
625
+ // Level 2: Redis cache
626
+ const redisCached = await this.redis.get(key);
627
+ if (redisCached) {
628
+ this.memCache.set(key, redisCached, 60); // 1 minute
629
+ return JSON.parse(redisCached);
630
+ }
631
+
632
+ return null;
633
+ }
634
+
635
+ async set(key: string, value: any, ttl: number): Promise<void> {
636
+ // Set in both caches
637
+ this.memCache.set(key, value, Math.min(ttl, 60));
638
+ await this.redis.setex(key, ttl, JSON.stringify(value));
639
+ }
640
+
641
+ async invalidate(pattern: string): Promise<void> {
642
+ // Invalidate in Redis
643
+ const keys = await this.redis.keys(pattern);
644
+ if (keys.length > 0) {
645
+ await this.redis.del(...keys);
646
+ }
647
+
648
+ // Invalidate in CDN
649
+ await this.cdn.createInvalidation({
650
+ DistributionId: process.env.CDN_DISTRIBUTION_ID,
651
+ InvalidationBatch: {
652
+ Paths: { Quantity: 1, Items: [`/${pattern}*`] },
653
+ CallerReference: Date.now().toString()
654
+ }
655
+ });
656
+ }
657
+ }
658
+ ```
659
+
660
+
661
+ ### 3. Circuit Breaker Pattern
662
+
663
+ **Resilience Against Service Failures**
664
+
665
+ ```typescript
666
+ // src/common/resilience/circuit-breaker.ts
667
+ import CircuitBreaker from 'opossum';
668
+
669
+ export class ResilientHttpClient {
670
+ private breakers: Map<string, CircuitBreaker> = new Map();
671
+
672
+ async call(serviceName: string, fn: () => Promise<any>): Promise<any> {
673
+ let breaker = this.breakers.get(serviceName);
674
+
675
+ if (!breaker) {
676
+ breaker = new CircuitBreaker(fn, {
677
+ timeout: 3000, // 3 seconds
678
+ errorThresholdPercentage: 50,
679
+ resetTimeout: 30000, // 30 seconds
680
+ rollingCountTimeout: 10000,
681
+ rollingCountBuckets: 10
682
+ });
683
+
684
+ breaker.on('open', () => {
685
+ console.error(`Circuit breaker opened for ${serviceName}`);
686
+ });
687
+
688
+ breaker.on('halfOpen', () => {
689
+ console.log(`Circuit breaker half-open for ${serviceName}`);
690
+ });
691
+
692
+ this.breakers.set(serviceName, breaker);
693
+ }
694
+
695
+ return await breaker.fire();
696
+ }
697
+ }
698
+
699
+ // Usage in Order Service
700
+ export class OrderService {
701
+ constructor(private readonly httpClient: ResilientHttpClient) {}
702
+
703
+ async createOrder(orderData: CreateOrderDto): Promise<Order> {
704
+ // Call payment service with circuit breaker
705
+ const payment = await this.httpClient.call(
706
+ 'payment-service',
707
+ () => this.paymentClient.processPayment(orderData.payment)
708
+ );
709
+
710
+ return await this.orderRepo.create({ ...orderData, paymentId: payment.id });
711
+ }
712
+ }
713
+ ```
714
+
715
+ ---
716
+
717
+ ## Security Implementation
718
+
719
+ ### 1. Authentication & Authorization
720
+
721
+ **JWT-Based Authentication**
722
+
723
+ ```typescript
724
+ // src/user-service/auth/auth.service.ts
725
+ import * as jwt from 'jsonwebtoken';
726
+ import * as bcrypt from 'bcrypt';
727
+
728
+ export class AuthService {
729
+ async login(email: string, password: string): Promise<{ accessToken: string; refreshToken: string }> {
730
+ const user = await this.userRepo.findByEmail(email);
731
+ if (!user) throw new UnauthorizedException('Invalid credentials');
732
+
733
+ const isValid = await bcrypt.compare(password, user.passwordHash);
734
+ if (!isValid) throw new UnauthorizedException('Invalid credentials');
735
+
736
+ const accessToken = jwt.sign(
737
+ { sub: user.id, email: user.email, roles: user.roles },
738
+ process.env.JWT_SECRET,
739
+ { expiresIn: '15m' }
740
+ );
741
+
742
+ const refreshToken = jwt.sign(
743
+ { sub: user.id },
744
+ process.env.JWT_REFRESH_SECRET,
745
+ { expiresIn: '7d' }
746
+ );
747
+
748
+ await this.tokenRepo.saveRefreshToken(user.id, refreshToken);
749
+
750
+ return { accessToken, refreshToken };
751
+ }
752
+
753
+ async refreshAccessToken(refreshToken: string): Promise<string> {
754
+ const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
755
+ const isValid = await this.tokenRepo.validateRefreshToken(payload.sub, refreshToken);
756
+
757
+ if (!isValid) throw new UnauthorizedException('Invalid refresh token');
758
+
759
+ const user = await this.userRepo.findById(payload.sub);
760
+ return jwt.sign(
761
+ { sub: user.id, email: user.email, roles: user.roles },
762
+ process.env.JWT_SECRET,
763
+ { expiresIn: '15m' }
764
+ );
765
+ }
766
+ }
767
+ ```
768
+
769
+ ### 2. PCI DSS Compliance (Payment Service)
770
+
771
+ **Secure Payment Processing**
772
+
773
+ ```typescript
774
+ // src/payment-service/payment.service.ts
775
+ export class PaymentService {
776
+ constructor(
777
+ private readonly stripe: Stripe,
778
+ private readonly encryptionService: EncryptionService,
779
+ private readonly auditLog: AuditLogService
780
+ ) {}
781
+
782
+ async processPayment(paymentData: PaymentDto): Promise<Payment> {
783
+ // Never store raw card data
784
+ // Use Stripe tokenization
785
+ const paymentIntent = await this.stripe.paymentIntents.create({
786
+ amount: paymentData.amount * 100, // Convert to cents
787
+ currency: 'usd',
788
+ payment_method: paymentData.stripeToken,
789
+ confirm: true,
790
+ metadata: {
791
+ orderId: paymentData.orderId,
792
+ customerId: paymentData.customerId
793
+ }
794
+ });
795
+
796
+ // Store only encrypted, tokenized reference
797
+ const payment = await this.paymentRepo.create({
798
+ orderId: paymentData.orderId,
799
+ amount: paymentData.amount,
800
+ status: paymentIntent.status,
801
+ stripePaymentIntentId: paymentIntent.id,
802
+ last4: paymentData.last4, // Only last 4 digits
803
+ cardBrand: paymentData.cardBrand
804
+ });
805
+
806
+ // Audit log for compliance
807
+ await this.auditLog.log({
808
+ action: 'PAYMENT_PROCESSED',
809
+ userId: paymentData.customerId,
810
+ orderId: paymentData.orderId,
811
+ amount: paymentData.amount,
812
+ timestamp: new Date(),
813
+ ipAddress: paymentData.ipAddress
814
+ });
815
+
816
+ return payment;
817
+ }
818
+ }
819
+ ```
820
+
821
+ ---
822
+
823
+ ## Deployment Strategy
824
+
825
+ ### 1. Blue-Green Deployment
826
+
827
+ **Zero-Downtime Deployments**
828
+
829
+ ```yaml
830
+ # k8s/blue-green-deployment.yml
831
+ apiVersion: v1
832
+ kind: Service
833
+ metadata:
834
+ name: product-service
835
+ spec:
836
+ selector:
837
+ app: product-service
838
+ version: blue # Switch to 'green' for deployment
839
+ ports:
840
+ - protocol: TCP
841
+ port: 80
842
+ targetPort: 3000
843
+ ---
844
+ apiVersion: apps/v1
845
+ kind: Deployment
846
+ metadata:
847
+ name: product-service-blue
848
+ spec:
849
+ replicas: 3
850
+ selector:
851
+ matchLabels:
852
+ app: product-service
853
+ version: blue
854
+ template:
855
+ metadata:
856
+ labels:
857
+ app: product-service
858
+ version: blue
859
+ spec:
860
+ containers:
861
+ - name: product-service
862
+ image: product-service:1.0.0
863
+ ---
864
+ apiVersion: apps/v1
865
+ kind: Deployment
866
+ metadata:
867
+ name: product-service-green
868
+ spec:
869
+ replicas: 3
870
+ selector:
871
+ matchLabels:
872
+ app: product-service
873
+ version: green
874
+ template:
875
+ metadata:
876
+ labels:
877
+ app: product-service
878
+ version: green
879
+ spec:
880
+ containers:
881
+ - name: product-service
882
+ image: product-service:1.1.0 # New version
883
+ ```
884
+
885
+ ### 2. CI/CD Pipeline
886
+
887
+ **GitHub Actions Workflow**
888
+
889
+ ```yaml
890
+ # .github/workflows/deploy.yml
891
+ name: Deploy Product Service
892
+
893
+ on:
894
+ push:
895
+ branches: [main]
896
+ paths:
897
+ - 'services/product-service/**'
898
+
899
+ jobs:
900
+ test:
901
+ runs-on: ubuntu-latest
902
+ steps:
903
+ - uses: actions/checkout@v3
904
+ - uses: actions/setup-node@v3
905
+ with:
906
+ node-version: '18'
907
+ - run: npm ci
908
+ - run: npm test
909
+ - run: npm run test:e2e
910
+
911
+ build:
912
+ needs: test
913
+ runs-on: ubuntu-latest
914
+ steps:
915
+ - uses: actions/checkout@v3
916
+ - uses: docker/build-push-action@v4
917
+ with:
918
+ context: ./services/product-service
919
+ push: true
920
+ tags: |
921
+ ${{ secrets.ECR_REGISTRY }}/product-service:${{ github.sha }}
922
+ ${{ secrets.ECR_REGISTRY }}/product-service:latest
923
+
924
+ deploy:
925
+ needs: build
926
+ runs-on: ubuntu-latest
927
+ steps:
928
+ - uses: actions/checkout@v3
929
+ - uses: aws-actions/configure-aws-credentials@v2
930
+ with:
931
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
932
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
933
+ aws-region: us-east-1
934
+ - run: |
935
+ kubectl set image deployment/product-service-green \
936
+ product-service=${{ secrets.ECR_REGISTRY }}/product-service:${{ github.sha }}
937
+ kubectl rollout status deployment/product-service-green
938
+ kubectl patch service product-service -p '{"spec":{"selector":{"version":"green"}}}'
939
+ ```
940
+
941
+ ---
942
+
943
+ ## Key Takeaways
944
+
945
+ ### Architecture Decisions
946
+
947
+ 1. **Microservices over Monolith**: Enables independent scaling and deployment
948
+ 2. **Event-Driven Communication**: Decouples services, improves resilience
949
+ 3. **API Gateway**: Single entry point, centralized security and routing
950
+ 4. **Saga Pattern**: Manages distributed transactions without 2PC
951
+ 5. **Circuit Breaker**: Prevents cascade failures
952
+ 6. **Multi-Level Caching**: Reduces database load, improves performance
953
+ 7. **Database per Service**: Data ownership, independent scaling
954
+
955
+ ### Trade-offs
956
+
957
+ **Benefits**
958
+ - ✅ Independent scaling of services
959
+ - ✅ Technology diversity
960
+ - ✅ Fault isolation
961
+ - ✅ Faster deployments
962
+ - ✅ Team autonomy
963
+
964
+ **Challenges**
965
+ - ❌ Increased operational complexity
966
+ - ❌ Distributed transaction management
967
+ - ❌ Network latency
968
+ - ❌ Data consistency challenges
969
+ - ❌ Testing complexity
970
+
971
+ ### Performance Metrics
972
+
973
+ - **Availability**: 99.99% (4 nines)
974
+ - **API Response Time**: P95 < 200ms
975
+ - **Order Processing**: 10,000 orders/day
976
+ - **Concurrent Users**: 10,000
977
+ - **Database Queries**: < 50ms (P95)
978
+ - **Cache Hit Rate**: > 80%
979
+
980
+ ---
981
+
982
+ ## References
983
+
984
+ - [Microservices Architecture](../rules/microservices-architecture.md)
985
+ - [Scalability Patterns](../rules/scalability.md)
986
+ - [Security Architecture](../rules/security.md)
987
+ - [Event-Driven Architecture](../rules/event-driven-architecture.md)
988
+ - [Saga Pattern](https://microservices.io/patterns/data/saga.html)
989
+ - [Circuit Breaker Pattern](https://martinfowler.com/bliki/CircuitBreaker.html)
990
+