# Architect — F-027 Caching layer with explicit contracts

## Feature
F-027 wraps hot catalog reads with Redis cache entries that document key, TTL, invalidation and source of truth.

## Design

### Module boundaries
Create `project/src/modules/cache/` with domain/application/infrastructure/api/tests. Cache is an in-process wrapper around a Redis-like adapter. PostgreSQL remains the source of truth.

### Adapter
- `InMemoryCacheAdapter` for v1 implementing `get/set/invalidate` and a metrics hook (`hit_ratio`).

### Public API
- `GET /cache/contracts` admin returns the list of registered cache entries with key, TTL, source.
- `GET /cache/metrics` returns hits/misses.

### Cache entries
- `product:{slug}` (TTL 5m, invalidated by `ProductUpdated` event)
- `category:{slug}` (TTL 5m)
- `nav:tree` (TTL 10m)
- `search:popular` (TTL 1m)

### Acceptance trace
- Catalog update invalidates `product:{slug}` and `category:{slug}`.
- Redis down -> reads still served from PostgreSQL via bypass.
- Hit ratio metric exposed on `/cache/metrics`.
