# BriefScore — Especificação de Projecto

## Contexto

Projecto desenvolvido numa agência de comunicação com o objectivo de monitorar a **satisfação dos criativos relativamente às passagens de briefing**. Os questionários são completamente anónimos.

---

## Stack Tecnológica

- **Frontend:** HTML, CSS, JavaScript (vanilla)
- **Backend:** PHP
- **Base de dados:** MySQL

### Credenciais de Base de Dados

```
host: nossavistbai.mysql.db
database: nossavistbai
user: nossavistbai
password: Nossa2050
```

### Envio de Email (PHPMailer)

```
email: brief.score@nossavisao.pt
password: Nossa2050#
```

---

## Estrutura de Páginas

### 1. `/questionnaire.php?id={TOKEN}`

Página pública onde os criativos respondem ao questionário.

**Comportamento:**
- Recebe um `id` único por URL (ex: `omeulink.pt?id=4AS324fnsjd4r32`)
- Esse `id` é o identificador do registo na base de dados
- Se o questionário já foi submetido com esse `id`, mostra mensagem de agradecimento: *"Obrigado por responderes!"*
- Se o `id` for inválido ou não existir, mostrar erro adequado

**Campos do questionário:**
1. **Cliente** — dropdown de selecção (lista gerida no dashboard)
2. **Account** — dropdown de selecção (lista gerida no dashboard)
3. **Perguntas livres** — campos de texto carregados dinamicamente da tabela `questions`, por ordem de `position`

> Os enunciados das perguntas são configuráveis no dashboard. O número de perguntas é variável.

---

### 2. `/sender.php`

Página interna para notificar criativos por email.

**Funcionalidades:**
- Campo de email com **autocomplete** baseado nos emails de criativos registados no dashboard
- Ao submeter, gera um token único (ex: `bin2hex(random_bytes(16))`)
- Cria registo na BD com esse token e estado `pending`
- Envia email ao criativo via PHPMailer com o link: `https://dominio.pt/questionnaire.php?id={TOKEN}`

---

### 3. `/dashboard.php`

Página interna com duas tabs principais.

---

#### Tab A — Gestão de Conteúdos

Gestão de todas as entidades configuráveis do sistema.

**Secções:**

**Clientes**
- Listar, adicionar, editar e remover clientes
- Campos: `nome`

**Accounts**
- Listar, adicionar, editar e remover accounts
- Campos: `nome`

**Criativos (Emails)**
- Listar, adicionar, editar e remover emails de criativos
- Campos: `email`
- Estes emails alimentam o autocomplete do Sender

**Perguntas Livres**
- Listar, adicionar, editar e remover perguntas livres
- Pré-populado com 4 perguntas na instalação, mas o número pode crescer
- A ordem de apresentação no questionário segue o campo `position`

---

#### Tab B — Gestão de Respostas

Listagem e análise das respostas submetidas.

**Filtros:**
- Por **cliente**
- Por **account**

**Tabela de listagem:**

| # | Data | Cliente | Account | Respostas | Acções |
|---|------|---------|---------|-----------|--------|
| 1 | dd/mm/aaaa | Nome | Nome | [Ver] | [Apagar] |

- **Ver:** abre modal ou linha expandida com as 4 respostas livres
- **Apagar:** elimina o registo após confirmação

**Exportação:**
- Botão **"Exportar CSV"** que exporta os registos filtrados (ou todos se sem filtro)

---

## Modelo de Base de Dados

### `clients`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
```

### `accounts`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
```

### `creatives`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE
```

### `questions`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
position TINYINT NOT NULL,  -- define a ordem de apresentação
label TEXT NOT NULL
```
> Pré-popular com 4 perguntas na instalação. Podem ser adicionadas ou removidas via dashboard.

### `questionnaires`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
token VARCHAR(64) NOT NULL UNIQUE,
status ENUM('pending', 'submitted') DEFAULT 'pending',
sent_to VARCHAR(255),          -- email do criativo que recebeu o link
sent_at DATETIME,
submitted_at DATETIME
```

### `responses`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
questionnaire_id INT NOT NULL,  -- FK -> questionnaires.id
client_id INT,                  -- FK -> clients.id
account_id INT,                 -- FK -> accounts.id
FOREIGN KEY (questionnaire_id) REFERENCES questionnaires(id) ON DELETE CASCADE
```

### `response_answers`
```sql
id INT AUTO_INCREMENT PRIMARY KEY,
response_id INT NOT NULL,       -- FK -> responses.id
question_id INT NOT NULL,       -- FK -> questions.id
answer TEXT,
FOREIGN KEY (response_id) REFERENCES responses(id) ON DELETE CASCADE,
FOREIGN KEY (question_id) REFERENCES questions(id)
```

> As respostas às perguntas livres ficam numa tabela separada (`response_answers`), uma linha por pergunta. Assim o modelo suporta qualquer número de perguntas sem alterações de schema.

---

## Fluxo Completo

```
[Sender] Insere email do criativo
    → Gera token único
    → Cria registo em questionnaires (status: pending)
    → PHPMailer envia email com link ?id=TOKEN

[Criativo] Abre o link
    → Se status = submitted → mensagem de agradecimento
    → Se status = pending   → mostra questionário

[Criativo] Submete questionário
    → Grava resposta em responses
    → Actualiza questionnaires.status para submitted

[Dashboard] Consulta respostas
    → Filtra por cliente/account
    → Visualiza respostas individuais
    → Apaga entradas
    → Exporta CSV
```

---

## Notas de Implementação

- **Autenticação:** não existe no MVP — a adicionar numa fase posterior. Dashboard e sender são páginas internas por enquanto
- O anonimato é garantido por não associar o email do criativo às respostas — o `sent_to` fica em `questionnaires` mas não é exposto no dashboard de respostas
- PHPMailer deve ser incluído via Composer (`composer require phpmailer/phpmailer`)
- Usar `PDO` com prepared statements para todas as queries
- O CSV exportado deve incluir: data, cliente, account, e uma coluna por cada pergunta activa (gerado dinamicamente com base nas perguntas existentes no momento da exportação)
