From 6d5a64be897017ecf0c2455dd1f94fc85d969429 Mon Sep 17 00:00:00 2001 From: Artur Oliveira Date: Tue, 16 Dec 2025 17:39:56 -0300 Subject: [PATCH] =?UTF-8?q?feat(types):=20tornar=20tipos=20configur=C3=A1v?= =?UTF-8?q?eis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - converte entidades de servidores para armazenar type/application/db como texto - adiciona modelo e API para registrar/listar TypeOptions com normalização - centraliza schema/data scripts para criar schema e seedar tipos e usuário padrão --- .../controllers/TypeOptionsController.java | 29 +++++++++++++ .../servermanager/model/Servers.java | 20 +++------ .../servermanager/model/TypeOption.java | 33 +++++++++++++++ .../model/enums/TypeCategory.java | 7 ++++ .../repositories/TypeOptionRepository.java | 13 ++++++ .../services/ServersService.java | 11 ----- .../services/TypeOptionService.java | 42 +++++++++++++++++++ .../servermanager/utils/TypeNormalizer.java | 30 +++++++++++++ backend/src/main/resources/application.yaml | 1 + backend/src/main/resources/data.sql | 23 ++++++++++ backend/src/main/resources/schema.sql | 4 +- 11 files changed, 187 insertions(+), 26 deletions(-) create mode 100644 backend/src/main/java/com/hitcommunications/servermanager/controllers/TypeOptionsController.java create mode 100644 backend/src/main/java/com/hitcommunications/servermanager/model/TypeOption.java create mode 100644 backend/src/main/java/com/hitcommunications/servermanager/model/enums/TypeCategory.java create mode 100644 backend/src/main/java/com/hitcommunications/servermanager/repositories/TypeOptionRepository.java create mode 100644 backend/src/main/java/com/hitcommunications/servermanager/services/TypeOptionService.java create mode 100644 backend/src/main/java/com/hitcommunications/servermanager/utils/TypeNormalizer.java diff --git a/backend/src/main/java/com/hitcommunications/servermanager/controllers/TypeOptionsController.java b/backend/src/main/java/com/hitcommunications/servermanager/controllers/TypeOptionsController.java new file mode 100644 index 0000000..c77635a --- /dev/null +++ b/backend/src/main/java/com/hitcommunications/servermanager/controllers/TypeOptionsController.java @@ -0,0 +1,29 @@ +package com.hitcommunications.servermanager.controllers; + +import com.hitcommunications.servermanager.model.enums.TypeCategory; +import com.hitcommunications.servermanager.services.TypeOptionService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/type-options") +@RequiredArgsConstructor +@Tag(name = "Type Options") +public class TypeOptionsController { + + private final TypeOptionService typeOptionService; + + @GetMapping("/{category}") + @Operation(summary = "Lista os valores disponíveis para um tipo de categoria (SERVER_TYPE, APPLICATION, DATABASE).") + public ResponseEntity> list(@PathVariable TypeCategory category) { + return ResponseEntity.ok(typeOptionService.list(category)); + } +} diff --git a/backend/src/main/java/com/hitcommunications/servermanager/model/Servers.java b/backend/src/main/java/com/hitcommunications/servermanager/model/Servers.java index 457efe3..c02806f 100644 --- a/backend/src/main/java/com/hitcommunications/servermanager/model/Servers.java +++ b/backend/src/main/java/com/hitcommunications/servermanager/model/Servers.java @@ -5,15 +5,10 @@ import java.sql.Timestamp; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; -import com.hitcommunications.servermanager.model.enums.Applications; -import com.hitcommunications.servermanager.model.enums.DatabaseType; -import com.hitcommunications.servermanager.model.enums.ServersType; import com.hitcommunications.servermanager.utils.ServerIdGenerator; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; import jakarta.persistence.Id; import jakarta.persistence.Table; import lombok.AllArgsConstructor; @@ -51,17 +46,14 @@ public class Servers { @Column(nullable = false) private String password; - @Column(nullable = false) - @Enumerated(EnumType.STRING) - private ServersType type; + @Column(nullable = false, length = 80) + private String type; - @Column(nullable = false) - @Enumerated(EnumType.STRING) - private Applications application; + @Column(nullable = false, length = 80) + private String application; - @Column(nullable = false) - @Enumerated(EnumType.STRING) - private DatabaseType dbType; + @Column(nullable = false, length = 80, name = "db_type") + private String dbType; @CreationTimestamp private Timestamp createdAt; diff --git a/backend/src/main/java/com/hitcommunications/servermanager/model/TypeOption.java b/backend/src/main/java/com/hitcommunications/servermanager/model/TypeOption.java new file mode 100644 index 0000000..975f132 --- /dev/null +++ b/backend/src/main/java/com/hitcommunications/servermanager/model/TypeOption.java @@ -0,0 +1,33 @@ +package com.hitcommunications.servermanager.model; + +import com.hitcommunications.servermanager.model.enums.TypeCategory; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "tab_type_options", schema = "server-manager", uniqueConstraints = { + @UniqueConstraint(columnNames = {"category", "value"}) +}) +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TypeOption { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, updatable = false) + private Long id; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 32) + private TypeCategory category; + + @Column(nullable = false, length = 80) + private String value; +} diff --git a/backend/src/main/java/com/hitcommunications/servermanager/model/enums/TypeCategory.java b/backend/src/main/java/com/hitcommunications/servermanager/model/enums/TypeCategory.java new file mode 100644 index 0000000..d711fbe --- /dev/null +++ b/backend/src/main/java/com/hitcommunications/servermanager/model/enums/TypeCategory.java @@ -0,0 +1,7 @@ +package com.hitcommunications.servermanager.model.enums; + +public enum TypeCategory { + SERVER_TYPE, + APPLICATION, + DATABASE +} diff --git a/backend/src/main/java/com/hitcommunications/servermanager/repositories/TypeOptionRepository.java b/backend/src/main/java/com/hitcommunications/servermanager/repositories/TypeOptionRepository.java new file mode 100644 index 0000000..2196aed --- /dev/null +++ b/backend/src/main/java/com/hitcommunications/servermanager/repositories/TypeOptionRepository.java @@ -0,0 +1,13 @@ +package com.hitcommunications.servermanager.repositories; + +import com.hitcommunications.servermanager.model.TypeOption; +import com.hitcommunications.servermanager.model.enums.TypeCategory; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface TypeOptionRepository extends JpaRepository { + Optional findByCategoryAndValue(TypeCategory category, String value); + List findAllByCategoryOrderByValueAsc(TypeCategory category); +} diff --git a/backend/src/main/java/com/hitcommunications/servermanager/services/ServersService.java b/backend/src/main/java/com/hitcommunications/servermanager/services/ServersService.java index 0b2cbc6..3665208 100644 --- a/backend/src/main/java/com/hitcommunications/servermanager/services/ServersService.java +++ b/backend/src/main/java/com/hitcommunications/servermanager/services/ServersService.java @@ -29,8 +29,6 @@ public class ServersService { private final ServersRepository repo; public ServerDTO create(NewServerDTO createDTO) { - ensureUniqueIpAndPort(createDTO.ip(), createDTO.port(), null); - Servers entity = mapper.toEntity(createDTO); entity = repo.save(entity); return mapper.toDTO(entity); @@ -166,8 +164,6 @@ public class ServersService { Servers entity = repo.findById(id) .orElseThrow(() -> new RuntimeException("Server not found with id: " + id)); - ensureUniqueIpAndPort(updateDTO.ip(), updateDTO.port(), id); - mapper.partialUpdate(updateDTO, entity); entity = repo.save(entity); return mapper.toDTO(entity); @@ -180,11 +176,4 @@ public class ServersService { repo.deleteById(id); } - private void ensureUniqueIpAndPort(String ip, Integer port, String currentServerId) { - repo.findByIpAndPort(ip, port).ifPresent(existingServer -> { - if (currentServerId == null || !existingServer.getId().equals(currentServerId)) { - throw new RuntimeException("Server already exists with IP: " + ip + " and port: " + port); - } - }); - } } diff --git a/backend/src/main/java/com/hitcommunications/servermanager/services/TypeOptionService.java b/backend/src/main/java/com/hitcommunications/servermanager/services/TypeOptionService.java new file mode 100644 index 0000000..b060819 --- /dev/null +++ b/backend/src/main/java/com/hitcommunications/servermanager/services/TypeOptionService.java @@ -0,0 +1,42 @@ +package com.hitcommunications.servermanager.services; + +import com.hitcommunications.servermanager.model.TypeOption; +import com.hitcommunications.servermanager.model.enums.TypeCategory; +import com.hitcommunications.servermanager.repositories.TypeOptionRepository; +import com.hitcommunications.servermanager.utils.TypeNormalizer; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class TypeOptionService { + + private final TypeOptionRepository repository; + + @Transactional + public void register(TypeCategory category, String rawValue) { + String normalized = TypeNormalizer.normalize(rawValue); + if (normalized == null) { + return; + } + + repository.findByCategoryAndValue(category, normalized) + .orElseGet(() -> repository.save( + TypeOption.builder() + .category(category) + .value(normalized) + .build() + )); + } + + public List list(TypeCategory category) { + return repository.findAllByCategoryOrderByValueAsc(category) + .stream() + .map(TypeOption::getValue) + .collect(Collectors.toList()); + } +} diff --git a/backend/src/main/java/com/hitcommunications/servermanager/utils/TypeNormalizer.java b/backend/src/main/java/com/hitcommunications/servermanager/utils/TypeNormalizer.java new file mode 100644 index 0000000..d32a537 --- /dev/null +++ b/backend/src/main/java/com/hitcommunications/servermanager/utils/TypeNormalizer.java @@ -0,0 +1,30 @@ +package com.hitcommunications.servermanager.utils; + +import java.text.Normalizer; +import java.util.Locale; +import java.util.regex.Pattern; + +public final class TypeNormalizer { + + private static final Pattern DIACRITICS = Pattern.compile("\\p{M}"); + + private TypeNormalizer() { + } + + public static String normalize(String value) { + if (value == null) { + return null; + } + + String trimmed = value.trim(); + if (trimmed.isEmpty()) { + return null; + } + + String normalized = Normalizer.normalize(trimmed, Normalizer.Form.NFD); + normalized = DIACRITICS.matcher(normalized).replaceAll(""); + normalized = normalized.replaceAll("[^A-Za-z0-9_\\- ]", ""); + normalized = normalized.replaceAll("\\s+", "_"); + return normalized.toUpperCase(Locale.ROOT); + } +} diff --git a/backend/src/main/resources/application.yaml b/backend/src/main/resources/application.yaml index 475c075..0f260cf 100644 --- a/backend/src/main/resources/application.yaml +++ b/backend/src/main/resources/application.yaml @@ -6,6 +6,7 @@ spring: init: mode: always schema-locations: classpath:schema.sql + data-locations: classpath:data.sql datasource: url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME} diff --git a/backend/src/main/resources/data.sql b/backend/src/main/resources/data.sql index fffa582..7fb192e 100644 --- a/backend/src/main/resources/data.sql +++ b/backend/src/main/resources/data.sql @@ -18,3 +18,26 @@ INSERT INTO "server-manager".tab_users ( CURRENT_TIMESTAMP ) ON CONFLICT DO NOTHING; + +INSERT INTO "server-manager".tab_type_options (id, category, value) +VALUES + (101, 'SERVER_TYPE', 'PRODUCTION'), + (102, 'SERVER_TYPE', 'HOMOLOGATION'), + (103, 'SERVER_TYPE', 'DATABASE'), + (201, 'APPLICATION', 'ASTERISK'), + (202, 'APPLICATION', 'HITMANAGER'), + (203, 'APPLICATION', 'HITMANAGER_V2'), + (204, 'APPLICATION', 'OMNIHIT'), + (205, 'APPLICATION', 'HITPHONE'), + (206, 'APPLICATION', 'CDR'), + (207, 'APPLICATION', 'FUNCIONALIDADE'), + (208, 'APPLICATION', 'VOICEMAIL'), + (301, 'DATABASE', 'MYSQL'), + (302, 'DATABASE', 'POSTGRESQL'), + (303, 'DATABASE', 'SQLSERVER'), + (304, 'DATABASE', 'ORACLE'), + (305, 'DATABASE', 'REDIS'), + (306, 'DATABASE', 'MONGODB'), + (307, 'DATABASE', 'MARIADB'), + (308, 'DATABASE', 'NONE') +ON CONFLICT DO NOTHING; diff --git a/backend/src/main/resources/schema.sql b/backend/src/main/resources/schema.sql index a75d5a2..77efe44 100644 --- a/backend/src/main/resources/schema.sql +++ b/backend/src/main/resources/schema.sql @@ -1 +1,3 @@ -CREATE SCHEMA IF NOT EXISTS "server-manager"; \ No newline at end of file +CREATE SCHEMA IF NOT EXISTS "server-manager"; + +CREATE EXTENSION IF NOT EXISTS "pgcrypto";