@63klabs/cache-data 1.3.7 → 1.3.9

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 ADDED
@@ -0,0 +1,1107 @@
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 Non-Public Class Organization
238
+
239
+ **CRITICAL**: Not all classes should be exported in the public API. Internal implementation classes must be kept separate from user-facing APIs.
240
+
241
+ #### Directory Structure for Classes
242
+
243
+ - **`src/lib/tools/`**: Public API classes and utilities
244
+ - Classes exported in `src/lib/tools/index.js`
245
+ - User-facing functionality
246
+ - Examples: `DebugAndLog`, `Timer`, `Response`, `APIRequest`
247
+
248
+ - **`src/lib/utils/`**: Internal implementation classes
249
+ - Classes NOT exported in public API
250
+ - Used internally by public classes
251
+ - Examples: `InMemoryCache`, `ValidationExecutor`, `ValidationMatcher`
252
+
253
+ #### When to Use Each Directory
254
+
255
+ **Use `src/lib/tools/` when:**
256
+ - Class is part of the public API
257
+ - Users need direct access to the class
258
+ - Class is exported in `src/index.js` or `src/lib/tools/index.js`
259
+ - Class provides user-facing functionality
260
+
261
+ **Use `src/lib/utils/` when:**
262
+ - Class is internal implementation detail
263
+ - Class is only used by other classes in the package
264
+ - Class should not be exposed to users
265
+ - Class is a helper or utility for internal use
266
+
267
+ #### Example: ValidationExecutor and ValidationMatcher
268
+
269
+ These classes are internal to ClientRequest's validation system:
270
+
271
+ ```javascript
272
+ // src/lib/utils/ValidationExecutor.class.js
273
+ // Internal class - not exported in public API
274
+ class ValidationExecutor {
275
+ static execute(validateFn, paramNames, paramValues) {
276
+ // Implementation
277
+ }
278
+ }
279
+
280
+ // src/lib/utils/ValidationMatcher.class.js
281
+ // Internal class - not exported in public API
282
+ class ValidationMatcher {
283
+ constructor(paramValidations, httpMethod, resourcePath) {
284
+ // Implementation
285
+ }
286
+ }
287
+
288
+ // src/lib/tools/ClientRequest.class.js
289
+ // Public class - uses internal classes
290
+ const ValidationMatcher = require('../utils/ValidationMatcher.class');
291
+ const ValidationExecutor = require('../utils/ValidationExecutor.class');
292
+
293
+ class ClientRequest {
294
+ // Uses ValidationMatcher and ValidationExecutor internally
295
+ }
296
+ ```
297
+
298
+ #### Testing Internal Classes
299
+
300
+ Internal classes can still be tested using direct imports in test files:
301
+
302
+ ```javascript
303
+ // test/request/validation/unit/validation-executor-tests.jest.mjs
304
+ const ValidationExecutorModule = await import('../../../../src/lib/utils/ValidationExecutor.class.js');
305
+ const ValidationExecutor = ValidationExecutorModule.default;
306
+
307
+ describe('ValidationExecutor', () => {
308
+ it('should execute validation correctly', () => {
309
+ // Test internal class
310
+ });
311
+ });
312
+ ```
313
+
314
+ #### Rules for AI Assistants
315
+
316
+ When creating new classes:
317
+
318
+ 1. **Determine visibility**: Is this class part of the public API?
319
+ 2. **Choose directory**:
320
+ - Public API → `src/lib/tools/`
321
+ - Internal implementation → `src/lib/utils/`
322
+ 3. **Update exports**: Only export public classes in `src/lib/tools/index.js`
323
+ 4. **Document clearly**: Mark internal classes with `@private` JSDoc tag
324
+ 5. **Test appropriately**: Internal classes can be tested directly
325
+
326
+ **DO NOT**:
327
+ - Export internal classes in public API
328
+ - Place public API classes in `src/lib/utils/`
329
+ - Mix concerns between directories
330
+ - Change class location without updating all imports
331
+
332
+ ### 3.5 Adding New Functionality
333
+
334
+ **Before adding new methods or classes:**
335
+
336
+ 1. **Check for existing functionality**
337
+ - Search codebase for similar functionality
338
+ - Check if existing classes can be extended
339
+ - Avoid duplication at all costs
340
+
341
+ 2. **Determine proper location**
342
+ - Does it belong in cache, endpoint, or tools?
343
+ - Is it a new class or method on existing class?
344
+ - Should it be public or private?
345
+
346
+ 3. **Follow existing patterns**
347
+ - Match naming conventions
348
+ - Use similar parameter structures
349
+ - Follow error handling patterns
350
+ - Maintain consistency with existing code
351
+
352
+ 4. **Consider backwards compatibility**
353
+ - Will this break existing code?
354
+ - Can it be added without breaking changes?
355
+ - Does it need a deprecation path?
356
+
357
+ **Example: Adding a new cache method**
358
+
359
+ ```javascript
360
+ // GOOD: Follows existing patterns
361
+ /**
362
+ * Clear all expired cache entries from storage.
363
+ *
364
+ * @returns {Promise<{success: boolean, count: number}>} Result with count of cleared entries
365
+ * @example
366
+ * const result = await Cache.clearExpired();
367
+ * console.log(`Cleared ${result.count} expired entries`);
368
+ */
369
+ static async clearExpired() {
370
+ // Implementation
371
+ }
372
+
373
+ // BAD: Breaks patterns, unclear purpose
374
+ static async doCleanup(opts) {
375
+ // Implementation
376
+ }
377
+ ```
378
+
379
+ ## 4. Code Quality Standards
380
+
381
+ ### 4.1 Code Style
382
+
383
+ - **Language**: JavaScript (Node.js >= 20.0.0)
384
+ - **Indentation**: Tabs (not spaces)
385
+ - **Quotes**: Double quotes for strings
386
+ - **Semicolons**: Required
387
+ - **Line Length**: Reasonable (no strict limit, but keep readable)
388
+ - **Comments**: Use JSDoc for public APIs, inline comments for complex logic
389
+
390
+ ### 4.2 Naming Conventions
391
+
392
+ **Classes**: PascalCase
393
+ ```javascript
394
+ class CacheData { }
395
+ class S3Cache { }
396
+ class APIRequest { }
397
+ ```
398
+
399
+ **Functions/Methods**: camelCase
400
+ ```javascript
401
+ async function getData() { }
402
+ static async read(idHash) { }
403
+ ```
404
+
405
+ **Constants**: UPPER_SNAKE_CASE
406
+ ```javascript
407
+ static PRIVATE = "private";
408
+ static PUBLIC = "public";
409
+ static STATUS_NO_CACHE = "original";
410
+ ```
411
+
412
+ **Private Fields**: # prefix
413
+ ```javascript
414
+ static #bucket = null;
415
+ #syncedNowTimestampInSeconds = 0;
416
+ ```
417
+
418
+ **Parameters**: camelCase
419
+ ```javascript
420
+ function processData(idHash, syncedNow, bodyContent) { }
421
+ ```
422
+
423
+ ### 4.3 Error Handling
424
+
425
+ **ALWAYS handle errors gracefully:**
426
+
427
+ ```javascript
428
+ // GOOD: Proper error handling
429
+ try {
430
+ const result = await someOperation();
431
+ return result;
432
+ } catch (error) {
433
+ tools.DebugAndLog.error(`Operation failed: ${error?.message || 'Unknown error'}`, error?.stack);
434
+ return defaultValue;
435
+ }
436
+
437
+ // BAD: Unhandled errors
438
+ const result = await someOperation(); // Could throw
439
+ ```
440
+
441
+ **Error Logging:**
442
+ - Use `tools.DebugAndLog.error()` for errors
443
+ - Include context (what operation failed)
444
+ - Include error message and stack trace
445
+ - Return sensible defaults on error
446
+
447
+ **Throwing Errors:**
448
+ - Only throw for unrecoverable errors
449
+ - Document with `@throws` JSDoc tag
450
+ - Use descriptive error messages
451
+ - Include context in error message
452
+
453
+ ### 4.4 Performance Considerations
454
+
455
+ This package is used in high-traffic Lambda functions. Performance matters.
456
+
457
+ **DO**:
458
+ - Minimize AWS SDK calls
459
+ - Use Promise.all() for parallel operations
460
+ - Cache expensive computations
461
+ - Use in-memory cache when appropriate
462
+ - Minimize JSON.stringify() calls (see existing specs)
463
+
464
+ **DON'T**:
465
+ - Make synchronous blocking calls
466
+ - Create unnecessary objects in loops
467
+ - Perform expensive operations in constructors
468
+ - Make redundant AWS API calls
469
+
470
+ ### 4.5 Security Considerations
471
+
472
+ **CRITICAL**: This package handles sensitive data and encryption.
473
+
474
+ **DO**:
475
+ - Encrypt sensitive data using CacheData encryption
476
+ - Use secure random for IVs and keys
477
+ - Validate all inputs
478
+ - Sanitize data before logging
479
+ - Use environment variables for secrets (never hardcode)
480
+
481
+ **DON'T**:
482
+ - Log sensitive data (keys, passwords, PII)
483
+ - Store unencrypted sensitive data
484
+ - Trust user input without validation
485
+ - Expose internal implementation details
486
+
487
+ ## 5. Testing Strategy
488
+
489
+ ### 5.1 Test Framework Migration
490
+
491
+ **CRITICAL: Mocha to Jest Migration in Progress**
492
+
493
+ This project is actively migrating from Mocha to Jest. During this transition period:
494
+
495
+ **Migration Status:**
496
+ - **Phase**: Active migration - both frameworks supported
497
+ - **Legacy**: Mocha tests (`*-tests.mjs`) - maintain but don't create new
498
+ - **Current**: Jest tests (`*.jest.mjs`) - all new tests must use this
499
+ - **Goal**: Complete migration to Jest, remove Mocha dependency
500
+
501
+ **File Naming Conventions:**
502
+ - Mocha (legacy): `cache-tests.mjs`, `endpoint-tests.mjs`, `*-property-tests.mjs`
503
+ - Jest (current): `cache-tests.jest.mjs`, `endpoint-tests.jest.mjs`, `*-property-tests.jest.mjs`
504
+
505
+ **Test Execution Commands:**
506
+ ```bash
507
+ # Run Mocha tests only (legacy)
508
+ npm test
509
+
510
+ # Run Jest tests only (current)
511
+ npm run test:jest
512
+
513
+ # Run both test suites (REQUIRED for CI/CD)
514
+ npm run test:all
515
+
516
+ # Run specific test suites
517
+ npm run test:cache # Mocha cache tests
518
+ npm run test:cache:jest # Jest cache tests
519
+ npm run test:endpoint # Mocha endpoint tests
520
+ npm run test:endpoint:jest # Jest endpoint tests
521
+ ```
522
+
523
+ **Migration Guidelines:**
524
+
525
+ 1. **Creating New Tests:**
526
+ - ALWAYS use Jest (`*.jest.mjs` files)
527
+ - Follow Jest patterns and assertions
528
+ - Use Jest mocking (not Sinon)
529
+ - Place in same directory as Mocha tests
530
+
531
+ 2. **Modifying Existing Tests:**
532
+ - If minor change: Update Mocha test
533
+ - If major change: Consider migrating to Jest
534
+ - If time permits: Migrate to Jest and delete Mocha version
535
+
536
+ 3. **Test Coverage:**
537
+ - Both test suites must pass in CI/CD
538
+ - Jest coverage: `coverage-jest/` directory
539
+ - Mocha coverage: `coverage/` directory (if generated)
540
+
541
+ 4. **Property-Based Tests:**
542
+ - Use fast-check in both Mocha and Jest
543
+ - Same property definitions work in both frameworks
544
+ - Migrate property tests to Jest when possible
545
+
546
+ **Why Jest?**
547
+ - Better ESM support
548
+ - Built-in mocking (no Sinon needed)
549
+ - Better async/await handling
550
+ - More modern and actively maintained
551
+ - Better IDE integration
552
+ - Simpler configuration
553
+
554
+ **Migration Checklist for Converting Tests:**
555
+ - [ ] Create new `*.jest.mjs` file
556
+ - [ ] Import from `@jest/globals` instead of `chai`
557
+ - [ ] Change `expect().to.equal()` to `expect().toBe()`
558
+ - [ ] Change `expect().to.not.equal()` to `expect().not.toBe()`
559
+ - [ ] Replace Sinon mocks with Jest mocks
560
+ - [ ] Update async test patterns if needed
561
+ - [ ] Run Jest tests to verify: `npm run test:jest`
562
+ - [ ] Delete old Mocha test file
563
+ - [ ] Update any references in documentation
564
+
565
+ ### 5.2 Test Organization
566
+
567
+ Tests mirror source structure:
568
+
569
+ ```
570
+ test/
571
+ ├── cache/ # Cache module tests
572
+ │ ├── cache-tests.mjs (Mocha - legacy)
573
+ │ ├── cache-tests.jest.mjs (Jest - new)
574
+ │ ├── in-memory-cache/
575
+ │ │ ├── unit/
576
+ │ │ ├── integration/
577
+ │ │ └── property/
578
+ ├── config/ # Configuration tests
579
+ ├── documentation/ # Documentation validation
580
+ │ └── property/
581
+ ├── endpoint/ # Endpoint module tests
582
+ │ ├── endpoint-tests.mjs (Mocha - legacy)
583
+ │ ├── endpoint-tests.jest.mjs (Jest - new)
584
+ ├── logging/ # Logging tests
585
+ ├── request/ # Request handling tests
586
+ ├── response/ # Response tests
587
+ ├── utils/ # Utility tests
588
+ └── helpers/ # Test utilities
589
+ ```
590
+
591
+ **Note**: During migration, both `.mjs` (Mocha) and `.jest.mjs` (Jest) files coexist in the same directories.
592
+
593
+ ### 5.3 Test Naming Conventions
594
+
595
+ **Mocha (Legacy):**
596
+ - Test files: `*-tests.mjs`
597
+ - Property tests: `*-property-tests.mjs`
598
+ - Integration tests: `*-integration-tests.mjs`
599
+ - Unit tests: `*-unit-tests.mjs` or `*-tests.mjs`
600
+
601
+ **Jest (Current - Use for All New Tests):**
602
+ - Test files: `*.jest.mjs`
603
+ - Property tests: `*-property-tests.jest.mjs`
604
+ - Integration tests: `*-integration-tests.jest.mjs`
605
+ - Unit tests: `*-unit-tests.jest.mjs` or `*.jest.mjs`
606
+
607
+ ### 5.4 Test Framework
608
+
609
+ **CRITICAL: Test Framework Migration in Progress**
610
+
611
+ This project is currently migrating from Mocha to Jest. Both frameworks are supported during the transition period.
612
+
613
+ **Current Status:**
614
+ - **Legacy Tests**: Mocha tests (files ending in `-tests.mjs`)
615
+ - **New Tests**: Jest tests (files ending in `.jest.mjs`)
616
+ - **Migration Goal**: All tests will eventually be in Jest
617
+
618
+ **Test Framework by Type:**
619
+
620
+ **Mocha (Legacy - Being Phased Out):**
621
+ - Test Runner: Mocha
622
+ - Assertions: Chai (expect style)
623
+ - Property Testing: fast-check
624
+ - Mocking: Sinon
625
+ - HTTP Testing: chai-http
626
+ - File Pattern: `*-tests.mjs`
627
+
628
+ **Jest (Current - All New Tests):**
629
+ - Test Runner: Jest
630
+ - Assertions: Jest built-in (expect)
631
+ - Property Testing: fast-check (same as Mocha)
632
+ - Mocking: Jest built-in
633
+ - HTTP Testing: Jest with mocks
634
+ - File Pattern: `*.jest.mjs`
635
+
636
+ **Rules for Test Development:**
637
+
638
+ 1. **ALL NEW TESTS MUST BE WRITTEN IN JEST** using the `*.jest.mjs` file pattern
639
+ 2. **DO NOT create new Mocha tests** - only maintain existing ones
640
+ 3. **When modifying existing tests**, consider migrating to Jest if time permits
641
+ 4. **Both test suites must pass** before merging (`npm run test:all`)
642
+ 5. **Jest tests coexist with Mocha tests** in the same directories
643
+
644
+ **Test Execution:**
645
+ ```bash
646
+ # Run Mocha tests (legacy)
647
+ npm test
648
+
649
+ # Run Jest tests (new)
650
+ npm run test:jest
651
+
652
+ # Run both test suites (required for CI/CD)
653
+ npm run test:all
654
+ ```
655
+
656
+ ### 5.5 Writing Good Tests
657
+
658
+ **DO**:
659
+ - Test one thing per test
660
+ - Use descriptive test names
661
+ - Test edge cases and error conditions
662
+ - Make tests deterministic
663
+ - Keep tests fast
664
+ - Use property-based testing for core logic
665
+ - **Write all new tests in Jest** (not Mocha)
666
+
667
+ **DON'T**:
668
+ - Test implementation details
669
+ - Create flaky tests
670
+ - Use real AWS services (mock them)
671
+ - Make tests dependent on each other
672
+ - Skip tests without good reason
673
+ - **Create new Mocha tests** (migration in progress)
674
+
675
+ **Example Test Structure (Jest - Use This for New Tests):**
676
+
677
+ ```javascript
678
+ import { describe, it, expect } from '@jest/globals';
679
+ import { Cache } from '../src/lib/dao-cache.js';
680
+
681
+ describe('Cache', () => {
682
+ describe('generateIdHash()', () => {
683
+ it('should generate consistent hash for same input', () => {
684
+ const conn = { host: 'example.com', path: '/api' };
685
+ const hash1 = Cache.generateIdHash(conn);
686
+ const hash2 = Cache.generateIdHash(conn);
687
+ expect(hash1).toBe(hash2);
688
+ });
689
+
690
+ it('should generate different hashes for different inputs', () => {
691
+ const conn1 = { host: 'example.com', path: '/api' };
692
+ const conn2 = { host: 'example.com', path: '/api2' };
693
+ const hash1 = Cache.generateIdHash(conn1);
694
+ const hash2 = Cache.generateIdHash(conn2);
695
+ expect(hash1).not.toBe(hash2);
696
+ });
697
+
698
+ it('should handle null input gracefully', () => {
699
+ expect(() => Cache.generateIdHash(null)).not.toThrow();
700
+ });
701
+ });
702
+ });
703
+ ```
704
+
705
+ **Legacy Test Structure (Mocha - Maintain Only, Don't Create New):**
706
+
707
+ ```javascript
708
+ import { expect } from 'chai';
709
+ import { Cache } from '../src/lib/dao-cache.js';
710
+
711
+ describe('Cache', () => {
712
+ describe('generateIdHash()', () => {
713
+ it('should generate consistent hash for same input', () => {
714
+ const conn = { host: 'example.com', path: '/api' };
715
+ const hash1 = Cache.generateIdHash(conn);
716
+ const hash2 = Cache.generateIdHash(conn);
717
+ expect(hash1).to.equal(hash2);
718
+ });
719
+ });
720
+ });
721
+ ```
722
+
723
+ ## 6. Kiro Steering Documents
724
+
725
+ This repository uses Kiro for AI-assisted development. Steering documents provide additional context and rules.
726
+
727
+ **Location**: `.kiro/steering/`
728
+
729
+ **Available Steering Documents**:
730
+
731
+ 1. **spec-naming-convention.md**: Spec directory naming rules
732
+ - Format: `{version}-{feature-name}`
733
+ - Version from package.json with dots replaced by hyphens
734
+ - Example: `.kiro/specs/1-3-6-in-memory-cache/`
735
+
736
+ 2. **documentation-standards.md**: Complete documentation standards
737
+ - JSDoc requirements and templates
738
+ - Documentation update process
739
+ - Quality standards and validation
740
+ - Common pitfalls and solutions
741
+
742
+ **CRITICAL**: Always follow steering document rules. They take precedence over general guidelines.
743
+
744
+ ## 7. Spec-Driven Development
745
+
746
+ This project uses spec-driven development for new features.
747
+
748
+ ### 7.1 Spec Structure
749
+
750
+ Specs are located in `.kiro/specs/{version}-{feature-name}/`:
751
+
752
+ - `requirements.md`: User stories and acceptance criteria
753
+ - `design.md`: Technical design and correctness properties
754
+ - `tasks.md`: Implementation task list
755
+
756
+ ### 7.2 Spec Workflow
757
+
758
+ 1. **Requirements**: Define what needs to be built
759
+ 2. **Design**: Define how it will be built
760
+ 3. **Tasks**: Break down into implementable tasks
761
+ 4. **Implementation**: Execute tasks one at a time
762
+ 5. **Testing**: Validate against correctness properties
763
+
764
+ ### 7.3 Property-Based Testing in Specs
765
+
766
+ Specs include correctness properties that must be validated:
767
+
768
+ - Properties are formal specifications of behavior
769
+ - Properties are tested using property-based testing
770
+ - Properties must pass before feature is complete
771
+ - Properties are linked to requirements
772
+
773
+ **Example Property:**
774
+
775
+ ```
776
+ Property 1: Cache Hit Consistency
777
+ For all valid cache keys and data:
778
+ If data is written to cache with key K,
779
+ Then reading from cache with key K returns the same data
780
+ Until the expiration time is reached
781
+ ```
782
+
783
+ ## 8. Common Patterns and Anti-Patterns
784
+
785
+ ### 8.1 Good Patterns
786
+
787
+ **Initialization Pattern:**
788
+ ```javascript
789
+ class MyClass {
790
+ static #initialized = false;
791
+ static #config = null;
792
+
793
+ static init(config) {
794
+ if (this.#initialized) {
795
+ tools.DebugAndLog.warn("Already initialized");
796
+ return;
797
+ }
798
+ this.#config = config;
799
+ this.#initialized = true;
800
+ }
801
+ }
802
+ ```
803
+
804
+ **Error Handling Pattern:**
805
+ ```javascript
806
+ static async operation() {
807
+ return new Promise(async (resolve) => {
808
+ try {
809
+ const result = await doSomething();
810
+ resolve(result);
811
+ } catch (error) {
812
+ tools.DebugAndLog.error(`Operation failed: ${error?.message}`, error?.stack);
813
+ resolve(defaultValue);
814
+ }
815
+ });
816
+ }
817
+ ```
818
+
819
+ **Configuration Pattern:**
820
+ ```javascript
821
+ static init(parameters) {
822
+ this.#setting = parameters.setting ||
823
+ process.env.ENV_VAR ||
824
+ defaultValue;
825
+ }
826
+ ```
827
+
828
+ ### 8.2 Anti-Patterns to Avoid
829
+
830
+ **DON'T: Break backwards compatibility**
831
+ ```javascript
832
+ // BAD: Changed parameter order
833
+ static write(body, idHash) { } // Was: write(idHash, body)
834
+
835
+ // GOOD: Add new optional parameter at end
836
+ static write(idHash, body, options = {}) { }
837
+ ```
838
+
839
+ **DON'T: Ignore errors**
840
+ ```javascript
841
+ // BAD: Silent failure
842
+ try {
843
+ await operation();
844
+ } catch (error) {
845
+ // Nothing
846
+ }
847
+
848
+ // GOOD: Log and handle
849
+ try {
850
+ await operation();
851
+ } catch (error) {
852
+ tools.DebugAndLog.error(`Failed: ${error?.message}`, error?.stack);
853
+ return defaultValue;
854
+ }
855
+ ```
856
+
857
+ **DON'T: Create god classes**
858
+ ```javascript
859
+ // BAD: Too many responsibilities
860
+ class CacheAndEndpointAndLogging {
861
+ cache() { }
862
+ request() { }
863
+ log() { }
864
+ }
865
+
866
+ // GOOD: Separate concerns
867
+ class Cache { }
868
+ class Endpoint { }
869
+ class Logger { }
870
+ ```
871
+
872
+ **DON'T: Duplicate functionality**
873
+ ```javascript
874
+ // BAD: Reimplementing existing functionality
875
+ function myHash(data) {
876
+ // Custom hash implementation
877
+ }
878
+
879
+ // GOOD: Use existing functionality
880
+ const hash = tools.hashThisData(data);
881
+ ```
882
+
883
+ ## 9. Deployment and Versioning
884
+
885
+ ### 9.1 Release Process
886
+
887
+ 1. Update version in `package.json`
888
+ 2. Update `CHANGELOG.md` with changes
889
+ 3. Run all tests: `npm test`
890
+ 4. Run documentation validation
891
+ 5. Commit changes
892
+ 6. Create git tag: `git tag v1.3.6`
893
+ 7. Push to npm: `npm publish`
894
+
895
+ ### 9.2 Changelog Format
896
+
897
+ Follow existing CHANGELOG.md format:
898
+
899
+ ```markdown
900
+ ## [1.3.6] - 2026-02-01
901
+
902
+ ### Added
903
+ - New feature description
904
+
905
+ ### Changed
906
+ - Changed behavior description
907
+
908
+ ### Fixed
909
+ - Bug fix description
910
+
911
+ ### Deprecated
912
+ - Deprecated feature with migration path
913
+ ```
914
+
915
+ ### 9.3 Breaking Changes
916
+
917
+ **CRITICAL**: Breaking changes require major version bump.
918
+
919
+ Breaking changes include:
920
+ - Removed exports
921
+ - Changed function signatures
922
+ - Changed default behaviors
923
+ - Removed or renamed parameters
924
+ - Changed return types
925
+ - Changed error behaviors
926
+
927
+ **Process for breaking changes:**
928
+ 1. Discuss with user first
929
+ 2. Create migration guide
930
+ 3. Update major version
931
+ 4. Document in CHANGELOG.md
932
+ 5. Update all documentation
933
+ 6. Update all examples
934
+
935
+ ## 10. AWS Integration
936
+
937
+ ### 10.1 AWS Services Used
938
+
939
+ - **S3**: Large object storage for cache
940
+ - **DynamoDB**: Metadata and small object storage
941
+ - **SSM Parameter Store**: Configuration and secrets
942
+ - **Lambda**: Execution environment (Node.js >= 20.0.0)
943
+
944
+ ### 10.2 AWS SDK Usage
945
+
946
+ **CRITICAL**: Use AWS SDK v3 only. Do not mix v2 and v3.
947
+
948
+ ```javascript
949
+ // GOOD: Use tools.AWS wrapper
950
+ const result = await tools.AWS.s3.get(params);
951
+ const item = await tools.AWS.dynamo.get(params);
952
+
953
+ // BAD: Direct SDK usage
954
+ const s3 = new S3Client();
955
+ ```
956
+
957
+ ### 10.3 IAM Permissions Required
958
+
959
+ Lambda execution role needs:
960
+ - S3: GetObject, PutObject
961
+ - DynamoDB: GetItem, PutItem
962
+ - SSM: GetParameter, GetParameters, GetParametersByPath
963
+
964
+ ## 11. Performance Optimization
965
+
966
+ ### 11.1 Lambda Memory Allocation
967
+
968
+ Recommended: 1024MB - 2048MB
969
+ Minimum: 512MB
970
+
971
+ See: `docs/lambda-optimization/README.md`
972
+
973
+ ### 11.2 Cache Strategy
974
+
975
+ - Use in-memory cache for hot data
976
+ - Use DynamoDB for small items (< 10KB)
977
+ - Use S3 for large items (> 10KB)
978
+ - Set appropriate expiration times
979
+ - Use interval-based expiration for predictable patterns
980
+
981
+ ### 11.3 Optimization Techniques
982
+
983
+ - Minimize JSON.stringify() calls
984
+ - Use Promise.all() for parallel operations
985
+ - Reuse connections and clients
986
+ - Cache expensive computations
987
+ - Use appropriate data structures
988
+
989
+ ## 12. Troubleshooting
990
+
991
+ ### 12.1 Common Issues
992
+
993
+ **Issue**: Tests failing after changes
994
+ - **Solution**: Check if backwards compatibility broken
995
+ - **Solution**: Verify test expectations are correct
996
+ - **Solution**: Check for race conditions
997
+
998
+ **Issue**: Documentation validation failing
999
+ - **Solution**: Ensure JSDoc matches implementation
1000
+ - **Solution**: Check parameter names match exactly
1001
+ - **Solution**: Verify examples are executable
1002
+
1003
+ **Issue**: Performance degradation
1004
+ - **Solution**: Check for unnecessary AWS calls
1005
+ - **Solution**: Verify in-memory cache is enabled
1006
+ - **Solution**: Check Lambda memory allocation
1007
+
1008
+ ### 12.2 Debugging
1009
+
1010
+ Use `tools.DebugAndLog` for debugging:
1011
+
1012
+ ```javascript
1013
+ tools.DebugAndLog.debug('Debug message', data);
1014
+ tools.DebugAndLog.info('Info message');
1015
+ tools.DebugAndLog.warn('Warning message');
1016
+ tools.DebugAndLog.error('Error message', error?.stack);
1017
+ ```
1018
+
1019
+ Set log level via environment variable:
1020
+ ```bash
1021
+ DEBUG_MODE=true
1022
+ ```
1023
+
1024
+ ## 13. Quick Reference
1025
+
1026
+ ### 13.1 Before Making Changes
1027
+
1028
+ - [ ] Read this AI_CONTEXT.md document
1029
+ - [ ] Review steering documents in `.kiro/steering/`
1030
+ - [ ] Check existing tests for expected behavior
1031
+ - [ ] Search codebase for similar functionality
1032
+ - [ ] Verify backwards compatibility impact
1033
+
1034
+ ### 13.2 Before Committing
1035
+
1036
+ - [ ] All tests pass: `npm test`
1037
+ - [ ] Documentation updated and validated
1038
+ - [ ] CHANGELOG.md updated
1039
+ - [ ] No breaking changes (or properly versioned)
1040
+ - [ ] Code follows style guidelines
1041
+ - [ ] Error handling is proper
1042
+ - [ ] Performance impact considered
1043
+
1044
+ ### 13.3 Key Commands
1045
+
1046
+ ```bash
1047
+ # Run all tests
1048
+ npm test
1049
+
1050
+ # Run specific test suite
1051
+ npm run test:cache
1052
+ npm run test:endpoint
1053
+ npm run test:utils
1054
+
1055
+ # Run documentation validation
1056
+ npm test -- test/documentation/
1057
+
1058
+ # Run documentation audit
1059
+ node scripts/audit-documentation.mjs
1060
+ ```
1061
+
1062
+ ### 13.4 Key Files
1063
+
1064
+ - `src/index.js`: Main entry point
1065
+ - `src/lib/dao-cache.js`: Cache module
1066
+ - `src/lib/dao-endpoint.js`: Endpoint module
1067
+ - `src/lib/tools/index.js`: Tools module
1068
+ - `package.json`: Version and dependencies
1069
+ - `CHANGELOG.md`: Version history
1070
+ - `.kiro/steering/`: Steering documents
1071
+
1072
+ ## 14. Getting Help
1073
+
1074
+ ### 14.1 Documentation
1075
+
1076
+ - README.md: Package overview and quick start
1077
+ - docs/: Detailed documentation
1078
+ - test/: Test examples showing usage
1079
+ - .kiro/steering/: Development guidelines
1080
+
1081
+ ### 14.2 Resources
1082
+
1083
+ - GitHub Issues: https://github.com/63Klabs/cache-data/issues
1084
+ - NPM Package: https://www.npmjs.com/package/@63klabs/cache-data
1085
+ - Atlantis Platform: https://github.com/63klabs/atlantis-tutorials
1086
+
1087
+ ---
1088
+
1089
+ ## Summary
1090
+
1091
+ **Remember the priorities:**
1092
+
1093
+ 1. **Backwards Compatibility**: Never break existing code
1094
+ 2. **Testing**: All changes must have tests
1095
+ 3. **Documentation**: All public APIs must be documented
1096
+ 4. **Separation of Concerns**: Keep modules and classes focused
1097
+ 5. **Performance**: This runs in production at scale
1098
+ 6. **Security**: Handle sensitive data properly
1099
+
1100
+ **When in doubt:**
1101
+ - Check existing code for patterns
1102
+ - Review steering documents
1103
+ - Ask the user before making breaking changes
1104
+ - Write tests first
1105
+ - Document as you go
1106
+
1107
+ This package is used in production by real applications. Quality and reliability are non-negotiable.