viniciusrbr.dev
← Todos os projetos

Domus

Aplicação para organizar tarefas domésticas recorrentes entre várias casas — agenda de recorrência fixa, histórico de execuções e status calculado no fuso de quem visualiza.

Next.jsReactTypeScriptTailwindFastifyPostgreSQLPrismaVitest
Capa do projeto Domus

Visão geral

O Domus ajuda uma casa a acompanhar tarefas domésticas recorrentes — limpeza, manutenção, contas — com agenda de recorrência fixa, histórico de execuções e suporte a uma pessoa que pertence a mais de uma casa.

O projeto é dividido em dois repositórios: a API REST (domusapp-api) e o cliente web (domusapp-web), com interface pensada primeiro para o celular. O design do MVP está no Figma.

Funcionalidades

  • Autenticação — cadastro, login, access tokens JWT com refresh tokens rotativos, recuperação de senha e renovação silenciosa de sessão.
  • Múltiplas casas — criar, renomear, excluir e alternar entre casas; cada uma com suas próprias tarefas, categorias e histórico.
  • Tarefas recorrentes — cadências por dia/semana/mês em grade fixa; criar, concluir, editar e excluir, com histórico de execuções por tarefa.
  • Status calculado em tempo realagendada, no prazo, vence hoje ou vencida.
  • Categorias — agrupamento das tarefas dentro de uma casa.
  • Colaboração (em andamento) — links de convite, papéis de membro (owner/admin/member) e transferência de propriedade.

Stack

API: Node.js · TypeScript · Fastify 5 · Prisma 7 · PostgreSQL · Zod 4 · JWT (@fastify/jwt) · Vitest · Biome · OpenAPI/Scalar

Web: Next.js 16 (App Router) · React 19 · TypeScript · TanStack Query · Tailwind CSS v4 · shadcn/ui · React Hook Form + Zod · dayjs · Vitest · Biome

Arquitetura e decisões

Na API, a organização é Clean Architecture com injeção de dependência: controllers → use cases → interfaces de repositório → implementações. As regras de negócio vivem nos use cases e são cobertas por testes unitários rápidos usando repositórios in-memory, então o domínio é testado sem tocar no banco. Os mesmos schemas Zod alimentam a validação em runtime e a geração automática da documentação OpenAPI, servida por uma UI Scalar em /docs — a referência não fica dessincronizada dos handlers.

O motor de recorrência é orientado ao domínio: tarefas recorrentes ficam em uma grade fixa ancorada na data de início, e a próxima ocorrência sempre avança a partir da data agendada, nunca da data real de conclusão — assim, atrasar não desloca silenciosamente a cadência. É um módulo puro e coberto por testes unitários.

O sistema é correto em relação a fuso horário por construção: instantes são armazenados em UTC e datas de recorrência como datas de calendário puras. O status da tarefa (vence hoje / atrasada) é derivado em relação ao dia local de quem está visualizando, o que evita o clássico erro de um dia para usuários em regiões diferentes. No cliente, esse cálculo é um módulo puro e testado — a mesma tarefa pode aparecer como vence hoje para uma pessoa e vencida para outra, corretamente.

Na autorização multi-tenant, as casas usam uma tabela de junção Membership; uma primitiva reutilizável de membership/papel autoriza cada requisição, e a criação de uma casa provisiona o dono atomicamente em uma única transação — sem casas órfãs sem dono. As sessões são seguras por construção: senhas hasheadas e access tokens JWT de vida curta combinados com refresh tokens rotativos persistidos (com hash) no banco.

No cliente web, a arquitetura é feature-first — uma simplificação deliberada. O projeto começou em Clean Architecture em camadas e foi refatorado para fora dela: como o cliente consome uma API externa e não tem domínio próprio a proteger, cada funcionalidade é uma pasta autocontida (types / schemas / api / hooks / components) em vez de lógica espalhada por camadas abstratas. Complexidade é adicionada localmente e sob demanda, nunca de forma global e especulativa.

Há também uma fronteira de mapeamento que a UI nunca cruza: o api.ts de cada feature converte o payload da API em tipos internos e o status HTTP em um único AppError tipado — o shape da API não vaza para os componentes e as mensagens ao usuário são traduzidas em um lugar só. A sessão é resiliente: o access token fica em memória (não no localStorage), um refresh silencioso single-flight o renova no 401 sem estourar requisições paralelas, e a sessão é restaurada no reload via cookie httpOnly de refresh. Os formulários são type-safe com React Hook Form + schemas Zod compartilhados entre a validação do formulário e o request — um schema só, sem divergência.

Testes

A prioridade da cobertura são as regras de negócio — em especial o motor de recorrência e a autorização — além da lógica pura de domínio no cliente (como a derivação do status da tarefa) e dos fluxos críticos: login, criar casa e excluir casa. A API tem testes unitários (Vitest, repositórios in-memory) e testes ponta a ponta contra um banco de teste real. No front, os testes ficam co-localizados na feature e consultam por papel/texto acessível — nunca por data-testid.

Roadmap

  • PWA instalável com leitura offline das tarefas já carregadas
  • UI de colaboração (convites, papéis de membro, transferência de propriedade)
  • Estatísticas da casa e de tarefas por membro (distribuição de carga)
  • Lembretes e notificações por WhatsApp/e-mail
  • Sugestões de tarefas/frequência assistidas por IA