Skip to content

refactor: user commands#155

Merged
Clintonrocha98 merged 34 commits into
3.xfrom
refactor/user-commands
Dec 23, 2025
Merged

refactor: user commands#155
Clintonrocha98 merged 34 commits into
3.xfrom
refactor/user-commands

Conversation

@Clintonrocha98
Copy link
Copy Markdown
Collaborator

@Clintonrocha98 Clintonrocha98 commented Dec 17, 2025

This pull request refactors and modernizes the user, provider, and character resolution flow across the Discord bot and related modules. The main change is the replacement of the old UserCharacterResolver approach with a more modular, action-based system that separates concerns for provider resolution, user linking, and character initialization. Additionally, new DTOs and actions are introduced to streamline context resolution, and error logging is improved for better debugging. Several files and tests related to the old approach are removed, and usages are updated accordingly.

Core architectural refactor:

  • Removed the legacy UserCharacterResolver and its DTO, along with associated tests, in favor of a new modular action-based system for resolving user, provider, and character relationships. [1] [2] [3]
  • Introduced new actions: ProviderResolver, LinkUserToProviderAction, CharacterInitializerAction, and ResolveUserContextAction, each handling a specific part of the user-provider-character resolution process. [1] [2] [3] [4]
  • Added a new DTO, ResolveUserProviderDTO, to standardize data transfer for user-provider resolution.

Refactoring usages across modules:

  • Updated WelcomeMember event, IntroductionCommand, and NewMessage action to use the new ResolveUserContextAction and related DTOs, replacing direct calls to the old resolver. [1] [2] [3] [4] [5]

User information management improvements:

  • Added InformationUserAction to handle upserting user information, and refactored IntroductionCommand to use it, improving data consistency and separation of concerns. [1] [2]

Error handling and logging:

  • Enhanced error logging in EditProfileCommand and IntroductionCommand for more informative debugging output. [1] [2]

Minor UX improvements:

  • Updated placeholder values in the introduction form for better clarity to users.

Summary by CodeRabbit

  • New Features

    • Unified user resolution powering onboarding, introductions, profile edits and message handling; automatic character creation on first resolve.
    • Richer welcome and introduction flows with improved presentation messaging and role assignment.
  • Bug Fixes

    • Improved error handling and logging with clearer failure messaging.
  • Configuration

    • Added environment/config entries for presentation channel and role.
  • Removed

    • Legacy resolver and old resolution pathway replaced by new service-based flow.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 17, 2025

📝 Walkthrough

Walkthrough

Removed the legacy UserCharacterResolver/ResolvedUserCharacter and related tests; introduced DTO-driven provider/user/character orchestration (ResolveUserProviderDTO, ProviderResolver, ResolveUserContextService, LinkUserToProviderAction, CharacterInitializerAction), new information/profile actions/DTOs, updated bot commands, message handling, controllers, config and .env placeholders.

Changes

Cohort / File(s) Summary
Removal: legacy resolver & DTO
app-modules/bot-discord/src/Actions/UserCharacterResolver.php, app-modules/bot-discord/src/DTO/ResolvedUserCharacter.php, app-modules/bot-discord/tests/Feature/Actions/UserCharacterResolverTest.php
Deleted legacy combined resolver, DTO and associated feature tests that handled creating/retrieving users, characters and provider links.
Provider DTO & Resolver
app-modules/provider/src/DTO/ResolveUserProviderDTO.php, app-modules/provider/src/Actions/ProviderResolver.php
Added ResolveUserProviderDTO and ProviderResolver that upserts Provider records (firstOrCreate) and captures username/email/avatar.
User context orchestration
app-modules/user/src/Services/ResolveUserContextService.php, app-modules/user/src/ValueObjects/UserContext.php
New service composes ProviderResolver, LinkUserToProviderAction and CharacterInitializerAction to return a UserContext (user, character, provider).
User linking & character init
app-modules/user/src/Actions/LinkUserToProviderAction.php, app-modules/character/src/Actions/CharacterInitializerAction.php
New actions: link provider to existing or newly-created User (UUID) and ensure Character exists (firstOrCreate).
User information upsert
app-modules/user/src/Actions/InformationUserAction.php, app-modules/user/src/DTO/UpsertInformationDTO.php
New action and DTO to upsert Information records (name, nickname, about, linkedin/github, birthdate).
Profile update refactor
app-modules/user/src/Actions/UpdateProfile.php, app-modules/user/src/Services/UpdateProfileService.php
UpdateProfile now uses constructor injection and delegates provider resolution + information persistence via ProviderResolver and InformationUserAction through UpdateProfileService.
Controllers & bot commands
app-modules/bot-discord/src/Events/WelcomeMember.php, app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php, app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php, app-modules/user/src/Http/Controllers/UsersController.php
Replaced direct UserCharacterResolver usage with ResolveUserContextService/UpdateProfileService; updated dependency types, DTO construction, error logging and welcome/introduction flows.
Message processing
app-modules/message/src/Actions/NewMessage.php
Switched message handling to ResolveUserContextService; refreshes character from returned context and updates experience accordingly.
Config & Env
app-modules/bot-discord/config/bot-discord.php, .env.example
Added presentation role config and new env placeholders HE4RT_PRESENTATIONS_CHANNEL_ID, HE4RT_AUTO_REPORT_CHANNEL_ID, HE4RT_PRESENTATION_ROLE_ID.

