From 5beba1c8eca3f864a581a8eca5160618c5ce8564 Mon Sep 17 00:00:00 2001 From: almdgustadev Date: Thu, 24 Jul 2025 22:42:35 -0300 Subject: [PATCH 1/4] feat: criar ponto de entrada da API e controller --- src/Controller/ExchangeController.php | 0 src/index.php | 24 ++++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/Controller/ExchangeController.php diff --git a/src/Controller/ExchangeController.php b/src/Controller/ExchangeController.php new file mode 100644 index 000000000..e69de29bb diff --git a/src/index.php b/src/index.php index 92841bc87..3b6b1d2c1 100644 --- a/src/index.php +++ b/src/index.php @@ -8,11 +8,31 @@ * * @category Challenge * @package Back-end - * @author Seu Nome + * @author Gustavo de Almeida Oliveira * @license http://opensource.org/licenses/MIT MIT * @link https://github.com/apiki/back-end-challenge */ declare(strict_types=1); -require __DIR__ . '/../vendor/autoload.php'; +require __DIR__ . '/Controller/ExchangeController.php'; +$uri = $_SERVER['REQUEST_URI']; +$method = $_SERVER['REQUEST_METHOD']; + +$pattern='#^/exchange/([\d.]+)/([A-Z]{3})/([A-Z]{3})/([\d.]+)$#'; + +if ($method === 'GET' && preg_match($pattern, $uri, $matches)) { + $amount = (float)$matches[1]; + $from = $matches[2]; + $to = $matches[3]; + $rate = (float)$matches[4]; + + $controller = new \Controller\ExchangeController(); + $response = $controller->convert($amount, $from, $to, $rate); + + header('Content-Type: application/json'); + echo json_encode($response); +} else { + http_response_code(404); + echo json_encode(['error' => 'Rota não encontrada ou inválida']); +} From dd58cb0597330b0a641383f2b41e2d499922ad6b Mon Sep 17 00:00:00 2001 From: almdgustadev Date: Thu, 24 Jul 2025 23:28:24 -0300 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20implementar=20controller,=20service?= =?UTF-8?q?=20e=20utilit=C3=A1rio=20para=20convers=C3=A3o=20de=20moedas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/ExchangeController.php | 15 +++++++++++++++ src/Service/ExchangeService.php | 21 +++++++++++++++++++++ src/Util/CurrencySymbol.php | 16 ++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/Service/ExchangeService.php create mode 100644 src/Util/CurrencySymbol.php diff --git a/src/Controller/ExchangeController.php b/src/Controller/ExchangeController.php index e69de29bb..fc8ea3edf 100644 --- a/src/Controller/ExchangeController.php +++ b/src/Controller/ExchangeController.php @@ -0,0 +1,15 @@ +convertCurrency($amount, $from, $to, $rate); + } +} \ No newline at end of file diff --git a/src/Service/ExchangeService.php b/src/Service/ExchangeService.php new file mode 100644 index 000000000..1dea8efb9 --- /dev/null +++ b/src/Service/ExchangeService.php @@ -0,0 +1,21 @@ + $converted, + 'simboloMoeda' => $symbol + ]; + } +} \ No newline at end of file diff --git a/src/Util/CurrencySymbol.php b/src/Util/CurrencySymbol.php new file mode 100644 index 000000000..2fc0eee82 --- /dev/null +++ b/src/Util/CurrencySymbol.php @@ -0,0 +1,16 @@ + '$', + 'BRL' => 'R$', + 'EUR' => '€' + ]; + + return $symbols[$currency] ?? ''; + } +} \ No newline at end of file From b4c34a0f2bbc8a231fcacb9e7227b221c9b5987b Mon Sep 17 00:00:00 2001 From: almdgustadev Date: Thu, 24 Jul 2025 23:43:39 -0300 Subject: [PATCH 3/4] =?UTF-8?q?Fix:=20formatar=20valor=20convertido=20na?= =?UTF-8?q?=20fun=C3=A7=C3=A3o=20convertCurrency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Service/ExchangeService.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Service/ExchangeService.php b/src/Service/ExchangeService.php index 1dea8efb9..560951091 100644 --- a/src/Service/ExchangeService.php +++ b/src/Service/ExchangeService.php @@ -9,12 +9,13 @@ class ExchangeService { public function convertCurrency(float $amount, string $from, string $to, float $rate): array { - $converted = round($amount * $rate); + $converted = $amount * $rate; + $convertedFormatted = number_format($converted, 2, ',', '.'); $symbol = CurrencySymbol::getSymbol($to); return [ - 'valorConvertido' => $converted, + 'valorConvertido' => $convertedFormatted, 'simboloMoeda' => $symbol ]; } From d654f627141b7f4add226543d9e406839ed24557 Mon Sep 17 00:00:00 2001 From: almdgustadev Date: Mon, 28 Jul 2025 20:54:46 -0300 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20finaliza=20desafio=20de=20API=20de?= =?UTF-8?q?=20convers=C3=A3o=20de=20moedas=20Adiciona=20tratamento=20de=20?= =?UTF-8?q?erros=20com=20mensagens=20em=20JSON=20padronizadas=20adicionand?= =?UTF-8?q?o=20docblocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/ExchangeController.php | 43 ++++++++++++++++++++-- src/Service/ExchangeService.php | 53 +++++++++++++++++++++++---- src/Util/CurrencySymbol.php | 34 +++++++++++++++-- src/index.php | 50 ++++++++++++++++--------- 4 files changed, 148 insertions(+), 32 deletions(-) diff --git a/src/Controller/ExchangeController.php b/src/Controller/ExchangeController.php index fc8ea3edf..b21024e2c 100644 --- a/src/Controller/ExchangeController.php +++ b/src/Controller/ExchangeController.php @@ -1,15 +1,50 @@ - + * @license MIT + * @link https://github.com/almdgustadev/back-end-challenge + */ + namespace Controller; require_once __DIR__ . '/../Service/ExchangeService.php'; use Service\ExchangeService; +/** + * Controlador responsável por receber requisições e chamar o serviço de conversão. + * + * @category Controller + * @package CurrencyExchange + * @author Gustavo de Almeida Oliveira + * @license MIT + * @link https://github.com/almdgustadev/back-end-challenge + */ + class ExchangeController { - public function convert(float $amount, string $from, string $to, float $rate): array - { + /** + * Converte um valor de uma moeda para outra. + * + * @param float $amount Valor a ser convertido + * @param string $from Moeda de origem (ex: BRL) + * @param string $to Moeda de destino (ex: USD) + * @param float $rate Taxa de conversão + * + * @return array Retorno com valor convertido e símbolo + */ + public function convert( + float $amount, + string $from, + string $to, + float $rate + ): array { $service = new ExchangeService(); return $service->convertCurrency($amount, $from, $to, $rate); } -} \ No newline at end of file +} diff --git a/src/Service/ExchangeService.php b/src/Service/ExchangeService.php index 560951091..c9c312c05 100644 --- a/src/Service/ExchangeService.php +++ b/src/Service/ExchangeService.php @@ -1,22 +1,59 @@ - + * @license MIT + * @link https://github.com/almdgustadev/back-end-challenge + */ + namespace Service; require_once __DIR__ . '/../Util/CurrencySymbol.php'; use Util\CurrencySymbol; +/** + * Serviço responsável pela lógica de conversão de moedas. + * + * @category Service + * @package CurrencyExchange + * @author Gustavo de Almeida Oliveira + * @license MIT + * @link https://github.com/almdgustadev/back-end-challenge + */ + class ExchangeService { - public function convertCurrency(float $amount, string $from, string $to, float $rate): array - { + /** + * Converte o valor da moeda para outra utilizando a taxa de câmbio fornecida. + * + * @param float $amount Valor a ser convertido. + * @param string $from Moeda de origem. + * @param string $to Moeda de destino. + * @param float $rate Taxa de câmbio. + * + * @return array Resultado da conversão com valor convertido e símbolo da moeda. + */ + public function convertCurrency( + float $amount, + string $from, + string $to, + float $rate + ): array { + if ($rate <= 0) { + throw new \InvalidArgumentException('A taxa de câmbio deve ser maior que zero.'); + } $converted = $amount * $rate; - $convertedFormatted = number_format($converted, 2, ',', '.'); $symbol = CurrencySymbol::getSymbol($to); return [ - 'valorConvertido' => $convertedFormatted, - 'simboloMoeda' => $symbol - ]; + 'valorConvertido' => $converted, + 'simboloMoeda' => $symbol, + ]; } -} \ No newline at end of file +} diff --git a/src/Util/CurrencySymbol.php b/src/Util/CurrencySymbol.php index 2fc0eee82..acd38265f 100644 --- a/src/Util/CurrencySymbol.php +++ b/src/Util/CurrencySymbol.php @@ -1,16 +1,44 @@ - + * @license MIT + * @link https://github.com/almdgustadev/back-end-challenge + */ + namespace Util; +/** + * Utilitário para obter o símbolo de uma moeda. + * + * @category Util + * @package CurrencyExchange + * @author Gustavo de Almeida Oliveira + * @license MIT + * @link https://github.com/almdgustadev/back-end-challenge + */ + class CurrencySymbol { + /** + * Retorna o símbolo da moeda correspondente ao código fornecido. + * + * @param string $currency Código da moeda. + * + * @return string Símbolo da moeda ou uma string vazia se não encontrado. + */ public static function getSymbol(string $currency): string { $symbols = [ 'USD' => '$', 'BRL' => 'R$', - 'EUR' => '€' + 'EUR' => '€', ]; return $symbols[$currency] ?? ''; } -} \ No newline at end of file +} diff --git a/src/index.php b/src/index.php index 3b6b1d2c1..ba559de6e 100644 --- a/src/index.php +++ b/src/index.php @@ -2,7 +2,7 @@ /** * Back-end Challenge. * - * PHP version 7.4 + * PHP version 8.1 * * Este será o arquivo chamado na execução dos testes automátizados. * @@ -10,29 +10,45 @@ * @package Back-end * @author Gustavo de Almeida Oliveira * @license http://opensource.org/licenses/MIT MIT - * @link https://github.com/apiki/back-end-challenge + * @link https://github.com/almdgustadev/back-end-challenge + * + * Ponto de entrada para a aplicação + * Roteia a requisição para o controlador de conversão de moedas */ -declare(strict_types=1); -require __DIR__ . '/Controller/ExchangeController.php'; +require_once __DIR__ . '/Controller/ExchangeController.php'; + +use Controller\ExchangeController; $uri = $_SERVER['REQUEST_URI']; $method = $_SERVER['REQUEST_METHOD']; -$pattern='#^/exchange/([\d.]+)/([A-Z]{3})/([A-Z]{3})/([\d.]+)$#'; +$pattern = '#^/exchange/(-?[\d.]+)/([A-Z]{3})/([A-Z]{3})/(-?[\d.]+)$#'; -if ($method === 'GET' && preg_match($pattern, $uri, $matches)) { - $amount = (float)$matches[1]; - $from = $matches[2]; - $to = $matches[3]; - $rate = (float)$matches[4]; +try { + if ($method === 'GET' && preg_match($pattern, $uri, $matches)) { + $amount = (float) $matches[1]; + $from = $matches[2]; + $to = $matches[3]; + $rate = (float) $matches[4]; - $controller = new \Controller\ExchangeController(); - $response = $controller->convert($amount, $from, $to, $rate); + $controller = new ExchangeController(); + $response = $controller->convert($amount, $from, $to, $rate); + http_response_code(200); + header('Content-Type: application/json'); + echo json_encode($response); + } else { + http_response_code(400); + header('Content-Type: application/json'); + echo json_encode(['error' => 'Rota não encontrada ou inválida']); + } +} catch (\InvalidArgumentException $e) { + http_response_code(400); + header('Content-Type: application/json'); + echo json_encode(['error' => $e->getMessage()]); +} catch (\Throwable $e) { + http_response_code(500); header('Content-Type: application/json'); - echo json_encode($response); -} else { - http_response_code(404); - echo json_encode(['error' => 'Rota não encontrada ou inválida']); -} + echo json_encode(['error' => 'Erro interno no servidor']); +} \ No newline at end of file