Skip to content

PIN único e modo de edição que expira ao fim de uma hora (v3.23.0) - #82

Merged
qzte merged 1 commit into
mainfrom
claude/loving-cori-68ipij
Sep 14, 2026
Merged

qzte merged 1 commit into
mainfrom
claude/loving-cori-68ipij

Conversation

@qzte

@qzte qzte commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Ponto #13 do plano, com a intenção corrigida: o PIN não é para proteger informação — é fricção deliberada, para que concluir passos do workflow seja sempre um acto consciente e nunca um clique distraído.

O que muda

1 · Um PIN só: SUPERMERCADO

Eram seis, um nome próprio por pessoa — seis nomes de colegas numa página pública, sem que isso protegesse fosse o que fosse. A lista continua a ser uma lista: acrescentar outro é acrescentar uma entrada.

2 · O modo de edição expira uma hora depois de o PIN ser aceite

Contagem absoluta e não por inactividade, de propósito: quem está a editar sem parar é precisamente quem deve voltar a parar. Uma sessão aberta de manhã ficava aberta o dia inteiro, e o travão diluía-se para uma vez por dia.

A expiração fecha os dois modos de edição — o React (separador Tracking) e o imperativo (separador Workflow) —, que o mesmo PIN abre conforme a vista. Fechar só um deixava-os a discordar, que é a família de bugs que esta aplicação já tem de sobra.

Expirar não perde trabalho. O deactivateWorkflowEditor grava o workflow ao sair, os processos continuam na sessão e o aviso ● não guardado mantém-se visível. O que desaparece são os controlos de edição — incluindo o 💾 Guardar backup —, que voltam com o PIN. O aviso in-app diz exactamente isso.

A saída forçada não pergunta nada, ao contrário da saída manual: ao fim de uma hora pode não estar ninguém à frente do ecrã, e uma pergunta sem resposta deixaria o editor aberto — que é precisamente o que a expiração existe para evitar.

A intenção fica escrita

O código e o README passam a dizer para que serve o PIN, com as duas advertências que faltavam e que apontam em sentidos opostos:

  • não o transformar em autenticação — hashear ou cifrar no cliente é teatro, porque a chave viaja com a fechadura;
  • não o remover por parecer inútil — o travão é a funcionalidade.

Guardas no build

Isto é do género de coisa que desaparece sem dar erro nenhum. O build.mjs falha se o expirarSessaoEditor deixar de existir, se o confirmPinModal deixar de armar a contagem, ou se a expiração deixar de fechar um dos dois modos.

Testes

Seis testes novos, em dois grupos, porque provam coisas diferentes:

Grupo O que exerce
a sessão expira e fecha os dois editores o que o temporizador chama: fechar ambos os modos, não perder dados, o aviso, e o PIN devolver o modo
expira à hora, não antes o próprio temporizador, com o relógio do Playwright — aberto aos 59 minutos, fechado aos 61

A separação não é zelo: uma expiração ligada a um setTimeout que nunca chega a ser armado passaria no primeiro grupo inteiro.

npm run ci passa (86 unitários, lint, validate, build). Nos testes de browser todos os funcionais passam; as falhas restantes são o ERR_CERT_AUTHORITY_INVALID do proxy TLS deste ambiente, que varia entre 12 e 14 conforme o momento em que o pedido ao Google Fonts falha.

Fora do âmbito, mas registado

Duas coisas que valem por si e não são sobre o PIN: proteger main com um ruleset (é o que protege mesmo a escrita) e não comprometer dados reais no repositório público (hoje o supermercados_backup.json ainda está vazio). Ficam para quando quiseres.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XwDMNpJzcA3Z2nP3jjwuJd


Generated by Claude Code

O PIN não protege informação nenhuma — está em texto simples no ficheiro
servido, que é público, e o estado oficial dos dados é protegido pelo acesso de
escrita ao repositório. O que ele faz é obrigar a um acto consciente antes de se
concluir passos do workflow: fricção deliberada, para que avançar um processo
nunca seja um clique distraído. Isso passa a estar escrito no código e no
README, com as duas advertências que faltavam: não o transformar em
autenticação (hashear ou cifrar no cliente é teatro, a chave viaja com a
fechadura) e não o remover por parecer inútil (o travão é a funcionalidade).

  · os seis PINs — um nome próprio por pessoa, seis nomes de colegas numa
    página pública — passam a um só, `SUPERMERCADO`;
  · o modo de edição expira **uma hora depois de o PIN ser aceite**. Contagem
    absoluta e não por inactividade, de propósito: quem está a editar sem parar
    é precisamente quem deve voltar a parar. Uma sessão aberta de manhã ficava
    aberta o dia inteiro, e o travão diluía-se para uma vez por dia.

A expiração fecha os **dois** modos de edição — o React, do separador Tracking,
e o imperativo, do separador Workflow —, que o mesmo PIN abre conforme a vista
em que se está. Fechar só um deixava-os a discordar, que é a família de bugs que
esta aplicação já tem de sobra.

Expirar não perde trabalho: o `deactivateWorkflowEditor` grava o workflow ao
sair, os processos continuam na sessão e o aviso `● não guardado` mantém-se. O
que desaparece são os controlos de edição, incluindo o "Guardar backup", que
voltam com o PIN. O aviso in-app diz isso.

A saída forçada (`__forceEditorExit`) não pergunta nada, ao contrário da saída
manual: ao fim de uma hora pode não estar ninguém à frente do ecrã, e uma
pergunta sem resposta deixaria o editor aberto — precisamente o que a expiração
existe para evitar.

Guardas no build, porque isto desaparece sem dar erro: falha se o
`expirarSessaoEditor` deixar de existir, se o `confirmPinModal` deixar de armar
a contagem, ou se a expiração deixar de fechar um dos dois modos.

Seis testes de browser novos, em dois grupos. O primeiro exerce o que o
temporizador chama — fechar os dois editores, não perder dados, o PIN devolver
o modo. O segundo exerce o temporizador, com o relógio do Playwright: aberto aos
59 minutos, fechado aos 61. São coisas diferentes — uma expiração ligada a um
`setTimeout` que nunca é armado passaria no primeiro grupo inteiro.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwDMNpJzcA3Z2nP3jjwuJd
@qzte
qzte marked this pull request as ready for review September 14, 2026 21:07
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@qzte
qzte merged commit d98ac18 into main Sep 14, 2026
3 checks passed
@qzte
qzte deleted the claude/loving-cori-68ipij branch September 14, 2026 21:07
Sign up for free to 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