Files
Condominio_SeConectai/Schemas/01-setup-projeto-docker.md
2026-09-29 12:12:31 -03:00

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 usar DriverManager.getConnection() direto por enquanto (mais simples) com um método getMasterConnection(). 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 .sql de um diretório de resources (ordenados por nome, prefixo numérico tipo 001_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 para db_master quanto para cada db_empresa_<slug> (usado nos prompts 02 e 03).

5. Router.java + Main.java

  • HttpServer escutando em HTTP_PORT, com um Router que mapeia path -> handler (pode ser simples: um Map<String, HttpHandler> com suporte a prefixo, tipo /api/** cai num handler, senão cai no StaticFileHandler).
  • Endpoint GET /health retornando 200 OK com {"status":"ok"} em JSON puro (sem lib de JSON externa — escrever um helper simples Json.write(Map<String,Object>) que serializa tipos básicos; pode ser reaproveitado nos próximos prompts).
  • StaticFileHandler serve os arquivos de src/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 pasta webapp/, expõe 8080, 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 up sobe postgres e app sem erro.
  • GET http://localhost:8080/health retorna 200 com {"status":"ok"}.
  • GET http://localhost:8080/ retorna o index.html placeholder.
  • Log de startup mostra "Conexão com db_master OK".
  • MigrationRunner roda sem erro mesmo sem nenhum arquivo .sql ainda (diretório vazio = no-op).
  • Projeto builda com mvn clean package (ou gradle 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.