Gerenciador de agenda pessoal com visualizações diária, semanal e mensal, suporte a tarefas recorrentes e assistente de IA integrado.
Visão diária com gráfico de distribuição de horas por categoria
Visão mensal com dots de prioridade por dia
Assistente de IA com streaming de resposta
- Visualizações — Diária, Semanal e Mensal com navegação entre períodos
- Tarefas — Criação com título, descrição, categoria, prioridade, duração (horas + minutos) e horário agendado
- Tarefas recorrentes — Selecione os dias da semana; instâncias são geradas automaticamente para os próximos 28 dias
- Timeline do dia — Gráfico de rosca SVG mostrando como as horas estão distribuídas por categoria
- Progresso — Barra de checklist indicando tarefas concluídas no período
- Stride AI — Assistente integrado via Groq que analisa sua agenda, sugere reordenação de tarefas e responde perguntas em chat com streaming
- Tema claro/escuro
- Node.js v18 ou superior
- npm v9 ou superior (incluído com o Node)
- Conta no Groq Console para obter uma API Key gratuita
git clone https://github.com/seu-usuario/stride.git
cd stridenpm installIsso instala as dependências de todos os workspaces (backend e frontend) de uma vez.
cp backend/.env.example backend/.envEdite backend/.env e preencha:
DATABASE_URL="file:./prisma/dev.db"
GROQ_API_KEY="gsk_sua_chave_aqui"
GROQ_MODEL="llama-3.1-8b-instant"
PORT=3001A chave Groq é gratuita em console.groq.com. O modelo padrão
llama-3.1-8b-instanté rápido e suficiente para as funcionalidades de IA.
cd backend
npx prisma db push
cd ..Isso cria o arquivo SQLite backend/prisma/dev.db com o schema completo.
npm run devSobe o backend e o frontend simultaneamente:
| Serviço | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend | http://localhost:3001 |
| Health | http://localhost:3001/health |
Na raiz do projeto:
| Comando | Descrição |
|---|---|
npm run dev |
Inicia backend e frontend em modo desenvolvimento |
npm run build |
Build de produção dos dois workspaces |
npm run test |
Roda os testes do backend |
npm run test:all |
Roda os testes de todos os workspaces |
Dentro de backend/:
| Comando | Descrição |
|---|---|
npm run db:studio |
Abre o Prisma Studio (GUI do banco) |
npm run db:push --force-reset |
Reseta o banco (apaga todos os dados) |
- Importe o repositório no vercel.com
- Configure o Root Directory como
frontend - Adicione a variável de ambiente:
VITE_API_URL=https://sua-api.railway.app - Deploy automático a cada push na
main
- Crie um novo projeto no railway.app e conecte o repositório
- Configure o Root Directory como
backend - Adicione as variáveis de ambiente:
DATABASE_URL=file:./prisma/dev.db GROQ_API_KEY=gsk_... GROQ_MODEL=llama-3.1-8b-instant PORT=3001 - Adicione o comando de start:
npm run db:push && npm start
Nota sobre SQLite em produção: o SQLite é persistido no disco do container. Para ambientes com redeploys frequentes, considere migrar para PostgreSQL alterando o
providernoschema.prismae ajustando oDATABASE_URL.
O projeto é um monorepo npm workspaces com dois pacotes independentes.
stride/
├── backend/ # API REST — Node.js + Express + TypeScript
└── frontend/ # SPA — React + Vite + TypeScript
O backend é organizado em quatro camadas com dependências de dentro para fora:
backend/src/
├── domain/
│ ├── entities/ # Task — regras de negócio puras, sem dependências externas
│ └── repositories/ # ITaskRepository — interface (contrato), não implementação
│
├── application/
│ ├── use-cases/ # Um arquivo por caso de uso:
│ │ # CreateTask, UpdateTask, DeleteTask, CompleteTask,
│ │ # GetTasksByPeriod, GenerateRecurringInstances
│ └── services/ # IAIAssistantService — interface do serviço de IA
│
├── infrastructure/
│ ├── database/ # PrismaTaskRepository — implementa ITaskRepository via SQLite
│ └── ai/ # GroqAIService — implementa IAIAssistantService via API Groq
│
└── api/
├── routes/ # tasks.ts, ai.ts — Express Router, sem lógica de negócio
├── schemas/ # taskSchemas.ts — validação de entrada com Zod
└── server.ts # ponto de entrada; monta Express + injeta dependências
Princípio central: a camada domain não conhece nada além de si mesma. Os casos de uso dependem apenas de interfaces (ITaskRepository), nunca de Prisma diretamente — a implementação concreta é injetada no server.ts. Isso torna o código testável sem banco de dados real.
Tarefas recorrentes: ao criar uma tarefa com isRecurring: true, o caso de uso GenerateRecurringInstances gera automaticamente instâncias individuais para os próximos 28 dias com base nos dias da semana selecionados. Cada instância é uma tarefa normal (isRecurring: false) com recurringParentId apontando para o template. Ao editar ou excluir o template, as instâncias pendentes são regeneradas ou removidas em cascata.
Tratamento de fuso horário: as consultas por período usam limites UTC calculados no frontend (com date-fns), não no servidor. Isso evita que tarefas noturnas (ex: dormir às 22h) apareçam no dia errado por diferença de fuso.
frontend/src/
├── pages/
│ ├── DailyView.tsx # Visualização do dia com timeline de horas
│ ├── WeeklyView.tsx # Visualização semanal com agrupamento por dia ou categoria
│ └── MonthlyView.tsx # Grade mensal com dots de prioridade por dia
│
├── components/
│ ├── TaskForm.tsx # Modal de criação/edição (renderizado via React Portal)
│ ├── TaskCard.tsx # Card de tarefa com ações (completar, iniciar, pular, editar)
│ ├── DayTimeline.tsx # Gráfico de rosca SVG — distribuição de horas por categoria
│ ├── ChecklistProgress.tsx# Barra de progresso do período
│ └── AIAssistant.tsx # Painel lateral de chat com a IA (streaming SSE)
│
├── hooks/
│ └── useTasks.ts # React Query — busca, criação, edição, exclusão de tarefas
│
├── services/
│ └── api.ts # Wrapper de fetch para a API REST
│
└── types/
└── task.ts # Tipos TypeScript compartilhados (Task, enums, payloads)
Gerenciamento de estado: não há store global (Redux, Zustand etc.). Todo estado de servidor vive no React Query (useQuery / useMutation). Estado local de UI (modal aberto, dia selecionado) vive em useState no componente que o usa.
Modais: o TaskForm usa ReactDOM.createPortal para renderizar no document.body, evitando problemas de clipping com contêineres overflow: hidden.
SQLite gerenciado pelo Prisma. Um único modelo Task armazena tanto templates recorrentes quanto instâncias regulares, diferenciados pelo campo isRecurring e recurringParentId.
Task {
id, title, description
period // daily | weekly | monthly
priority // low | medium | high | urgent
category // work | personal | health | leisure | household | food | hygiene | other
status // pending | in_progress | completed | overdue | skipped
timeLimitMinutes
scheduledAt // horário de início (opcional)
dueDate // calculado: scheduledAt + timeLimitMinutes
isRecurring // true = template; false = instância ou tarefa avulsa
recurringConfig // JSON: { frequency, daysOfWeek }
recurringParentId
tags // JSON array
}
| Camada | Tecnologia |
|---|---|
| Frontend | React 18, TypeScript, Vite, TailwindCSS, React Query, date-fns, React Router 6 |
| Backend | Node.js, Express, TypeScript, Zod |
| Banco | SQLite via Prisma 5 |
| IA | Groq API — modelo llama-3.1-8b-instant |
| Testes | Vitest, Testing Library |
| Monorepo | npm workspaces + concurrently |


