carlos@cesaints: ~/projects/project-office.md — zsh

Comando: cat projects/project-office.md

projects/project-office.md · 1,4 KB

PMO de produto e projetos, com edição simultânea sem perda

Sistema interno para gerir produto, projetos e pessoas: Scrum e Kanban com sprints, backlog priorizado, burndown e velocity, carga por pessoa, dossiê de cada projeto, mapa mental e uma visão executiva. Várias pessoas editam o mesmo projeto ao mesmo tempo sem que uma apague o trabalho da outra, e cada projeto só chega a quem tem permissão, conferida no servidor em toda requisição.

abrir demonstraçãosimulação do sistema com dados fictícios · 6 telas

Papel
Único engenheiro, do produto à operação
Período
jul/2026 – set/2026
O que eu fiz

Eu: Produto, arquitetura, backend na borda sem Node, modelo de dados, sincronização e fusão de edições, segurança do login, todas as telas e os testes.

Projeto privado, descrito sem identificar cliente, produto ou empresa.

Diagrama

Salvar com a versão, fundir no conflito

No navegador, a SPA React salva cada projeto levando a versão que conhece e, periodicamente, checa só a versão atual. O Worker, feito só com Web APIs e sem Node, confere a lista de acesso do projeto em toda requisição e protege o login com PBKDF2 e uma verificação anti-robô que falha fechada; grava no D1 com prepared statements e guarda os arquivos no KV, fora do banco. Se alguém salvou antes, o Worker responde conflito, e o navegador faz a fusão de três vias e reenvia depois de uma espera aleatória.

Contexto

O grupo precisava de um lugar só para gerir produto, projetos e pessoas: sprints, backlog, prazos, a carga de cada um e o porquê das decisões, com várias pessoas mexendo no mesmo quadro ao mesmo tempo.

O que eu construí

  • Execução. Quadro Kanban com arrastar e soltar, e também mover por seleção, para quem usa teclado; sprints com meta e datas; backlog por MoSCoW com pontos Fibonacci; e um dashboard com burndown, velocity, distribuição de tarefas e próximos prazos.
  • Pessoas & Desempenho. Carga contra capacidade, cycle time, throughput de 14 dias e risco de atraso, calculados a partir das tarefas de cada pessoa.
  • Conhecimento. O dossiê de cada projeto (visão, modelo de negócio, OKRs, riscos e decisões), um mapa mental em canvas infinito com organização automática, documentos com visualização no próprio app e um diretório de ferramentas por setor.
  • Visão executiva. Um consolidado por período, por projeto e por pessoa, que soma a mesma pessoa entre projetos pelo e-mail.
  • Colaboração sem perda. Salvamento automático com versão, fusão item a item quando há conflito e as mudanças da equipe aparecendo sozinhas na tela.

O que eu faria diferente

Colocaria o teste de carga com vários editores junto da primeira versão da fusão. O livelock só apareceu quando oito editores salvaram ao mesmo tempo, e a espera aleatória que veio depois poderia ter nascido junto com o tratamento de conflito.

Restrições

  • Várias pessoas editando o mesmo projeto ao mesmo tempo, sem perder trabalho.
  • Cada pessoa vê só os projetos liberados para ela, e quem garante isso é o servidor.
  • Backend no runtime de borda, sem Node e sem ORM.
  • Uma única pessoa técnica para construir e operar.

Decisões

Concorrência otimista com fusão de três vias

Contexto
Cada projeto é salvo como um documento. Com duas pessoas editando, quem salvasse por último apagaria a mudança da outra sem aviso.
Escolha
Cada salvamento leva a versão que o navegador conhece. Se alguém salvou antes, o servidor responde conflito, e o navegador junta base, versão local e versão do servidor item a item (tarefa, sprint, bloco do mapa) e reenvia depois de uma espera aleatória.
Ganhos
  • Conflito vira fusão, e não sobrescrita.
  • A espera aleatória veio de um livelock medido num teste de carga com oito editores.
