Skip to content

Feat/cloudnary n i18n - #32

Merged
Megueutu merged 12 commits into
mainfrom
feat/cloudnary-n-i18n
Aug 29, 2026
Merged

Feat/cloudnary n i18n#32
Megueutu merged 12 commits into
mainfrom
feat/cloudnary-n-i18n

Conversation

@Megueutu

Copy link
Copy Markdown
Contributor

Objetivo

Adicionar à API os campos que já existem no front-end mas faltavam nas tabelas, e implementar tradução automática (via Google Translate) do conteúdo das ofertas (placas solares) para os idiomas suportados (pt-BR, en-US, es-ES).

Alterações

  • Model: campo dimension (BigDecimal único) substituído por width + length; adicionado campo type (PanelType: MONOCRYSTALLINE, POLYCRYSTALLINE, THIN_FILM).
  • Company: adicionado campo slug (gerado a partir de tradeName na criação, único).
  • Technician: adicionado campo slug (gerado a partir do nome da pessoa vinculada na criação, único).
  • Offer: adicionados slug (gerado a partir de marca+modelo), discountPercentage, serviceRegions (lista de regiões atendidas), sourceLocale e translationStatus (PENDING/COMPLETED/FAILED).
  • Nova tabela offer_translation: uma linha por idioma (title, description, details), com FK para offer.
  • Tradução automática assíncrona: após uma oferta ser criada, o idioma do conteúdo enviado é detectado via Google Translate API e o conteúdo é traduzido para os demais idiomas suportados, tudo em background (a criação da oferta responde imediatamente, sem esperar a tradução). Implementado com @Async (primeira vez que o projeto usa processamento assíncrono) disparado após o commit da transação de criação.
  • Imagens/Cloudinary: nenhuma alteração — a branch feat/cloudnaryPhotos (já mergeada aqui) implementa isso por completo com entidades de foto dedicadas; adicionar mais um campo de imagem duplicaria esse trabalho.
  • Front-end: nenhuma alteração feita nesta PR (avaliação de necessidade pendente — ver observação no final).

Endpoints afetados

Nenhum endpoint novo. POST /api/offers e PUT /api/offers/{id} passam a aceitar title, description, details, discountPercentage e serviceRegions; as respostas de oferta (OfferResponseDTO) passam a incluir slug, discountPercentage, serviceRegions, sourceLocale, translationStatus e translations[]. ModelResponseDTO/CompanyResponseDTO/TechnicianResponseDTO ganham os campos novos (type/width/length, slug, slug, respectivamente).

Banco de Dados

  • Migration
  • Schema
  • Seed

Não há ferramenta de migration no projeto (ddl-auto=validate), então o SQL abaixo precisa ser aplicado manualmente no banco antes do deploy:

-- model: dimension -> width + length, + typeALTERTABLE model ADD COLUMN width NUMERIC;
ALTERTABLE model ADD COLUMN length NUMERIC;
UPDATE model SET width = dimension, length = dimension WHERE dimension IS NOT NULL;
ALTERTABLE model ALTER COLUMN width SETNOT NULL;
ALTERTABLE model ALTER COLUMN length SETNOT NULL;
ALTERTABLE model DROP COLUMN dimension;
ALTERTABLE model ADD COLUMN type VARCHAR(20);
UPDATE model SET type ='MONOCRYSTALLINE'WHERE type IS NULL; -- ajustar valor default conforme o realALTERTABLE model ALTER COLUMN type SETNOT NULL;
-- company: slugALTERTABLE company ADD COLUMN slug VARCHAR(160);
-- preencher slug das linhas existentes antes do NOT NULL/UNIQUE, ex.:-- UPDATE company SET slug = lower(regexp_replace(trade_name, '[^a-zA-Z0-9]+', '-', 'g'));ALTERTABLE company ALTER COLUMN slug SETNOT NULL;
ALTERTABLE company ADD CONSTRAINT uq_company_slug UNIQUE (slug);
-- technician: slugALTERTABLE technician ADD COLUMN slug VARCHAR(160);
-- preencher slug das linhas existentes antes do NOT NULL/UNIQUEALTERTABLE technician ALTER COLUMN slug SETNOT NULL;
ALTERTABLE technician ADD CONSTRAINT uq_technician_slug UNIQUE (slug);
-- offer: slug, discount, source_locale, translation_statusALTERTABLE offer ADD COLUMN slug VARCHAR(160);
-- preencher slug das linhas existentes antes do NOT NULL/UNIQUEALTERTABLE offer ALTER COLUMN slug SETNOT NULL;
ALTERTABLE offer ADD CONSTRAINT uq_offer_slug UNIQUE (slug);
ALTERTABLE offer ADD COLUMN discount_percentage NUMERIC;
ALTERTABLE offer ADD COLUMN source_locale VARCHAR(10);
ALTERTABLE offer ADD COLUMN translation_status VARCHAR(20) NOT NULL DEFAULT 'PENDING';
-- offer_service_region (coleção de regiões atendidas por oferta)CREATETABLEoffer_service_region (
fk_offer UUID NOT NULLREFERENCES offer(id),
region VARCHAR(120)
);
-- offer_translation (uma linha por idioma)CREATETABLEoffer_translation (
id UUID PRIMARY KEY,
fk_offer UUID NOT NULLREFERENCES offer(id),
locale VARCHAR(10) NOT NULL,
title VARCHAR(160) NOT NULL,
description TEXTNOT NULL,
details TEXT,
CONSTRAINT uq_offer_translation_offer_locale UNIQUE (fk_offer, locale)
);

