# CR Nº 3 - Resumo de Implementação

## Data: 11/12/2025

## Mudanças Implementadas

### 1. Schema de Validação (`utils/campaignSchema.js`)

#### Novos Campos para Campanha Sorteio:
- `draw_periodicity` (VARCHAR) - Periodicidade de atribuição de prémios: 'daily', 'weekly', 'monthly', 'event' (obrigatório para sorteio)
- `draw_points_per_participation` (INTEGER) - Pontos necessários por participação
- `draw_prizes_list` (JSONB) - Lista de prémios por fase (opcional)

#### Novos Campos para Campanha Troca:
- `exchange_prizes_list` (JSONB) - Lista de prémios disponíveis para troca (obrigatório para troca)
  - Cada prémio contém: `id`, `name`, `price_mt`, `points_required`, `stock`, `description`

### 2. Migration do Banco de Dados (`database/migrate-cr3-campaign-fields.sql`)

#### Colunas Adicionadas na Tabela `campaigns`:
- `draw_periodicity` - Periodicidade de atribuição de prémios
- `draw_points_per_participation` - Pontos necessários por participação
- `draw_prizes_list` - Lista de prémios por fase (JSONB)
- `exchange_prizes_list` - Lista de prémios para troca (JSONB)

#### Colunas Adicionadas na Tabela `campaign_participations`:
- `points_decremented_after_win` - Pontos decrementados após vencer prémio
- `virtual_tickets` - Número de bilhetes virtuais (proporcional aos pontos)
- `prize_won_id` - ID do prémio ganho no sorteio

#### Nova Tabela:
- `campaign_exchange_prizes` - Tabela para armazenar prémios de campanhas de troca (estrutura alternativa)

### 3. Modelo de Campanhas (`models/CampaignsModel.js`)

- Adicionado suporte para salvar os novos campos `draw_periodicity`, `draw_points_per_participation`, `draw_prizes_list` e `exchange_prizes_list`
- Campos são salvos como JSONB quando necessário

### 4. Controller de Campanhas (`controllers/campaignsController.js`)

#### Validações Adicionadas:
- Para `RewardType_Draw`: `draw_periodicity` é obrigatório
- Para `RewardType_Exchange`: `exchange_prizes_list` é obrigatório e deve conter pelo menos um prémio

#### `processDrawCampaign` - Nova Lógica:
1. **Pontos necessários por participação**: Se `draw_points_per_participation` > 0, debita pontos antes de participar
2. **Bilhetes virtuais proporcionais**: Calcula bilhetes virtuais = pontos do usuário (quanto mais pontos, mais bilhetes)
3. **Atualização de bilhetes**: Se usuário já participa, atualiza bilhetes virtuais baseado nos pontos atuais

#### `processExchangeCampaign` - Nova Lógica:
1. **Suporte a múltiplos produtos**: Aceita `prizeId` para selecionar prémio específico da lista
2. **Lista de prémios**: Usa `exchange_prizes_list` quando disponível, com fallback para campos legados
3. **Estoque por prémio**: Gerencia estoque individual para cada prémio na lista
4. **Validação de prémio**: Verifica se prémio existe e tem estoque disponível

### 5. Utilitário de Seleção de Vencedores (`utils/drawWinnerSelection.js`)

#### Funções Implementadas:
- `selectDrawWinners(participants, winnersCount)` - Seleciona vencedores com probabilidade proporcional aos bilhetes virtuais
- `selectDrawWinnersWithDetails(participants, winnersCount, prizesList)` - Retorna vencedores com detalhes e prémios atribuídos

#### Lógica de Probabilidade:
- Cada participante tem bilhetes virtuais = seus pontos
- Probabilidade de ganhar = (bilhetes do participante / total de bilhetes) × 100%
- Quanto mais pontos, maior a probabilidade de ganhar

### 6. Endpoint de Scan Atualizado

- `POST /api/campaigns/scan` agora aceita `prizeId` no body para campanhas de troca
- Permite selecionar prémio específico da lista `exchange_prizes_list`

## Pendências (Não Implementadas)

### 1. Decremento Automático de Pontos Após Vencer Prémio
- **Status**: Pendente
- **Descrição**: Após vencer um prémio no sorteio, os pontos necessários para ganhar devem ser decrementados automaticamente
- **Implementação Necessária**: 
  - Criar função para processar vencedores do sorteio
  - Decrementar pontos dos vencedores baseado em `draw_points_per_participation`
  - Atualizar `points_decremented_after_win` em `campaign_participations`

### 2. Seleção Automática de Vencedores
- **Status**: Pendente
- **Descrição**: Sistema deve selecionar automaticamente vencedores baseado na periodicidade configurada
- **Implementação Necessária**:
  - Criar job/cron para processar sorteios baseado em `draw_periodicity`
  - Usar `selectDrawWinners` para selecionar vencedores
  - Atribuir prémios da `draw_prizes_list` por ordem de seleção
  - Decrementar pontos dos vencedores

### 3. Simplificação do Formulário Base
- **Status**: Parcialmente Implementado
- **Descrição**: Formulário base deve mostrar apenas: Nome, Dinheiro gasto, Pontos correspondentes, Data Início, Data Fim
- **Observação**: Schema permite todos os campos, mas frontend deve controlar quais campos mostrar baseado no tipo

## Como Usar

### Criar Campanha Sorteio:
```json
{
  "type": "RewardType_Draw",
  "campaign_name": "Sorteio Mensal",
  "establishment_id": "EST_123",
  "valid_from": "2025-12-01T00:00:00Z",
  "valid_until": "2025-12-31T23:59:59Z",
  "draw_periodicity": "monthly",
  "draw_points_per_participation": 100,
  "draw_min_spend": 500,
  "draw_prize_description": "Jantar grátis",
  "draw_prizes_list": [
    {
      "name": "Prémio 1",
      "value_mt": 500,
      "phase": "fase1"
    }
  ]
}
```

### Criar Campanha Troca:
```json
{
  "type": "RewardType_Exchange",
  "campaign_name": "Troca de Pontos",
  "establishment_id": "EST_123",
  "valid_from": "2025-12-01T00:00:00Z",
  "valid_until": "2025-12-31T23:59:59Z",
  "exchange_prizes_list": [
    {
      "name": "Sobremesa Grátis",
      "price_mt": 50,
      "points_required": 500,
      "stock": 100
    },
    {
      "name": "Desconto 10%",
      "price_mt": null,
      "points_required": 1000,
      "stock": null
    }
  ]
}
```

### Resgatar Prémio Específico (Troca):
```json
POST /api/campaigns/scan
{
  "qrCode": "...",
  "prizeId": "id_do_premio" // ou "name_do_premio"
}
```

## Próximos Passos

1. Implementar job/cron para processar sorteios automaticamente
2. Implementar decremento de pontos após vencer
3. Criar endpoint para listar prémios disponíveis de uma campanha de troca
4. Adicionar validação de periodicidade no processamento de sorteios
5. Documentar API para frontend