Sequence Diagram(s)

sequenceDiagram
    participant Discord as Discord / Client
    participant Service as ResolveUserContextService
    participant Provider as ProviderResolver
    participant Linker as LinkUserToProviderAction
    participant CharInit as CharacterInitializerAction
    participant DB as Database

    Note over Discord,Service: incoming operation (message / welcome / profile)
    Discord->>Service: handle(ResolveUserProviderDTO)
    Service->>Provider: handle(dto)
    Provider->>DB: firstOrCreate(provider, tenant_id, provider_id)
    DB-->>Provider: Provider
    Provider-->>Service: Provider

    Service->>Linker: handle(Provider)
    alt provider.model exists
        Linker->>DB: fetch User
        DB-->>Linker: User
    else new user
        Linker->>DB: create User (UUID)
        DB-->>Linker: User
        Linker->>DB: update Provider.model_id
    end
    Linker-->>Service: User

    Service->>CharInit: ensure(User, tenantId)
    CharInit->>DB: firstOrCreate(user_id, tenant_id)
    DB-->>CharInit: Character
    CharInit-->>Service: Character

    Service-->>Discord: UserContext(User, Character, Provider)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • danielhe4rt
  • gvieira18
  • RichardGL11

Poem

🐇 I hopped through code with eager cheer,
Old resolver gone — new paths appear.
Providers, users, characters align,
DTOs and services stitch the vine.
A tiny hop — clean flows near! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'refactor: user commands' is overly broad and vague. It refers to a real aspect of the change (some commands were refactored), but obscures the core architectural shift—replacing the entire UserCharacterResolver system with a modular action-based pattern involving provider resolution, user linking, and character initialization. Consider a more specific title like 'refactor: replace UserCharacterResolver with modular action-based user context resolution' to better convey the primary architectural change and scope of this large refactoring.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/user-commands

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (1)

166-170: Consider using structured logging format for consistency.

The error logging wraps the message in an array [$throwable->getMessage()], but other files in this PR (e.g., WelcomeMember.php) use a more structured format with named keys like ['exception' => $throwable]. Consider aligning for consistency and better log parsing.

-            $this->logger()->error('Error EditProfileCommand:', [$throwable->getMessage()]);
+            $this->logger()->error('Error EditProfileCommand:', [
+                'exception' => $throwable->getMessage(),
+                'provider_id' => $interaction->user->id ?? null,
+            ]);
app-modules/message/src/Actions/NewMessage.php (1)

32-36: Potentially unnecessary refresh() call.

ResolveUserContextAction calls CharacterInitializerAction::ensure(), which returns a fresh model from firstOrCreate. The immediate refresh() on line 34 may be redundant unless there's concurrent modification concern between the action call and this line.

If no concurrent updates are expected, consider removing the refresh:

             $userContext = resolve(ResolveUserContextAction::class)->handle($userDto);

-            $userContext->character->refresh();
-
             $characterEntity = CharacterEntity::make($userContext->character->toArray());
app-modules/user/src/ValueObjects/UserContext.php (1)

11-29: Well-structured value object.

The UserContext value object cleanly encapsulates the resolved user, character, and provider. Consider adding readonly to the class declaration for immutability, aligning with ResolveUserContextAction which is already declared as readonly class.

-final class UserContext
+final readonly class UserContext
 {
app-modules/user/src/Actions/LinkUserToProviderAction.php (1)

19-28: Consider wrapping user creation and provider update in a transaction.

If the $provider->update() fails after the user is created, you'll have an orphaned user record. Wrapping both operations in a database transaction ensures atomicity.

+use Illuminate\Support\Facades\DB;
+
 final class LinkUserToProviderAction
 {
     public function handle(Provider $provider): User
     {
         if ($provider->model instanceof User) {
             return $provider->model;
         }

-        $user = User::query()->create([
-            'id' => Uuid::uuid4()->toString(),
-            'username' => $provider->username,
-            'name' => $provider->username,
-            'is_donator' => false,
-        ]);
-
-        $provider->update([
-            'model_id' => $user->id,
-        ]);
-
-        return $user;
+        return DB::transaction(function () use ($provider) {
+            $user = User::query()->create([
+                'id' => Uuid::uuid4()->toString(),
+                'username' => $provider->username,
+                'name' => $provider->username,
+                'is_donator' => false,
+            ]);
+
+            $provider->update([
+                'model_id' => $user->id,
+            ]);
+
+            return $user;
+        });
     }
 }
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)

9-9: Consider marking the class as final for consistency.

Other DTOs in this PR (e.g., UpsertInformationDTO) are declared as final. For consistency and to prevent unintended inheritance of a data transfer object, consider adding the final modifier.

-class ResolveUserProviderDTO
+final class ResolveUserProviderDTO
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (1)

188-189: Consider logging the full exception for better debugging.

