From 8daa75f3d1515dca987eac8baa4a1c74e19b19a6 Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 12:34:50 -0300 Subject: [PATCH 1/7] (chore): Mago analyse --- .github/issues.json | 11 +++++--- .../UseCase/Dice/RollDice/RollDiceUseCase.php | 3 ++- .../StartSession/StartSessionUseCase.php | 6 ++--- .../StartSession/StartSessionUseCaseInput.php | 4 +++ src/Domain/Entities/Session.php | 6 +++++ src/Domain/ValueObjects/Utils/Result.php | 2 +- .../Console/Dice/RollDiceCommand.php | 5 ++-- .../Console/Session/StartSessionCommand.php | 14 ++++++++--- src/Infrastructure/Handler/LogHandler.php | 25 +++++++++++++++++-- 9 files changed, 61 insertions(+), 15 deletions(-) diff --git a/.github/issues.json b/.github/issues.json index 9bc53e3..d256d3c 100644 --- a/.github/issues.json +++ b/.github/issues.json @@ -1,7 +1,12 @@ [ { - "title": "Test", - "body": "Testing auto issue creation", - "labels": ["documentation"] + "title": "(refactor): Return types and throwing exceptions", + "body": "Its necessary to update the return types of the use case and its input, as well as to throw exceptions for invalid input. This will improve the robustness and clarity of the code.", + "labels": ["refactor"] + }, + { + "title": "(refactor): Command structure", + "body": "Update the command structure to something more clear and abstract, too many information in one single command can be overwhelming and hard to maintain. Consider breaking it down into smaller, more focused commands or methods.", + "labels": ["refactor"] } ] \ No newline at end of file diff --git a/src/Application/UseCase/Dice/RollDice/RollDiceUseCase.php b/src/Application/UseCase/Dice/RollDice/RollDiceUseCase.php index c764789..52e0234 100644 --- a/src/Application/UseCase/Dice/RollDice/RollDiceUseCase.php +++ b/src/Application/UseCase/Dice/RollDice/RollDiceUseCase.php @@ -30,7 +30,7 @@ public function run(RollDiceUseCaseInput $input): Result foreach ($this->generateChunks($multiplier, 250_000) as $chunkSize) { $awaitables[] = Async\run(function () use ($chunkSize, $dice): int { $sum = 0; - for ($i = 0; $i < $chunkSize; $i++) { + for ($i = 0; $i < (int) $chunkSize; $i++) { $sum += RollDiceAction::roll($dice); } return $sum; @@ -73,6 +73,7 @@ public function run(RollDiceUseCaseInput $input): Result } } + /** @return \Generator */ private function generateChunks(int $multiplier, int $chunkSize): \Generator { $remaining = $multiplier; diff --git a/src/Application/UseCase/Session/StartSession/StartSessionUseCase.php b/src/Application/UseCase/Session/StartSession/StartSessionUseCase.php index e6bac22..3fd417b 100644 --- a/src/Application/UseCase/Session/StartSession/StartSessionUseCase.php +++ b/src/Application/UseCase/Session/StartSession/StartSessionUseCase.php @@ -12,7 +12,7 @@ final class StartSessionUseCase { /** - * @return Result + * @return Result */ public function run(StartSessionUseCaseInput $input): Result { @@ -27,8 +27,8 @@ public function run(StartSessionUseCaseInput $input): Result 'Session (' . $resultStartSession->session->identifier->value . ') started successfully.', $resultStartSession, ); - } catch (\Exception $e) { - return Result::error(message: 'Failed to start session: ' . $e->getMessage()); + } catch (\InvalidArgumentException $e) { + return Result::error('Failed to start session' . $e->getMessage()); } } } diff --git a/src/Application/UseCase/Session/StartSession/StartSessionUseCaseInput.php b/src/Application/UseCase/Session/StartSession/StartSessionUseCaseInput.php index e9c5c64..ce20884 100644 --- a/src/Application/UseCase/Session/StartSession/StartSessionUseCaseInput.php +++ b/src/Application/UseCase/Session/StartSession/StartSessionUseCaseInput.php @@ -6,6 +6,10 @@ final class StartSessionUseCaseInput { + /** + * @param string $name The name of the session to be started + * @throws \InvalidArgumentException if the name is empty + */ public function __construct( public string $name, ) { diff --git a/src/Domain/Entities/Session.php b/src/Domain/Entities/Session.php index 033aa3f..d857f91 100644 --- a/src/Domain/Entities/Session.php +++ b/src/Domain/Entities/Session.php @@ -8,6 +8,12 @@ final class Session { + /** + * @param string $name The name of the session + * @param Identifier $identifier The unique identifier for the session + * @param \DateTime $createdAt The date and time when the session was created + * @throws \InvalidArgumentException if the session name is empty + */ public function __construct( public readonly string $name, public readonly Identifier $identifier, diff --git a/src/Domain/ValueObjects/Utils/Result.php b/src/Domain/ValueObjects/Utils/Result.php index e61c9e5..62bafdf 100644 --- a/src/Domain/ValueObjects/Utils/Result.php +++ b/src/Domain/ValueObjects/Utils/Result.php @@ -24,7 +24,7 @@ private function __construct( /** * @template TValue * @param TValue $data - * @return self + * @return self */ public static function success(string $message, mixed $data = null): self { diff --git a/src/Infrastructure/EntryPoints/Console/Dice/RollDiceCommand.php b/src/Infrastructure/EntryPoints/Console/Dice/RollDiceCommand.php index 0ca1098..f47f856 100644 --- a/src/Infrastructure/EntryPoints/Console/Dice/RollDiceCommand.php +++ b/src/Infrastructure/EntryPoints/Console/Dice/RollDiceCommand.php @@ -4,6 +4,7 @@ namespace RPGPlayground\Infrastructure\EntryPoints\Console\Dice; +use Monolog\Level; use RPGPlayground\Application\UseCase\Dice\RollDice\RollDiceUseCase; use RPGPlayground\Application\UseCase\Dice\RollDice\RollDiceUseCaseInput; use RPGPlayground\Domain\ValueObjects\App\Dice; @@ -138,7 +139,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int padding: true, ); - LogHandler::dispatch('info', 'Rolled dice', [ + LogHandler::dispatch(Level::Info, 'Rolled dice', [ 'dice_params' => $diceParams, 'roll_value' => $resultRollValue->rollValue, ]); @@ -147,7 +148,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } catch (\InvalidArgumentException $e) { $io = new SymfonyStyle($input, $output); $io->error($e->getMessage()); - LogHandler::dispatch('error', 'Roll dice command', ['exception' => $e->getMessage()]); + LogHandler::dispatch(Level::Error, 'Roll dice command', ['exception' => $e->getMessage()]); return Command::FAILURE; } } diff --git a/src/Infrastructure/EntryPoints/Console/Session/StartSessionCommand.php b/src/Infrastructure/EntryPoints/Console/Session/StartSessionCommand.php index c6d49a0..f037548 100644 --- a/src/Infrastructure/EntryPoints/Console/Session/StartSessionCommand.php +++ b/src/Infrastructure/EntryPoints/Console/Session/StartSessionCommand.php @@ -4,6 +4,7 @@ namespace RPGPlayground\Infrastructure\EntryPoints\Console\Session; +use Monolog\Level; use RPGPlayground\Application\UseCase\Session\StartSession\StartSessionUseCase; use RPGPlayground\Application\UseCase\Session\StartSession\StartSessionUseCaseInput; use RPGPlayground\Infrastructure\Handler\LogHandler; @@ -71,6 +72,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int $resultStartSession = $useCase->run(new StartSessionUseCaseInput(name: $name)); + if (!isset($resultStartSession)) { + $io->error('An unexpected error occurred while starting the session.'); + LogHandler::dispatch(Level::Error, 'Start session command', ['error' => 'Result is null']); + return Command::FAILURE; + } + if ($resultStartSession->isError()) { $io->error($resultStartSession->getMessage()); return Command::FAILURE; @@ -78,8 +85,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $resultStartSession = $resultStartSession->getData(); - if (!$resultStartSession) { + if (!isset($resultStartSession)) { $io->error('An unexpected error occurred while starting the session.'); + LogHandler::dispatch(Level::Error, 'Start session command', ['error' => 'Result data is null']); return Command::FAILURE; } @@ -96,14 +104,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int padding: true, ); - LogHandler::dispatch('info', 'Started session', [ + LogHandler::dispatch(Level::Info, 'Started session', [ 'session_id' => $resultStartSession->session->identifier->value, ]); return Command::SUCCESS; } catch (\InvalidArgumentException $e) { $io = new SymfonyStyle($input, $output); $io->error($e->getMessage()); - LogHandler::dispatch('error', 'Start session command', ['exception' => $e->getMessage()]); + LogHandler::dispatch(Level::Error, 'Start session command', ['exception' => $e->getMessage()]); return Command::FAILURE; } } diff --git a/src/Infrastructure/Handler/LogHandler.php b/src/Infrastructure/Handler/LogHandler.php index aabe024..2ad2679 100644 --- a/src/Infrastructure/Handler/LogHandler.php +++ b/src/Infrastructure/Handler/LogHandler.php @@ -5,24 +5,45 @@ namespace RPGPlayground\Infrastructure\Handler; use Monolog\Handler\StreamHandler; +use Monolog\Level; use Monolog\Logger; final class LogHandler { private static ?Logger $instance = null; + /** + * Bind a logger instance to the LogHandler. + * @param Logger $logger The logger instance to bind + * @return void + */ public static function bind(Logger $logger): void { self::$instance = $logger; } + /** + * Add a log handler to the logger instance. + * @param StreamHandler $streamHandler The log handler to add + * @return void + */ public static function stream(StreamHandler $streamHandler): void { self::$instance?->pushHandler($streamHandler); } - public static function dispatch(string $level, string $message, array $context = []): void + /** + * @param Level $level The log level (e.g., Level::Error, Level::Info) + * @param string $message The log message + * @param array $context Additional context for the log entry + */ + public static function dispatch(Level $level, string $message, array $context = []): void { - self::$instance?->log($level, $message, $context); + try { + self::$instance?->log($level, $message, $context); + } catch (\Throwable $e) { + // Handle logging errors gracefully, e.g., by writing to a fallback log file + error_log('Logging error: ' . $e->getMessage()); + } } } From 6d0b981e0e280f4600a77ba07f37473daf0a2c33 Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 12:39:57 -0300 Subject: [PATCH 2/7] (workflow): Auto Issue Creator --- .github/workflows/auto-issue.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/auto-issue.yml b/.github/workflows/auto-issue.yml index 9f3c157..8463223 100644 --- a/.github/workflows/auto-issue.yml +++ b/.github/workflows/auto-issue.yml @@ -1,8 +1,9 @@ name: Auto Issue Creator on: - schedule: - - cron: '0 9 * * 1' - workflow_dispatch: + push: + branches: + - main + - '*develop*' jobs: create-issues: From 0449eba206cb3ca991a2a67b700a440f7c9a4e31 Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 12:48:26 -0300 Subject: [PATCH 3/7] (fix): Minor fix, Workflow --- .github/workflows/auto-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-issue.yml b/.github/workflows/auto-issue.yml index 8463223..642e4d7 100644 --- a/.github/workflows/auto-issue.yml +++ b/.github/workflows/auto-issue.yml @@ -3,7 +3,7 @@ on: push: branches: - main - - '*develop*' + - '**' jobs: create-issues: From d9731033e3e5447c945dc02723c4eed2ae343eb6 Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 12:49:47 -0300 Subject: [PATCH 4/7] (fix): Minor changes to auto-issue.yml --- .github/workflows/auto-issue.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/auto-issue.yml b/.github/workflows/auto-issue.yml index 642e4d7..55eb2a3 100644 --- a/.github/workflows/auto-issue.yml +++ b/.github/workflows/auto-issue.yml @@ -2,12 +2,13 @@ name: Auto Issue Creator on: push: branches: - - main - '**' jobs: create-issues: runs-on: ubuntu-latest + permissions: + issues: write steps: - uses: actions/checkout@v4 From d1c4bd2d4f218bba829c1b182d7ff0b7e49f408b Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 12:52:28 -0300 Subject: [PATCH 5/7] (fix): Update auto-issue.yml to not duplicate issues on every push --- .github/workflows/auto-issue.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/auto-issue.yml b/.github/workflows/auto-issue.yml index 55eb2a3..dc4a740 100644 --- a/.github/workflows/auto-issue.yml +++ b/.github/workflows/auto-issue.yml @@ -12,12 +12,22 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Create Weekly TODO Issues + - name: Auto create issues from .github/issues.json uses: actions/github-script@v7 with: script: | const todos = require('.github/issues.json'); + const existing = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'all' + }); + + const existingTitles = existing.data.map(i => i.title); + for (const todo of todos) { + if (existingTitles.includes(todo.title)) continue; + await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, From f8b5c0421a8ce81be5c3aaf779e769b65394fd10 Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 16:46:51 -0300 Subject: [PATCH 6/7] (chore): Ambient configuration --- .vscode/settings.json | 6 ++++-- .vscode/tasks.json | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 .vscode/tasks.json diff --git a/.vscode/settings.json b/.vscode/settings.json index dbafcfb..2e771c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,7 @@ "cmd": "${workspaceFolder}/vendor/bin/mago format ${file}" } ] - } -} \ No newline at end of file + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.shellIntegration.enabled": true +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..73de7f0 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,31 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Composer Test", + "type": "shell", + "command": "composer test", + "presentation": { + "reveal": "always", + "panel": "new", + "group": "tests" + }, + "runOptions": { + "runOn": "folderOpen" + } + }, + { + "label": "MAGO Analyse", + "type": "shell", + "command": "mago analyse", + "presentation": { + "reveal": "always", + "panel": "new", + "group": "analysis" + }, + "runOptions": { + "runOn": "folderOpen" + } + } + ] +} \ No newline at end of file From 244702db42dd2e183aaf6da960a59d02febb29b7 Mon Sep 17 00:00:00 2001 From: valb-mig Date: Wed, 4 Mar 2026 18:00:12 -0300 Subject: [PATCH 7/7] (obsidian): Updating obsidian --- obsidian/.obsidian/workspace.json | 15 ++++++++------- obsidian/Design.md | 4 ++-- obsidian/Domain/Characters.md | 1 - 3 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 obsidian/Domain/Characters.md diff --git a/obsidian/.obsidian/workspace.json b/obsidian/.obsidian/workspace.json index 152251f..c78aaaa 100644 --- a/obsidian/.obsidian/workspace.json +++ b/obsidian/.obsidian/workspace.json @@ -76,7 +76,8 @@ } ], "direction": "horizontal", - "width": 233.5 + "width": 233.5, + "collapsed": true }, "right": { "id": "7ca2f4f0bbdfa382", @@ -184,15 +185,15 @@ }, "active": "ca2d8013c7331e8e", "lastOpenFiles": [ - "Process.md", - "Idea.md", - "Design.md", - "TODO.md", - "Excalidraw/Overall.md", - "Domain/Characters.md", "Domain/Dice.md", "Domain/Session.md", + "Design.md", + "Idea.md", + "Process.md", + "TODO.md", "Domain/World.md", + "Domain/Characters.md", + "Excalidraw/Overall.md", "Domain/NPC.md", "Excalidraw/Drawing 2026-03-02 14.34.45.excalidraw.md", "Sem título", diff --git a/obsidian/Design.md b/obsidian/Design.md index 0a30f61..fd74e95 100644 --- a/obsidian/Design.md +++ b/obsidian/Design.md @@ -1,8 +1,8 @@ # Purpose Hub of creative creation involving RPG, making easy to create histories and managing parties. ## Anchors +[[Session]] [[Dice]] [[World]] -[[Characters]] -[[NPC]] + diff --git a/obsidian/Domain/Characters.md b/obsidian/Domain/Characters.md deleted file mode 100644 index 21ef479..0000000 --- a/obsidian/Domain/Characters.md +++ /dev/null @@ -1 +0,0 @@ -## Attributess