5.8 KiB
Prompt 01 — Setup do projeto, Docker e HttpServer básico
Contexto
Início do zero. Projeto: sistema de cadastro de referência para escritórios de contabilidade de condomínio (multi-tenant, 1 database PostgreSQL por empresa + 1 db_master). Stack: Java puro (sem framework), JDBC puro, com.sun.net.httpserver.HttpServer (built-in do JDK) para HTTP, PostgreSQL 16, Docker Compose. Frontend HTML/CSS/JS puro, servido pelo mesmo processo Java.
Este é o primeiro prompt da sequência. Não existe nenhum código ainda.
Objetivo
Criar o esqueleto do projeto: estrutura de pastas, Dockerfile, docker-compose.yml, conexão JDBC básica com o db_master, e um HttpServer que sobe, responde a um healthcheck, e já tem a estrutura de roteamento pronta para os próximos prompts registrarem handlers.
Especificação
1. Estrutura de pastas
condominio-contabilidade/
├── src/main/java/com/seconectai/condocontab/
│ ├── Main.java
│ ├── config/
│ │ ├── AppConfig.java (lê variáveis de ambiente)
│ │ └── DataSourceProvider.java (cria/gerencia conexões JDBC)
│ ├── http/
│ │ ├── Router.java (registra rotas -> handlers)
│ │ └── StaticFileHandler.java (serve arquivos de webapp/)
│ ├── master/ (vazio por enquanto, prompts futuros)
│ ├── tenant/ (vazio por enquanto)
│ ├── auth/ (vazio por enquanto)
│ ├── integracao/ (vazio por enquanto)
│ └── db/
│ └── MigrationRunner.java (executa .sql de resources/migrations)
├── src/main/resources/
│ └── migrations/
│ ├── master/ (vazio por enquanto — prompt 02)
│ └── tenant/ (vazio por enquanto — prompt 03)
├── src/main/webapp/
│ └── index.html (placeholder: "Sistema no ar")
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md
2. AppConfig.java
Lê das variáveis de ambiente (com valores default sensatos para dev local):
DB_HOST,DB_PORT(5432),DB_USER,DB_PASSWORD,DB_MASTER_NAME(db_master)HTTP_PORT(8080)MASTER_PASSWORD_HASH(usado só no prompt 04, mas já lido aqui)JWT_SECRET(usado só no prompt 04)
Falhar de forma clara (log + exit) se uma variável obrigatória estiver ausente.
3. DataSourceProvider.java
- Sem HikariCP nem pool de terceiros: implementar um pool simples próprio (uma
BlockingQueue<Connection>com tamanho configurável, ex: 10 conexões) OU usarDriverManager.getConnection()direto por enquanto (mais simples) com um métodogetMasterConnection(). Documentar no código que o cache de DataSource por tenant vem no prompt 03/06. - Testar a conexão na subida da aplicação (
SELECT 1) e logar sucesso/erro.
4. MigrationRunner.java
- Lê todos os arquivos
.sqlde um diretório de resources (ordenados por nome, prefixo numérico tipo001_xxx.sql,002_xxx.sql), executa os que ainda não rodaram. - Cria uma tabela de controle
schema_migrations (id, nome_arquivo, executado_em)no banco de destino, se não existir. - Método
runMigrations(Connection conn, String diretorioResources)reutilizável tanto paradb_masterquanto para cadadb_empresa_<slug>(usado nos prompts 02 e 03).
5. Router.java + Main.java
HttpServerescutando emHTTP_PORT, com umRouterque mapeiapath -> handler(pode ser simples: umMap<String, HttpHandler>com suporte a prefixo, tipo/api/**cai num handler, senão cai noStaticFileHandler).- Endpoint
GET /healthretornando200 OKcom{"status":"ok"}em JSON puro (sem lib de JSON externa — escrever um helper simplesJson.write(Map<String,Object>)que serializa tipos básicos; pode ser reaproveitado nos próximos prompts). StaticFileHandlerserve os arquivos desrc/main/webapp/(ou do diretório equivalente dentro do JAR/imagem) para qualquer rota que não comece com/api/.
6. Dockerfile (multi-stage)
- Stage 1: build com
maven:3.9-eclipse-temurin-21(ou Gradle, se preferir — usar Maven por simplicidade), gera o JAR. - Stage 2:
eclipse-temurin:21-jre, copia o JAR + a pastawebapp/, expõe8080,ENTRYPOINT ["java","-jar","app.jar"].
7. docker-compose.yml
version: "3.9"
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: db_master
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
app:
build: .
environment:
DB_HOST: postgres
DB_PORT: 5432
DB_USER: app
DB_PASSWORD: ${DB_PASSWORD}
DB_MASTER_NAME: db_master
HTTP_PORT: 8080
MASTER_PASSWORD_HASH: ${MASTER_PASSWORD_HASH}
JWT_SECRET: ${JWT_SECRET}
depends_on:
- postgres
ports:
- "8080:8080"
volumes:
pgdata:
8. .env.example
Listar todas as variáveis usadas, com comentário de exemplo (sem valores reais sensíveis).
Critérios de aceite
docker compose upsobepostgreseappsem erro.GET http://localhost:8080/healthretorna200com{"status":"ok"}.GET http://localhost:8080/retorna oindex.htmlplaceholder.- Log de startup mostra "Conexão com db_master OK".
MigrationRunnerroda sem erro mesmo sem nenhum arquivo.sqlainda (diretório vazio = no-op).- Projeto builda com
mvn clean package(ougradle build) sem dependências externas além do driver JDBC do PostgreSQL (org.postgresql:postgresql). - README.md com instruções de como rodar localmente (
docker compose up, variáveis de.env).
Ao concluir
Atualizar 10-tracker-progresso.md marcando o Prompt 01 como concluído, com a data e um resumo de 1-2 linhas do que foi feito. Não avançar para o Prompt 02 sem esse tracker atualizado.