116 lines
5.8 KiB
Markdown
116 lines
5.8 KiB
Markdown
# 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
|
|
```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.
|