@mytechtoday/augment-extensions 1.2.1 → 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 (87) hide show
  1. package/AGENTS.md +33 -1
  2. package/README.md +3 -3
  3. package/augment-extensions/domain-rules/software-architecture/README.md +143 -0
  4. package/augment-extensions/domain-rules/software-architecture/examples/banking-layered.md +961 -0
  5. package/augment-extensions/domain-rules/software-architecture/examples/ecommerce-microservices.md +990 -0
  6. package/augment-extensions/domain-rules/software-architecture/examples/iot-eventdriven.md +882 -0
  7. package/augment-extensions/domain-rules/software-architecture/examples/monolith-to-microservices-migration.md +703 -0
  8. package/augment-extensions/domain-rules/software-architecture/examples/serverless-imageprocessing.md +957 -0
  9. package/augment-extensions/domain-rules/software-architecture/examples/trading-eventdriven.md +747 -0
  10. package/augment-extensions/domain-rules/software-architecture/module.json +119 -0
  11. package/augment-extensions/domain-rules/software-architecture/rules/challenges-solutions.md +763 -0
  12. package/augment-extensions/domain-rules/software-architecture/rules/definitions-terminology.md +409 -0
  13. package/augment-extensions/domain-rules/software-architecture/rules/design-principles.md +684 -0
  14. package/augment-extensions/domain-rules/software-architecture/rules/evaluation-testing.md +1381 -0
  15. package/augment-extensions/domain-rules/software-architecture/rules/event-driven-architecture.md +616 -0
  16. package/augment-extensions/domain-rules/software-architecture/rules/fundamentals.md +306 -0
  17. package/augment-extensions/domain-rules/software-architecture/rules/industry-architectures.md +554 -0
  18. package/augment-extensions/domain-rules/software-architecture/rules/layered-architecture.md +776 -0
  19. package/augment-extensions/domain-rules/software-architecture/rules/microservices-architecture.md +503 -0
  20. package/augment-extensions/domain-rules/software-architecture/rules/modeling-documentation.md +1199 -0
  21. package/augment-extensions/domain-rules/software-architecture/rules/monolithic-architecture.md +351 -0
  22. package/augment-extensions/domain-rules/software-architecture/rules/principles.md +556 -0
  23. package/augment-extensions/domain-rules/software-architecture/rules/quality-attributes.md +797 -0
  24. package/augment-extensions/domain-rules/software-architecture/rules/scalability-performance.md +1345 -0
  25. package/augment-extensions/domain-rules/software-architecture/rules/security-architecture.md +1039 -0
  26. package/augment-extensions/domain-rules/software-architecture/rules/serverless-architecture.md +711 -0
  27. package/augment-extensions/domain-rules/software-architecture/rules/skills-development.md +568 -0
  28. package/augment-extensions/domain-rules/software-architecture/rules/tools-methodologies.md +961 -0
  29. package/augment-extensions/visual-design/CHANGELOG.md +132 -0
  30. package/augment-extensions/visual-design/README.md +255 -0
  31. package/augment-extensions/visual-design/__tests__/README.md +119 -0
  32. package/augment-extensions/visual-design/__tests__/style-selector.test.ts +172 -0
  33. package/augment-extensions/visual-design/__tests__/vendor-styles.test.ts +214 -0
  34. package/augment-extensions/visual-design/domains/other/ai-prompt-helper.ts +157 -0
  35. package/augment-extensions/visual-design/domains/other/dotnet-application.ts +156 -0
  36. package/augment-extensions/visual-design/domains/other/linux-platform.ts +156 -0
  37. package/augment-extensions/visual-design/domains/other/mobile-application.ts +157 -0
  38. package/augment-extensions/visual-design/domains/other/motion-picture.ts +156 -0
  39. package/augment-extensions/visual-design/domains/other/os-application.ts +156 -0
  40. package/augment-extensions/visual-design/domains/other/print-campaigns.ts +158 -0
  41. package/augment-extensions/visual-design/domains/other/web-app.ts +157 -0
  42. package/augment-extensions/visual-design/domains/other/website.ts +161 -0
  43. package/augment-extensions/visual-design/domains/other/windows-platform.ts +156 -0
  44. package/augment-extensions/visual-design/domains/web-page-styles/amazon-cloudscape.ts +506 -0
  45. package/augment-extensions/visual-design/domains/web-page-styles/google-modern.ts +615 -0
  46. package/augment-extensions/visual-design/domains/web-page-styles/microsoft-fluent.ts +531 -0
  47. package/augment-extensions/visual-design/examples/README.md +97 -0
  48. package/augment-extensions/visual-design/examples/ai-prompt-generation.md +233 -0
  49. package/augment-extensions/visual-design/examples/basic-usage.md +216 -0
  50. package/augment-extensions/visual-design/examples/domain-workflows.md +257 -0
  51. package/augment-extensions/visual-design/examples/vendor-comparison.md +247 -0
  52. package/augment-extensions/visual-design/module.json +78 -0
  53. package/augment-extensions/visual-design/style-selector.ts +177 -0
  54. package/augment-extensions/visual-design/types.ts +302 -0
  55. package/augment-extensions/visual-design/visual-design-core.ts +469 -0
  56. package/augment-extensions/workflows/adr-support/README.md +227 -0
  57. package/augment-extensions/workflows/adr-support/__tests__/adr-validator.test.ts +203 -0
  58. package/augment-extensions/workflows/adr-support/adr-validator.ts +162 -0
  59. package/augment-extensions/workflows/adr-support/examples/complete-lifecycle-example.md +449 -0
  60. package/augment-extensions/workflows/adr-support/examples/integration-example.md +580 -0
  61. package/augment-extensions/workflows/adr-support/examples/superseding-example.md +436 -0
  62. package/augment-extensions/workflows/adr-support/module.json +112 -0
  63. package/augment-extensions/workflows/adr-support/rules/adr-creation.md +372 -0
  64. package/augment-extensions/workflows/adr-support/rules/beads-integration.md +443 -0
  65. package/augment-extensions/workflows/adr-support/rules/conflict-detection.md +486 -0
  66. package/augment-extensions/workflows/adr-support/rules/decision-detection.md +362 -0
  67. package/augment-extensions/workflows/adr-support/rules/lifecycle-management.md +427 -0
  68. package/augment-extensions/workflows/adr-support/rules/openspec-integration.md +465 -0
  69. package/augment-extensions/workflows/adr-support/rules/template-selection.md +405 -0
  70. package/augment-extensions/workflows/adr-support/rules/validation-rules.md +543 -0
  71. package/augment-extensions/workflows/adr-support/schemas/adr-config.json +191 -0
  72. package/augment-extensions/workflows/adr-support/schemas/adr-metadata.json +172 -0
  73. package/augment-extensions/workflows/adr-support/templates/business-case.md +235 -0
  74. package/augment-extensions/workflows/adr-support/templates/madr-elaborate.md +197 -0
  75. package/augment-extensions/workflows/adr-support/templates/madr-simple.md +68 -0
  76. package/augment-extensions/workflows/adr-support/templates/nygard.md +84 -0
  77. package/augment-extensions/workflows/beads/rules/workflow.md +1 -1
  78. package/cli/dist/utils/__tests__/adr-validator.example.d.ts +6 -0
  79. package/cli/dist/utils/__tests__/adr-validator.example.d.ts.map +1 -0
  80. package/cli/dist/utils/__tests__/adr-validator.example.js +148 -0
  81. package/cli/dist/utils/__tests__/adr-validator.example.js.map +1 -0
  82. package/cli/dist/utils/adr-validator.d.ts +65 -0
  83. package/cli/dist/utils/adr-validator.d.ts.map +1 -0
  84. package/cli/dist/utils/adr-validator.js +203 -0
  85. package/cli/dist/utils/adr-validator.js.map +1 -0
  86. package/modules.md +40 -3
  87. package/package.json +1 -1
