Plataforma de customização visual de produtos têxteis (calçados e bolsas): o usuário escolhe uma parte do produto (tira, palmilha, sola…), o sistema segmenta essa região por IA e a recolore ou repinta o material — seja de forma determinística (cor exata de um Pantone) ou generativa (Stable Diffusion + ControlNet).
Este repositório reúne, num único lugar, todo o código do projeto para quem
quiser entender a arquitetura ou colocar o sistema inteiro no ar. Ele é um
snapshot — cada subpasta é mantida no dia a dia em seu próprio repositório na
organização Projeto-camaleoa-brisa.
Aviso de configuração: todos os tokens, chaves e endpoints neste repositório foram substituídos por placeholders (ex.:
troque-por-um-segredo-forte,https://sua-vm-sam.example,localhost). Nada aqui funciona "de fábrica" — você precisa preencher os valores reais no seu ambiente (via.env/ variáveis de ambiente) como descrito abaixo.
- O que o sistema faz
- Arquitetura e portas
- Cadeia de chamadas ponta a ponta
- Componentes (o que cada um é e faz)
- Pré-requisitos globais
- Como rodar TUDO — passo a passo
- Referência de variáveis de ambiente
- Autenticação e tokens
- Pesos dos modelos (~11 GB)
- Troubleshooting
O produto gira em torno de customizar a aparência de um produto (ex.: um chinelo) trocando a cor/material de partes específicas:
- O usuário abre um produto no frontend e escolhe uma parte (ex.: a tira).
- O sistema segmenta aquela parte na foto — gera uma máscara que isola exatamente aquela região (IA de segmentação: GroundingDINO + SAM 2, com Qwen2.5-VL e CLIP auxiliando na identificação).
- O usuário escolhe uma cor (Pantone) ou um material novo. O sistema
aplica a mudança de duas formas possíveis:
- Recolor determinístico (rápido, cor exata, CPU): troca a cor da região preservando textura e sombreamento. Reproduzível.
- Repintura generativa (Stable Diffusion + ControlNet, GPU): regenera o material da região com realismo, aplicando uma textura recolorida.
Tudo é orquestrado por um backend Java (Spring Boot) multi-tenant, que guarda projetos, produtos, materiais e paletas em MySQL, armazena imagens em MinIO (compatível com S3) e chama os microserviços de IA por URLs pré-assinadas.
flowchart TD
U[Usuário] --> F["rep-front<br/>Vite + React<br/>:3000"]
F -->|/api| B["rep-backend<br/>Spring Boot / Java 21<br/>:8080"]
B --> DB[(MySQL :3306)]
B --> S3[(MinIO :9000)]
B -->|segmentar| SAM["rep-microservico-SAM<br/>FastAPI :8000"]
B -->|recolor determinístico| CV["rep-microservico-OpenCV<br/>FastAPI :8002"]
B -->|repintura generativa| SD["rep-microservico-SD<br/>FastAPI :8003"]
SAM -->|proxy p/ GPU| VMSAM["rep-api-externa-AI · sam-api<br/>GPU · :8000"]
SD -->|proxy p/ GPU| VMSD["rep-api-externa-AI · sd-api<br/>GPU · :8003"]
subgraph VM["Máquina com GPU (VM)"]
VMSAM
VMSD
end
| Componente | Tecnologia | Porta | Papel |
|---|---|---|---|
rep-front |
Vite + React + TS | 3000 | Interface do usuário |
rep-backend |
Java 21 / Spring Boot | 8080 | Orquestrador, regras de negócio, auth, storage |
rep-microservico-OpenCV-python |
FastAPI | 8002 | Recolor determinístico (CPU, cor exata) |
rep-microservico-SAM-python |
FastAPI | 8000 | Segmentação (local ou proxy p/ a VM) |
rep-microservico-SD-python |
FastAPI | 8003 | Repintura generativa (proxy p/ a VM) |
rep-api-externa-AI / sam-api |
FastAPI + PyTorch | 8000 (na VM) | Segmentação na GPU |
rep-api-externa-AI / sd-api |
FastAPI + PyTorch | 8003 (na VM) | Inpaint SD+ControlNet na GPU |
| MySQL | — | 3306 | Banco relacional |
| MinIO | — | 9000 | Armazenamento de imagens (S3) |
As duas portas
8000/8003aparecem duplicadas porque os microserviços (VPS) e os servidores de IA (rep-api-externa-AI, GPU) rodam em máquinas diferentes. Num setup 100% local você escolhe uma das topologias (ver seção 6).
O frontend nunca chama os microserviços diretamente — sempre passa pelo backend, que valida permissão/posse (multi-tenant) e gera URLs pré-assinadas do MinIO. Os microserviços baixam a imagem sozinhos a partir dessas URLs.
Fluxo 1 — Segmentar uma parte
front → backend → SAM microservice (:8000) → [proxy] → sam-api na GPU (:8000)
← máscara PNG ←
Fluxo 2 — Recolorir com cor exata (Pantone)
front → backend → OpenCV microservice (:8002) [tudo local, CPU, sem GPU]
← PNG recolorido ←
Fluxo 3 — Repintar material (generativo)
front → backend → SD microservice (:8003) → [proxy] → sd-api na GPU (:8003)
← PNG repintado ←
Os microserviços SAM e SD funcionam em dois modos:
- Local: carregam os modelos de IA na própria máquina (precisa de GPU e dos pesos). Bom para desenvolvimento numa máquina forte.
- Proxy: rodam "leves" numa VPS e encaminham as requisições para os
servidores em
rep-api-externa-AI, que ficam na máquina com GPU. É a topologia de produção.
O OpenCV é sempre local (é só numpy/Pillow, não precisa de GPU nem VM).
O que é: SPA em React + TypeScript, empacotada com Vite. É onde o usuário monta o projeto, escolhe partes, cores e materiais, e vê o resultado.
O que faz: fala apenas com o backend (/api). O Vite faz proxy de /api
para http://localhost:8080 em desenvolvimento.
Rodar:
cd rep-front
npm install
cp .env.example .env # ajuste VITE_API_URL se o backend não estiver em :8080
npm run dev # sobe em http://localhost:3000Variáveis (.env):
VITE_API_URL— base da API do backend (padrãohttp://localhost:8080/api).VITE_AUTH_MOCK—trueusa usuários mock (útil sem backend); em produçãofalse.
O que é: monólito Spring Boot 4 / Java 21, arquitetura por feature
(Screaming Architecture) sob com.textilAI.domain.<feature>. Ver
rep-backend/DOMAIN_ARCHITECTURE.md para a
mecânica de negócio dos 10 domínios (Projeto, Produto, Material, Pantone, etc.).
O que faz: autenticação (JWT), regras de negócio multi-tenant, persistência
(MySQL via JPA), storage de imagens (MinIO), e orquestração dos 3 microserviços
de IA com resiliência (resilience4j circuit breaker). Gera URLs pré-assinadas
do MinIO e nunca trafega bytes de imagem nos payloads para os microserviços.
Dependências de infra: MySQL e MinIO precisam estar de pé.
Rodar (perfil local):
cd rep-backend
# variáveis obrigatórias no ambiente (exemplos):
export MYSQL_PASSWORD_DEV=suasenha
export MINIO_ROOT_USER_DEV=minioadmin
export MINIO_ROOT_PASSWORD_DEV=minioadmin
export JWT_SECRET_KEY=uma-chave-jwt-bem-longa-e-aleatoria
export OPENCV_SERVICE_KEY=troque-por-um-segredo-forte
./mvnw spring-boot:run -Dspring-boot.run.profiles=local # sobe em http://localhost:8080Swagger em http://localhost:8080/swagger-ui.html (springdoc).
Configuração: src/main/resources/application.yaml (+ perfis -local,
-dev, -uat). Os endpoints e chaves dos microserviços ficam em
external.python-service.{sam,opencv,stable-diffusion} — ver
seção 7.
O que é: microserviço FastAPI (porta 8002) de recoloração algorítmica (numpy/Pillow, CPU — não usa GPU nem a VM).
O que faz: recebe a foto do produto e troca uma cor de referência por uma cor alvo (Pantone), preservando textura e sombreamento. Cor exata e resultado reproduzível.
Endpoint principal: POST /api/v1/fabric/change-color
(auth X-Internal-Token). GET /health para status.
Rodar:
cd rep-microservico-OpenCV-python
python -m venv .venv && source .venv/Scripts/activate # Windows Git Bash
pip install -r requirements.txt
cp .env.example .env
ENV=local uvicorn main:app --host 0.0.0.0 --port 8002 --reloadENV=local desabilita o token no Swagger (/docs) durante o desenvolvimento.
Variáveis: ENV, INTERNAL_AUTH_TOKEN (obrigatório fora de local),
MAX_FILE_SIZE_BYTES, IMAGE_DOWNLOAD_TIMEOUT_SECONDS.
O que é: microserviço FastAPI (porta 8000), também empacotado como o
app "Textil IA". Faz o pipeline de segmentação:
Imagem → GroundingDINO → SAM 2 → refinamento por componente → máscara.
Qwen2.5-VL 3B e CLIP entram como auxiliares.
O que faz: dado uma imagem e uma parte-alvo (ex.: insole), devolve a máscara
binária daquela região. Trabalha uma imagem/uma parte por vez.
Endpoints: POST /v1/segment, POST /v1/segment/start,
GET /v1/segment/progress, GET /health (auth X-Internal-Token via
INTERNAL_API_TOKEN).
Dois modos (via .env):
PRELOAD_LOCAL_MODELS=true— carrega SAM2/GroundingDINO localmente (precisa de GPU + pesos).REMOTE_API_ENABLED=truefaz usar a API remota primeiro quando ela responde.PRELOAD_LOCAL_MODELS=false— modo proxy (container leve): encaminha paraREMOTE_API_URL(asam-apiemrep-api-externa-AI).
Rodar:
cd rep-microservico-SAM-python
python -m venv .venv && source .venv/Scripts/activate
pip install -r requirements.txt # ou requirements-proxy.txt no modo proxy
cp .env.example .env # ajuste REMOTE_API_URL, API_KEY, INTERNAL_API_TOKEN
python main.py # ou: uvicorn app.ia_server:app --port 8000Variáveis-chave: PRELOAD_LOCAL_MODELS, REMOTE_API_ENABLED,
REMOTE_API_URL, API_KEY (saída p/ a VM), INTERNAL_API_TOKEN (entrada do
backend), DEVICE, HF_HOME, SAM2_CHECKPOINT, GROUNDING_CHECKPOINT.
O que é: microserviço FastAPI (porta 8003) que faz a ponte entre o backend e a sd-api na GPU (SD 1.5 + ControlNet inpaint).
O que faz:
POST /v1/inpaint— repintura generativa via VM. Enviaimage,maskematerial_projeto(textura recolorida) emmultipart/form-datapara a VM.POST /api/v1/fabric/change-color— adaptador que implementa o mesmo contrato do slot "OpenCV" esperado pelo backend (recolor determinístico local), útil para não alterar o back.GET /health.
Rodar:
cd rep-microservico-SD-python
python -m venv .venv && source .venv/Scripts/activate
pip install -r requirements.txt
cp .env.example .env # ajuste VM_API_URL, VM_API_KEY, MICROSERVICE_API_KEYS
uvicorn main:app --host 0.0.0.0 --port 8003Variáveis-chave: VM_API_URL (a sd-api da VM), VM_API_KEY (Bearer de
saída), VM_API_TIMEOUT, MICROSERVICE_API_KEYS (chaves aceitas de entrada,
inclui o token que o backend envia), CORS_ORIGINS.
O que é: os dois servidores FastAPI que rodam os modelos pesados na GPU da máquina (VM). O backend Java e os microserviços da VPS chamam estes endpoints. É o "motor de IA" de verdade.
| Porta | Pasta | Papel | Endpoint |
|---|---|---|---|
| 8000 | sam-api/ |
Segmentação: Qwen2.5-VL → GroundingDINO → SAM 2 → CLIP | POST /v1/segment |
| 8003 | sd-api/ |
Inpaint: SD 1.5 + ControlNet inpaint | POST /v1/inpaint |
Autenticação nos dois: X-Internal-Token (backend) ou Authorization: Bearer
(clientes legados). /health, /docs, /openapi.json e /redoc ficam livres.
Instalar e rodar: venv único na raiz da pasta, Python 3.11. Os comandos
completos (torch cu126 + sam2 via git com --no-build-isolation) estão no topo
de requirements-servers.txt.
cd rep-api-externa-AI
# criar venv e instalar conforme requirements-servers.txt, depois:
./.venv/Scripts/python.exe start_both.py # sobe sam-api e sd-api juntosstart_both.py sobe os dois em subprocessos e espera o /health de cada um
(o sam-api leva ~30s carregando os modelos). Para rodar só um: python server.py
dentro da pasta correspondente.
Pesos: sam-api/models/ (~11 GB) fica fora do repo (ver
seção 9).
| Ferramenta | Versão | Usado por |
|---|---|---|
| Node.js | 18+ | rep-front |
| Java (JDK) | 21 | rep-backend |
| Python | 3.11 | todos os microserviços e rep-api-externa-AI |
| MySQL | 8.x | rep-backend |
| MinIO | recente | rep-backend (storage S3) |
| GPU NVIDIA + CUDA | CUDA 12.x | modelos de IA (SAM 2, SD) — para segmentação/repintura reais |
| ~11 GB de disco | — | pesos dos modelos |
Sem GPU você ainda consegue rodar o frontend, o backend, o OpenCV (recolor determinístico) e os microserviços em modo proxy — só a segmentação e a repintura generativa exigem a máquina com GPU.
Ordem recomendada (de baixo para cima na cadeia de dependências):
1) Infra
# suba MySQL e MinIO (localmente ou via Docker). Crie o bucket 'textilai-bucket'.2) Servidores de IA na GPU (rep-api-externa-AI) — se você tem GPU
cd rep-api-externa-AI
# instalar venv conforme requirements-servers.txt
./.venv/Scripts/python.exe start_both.py # sam-api :8000 + sd-api :80033) Microserviços (VPS) — apontando para a VM do passo 2
# terminal A — segmentação (modo proxy p/ a GPU)
cd rep-microservico-SAM-python && cp .env.example .env
# REMOTE_API_URL=<url da sam-api> PRELOAD_LOCAL_MODELS=false
python main.py # :8000
# terminal B — recolor determinístico (local, sem GPU)
cd rep-microservico-OpenCV-python && cp .env.example .env
ENV=local uvicorn main:app --port 8002 # :8002
# terminal C — repintura generativa (proxy p/ a GPU)
cd rep-microservico-SD-python && cp .env.example .env
# VM_API_URL=<url da sd-api> VM_API_KEY=<chave>
uvicorn main:app --port 8003 # :80034) Backend — apontando para os microserviços do passo 3
cd rep-backend
export MYSQL_PASSWORD_DEV=... MINIO_ROOT_USER_DEV=... MINIO_ROOT_PASSWORD_DEV=...
export JWT_SECRET_KEY=... OPENCV_SERVICE_KEY=troque-por-um-segredo-forte
./mvnw spring-boot:run -Dspring-boot.run.profiles=local # :80805) Frontend
cd rep-front && cp .env.example .env
npm install && npm run dev # http://localhost:3000Abra http://localhost:3000 e faça o fluxo completo. Se algo falhar, cada
serviço tem /health (microserviços) ou /swagger-ui.html (backend) para
diagnóstico.
Setup mínimo sem GPU: pule o passo 2; rode o SAM em modo local desativado (ou use apenas o fluxo de recolor determinístico do OpenCV). O frontend + backend + OpenCV já demonstram o produto ponta a ponta para cores exatas.
rep-front/.env
| Variável | Padrão | Descrição |
|---|---|---|
VITE_API_URL |
http://localhost:8080/api |
Base da API do backend |
VITE_AUTH_MOCK |
false |
Usa usuários mock em vez da API real |
rep-backend (variáveis de ambiente / application-*.yaml)
| Variável | Descrição |
|---|---|
MYSQL_PASSWORD_DEV |
Senha do MySQL |
MINIO_ROOT_USER_DEV / MINIO_ROOT_PASSWORD_DEV |
Credenciais do MinIO |
JWT_SECRET_KEY |
Segredo de assinatura dos JWT |
SAM_SERVICE_URL / SAM_SERVICE_KEY |
URL e token do microserviço SAM (:8000) |
OPENCV_SERVICE_URL / OPENCV_SERVICE_KEY |
URL e token do microserviço OpenCV (:8002) |
STABLE_DIFFUSION_SERVICE_URL / STABLE_DIFFUSION_SERVICE_KEY |
URL e token do microserviço SD (:8003) |
rep-microservico-OpenCV-python/.env
| Variável | Descrição |
|---|---|
ENV |
local desliga auth no Swagger; production/staging ativa o token |
INTERNAL_AUTH_TOKEN |
Token de entrada (obrigatório fora de local) |
MAX_FILE_SIZE_BYTES |
Tamanho máximo de upload |
IMAGE_DOWNLOAD_TIMEOUT_SECONDS |
Timeout para baixar a imagem |
rep-microservico-SAM-python/.env
| Variável | Descrição |
|---|---|
PRELOAD_LOCAL_MODELS |
true = carrega modelos locais; false = modo proxy |
REMOTE_API_ENABLED / REMOTE_API_URL |
Usar a API remota (VM) e sua URL |
API_KEY |
Chave de saída para a sam-api da VM |
INTERNAL_API_TOKEN |
Token de entrada que o backend envia (X-Internal-Token) |
DEVICE, HF_HOME, SAM2_CHECKPOINT, GROUNDING_CHECKPOINT, QWEN_MODEL, CLIP_MODEL |
Modelos e caminhos |
rep-microservico-SD-python/.env
| Variável | Descrição |
|---|---|
VM_API_URL |
URL da sd-api na VM |
VM_API_KEY |
Chave (Bearer) de saída para a VM |
VM_API_TIMEOUT |
Timeout das chamadas à VM |
MICROSERVICE_API_KEYS |
Lista de chaves aceitas na entrada (inclui o token do backend) |
CORS_ORIGINS |
Origens permitidas (restringir em produção) |
rep-api-externa-AI (variáveis opcionais para sobrescrever caminhos)
SAM_INTERNAL_TOKEN, SD_INTERNAL_TOKEN, SAM2_CHECKPOINT, SAM2_CONFIG,
QWEN_MODEL, GROUNDING_MODEL, CLIP_MODEL, SAM_PORT, HF_HOME.
- Frontend → Backend: JWT (login gera o token;
JWT_SECRET_KEYassina). - Backend → Microserviços: header
X-Internal-Token. O mesmo valor precisa estar configurado nos dois lados (ex.:OPENCV_SERVICE_KEYno backend =INTERNAL_AUTH_TOKENno OpenCV). - Microserviços → VM (GPU):
Authorization: Bearer <chave>(SD usaVM_API_KEY; SAM usaAPI_KEY). No SAM, note queAPI_KEY(saída) eINTERNAL_API_TOKEN(entrada) são valores diferentes — não reutilize.
Nos .env.example deste repo esses valores estão como placeholders. Defina
segredos fortes e mantenha-os sincronizados entre os pares que se comunicam.
Se você importou este código de um lugar onde havia chaves reais, rotacione-as.
Os pesos não são versionados (.gitignore). O sam-api (em
rep-api-externa-AI) espera:
sam-api/models/sam2_hiera_large.pt— checkpoint do SAM 2.sam-api/models/huggingface/— cache do HuggingFace (HF_HOME). Qwen2.5-VL-3B, grounding-dino-tiny e CLIP baixam sozinhos no primeiro boot.
Dá para sobrescrever caminhos por variável de ambiente
(SAM2_CHECKPOINT, SAM2_CONFIG, QWEN_MODEL, GROUNDING_MODEL, CLIP_MODEL).
O microserviço rep-microservico-SAM-python, quando roda em modo local, usa uma
pasta weights/ própria (também ignorada).
| Sintoma | Provável causa | O que checar |
|---|---|---|
| Front carrega mas login/telas falham | Backend fora do ar ou VITE_API_URL errado |
curl http://localhost:8080/swagger-ui.html |
| Backend não sobe | MySQL/MinIO indisponíveis ou variáveis faltando | Logs do Spring; MYSQL_PASSWORD_DEV, JWT_SECRET_KEY |
| Segmentação retorna 401/403 | Token divergente entre backend e SAM | X-Internal-Token = INTERNAL_API_TOKEN |
| Segmentação demora/timeout no 1º uso | sam-api carregando modelos (~30s) | GET /health da sam-api; SAM_READ_TIMEOUT_MS no back |
| Repintura sai escura/estranha | Falta a textura material_projeto |
Fluxo de MascaraRecolorizada; strength/controlnet_scale |
sam2 não instala |
Falta --no-build-isolation |
Topo do requirements-servers.txt |
| Recolor devolve a imagem original | Cor de referência não encontrada na foto | Header X-Recolor-Coverage; calibrar RECOLOR_* |
.
├── rep-front/ Frontend (Vite + React)
├── rep-backend/ Backend Spring Boot (Java 21)
├── rep-microservico-OpenCV-python/ Recolor determinístico (:8002)
├── rep-microservico-SAM-python/ Segmentação (:8000)
├── rep-microservico-SD-python/ Repintura generativa (:8003)
└── rep-api-externa-AI/ Servidores de IA na GPU (sam-api :8000, sd-api :8003)
Cada subpasta mantém seus próprios .env.example, requirements*.txt/package.json
e, em alguns casos, um README.md ou GEMINI.md/DOMAIN_ARCHITECTURE.md com
detalhes adicionais.