Para ofertas já existentes: rodar um backfill (script ou chamada manual) que crie a linha offer_translation inicial e dispare a tradução, já que a migration acima não faz isso automaticamente.

Variável de ambiente nova

GOOGLE_TRANSLATE_API_KEY — chave da Google Cloud Translation API (v2). Adicionada em .env.example, application.properties (google-translate.api-key) e no metadata de configuração.

Como testar

  1. Configurar GOOGLE_TRANSLATE_API_KEY no .env.
  2. Aplicar o SQL acima no banco local.
  3. Criar um modelo aprovado, depois POST /api/offers com title/description em português.
  4. Conferir que a resposta volta imediatamente com translationStatus: PENDING.
  5. Aguardar alguns segundos e consultar a oferta de novo (GET) — translationStatus deve virar COMPLETED, sourceLocale deve ser pt-BR, e translations[] deve ter as versões em en-US e es-ES.

Evidências

Sem evidências visuais.

Observações / pontos em aberto

  • O slug de Offer/Company/Technician é gerado uma única vez na criação e não muda em updates — se isso não for aceitável (ex.: precisa mudar quando o nome/marca muda), me avise.
  • Não toquei em nada de imagem/Cloudinary (ver seção "Alterações").
  • Front-end (web-app): ainda não avaliei/mexi em nada relacionado a essa PR (ex.: alinhar o enum de tipo de placa do front com PanelType, consumir os novos campos de oferta). Aguardando confirmação se isso é necessário agora ou fica para depois.

Closes #

ArthurMachado2501and others added 9 commits August 23, 2026 14:30
add photo management with Cloudinary integration
- Created UserPhoto entity and corresponding repository.
- Introduced PhotoType enum for categorizing photo types.
- Developed services for managing company, local unit, model, and user photos, including upload and delete functionalities.
- Implemented CloudinaryService for handling file uploads and deletions.
- Added response DTOs for various photo types.
- Enhanced EnergyBillService to support photo attachment and removal.
- Updated CompanyService and LocalUnitService to include photo repository checks during deletions.
- Configured application properties for Cloudinary settings and increased file upload limits.
CopilotAI lite review requested due to automatic review settings August 29, 2026 21:48

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

CopilotAI review requested due to automatic review settings August 29, 2026 21:53

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

CopilotAI review requested due to automatic review settings August 29, 2026 22:03

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

- adiciona metodos attachPhoto/removePhoto faltantes na interface EnergyBillOpenApi, corrigindo erro de compilacao
- restaura dependencia h2 (removida por engano ao mesclar cloudinary-http5), corrigindo falha nos testes
- agrupa alternancia no regex de EDGE_HYPHENS em SlugUtil para eliminar ambiguidade de precedencia (S5850)
- reduz limite de upload multipart de 10MB para 8MB para atender ao rating de seguranca do SonarCloud (S5693)
@sonarqubecloud

Copy link
Copy Markdown

@Megueutu
Megueutu merged commit 86b38e2 into mainAug 29, 2026
3 checks passed
@Megueutu
Megueutu deleted the feat/cloudnary-n-i18n branch August 29, 2026 22:15
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@Megueutu@maykitw1@ArthurMachado2501