Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md → CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CLAUDE.md
# Contribuir para o Vozen Helper

Guia para agentes de IA a trabalhar no **Vozen Helper** (bot de moderação privado).
Regras e guia de desenvolvimento do **Vozen Helper** (bot de moderação privado).

## Comandos

Expand Down
14 changes: 13 additions & 1 deletion docs/PLAN-CONFIG-COMUNIDADE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Plano — Ativar as features de comunidade no Vozen Support

> Planeado com Fable 5 (2026-07-13). Execução: Opus. O bot e as features já estão
> Planeado em 2026-07-13. O bot e as features já estão
> no VPS; isto é o plano de CONFIGURAÇÃO (canais, cargos, IDs) para as tornar vivas.

## Objetivo
Expand All @@ -26,19 +26,23 @@ canal de painel de tickets, canal de transcripts, cargos de nível.
## Scope

### In

- Criar 4 canais + 1 canal de voz + 3 cargos de nível (via script one-shot com o token do bot).
- Preencher `modConfig.community` com os IDs; build + deploy + restart no VPS.
- Painéis publicados (`/ticket-panel`) e verificação de cada feature.

### Out

- Boas-vindas e aniversários (REMOVIDOS a pedido do Diogo — não recriar).
- Self-roles `/rolepanel` (já funciona sem config; o Diogo publica painéis quando quiser).
- Mudanças de lógica/features novas; XP de voz; rank cards em imagem.

## Fases

### Fase 1 — Criar a infraestrutura no Discord (script one-shot)

Deliverable: canais e cargos criados, IDs impressos.

- [ ] Script `tools/setup-community.mjs` (usa DISCORD_TOKEN/GUILD_ID do .env; correr LOCALMENTE uma vez):
- [ ] Texto `₊˚ʚ💡୧﹕sugestões` na categoria "Canais de Texto" — escrita bloqueada para @everyone (só o bot posta; membros usam /suggest)
- [ ] Texto `₊˚ʚ⭐୧﹕destaques` (starboard) na mesma categoria — escrita bloqueada para @everyone
Expand All @@ -50,7 +54,9 @@ Deliverable: canais e cargos criados, IDs impressos.
- **Done**: script imprime o mapa nome→ID completo, sem erros.

### Fase 2 — Preencher a config

Deliverable: `src/config.ts` com o bloco `community` real. Dependências: Fase 1 (IDs).

- [ ] `suggestions.channelId` = #sugestões
- [ ] `memberCounter.channelId` = canal de voz 📊; `template: '📊 Membros: {count}'`
- [ ] `leveling.announceChannelId` = #general-chat (servidor pequeno — canal dedicado seria deserto); `levelRoles: [{5,🥉},{10,🥈},{20,🥇}]`; `stackRoles: false` (substitui — mostra só o marco mais alto); `noXpChannelIds: [mod-helper-bot, bot-testing]` (anti-farm em canais de bot)
Expand All @@ -60,14 +66,18 @@ Deliverable: `src/config.ts` com o bloco `community` real. Dependências: Fase 1
- **Done**: typecheck verde; IDs todos validados contra o output da Fase 1.

### Fase 3 — Deploy + ativação

Deliverable: features vivas no servidor. Dependências: Fase 2.

- [ ] `npm run build` + `npx vitest run` verdes localmente
- [ ] tar do `src` → VPS, build no VPS, restart do bot (método habitual: matar o filho, supervisor sobe)
- [ ] Publicar o painel de tickets: `/ticket-panel` no #suporte
- **Done**: bot online (`Vozen Helper pronto` no log), contador de voz renomeado com o nº real.

### Fase 4 — Verificação feature a feature

Deliverable: prova de que cada uma funciona.

- [ ] `/suggest teste` → embed #1 em #sugestões, votos 👍/👎 respondem
- [ ] Contador de voz mostra "📊 Membros: N" correto
- [ ] Mensagem no #general-chat dá XP; `/rank` responde; (o level-up 5 só se testa com uso real)
Expand All @@ -77,13 +87,15 @@ Deliverable: prova de que cada uma funciona.
- **Done**: checklist toda verde; pedir ao Diogo para confirmar visualmente.

## Riscos

- **Permissões do script**: criar canais/cargos exige `Manage Channels`/`Manage Roles` — o bot tem ambas; se algum overwrite falhar (ex.: connect do canal de voz), criar na mesma e avisar, não abortar.
- **Cargos de nível acima do bot**: o script cria-os automaticamente ABAIXO do cargo do bot — sem risco de hierarquia.
- **Starboard em servidor pequeno**: threshold 3 pode banalizar os destaques; é config de 1 linha se o Diogo quiser subir para 4–5.
- **Bump reminder inerte**: sem o bot DISBOARD no servidor nunca dispara — comportamento esperado, não é bug.
- **Level-ups no #general-chat**: se vier a incomodar, muda-se `announceChannelId` para um canal dedicado (1 linha).

## MVP

Fim da Fase 3: tudo configurado e vivo. A Fase 4 é a prova.

**Próxima ação concreta: escrever `tools/setup-community.mjs` (Fase 1) e corrê-lo uma vez para criar os canais/cargos e obter os IDs.**
32 changes: 21 additions & 11 deletions docs/PLAN-GDPR.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Plano — Conformidade GDPR do Vozen Helper (site + API + bot)

> Planeado com Fable 5 (2026-07-15). ✅ EXECUTADO (2026-07-15, Opus). Fases 1–4 feitas.
> Planeado em 2026-07-15. ✅ EXECUTADO em 2026-07-15. Fases 1–4 feitas.
> Entregáveis: `docs/GDPR-INVENTARIO.md`; `site/privacidade.html` + link no gate (no ar);
> `src/store/gdpr.ts` (purga/export/apagar) ligado ao arranque e ao member-leave;
> comando `/privacidade dados|apagar`; `deploy/vozen-panel-logrotate.conf`.
Expand All @@ -23,6 +23,7 @@ de conformidade. Tu és o responsável pelo tratamento (controller); Discord, Gi
## Scope

