# Project Memory

This file stores project-specific facts, preferences, and recurring patterns discovered during development.

## Core Facts
- **Memory Ability Included**: The Gemini CLI Memory ability is active for this project, allowing for global preference storage via the `save_memory` tool.
- **Test Coverage Requirement**: 100% test coverage is mandated for all new and modified code.
- **Commit Strategy**: Commits are performed at the end of each phase, including a detailed summary of changes in the commit message body.
- **Database Schema**: Unified Baseline Schema uses `UUID` for all IDs and `inventory` for stock levels.

## Developer Preferences
- **Naming**: Prefer `inventory` over `stock` for product availability.
- **ID Strategy**: Always use `UUID` (`gen_random_uuid()`) for primary keys to ensure consistency between development, test, and production.
- **Numeric Handling**: Coerce numeric database fields to numbers in Zod schemas (using `z.coerce.number()`) as PostgreSQL returns them as strings.

## Discovered Patterns
- **Anti-Mocking Test Setup**: Use `resetPool()` in `lib/db.ts` to allow tests to re-initialize the database connection pool after setting a test-specific `DATABASE_URL`.
- **Repository Dependency Injection**: Use a getter and a `setInstance` method (e.g., `setCatalogRepo`) in server action files to allow for easy injection of mock repositories during unit testing.
- **Standardized Setup**: Consolidate database setup into `scripts/setup-database.ts` to avoid fragmented or conflicting schema definitions.
- **Specialized Repositories**:
    - `InventoryRepository`: Manages product stock levels and availability checks.
    - `PricingRepository`: Manages product prices and currency.
- **Uncodixfy UI Standardization**: Standardized all Dashboard cards to use `hover:scale-[1.02]`, `duration-300`, and `shadow-md` transitions. All buttons should avoid redundant Tailwind classes (`rounded-lg`, `transition-all`) if they are already defined in the primitive.
- **Blackboard Haptic Feedback**: Use `rotate-2 scale-110 z-[100]` and deep shadows (`shadow-[0_25px_60px_-15px_rgba(0,0,0,0.3)]`) on the `DragOverlay` to provide premium "haptic" feedback during drag-and-drop operations.
- **Visual Refinement (Standard)**: Prefer a global border radius of `0.5rem` (8px) for a sharper, more professional dashboard look. Avoid aggressive hover scaling on common UI elements (Cards, Buttons) to prevent visual noise; stick to shadow and border transitions.
- **Entity Header Pattern**: Always consolidate overview page headers and primary actions (e.g., "Add" button) into the standardized `EntityOverviewHeader` component to avoid layout redundancy.
- **Dynamic BI Summary**: Use `Recharts` within a `Suspense` boundary on the main dashboard page to provide immediate visual feedback of key metrics like Revenue Trends and Bestsellers.
- **Breadcrumb Mapping**: Maintain a comprehensive `routeMap` in the `DashboardHeader` to ensure technical URL segments are translated into human-friendly, localized labels.
- **UI State Standardization**: Always use `DataTableSkeleton` for loading table states and `EmptyState` with context-aware CTAs for empty lists to maintain a premium feel. Use `InlineError` for non-intrusive error display in components.
- **Retry Logic**: Configure `useAction` with `retry` options for background tasks that might fail intermittently (e.g., external API synchronization).
- **Logical Atomicity (Multi-System)**: When synchronizing PostgreSQL and Redis (or other side effects), perform the side effects *inside* the PostgreSQL transaction block. This ensures that a failure in the side effect (like Redis being down) triggers a database rollback, maintaining cross-system consistency.
- **Dynamic Update Type Safety**: In repository `update` methods using dynamic SQL construction from `Object.keys()`, always wrap the field names in `String(field)` to avoid TypeScript's "Implicit conversion of a 'symbol' to a 'string' will fail" error.
- **PII Protection in Logs**: 
    - Use `sanitizeError(error)` from `@/lib/utils` for all `logger.error` calls to ensure Zod or Postgres errors don't leak user data in their messages.
    - Use `redactPii(data)` for any arbitrary data objects (like DB params or API payloads) before logging.
    - Pino's built-in `redact` is excellent for known keys (email, token), but recursive sanitization is safer for complex objects.
    - Always replace `console.log` with `logger.info` in production code to leverage structured logging and automatic redaction.
- **Transaction-Aware Cache Invalidation**: Use a `WeakMap<PoolClient, Set<string>>` to track cache keys modified during a database transaction. In the `withTransaction` helper, ensure that a `ROLLBACK` triggers an automatic `redis.del` for all tracked keys to prevent stale cache data.
- **Nested Transaction Support**: Design `withTransaction` to accept an optional `existingClient`. If provided, the helper should reuse the client without issuing `BEGIN/COMMIT/ROLLBACK` commands, allowing for logical atomicity across multiple repository methods.
- **Lua-Based Versioned Updates**: Use Redis Lua scripts (`redis.eval`) to perform "Compare-and-Set" operations based on entity version fields (`updated_at_ns`, `version_id`). This ensures that older out-of-order updates do not overwrite newer data in the cache.

