feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(privacidade): exportar dados e excluir conta - #240

Open
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao
Open

feat(privacidade): exportar dados e excluir conta#240
Jovinull wants to merge 3 commits into
Cla-Code-Community:developfrom
Jovinull:feature/pav-41-lgpd-exportacao-exclusao

Conversation

@Jovinull

Copy link
Copy Markdown
Contributor

Card

O que foi feito

  • Adicionados os endpoints autenticados GET /users/export e DELETE /users/account.
  • A exportação retorna perfil, preferências, vagas salvas, eventos de candidatura, notificações, keywords e provedores conectados, sem senhas, tokens, hashes ou campos internos de criptografia.
  • Incluído painel de privacidade no perfil para exportar os dados e confirmar a exclusão definitiva da conta.
  • Ajustada a chave de auditoria para preservar logs sem vínculo ao usuário excluído, evitando bloqueio na exclusão.
  • Documentado o fluxo de exportação e exclusão no README.

Validação

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • npm run test:coverage --workspace=backend — cobertura global: statements 90,58%, branches 81,53%, functions 91,45% e lines 91,32%.
  • npm run test --workspace=frontend — 53 arquivos e 342 testes aprovados.
  • npm run lint --workspace=frontend e npm run build --workspace=frontend aprovados.
  • Fluxo navegável validado em /perfil: exportação iniciou o download de meus-dados.json; exclusão exibiu a confirmação final e enviou a requisição apenas após a segunda ação.

Riscos

  • A exclusão é definitiva após a confirmação e não possui recuperação; esse é o comportamento definido para o fluxo self-service.
  • A migration altera apenas a regra de exclusão da FK de auditoria; os logs são mantidos com actor_id nulo.

Evidências

  • Testes de integração cobrem autorização, exportação, validação da confirmação, exclusão e invalidação da sessão.
  • Testes unitários cobrem a remoção de hashes/campos criptografados no export e o tratamento de conta inexistente.

Checklist

  • Escopo limitado ao card
  • Sem arquivos temporários ou gerados desnecessários
  • Sem segredo/token em código
  • Testes locais executados
  • Documentação atualizada

hltavand others added 2 commits August 23, 2026 18:32
…ode-Community#230)
## Linear
Issue: PAV-119
Closes PAV-119
## Branch flow
- [ ] Este PR é uma feature/fix/chore destinada a `develop`.
- [x] Este é um PR de release com origem `develop` e destino `master`.
- [x] Este PR não pula o fluxo obrigatório entre `develop` e `master`.
## Objetivo
Promover para `master` a implementação do lock distribuído do scraper,
garantindo no máximo uma execução ativa do pipeline entre diferentes
origens de disparo.
## Resumo das Alterações
- Implementa lock distribuído no Valkey compartilhado por cron, execução
manual administrativa e cache miss de `/scrape`.
- Utiliza aquisição atômica com `SET NX PX`, TTL e renovação periódica.
- Protege renovação e liberação por ownership/token.
- Implementa comportamento fail-closed quando o Valkey não confirma a
aquisição.
- Cancela a execução de forma segura em caso de perda do lock.
- Adiciona estado operacional com `runId`, origem, início e expiração
sem expor o token proprietário.
- Adiciona contratos HTTP para execução concorrente e indisponibilidade
do run lock.
- Alinha os defaults de `SCRAPER_RUN_LOCK_TTL` e
`SCRAPER_RUN_LOCK_RENEW_INTERVAL` à semântica fail-fast definida
anteriormente.
- Adiciona cobertura de testes para concorrência, ownership,
configuração, renovação, liberação e cenários de falha.
- Atualiza documentação e configuração do Docker Compose.
## Arquivos e Módulos Afetados
- Scraper Go
- Run lock / Valkey
- Scheduler e pipeline do scraper
- Backend administrativo
- Configuração do scraper
- Docker Compose
- Testes Go e backend
- Documentação operacional
## Validação
- [x] Implementação revisada contra o escopo da PAV-119.
- [x] Ajustes solicitados no code review aplicados.
- [x] Semântica fail-fast das configurações do run lock validada.
- [x] Nenhuma alteração de frontend incluída no escopo.
- [ ] CI final do PR de release validado.
## Observações
Este PR promove alterações já integradas e revisadas em `develop`.
Não realizar squash ou alterações adicionais diretamente em `master`
fora do fluxo de release.

@hltavhltav left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A implementação cobre boa parte do fluxo previsto na PAV-41, porém ainda existem dois pontos que precisam ser tratados antes da aprovação.

Primeiro, há uma dependência de integração com outra alteração de schema atualmente em review. O PR introduz uma migration com a mesma sequência utilizada por outro PR aberto, incluindo snapshot e journal do Drizzle. Antes do merge, será necessário reconciliar a ordem das migrations e regenerar os artefatos de schema com base no estado atualizado da develop.

Segundo, o fluxo de exclusão ainda não garante integralmente o critério de remoção/anonimização dos dados relacionados ao usuário. A alteração da FK de auditoria permite excluir a conta preservando os logs, porém remover apenas o vínculo direto com o usuário não garante, por si só, que os registros restantes deixem de conter dados identificáveis.

Revise o tratamento dos registros preservados após a exclusão, em especial os campos potencialmente correlacionáveis ou pessoais, e adicione cobertura garantindo que o estado final esteja de acordo com o critério de anonimização da PAV-41.

Após esses ajustes e a reconciliação das migrations, o PR pode voltar para revisão.

@Jovinull

Copy link
Copy Markdown
ContributorAuthor

Atualização aplicada em resposta ao review.

Além da FK com ON DELETE SET NULL, a exclusão self-service agora anonimiza previamente os logs de auditoria relacionados ao usuário: actor_id, target_id, metadata e ip são limpos. Isso cobre tanto logs em que o usuário era o ator quanto registros administrativos que poderiam carregar o ID, e-mail ou username do usuário excluído.

Também atualizei a documentação e adicionei cobertura unitária para confirmar o payload de anonimização antes da remoção.

Validação:

  • npm run test --workspace=backend — 61 arquivos e 575 testes aprovados.
  • Testes de privacidade e rotas — 22 testes aprovados.
  • O pre-push executou a suíte backend e iniciou lint/build do frontend com sucesso.

A migration 0014 continua precisando ser reconciliada com a sequência final da develop no merge, conforme o comentário anterior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Jovinull@hltav