---
# System prepended metadata

title: Área de Notificações

---

# Área de Notificações

## Estrutura

- Texto (com limitação de caracteres?);
- Data de envio (DD/MM/AAAA);
- Categorias (Campanhas, Financeiro, Insights);
- Ícone de categoria;
- Notificação lida/não-lida;
- Link de redirecionamento (opcional);
- CTA (opcional);

## Conteúdos

### Campanha
- **Sua campanha "XXXX" está terminando**
-- Direcionamento: Página de campanhas
-- Dados: Campanhas com data de término definidas
-- Periodicidade: 2 dias antes da data de término

### Financeiro
- **Confirmação de crédito**
-- Direcionamento: Página do extrato do financeiro
-- Dados: Transação financeira da conta
-- Periodicidade: Envio pontual

- **RA não realizado por falta de saldo**
-- Direcionamento: Página de financeiro
-- Dados: RA não realizado
-- Periodicidade: Envio pontual

### Insights
- **Campanha com Orçamento Diário abaixo do mínimo**
-- Direcionamento: Página da campanha
-- Dados: Conta com campanha ativa + orçamento diário abaixo do mínimo
-- Periodicidade: Envio único

- **Relatório semanal**
-- Direcionamento: CTA Download
-- Dados: Relatório da semana vigente
-- Periodicidade: Envio semanal

- **Sua campanha "XXXX(PADS)" possui X grupos de anúncio com anúncios abaixo da média. Ajuste agora!**
-- Direcionamento: Página da campanha citada
-- Dados: Campanhas ativas com itens farol vermelho 
-- Periodicidade: Reenvio a cada 15 dias

## Back End
Notas sobre serialização:
 * ObjectId será transformado em string
 * Set será transformado em objeto:
   * { 1, 2, 3 } => { 1: true, 2: true, 3: true}
### Comunicação back <-> front
Investigar: Server sent events, WebSocket. No pior dos casos faremos poll constante.
### Tokens especiais na URL:
`<app>`: Substitui por app.b2wads.com ou app-staging.b2wads.com
`<api>`: Substitui por api.b2wads.com ou api-staging.b2wads.com
`<token>`: Substitui pelo token atual do usuário

Substituições feitas pelo front-end
### Mongo
```typescript=
enum NotificationCategory {
  Campaigns,
  Financial,
  Insights
}

enum NotificationType {
  Manual,
  CampaignEnding,
  CreditConfirmation,
  AutoTransferNoCredit,
  DailyBudgetBelowMinimum,
  PeriodicReport,
  LowAverageCpc,
}

interface Cta {
  type: string;
}

interface RedirectCta extends Cta {
  type: "Redirect";
  url: string;
}

interface Notification {
  id: ObjectId;
  type: NotificationType;
  accountId: ObjectId;
  text: string;
  createdAt: Date;
  category: NotificationCategory;
  clickUrl: string;
  readBy: Set<ObjectId>;
  ctas: Cta[];
}
```

### Interface REST
#### PUT /notifications/read/
Marca todas as notificações do usuário atualmente logado como lidas
##### Retorno
204 No Content, sem body
#### PUT /notifications/{id}/read/
Marca notificação como lida ou não lida pelo usuário atualmente logado
##### Retorno
204 No Content, sem body
##### Body
```typescript=
interface MarkReadParameters {
  read: bool;
}
```

#### GET /notifications/
Endpoint de notificações já existentes
##### Query String
```typescript=
interface GetNotificationsParameters {
  from: String; // Cursor para os próximos elementos
  limit: Number; // Número máximo de notificações à retornar
}
```
##### Retorno
200 OK
###### Body
```typescript=
{
  results: Notification[]; // ordenado por data de criação
  next: String; // Cursor para os próximos elementos
}
```
### GET /notifications/unread
Endpoint de contagem de notificações não lidas
#### Query string
```typescript=
interface GetUnreadCountParameters {
  // campos temporários, remover depois
  userId: String;
  accountId: ObjectId;
}
```
#### Retorno
200 OK
###### Body
```typescript=
Number
```
#### GET /notifications/stream/accountId/{accountId}
Endpoint de server sent events para novas notificações.
##### Query string (enviado na requisição inicial)
```typescript=
interface NotificationStreamParameters {
  // Timestamp da última notificação recebida (via GET /notifications)
  // Usado para fazer enviar notificações 
  // que chegaram entre as duas requisições
  lastReceived: Date; 
}
```
##### Eventos
###### Formato padrão
```typescript=
interface Message<T> {
  type: string;
  payload: T;
}
```
###### Handshake
```typescript=
interface Handshake {}

interface HandshakeMessage extends Message {
  type: "Handshake";
  payload: Handshake;
}
```
###### Nova notificação
```typescript=
interface NewNotificationMessage extends Message {
  type: "NewNotification";
  payload: Notification;
}
```
###### Mensagem marcada como lida ou não lida
```typescript=
interface MessageReadChanged {
  id: ObjectId;
  userId: string;
  read: bool;
}
interface NotificationReadMessage extends Message {
  type: "NotificationReadChanged";
  payload: NotificationReadChanged;
}
```

### Consumidor de mensagens
Precisamos de algum worker que tenha uma fila que receba de múltiplas routing keys e crie as entidades das notificações no MongoDB (e despache para web?)
### Notificações específicas

 * Campanha terminando
   * Cronjob diário?
   * Algo no publicador?
 * Confirmação de crédito
   * Adaptar o Billing para escrever em uma routing key quando ocorrer o crédito
 * RA não realizado por falta de saldo
   * O auto manager já dispara um email para o MNS. Adapter para escrever em routing key
 * Orçamento diário abaixo do mínimo
   * Escrever script para ser executado periodicamente
 * Relatório semanal
   * Cronjob semanal criando notificação enviando para o link do xlsx com filtro da semana pré-definido
 * Anúncio abaixo do CPC médio da categoria
   * Ao fim do ETL do farol de CPC, consultar campanhas abaixo da média e enviar pra routing key de notificações, que confere se há alguma notificação do mesmo tipo nos últimos 15 dias.
 

## Front End

### Geral
- [ ] Jest tests
- [ ] Cypress tests

### Sessão:
- [x] Botão no header (sininho) com badge numerado;
- [x] Espaço de notificações (vide Ajuda);
- [ ] Marcar todas como lida;
- [ ] Scrollable ("paginação" automática);

### Modelo unitário:
- [x] ~~Ícone da categoria;~~
- [x] ~~Texto;~~
- [x] ~~Data de envio (DD/MM/AAAA);~~
- [x] ~~Hover: botão opções (Marcar como lida/não-lida);~~
- [x] ~~Card clicável (link de redirecionamento de acordo com categoria)~~;
- [x] ~~Botão CTA~~;

### Marcar como lida/não-lida:
- [ ] Atualizar `unreadNotifications` ao marcar notificação;
- [ ] Atualizar `unreadNotifications` ao marcar todas notificações;

### Outros
- ~~altText ou title do ícone com nome da categoria;~~
- Ao receber notificação nova enquanto dentro da plataforma, atualizar número de notificações (sem toaster);


### Links úteis

[Miro](https://miro.com/app/board/o9J_laq5T8Y=/)
[Figma](https://www.figma.com/file/n9OrzASBYNiNMmqgRlBppY/Notifica%C3%A7%C3%B5es)
[Server sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
[Shared worker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)
[Frontend PR Github](https://github.com/b2wads/b2wads-webapp/pull/395)