89 lines
3.3 KiB
Markdown
89 lines
3.3 KiB
Markdown
# Implementer evidence — CLUB-001
|
|
|
|
## Resumen
|
|
Implementé la **Fase 1 — Core backend** del nuevo módulo **Club de Clientes**.
|
|
|
|
## Qué se creó
|
|
|
|
### 1) Nuevo módulo backend `club`
|
|
Archivos nuevos en `project/src/modules/club/`:
|
|
- `api/club.routes.ts`
|
|
- `application/club-service.ts`
|
|
- `domain/club.ts`
|
|
- `domain/errors.ts`
|
|
- `domain/ports.ts`
|
|
- `infrastructure/device-token.ts`
|
|
- `infrastructure/member-code.ts`
|
|
- `infrastructure/pg-club-repository.ts`
|
|
- `index.ts`
|
|
- `tests/token-and-code.test.ts`
|
|
- `tests/boundary.test.ts`
|
|
|
|
### 2) Migración core del Club
|
|
- Nueva migración: `project/migrations/066_club_core.js`
|
|
- Crea tablas:
|
|
- `club_members`
|
|
- `club_devices`
|
|
- `club_transactions`
|
|
- `club_recovery_codes`
|
|
- `club_rewards`
|
|
- `club_campaigns`
|
|
- Añade seeds en `store_settings` para:
|
|
- `club_enabled`
|
|
- `club_cashback_bps`
|
|
- `club_allow_anonymous_members`
|
|
- `club_allow_recovery_codes`
|
|
- `club_minimum_redeem_cents`
|
|
|
|
### 3) Endpoints backend de Fase 1
|
|
- `GET /club/config`
|
|
- `POST /club/join`
|
|
- `GET /club/me`
|
|
- `GET /club/movements`
|
|
- `GET /admin/club/settings`
|
|
- `PATCH /admin/club/settings`
|
|
|
|
### 4) Comportamiento implementado
|
|
- Alta anónima de socio Club.
|
|
- Generación de `deviceToken` opaco.
|
|
- Persistencia solo del `device_token_hash`.
|
|
- Reutilización del socio actual si el dispositivo ya tenía token válido.
|
|
- `memberCode` corto formato `MDV-XXXXXXXX`.
|
|
- Ledger `club_transactions` como fuente de verdad.
|
|
- `current_balance_cents` como cache transaccional.
|
|
- Registro de transacciones idempotentes mediante `idempotencyKey`.
|
|
- Configuración Club reutilizando `store_settings`.
|
|
|
|
### 5) Wiring en la app
|
|
- Registré el módulo en `project/src/app/build-app.ts`.
|
|
|
|
## Tests añadidos
|
|
- `project/src/modules/club/tests/token-and-code.test.ts`
|
|
- `project/src/modules/club/tests/boundary.test.ts`
|
|
- `project/src/app/tests/club.itest.ts`
|
|
|
|
## Fixes necesarios para poder ejecutar itest reales
|
|
Las itest reales del proyecto estaban bloqueadas por migraciones previas mal definidas con `pgm.addColumn(...)`.
|
|
Corregí:
|
|
- `project/migrations/057_product_variant_weight_and_expiry.js`
|
|
- `project/migrations/058_identity_email_confirmation.js`
|
|
|
|
Esto no cambia la intención funcional de esas migraciones; corrige únicamente su forma para que node-pg-migrate pueda aplicarlas.
|
|
|
|
## Validación ejecutada
|
|
- `./scripts/verify.sh` ✅
|
|
- `cd project && npm run typecheck` ✅
|
|
- `cd project && npm run build` ✅
|
|
- `cd project && npx vitest run src/modules/club/tests/token-and-code.test.ts src/modules/club/tests/boundary.test.ts` ✅
|
|
- `cd project && TEST_DATABASE_URL=postgres://mdv:mdv_dev_only@localhost:5432/mercadodevida_test npx vitest run src/app/tests/club.itest.ts --no-file-parallelism` ✅
|
|
- `git diff --check` ✅
|
|
|
|
## Decisiones técnicas relevantes
|
|
- Reutilicé `store_settings` para configuración del Club en vez de crear otro subsistema.
|
|
- El token de dispositivo sigue el patrón de sesiones existente: token opaco en cliente, hash SHA-256 en BD.
|
|
- El módulo ya queda preparado para fases posteriores (PWA, TPV, recovery, linking, admin UI) sin introducirlas todavía.
|
|
|
|
## Deuda / siguiente paso
|
|
- Fase 2 debería construir la PWA `/club/*` consumiendo estos endpoints y mostrando la tarjeta digital.
|
|
- `npm run lint:boundaries` sigue fallando por violaciones **preexistentes y ajenas** en módulos `pos` y `security`; no introducidas por CLUB-001.
|