@@ -0,0 +1,957 @@
1
+ # Serverless Image Processing Pipeline Example
2
+
3
+ ## Overview
4
+
5
+ This document provides a comprehensive example of a serverless image processing pipeline built with AWS Lambda, S3, and event-driven architecture, focusing on scalability, cost-efficiency, and automatic scaling.
6
+
7
+ ---
8
+
9
+ ## System Context
10
+
11
+ ### Business Requirements
12
+
13
+ **Functional Requirements**
14
+ - Image upload and storage
15
+ - Automatic thumbnail generation (multiple sizes)
16
+ - Image optimization and compression
17
+ - Metadata extraction (EXIF, dimensions, format)
18
+ - Image format conversion (JPEG, PNG, WebP)
19
+ - Watermark application
20
+ - Face detection and tagging
21
+ - Content moderation (NSFW detection)
22
+ - Image search and retrieval
23
+
24
+ **Non-Functional Requirements**
25
+ - **Scalability**: Handle 1M+ images/day
26
+ - **Cost**: Pay-per-use, no idle costs
27
+ - **Latency**: < 5 seconds for thumbnail generation
28
+ - **Availability**: 99.9% uptime
29
+ - **Storage**: Unlimited image storage
30
+ - **Security**: Encrypted storage, signed URLs
31
+
32
+ ### Use Cases
33
+
34
+ - **Social Media Platform**: User profile pictures, photo uploads
35
+ - **E-Commerce**: Product images, multiple sizes for responsive design
36
+ - **Content Management**: Media library, automatic optimization
37
+ - **Real Estate**: Property photos, virtual tours
38
+
39
+ ---
40
+
41
+ ## Architecture Overview
42
+
43
+ ### High-Level Architecture
44
+
45
+ ```
46
+ ┌─────────────────────────────────────────────────────────────┐
47
+ │ Serverless Image Processing Pipeline │
48
+ ├─────────────────────────────────────────────────────────────┤
49
+ │ │
50
+ │ User Upload → API Gateway → Lambda (Upload) → S3 (Original) │
51
+ │ ↓ │
52
+ │ S3 Event Trigger │
53
+ │ ↓ │
54
+ │ Lambda (Process Image) │
55
+ │ ↓ │
56
+ │ ┌─────────────────────────┴─────┐ │
57
+ │ ↓ ↓ │
58
+ │ Lambda (Thumbnail) Lambda (Metadata) │
59
+ │ ↓ ↓ │
60
+ │ S3 (Thumbnails) DynamoDB │
61
+ │ │
62
+ └─────────────────────────────────────────────────────────────┘
63
+ ```
64
+
65
+ ### Event Flow
66
+
67
+ ```
68
+ 1. Upload Flow
69
+ User → API Gateway → Lambda → S3 → S3 Event → Lambda (Process)
70
+
71
+ 2. Processing Flow
72
+ S3 Event → Lambda → [Thumbnail, Optimize, Metadata, Moderation]
73
+
74
+ 3. Retrieval Flow
75
+ User → API Gateway → Lambda → S3 (Signed URL) → User
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Service Architecture
81
+
82
+ ### Lambda Functions
83
+
84
+ **1. Upload Handler**
85
+ - Validate image file (type, size)
86
+ - Generate unique filename
87
+ - Upload to S3 original bucket
88
+ - Return upload confirmation
89
+
90
+ **2. Image Processor (Orchestrator)**
91
+ - Triggered by S3 event
92
+ - Invoke parallel processing functions
93
+ - Coordinate workflow
94
+
95
+ **3. Thumbnail Generator**
96
+ - Generate multiple thumbnail sizes (150x150, 300x300, 600x600)
97
+ - Maintain aspect ratio
98
+ - Upload to S3 thumbnails bucket
99
+
100
+ **4. Image Optimizer**
101
+ - Compress images (reduce file size)
102
+ - Convert to WebP format
103
+ - Optimize for web delivery
104
+
105
+ **5. Metadata Extractor**
106
+ - Extract EXIF data (camera, location, timestamp)
107
+ - Calculate image dimensions
108
+ - Store metadata in DynamoDB
109
+
110
+ **6. Content Moderator**
111
+ - Detect NSFW content (AWS Rekognition)
112
+ - Flag inappropriate images
113
+ - Send notification if flagged
114
+
115
+ **7. Face Detector**
116
+ - Detect faces in images
117
+ - Extract face bounding boxes
118
+ - Store face data for search
119
+
120
+ ---
121
+
122
+ ## Technology Stack
123
+
124
+ ### AWS Services
125
+ - **Compute**: AWS Lambda (Node.js, Python)
126
+ - **Storage**: S3 (original, thumbnails, optimized)
127
+ - **Database**: DynamoDB (metadata, image index)
128
+ - **API**: API Gateway (REST API)
129
+ - **AI/ML**: AWS Rekognition (face detection, content moderation)
130
+ - **Messaging**: SNS (notifications), SQS (dead letter queue)
131
+ - **CDN**: CloudFront (image delivery)
132
+ - **Security**: IAM, KMS (encryption)
133
+
134
+ ### Libraries
135
+ - **Image Processing**: Sharp (Node.js), Pillow (Python)
136
+ - **Format Conversion**: ImageMagick
137
+ - **Metadata**: ExifTool
138
+
139
+ ### Infrastructure as Code
140
+ - **IaC**: AWS SAM (Serverless Application Model)
141
+ - **CI/CD**: AWS CodePipeline, CodeBuild
142
+ - **Monitoring**: CloudWatch, X-Ray
143
+
144
+ ---
145
+
146
+ ## Implementation Details
147
+
148
+ ### 1. Upload Handler Lambda
149
+
150
+ **API Gateway Integration**
151
+ ```
152
+
153
+ ### 2. Thumbnail Generator Lambda
154
+
155
+ **S3 Event-Triggered Processing**
156
+
157
+ ```javascript
158
+ // thumbnail-generator/index.js
159
+ const AWS = require('aws-sdk');
160
+ const sharp = require('sharp');
161
+ const s3 = new AWS.S3();
162
+
163
+ const THUMBNAIL_SIZES = [
164
+ { name: 'small', width: 150, height: 150 },
165
+ { name: 'medium', width: 300, height: 300 },
166
+ { name: 'large', width: 600, height: 600 }
167
+ ];
168
+
169
+ exports.handler = async (event) => {
170
+ // Get S3 event details
171
+ const record = event.Records[0];
172
+ const bucket = record.s3.bucket.name;
173
+ const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
174
+
175
+ try {
176
+ // Download original image from S3
177
+ const originalImage = await s3.getObject({
178
+ Bucket: bucket,
179
+ Key: key
180
+ }).promise();
181
+
182
+ // Generate thumbnails in parallel
183
+ const thumbnailPromises = THUMBNAIL_SIZES.map(async (size) => {
184
+ // Resize image using Sharp
185
+ const thumbnail = await sharp(originalImage.Body)
186
+ .resize(size.width, size.height, {
187
+ fit: 'inside',
188
+ withoutEnlargement: true
189
+ })
190
+ .jpeg({ quality: 80 })
191
+ .toBuffer();
192
+
193
+ // Upload thumbnail to S3
194
+ const thumbnailKey = key.replace('original/', `thumbnails/${size.name}/`);
195
+
196
+ await s3.putObject({
197
+ Bucket: process.env.THUMBNAIL_BUCKET,
198
+ Key: thumbnailKey,
199
+ Body: thumbnail,
200
+ ContentType: 'image/jpeg',
201
+ CacheControl: 'max-age=31536000' // 1 year
202
+ }).promise();
203
+
204
+ return {
205
+ size: size.name,
206
+ key: thumbnailKey,
207
+ width: size.width,
208
+ height: size.height
209
+ };
210
+ });
211
+
212
+ const thumbnails = await Promise.all(thumbnailPromises);
213
+
214
+ console.log('Thumbnails generated:', thumbnails);
215
+
216
+ return {
217
+ statusCode: 200,
218
+ body: JSON.stringify({ thumbnails })
219
+ };
220
+ } catch (error) {
221
+ console.error('Thumbnail generation error:', error);
222
+ throw error;
223
+ }
224
+ };
225
+ ```
226
+
227
+ ### 3. Metadata Extractor Lambda
228
+
229
+ **Extract and Store Image Metadata**
230
+
231
+ ```javascript
232
+ // metadata-extractor/index.js
233
+ const AWS = require('aws-sdk');
234
+ const sharp = require('sharp');
235
+ const ExifParser = require('exif-parser');
236
+ const s3 = new AWS.S3();
237
+ const dynamodb = new AWS.DynamoDB.DocumentClient();
238
+
239
+ exports.handler = async (event) => {
240
+ const record = event.Records[0];
241
+ const bucket = record.s3.bucket.name;
242
+ const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
243
+
244
+ try {
245
+ // Download image
246
+ const image = await s3.getObject({
247
+ Bucket: bucket,
248
+ Key: key
249
+ }).promise();
250
+
251
+ // Extract image metadata using Sharp
252
+ const metadata = await sharp(image.Body).metadata();
253
+
254
+ // Extract EXIF data
255
+ let exifData = {};
256
+ try {
257
+ const parser = ExifParser.create(image.Body);
258
+ const result = parser.parse();
259
+ exifData = result.tags;
260
+ } catch (e) {
261
+ console.log('No EXIF data found');
262
+ }
263
+
264
+ // Extract image ID from key
265
+ const imageId = key.split('/').pop().split('.')[0];
266
+
267
+ // Prepare metadata document
268
+ const metadataDoc = {
269
+ imageId,
270
+ key,
271
+ bucket,
272
+ format: metadata.format,
273
+ width: metadata.width,
274
+ height: metadata.height,
275
+ size: image.ContentLength,
276
+ hasAlpha: metadata.hasAlpha,
277
+ orientation: metadata.orientation,
278
+ exif: {
279
+ make: exifData.Make,
280
+ model: exifData.Model,
281
+ dateTime: exifData.DateTime,
282
+ gps: {
283
+ latitude: exifData.GPSLatitude,
284
+ longitude: exifData.GPSLongitude
285
+ }
286
+ },
287
+ createdAt: new Date().toISOString()
288
+ };
289
+
290
+ // Store metadata in DynamoDB
291
+ await dynamodb.put({
292
+ TableName: process.env.METADATA_TABLE,
293
+ Item: metadataDoc
294
+ }).promise();
295
+
296
+ console.log('Metadata stored:', metadataDoc);
297
+
298
+ return {
299
+ statusCode: 200,
300
+ body: JSON.stringify({ metadata: metadataDoc })
301
+ };
302
+ } catch (error) {
303
+ console.error('Metadata extraction error:', error);
304
+ throw error;
305
+ }
306
+ };
307
+ ```
308
+
309
+ ### 4. Image Optimizer Lambda
310
+
311
+ **Optimize and Convert Images**
312
+
313
+ ```javascript
314
+ // image-optimizer/index.js
315
+ const AWS = require('aws-sdk');
316
+ const sharp = require('sharp');
317
+ const s3 = new AWS.S3();
318
+
319
+ exports.handler = async (event) => {
320
+ const record = event.Records[0];
321
+ const bucket = record.s3.bucket.name;
322
+ const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
323
+
324
+ try {
325
+ // Download original image
326
+ const originalImage = await s3.getObject({
327
+ Bucket: bucket,
328
+ Key: key
329
+ }).promise();
330
+
331
+ // Optimize JPEG
332
+ const optimizedJpeg = await sharp(originalImage.Body)
333
+ .jpeg({
334
+ quality: 85,
335
+ progressive: true,
336
+ mozjpeg: true
337
+ })
338
+ .toBuffer();
339
+
340
+ // Convert to WebP (modern format, better compression)
341
+ const webpImage = await sharp(originalImage.Body)
342
+ .webp({
343
+ quality: 85,
344
+ effort: 6
345
+ })
346
+ .toBuffer();
347
+
348
+ // Upload optimized JPEG
349
+ const jpegKey = key.replace('original/', 'optimized/jpeg/');
350
+ await s3.putObject({
351
+ Bucket: process.env.OPTIMIZED_BUCKET,
352
+ Key: jpegKey,
353
+ Body: optimizedJpeg,
354
+ ContentType: 'image/jpeg',
355
+ CacheControl: 'max-age=31536000'
356
+ }).promise();
357
+
358
+ // Upload WebP version
359
+ const webpKey = key.replace('original/', 'optimized/webp/').replace(/\.(jpg|jpeg|png)$/, '.webp');
360
+ await s3.putObject({
361
+ Bucket: process.env.OPTIMIZED_BUCKET,
362
+ Key: webpKey,
363
+ Body: webpImage,
364
+ ContentType: 'image/webp',
365
+ CacheControl: 'max-age=31536000'
366
+ }).promise();
367
+
368
+ // Calculate compression ratio
369
+ const originalSize = originalImage.ContentLength;
370
+ const jpegSize = optimizedJpeg.length;
371
+ const webpSize = webpImage.length;
372
+
373
+ console.log('Optimization complete:', {
374
+ originalSize,
375
+ jpegSize,
376
+ webpSize,
377
+ jpegSavings: ((originalSize - jpegSize) / originalSize * 100).toFixed(2) + '%',
378
+ webpSavings: ((originalSize - webpSize) / originalSize * 100).toFixed(2) + '%'
379
+ });
380
+
381
+ return {
382
+ statusCode: 200,
383
+ body: JSON.stringify({
384
+ jpegKey,
385
+ webpKey,
386
+ originalSize,
387
+ jpegSize,
388
+ webpSize
389
+ })
390
+ };
391
+ } catch (error) {
392
+ console.error('Optimization error:', error);
393
+ throw error;
394
+ }
395
+ };
396
+ ```
397
+
398
+ ### 5. Content Moderator Lambda
399
+
400
+ **AI-Powered Content Moderation**
401
+
402
+ ```javascript
403
+ // content-moderator/index.js
404
+ const AWS = require('aws-sdk');
405
+ const rekognition = new AWS.Rekognition();
406
+ const sns = new AWS.SNS();
407
+ const dynamodb = new AWS.DynamoDB.DocumentClient();
408
+
409
+ exports.handler = async (event) => {
410
+ const record = event.Records[0];
411
+ const bucket = record.s3.bucket.name;
412
+ const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
413
+
414
+ try {
415
+ // Detect inappropriate content using AWS Rekognition
416
+ const moderationResult = await rekognition.detectModerationLabels({
417
+ Image: {
418
+ S3Object: {
419
+ Bucket: bucket,
420
+ Name: key
421
+ }
422
+ },
423
+ MinConfidence: 75
424
+ }).promise();
425
+
426
+ const imageId = key.split('/').pop().split('.')[0];
427
+
428
+ // Check for inappropriate content
429
+ const inappropriateLabels = moderationResult.ModerationLabels.filter(
430
+ label => label.Confidence > 80
431
+ );
432
+
433
+ const isFlagged = inappropriateLabels.length > 0;
434
+
435
+ // Update DynamoDB with moderation results
436
+ await dynamodb.update({
437
+ TableName: process.env.METADATA_TABLE,
438
+ Key: { imageId },
439
+ UpdateExpression: 'SET moderation = :moderation, isFlagged = :isFlagged',
440
+ ExpressionAttributeValues: {
441
+ ':moderation': {
442
+ labels: inappropriateLabels,
443
+ checkedAt: new Date().toISOString()
444
+ },
445
+ ':isFlagged': isFlagged
446
+ }
447
+ }).promise();
448
+
449
+ // Send notification if flagged
450
+ if (isFlagged) {
451
+ await sns.publish({
452
+ TopicArn: process.env.ALERT_TOPIC_ARN,
453
+ Subject: 'Inappropriate Content Detected',
454
+ Message: JSON.stringify({
455
+ imageId,
456
+ key,
457
+ labels: inappropriateLabels
458
+ })
459
+ }).promise();
460
+ }
461
+
462
+ console.log('Moderation complete:', {
463
+ imageId,
464
+ isFlagged,
465
+ labels: inappropriateLabels
466
+ });
467
+
468
+ return {
469
+ statusCode: 200,
470
+ body: JSON.stringify({
471
+ imageId,
472
+ isFlagged,
473
+ labels: inappropriateLabels
474
+ })
475
+ };
476
+ } catch (error) {
477
+ console.error('Moderation error:', error);
478
+ throw error;
479
+ }
480
+ };
481
+ ```
482
+
483
+ ---
484
+
485
+ ## Infrastructure as Code (AWS SAM)
486
+
487
+ ### SAM Template
488
+
489
+ ```yaml
490
+ # template.yaml
491
+ AWSTemplateFormatVersion: '2010-09-09'
492
+ Transform: AWS::Serverless-2016-10-31
493
+ Description: Serverless Image Processing Pipeline
494
+
495
+ Globals:
496
+ Function:
497
+ Timeout: 30
498
+ MemorySize: 1024
499
+ Runtime: nodejs18.x
500
+ Environment:
501
+ Variables:
502
+ ORIGINAL_BUCKET: !Ref OriginalBucket
503
+ THUMBNAIL_BUCKET: !Ref ThumbnailBucket
504
+ OPTIMIZED_BUCKET: !Ref OptimizedBucket
505
+ METADATA_TABLE: !Ref MetadataTable
506
+
507
+ Resources:
508
+ # S3 Buckets
509
+ OriginalBucket:
510
+ Type: AWS::S3::Bucket
511
+ Properties:
512
+ BucketName: !Sub '${AWS::StackName}-original'
513
+ VersioningConfiguration:
514
+ Status: Enabled
515
+ LifecycleConfiguration:
516
+ Rules:
517
+ - Id: DeleteOldVersions
518
+ Status: Enabled
519
+ NoncurrentVersionExpirationInDays: 30
520
+
521
+ ThumbnailBucket:
522
+ Type: AWS::S3::Bucket
523
+ Properties:
524
+ BucketName: !Sub '${AWS::StackName}-thumbnails'
525
+
526
+ OptimizedBucket:
527
+ Type: AWS::S3::Bucket
528
+ Properties:
529
+ BucketName: !Sub '${AWS::StackName}-optimized'
530
+
531
+ # DynamoDB Table
532
+ MetadataTable:
533
+ Type: AWS::DynamoDB::Table
534
+ Properties:
535
+ TableName: !Sub '${AWS::StackName}-metadata'
536
+ BillingMode: PAY_PER_REQUEST
537
+ AttributeDefinitions:
538
+ - AttributeName: imageId
539
+ AttributeType: S
540
+ KeySchema:
541
+ - AttributeName: imageId
542
+ KeyType: HASH
543
+
544
+ # Lambda Functions
545
+ UploadFunction:
546
+ Type: AWS::Serverless::Function
547
+ Properties:
548
+ CodeUri: upload-handler/
549
+ Handler: index.handler
550
+ Events:
551
+ UploadApi:
552
+ Type: Api
553
+ Properties:
554
+ Path: /upload
555
+ Method: post
556
+ Policies:
557
+ - S3WritePolicy:
558
+ BucketName: !Ref OriginalBucket
559
+
560
+ ThumbnailFunction:
561
+ Type: AWS::Serverless::Function
562
+ Properties:
563
+ CodeUri: thumbnail-generator/
564
+ Handler: index.handler
565
+ MemorySize: 2048 # More memory for image processing
566
+ Timeout: 60
567
+ Events:
568
+ S3Event:
569
+ Type: S3
570
+ Properties:
571
+ Bucket: !Ref OriginalBucket
572
+ Events: s3:ObjectCreated:*
573
+ Filter:
574
+ S3Key:
575
+ Rules:
576
+ - Name: prefix
577
+ Value: original/
578
+ Policies:
579
+ - S3ReadPolicy:
580
+ BucketName: !Ref OriginalBucket
581
+ - S3WritePolicy:
582
+ BucketName: !Ref ThumbnailBucket
583
+
584
+ MetadataFunction:
585
+ Type: AWS::Serverless::Function
586
+ Properties:
587
+ CodeUri: metadata-extractor/
588
+ Handler: index.handler
589
+ Events:
590
+ S3Event:
591
+ Type: S3
592
+ Properties:
593
+ Bucket: !Ref OriginalBucket
594
+ Events: s3:ObjectCreated:*
595
+ Policies:
596
+ - S3ReadPolicy:
597
+ BucketName: !Ref OriginalBucket
598
+ - DynamoDBWritePolicy:
599
+ TableName: !Ref MetadataTable
600
+
601
+ OptimizerFunction:
602
+ Type: AWS::Serverless::Function
603
+ Properties:
604
+ CodeUri: image-optimizer/
605
+ Handler: index.handler
606
+ MemorySize: 2048
607
+ Timeout: 60
608
+ Events:
609
+ S3Event:
610
+ Type: S3
611
+ Properties:
612
+ Bucket: !Ref OriginalBucket
613
+ Events: s3:ObjectCreated:*
614
+ Policies:
615
+ - S3ReadPolicy:
616
+ BucketName: !Ref OriginalBucket
617
+ - S3WritePolicy:
618
+ BucketName: !Ref OptimizedBucket
619
+
620
+ ModeratorFunction:
621
+ Type: AWS::Serverless::Function
622
+ Properties:
623
+ CodeUri: content-moderator/
624
+ Handler: index.handler
625
+ Events:
626
+ S3Event:
627
+ Type: S3
628
+ Properties:
629
+ Bucket: !Ref OriginalBucket
630
+ Events: s3:ObjectCreated:*
631
+ Policies:
632
+ - S3ReadPolicy:
633
+ BucketName: !Ref OriginalBucket
634
+ - DynamoDBWritePolicy:
635
+ TableName: !Ref MetadataTable
636
+ - RekognitionDetectOnlyPolicy: {}
637
+ - SNSPublishMessagePolicy:
638
+ TopicName: !GetAtt AlertTopic.TopicName
639
+
640
+ # SNS Topic for Alerts
641
+ AlertTopic:
642
+ Type: AWS::SNS::Topic
643
+ Properties:
644
+ TopicName: !Sub '${AWS::StackName}-alerts'
645
+
646
+ Outputs:
647
+ UploadApiUrl:
648
+ Description: API Gateway endpoint URL for upload
649
+ Value: !Sub 'https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/upload/'
650
+
651
+ OriginalBucketName:
652
+ Description: S3 bucket for original images
653
+ Value: !Ref OriginalBucket
654
+
655
+ MetadataTableName:
656
+ Description: DynamoDB table for metadata
657
+ Value: !Ref MetadataTable
658
+ ```
659
+
660
+ ---
661
+
662
+ ## Cost Optimization
663
+
664
+ ### Lambda Cost Optimization
665
+
666
+ **1. Right-Size Memory**
667
+ ```javascript
668
+ // Use AWS Lambda Power Tuning to find optimal memory
669
+ // Higher memory = faster execution = lower cost (sometimes)
670
+ // Example: 1024MB @ 500ms vs 512MB @ 1000ms (same cost, faster response)
671
+ ```
672
+
673
+ **2. Reduce Cold Starts**
674
+ ```javascript
675
+ // Keep functions warm with scheduled pings (if needed)
676
+ // Use provisioned concurrency for critical functions
677
+ // Minimize dependencies (smaller deployment package)
678
+ ```
679
+
680
+ **3. Batch Processing**
681
+ ```javascript
682
+ // Process multiple images in one invocation (if possible)
683
+ // Use S3 Batch Operations for bulk processing
684
+ ```
685
+
686
+ ### S3 Cost Optimization
687
+
688
+ **1. Lifecycle Policies**
689
+ ```yaml
690
+ # Move old images to cheaper storage classes
691
+ LifecycleConfiguration:
692
+ Rules:
693
+ - Id: MoveToIA
694
+ Status: Enabled
695
+ Transitions:
696
+ - Days: 30
697
+ StorageClass: STANDARD_IA # Infrequent Access
698
+ - Days: 90
699
+ StorageClass: GLACIER # Archive
700
+ ```
701
+
702
+ **2. Intelligent Tiering**
703
+ - Automatically moves objects between access tiers
704
+ - Optimizes costs based on access patterns
705
+
706
+ ### Cost Metrics
707
+
708
+ **Monthly Cost Estimate (1M images/month)**
709
+
710
+ - **Lambda**: $50 (1M invocations × 5 functions × 1s avg × $0.0000166667/GB-second)
711
+ - **S3 Storage**: $100 (500GB × $0.023/GB)
712
+ - **S3 Requests**: $5 (5M PUT/GET requests)
713
+ - **DynamoDB**: $25 (1M writes, 5M reads)
714
+ - **Rekognition**: $100 (1M images × $0.001/image)
715
+ - **Data Transfer**: $20 (200GB out)
716
+
717
+ **Total**: ~$300/month for 1M images
718
+
719
+ **Comparison to EC2**:
720
+ - EC2 (t3.large 24/7): $60/month + EBS + ALB = ~$100/month
721
+ - But: No auto-scaling, manual management, idle costs
722
+
723
+ ---
724
+
725
+ ## Monitoring and Observability
726
+
727
+ ### CloudWatch Metrics
728
+
729
+ **Lambda Metrics**
730
+ ```javascript
731
+ // Custom metrics
732
+ const AWS = require('aws-sdk');
733
+ const cloudwatch = new AWS.CloudWatch();
734
+
735
+ async function publishMetric(metricName, value, unit = 'Count') {
736
+ await cloudwatch.putMetricData({
737
+ Namespace: 'ImageProcessing',
738
+ MetricData: [{
739
+ MetricName: metricName,
740
+ Value: value,
741
+ Unit: unit,
742
+ Timestamp: new Date()
743
+ }]
744
+ }).promise();
745
+ }
746
+
747
+ // Usage
748
+ await publishMetric('ThumbnailsGenerated', 3);
749
+ await publishMetric('ImageSizeReduction', 45, 'Percent');
750
+ ```
751
+
752
+ **Key Metrics to Monitor**
753
+ - Lambda invocations, duration, errors, throttles
754
+ - S3 bucket size, request count
755
+ - DynamoDB read/write capacity
756
+ - API Gateway latency, 4xx/5xx errors
757
+
758
+ ### X-Ray Tracing
759
+
760
+ **Enable Distributed Tracing**
761
+ ```javascript
762
+ const AWSXRay = require('aws-xray-sdk-core');
763
+ const AWS = AWSXRay.captureAWS(require('aws-sdk'));
764
+
765
+ // Trace subsegments
766
+ exports.handler = async (event) => {
767
+ const segment = AWSXRay.getSegment();
768
+
769
+ const subsegment = segment.addNewSubsegment('ImageProcessing');
770
+ try {
771
+ // Process image
772
+ await processImage(event);
773
+ subsegment.close();
774
+ } catch (error) {
775
+ subsegment.addError(error);
776
+ subsegment.close();
777
+ throw error;
778
+ }
779
+ };
780
+ ```
781
+
782
+ ### Alarms
783
+
784
+ ```yaml
785
+ # CloudWatch Alarms
786
+ Alarms:
787
+ HighErrorRate:
788
+ Type: AWS::CloudWatch::Alarm
789
+ Properties:
790
+ AlarmName: ImageProcessing-HighErrorRate
791
+ MetricName: Errors
792
+ Namespace: AWS/Lambda
793
+ Statistic: Sum
794
+ Period: 300
795
+ EvaluationPeriods: 1
796
+ Threshold: 10
797
+ ComparisonOperator: GreaterThanThreshold
798
+ AlarmActions:
799
+ - !Ref AlertTopic
800
+
801
+ HighLatency:
802
+ Type: AWS::CloudWatch::Alarm
803
+ Properties:
804
+ AlarmName: ImageProcessing-HighLatency
805
+ MetricName: Duration
806
+ Namespace: AWS/Lambda
807
+ Statistic: Average
808
+ Period: 300
809
+ EvaluationPeriods: 2
810
+ Threshold: 5000 # 5 seconds
811
+ ComparisonOperator: GreaterThanThreshold
812
+ AlarmActions:
813
+ - !Ref AlertTopic
814
+ ```
815
+
816
+ ---
817
+
818
+ ## Security Best Practices
819
+
820
+ ### 1. Least Privilege IAM Policies
821
+
822
+ ```yaml
823
+ # Lambda execution role with minimal permissions
824
+ LambdaExecutionRole:
825
+ Type: AWS::IAM::Role
826
+ Properties:
827
+ AssumeRolePolicyDocument:
828
+ Version: '2012-10-17'
829
+ Statement:
830
+ - Effect: Allow
831
+ Principal:
832
+ Service: lambda.amazonaws.com
833
+ Action: sts:AssumeRole
834
+ ManagedPolicyArns:
835
+ - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
836
+ Policies:
837
+ - PolicyName: S3Access
838
+ PolicyDocument:
839
+ Version: '2012-10-17'
840
+ Statement:
841
+ - Effect: Allow
842
+ Action:
843
+ - s3:GetObject
844
+ Resource: !Sub '${OriginalBucket}/*'
845
+ - Effect: Allow
846
+ Action:
847
+ - s3:PutObject
848
+ Resource: !Sub '${ThumbnailBucket}/*'
849
+ ```
850
+
851
+ ### 2. Encryption
852
+
853
+ **S3 Encryption**
854
+ ```yaml
855
+ OriginalBucket:
856
+ Type: AWS::S3::Bucket
857
+ Properties:
858
+ BucketEncryption:
859
+ ServerSideEncryptionConfiguration:
860
+ - ServerSideEncryptionByDefault:
861
+ SSEAlgorithm: AES256 # or aws:kms for KMS
862
+ ```
863
+
864
+ **DynamoDB Encryption**
865
+ ```yaml
866
+ MetadataTable:
867
+ Type: AWS::DynamoDB::Table
868
+ Properties:
869
+ SSESpecification:
870
+ SSEEnabled: true
871
+ SSEType: KMS
872
+ KMSMasterKeyId: !Ref KMSKey
873
+ ```
874
+
875
+ ### 3. API Security
876
+
877
+ **API Gateway with API Key**
878
+ ```yaml
879
+ UploadApi:
880
+ Type: AWS::Serverless::Api
881
+ Properties:
882
+ StageName: Prod
883
+ Auth:
884
+ ApiKeyRequired: true
885
+ UsagePlan:
886
+ CreateUsagePlan: PER_API
887
+ Quota:
888
+ Limit: 10000
889
+ Period: DAY
890
+ Throttle:
891
+ BurstLimit: 100
892
+ RateLimit: 50
893
+ ```
894
+
895
+ ---
896
+
897
+ ## Key Takeaways
898
+
899
+ ### Architecture Decisions
900
+
901
+ 1. **Serverless Architecture**: No server management, automatic scaling, pay-per-use
902
+ 2. **Event-Driven Processing**: S3 events trigger Lambda functions automatically
903
+ 3. **Parallel Processing**: Multiple Lambda functions process images concurrently
904
+ 4. **Managed Services**: S3, DynamoDB, Rekognition reduce operational overhead
905
+ 5. **Infrastructure as Code**: AWS SAM for reproducible deployments
906
+
907
+ ### Trade-offs
908
+
909
+ **Benefits**
910
+ - ✅ Zero server management
911
+ - ✅ Automatic scaling (0 to millions)
912
+ - ✅ Pay only for actual usage
913
+ - ✅ Built-in high availability
914
+ - ✅ Fast time-to-market
915
+ - ✅ Reduced operational costs
916
+
917
+ **Challenges**
918
+ - ❌ Cold start latency (100-500ms)
919
+ - ❌ Execution time limits (15 min max)
920
+ - ❌ Vendor lock-in (AWS-specific)
921
+ - ❌ Debugging complexity (distributed system)
922
+ - ❌ Limited control over infrastructure
923
+
924
+ ### Performance Metrics
925
+
926
+ **Before Optimization**
927
+ - Processing time: 10 seconds/image
928
+ - Cost: $500/month (1M images)
929
+ - Cold start: 2 seconds
930
+
931
+ **After Optimization**
932
+ - Processing time: 3 seconds/image
933
+ - Cost: $300/month (1M images)
934
+ - Cold start: 500ms (optimized package size)
935
+
936
+ ### Lessons Learned
937
+
938
+ 1. **Optimize Lambda memory**: Higher memory = faster execution (sometimes cheaper)
939
+ 2. **Use S3 lifecycle policies**: Reduce storage costs for old images
940
+ 3. **Implement dead letter queues**: Catch failed processing
941
+ 4. **Monitor cold starts**: Use provisioned concurrency if needed
942
+ 5. **Batch operations**: Process multiple items when possible
943
+ 6. **Use CloudFront**: Cache images at edge for faster delivery
944
+
945
+ ---
946
+
947
+ ## References
948
+
949
+ - **AWS Lambda**: Serverless compute service
950
+ - **AWS SAM**: Serverless Application Model
951
+ - **Sharp**: High-performance Node.js image processing
952
+ - **AWS Rekognition**: AI-powered image analysis
953
+ - **AWS X-Ray**: Distributed tracing
954
+
955
+ ---
956
+
957
+ **Total Lines**: 957