PrimoDev/ apps

Teorical Questions DETRAN

API com 1.500 questões da prova teórica da CNH

  • API
  • Self-hosted
  • Grátis (repositório público no GitHub)
  • Open source
Ver no GitHub

O que é o Teorical Questions DETRAN?

O Teorical Questions DETRAN é uma API REST que serve um banco de 1.500 questões da prova teórica da CNH, extraídas do PDF Banco Nacional de Questões. Ela é a base pra montar simulados e apps de estudo pra quem vai tirar a carteira de motorista.

O código está num repositório público no GitHub e você roda a API por conta própria, com Node 20+ e PostgreSQL 16+ (o repo traz docker compose, Dockerfile e passo a passo de deploy no Railway).

O que ele faz

  1. 011.500 questões com enunciado, alternativa correta, 3 incorretas e comentário
  2. 024 módulos: Placas, Cores e Caminhos; Escolhas e Consequências; Na Direção da Segurança; Cuidar, Agir e Preservar
  3. 03Dificuldade fácil, intermediária ou difícil em cada questão
  4. 04Código da placa nas questões de sinalização
  5. 05Endpoints de listagem paginada, questão aleatória, detalhe e módulos
  6. 06Filtros por parte, módulo, dificuldade e busca por texto
  7. 07Contrato OpenAPI 3.0 e Swagger UI em /docs
  8. 08Extrator em Python que converte o PDF em JSON, JSONL e CSV

Perguntas frequentes

Quantas questões tem o banco?
1.500 questões: 1.340 do banco principal e 160 da seção Teste seus conhecimentos, divididas em 4 módulos.
De onde vêm as questões?
Do PDF Banco Nacional de Questões (CNH), convertido por um script em Python que também gera JSON, JSONL e CSV.
Dá pra pegar uma questão aleatória pra montar um simulado?
Dá. O endpoint GET /questions/random devolve uma questão aleatória e aceita os mesmos filtros da listagem, como módulo e dificuldade.
Como rodo a API localmente?
Suba o Postgres com docker compose up -d, copie o .env.example, rode npm install, npm run migrate e npm run import:questions, e depois npm run dev. A API fica em localhost:3000 e a documentação em /docs.
É um app pra estudar direto no celular?
Não. Este repositório é a API e o banco de questões. Ela serve de base pra um app ou site de simulado, que precisa ser feito à parte.

Guias

Documentação

README do repositório lucianodiisouza/teorical-questions-detran, atualizado a cada deploy. O texto original é em inglês.

API REST em Node 20, Express, TypeScript e PostgreSQL para servir o banco de questões extraído em tools/extractor/data/questions.json.

  • Contrato HTTP: OpenAPI 3.0 em openapi/openapi.yaml (também servido em GET /openapi.json).
  • Documentação interativa: GET /docs (Swagger UI), exceto se ENABLE_SWAGGER=false.

Requisitos

  • Node.js >= 20
  • PostgreSQL 16+ (local ou Docker)

Banco e responsabilidades

Esta API só cria e mantém o schema de questões (migrations/questions_*.sql → tabela questions). Usuários, tokens e perfil ficam na kuaa-api (auto-quiz-api).

Mesmo Postgres para os dois serviços: use o mesmo DATABASE_URL se quiser. Cada API guarda o histórico de migrações numa tabela separada (SCHEMA_MIGRATIONS_TABLE, por defeito questions_schema_migrations aqui e schema_migrations na kuaa-api), por isso não há colisão entre ficheiros com o mesmo nome (ex.: 001_init.sql) nem entre equipas de migrações.

Se já tinha migrado antes com a tabela antiga schema_migrations, defina SCHEMA_MIGRATIONS_TABLE=schema_migrations até migrar os dados ou renomear a tabela.

Desenvolvimento local

1. Banco de dados

Na raiz do repositório:

docker compose up -d

Isso sobe Postgres em localhost:5432 com:

  • Banco autocurso (desenvolvimento)
  • Banco autocurso_test (testes de integração)