### In

- Inventário de dados pessoais (registo de tratamento simplificado, art. 30.º).
- Página de **Política de Privacidade** no site (pt-PT) + link visível no gate.
- Retenção: purga automática de dados antigos na BD e rotação de logs no VPS.
Expand All @@ -32,6 +33,7 @@ de conformidade. Tu és o responsável pelo tratamento (controller); Discord, Gi
sem banner de consentimento, mas com menção na política).

### Out

- Banner de cookies (não há trackers, analytics nem cookies não-essenciais — não é preciso).
- DPO, DPIA formal, representante na UE (escala não o exige).
- Contratos DPA formais com GitHub/Cloudflare/Discord (usam os termos standard deles; só divulgar).
Expand All @@ -41,42 +43,50 @@ de conformidade. Tu és o responsável pelo tratamento (controller); Discord, Gi
## Fases

### Fase 1 — Inventário de dados (registo de tratamento)

Deliverable: `docs/GDPR-INVENTARIO.md` — tabela: dado → onde vive (tabela BD / log /
localStorage / cookie) → finalidade → base legal → retenção proposta. Dep.: nenhuma.

- [ ] Mapear as ~20 tabelas da BD (`src/store/db.ts`) + `api.log` + logs do túnel +
localStorage/cookie do painel.
localStorage/cookie do painel.
- [ ] Classificar base legal por dado: **interesse legítimo** (moderação: cases, notes,
infractions, quarantine, anti-raid), **consentimento por ato voluntário** (birthdays,
AFK, lembretes, votos, giveaways), **interesse legítimo** (stats/levels — a validar).
infractions, quarantine, anti-raid), **consentimento por ato voluntário** (birthdays,
AFK, lembretes, votos, giveaways), **interesse legítimo** (stats/levels — a validar).
- [ ] Propor retenção por categoria (ex.: cases 2 anos, stats 1 ano, api.log 30 dias).
- **Done:** cada dado pessoal identificado tem linha na tabela com os 5 campos preenchidos.

### Fase 2 — Política de privacidade no site

Deliverable: `site/privacidade.html` publicada + link no gate. Dep.: Fase 1 (a política
descreve o que o inventário apurou — sem inventário, a política mente).

- [ ] Redigir em pt-PT claro: quem é o responsável, que dados, para quê, base legal,
retenção, com quem se partilha (Discord/GitHub/Cloudflare/VPS), direitos e como
exercê-los (contacto Discord), cookie `vh_session` + localStorage.
retenção, com quem se partilha (Discord/GitHub/Cloudflare/VPS), direitos e como
exercê-los (contacto Discord), cookie `vh_session` + localStorage.
- [ ] Página estática com os tokens visuais do painel; link "Privacidade" no rodapé do gate.
- [ ] Mencionar a política na descrição do bot / canal de regras do servidor (os membros
do servidor são os titulares — têm de conseguir encontrá-la).
do servidor são os titulares — têm de conseguir encontrá-la).
- **Done:** URL pública abre a política; gate tem link visível; membros conseguem chegar lá.

### Fase 3 — Retenção e minimização

Deliverable: purga automática na BD + rotação de logs. Dep.: Fase 1 (os prazos vêm do inventário).

- [ ] Job diário no bot: apagar/anonimizar registos além da retenção (cases antigos →
manter contagem, apagar user_id? decidir na Fase 1; stats/levels de quem saiu do servidor).
manter contagem, apagar user_id? decidir na Fase 1; stats/levels de quem saiu do servidor).
- [ ] Rotação do `api.log` no VPS (logrotate ou truncagem no supervisor, 30 dias).
- [ ] Auditar o `api.log`: registar ações, não dados desnecessários.
- [ ] Testes (vitest) da função de purga: TDD como o resto do projeto.
- **Done:** inserir registo com timestamp antigo + correr purga → desaparece; log não cresce sem limite.

### Fase 4 — Direitos dos titulares

Deliverable: comandos Discord de exportação e apagamento. Dep.: Fases 1 e 3.

- [ ] `/privacidade dados` — DM com JSON de tudo o que a BD tem sobre o requerente.
- [ ] `/privacidade apagar` — apaga dados voluntários (birthday, AFK, lembretes, votos,
XP…) com confirmação; **recusa fundamentada** para registos de moderação ativos
(interesse legítimo prevalece — art. 17.º/3) com resposta clara a dizê-lo.
XP…) com confirmação; **recusa fundamentada** para registos de moderação ativos
(interesse legítimo prevalece — art. 17.º/3) com resposta clara a dizê-lo.
- [ ] Registar pedidos de apagamento (data + user) para prova de cumprimento.
- [ ] Testes de ambos os comandos.
- **Done:** conta de teste recebe o seu JSON completo; após apagar, `/privacidade dados`
Expand All @@ -95,7 +105,7 @@ Deliverable: comandos Discord de exportação e apagamento. Dep.: Fases 1 e 3.

## Riscos

- **Isenção doméstica é ambígua:** um servidor Discord privado *pode* cair fora do GDPR
- **Isenção doméstica é ambígua:** um servidor Discord privado _pode_ cair fora do GDPR
(uso pessoal, art. 2.º/2-c), mas a jurisprudência trata comunidades com membros como
tratamento real. Assumimos que o GDPR se aplica — se não se aplicar, o trabalho fica
a mais, nunca a menos. Custo baixo, risco eliminado.
Expand Down
Loading
Loading