Monorepo da plataforma educacional Studdy. O projeto reúne uma API REST em Express, uma aplicação web em Next.js e a persistência PostgreSQL gerenciada pelo Prisma.
O ambiente Docker Compose prepara todo o sistema: cria o banco, aplica a migration inicial, executa o seed idempotente e inicia API e frontend respeitando a ordem e a saúde de cada serviço.
A plataforma possui três perfis de acesso:
- Administrador: gerencia usuários, professores, alunos, turmas e disciplinas.
- Professor: acompanha turmas e cria quizzes, resumos e videoaulas.
- Aluno: acessa materiais, responde quizzes e consulta seu desempenho.
O monorepo preserva os manifests e lockfiles independentes dos projetos de origem. Os comandos da raiz apenas coordenam os aplicativos em apps/api e apps/web.
| Camada | Tecnologias principais |
|---|---|
| API | Node.js, Express 5, Prisma 6, Zod e JWT |
| Web | Next.js 15, React 19 e Tailwind CSS 4 |
| Banco | PostgreSQL 17 |
| Infraestrutura local | Docker e Docker Compose |
.
├── apps/
│ ├── api/
│ │ ├── prisma/ # Schema, migration inicial e seed
│ │ └── src/ # API Express
│ └── web/
│ └── src/ # Aplicação Next.js
├── compose.yaml # Ambiente completo
├── package.json # Scripts de coordenação do monorepo
└── README.md
Existe apenas um diretório .git, localizado na raiz. As dependências não usam npm workspaces: cada aplicativo mantém seu próprio package.json e package-lock.json.
Navegador
├── http://localhost:3001 -> Web (Next.js)
└── http://localhost:3000 -> API (Express)
│
└── db:5432 -> PostgreSQL
O Compose também possui o serviço temporário migrate. Ele termina com código 0 depois de executar prisma migrate deploy e prisma db seed. A API só inicia depois dessa conclusão, e o Web aguarda o healthcheck da API.
- Docker com o plugin Docker Compose.
- Portas
3000,3001e5432disponíveis.
Na raiz do repositório, execute:
npm run docker:upEsse comando constrói as imagens e mantém os logs no terminal. Para executar em segundo plano:
docker compose up --build --detachNa primeira inicialização, o Compose executa esta sequência:
- Cria o volume persistente do PostgreSQL.
- Aguarda o banco responder ao
pg_isready. - Aplica
apps/api/prisma/migrations/20260803120000_initial/migration.sql. - Executa o seed Prisma.
- Inicia a API e valida
GET /health. - Inicia o frontend Next.js.
| Serviço | Endereço | Comportamento esperado |
|---|---|---|
| Web | http://localhost:3001 | Interface da plataforma |
| API | http://localhost:3000 | Endpoints REST |
| Healthcheck | http://localhost:3000/health | Retorna {"status":"ok"} quando API e banco estão disponíveis |
| PostgreSQL | localhost:5432 |
Banco studdy, usuário studdy no ambiente padrão |
| Migration | migrate |
Finaliza com status Exited (0) |
Consulte o estado de todos os serviços, inclusive o job concluído:
docker compose ps --allO seed cria um cenário funcional para os três perfis. Todos os usuários usam a senha studdy123.
| Perfil | |
|---|---|
| Administrador | admin@studdy.local |
| Professor | professor@studdy.local |
| Aluno | aluno@studdy.local |
Além dos usuários, são criados:
- Uma turma de Ensino Médio no período da manhã.
- Uma disciplina de Matemática vinculada ao professor e à turma.
- Um aluno matriculado na turma.
- Um quiz público com questão e quatro alternativas.
- Uma tentativa concluída com resposta e pontuação.
- Um resumo e um vídeo demonstrativo.
O seed é idempotente: executá-lo novamente atualiza os registros conhecidos sem criar duplicações.
docker compose exec api npm run db:seedO ambiente funciona sem criar arquivos adicionais. Para sobrescrever valores, crie um .env na raiz.
| Variável | Padrão | Uso |
|---|---|---|
POSTGRES_DB |
studdy |
Nome do banco |
POSTGRES_USER |
studdy |
Usuário do PostgreSQL |
POSTGRES_PASSWORD |
studdy |
Senha do PostgreSQL |
JWT_SECRET |
studdy-local-secret |
Assinatura dos tokens locais |
OPENAI_API_KEY |
Vazio | Geração de alternativas e resumos |
YOUTUBE_API_KEY |
Vazio | Integrações da API com YouTube |
NEXT_PUBLIC_YOUTUBE_API_KEY |
Vazio | Consulta ao YouTube pelo frontend |
Os valores padrão são exclusivos para desenvolvimento local e não devem ser usados em produção.
Configure apps/api/.env com base em apps/api/.env.example e ajuste a conexão PostgreSQL:
DATABASE_URL=postgresql://studdy:studdy@localhost:5432/studdy?schema=public
PORT=3000
CORS_ORIGIN=http://localhost:3001
JWT_SECRET=change-me-in-production
OPENAI_API_KEY=
YOUTUBE_API_KEY=O frontend lê NEXT_PUBLIC_YOUTUBE_API_KEY quando a funcionalidade de videoaulas consulta diretamente a API do YouTube.
É possível executar API e Web no host e manter apenas o PostgreSQL no Docker.
Instale as dependências reproduzindo os lockfiles independentes:
npm run install:allInicie somente o banco:
docker compose up --detach dbPrepare o Prisma dentro de apps/api:
npm --prefix apps/api run db:generate
npm --prefix apps/api run db:deploy
npm --prefix apps/api run db:seedExecute API e frontend em terminais separados:
npm run dev:api
npm run dev:webO frontend inicia em http://localhost:3001 e acessa a API em http://localhost:3000.
O schema usa exclusivamente PostgreSQL e está em apps/api/prisma/schema.prisma. Como o banco do ambiente é novo, a primeira migration contém toda a estrutura e não utiliza baseline.
Comandos disponíveis na API:
| Comando | Descrição |
|---|---|
npm run db:generate |
Gera o Prisma Client no diretório configurado pelo schema |
npm run db:deploy |
Aplica migrations pendentes sem criar novas migrations |
npm run db:seed |
Executa o seed idempotente |
npm run validate |
Valida o schema Prisma |
Para verificar o estado do banco em execução:
docker compose exec api npx prisma migrate status| Script | Descrição |
|---|---|
npm run install:all |
Instala dependências da API e do Web |
npm run dev:api |
Inicia a API em modo watch |
npm run dev:web |
Inicia o Next.js em modo desenvolvimento na porta 3001 |
npm run build |
Gera o build de produção do frontend |
npm run validate:api |
Valida o schema Prisma |
npm run docker:up |
Constrói e inicia o ambiente Compose |
npm run docker:down |
Para e remove os containers e a rede |
npm run docker:reset |
Remove containers, rede e volume do banco |
Validações estáticas:
npm run validate:api
npm run build
docker compose config --quietValidações do ambiente em execução:
curl --fail http://localhost:3000/health
curl --fail --output /dev/null http://localhost:3001/pages/login
docker compose exec api npx prisma migrate statusO fluxo Docker foi validado com banco vazio, execução repetida do seed e autenticação dos perfis Administrador, Professor e Aluno. A API ainda não possui uma suíte automatizada configurada no script test.
Visualizar logs:
docker compose logs --follow api web
docker compose logs migrateParar o ambiente preservando os dados:
npm run docker:downRecriar o banco desde a migration inicial:
npm run docker:reset
docker compose up --build --detachO comando de reset remove permanentemente o volume local postgres_data.
OpenAI e YouTube são opcionais para inicialização, healthchecks, autenticação e smoke tests. As funcionalidades que chamam esses provedores precisam das respectivas chaves.
Existem chamadas do frontend para http://localhost:3002/api/resumos. Esse serviço não pertence à API Express nem ao ambiente Compose atual; essas chamadas devem ser ignoradas até a integração correspondente ser definida.
Verifique se outro processo ocupa 3000, 3001 ou 5432. O Compose publica essas três portas diretamente no host.
Consulte primeiro o job de banco e depois os logs da API:
docker compose logs migrate
docker compose logs apiSe migrate não terminar com código 0, a API permanecerá bloqueada por design.
Verifique migrations pendentes com docker compose exec api npx prisma migrate status. Em um ambiente local descartável, também é possível remover o volume e reaplicar a migration inicial com npm run docker:reset.
Isso é suportado. O script usa operações de atualização/criação para manter o mesmo conjunto lógico de dados.