first commit

This commit is contained in:
Claudecio Martins
2025-11-04 18:22:02 +01:00
commit c1184d2878
4394 changed files with 444123 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
<?php
namespace Zampet\Module\Tutor\v0\Services;
use DateTime;
use Exception;
use Ramsey\Uuid\Uuid;
use Zampet\Module\Auth\v0\Models\UsuarioModel;
use Zampet\Services\DB;
use Zampet\Services\JWTService;
use Zampet\Helpers\DataValidator;
use Zampet\Module\Tutor\v0\DTO\PetDTO;
use Zampet\Module\Tutor\v0\DTO\PetRacaDTO;
use Zampet\Module\Tutor\v0\Models\PetModel;
class PetService {
/**
* Retorna a lista de todas as espécies de pets disponíveis no sistema.
*
* Este método atua como um **wrapper** (invólucro) para o método de mesmo nome na classe `PetModel`. Ele delega a responsabilidade de buscar a lista completa das espécies de pets cadastradas para a camada de modelo (DAO).
*
* @return array Um array associativo contendo o status da operação, o código HTTP e os dados das espécies, conforme retornado pelo `PetModel`.
*/
public function getAllEspecies(): array {
return (new PetModel())->getAllEspecies();
}
/**
* Lista todos os pets de um tutor específico, buscando pelo UUID do tutor.
*
* Este método atua como um **wrapper** para o método `listPetsByTutorIdentifier` da classe `PetModel`. Ele delega a responsabilidade de buscar a lista completa e detalhada de pets associados a um tutor, utilizando o UUID como o identificador principal.
*
* @param string $uuid O UUID do tutor cujos pets devem ser listados.
* @return array Um array associativo contendo o status da operação, o código HTTP e os dados dos pets, conforme retornado pelo `PetModel`.
*/
public function listPetsByTutorUuid(string $uuid): array {
return (new PetModel())->listPetsByTutorIdentifier(identifier: 'uuid', value: $uuid);
}
/**
* Busca uma espécie de pet no sistema por um identificador específico.
*
* Este método atua como um **wrapper** para o método de busca de espécies na classe `PetModel`. Ele delega a responsabilidade de consultar a espécie para a camada de modelo (DAO), que lida com a lógica de acesso ao banco de dados.
*
* @param string $identifier A coluna da tabela a ser usada como critério de busca (ex: 'id', 'uuid', 'descricao').
* @param string $value O valor correspondente ao identificador que está sendo buscado.
* @return array Um array associativo contendo o status da operação, o código HTTP e os dados da espécie, conforme retornado pelo `PetModel`.
*/
public function getEspecieByIdentifier(string $identifier, string $value): array {
return (new PetModel())->getEspecieByIdentifier(identifier: $identifier, value: $value);
}
/**
* Busca uma raça de pet no sistema por um identificador específico.
*
* Este método atua como um **wrapper** (invólucro) para o método de busca de raças na classe `PetModel`. Ele delega a responsabilidade de consultar a raça para a camada de modelo (DAO), que lida com a lógica de acesso ao banco de dados e retorna o resultado.
*
* @param string $identifier A coluna da tabela a ser usada como critério de busca (ex: 'uuid', 'id', 'descricao').
* @param string $value O valor correspondente ao identificador que está sendo buscado.
* @return array Um array associativo contendo o status da operação, o código HTTP e os dados da raça, conforme retornado pelo `PetModel`.
*/
public function getRacaByIdentifier(string $identifier, string $value): array {
return (new PetModel())->getRacaByIdentifier(identifier: $identifier, value: $value);
}
/**
* Busca um pet no sistema por um identificador específico.
*
* Este método atua como um **wrapper** (invólucro) para o método de busca de pets na classe `PetModel`. Ele delega a responsabilidade de consultar o pet para a camada de modelo (DAO), que lida com a lógica de acesso ao banco de dados.
*
* @param string $identifier A coluna da tabela a ser usada como critério de busca (ex: 'uuid', 'id', 'nome').
* @param string $value O valor correspondente ao identificador que está sendo buscado.
* @return array Um array associativo contendo o status da operação, o código HTTP e os dados do pet, conforme retornado pelo `PetModel`.
*/
public function getPetByIdentifier(string $identifier, string $value): array {
return (new PetModel())->getPetByIdentifier(identifier: $identifier, value: $value);
}
/**
* Cria uma nova raça de pet no sistema após validação.
*
* Este método orquestra a criação de uma nova raça de pet. Ele realiza a validação dos dados de entrada, define metadados essenciais (UUID) e persiste o registro no banco de dados, garantindo a atomicidade da operação através de uma transação.
*
* #### Fluxo de Operação:
* 1. **Início da Transação:** Inicia uma transação no banco de dados (`DB::beginTransaction()`).
* 2. **Validação de Dados:** Utiliza o `DataValidator` para verificar se os campos **'especie_id'** e **'descricao'** foram preenchidos.
* 3. **Encerramento em Caso de Falha na Validação:** Se houver erros de validação, a transação é revertida (`DB::rollBack()`) e um array de erro formatado é retornado com o código `400 Bad Request`.
* 4. **Preparação Final dos Dados:** Define um **UUID** único para a nova raça.
* 5. **Persistência:** Chama o método `storeRaca` do `PetModel` para inserir o registro no banco de dados. Se a persistência falhar, uma `Exception` é lançada com a mensagem de erro do modelo.
* 6. **Confirmação e Retorno:** Se a persistência for bem-sucedida, a transação é **confirmada** (`DB::commit()`) e o resultado de sucesso é retornado com o código `201 Created`.
*
* #### Tratamento de Erros:
* - Qualquer `Exception` lançada durante o processo é capturada, e a transação é **revertida** (`DB::rollBack()`).
* - Retorna um array de erro formatado contendo o código HTTP e a mensagem da exceção.
*
* @param PetRacaDTO $petRacaDTO O objeto DTO contendo o ID da espécie e a descrição da nova raça.
* @return array Um array associativo contendo o status da operação, o código de resposta HTTP e os dados de saída, ou erros de validação.
*/
public function storeRaca(PetRacaDTO $petRacaDTO): array {
// Inicia transação no banco de dados
DB::beginTransaction();
try {
// Valida os dados do DTO
$dataValidador = new DataValidator(inputs: $petRacaDTO->toArray());
$dataValidador->validate(field: 'especie_id', rule: 'notEmpty', message: 'Espécie é obrigatória.');
$dataValidador->validate(field: 'descricao', rule: 'notEmpty', message: 'Descrição é obrigatória.');
// Se houver erros de validação, retornar resposta de erro
if(!$dataValidador->passes()) {
DB::rollBack();
return [
'response_code' => 400,
'status' => 'error',
'message' => 'Validation errors',
'output' => [
'errors' => $dataValidador->getErrors()
]
];
}
// Define dados adicionais
$petRacaDTO->setUuid(uuid: Uuid::uuid7()->toString());
// Cria a nova raça no banco de dados
$storeRaca = (new PetModel())->storeRaca(petRacaDTO: $petRacaDTO);
if($storeRaca['status'] !== 'success') {
throw new Exception(message: $storeRaca['message'], code: $storeRaca['response_code']);
}
DB::commit();
return [
'response_code' => 201,
'status' => 'success',
'message' => 'Raça criada com sucesso.',
'output' => $storeRaca['output']
];
} catch(Exception $e) {
DB::rollBack();
return [
'response_code' => $e->getCode(),
'status' => 'error',
'message' => $e->getMessage()
];
}
}
/**
* Armazena um novo pet no sistema e o associa ao usuário autenticado.
*
* Este método é responsável por orquestrar a criação de um novo pet, desde a validação inicial até a persistência do pet e o registro da relação com o tutor. A operação é **atômica** e garante a integridade dos dados através de uma transação de banco de dados.
*
* #### Fluxo de Operação:
* 1. **Início da Transação:** Inicia uma transação no banco de dados (`DB::beginTransaction()`).
* 2. **Validação de Dados:** O `DataValidator` verifica a presença e validade dos campos obrigatórios (nome, raça UUID, data de nascimento e sexo). Se falhar, a transação é revertida e um erro `400 Bad Request` é retornado.
* 3. **Validação de Duplicidade (RGA):** Se fornecido, o Registro Geral Animal (RGA) é verificado quanto à unicidade. Se um pet com o mesmo RGA for encontrado, uma `Exception` é lançada com o código `409 Conflict`.
* 4. **Preparação Final dos Dados:** O UUID do pet e o timestamp de criação são definidos.
* 5. **Criação do Pet:** O método `storePet` do `PetModel` é chamado para inserir o registro do pet. Se falhar, uma `Exception` é lançada.
* 6. **Associação ao Tutor:** O token JWT é decodificado para obter o UUID do tutor. O ID interno do tutor é buscado, e o pet é associado ao tutor através do método `storeUsuarioPet`. Se o tutor não for encontrado ou a associação falhar, uma `Exception` é lançada.
* 7. **Confirmação e Retorno:** Se todas as operações forem bem-sucedidas, a transação é **confirmada** (`DB::commit()`) e o resultado de sucesso é retornado com o código `201 Created`.
*
* #### Tratamento de Erros:
* - Qualquer `Exception` lançada durante o processo é capturada, a transação é **revertida** (`DB::rollBack()`), e um array de erro formatado contendo o código HTTP e a mensagem da exceção é retornado.
*
* @param PetDTO $petDTO O objeto DTO contendo os dados do novo pet.
* @return array Um array associativo com o status da operação, código HTTP e os dados do pet criado.
*/
public function storePet(PetDTO $petDTO): array {
// Inicia transação no banco de dados
DB::beginTransaction();
try {
// Valida os dados do DTO
$dataValidador = new DataValidator(inputs: $petDTO->toArray());
$dataValidador->validate(field: 'nome', rule: 'notEmpty', message: 'Nome do pet é obrigatório.');
$dataValidador->validate(field: 'sexo', rule: 'notEmpty', message: 'Sexo do pet é obrigatório.');
$dataValidador->validate(field: 'raca_id', rule: 'notEmpty', message: 'Raça do pet é obrigatória.');
$dataValidador->validate(field: 'especie_id', rule: 'notEmpty', message: 'Espécie do pet é obrigatória.');
$dataValidador->validate(field: 'data_nascimento', rule: 'notEmpty', message: 'Data de nascimento do pet é obrigatória.');
// Se houver erros de validação, retornar resposta de erro
if(!$dataValidador->passes()) {
return [
'response_code' => 400,
'status' => 'error',
'message' => 'Validation errors',
'output' => [
'errors' => $dataValidador->getErrors()
]
];
}
// Verifica se o Registro Geral Animal do PET (RGA) é único, se fornecido
if(($petDTO->getRegistroGeralAnimal() !== null) && !empty($petDTO->getRegistroGeralAnimal())) {
$existingPet = $this->getPetByIdentifier(identifier: 'registro_geral_animal', value: $petDTO->getRegistroGeralAnimal());
if($existingPet['status'] === 'success' && !empty($existingPet['output']['data'])) {
throw new Exception(message: 'Já existe um pet cadastrado com este Registro Geral Animal (RGA).', code: 409);
}
}
// Define dados adicionais
$petDTO->setUuid(uuid: Uuid::uuid7()->toString());
$petDTO->setCreatedAt(created_at: (new DateTime())->format(format: 'Y-m-d H:i:s'));
// Cria o novo pet no banco de dados
$storePet = (new PetModel())->storePet(petDTO: $petDTO);
if($storePet['status'] !== 'success') {
throw new Exception(message: $storePet['message'], code: $storePet['response_code']);
}
// Consulta o token JWT
$decodedToken = JWTService::decode(token: JWTService::getBearerToken());
// Consulta o ID do tutor pelo UUID
$getTutor = (new UsuarioModel())->getUsuarioByIdentifier(identifier: 'uuid', value: $decodedToken['user_uuid']);
if($getTutor['status'] !== 'success' || empty($getTutor['output']['data'])) {
throw new Exception(message: 'Tutor não encontrado.', code: 404);
}
// Relaciona o pet ao tutor autenticado
$dataValidador = (new PetModel())->storeUsuarioPet(usuario_id: $getTutor['output']['data']['id'], pet_id: $storePet['output']['data']['id']);
if($dataValidador['status'] !== 'success') {
throw new Exception(message: $dataValidador['message'], code: $dataValidador['response_code']);
}
DB::commit();
return [
'response_code' => 201,
'status' => 'success',
'message' => 'Pet criado com sucesso.',
'output' => $storePet['output']
];
} catch(Exception $e) {
DB::rollBack();
return [
'response_code' => $e->getCode(),
'status' => 'error',
'message' => $e->getMessage()
];
}
}
}