While the error message prefix is helpful for searchability, logging only the message loses the stack trace. Consider including the exception itself for debugging purposes.

         } catch (Throwable $throwable) {
-            $this->logger()->error('Error IntroductionCommand', [$throwable->getMessage()]);
+            $this->logger()->error('Error IntroductionCommand', [
+                'message' => $throwable->getMessage(),
+                'exception' => $throwable,
+            ]);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a780f5f and d09763f.

📒 Files selected for processing (16)
  • app-modules/bot-discord/src/Actions/UserCharacterResolver.php (0 hunks)
  • app-modules/bot-discord/src/DTO/ResolvedUserCharacter.php (0 hunks)
  • app-modules/bot-discord/src/Events/WelcomeMember.php (2 hunks)
  • app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (1 hunks)
  • app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (4 hunks)
  • app-modules/bot-discord/tests/Feature/Actions/UserCharacterResolverTest.php (0 hunks)
  • app-modules/character/src/Actions/CharacterInitializerAction.php (1 hunks)
  • app-modules/message/src/Actions/NewMessage.php (1 hunks)
  • app-modules/provider/src/Actions/ProviderResolver.php (1 hunks)
  • app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1 hunks)
  • app-modules/user/src/Actions/InformationUserAction.php (1 hunks)
  • app-modules/user/src/Actions/LinkUserToProviderAction.php (1 hunks)
  • app-modules/user/src/Actions/ResolveUserContextAction.php (1 hunks)
  • app-modules/user/src/Actions/UpdateProfile.php (1 hunks)
  • app-modules/user/src/DTO/UpsertInformationDTO.php (1 hunks)
  • app-modules/user/src/ValueObjects/UserContext.php (1 hunks)
💤 Files with no reviewable changes (3)
  • app-modules/bot-discord/src/DTO/ResolvedUserCharacter.php
  • app-modules/bot-discord/src/Actions/UserCharacterResolver.php
  • app-modules/bot-discord/tests/Feature/Actions/UserCharacterResolverTest.php
🧰 Additional context used
🧬 Code graph analysis (11)
app-modules/provider/src/Actions/ProviderResolver.php (2)
app-modules/provider/src/Models/Provider.php (1)
  • Provider (28-96)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/Actions/LinkUserToProviderAction.php (2)
app-modules/provider/src/Models/Provider.php (2)
  • Provider (28-96)
  • model (51-54)
app-modules/user/src/Entities/InformationEntity.php (1)
  • update (36-44)
app-modules/user/src/Actions/InformationUserAction.php (2)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Models/Information.php (1)
  • Information (13-43)
app-modules/user/src/ValueObjects/UserContext.php (2)
app-modules/character/src/Models/Character.php (1)
  • Character (28-128)
app-modules/provider/src/Models/Provider.php (1)
  • Provider (28-96)
app-modules/bot-discord/src/Events/WelcomeMember.php (3)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (2)
  • ResolveUserProviderDTO (9-33)
  • make (21-32)
app-modules/user/src/Actions/ResolveUserContextAction.php (1)
  • ResolveUserContextAction (12-28)
app-modules/bot-discord/src/Events/MessageReceivedEvent.php (1)
  • handle (27-56)
app-modules/character/src/Actions/CharacterInitializerAction.php (1)
app-modules/character/src/Models/Character.php (1)
  • Character (28-128)
app-modules/message/src/Actions/NewMessage.php (3)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (3)
  • ResolveUserProviderDTO (9-33)
  • __construct (11-19)
  • make (21-32)
app-modules/user/src/Actions/ResolveUserContextAction.php (1)
  • ResolveUserContextAction (12-28)
app-modules/character/src/Entities/CharacterEntity.php (1)
  • CharacterEntity (9-66)
app-modules/user/src/Actions/UpdateProfile.php (5)
app-modules/provider/src/Actions/ProviderResolver.php (1)
  • ProviderResolver (10-28)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/DTO/UpdateProfileDTO.php (2)
  • UpdateProfileDTO (9-49)
  • __construct (11-21)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Actions/InformationUserAction.php (1)
  • InformationUserAction (10-23)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
app-modules/provider/src/Models/Provider.php (1)
  • Provider (28-96)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (5)
app-modules/provider/src/Models/Provider.php (2)
  • Provider (28-96)
  • user (59-62)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/Actions/InformationUserAction.php (1)
  • InformationUserAction (10-23)
app-modules/user/src/Actions/ResolveUserContextAction.php (1)
  • ResolveUserContextAction (12-28)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Actions/ResolveUserContextAction.php (7)
app-modules/character/src/Models/Character.php (1)
  • Character (28-128)
app-modules/character/src/Actions/CharacterInitializerAction.php (2)
  • CharacterInitializerAction (10-21)
  • ensure (12-20)
app-modules/provider/src/Models/Provider.php (1)
  • Provider (28-96)
app-modules/provider/src/Actions/ProviderResolver.php (1)
  • ProviderResolver (10-28)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/ValueObjects/UserContext.php (1)
  • UserContext (11-30)
app-modules/user/src/Actions/LinkUserToProviderAction.php (1)
  • LinkUserToProviderAction (11-32)
🔇 Additional comments (8)
app-modules/user/src/Actions/InformationUserAction.php (1)

10-23: Clean action implementation.

The implementation correctly uses updateOrCreate for upserting user information. The field mapping aligns with the Information model's fillable fields.

app-modules/bot-discord/src/Events/WelcomeMember.php (1)

32-60: Welcome message sends even if user resolution fails.

The try-catch block (lines 32-48) catches resolution errors and logs them, but the welcome message (lines 54-60) executes regardless of success or failure. Verify this is the intended behavior - should new members still see the welcome message if their user record fails to persist?

