# Exchange Validation Feature – Development Guide

Fecha: 2025-09-03

## Objetivo

Al finalizar un intercambio:

- El receptor del objeto genera un código aleatorio.
- Entrega ese código por chat al entregador.
- El entregador valida el código, se cierra el chat permanentemente y se oculta la publicación.
- Si el artículo es de tipo "lost" y ofrece recompensa (> 0), el publicador debe pagar la recompensa por Stripe para desbloquear definitivamente el código de confirmación y se avisa al usuario que encontró el producto.

## Checklist de implementación

### 1) Modelo y BD

- [ ] Añadir columnas a `conversations`:
  - `exchange_code` (string, nullable)
  - `exchange_code_generated_by` (bigint, nullable)
  - `exchange_code_generated_at` (timestamp, nullable)
  - `exchange_code_verified_at` (timestamp, nullable)
  - `is_closed` (boolean, default false)
  - `closed_at` (timestamp, nullable)
  - `code_locked` (boolean, default false) – bloqueado hasta pagar recompensa si aplica
  - `reward_payment_id` (bigint, nullable) – pago Stripe para recompensa, si aplica
- [ ] Actualizar `App\\Models\\Conversation` ($fillable, $casts)

### 2) Endpoints App (Routes `routes/app.php`)

- [ ] POST `/conversations/{conversationId}/exchange/generate` – Genera código (solo receptor según tipo y participantes)
- [ ] GET `/conversations/{conversationId}/exchange/status` – Estado de intercambio
- [ ] POST `/conversations/{conversationId}/exchange/validate` – Valida código (solo entregador)
- [ ] Bloquear envío de mensajes/imagenes si `is_closed = true` (hard stop en ChatController)

### 3) Flujo de recompensa (Stripe)

- [ ] POST `/payment/reward-intent/{conversationId}` – Crea PaymentIntent por `article.amount` (paga publicador)
- [ ] POST `/payment/reward-confirm` – Confirma el pago y desbloquea el código (set `code_locked = false`, `reward_payment_id`)

### 4) Lógica de roles

- Artículo `type = lost`:
  - Receptor del objeto = `article.user_id` (publicador)
  - Entregador = el otro participante de la conversación
  - Si `reward_offered = true` y `amount > 0` → pago obligatorio para desbloquear el código
- Artículo `type = found`:
  - Receptor del objeto = participante NO publicador
  - Entregador = `article.user_id` (publicador)

### 5) Cierre y ocultación

- Al validar el código:
  - `conversations.is_closed = true`, `closed_at = now()`
  - Ocultar publicación: `Article::find(conversation.article_id)->delete()` (soft delete)
  - A partir de ese momento, impedir mensajes en la conversación

### 6) Mensajería/UX

- Mensajes i18n mínimos (en/es):
  - `messages.exchange_code_generated`
  - `messages.exchange_code_locked_until_reward`
  - `messages.exchange_reward_payment_required`
  - `messages.exchange_code_invalid`
  - `messages.exchange_already_closed`
  - `messages.exchange_validated_success`
  - `messages.exchange_status`
  - `messages.chat_closed`

### 7) Seguridad y bordes

- Validar pertenencia a la conversación
- Verificar bloqueos entre usuarios (ya existe)
- No permitir regenerar código si ya verificado/cerrado
- No permitir validar si el código está bloqueado
- Manejar reintentos de validación (sin contador por ahora)
- Validar pertenencia a la conversación
- Verificar bloqueos entre usuarios (ya existe)
- No permitir regenerar código si ya verificado/cerrado
- No permitir validar si el código está bloqueado
- Manejar reintentos de validación (sin contador por ahora)

### 8) Pruebas rápidas

- Generación por usuario receptor correcto vs incorrecto
- Estado reporta bloqueo por recompensa para lost+reward
- Pago de recompensa desbloquea código, notifica al otro usuario
- Validación por entregador cierra chat y oculta artículo
- Intento de enviar mensaje después de cierre → 403
- Generación por usuario receptor correcto vs incorrecto
- Estado reporta bloqueo por recompensa para lost+reward
- Pago de recompensa desbloquea código, notifica al otro usuario
- Validación por entregador cierra chat y oculta artículo
- Intento de enviar mensaje después de cierre → 403

### 9) Siguientes mejoras (opcional)

- Límite de intentos de validación
- Mensaje de sistema con el código
- Payout al encontrador (Stripe Connect) si aplica negocio
- Límite de intentos de validación
- Mensaje de sistema con el código
- Payout al encontrador (Stripe Connect) si aplica

---

## Plan de entrega

- Paso 1: Migración + modelo + rutas + endpoints básicos
- Paso 2: Integración Stripe para recompensa y desbloqueo
- Paso 3: i18n + notificaciones + QA

Nota: Esta funcionalidad requiere una migración de base de datos. Confirmar despliegue coordinado.
