feat(funcionario): adicionar módulo de gerenciamento de funcionários com rotas e controle de API

This commit is contained in:
Claudecio Martins
2025-10-22 16:03:18 +02:00
parent 311cadc1d1
commit 037900720b
25 changed files with 247 additions and 46 deletions

View File

@@ -0,0 +1,73 @@
<?php
namespace Workbloom\Module\Funcionario;
use DateTime;
use Exception;
use AxiumPHP\Core\Router;
// Caminho do manifest.json
$manifestPath = realpath(path: __DIR__ . "/manifest.json");
if (!$manifestPath || !file_exists(filename: $manifestPath)) {
throw new Exception(message: "Arquivo 'manifest.json' não encontrado.");
}
// Lê e decodifica
$manifest = json_decode(json: file_get_contents(filename: $manifestPath), associative: true);
// Verifica estrutura
if (!isset($manifest['apis']) || !is_array(value: $manifest['apis'])) {
throw new Exception(message: "Estrutura de 'apis' inválida no manifest.");
}
$now = (new DateTime())->format(format: 'Y-m-d');
$newApis = [];
$updated = false;
// Checa se tem versão esperando que começa hoje
foreach ($manifest['apis'] as $api) {
if ($api['status'] === 'planned' && $api['start_date'] === $now) {
// Promote a nova
$api['status'] = 'active';
$newApis[] = $api;
$updated = true;
} elseif ($api['status'] === 'active' && $api['start_date'] !== $now) {
// Ignora versão antiga ativa
continue;
} else {
$newApis[] = $api;
}
}
// Atualiza manifest se tiver mudança
if ($updated) {
$manifest['apis'] = $newApis;
file_put_contents(filename: $manifestPath, data: json_encode(value: $manifest, flags: JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
// Carrega a versão ativa
$loaded = false;
foreach ($manifest['apis'] as $api) {
$startDate = new DateTime(datetime: $api['start_date']);
if ($api['status'] === 'active' && $startDate <= new DateTime()) {
$routeFile = MODULE_PATH . "/{$manifest['dirName']}/{$api['version']}/Routes/Routes.php";
if (file_exists(filename: $routeFile)) {
Router::group(
prefix: "/{$manifest['slug']}",
callback: function() use ($routeFile) {
require_once realpath(path: $routeFile);
},
middlewares: []
);
$loaded = true;
break;
} else {
throw new Exception(message: "Arquivo de rotas não encontrado para a versão '{$api['version']}'.");
}
}
}
// Verifica se carregou
if (!$loaded) {
throw new Exception(message: "Nenhuma versão ativa da API foi carregada.");
}

View File

@@ -0,0 +1,16 @@
{
"name": "Funcionários",
"dirName": "Funcionario",
"slug": "funcionario",
"description": "Gerencia dados e operações relacionadas aos funcionários.",
"uuid": "019a0bfa-fc2f-7955-94d3-5f5273f07b3b",
"version": "1.0",
"dependencies": [],
"apis": [
{
"version": "v0",
"status": "active",
"start_date": "2025-10-22"
}
]
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Workbloom\Module\Funcionario\v0\Controllers;
use AxiumPHP\Helpers\RequestHelper;
class FuncionarioController {
public function listFuncionarios() {
// Resposta JSON
RequestHelper::sendJsonResponse(
response_code: 200,
status: 'success',
message: 'Lista de funcionários obtida com sucesso',
output: []
);
}
}

View File

@@ -0,0 +1,33 @@
<?php
use AxiumPHP\Core\Router;
use Workbloom\Module\Funcionario\v0\Controllers\FuncionarioController;
// Listagem de funcionários
Router::GET(
uri: '/',
handler: [FuncionarioController::class, 'listFuncionarios']
);
// Registro de novo funcionário
Router::POST(
uri: '/',
handler: [FuncionarioController::class, 'createFuncionario']
);
// Detalhes de um funcionário
Router::GET(
uri: '/{uuid}',
handler: [FuncionarioController::class, 'getFuncionario']
);
// Atualização de um funcionário
Router::PATCH(
uri: '/{uuid}',
handler: [FuncionarioController::class, 'updateFuncionario']
);
// Remoção de um funcionário
Router::DELETE(
uri: '/{uuid}',
handler: [FuncionarioController::class, 'deleteFuncionario']
);

View File

@@ -0,0 +1,2 @@
<?php
require_once 'FuncionarioRoutes.php';

View File

@@ -19,8 +19,8 @@
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Workbloom\\": "app/Common", "Workbloom\\": "app/Common",
"WorkbloomComponent\\": "app/Common/Component", "Workbloom\\Component\\": "app/Common/Component",
"WorkbloomModule\\": "app/Module" "Workbloom\\Module\\": "app/Module"
} }
}, },
"require-dev": { "require-dev": {

12
composer.lock generated
View File

@@ -795,16 +795,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.6.1", "version": "v5.6.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" "reference": "3a454ca033b9e06b63282ce19562e892747449bb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "reference": "3a454ca033b9e06b63282ce19562e892747449bb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -847,9 +847,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
}, },
"time": "2025-08-13T20:13:15+00:00" "time": "2025-10-21T19:32:17+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",

