@63klabs/cache-data 1.3.8 → 1.3.10

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.
package/AGENTS.md DELETED
@@ -1,1012 +0,0 @@
1
- # AI Development Context & Guidelines for This Repository
2
-
3
- This document provides essential context for AI coding assistants working within this repository.
4
-
5
- It outlines architectural principles, constraints, naming conventions, and deployment workflows.
6
-
7
- All code and infrastructure generated by AI must follow these standards.
8
-
9
- **CRITICAL**: This is an NPM package (@63klabs/cache-data) used by external applications. Backwards compatibility is paramount. Breaking changes require major version bumps and migration guides.
10
-
11
- ## 1. Purpose of This Repository
12
-
13
- This repository contains the **@63klabs/cache-data NPM package** - a distributed, serverless data caching solution for AWS Lambda Node.js functions. The package provides:
14
-
15
- - **Cache Module**: Distributed caching using DynamoDB and S3 with optional in-memory caching
16
- - **Endpoint Module**: HTTP/HTTPS request handling with built-in retry logic and caching
17
- - **Tools Module**: Logging, debugging, request handling, AWS integration, and utility functions
18
-
19
- This package is used in production environments handling over 1 million requests per week.
20
-
21
- ## 2. Critical Constraints
22
-
23
- ### 2.1 Backwards Compatibility (HIGHEST PRIORITY)
24
-
25
- **NEVER break backwards compatibility without explicit user approval and proper versioning.**
26
-
27
- - All public APIs must remain stable across minor and patch versions
28
- - Function signatures cannot change without deprecation warnings
29
- - Parameter names in JSDoc must match actual function parameters exactly
30
- - Default behaviors cannot change in ways that affect existing users
31
- - Environment variable names and behaviors must remain consistent
32
- - Exported classes, functions, and constants must maintain their interfaces
33
-
34
- **Before making ANY change to public APIs:**
35
- 1. Check if the function/class is exported in `src/index.js`
36
- 2. Search for usage in tests to understand expected behavior
37
- 3. Consider if existing applications would break
38
- 4. If breaking change is necessary, discuss with user first
39
-
40
- **Deprecation Process:**
41
- 1. Add `@deprecated` JSDoc tag with migration instructions
42
- 2. Log deprecation warnings when deprecated features are used
43
- 3. Update CHANGELOG.md with deprecation notice
44
- 4. Maintain deprecated functionality for at least one major version
45
- 5. Provide clear migration path in documentation
46
-
47
- ### 2.2 Semantic Versioning
48
-
49
- This package follows strict semantic versioning (semver):
50
-
51
- - **MAJOR** (x.0.0): Breaking changes, API changes, removed features
52
- - **MINOR** (1.x.0): New features, new APIs, backwards-compatible additions
53
- - **PATCH** (1.3.x): Bug fixes, documentation updates, internal improvements
54
-
55
- Current version: **1.3.6** (from package.json)
56
-
57
- **Version Bump Guidelines:**
58
- - Bug fixes that don't change behavior: PATCH
59
- - New optional parameters with defaults: MINOR
60
- - New classes or functions: MINOR
61
- - Changed function signatures: MAJOR
62
- - Removed or renamed exports: MAJOR
63
- - Changed default behaviors: MAJOR
64
-
65
- ### 2.3 Testing Requirements
66
-
67
- **ALL changes must include appropriate tests. No exceptions.**
68
-
69
- #### Test Types Required:
70
-
71
- 1. **Unit Tests** (Required for all new functions/classes)
72
- - Test specific examples and expected behavior
73
- - Test edge cases (null, undefined, empty, boundary values)
74
- - Test error conditions and error messages
75
- - Use descriptive test names
76
- - Located in `test/` directory matching source structure
77
-
78
- 2. **Property-Based Tests** (Required for core logic)
79
- - Test universal properties across many inputs
80
- - Use fast-check library for property generation
81
- - Validate invariants and mathematical properties
82
- - Located in `test/*/property/` directories
83
-
84
- 3. **Integration Tests** (Required for module interactions)
85
- - Test interactions between classes/modules
86
- - Test AWS service integrations (with mocks)
87
- - Test end-to-end workflows
88
- - Located in `test/*/integration/` directories
89
-
90
- #### Test Execution:
91
-
92
- ```bash
93
- # Run all tests
94
- npm test
95
-
96
- # Run specific test suites
97
- npm run test:cache
98
- npm run test:config
99
- npm run test:endpoint
100
- npm run test:logging
101
- npm run test:request
102
- npm run test:response
103
- npm run test:utils
104
- ```
105
-
106
- #### Test Requirements Before Merging:
107
-
108
- - [ ] All existing tests pass
109
- - [ ] New tests added for new functionality
110
- - [ ] Property-based tests added for core logic
111
- - [ ] Edge cases covered
112
- - [ ] Error conditions tested
113
- - [ ] No test coverage regression
114
- - [ ] Tests are deterministic (no flaky tests)
115
-
116
- **CRITICAL**: If tests fail, fix the code OR the test. Never ignore failing tests. Tests may reveal bugs in code - don't assume code is always correct.
117
-
118
- ### 2.4 Documentation Requirements
119
-
120
- **ALL public APIs must have complete JSDoc documentation.**
121
-
122
- See `.kiro/steering/documentation-standards.md` for complete documentation standards.
123
-
124
- #### Required JSDoc Tags:
125
-
126
- **For Functions/Methods:**
127
- - Description (no tag, just text)
128
- - `@param` for each parameter with type and description
129
- - `@returns` with type and description (omit only for void)
130
- - `@example` with at least one working code example
131
- - `@throws` for each error type that can be thrown
132
-
133
- **For Classes:**
134
- - Description of purpose and responsibilities
135
- - `@param` for constructor parameters
136
- - `@example` showing instantiation and common usage
137
- - `@property` for public properties
138
-
139
- #### Documentation Update Checklist:
140
-
141
- - [ ] JSDoc added/updated for all public APIs
142
- - [ ] Parameter names match function signatures exactly
143
- - [ ] Return types match actual return values
144
- - [ ] Examples are executable and correct
145
- - [ ] User documentation updated if behavior changed
146
- - [ ] CHANGELOG.md updated with user-facing changes
147
- - [ ] All documentation validation tests pass
148
-
149
- #### Run Documentation Validation:
150
-
151
- ```bash
152
- # Run all documentation tests
153
- npm test -- test/documentation/
154
-
155
- # Run documentation audit
156
- node scripts/audit-documentation.mjs
157
- ```
158
-
159
- **CRITICAL**: Documentation must be accurate. No hallucinations. Every documented feature must exist in the implementation.
160
-
161
- ## 3. Architecture and Code Organization
162
-
163
- ### 3.1 Module Structure
164
-
165
- The package is organized into three main modules:
166
-
167
- ```
168
- src/
169
- ├── index.js # Main entry point, exports tools, cache, endpoint
170
- ├── lib/
171
- │ ├── dao-cache.js # Cache module (S3Cache, DynamoDbCache, CacheData, Cache)
172
- │ ├── dao-endpoint.js # Endpoint module (Endpoint class, get function)
173
- │ ├── tools/ # Tools module
174
- │ │ ├── index.js # Tools entry point
175
- │ │ ├── AWS.classes.js # AWS SDK wrappers
176
- │ │ ├── APIRequest.class.js
177
- │ │ ├── ClientRequest.class.js
178
- │ │ ├── Response.class.js
179
- │ │ ├── ResponseDataModel.class.js
180
- │ │ ├── Timer.class.js
181
- │ │ ├── DebugAndLog.class.js
182
- │ │ ├── ImmutableObject.class.js
183
- │ │ ├── Connections.classes.js
184
- │ │ ├── CachedParametersSecrets.classes.js
185
- │ │ ├── RequestInfo.class.js
186
- │ │ ├── generic.response.*.js
187
- │ │ ├── utils.js
188
- │ │ └── vars.js
189
- │ └── utils/
190
- │ └── InMemoryCache.js
191
- ```
192
-
193
- ### 3.2 Separation of Concerns
194
-
195
- **CRITICAL**: Maintain clear separation between modules and classes.
196
-
197
- #### Cache Module (`dao-cache.js`):
198
- - **S3Cache**: Low-level S3 storage operations only
199
- - **DynamoDbCache**: Low-level DynamoDB storage operations only
200
- - **CacheData**: Cache management, encryption, expiration logic
201
- - **Cache**: Public API, cache profiles, configuration
202
-
203
- **DO NOT**:
204
- - Add endpoint logic to cache classes
205
- - Add cache logic to endpoint classes
206
- - Mix storage operations with business logic
207
- - Add AWS SDK calls outside of designated classes
208
-
209
- #### Endpoint Module (`dao-endpoint.js`):
210
- - **Endpoint**: HTTP request handling and response parsing
211
- - **get()**: Public API function
212
-
213
- **DO NOT**:
214
- - Add cache logic to endpoint classes
215
- - Add business logic to request handling
216
- - Mix concerns between modules
217
-
218
- #### Tools Module (`tools/`):
219
- - Each class has a single, well-defined responsibility
220
- - Utility functions are pure and stateless
221
- - AWS SDK wrappers isolate AWS-specific code
222
-
223
- **DO NOT**:
224
- - Create god classes with multiple responsibilities
225
- - Add business logic to utility functions
226
- - Mix AWS SDK versions (use v3 only)
227
-
228
- ### 3.3 Class Design Principles
229
-
230
- 1. **Single Responsibility**: Each class does one thing well
231
- 2. **Static vs Instance**: Use static for stateless operations, instance for stateful
232
- 3. **Initialization**: Static classes use `init()` method, called once at boot
233
- 4. **Private Fields**: Use `#` prefix for private static/instance fields
234
- 5. **Immutability**: Prefer immutable objects where possible
235
- 6. **Error Handling**: Always handle errors gracefully, log appropriately
236
-
237
- ### 3.4 Adding New Functionality
238
-
239
- **Before adding new methods or classes:**
240
-
241
- 1. **Check for existing functionality**
242
- - Search codebase for similar functionality
243
- - Check if existing classes can be extended
244
- - Avoid duplication at all costs
245
-
246
- 2. **Determine proper location**
247
- - Does it belong in cache, endpoint, or tools?
248
- - Is it a new class or method on existing class?
249
- - Should it be public or private?
250
-
251
- 3. **Follow existing patterns**
252
- - Match naming conventions
253
- - Use similar parameter structures
254
- - Follow error handling patterns
255
- - Maintain consistency with existing code
256
-
257
- 4. **Consider backwards compatibility**
258
- - Will this break existing code?
259
- - Can it be added without breaking changes?
260
- - Does it need a deprecation path?
261
-
262
- **Example: Adding a new cache method**
263
-
264
- ```javascript
265
- // GOOD: Follows existing patterns
266
- /**
267
- * Clear all expired cache entries from storage.
268
- *
269
- * @returns {Promise<{success: boolean, count: number}>} Result with count of cleared entries
270
- * @example
271
- * const result = await Cache.clearExpired();
272
- * console.log(`Cleared ${result.count} expired entries`);
273
- */
274
- static async clearExpired() {
275
- // Implementation
276
- }
277
-
278
- // BAD: Breaks patterns, unclear purpose
279
- static async doCleanup(opts) {
280
- // Implementation
281
- }
282
- ```
283
-
284
- ## 4. Code Quality Standards
285
-
286
- ### 4.1 Code Style
287
-
288
- - **Language**: JavaScript (Node.js >= 20.0.0)
289
- - **Indentation**: Tabs (not spaces)
290
- - **Quotes**: Double quotes for strings
291
- - **Semicolons**: Required
292
- - **Line Length**: Reasonable (no strict limit, but keep readable)
293
- - **Comments**: Use JSDoc for public APIs, inline comments for complex logic
294
-
295
- ### 4.2 Naming Conventions
296
-
297
- **Classes**: PascalCase
298
- ```javascript
299
- class CacheData { }
300
- class S3Cache { }
301
- class APIRequest { }
302
- ```
303
-
304
- **Functions/Methods**: camelCase
305
- ```javascript
306
- async function getData() { }
307
- static async read(idHash) { }
308
- ```
309
-
310
- **Constants**: UPPER_SNAKE_CASE
311
- ```javascript
312
- static PRIVATE = "private";
313
- static PUBLIC = "public";
314
- static STATUS_NO_CACHE = "original";
315
- ```
316
-
317
- **Private Fields**: # prefix
318
- ```javascript
319
- static #bucket = null;
320
- #syncedNowTimestampInSeconds = 0;
321
- ```
322
-
323
- **Parameters**: camelCase
324
- ```javascript
325
- function processData(idHash, syncedNow, bodyContent) { }
326
- ```
327
-
328
- ### 4.3 Error Handling
329
-
330
- **ALWAYS handle errors gracefully:**
331
-
332
- ```javascript
333
- // GOOD: Proper error handling
334
- try {
335
- const result = await someOperation();
336
- return result;
337
- } catch (error) {
338
- tools.DebugAndLog.error(`Operation failed: ${error?.message || 'Unknown error'}`, error?.stack);
339
- return defaultValue;
340
- }
341
-
342
- // BAD: Unhandled errors
343
- const result = await someOperation(); // Could throw
344
- ```
345
-
346
- **Error Logging:**
347
- - Use `tools.DebugAndLog.error()` for errors
348
- - Include context (what operation failed)
349
- - Include error message and stack trace
350
- - Return sensible defaults on error
351
-
352
- **Throwing Errors:**
353
- - Only throw for unrecoverable errors
354
- - Document with `@throws` JSDoc tag
355
- - Use descriptive error messages
356
- - Include context in error message
357
-
358
- ### 4.4 Performance Considerations
359
-
360
- This package is used in high-traffic Lambda functions. Performance matters.
361
-
362
- **DO**:
363
- - Minimize AWS SDK calls
364
- - Use Promise.all() for parallel operations
365
- - Cache expensive computations
366
- - Use in-memory cache when appropriate
367
- - Minimize JSON.stringify() calls (see existing specs)
368
-
369
- **DON'T**:
370
- - Make synchronous blocking calls
371
- - Create unnecessary objects in loops
372
- - Perform expensive operations in constructors
373
- - Make redundant AWS API calls
374
-
375
- ### 4.5 Security Considerations
376
-
377
- **CRITICAL**: This package handles sensitive data and encryption.
378
-
379
- **DO**:
380
- - Encrypt sensitive data using CacheData encryption
381
- - Use secure random for IVs and keys
382
- - Validate all inputs
383
- - Sanitize data before logging
384
- - Use environment variables for secrets (never hardcode)
385
-
386
- **DON'T**:
387
- - Log sensitive data (keys, passwords, PII)
388
- - Store unencrypted sensitive data
389
- - Trust user input without validation
390
- - Expose internal implementation details
391
-
392
- ## 5. Testing Strategy
393
-
394
- ### 5.1 Test Framework Migration
395
-
396
- **CRITICAL: Mocha to Jest Migration in Progress**
397
-
398
- This project is actively migrating from Mocha to Jest. During this transition period:
399
-
400
- **Migration Status:**
401
- - **Phase**: Active migration - both frameworks supported
402
- - **Legacy**: Mocha tests (`*-tests.mjs`) - maintain but don't create new
403
- - **Current**: Jest tests (`*.jest.mjs`) - all new tests must use this
404
- - **Goal**: Complete migration to Jest, remove Mocha dependency
405
-
406
- **File Naming Conventions:**
407
- - Mocha (legacy): `cache-tests.mjs`, `endpoint-tests.mjs`, `*-property-tests.mjs`
408
- - Jest (current): `cache-tests.jest.mjs`, `endpoint-tests.jest.mjs`, `*-property-tests.jest.mjs`
409
-
410
- **Test Execution Commands:**
411
- ```bash
412
- # Run Mocha tests only (legacy)
413
- npm test
414
-
415
- # Run Jest tests only (current)
416
- npm run test:jest
417
-
418
- # Run both test suites (REQUIRED for CI/CD)
419
- npm run test:all
420
-
421
- # Run specific test suites
422
- npm run test:cache # Mocha cache tests
423
- npm run test:cache:jest # Jest cache tests
424
- npm run test:endpoint # Mocha endpoint tests
425
- npm run test:endpoint:jest # Jest endpoint tests
426
- ```
427
-
428
- **Migration Guidelines:**
429
-
430
- 1. **Creating New Tests:**
431
- - ALWAYS use Jest (`*.jest.mjs` files)
432
- - Follow Jest patterns and assertions
433
- - Use Jest mocking (not Sinon)
434
- - Place in same directory as Mocha tests
435
-
436
- 2. **Modifying Existing Tests:**
437
- - If minor change: Update Mocha test
438
- - If major change: Consider migrating to Jest
439
- - If time permits: Migrate to Jest and delete Mocha version
440
-
441
- 3. **Test Coverage:**
442
- - Both test suites must pass in CI/CD
443
- - Jest coverage: `coverage-jest/` directory
444
- - Mocha coverage: `coverage/` directory (if generated)
445
-
446
- 4. **Property-Based Tests:**
447
- - Use fast-check in both Mocha and Jest
448
- - Same property definitions work in both frameworks
449
- - Migrate property tests to Jest when possible
450
-
451
- **Why Jest?**
452
- - Better ESM support
453
- - Built-in mocking (no Sinon needed)
454
- - Better async/await handling
455
- - More modern and actively maintained
456
- - Better IDE integration
457
- - Simpler configuration
458
-
459
- **Migration Checklist for Converting Tests:**
460
- - [ ] Create new `*.jest.mjs` file
461
- - [ ] Import from `@jest/globals` instead of `chai`
462
- - [ ] Change `expect().to.equal()` to `expect().toBe()`
463
- - [ ] Change `expect().to.not.equal()` to `expect().not.toBe()`
464
- - [ ] Replace Sinon mocks with Jest mocks
465
- - [ ] Update async test patterns if needed
466
- - [ ] Run Jest tests to verify: `npm run test:jest`
467
- - [ ] Delete old Mocha test file
468
- - [ ] Update any references in documentation
469
-
470
- ### 5.2 Test Organization
471
-
472
- Tests mirror source structure:
473
-
474
- ```
475
- test/
476
- ├── cache/ # Cache module tests
477
- │ ├── cache-tests.mjs (Mocha - legacy)
478
- │ ├── cache-tests.jest.mjs (Jest - new)
479
- │ ├── in-memory-cache/
480
- │ │ ├── unit/
481
- │ │ ├── integration/
482
- │ │ └── property/
483
- ├── config/ # Configuration tests
484
- ├── documentation/ # Documentation validation
485
- │ └── property/
486
- ├── endpoint/ # Endpoint module tests
487
- │ ├── endpoint-tests.mjs (Mocha - legacy)
488
- │ ├── endpoint-tests.jest.mjs (Jest - new)
489
- ├── logging/ # Logging tests
490
- ├── request/ # Request handling tests
491
- ├── response/ # Response tests
492
- ├── utils/ # Utility tests
493
- └── helpers/ # Test utilities
494
- ```
495
-
496
- **Note**: During migration, both `.mjs` (Mocha) and `.jest.mjs` (Jest) files coexist in the same directories.
497
-
498
- ### 5.3 Test Naming Conventions
499
-
500
- **Mocha (Legacy):**
501
- - Test files: `*-tests.mjs`
502
- - Property tests: `*-property-tests.mjs`
503
- - Integration tests: `*-integration-tests.mjs`
504
- - Unit tests: `*-unit-tests.mjs` or `*-tests.mjs`
505
-
506
- **Jest (Current - Use for All New Tests):**
507
- - Test files: `*.jest.mjs`
508
- - Property tests: `*-property-tests.jest.mjs`
509
- - Integration tests: `*-integration-tests.jest.mjs`
510
- - Unit tests: `*-unit-tests.jest.mjs` or `*.jest.mjs`
511
-
512
- ### 5.4 Test Framework
513
-
514
- **CRITICAL: Test Framework Migration in Progress**
515
-
516
- This project is currently migrating from Mocha to Jest. Both frameworks are supported during the transition period.
517
-
518
- **Current Status:**
519
- - **Legacy Tests**: Mocha tests (files ending in `-tests.mjs`)
520
- - **New Tests**: Jest tests (files ending in `.jest.mjs`)
521
- - **Migration Goal**: All tests will eventually be in Jest
522
-
523
- **Test Framework by Type:**
524
-
525
- **Mocha (Legacy - Being Phased Out):**
526
- - Test Runner: Mocha
527
- - Assertions: Chai (expect style)
528
- - Property Testing: fast-check
529
- - Mocking: Sinon
530
- - HTTP Testing: chai-http
531
- - File Pattern: `*-tests.mjs`
532
-
533
- **Jest (Current - All New Tests):**
534
- - Test Runner: Jest
535
- - Assertions: Jest built-in (expect)
536
- - Property Testing: fast-check (same as Mocha)
537
- - Mocking: Jest built-in
538
- - HTTP Testing: Jest with mocks
539
- - File Pattern: `*.jest.mjs`
540
-
541
- **Rules for Test Development:**
542
-
543
- 1. **ALL NEW TESTS MUST BE WRITTEN IN JEST** using the `*.jest.mjs` file pattern
544
- 2. **DO NOT create new Mocha tests** - only maintain existing ones
545
- 3. **When modifying existing tests**, consider migrating to Jest if time permits
546
- 4. **Both test suites must pass** before merging (`npm run test:all`)
547
- 5. **Jest tests coexist with Mocha tests** in the same directories
548
-
549
- **Test Execution:**
550
- ```bash
551
- # Run Mocha tests (legacy)
552
- npm test
553
-
554
- # Run Jest tests (new)
555
- npm run test:jest
556
-
557
- # Run both test suites (required for CI/CD)
558
- npm run test:all
559
- ```
560
-
561
- ### 5.5 Writing Good Tests
562
-
563
- **DO**:
564
- - Test one thing per test
565
- - Use descriptive test names
566
- - Test edge cases and error conditions
567
- - Make tests deterministic
568
- - Keep tests fast
569
- - Use property-based testing for core logic
570
- - **Write all new tests in Jest** (not Mocha)
571
-
572
- **DON'T**:
573
- - Test implementation details
574
- - Create flaky tests
575
- - Use real AWS services (mock them)
576
- - Make tests dependent on each other
577
- - Skip tests without good reason
578
- - **Create new Mocha tests** (migration in progress)
579
-
580
- **Example Test Structure (Jest - Use This for New Tests):**
581
-
582
- ```javascript
583
- import { describe, it, expect } from '@jest/globals';
584
- import { Cache } from '../src/lib/dao-cache.js';
585
-
586
- describe('Cache', () => {
587
- describe('generateIdHash()', () => {
588
- it('should generate consistent hash for same input', () => {
589
- const conn = { host: 'example.com', path: '/api' };
590
- const hash1 = Cache.generateIdHash(conn);
591
- const hash2 = Cache.generateIdHash(conn);
592
- expect(hash1).toBe(hash2);
593
- });
594
-
595
- it('should generate different hashes for different inputs', () => {
596
- const conn1 = { host: 'example.com', path: '/api' };
597
- const conn2 = { host: 'example.com', path: '/api2' };
598
- const hash1 = Cache.generateIdHash(conn1);
599
- const hash2 = Cache.generateIdHash(conn2);
600
- expect(hash1).not.toBe(hash2);
601
- });
602
-
603
- it('should handle null input gracefully', () => {
604
- expect(() => Cache.generateIdHash(null)).not.toThrow();
605
- });
606
- });
607
- });
608
- ```
609
-
610
- **Legacy Test Structure (Mocha - Maintain Only, Don't Create New):**
611
-
612
- ```javascript
613
- import { expect } from 'chai';
614
- import { Cache } from '../src/lib/dao-cache.js';
615
-
616
- describe('Cache', () => {
617
- describe('generateIdHash()', () => {
618
- it('should generate consistent hash for same input', () => {
619
- const conn = { host: 'example.com', path: '/api' };
620
- const hash1 = Cache.generateIdHash(conn);
621
- const hash2 = Cache.generateIdHash(conn);
622
- expect(hash1).to.equal(hash2);
623
- });
624
- });
625
- });
626
- ```
627
-
628
- ## 6. Kiro Steering Documents
629
-
630
- This repository uses Kiro for AI-assisted development. Steering documents provide additional context and rules.
631
-
632
- **Location**: `.kiro/steering/`
633
-
634
- **Available Steering Documents**:
635
-
636
- 1. **spec-naming-convention.md**: Spec directory naming rules
637
- - Format: `{version}-{feature-name}`
638
- - Version from package.json with dots replaced by hyphens
639
- - Example: `.kiro/specs/1-3-6-in-memory-cache/`
640
-
641
- 2. **documentation-standards.md**: Complete documentation standards
642
- - JSDoc requirements and templates
643
- - Documentation update process
644
- - Quality standards and validation
645
- - Common pitfalls and solutions
646
-
647
- **CRITICAL**: Always follow steering document rules. They take precedence over general guidelines.
648
-
649
- ## 7. Spec-Driven Development
650
-
651
- This project uses spec-driven development for new features.
652
-
653
- ### 7.1 Spec Structure
654
-
655
- Specs are located in `.kiro/specs/{version}-{feature-name}/`:
656
-
657
- - `requirements.md`: User stories and acceptance criteria
658
- - `design.md`: Technical design and correctness properties
659
- - `tasks.md`: Implementation task list
660
-
661
- ### 7.2 Spec Workflow
662
-
663
- 1. **Requirements**: Define what needs to be built
664
- 2. **Design**: Define how it will be built
665
- 3. **Tasks**: Break down into implementable tasks
666
- 4. **Implementation**: Execute tasks one at a time
667
- 5. **Testing**: Validate against correctness properties
668
-
669
- ### 7.3 Property-Based Testing in Specs
670
-
671
- Specs include correctness properties that must be validated:
672
-
673
- - Properties are formal specifications of behavior
674
- - Properties are tested using property-based testing
675
- - Properties must pass before feature is complete
676
- - Properties are linked to requirements
677
-
678
- **Example Property:**
679
-
680
- ```
681
- Property 1: Cache Hit Consistency
682
- For all valid cache keys and data:
683
- If data is written to cache with key K,
684
- Then reading from cache with key K returns the same data
685
- Until the expiration time is reached
686
- ```
687
-
688
- ## 8. Common Patterns and Anti-Patterns
689
-
690
- ### 8.1 Good Patterns
691
-
692
- **Initialization Pattern:**
693
- ```javascript
694
- class MyClass {
695
- static #initialized = false;
696
- static #config = null;
697
-
698
- static init(config) {
699
- if (this.#initialized) {
700
- tools.DebugAndLog.warn("Already initialized");
701
- return;
702
- }
703
- this.#config = config;
704
- this.#initialized = true;
705
- }
706
- }
707
- ```
708
-
709
- **Error Handling Pattern:**
710
- ```javascript
711
- static async operation() {
712
- return new Promise(async (resolve) => {
713
- try {
714
- const result = await doSomething();
715
- resolve(result);
716
- } catch (error) {
717
- tools.DebugAndLog.error(`Operation failed: ${error?.message}`, error?.stack);
718
- resolve(defaultValue);
719
- }
720
- });
721
- }
722
- ```
723
-
724
- **Configuration Pattern:**
725
- ```javascript
726
- static init(parameters) {
727
- this.#setting = parameters.setting ||
728
- process.env.ENV_VAR ||
729
- defaultValue;
730
- }
731
- ```
732
-
733
- ### 8.2 Anti-Patterns to Avoid
734
-
735
- **DON'T: Break backwards compatibility**
736
- ```javascript
737
- // BAD: Changed parameter order
738
- static write(body, idHash) { } // Was: write(idHash, body)
739
-
740
- // GOOD: Add new optional parameter at end
741
- static write(idHash, body, options = {}) { }
742
- ```
743
-
744
- **DON'T: Ignore errors**
745
- ```javascript
746
- // BAD: Silent failure
747
- try {
748
- await operation();
749
- } catch (error) {
750
- // Nothing
751
- }
752
-
753
- // GOOD: Log and handle
754
- try {
755
- await operation();
756
- } catch (error) {
757
- tools.DebugAndLog.error(`Failed: ${error?.message}`, error?.stack);
758
- return defaultValue;
759
- }
760
- ```
761
-
762
- **DON'T: Create god classes**
763
- ```javascript
764
- // BAD: Too many responsibilities
765
- class CacheAndEndpointAndLogging {
766
- cache() { }
767
- request() { }
768
- log() { }
769
- }
770
-
771
- // GOOD: Separate concerns
772
- class Cache { }
773
- class Endpoint { }
774
- class Logger { }
775
- ```
776
-
777
- **DON'T: Duplicate functionality**
778
- ```javascript
779
- // BAD: Reimplementing existing functionality
780
- function myHash(data) {
781
- // Custom hash implementation
782
- }
783
-
784
- // GOOD: Use existing functionality
785
- const hash = tools.hashThisData(data);
786
- ```
787
-
788
- ## 9. Deployment and Versioning
789
-
790
- ### 9.1 Release Process
791
-
792
- 1. Update version in `package.json`
793
- 2. Update `CHANGELOG.md` with changes
794
- 3. Run all tests: `npm test`
795
- 4. Run documentation validation
796
- 5. Commit changes
797
- 6. Create git tag: `git tag v1.3.6`
798
- 7. Push to npm: `npm publish`
799
-
800
- ### 9.2 Changelog Format
801
-
802
- Follow existing CHANGELOG.md format:
803
-
804
- ```markdown
805
- ## [1.3.6] - 2026-02-01
806
-
807
- ### Added
808
- - New feature description
809
-
810
- ### Changed
811
- - Changed behavior description
812
-
813
- ### Fixed
814
- - Bug fix description
815
-
816
- ### Deprecated
817
- - Deprecated feature with migration path
818
- ```
819
-
820
- ### 9.3 Breaking Changes
821
-
822
- **CRITICAL**: Breaking changes require major version bump.
823
-
824
- Breaking changes include:
825
- - Removed exports
826
- - Changed function signatures
827
- - Changed default behaviors
828
- - Removed or renamed parameters
829
- - Changed return types
830
- - Changed error behaviors
831
-
832
- **Process for breaking changes:**
833
- 1. Discuss with user first
834
- 2. Create migration guide
835
- 3. Update major version
836
- 4. Document in CHANGELOG.md
837
- 5. Update all documentation
838
- 6. Update all examples
839
-
840
- ## 10. AWS Integration
841
-
842
- ### 10.1 AWS Services Used
843
-
844
- - **S3**: Large object storage for cache
845
- - **DynamoDB**: Metadata and small object storage
846
- - **SSM Parameter Store**: Configuration and secrets
847
- - **Lambda**: Execution environment (Node.js >= 20.0.0)
848
-
849
- ### 10.2 AWS SDK Usage
850
-
851
- **CRITICAL**: Use AWS SDK v3 only. Do not mix v2 and v3.
852
-
853
- ```javascript
854
- // GOOD: Use tools.AWS wrapper
855
- const result = await tools.AWS.s3.get(params);
856
- const item = await tools.AWS.dynamo.get(params);
857
-
858
- // BAD: Direct SDK usage
859
- const s3 = new S3Client();
860
- ```
861
-
862
- ### 10.3 IAM Permissions Required
863
-
864
- Lambda execution role needs:
865
- - S3: GetObject, PutObject
866
- - DynamoDB: GetItem, PutItem
867
- - SSM: GetParameter, GetParameters, GetParametersByPath
868
-
869
- ## 11. Performance Optimization
870
-
871
- ### 11.1 Lambda Memory Allocation
872
-
873
- Recommended: 1024MB - 2048MB
874
- Minimum: 512MB
875
-
876
- See: `docs/lambda-optimization/README.md`
877
-
878
- ### 11.2 Cache Strategy
879
-
880
- - Use in-memory cache for hot data
881
- - Use DynamoDB for small items (< 10KB)
882
- - Use S3 for large items (> 10KB)
883
- - Set appropriate expiration times
884
- - Use interval-based expiration for predictable patterns
885
-
886
- ### 11.3 Optimization Techniques
887
-
888
- - Minimize JSON.stringify() calls
889
- - Use Promise.all() for parallel operations
890
- - Reuse connections and clients
891
- - Cache expensive computations
892
- - Use appropriate data structures
893
-
894
- ## 12. Troubleshooting
895
-
896
- ### 12.1 Common Issues
897
-
898
- **Issue**: Tests failing after changes
899
- - **Solution**: Check if backwards compatibility broken
900
- - **Solution**: Verify test expectations are correct
901
- - **Solution**: Check for race conditions
902
-
903
- **Issue**: Documentation validation failing
904
- - **Solution**: Ensure JSDoc matches implementation
905
- - **Solution**: Check parameter names match exactly
906
- - **Solution**: Verify examples are executable
907
-
908
- **Issue**: Performance degradation
909
- - **Solution**: Check for unnecessary AWS calls
910
- - **Solution**: Verify in-memory cache is enabled
911
- - **Solution**: Check Lambda memory allocation
912
-
913
- ### 12.2 Debugging
914
-
915
- Use `tools.DebugAndLog` for debugging:
916
-
917
- ```javascript
918
- tools.DebugAndLog.debug('Debug message', data);
919
- tools.DebugAndLog.info('Info message');
920
- tools.DebugAndLog.warn('Warning message');
921
- tools.DebugAndLog.error('Error message', error?.stack);
922
- ```
923
-
924
- Set log level via environment variable:
925
- ```bash
926
- DEBUG_MODE=true
927
- ```
928
-
929
- ## 13. Quick Reference
930
-
931
- ### 13.1 Before Making Changes
932
-
933
- - [ ] Read this AI_CONTEXT.md document
934
- - [ ] Review steering documents in `.kiro/steering/`
935
- - [ ] Check existing tests for expected behavior
936
- - [ ] Search codebase for similar functionality
937
- - [ ] Verify backwards compatibility impact
938
-
939
- ### 13.2 Before Committing
940
-
941
- - [ ] All tests pass: `npm test`
942
- - [ ] Documentation updated and validated
943
- - [ ] CHANGELOG.md updated
944
- - [ ] No breaking changes (or properly versioned)
945
- - [ ] Code follows style guidelines
946
- - [ ] Error handling is proper
947
- - [ ] Performance impact considered
948
-
949
- ### 13.3 Key Commands
950
-
951
- ```bash
952
- # Run all tests
953
- npm test
954
-
955
- # Run specific test suite
956
- npm run test:cache
957
- npm run test:endpoint
958
- npm run test:utils
959
-
960
- # Run documentation validation
961
- npm test -- test/documentation/
962
-
963
- # Run documentation audit
964
- node scripts/audit-documentation.mjs
965
- ```
966
-
967
- ### 13.4 Key Files
968
-
969
- - `src/index.js`: Main entry point
970
- - `src/lib/dao-cache.js`: Cache module
971
- - `src/lib/dao-endpoint.js`: Endpoint module
972
- - `src/lib/tools/index.js`: Tools module
973
- - `package.json`: Version and dependencies
974
- - `CHANGELOG.md`: Version history
975
- - `.kiro/steering/`: Steering documents
976
-
977
- ## 14. Getting Help
978
-
979
- ### 14.1 Documentation
980
-
981
- - README.md: Package overview and quick start
982
- - docs/: Detailed documentation
983
- - test/: Test examples showing usage
984
- - .kiro/steering/: Development guidelines
985
-
986
- ### 14.2 Resources
987
-
988
- - GitHub Issues: https://github.com/63Klabs/cache-data/issues
989
- - NPM Package: https://www.npmjs.com/package/@63klabs/cache-data
990
- - Atlantis Platform: https://github.com/63klabs/atlantis-tutorials
991
-
992
- ---
993
-
994
- ## Summary
995
-
996
- **Remember the priorities:**
997
-
998
- 1. **Backwards Compatibility**: Never break existing code
999
- 2. **Testing**: All changes must have tests
1000
- 3. **Documentation**: All public APIs must be documented
1001
- 4. **Separation of Concerns**: Keep modules and classes focused
1002
- 5. **Performance**: This runs in production at scale
1003
- 6. **Security**: Handle sensitive data properly
1004
-
1005
- **When in doubt:**
1006
- - Check existing code for patterns
1007
- - Review steering documents
1008
- - Ask the user before making breaking changes
1009
- - Write tests first
1010
- - Document as you go
1011
-
1012
- This package is used in production by real applications. Quality and reliability are non-negotiable.