# 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` 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_` (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` 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)` 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 ```yaml 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.