# Limitador de ritmo — geração de certificados (n8n + Google Slides)

**Problema:** o app dispara um webhook por certificado; 100 certificados = 100 execuções
no mesmo segundo = ~200 escritas no Slides (limite: 60 por minuto por usuário) → erro 429.

**Solução:** antes de tocar no Slides, cada execução pede uma *vaga com hora marcada* ao
banco e espera o seu turno (nó Wait). As execuções passam a começar uma a cada
`intervalo_segundos` (padrão 5 s = 12 certificados/min = 24 escritas/min).

## O que muda (e o que NÃO muda)

| Mudança | Detalhe |
|---|---|
| NOVA tabela `procrt_limitador` | 1 linha, interna do n8n (RLS ligada, sem acesso para o app) |
| NOVA função `procrt_reservar_vaga()` | só o `service_role` (n8n) executa |
| +2 nós no workflow | `reservar-vaga-slides` e `aguardar-vez-slides`, entre `isFinal` (saída *true*) e `row_certificado` |

Não muda: `pro_crt`, views, policies, o app FlutterFlow, a URL do webhook, o JWT, nem
nenhum nó existente do workflow (só uma ligação é trocada).

## Passo a passo

### 1) Banco (uma vez)
Supabase → SQL Editor → colar e executar `sql/001_procrt_limitador.sql`.
Pode rodar de novo sem problema. Para conferir: `select * from public.procrt_limitador;` (1 linha).

### 2) n8n — colar os 2 nós
1. Abra o workflow de gerar certificado.
2. Abra `n8n/nos-limitador.json`, copie TODO o conteúdo (Ctrl+A, Ctrl+C).
3. Clique numa área vazia do canvas e cole (Ctrl+V). Entram os 2 nós já ligados entre si.
4. Arraste-os para ficar entre `isFinal` e `row_certificado`.

### 3) n8n — trocar uma ligação
1. Apague a ligação `isFinal (true)` → `row_certificado` (passe o mouse nela → lixeira).
2. Ligue `isFinal (true)` → `reservar-vaga-slides`.
3. Ligue `aguardar-vez-slides` → `row_certificado`.
4. **Salve** o workflow (ele continua ativo; a troca vale na hora).

Ficando assim: `isFinal ─true→ reservar-vaga-slides → aguardar-vez-slides → row_certificado → …`

### 4) Conferir
Gere 3 ou 4 certificados de uma vez. Em *Executions*, os primeiros ficam *Running*/*Waiting*
e os seguintes começam de 5 em 5 segundos. Todos terminam normalmente.

## Se o limitador falhar, o certificado sai igual
`reservar-vaga-slides` tenta 3 vezes e, se o banco não responder, segue sem esperar
(comportamento de hoje). O limitador nunca impede a geração.

## Ajustes (SQL Editor)
```sql
-- mais devagar (8 s entre certificados) ou mais rápido (3 s)
update public.procrt_limitador set intervalo_segundos = 8 where id = 1;

-- ver o estado
select * from public.procrt_limitador;

-- "esvaziar" a fila de reservas (quem já está esperando no n8n continua esperando)
update public.procrt_limitador set proxima_vaga = now() where id = 1;
```
Quanto tempo leva? `quantidade × intervalo`: 100 certificados × 5 s ≈ 8 min.
Cada certificado gasta 2 escritas no Slides: 60 ÷ 2 = 30/min é o teto; 5 s (12/min) deixa folga.

## Outros workflows que usam o Slides com a MESMA credencial
A cota é por usuário Google, então vale para todos. Se houver outro fluxo (modelo/template)
que usa `credential-sistemas-gslides`, cole os mesmos 2 nós nele: a função é a mesma, e
as vagas passam a ser divididas entre todos.

## Desfazer
Religar `isFinal (true)` → `row_certificado` e apagar os 2 nós. A tabela/função podem ficar
(não fazem nada sozinhas) ou sair com:
```sql
drop function if exists public.procrt_reservar_vaga();
drop table if exists public.procrt_limitador;
```