View File

@@ -3,7 +3,9 @@
require_once realpath(path: __DIR__ . '/../vendor/autoload.php'); require_once realpath(path: __DIR__ . '/../vendor/autoload.php');
use AxiumPHP\AxiumPHP; use AxiumPHP\AxiumPHP;
use AxiumPHP\Core\Router;
use Workbloom\Config\Config; use Workbloom\Config\Config;
use Workbloom\Component\Auth\v0\Middlewares\AuthMiddleware;
// ============================ // ============================
// Configurações globais // Configurações globais
@@ -48,6 +50,19 @@
// ============================ // ============================
require COMPONENT_PATH . "/Auth/bootstrap.php"; require COMPONENT_PATH . "/Auth/bootstrap.php";
// ============================================
// Carrega módulos do sistema versão 0
// ============================================
Router::group(
prefix: '/v0/module',
callback: function() {
require MODULE_PATH . "/Funcionario/bootstrap.php";
},
middlewares: [
[AuthMiddleware::class, 'handle']
]
);
// ============================ // ============================
// Dispara o roteador // Dispara o roteador
// ============================ // ============================

View File

@@ -6,9 +6,9 @@ $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'Workbloom\\Module\\' => array($baseDir . '/app/Module'),
'Workbloom\\Component\\' => array($baseDir . '/app/Common/Component'),
'Workbloom\\' => array($baseDir . '/app/Common'), 'Workbloom\\' => array($baseDir . '/app/Common'),
'WorkbloomModule\\' => array($baseDir . '/app/Module'),
'WorkbloomComponent\\' => array($baseDir . '/app/Common/Component'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),

View File