If the welcome message should only be sent on successful resolution, consider:

         try {
             $userDto = ResolveUserProviderDTO::make([
                 'tenant_id' => $tenantProvider->tenant_id,
                 'provider' => $tenantProvider->provider,
                 'provider_id' => $member->user->id,
                 'model_type' => User::class,
                 'username' => $member->user->username,
                 'avatar' => $member->user->avatar,
             ]);

             resolve(ResolveUserContextAction::class)->handle($userDto);
         } catch (Throwable $throwable) {
             Log::error('Erro ao resolver usuário no evento WelcomeMember', [
                 'exception' => $throwable,
                 'member_id' => $member->user->id ?? null,
             ]);
+            return;
         }
app-modules/provider/src/Actions/ProviderResolver.php (1)

14-26: Profile attributes only set on creation, not updated.

firstOrCreate sets username, email, and avatar only when creating a new record. If a user changes their Discord username or avatar, subsequent calls won't update these fields in the provider record.

If updates are needed, consider using updateOrCreate:

-        return Provider::query()->firstOrCreate(
+        return Provider::query()->updateOrCreate(
             [
                 'provider' => $dto->provider,
                 'tenant_id' => $dto->tenantId,
                 'provider_id' => $dto->providerId,
                 'model_type' => $dto->modelType,
             ],
             [
                 'username' => $dto->username,
                 'email' => $dto->email,
                 'avatar' => $dto->avatar,
             ]
         );
app-modules/character/src/Actions/CharacterInitializerAction.php (1)

10-21: Clean character initialization.

The ensure method appropriately uses firstOrCreate with the composite key [user_id, tenant_id], relying on model/database defaults for reputation, experience, and daily_bonus_claimed_at.

app-modules/user/src/DTO/UpsertInformationDTO.php (1)

9-32: LGTM!

Clean DTO implementation with proper separation between camelCase properties and snake_case array keys. The nullable optional fields and factory method pattern are well-implemented.

app-modules/user/src/Actions/ResolveUserContextAction.php (1)

12-27: LGTM!

Well-structured orchestration action with clear separation of concerns. The readonly class with constructor injection follows best practices, and the composition of ProviderResolver → LinkUserToProviderAction → CharacterInitializerAction creates a clean resolution pipeline.

app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (2)

141-150: Good refactoring to the new action-based pattern.

The transition from the old resolver to the new ResolveUserProviderDTO and ResolveUserContextAction flow is clean and aligns with the modular architecture.


168-177: Verify the display intent for "Nome/Nickname" field.

The "Nome/Nickname" field at line 171 only displays the nickname, even though users enter both name and nickname in the form. Consider whether this should display the name, the nickname, or both (e.g., $userInformation->name . ' (' . $userInformation->nickname . ')').

Comment thread app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php
Comment thread app-modules/user/src/Services/UpdateProfileService.php
Comment thread app-modules/bot-discord/src/Events/WelcomeMember.php
Comment thread app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php
Copy link
Copy Markdown
Contributor

@1pride 1pride left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need a few adjusts as explained on the files.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
app-modules/user/src/Services/UpdateProfileService.php (1)

29-32: Potential null access on $provider->user.

The previous review's concern remains valid: ProviderResolver::handle() may create a provider without setting model_id, causing $provider->user to return null on Line 32. This will fail when building UpsertInformationDTO.

Consider calling LinkUserToProviderAction (as done in ResolveUserContextService) to ensure the user is linked before accessing $provider->user:

🔎 Proposed fix to ensure user exists
+use He4rt\User\Actions\LinkUserToProviderAction;
+
 final readonly class UpdateProfileService
 {
     public function __construct(
         private ProviderResolver $providerResolver,
+        private LinkUserToProviderAction $linkUserToProviderAction,
         private InformationUserAction $informationUserAction,
     ) {}

     public function handle(UpdateProfileDTO $profileDTO): void
     {
         $providerDto = ResolveUserProviderDTO::make([
             'provider_id' => $profileDTO->providerId,
             'provider' => $profileDTO->provider,
             'tenant_id' => $profileDTO->tenantId,
             'model_type' => User::class,
         ]);
         $provider = $this->providerResolver->handle($providerDto);
+        $user = $this->linkUserToProviderAction->handle($provider);

         $informationDto = UpsertInformationDTO::make([
-            'user' => $provider->user,
+            'user' => $user,
             'name' => $profileDTO->name,
             'nickname' => $profileDTO->nickname,
             'linkedin_url' => $profileDTO->linkedinUrl,
             'github_url' => $profileDTO->githubUrl,
             'birthdate' => $profileDTO->birthdate,
             'about' => $profileDTO->about,
         ]);

         $this->informationUserAction->handle($informationDto);
     }
 }
🧹 Nitpick comments (2)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (2)

120-121: Remove redundant null coalescing operators.

The ?? null operators on these lines are redundant. The $components->get() method already returns null when the component doesn't exist or has no value, making the fallback unnecessary.

🔎 Proposed simplification
-                'linkedin_url' => $components->get('custom_id', 'linkedin_url')->value ?? null,
-                'github_url' => $components->get('custom_id', 'github_url')->value ?? null,
+                'linkedin_url' => $components->get('custom_id', 'linkedin_url')?->value,
+                'github_url' => $components->get('custom_id', 'github_url')?->value,

127-137: LGTM! Clear success feedback to user.

The success message properly acknowledges the user's submission and provides helpful context.

Consider extracting the color value '4b0080' to a class constant for reusability, as it's used twice (lines 133 and 162).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d09763f and 13019da.

📒 Files selected for processing (9)
  • .env.example (1 hunks)
  • app-modules/bot-discord/src/Events/WelcomeMember.php (1 hunks)
  • app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (3 hunks)
  • app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (2 hunks)
  • app-modules/message/src/Actions/NewMessage.php (1 hunks)
  • app-modules/user/src/Http/Controllers/UsersController.php (2 hunks)
  • app-modules/user/src/Services/ResolveUserContextService.php (1 hunks)
  • app-modules/user/src/Services/UpdateProfileService.php (1 hunks)
  • config/he4rt.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
app-modules/user/src/Http/Controllers/UsersController.php (1)
app-modules/user/src/Services/UpdateProfileService.php (1)
  • UpdateProfileService (14-44)
app-modules/user/src/Services/ResolveUserContextService.php (7)
app-modules/character/src/Models/Character.php (1)
  • Character (28-128)
app-modules/character/src/Actions/CharacterInitializerAction.php (2)
  • CharacterInitializerAction (10-21)
  • ensure (12-20)
app-modules/provider/src/Models/Provider.php (1)
  • Provider (28-96)
app-modules/provider/src/Actions/ProviderResolver.php (1)
  • ProviderResolver (10-28)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/Actions/LinkUserToProviderAction.php (1)
  • LinkUserToProviderAction (11-32)
app-modules/user/src/ValueObjects/UserContext.php (1)
  • UserContext (11-30)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (4)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/Actions/InformationUserAction.php (1)
  • InformationUserAction (10-23)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Services/ResolveUserContextService.php (1)
  • ResolveUserContextService (13-29)
app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (1)
app-modules/user/src/Services/UpdateProfileService.php (1)
  • UpdateProfileService (14-44)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 82-82: [UnorderedKey] The GUILD_RULE_ID key should go before the WELCOME_CHANNEL_ID key

(UnorderedKey)

🪛 PHPMD (2.15.0)
app-modules/bot-discord/src/Events/WelcomeMember.php

23-23: Avoid unused parameters such as '$discord'. (undefined)

(UnusedFormalParameter)

🔇 Additional comments (17)
config/he4rt.php (1)

22-23: LGTM! Configuration entries added correctly.

The new welcome_channel and guild_rule_id configuration entries are well-structured with sensible defaults, allowing the system to fall back gracefully if environment variables are not set.

.env.example (1)

81-82: LGTM! Environment placeholders added.

The new environment variable placeholders align with the configuration updates in config/he4rt.php.

app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (2)

11-11: LGTM! Service migration completed correctly.

The migration from UpdateProfile to UpdateProfileService is correctly implemented, maintaining compatibility with the existing DTO construction flow.

Also applies to: 142-142


167-167: LGTM! Improved error logging.

The error logging now uses a structured format with a clear prefix and context array, which will improve debugging and log aggregation.

app-modules/message/src/Actions/NewMessage.php (2)

24-47: LGTM! User resolution refactored to DTO-driven service.

The migration from the legacy resolver to the new ResolveUserContextService is well-executed. The DTO construction includes all required fields, and the service ensures proper provider, user, and character initialization. The character refresh before experience updates ensures data consistency.


49-56: LGTM! Comprehensive error logging added.

The error handler now logs all relevant context (provider_id, tenant_id, error message, and stack trace), which will significantly aid in debugging message processing failures.

app-modules/user/src/Services/ResolveUserContextService.php (1)

1-29: LGTM! Well-designed orchestration service.

The ResolveUserContextService provides clean separation of concerns by orchestrating three discrete actions (provider resolution, user linking, and character initialization) in a logical sequence. Each action handles entity creation when necessary, ensuring the returned UserContext contains fully initialized entities.

app-modules/bot-discord/src/Events/WelcomeMember.php (3)

25-25: LGTM! Channel configuration externalized.

Replacing the hardcoded channel ID with config('he4rt.channels.welcome_channel') improves configurability and addresses the previous concern about environment-specific values.


32-62: LGTM! Robust error handling for user resolution.

The try-catch block around user context resolution provides comprehensive error logging with all relevant context (tenant_id, provider, provider_id, exception). The fallback welcome message appropriately informs the user about the issue while directing them to contact moderation.


64-77: LGTM! Clear and actionable welcome message.

The success path sends a well-structured welcome message that guides new members to use the /apresentar command, providing clear next steps for onboarding.

app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (7)

56-56: LGTM! Improved placeholder examples.

The updated placeholders ('Fulano de Tal', 'Fulano123') are more culturally appropriate and provide clearer examples for Portuguese-speaking users.

Also applies to: 63-63


104-113: LGTM! User context resolution implemented correctly.

The flow properly constructs the ResolveUserProviderDTO and resolves the user context through the ResolveUserContextService, following the new modular architecture.


125-125: LGTM! Persistence follows the new architecture.

The use of InformationUserAction aligns with the refactored action-based design and properly captures the result for subsequent operations.


176-176: LGTM! Enhanced error logging.

Adding the context string 'Error IntroductionCommand' improves error traceability and debugging.


38-48: Verify config key exists and consider renaming for clarity.

The pre-check logic correctly prevents duplicate introductions. However, config('he4rt.channels.guild_rule_id') uses a confusing namespace—'channels' typically suggests channel IDs, not role IDs.

Please verify that this config key exists and returns the correct role ID. Consider renaming to something like config('he4rt.roles.presented_role_id') for clarity.

#!/bin/bash
# Description: Verify the config key exists and check its usage context

# Search for the config key definition
rg -nP "guild_rule_id" --type=php -C3

# Search for other role-related config keys to understand the naming pattern
rg -nP "config\(['\"]he4rt\.(roles|channels)" --type=php -C2

139-163: The welcome channel is properly configured with a default value in config/he4rt.php, and the ->send() operation is already protected by a try-catch block that logs errors. No changes needed.

Likely an incorrect or invalid review comment.


165-173: Ensure the bot has MANAGE_ROLES permission and the guild_rule_id role exists.

The role assignment implementation is correct. The code properly collects existing roles, adds the guild_rule_id, and calls setRoles() with the complete array. The user is checked for the role beforehand (line 39) to avoid redundant assignments. However, setRoles() will fail silently if the bot lacks MANAGE_ROLES permission. Verify:

  1. The bot has MANAGE_ROLES permission in the guild
  2. The configured guild_rule_id (546150872397119491 by default) exists as a valid role

Comment thread app-modules/user/src/Http/Controllers/UsersController.php
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
.env.example (1)

81-82: Consider adding comments to document the new environment variables.

The new WELCOME_CHANNEL_ID and PRESENTATION_ROLE_ID variables lack explanatory comments. Adding brief descriptions would help developers understand their purpose and expected values.

💡 Suggested documentation
 DISCORD_TOKEN=
+
+# Discord welcome flow configuration
+# WELCOME_CHANNEL_ID: Channel ID where welcome messages are sent
 WELCOME_CHANNEL_ID=
+# PRESENTATION_ROLE_ID: Role ID assigned to users after introduction
 PRESENTATION_ROLE_ID=
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (1)

38-38: Fix typo in property name.

The property is named welcomeChanelId but should be welcomeChannelId (missing 'n' in "Channel").

🔎 Proposed fix
-    private readonly string $welcomeChanelId;
+    private readonly string $welcomeChannelId;

Also update line 43:

-        $this->welcomeChanelId = config('he4rt.channels.welcome_channel_id');
+        $this->welcomeChannelId = config('he4rt.channels.welcome_channel_id');

And line 174:

-                ->send($this->welcomeChanelId);
+                ->send($this->welcomeChannelId);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13019da and e3fface.

📒 Files selected for processing (3)
  • .env.example (1 hunks)
  • app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (2 hunks)
  • config/he4rt.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (4)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/Actions/InformationUserAction.php (1)
  • InformationUserAction (10-23)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Services/ResolveUserContextService.php (1)
  • ResolveUserContextService (13-29)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 82-82: [UnorderedKey] The PRESENTATION_ROLE_ID key should go before the WELCOME_CHANNEL_ID key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Perform Pest Tests / Run
🔇 Additional comments (6)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (6)

48-58: LGTM!

The pre-check correctly prevents duplicate presentations by validating the role before showing the modal, improving user experience by avoiding unnecessary form fills. This addresses the past review feedback about moving validations to the handle method.


114-123: LGTM!

The user resolution flow correctly uses the new modular architecture with ResolveUserProviderDTO and ResolveUserContextService, replacing the legacy UserCharacterResolver approach as intended by the PR objectives.


132-132: LGTM!

Setting birthdate to null correctly addresses the past review comment about the field being referenced but not present in the form. The UpsertInformationDTO accepts nullable birthdate, so this is handled correctly.


135-174: LGTM!

The information persistence flow correctly uses InformationUserAction, and the success messages properly utilize the persisted user information fields (name, nickname, about, GitHub, LinkedIn) in the welcome embed. This addresses the past review feedback about using gathered information in the embed sent to the welcome channel.


176-184: Verify that role assignment persists correctly.

The role assignment logic correctly uses setRoles() (addressing past feedback about addRole() not working). However, ensure that setRoles() successfully persists the role change to Discord's API, as some DiscordPHP operations are asynchronous and may fail silently.

You may want to verify this works as expected in testing, or consider adding explicit error handling or confirmation for the role assignment operation if the Discord library provides callbacks or promises for async operations.


186-193: LGTM!

Error handling is properly implemented with enhanced logging context ('Error IntroductionCommand') for easier debugging, while maintaining a user-friendly error message. The try-catch block appropriately handles exceptions from provider resolution, user context resolution, information persistence, and role assignment operations.

Comment thread app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php Outdated
Comment thread config/he4rt.php Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (1)

132-132: Birthdate field is set to null but not present in the form.

Line 132 sets birthdate to null, but there's no birthdate TextInput in the modal (lines 60-96). This is dead code. Either add a birthdate field to the form or remove this parameter from the DTO.

🧹 Nitpick comments (1)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (1)

125-135: Consider validating URL formats for optional fields.

The LinkedIn and GitHub URL inputs are accepted without format validation. While the modal enforces length constraints, malformed URLs could be persisted.

Example validation approach
$linkedinUrl = $components->get('custom_id', 'linkedin_url')?->value;
$githubUrl = $components->get('custom_id', 'github_url')?->value;

if ($linkedinUrl && !filter_var($linkedinUrl, FILTER_VALIDATE_URL)) {
    throw new \InvalidArgumentException('Invalid LinkedIn URL format');
}

if ($githubUrl && !filter_var($githubUrl, FILTER_VALIDATE_URL)) {
    throw new \InvalidArgumentException('Invalid GitHub URL format');
}

$informationDto = UpsertInformationDTO::make([
    'user' => $userContext->user,
    'name' => $components->get('custom_id', 'name')->value,
    'nickname' => $components->get('custom_id', 'nickname')->value,
    'about' => $components->get('custom_id', 'about')->value,
    'linkedin_url' => $linkedinUrl,
    'github_url' => $githubUrl,
    'birthdate' => null,
]);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e3fface and db8e86c.

📒 Files selected for processing (1)
  • app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (6)
app-modules/provider/src/Models/Provider.php (2)
  • Provider (28-96)
  • user (59-62)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/tenant/src/Models/Tenant.php (1)
  • Tenant (23-104)
app-modules/user/src/Actions/InformationUserAction.php (1)
  • InformationUserAction (10-23)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Services/ResolveUserContextService.php (1)
  • ResolveUserContextService (13-29)
🔇 Additional comments (8)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (8)

11-17: Imports align with the new modular architecture.

The new imports (ResolveUserProviderDTO, InformationUserAction, UpsertInformationDTO, User, ResolveUserContextService) are correctly added and used throughout the refactored persistData method.


48-58: Early validation prevents duplicate presentations.

The role check correctly prevents users from submitting the form multiple times by validating membership before showing the modal. This addresses the previous feedback about moving validations to the handle method.


60-96: Modal form is well-structured.

The form fields have appropriate validation constraints (min/max length, required/optional flags) and updated placeholders that provide clear guidance to users.


114-123: User context resolution follows the new modular pattern.

The code correctly constructs ResolveUserProviderDTO with Discord interaction data and resolves the user context using the new ResolveUserContextService, aligning with the PR's architectural refactor.


130-131: Null-safe operators correctly handle optional fields.

The optional fields linkedin_url and github_url now use the null-safe operator (?->value), which properly prevents null pointer exceptions when users leave these fields empty.


176-184: Role assignment logic is correctly implemented.

The code collects existing role IDs, appends the presentation role ID, and applies them using setRoles(). This approach correctly updates the member's roles without losing existing assignments.


186-193: Enhanced error logging improves debugging.

The error handler now logs with the context string "Error IntroductionCommand" alongside the exception message, making it easier to trace issues in production logs.


40-44: No action needed. The config values presentation_role_id and welcome_channel_id are properly defined in config/he4rt.php with default Discord IDs. They cannot be missing or null at runtime.

Likely an incorrect or invalid review comment.

Comment thread app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (1)

167-167: Improve error logging format and context.

The current logging format passes an indexed array [$throwable->getMessage()] as context, which is not idiomatic. Consider these improvements:

  1. Use proper context keys for better log readability
  2. Include the full exception object to capture stack traces
🔎 Recommended logging format
-            $this->logger()->error('Error EditProfileCommand:', [$throwable->getMessage()]);
+            $this->logger()->error('Error EditProfileCommand', [
+                'error' => $throwable->getMessage(),
+                'exception' => $throwable,
+            ]);

This provides structured context with the exception object, enabling better debugging with full stack traces in your logs.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db8e86c and 52d4b17.

📒 Files selected for processing (1)
  • app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (1)
app-modules/user/src/Services/UpdateProfileService.php (1)
  • UpdateProfileService (14-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Perform Pest Tests / Run
🔇 Additional comments (2)
app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php (2)

11-11: LGTM: Service import updated correctly.

The import change from UpdateProfile to UpdateProfileService aligns with the refactoring described in the PR objectives and is used consistently at line 142.


142-142: LGTM: Service resolution updated correctly.

The service resolution change to UpdateProfileService::class is consistent with the import and follows Laravel's dependency injection pattern.

Comment thread app-modules/bot-discord/src/SlashCommands/EditProfileCommand.php
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (3)

176-184: Role assignment may need promise handling.

The setRoles() method in Discord.php typically returns a Promise. If this promise is not handled, any errors during role assignment will be silently swallowed. Consider handling the promise or using addRole() for a single role addition.

🔎 Suggested refactor using addRole
-            $actualRoles = [];
-
-            foreach ($interaction->member->roles as $role) {
-                $actualRoles[] = $role->id;
-            }
-
-            $actualRoles[] = $this->roleId;
-
-            $interaction->member->setRoles($actualRoles);
+            $interaction->member->addRole($this->roleId)->done(
+                null,
+                fn ($error) => $this->logger()->error('Failed to add role', ['error' => $error->getMessage()])
+            );

186-188: Enhance error logging with more context.

The error log only includes the message. For better debugging, consider including the full exception and contextual data, similar to the pattern used in WelcomeMember.php.

🔎 Suggested improvement
         } catch (Throwable $throwable) {
-            $this->logger()->error('Error IntroductionCommand', [$throwable->getMessage()]);
+            $this->logger()->error('Error IntroductionCommand', [
+                'user_id' => $interaction->user->id ?? null,
+                'guild_id' => $interaction->guild_id ?? null,
+                'exception' => $throwable->getMessage(),
+                'trace' => $throwable->getTraceAsString(),
+            ]);

143-143: Use hex string format for consistency with other Discord embeds.

The color format (string) hexdec('4b0080') produces a decimal string and is valid in Laracord, but other Discord embeds in the codebase (EditProfileCommand, ProfileCommand) use hex strings like '800080' instead. Change to ->color('800080') to match the pattern.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52d4b17 and 7ec10de.

📒 Files selected for processing (4)
  • .env.example
  • app-modules/bot-discord/config/bot-discord.php
  • app-modules/bot-discord/src/Events/WelcomeMember.php
  • app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • .env.example
🧰 Additional context used
🧬 Code graph analysis (2)
app-modules/bot-discord/src/Events/WelcomeMember.php (5)
app-modules/provider/src/Models/Provider.php (2)
  • Provider (28-96)
  • user (59-62)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (2)
  • ResolveUserProviderDTO (9-33)
  • make (21-32)
app-modules/tenant/src/Models/Tenant.php (1)
  • Tenant (23-104)
app-modules/user/src/Services/ResolveUserContextService.php (1)
  • ResolveUserContextService (13-29)
app-modules/bot-discord/src/Events/MessageReceivedEvent.php (1)
  • handle (27-56)
app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (4)
app-modules/provider/src/DTO/ResolveUserProviderDTO.php (1)
  • ResolveUserProviderDTO (9-33)
app-modules/user/src/Actions/InformationUserAction.php (1)
  • InformationUserAction (10-23)
app-modules/user/src/DTO/UpsertInformationDTO.php (1)
  • UpsertInformationDTO (9-33)
app-modules/user/src/Services/ResolveUserContextService.php (1)
  • ResolveUserContextService (13-29)
🪛 PHPMD (2.15.0)
app-modules/bot-discord/src/Events/WelcomeMember.php

23-23: Avoid unused parameters such as '$discord'. (undefined)

(UnusedFormalParameter)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Perform Pest Tests / Run
🔇 Additional comments (9)
app-modules/bot-discord/config/bot-discord.php (1)

9-11: LGTM!

The new roles.presentation config follows the existing pattern and properly uses env() with a fallback default. This aligns well with the refactored command flow that now references config values instead of hardcoded IDs.

app-modules/bot-discord/src/Events/WelcomeMember.php (4)

32-42: DTO construction and service usage looks correct.

The DTO is properly constructed with all required fields from the ResolveUserProviderDTO definition. The service call is wrapped appropriately in try-catch with good contextual logging.


43-62: Error handling is well-structured.

The catch block provides good observability with contextual logging and gracefully informs the user about the failure. The defensive null-coalescing on tenant_id and provider is unnecessary since $tenantProvider is guaranteed to exist at this point (from firstOrFail()), but it's harmless.


64-77: Clean success path implementation.

The welcome message is well-formatted and uses the config-driven channel ID. The embed provides clear instructions for new members.


23-23: Unused $discord parameter is likely required by parent signature.

The static analysis flags this as unused, but this parameter is typically required by the Laracord Event class's method signature. Suppressing this warning with a docblock annotation (e.g., @SuppressWarnings(PHPMD.UnusedFormalParameter)) or using @phpstan-ignore-next-line would silence the false positive if desired.

app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php (4)

48-58: Role pre-check logic is correct.

The early validation prevents users from presenting multiple times by checking for the configured role. This addresses the concern from past reviews about moving validation to the handle method.


60-102: Modal definition is well-structured.

The form fields have appropriate validation constraints (min/max lengths, required flags). The birthdate field was intentionally removed with null passed to the DTO, addressing the past review comment.


125-133: DTO construction is correct with birthdate set to null.

The birthdate field is explicitly set to null since there's no corresponding input in the modal. This correctly addresses the past review comment about the missing birthdate field. The null-safe operators on optional fields (linkedin_url, github_url) are properly applied.


40-44: Parent constructor call may be necessary depending on Laracord's implementation.

While no other commands in the codebase define custom constructors or call parent::__construct(), this alone doesn't confirm it's unnecessary. The SlashCommand parent class from the Laracord framework may require initialization that isn't obvious from examining the local codebase. Verify the Laracord framework documentation or source code to determine if parent::__construct() needs to be invoked for proper initialization.

Copy link
Copy Markdown
Contributor

@1pride 1pride left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FELIZ 2006

Comment thread app-modules/bot-discord/src/Events/WelcomeMember.php
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.env.example (1)

81-83: Reorder environment variables alphabetically.

The dotenv-linter tool flags that HE4RT_AUTO_REPORT_CHANNEL_ID should be ordered before HE4RT_PRESENTATIONS_CHANNEL_ID. While this doesn't affect functionality, maintaining alphabetical order improves consistency and readability.

🔎 Proposed reordering
 DISCORD_TOKEN=
-HE4RT_PRESENTATIONS_CHANNEL_ID=
 HE4RT_AUTO_REPORT_CHANNEL_ID=
+HE4RT_PRESENTATIONS_CHANNEL_ID=
 HE4RT_PRESENTATION_ROLE_ID=
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a15e478 and 3788e82.

📒 Files selected for processing (1)
  • .env.example
🧰 Additional context used
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 82-82: [UnorderedKey] The HE4RT_AUTO_REPORT_CHANNEL_ID key should go before the HE4RT_PRESENTATIONS_CHANNEL_ID key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Perform Pest Tests / Run

@Clintonrocha98 Clintonrocha98 merged commit e8e63ae into 3.x Dec 23, 2025
6 checks passed
@Clintonrocha98 Clintonrocha98 deleted the refactor/user-commands branch December 23, 2025 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants