# Implementer evidence — CLUB-003

## Resumen
Implementé la integración del Club en el TPV: resolución de socio por código, acumulación de cashback en ledger idempotente y campos de respuesta en venta POS.

## Qué se añadió

### 1) Endpoint de resolución de socio
- `GET /club/resolve?memberCode=MDV-XXXXXXXX` en `project/src/modules/club/api/club.routes.ts`
- Método `resolveByCode` en `ClubService`
- Método `findMemberByCode` en `PgClubRepository` (solo socios activos)

### 2) Integración de cashback en venta POS
- `PosSaleInput` ahora acepta `clubMemberId?: string` (domain type)
- `PosSaleResult` ahora devuelve `clubEarnedCents` y `clubMemberCode`
- `CreatePosSaleUseCase`:
  - Al completar una venta (orderState === 'COMPLETED'), si hay `clubMemberId`:
    - Consulta `club_enabled` y `club_cashback_bps` de `store_settings`
    - Calcula `cashbackCents = round(totalCents * cashbackBps / 10_000)`
    - Inserta transacción de ledger idempotente con `idempotency_key = club-earn-${orderId}` dentro de la misma transacción DB que la venta
    - Si la insercción falla, continúa sin bloquear la venta (fail-safe)
- `loadResult` recupera el `clubEarnedCents` del ledger al recargar una venta por idempotency key
- `receive-rest-payment.ts` devuelve `clubEarnedCents: 0` (pagos adicionales no re-acumulan cashback)

### 3) API del TPV
- El body de `POST /pos/sales` acepta `clubMemberId` con validación UUID
- La respuesta de venta incluye `clubEarnedCents` y `clubMemberCode`

### 4) Tipos frontend
- `PosSaleResponse` en `apps/pos/src/types/checkout.ts` incluye `clubEarnedCents` y `clubMemberCode`

## Decisiones técnicas
- El cashback se acumula **solo cuando la venta pasa a COMPLETED**, no en ventas PENDING.
- Si la escritura de ledger falla, la venta sigue adelante (fail-safe).
- El idempotency key del ledger incluye el `orderId` (`club-earn-${orderId}`), garantizando una única acumulación por venta.
- El `loadResult` recupera el cashback del ledger para mantener consistencia en respuestas por idempotency.

## Validación ejecutada
- `cd project && npm run typecheck` ✅
- `cd project && npm run build` ✅
- `cd project/apps/pos && npm run build` ✅
- `./scripts/verify.sh` ✅
- `cd project && npx vitest run src/modules/pos/tests/payment-allocation.test.ts` ✅
- `cd project && npx vitest run src/modules/club/tests/` ✅
- `git diff --check` ✅

## Riesgos / siguiente paso
- CLUB-004 debe implementar el flujo de devolución TPV que revierte el cashback acumulado cuando se reintegran artículos.
- El frontend TPV (interfaz de búsqueda de socio Club) queda pendiente de implementar en la UI del terminal; los campos del endpoint ya están listos.