@@ -19,9 +19,9 @@ class ComposerStaticInit8166d455774ce82597f7c8b1884b0ce8
public static $prefixLengthsPsr4 = array ( public static $prefixLengthsPsr4 = array (
'W' => 'W' =>
array ( array (
'Workbloom\\Module\\' => 17,
'Workbloom\\Component\\' => 20,
'Workbloom\\' => 10, 'Workbloom\\' => 10,
'WorkbloomModule\\' => 16,
'WorkbloomComponent\\' => 19,
), ),
'S' => 'S' =>
array ( array (
@@ -55,18 +55,18 @@ class ComposerStaticInit8166d455774ce82597f7c8b1884b0ce8
); );
public static $prefixDirsPsr4 = array ( public static $prefixDirsPsr4 = array (
'Workbloom\\' => 'Workbloom\\Module\\' =>
array (
0 => __DIR__ . '/../..' . '/app/Common',
),
'WorkbloomModule\\' =>
array ( array (
0 => __DIR__ . '/../..' . '/app/Module', 0 => __DIR__ . '/../..' . '/app/Module',
), ),
'WorkbloomComponent\\' => 'Workbloom\\Component\\' =>
array ( array (
0 => __DIR__ . '/../..' . '/app/Common/Component', 0 => __DIR__ . '/../..' . '/app/Common/Component',
), ),
'Workbloom\\' =>
array (
0 => __DIR__ . '/../..' . '/app/Common',
),
'Symfony\\Polyfill\\Php80\\' => 'Symfony\\Polyfill\\Php80\\' =>
array ( array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80', 0 => __DIR__ . '/..' . '/symfony/polyfill-php80',

View File

@@ -233,17 +233,17 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.6.1", "version": "v5.6.2",
"version_normalized": "5.6.1.0", "version_normalized": "5.6.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" "reference": "3a454ca033b9e06b63282ce19562e892747449bb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "reference": "3a454ca033b9e06b63282ce19562e892747449bb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -256,7 +256,7 @@
"ircmaxell/php-yacc": "^0.0.7", "ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.0"
}, },
"time": "2025-08-13T20:13:15+00:00", "time": "2025-10-21T19:32:17+00:00",
"bin": [ "bin": [
"bin/php-parse" "bin/php-parse"
], ],
@@ -288,7 +288,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
}, },
"install-path": "../nikic/php-parser" "install-path": "../nikic/php-parser"
}, },

View File

@@ -1,9 +1,9 @@
<?php return array( <?php return array(
'root' => array( 'root' => array(
'name' => 'cybercore/workbloom', 'name' => 'cybercore/workbloom',
'pretty_version' => '1.0.0+no-version-set', 'pretty_version' => 'dev-main',
'version' => '1.0.0.0', 'version' => 'dev-main',
'reference' => null, 'reference' => '311cadc1d12a6f269a473c6861dfc268a201ef6f',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@@ -20,9 +20,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'cybercore/workbloom' => array( 'cybercore/workbloom' => array(
'pretty_version' => '1.0.0+no-version-set', 'pretty_version' => 'dev-main',
'version' => '1.0.0.0', 'version' => 'dev-main',
'reference' => null, 'reference' => '311cadc1d12a6f269a473c6861dfc268a201ef6f',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@@ -56,9 +56,9 @@
'dev_requirement' => true, 'dev_requirement' => true,
), ),
'nikic/php-parser' => array( 'nikic/php-parser' => array(
'pretty_version' => 'v5.6.1', 'pretty_version' => 'v5.6.2',
'version' => '5.6.1.0', 'version' => '5.6.2.0',
'reference' => 'f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2', 'reference' => '3a454ca033b9e06b63282ce19562e892747449bb',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../nikic/php-parser', 'install_path' => __DIR__ . '/../nikic/php-parser',
'aliases' => array(), 'aliases' => array(),

View File

@@ -5,7 +5,11 @@ namespace PhpParser\Node\Expr;
require __DIR__ . '/../ArrayItem.php'; require __DIR__ . '/../ArrayItem.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\ArrayItem instead.
*/
class ArrayItem extends \PhpParser\Node\ArrayItem { class ArrayItem extends \PhpParser\Node\ArrayItem {
} }
} }

View File

@@ -5,7 +5,11 @@ namespace PhpParser\Node\Expr;
require __DIR__ . '/../ClosureUse.php'; require __DIR__ . '/../ClosureUse.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\ClosureUse instead.
*/
class ClosureUse extends \PhpParser\Node\ClosureUse { class ClosureUse extends \PhpParser\Node\ClosureUse {
} }
} }

View File

@@ -71,6 +71,10 @@ class Param extends NodeAbstract {
return $this->flags !== 0 || $this->hooks !== []; return $this->flags !== 0 || $this->hooks !== [];
} }
public function isFinal(): bool {
return (bool) ($this->flags & Modifiers::FINAL);
}
public function isPublic(): bool { public function isPublic(): bool {
$public = (bool) ($this->flags & Modifiers::PUBLIC); $public = (bool) ($this->flags & Modifiers::PUBLIC);
if ($public) { if ($public) {

View File

@@ -5,7 +5,11 @@ namespace PhpParser\Node\Scalar;
require __DIR__ . '/Float_.php'; require __DIR__ . '/Float_.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\Scalar\Float_ instead.
*/
class DNumber extends Float_ { class DNumber extends Float_ {
} }
} }

View File

@@ -5,7 +5,11 @@ namespace PhpParser\Node\Scalar;
require __DIR__ . '/InterpolatedString.php'; require __DIR__ . '/InterpolatedString.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\Scalar\InterpolatedString instead.
*/
class Encapsed extends InterpolatedString { class Encapsed extends InterpolatedString {
} }
} }

View File

@@ -7,7 +7,11 @@ use PhpParser\Node\InterpolatedStringPart;
require __DIR__ . '/../InterpolatedStringPart.php'; require __DIR__ . '/../InterpolatedStringPart.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\InterpolatedStringPart instead.
*/
class EncapsedStringPart extends InterpolatedStringPart { class EncapsedStringPart extends InterpolatedStringPart {
} }
} }