Custos
  • A fusão precisa conhecer cada tipo de item do documento; um tipo novo pede regra nova.

Sincronização por checagem leve de versão

Contexto
Conexões persistentes trariam mais infraestrutura para um time pequeno, com poucos editores ao mesmo tempo.
Escolha
A cada 4 segundos, com variação aleatória, o navegador pergunta só a versão do projeto, e pausa quando a aba está escondida. Os índices do banco foram criados para esse caminho.
Ganhos
  • Simples e barato, sem conexão aberta.
Custos
  • A mudança de outra pessoa pode levar alguns segundos para aparecer.
  • Tráfego constante, ainda que leve, enquanto a aba está aberta.

Permissão por projeto no servidor, em toda requisição

Contexto
Esconder um projeto na tela não impede um membro de pedi-lo direto à API.
Escolha
Uma lista de acesso usuário × projeto conferida em toda requisição; administradores veem tudo, com salvaguardas para que um administrador não se tranque para fora.
Ganhos
  • Quem não está na lista do projeto não recebe o projeto do servidor.
Custos
  • Toda rota nova precisa aplicar a checagem, o que pede disciplina e um teste a cada rota.

Login que falha fechado

Contexto
Força bruta e robôs são o risco mais óbvio de um sistema na internet, e uma configuração esquecida não pode abrir a porta.
Escolha
PBKDF2 com 100 mil iterações, comparação em tempo constante e o mesmo custo para e-mail inexistente, bloqueio atômico por conta, limite por IP em tabela própria e verificação anti-robô que bloqueia o login quando o segredo não está configurado.
Ganhos
  • Uma configuração ausente bloqueia, em vez de liberar em silêncio.
Custos
  • Um deploy mal configurado tranca todo mundo para fora até ser corrigido.

Stack e por quê

React 18 e Vite
Aplicação de página única servida pelo próprio Worker.
Cloudflare Workers, D1 e KV
Backend em Web APIs do runtime, SQL com prepared statements e arquivos fora do banco.
Recharts e React Flow
Burndown, velocity e distribuição; mapa mental em canvas infinito.
WebCrypto e Turnstile
PBKDF2 sem dependência e verificação anti-robô que falha fechada.
Vitest
Rotas do Worker, segurança, fusão e estado testados no CI.

Resultados

  • 23 arquivos de teste com cerca de 220 casos, cobrindo rotas do Worker, segurança, fusão de edições e estado, rodando no CI.

    repositório privado auditadoTestes e workflow de CI do repositório(Auditoria do repositório privado, set/2026)
  • Uma tabela de rotas única, com um teste que falha se algum handler ficar de fora.

    repositório privado auditadoCódigo do Worker e testes(Auditoria do repositório privado, set/2026)
  • Uma rodada de correção de 19 itens de segurança e de integridade de dados, todos fechados com testes.

    declaradoRegistro de correções do projeto

Ângulo de segurança

Superfície de ataque

  • Login com senha e verificação anti-robô.
  • API de projetos, documentos e usuários.
  • Upload e visualização de documentos no próprio app.
  • Edição simultânea do mesmo projeto.

Controles implementados

  • PBKDF2 com 100 mil iterações, comparação em tempo constante e o mesmo custo para e-mail inexistente.
  • Bloqueio atômico por conta e limite de tentativas por IP.
  • Verificação anti-robô e checagem de origem que falham fechadas.
  • Lista de acesso por projeto conferida em toda requisição.
  • Upload por lista permitida, sem executáveis, e arquivos servidos com política restritiva.
  • Links aceitos só em http e https.

O que eu testaria hoje

  • Um membro pedindo pela API um projeto que não foi liberado para ele.
  • Dois editores salvando o mesmo item no mesmo instante.
  • Uma mutação enviada de outra origem.

Evidências

  • repositório privado auditadoRepositório privado auditado(Auditoria do repositório privado, set/2026)