O problema
Quem joga a sério acumula definições: sensibilidade do rato, teclas, gráficos, áudio, várias versões para o portátil e para o PC principal. Ficam espalhadas por ficheiros de configuração, notas e capturas de ecrã, e perdem-se quando se muda de computador ou se reinstala o jogo.
As ferramentas que existem ou são feitas para um só jogo, ou guardam tudo como texto solto. Eu queria um cofre que funcionasse para qualquer jogo sem integração específica, e que também conseguisse ler e escrever os ficheiros dos jogos mais populares.
O que construí
- Qualquer jogo, qualquer definição. Interruptores, números, sliders, listas, teclas, cores e resoluções, num modelo genérico. Counter-Strike 2 e Rocket League trazem os menus reais, com os nomes e as opções verdadeiras.
- Presets e histórico. Várias configurações por jogo (Principal, Competitivo, Portátil), comparação lado a lado e uma versão guardada a cada alteração, que se pode restaurar.
- Perfil público. Cada pessoa pode partilhar os presets em
/p/<utilizador>, e quem visita pode copiá-los para o seu cofre. - CLI
csync. Deteta os jogos instalados (Steam e Epic), importa os ficheiros de configuração como presets e aplica-os de volta, sempre com cópia de segurança. - Free e Pro. O plano gratuito cobre três jogos; o Pro custa 2,99 €/mês ou 24,99 € uma vez. Quem aloja o projeto no seu servidor tem tudo desbloqueado.
- Os dados são de quem os cria. Exportação completa em JSON, Markdown e CSV, num formato documentado.
Arquitetura
Um só processo Next.js serve a interface e o servidor. As alterações feitas na interface são Server Actions; a CLI fala com route handlers autenticados por token. Tudo fica numa base de dados PostgreSQL.
Tracejado: serviços opcionais. Sem as chaves da Paddle, todos os utilizadores são Pro.
Decisões técnicas
Cada decisão importante ficou registada no repositório, com o contexto e as consequências. Estas foram as que mais moldaram o produto:
01Um só processo, sem API separada
Next.js com Server Actions faz de servidor inteiro. Alojar o projeto é docker compose up: não há fila, nem armazenamento de objetos, nem uma API REST para manter sincronizada com a interface.
02Definições genéricas com valor JSON tipado
Cada jogo tem definições completamente diferentes, por isso não podem ser colunas. Cada definição tem um tipo e um valor em JSONB; a validação, a edição e a apresentação dependem do tipo. Adicionar um tipo novo não mexe nas tabelas.
03Um documento para exportar, importar e guardar histórico
Um único esquema Zod serve a exportação JSON, a importação, as versões do histórico e a comparação. Restaurar uma versão é literalmente importar esse documento.
04Autenticação dentro da própria base de dados
Com better-auth, utilizadores e sessões ficam no mesmo PostgreSQL. Quem aloja o projeto não precisa de nenhum serviço externo de identidade.
05Código aberto, sem perder o negócio
Licença FSL-1.1-MIT: qualquer pessoa pode usar, alterar e alojar para si, mas não oferecer um serviço concorrente. Cada versão passa a MIT ao fim de dois anos. Os planos só se aplicam no servidor oficial.
Qualidade
- TypeScript em modo estrito, com lint e testes unitários num só comando (
pnpm check). - Testes de ponta a ponta com Playwright que percorrem a aplicação em desktop e em mobile.
- Pagamentos testados a sério: uma compra real, reembolsada, para confirmar que o reembolso retira o plano Pro em segundos.
- Migrações versionadas com Drizzle e uma conta de demonstração criada por script.
- Documentação de produto: arquitetura, formato de importação, catálogo de jogos, faturação e um guia de lançamento.
Capturas
A seguir
O plano de produto aposta na parte social: amigos e atividade, configurações de jogadores profissionais verificadas e partilha com origem e versão, para se saber de onde veio cada configuração. Em paralelo, mais jogos no catálogo com os menus reais.