pocketbase-notification-preferences-hooks

# PocketBase Notification Preferences Hooks

## Objetivo

Documentar os hooks externos do PocketBase que provisionam `notification_preferences` automaticamente.

Esses hooks nao ficam neste repositorio. Eles vivem no repositorio `plans-structure`, em:

- `pb_hooks/notification_preferences_provisioning.shared.js`
- `pb_hooks/notification_preferences_provisioning_hooks.pb.js`

O Communications Service depende do resultado desses hooks, porque aplica `notification_preferences` durante a criacao de notificacoes em `POST /internal/notifications`.

## O que os hooks fazem

Os hooks criam preferencias padrao para usuarios e vinculos de usuario com instancia.

Gatilhos atuais:

- `users` depois de criar: provisiona preferencia global `application`
- `user_instance_roles` depois de criar: provisiona `application` e `instance:<instanceId>`
- `user_instance_roles` depois de atualizar: reconcilia `application` e `instance:<instanceId>`

O provisionamento e idempotente:

- procura registro existente por `user` + `scope_key`
- ignora duplicidade causada por corrida de hooks
- registra logs de erro sem bloquear explicitamente o fluxo principal do PocketBase

## Scope keys

O helper externo usa esta regra para montar `scope_key`:

- com instancia e servico: `instance:<instanceId>:service:<serviceId>`
- apenas instancia: `instance:<instanceId>`
- apenas servico: `service:<serviceId>`
- sem instancia e sem servico: `application`

Hoje os gatilhos automaticos provisionam principalmente:

- `application`
- `instance:<instanceId>`

Preferencias por servico podem ser criadas por outro fluxo administrativo quando necessario.

## Defaults atuais

Os hooks criam cada preferencia com:

```txt
in_app_enabled=true
push_enabled=false
email_enabled=false
whatsapp_enabled=false
toast_enable=true
mute_low_priority=false
require_action_push=false
mute_until=null
quiet_hours=null
```

Na pratica, isso deixa a experiencia in-app/toast ligada por padrao, mas mantem push, email e WhatsApp desligados ate o usuario ou um fluxo administrativo habilitar.

## Como o Communications Service usa isso

Durante `POST /internal/notifications`, o servico:

1. busca preferencias do usuario em `notification_preferences`
2. escolhe a preferencia mais especifica para `instanceId` e `serviceId`
3. aplica os flags antes de criar deliveries efetivas

Regras importantes hoje:

- `in_app_enabled` e `toast_enable` controlam `realtime`
- `push_enabled` controla `push`
- `email_enabled` controla `email`
- `whatsapp_enabled` controla `whatsapp`
- `mute_low_priority` suprime notificacoes `low`
- `require_action_push` permite push apenas quando `requireAction=true`
- `mute_until` suprime envios ate a data configurada

`quiet_hours` existe no schema, mas ainda nao e interpretado na ingestao do Communications Service.

## Implicacoes para novos canais

WhatsApp em `notifications` depende desse campo para evitar disparos acidentais.

Pontos importantes:

- provisionar `whatsapp_enabled=false` por padrao
- habilitar `whatsapp_enabled=true` apenas por opt-in ou fluxo administrativo explicito
- garantir que o telefone/WhatsApp do usuario seja tratado como canal opt-in, nao apenas como dado cadastral

Para `reminders`, WhatsApp ja existe como canal no schema atual de reminders. Mesmo assim, se reminders passarem a respeitar preferencias do usuario, o mesmo campo `whatsapp_enabled` deve ser considerado.

## Mudancas esperadas no repositorio dos hooks

Quando atualizar os hooks externos, aplique estes ajustes no `getDefaults()` e na criacao do record:

```js
whatsapp_enabled: false
```

E no bloco de `record.set(...)`:

```js
record.set('whatsapp_enabled', defaults.whatsapp_enabled)
```

## Operacao e debug

Os hooks externos suportam debug por variavel de ambiente:

```txt
DEBUG_NOTIFICATION_PREFERENCES_HOOKS=true
```

Use isso no PocketBase quando precisar investigar provisionamento de preferencias. O Communications Service apenas consome os registros ja gravados.