Pular para o conteúdo
Development

Prateleira de colheita: dando aos itens lançados do Greenhouse um lugar para pousar

Por Victor Da Luz•
rusttaurisveltedev-loggreenhouse

O Greenhouse é o meu gerenciador de projetos criativos com opinião forte. Ideias são capturadas, amadurecem, são trabalhadas através de um pipeline de estágios, e por fim são guardadas no vault (arquivadas, reversível) ou lançadas (publicadas, feito). Eu construí o lado do vault disso faz um tempo: um contador no rodapé, uma tela de navegação, um botão de resgate. O lado do lançamento nunca recebeu o mesmo tratamento.

Uma revisão recente do app inteiro pegou isso: lançar um projeto era write-only. O banco marcava um item como released e carimbava um timestamp, mas nenhum comando jamais listava os itens lançados de volta. O badge “Released” do ItemCard tinha um branch inteiro de switch-case para isso que nunca conseguia de fato renderizar, porque nada nunca entregava a ele um item lançado. O diálogo de confirmação de Publish dizia ao usuário de onde o projeto estava saindo, mas não para onde ia. Funcionalmente: para lugar nenhum. Todo o payoff do pipeline - a coisa que a metáfora da planta chama de Fruiting, Harvest - estava invisível.

Por que esse formato

A tela do vault já era o template certo. Mesmo formato de problema: um status que filtra itens para fora da lista de trabalho principal, uma contagem que precisa de um indicador no rodapé, uma tela de navegação em janela cheia que espelha o próprio shell do dashboard em vez de abrir um modal. Eu não queria inventar um segundo padrão quando um já existia e funcionava. Então o plano foi mecânico: copiar a fiação do vault, trocar o status e a direção da ordenação.

Uma decisão de design de verdade: a ordem de ordenação. A tela do vault ordena do mais dormente para o mais recente, porque o objetivo todo é trazer à tona a coisa que está parada há mais tempo para uma decisão de Resgatar-ou-Manter. O Harvest não tem decisão nenhuma a tomar - é uma prateleira de troféus, não uma fila - então lançamento-mais-recente-primeiro fazia mais sentido. Você quer ver o que acabou de lançar no topo.

Implementação

Do lado do Rust: uma nova query, list_released_by_recency, ordenando por released_at DESC em vez do vaulted_at ASC do vault. Um campo released_count na struct de estado diário, calculado do mesmo jeito que o vaulted_count existente. Dois novos comandos Tauri - get_released_items e open_harvest_folder - ambos cópias quase idênticas dos seus equivalentes do vault.

O único lugar em que de fato tive que pensar em vez de copiar: lançar um projeto é só uma transição de status, nunca move a pasta do item no disco. Um item lançado simplesmente fica onde quer que o estágio terminal do pipeline o tenha colocado (sua pasta de estágio, ex. 60-released/). Então “abrir a pasta inteira do harvest” não pode reaproveitar o caminho fixo 90-vault/ do vault - tem que resolver seja qual for a pasta para a qual o último estágio configurado do pipeline aponta, já que isso é orientado por config e não uma constante hardcoded.

No frontend: um novo HarvestView.svelte, quase uma cópia direta de VaultView.svelte, menos o botão de Rescue - não existe “des-lançar” um projeto, então a única ação por item é Show in Finder. Adicionei um campo released_at ao lado do vaulted_at já existente para que ItemCard pudesse mostrar uma duração “Released 3d ago” ao lado do badge, do mesmo jeito que já mostra “Dormant 12d” para itens no vault.

Gotchas

Adicionar um campo a uma struct compartilhada que é serializada direto para o frontend (DerivedItemState) significa que toda fixture de teste que constrói uma à mão também precisa do campo novo, ou a checagem estrita de object literal do TypeScript acusa. Quinze arquivos tocados, e a lógica real da feature vivia em talvez seis deles. Não é uma reclamação, só um lembrete de que “adicionar um campo” raramente é uma mudança de uma linha quando a cobertura de teste é de verdade.

Também conduzi o app compilado de ponta a ponta com o harness de WebDriver do projeto em vez de confiar só na suíte de testes. Semeei um item lançado direto no arquivo SQLite de um vault descartável, relancei o app de verdade, e cliquei até o fim: o rodapé dizia “Harvest: 1 release”, a tela abriu, o item apareceu com sua duração de lançamento, os dois botões de Show-in-Finder estavam lá. IPC mockado numa suíte de testes prova que a fiação é internamente consistente; não prova que um clique real através de uma webview real de fato renderiza a coisa. Valeu os dez minutos extras.

Resultado

Lançar um projeto agora vai para algum lugar. O branch morto do badge faz alguma coisa. E existe um contador pequeno, deliberadamente barato, de “olha o que você lançou” sentado bem ao lado do indicador do vault - o que, para uma ferramenta cuja premissa de design inteira é combater o instinto de abandonar projetos, pareceu o tipo certo de payoff para tornar visível.

Leitura relacionada

Você também pode achar útil

RackNerd

RackNerd VPS

Hospedagem VPS econômica para serviços leves que funcionam continuamente.

Como afiliado da RackNerd, ganho com compras qualificadas.

Saiba mais
AdGuard

AdGuard para iOS

Bloqueio de anúncios e rastreadores em todo o sistema no iOS, sem necessidade de um servidor DNS separado.

Como afiliado da AdGuard, ganho com compras qualificadas.

Saiba mais
Proton

Proton Pass

Gerenciador de senhas focado em privacidade, da equipe por trás do Proton Mail.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais