">
VICTOR SAAD
All buildsTodos os projetos
FastAPI · PostgreSQL · hand-written SVG
FastAPI · PostgreSQL · SVG escrito à mão

Painel — the front door

Painel — a porta de entrada

A dozen services is eleven too many tabs. The data was all there, and none of it was in one place.

Uma dúzia de serviços são onze abas a mais. Os dados estavam todos lá, e nenhum num lugar só.

FastAPIpsycopgPostgreSQLES modulesSVGsystemd

The problemO problema

The homelab grew one service at a time, each justified on its own. Collectively they became a bookmarks folder I had to work through every morning to find out whether anything needed me.

O homelab cresceu um serviço por vez, cada um justificado por si só. Juntos, viraram uma pasta de favoritos que eu precisava percorrer toda manhã para saber se alguma coisa precisava de mim.

Aggregate, don't duplicate

Agregar, não duplicar

The rule the whole design follows: the panel reads from the systems that own the data and stores almost nothing itself. The moment it starts keeping its own copy, there are two answers to every question and a sync job to get wrong.

A regra que guia todo o design: o painel lê dos sistemas donos dos dados e quase não guarda nada. No momento em que ele começa a manter a própria cópia, passa a haver duas respostas para cada pergunta e um job de sincronização para dar errado.

Each section is a folder — queries, its own route, its own front-end module — so a new one drops in without touching the others.

Cada seção é uma pasta — queries, rota própria, módulo de front-end próprio —, então uma nova entra sem mexer nas outras.

Where the numbers come from

De onde vêm os números

The metric SQL wasn't rewritten from scratch. It was lifted out of the Metabase dashboard I already used and trusted, and each query carries the source card's ID in a comment next to it. So when a number looks wrong there's a path back to the original definition instead of two plausible queries and no tiebreaker.

O SQL das métricas não foi reescrito do zero. Saiu do dashboard do Metabase que eu já usava e em que confiava, e cada query leva num comentário o ID do card de origem. Então, quando um número parece errado, existe um caminho de volta à definição original, em vez de duas queries plausíveis e nenhum critério de desempate.

A parity test asserts the panel and Metabase agree. If they diverge, the adaptation is wrong — and two adaptations were genuinely needed and are documented at the top of the file, because one card used Metabase's optional-filter syntax that isn't valid SQL outside it, and another read a view rather than the raw table.

Um teste de paridade garante que o painel e o Metabase batem. Se divergirem, a adaptação está errada — e duas adaptações foram de fato necessárias e estão documentadas no topo do arquivo: um card usava a sintaxe de filtro opcional do Metabase, que não é SQL válido fora dele, e outro lia uma view em vez da tabela bruta.

No build step, on purpose

Sem build step, de propósito

One HTML file and an ES module per section. Charts are hand-written SVG rather than a charting library, because the home page has to open on the LAN with the internet down, and every CDN dependency is a way for that to fail. It costs a few hours of writing axis code once and buys a page that will still work in five years.

Um arquivo HTML e um ES module por seção. Os gráficos são SVG escrito à mão, e não uma biblioteca de gráficos, porque a página inicial precisa abrir na rede local com a internet fora do ar, e cada dependência de CDN é uma forma de isso falhar. Custa algumas horas escrevendo código de eixo uma vez só e compra uma página que ainda vai funcionar daqui a cinco anos.

Screenshots withheld: the financial module is the one that's live, and it renders real balances. The architecture is the interesting part anyway.
Sem capturas de tela: o módulo no ar é o financeiro, e ele mostra saldos reais. A arquitetura é a parte interessante, de qualquer forma.

Want to talk about this? I'm happy to walk through how it was built.Quer conversar sobre isso? Mostro com prazer como foi construído.