Credenciais padrão: postgres / postgres (veja docker-compose.yml).

2. Variáveis de ambiente

cp .env.example .env
# Ajuste DATABASE_URL se necessário

3. Instalar dependências e migrar

npm install
npm run migrate

4. Importar questões (uma vez ou após atualizar o JSON)

npm run import:questions

Por padrão o script lê tools/extractor/data/questions.json. Use QUESTIONS_JSON_PATH para outro caminho.

5. Subir a API

npm run dev

Scripts

Script Descrição
npm run dev Servidor com hot reload (tsx)
npm run build Compila para dist/
npm start Produção: node dist/server.js (migrações rodam na subida)
npm run migrate Executa migrações SQL em migrations/
npm run import:questions Importa/atualiza questões a partir do JSON (upsert por id)
npm test Testes (Vitest)
npm run test:coverage Testes + cobertura
npm run ci build + test:coverage
npm run lint:openapi Valida openapi/openapi.yaml (Redocly)

Endpoints principais

Método Caminho Descrição
GET /health Saúde do serviço
GET /openapi.json Especificação OpenAPI (JSON)
GET /docs Swagger UI
GET /questions Lista paginada (page, limit, parte, modulo_numero, dificuldade, q)
GET /questions/random Uma questão aleatória (filtros opcionais)
GET /questions/:id Detalhe
GET /modules Módulos com contagem de questões

Erros seguem o schema ErrorResponse no OpenAPI (error.code, error.message, error.details).

Testes

Requer Postgres com o banco autocurso_test (gerado pelo docker compose da raiz).

# Na raiz do repo
docker compose up -d

npm run test:coverage

src/test/setup-env.ts define TEST_DATABASE_URL (sobrescrevível). A suíte de integração aplica migrações e insere dados de teste.

Docker (imagem de produção)

Na raiz do repositório:

docker build -t autocurso-api .
docker run --rm -p 3000:3000 -e DATABASE_URL=postgresql://... autocurso-api

A imagem não inclui dados: use import:questions uma vez no ambiente (job manual ou release) após o primeiro deploy.

Deploy no Railway

Nome do serviço no Railway: teoretical-questions-detran (API de questões teóricas DETRAN).

  1. Crie um projeto e conecte o repositório (a API está na raiz do repo).

  2. Adicione o recurso PostgreSQL ao projeto (botão New → Database → Postgres).

  3. Ligue o DATABASE_URL ao serviço da API (passo que costuma faltar):

    • Abra o serviço da API (não só o Postgres) → Variables.
    • Add variable → Reference → selecione o serviço Postgres → escolha DATABASE_URL.
    • Sem isso os logs mostram DATABASE_URL: Required, o processo reinicia e o healthcheck falha.
  4. Build: use o Dockerfile (veja railway.toml) ou build Nixpacks com npm run build e npm start.

  5. Variáveis: PORT é injetado; não fixe manualmente em produção.

  6. Primeiro deploy: após o banco vazio, rode uma vez o import das questões, por exemplo:

    railway run --service teoretical-questions-detran npm run import:questions

    (ou job one-off no dashboard), com QUESTIONS_JSON_PATH apontando para o JSON se necessário.

  7. Migrações: no arranque, após o servidor passar a escutar, runMigrations() aplica os SQL em migrations/.

  8. Release command (opcional): você pode configurar no Railway npm run migrate como release step e remover migrações do startup no futuro para deploys mais controlados.

Estrutura

openapi/openapi.yaml     # Contrato OpenAPI
migrations/              # SQL versionado
src/
  app.ts                 # Express + rotas + Swagger
  server.ts              # Entrada + migrações + HTTP server
  config/                # Env (Zod)
  db/                    # Pool + migrações
  modules/questions/     # Rotas, serviço, repositório
  scripts/               # import-questions
  test/                  # setup Vitest
tools/extractor/         # Extração PDF → JSON (Python), opcional