View File

@@ -5,7 +5,11 @@ namespace PhpParser\Node\Scalar;
require __DIR__ . '/Int_.php'; require __DIR__ . '/Int_.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\Scalar\Int_ instead.
*/
class LNumber extends Int_ { class LNumber extends Int_ {
} }
} }

View File

@@ -124,7 +124,7 @@ class String_ extends Scalar {
// If it overflowed to float, treat as INT_MAX, it will throw an error anyway. // If it overflowed to float, treat as INT_MAX, it will throw an error anyway.
return self::codePointToUtf8(\is_int($dec) ? $dec : \PHP_INT_MAX); return self::codePointToUtf8(\is_int($dec) ? $dec : \PHP_INT_MAX);
} else { } else {
return chr(octdec($str)); return chr(octdec($str) & 255);
} }
}, },
$str $str

View File

@@ -7,7 +7,11 @@ use PhpParser\Node\DeclareItem;
require __DIR__ . '/../DeclareItem.php'; require __DIR__ . '/../DeclareItem.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\DeclareItem instead.
*/
class DeclareDeclare extends DeclareItem { class DeclareDeclare extends DeclareItem {
} }
} }

View File

@@ -7,7 +7,11 @@ use PhpParser\Node\PropertyItem;
require __DIR__ . '/../PropertyItem.php'; require __DIR__ . '/../PropertyItem.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\PropertyItem instead.
*/
class PropertyProperty extends PropertyItem { class PropertyProperty extends PropertyItem {
} }
} }

View File

@@ -5,7 +5,11 @@ namespace PhpParser\Node\Stmt;
require __DIR__ . '/../StaticVar.php'; require __DIR__ . '/../StaticVar.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\StaticVar instead.
*/
class StaticVar extends \PhpParser\Node\StaticVar { class StaticVar extends \PhpParser\Node\StaticVar {
} }
} }

View File

@@ -7,7 +7,11 @@ use PhpParser\Node\UseItem;
require __DIR__ . '/../UseItem.php'; require __DIR__ . '/../UseItem.php';
if (false) { if (false) {
// For classmap-authoritative support. /**
* For classmap-authoritative support.
*
* @deprecated use \PhpParser\Node\UseItem instead.
*/
class UseUse extends UseItem { class UseUse extends UseItem {
} }
} }

View File

@@ -678,8 +678,10 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
} }
[$printFn, $findToken] = $this->modifierChangeMap[$key]; [$printFn, $findToken] = $this->modifierChangeMap[$key];
$skipWSPos = $this->origTokens->skipRightWhitespace($pos);
$result .= $this->origTokens->getTokenCode($pos, $skipWSPos, $indentAdjustment);
$result .= $this->$printFn($subNode); $result .= $this->$printFn($subNode);
$pos = $this->origTokens->findRight($pos, $findToken); $pos = $this->origTokens->findRight($skipWSPos, $findToken);
continue; continue;
} }