Skip to content

refactor(integrations): split monolithic module into separate discord and twitch modules#179

Merged
danielhe4rt merged 1 commit into4.xfrom
feat/integrations
Mar 17, 2026
Merged

refactor(integrations): split monolithic module into separate discord and twitch modules#179
danielhe4rt merged 1 commit into4.xfrom
feat/integrations

Conversation

@danielhe4rt
Copy link
Contributor

@danielhe4rt danielhe4rt commented Mar 17, 2026

Summary

  • Split the monolithic integrations module into two dedicated modules: integration-discord and integration-twitch
  • Each module now has its own namespace, service provider, and composer configuration
  • Updated IdentityProvider enum imports to reference new module namespaces
  • Removed the old monolithic integrations module

Changes

  • integration-discord: Contains Discord OAuth implementation (client, DTOs, user handling)
  • integration-twitch: Contains Twitch OAuth and subscribers functionality (clients, DTOs, contracts)
  • Updated root composer.json to require individual integration modules
  • Added dedicated service providers for each module with appropriate bindings

Testing

  • All 152 tests pass ✓ (8 skipped)

Summary by CodeRabbit

  • Refactor
    • Reorganized Discord and Twitch integrations into separate, independent packages.
    • Updated project dependencies to reflect the new module structure.

… and twitch modules

- Create separate app-modules/integration-discord and app-modules/integration-twitch modules
- Move Discord OAuth implementation to dedicated module with proper namespace
- Move Twitch OAuth and subscribers implementation to dedicated module
- Update IdentityProvider enum imports to reference new module namespaces
- Remove monolithic integrations module in favor of modular structure
- Update composer.json to require individual integration modules
- Add service providers for each integration module with appropriate bindings
@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

📝 Walkthrough

Walkthrough

This pull request refactors the integration modules from a monolithic structure to separate, modular components. The previous He4rt\Integrations namespace is split into two distinct modules: He4rt\IntegrationDiscord for Discord integration and He4rt\IntegrationTwitch for Twitch integration. Each new module includes its own composer.json configuration with PSR-4 autoloading and Laravel service provider registration. The original monolithic integrations module, including its service provider and PHPStan configurations, is removed. All namespace declarations and import statements across related files are updated to reflect the new module structure. The root composer.json dependency is updated to reference the new integration modules instead of the previous monolithic package.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: splitting a monolithic integrations module into separate discord and twitch modules, which aligns perfectly with the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can suggest fixes for GitHub Check annotations.

Configure the reviews.tools.github-checks setting to adjust the time to wait for GitHub Checks to complete.

Copy link

@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.

🧹 Nitpick comments (4)
app-modules/integration-discord/composer.json (1)

3-3: Consider adding a non-empty package description.

Line 3 currently sets "description": ""; adding a short description improves package metadata quality and discoverability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app-modules/integration-discord/composer.json` at line 3, The package
metadata has an empty description field ("description": "") in composer.json;
update the "description" value to a concise non-empty string that summarizes the
package (e.g., one short sentence describing the Discord integration), ensuring
the key remains "description" and the string is properly quoted in
composer.json.
app-modules/integration-discord/src/Providers/IntegrationDiscordServiceProvider.php (1)

11-13: Wire Discord client in the provider (or remove the empty scaffold).

register() and boot() are both empty, so this provider currently adds no container behavior. Consider binding DiscordOAuthClient here for consistency with the Twitch module wiring and easier DI testing.

Suggested refactor
 use Illuminate\Support\ServiceProvider;
+use He4rt\IntegrationDiscord\OAuth\DiscordOAuthClient;

 class IntegrationDiscordServiceProvider extends ServiceProvider
 {
-    public function register(): void {}
+    public function register(): void
+    {
+        $this->app->singleton(DiscordOAuthClient::class);
+    }

     public function boot(): void {}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app-modules/integration-discord/src/Providers/IntegrationDiscordServiceProvider.php`
around lines 11 - 13, The IntegrationDiscordServiceProvider currently has empty
register() and boot() methods; either remove the unused provider or wire the
Discord client into the container: in
IntegrationDiscordServiceProvider::register(), bind or singleton the
DiscordOAuthClient (the same way Twitch wiring does) so consumers can type-hint
DiscordOAuthClient for DI and tests can swap a mock; keep boot() only if you
need runtime setup (otherwise leave it empty or remove it) and ensure the
binding references the concrete class name DiscordOAuthClient and any required
factory/config values.
app-modules/identity/src/ExternalIdentity/Enums/IdentityProvider.php (1)

14-15: Prefer contract-based resolution for both providers.

Line 14 imports a concrete DiscordOAuthClient while Line 15 uses a Twitch contract. Consider introducing/resolving a Discord contract too, so IdentityProvider depends only on abstractions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app-modules/identity/src/ExternalIdentity/Enums/IdentityProvider.php` around
lines 14 - 15, The IdentityProvider currently imports and depends on the
concrete DiscordOAuthClient while using the TwitchOAuthService contract; change
IdentityProvider to depend on an abstraction for Discord as well: introduce or
use a DiscordOAuthService interface (nameable as DiscordOAuthService) and
replace the concrete import/typing of DiscordOAuthClient in IdentityProvider
with that interface, update any constructor/type hints to the interface, and
ensure the DI container is bound to resolve DiscordOAuthClient as the
implementation for DiscordOAuthService so both providers are resolved via
contracts.
app-modules/integration-twitch/composer.json (1)

8-15: Move test namespace to autoload-dev to avoid loading test classes in production.

The Tests namespace is currently in the main autoload section, which means test classes will be autoloaded in production environments. This increases the autoloader size unnecessarily and could expose test code.

♻️ Proposed fix
     "autoload": {
         "psr-4": {
             "He4rt\\IntegrationTwitch\\": "src/",
-            "He4rt\\IntegrationTwitch\\Tests\\": "tests/",
             "He4rt\\IntegrationTwitch\\Database\\Factories\\": "database/factories/",
             "He4rt\\IntegrationTwitch\\Database\\Seeders\\": "database/seeders/"
         }
-    },
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "He4rt\\IntegrationTwitch\\Tests\\": "tests/"
+        }
+    },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app-modules/integration-twitch/composer.json` around lines 8 - 15, The
composer.json currently lists the test namespace under "autoload" which causes
test classes (He4rt\\IntegrationTwitch\\Tests\\) to be loaded in production;
move the "He4rt\\IntegrationTwitch\\Tests\\" entry from the "autoload" ->
"psr-4" block into an "autoload-dev" -> "psr-4" block so test classes are only
autoloaded in development, leaving the other entries
(He4rt\\IntegrationTwitch\\, Database\\Factories\\, Database\\Seeders\\)
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app-modules/identity/src/ExternalIdentity/Enums/IdentityProvider.php`:
- Around line 14-15: The IdentityProvider currently imports and depends on the
concrete DiscordOAuthClient while using the TwitchOAuthService contract; change
IdentityProvider to depend on an abstraction for Discord as well: introduce or
use a DiscordOAuthService interface (nameable as DiscordOAuthService) and
replace the concrete import/typing of DiscordOAuthClient in IdentityProvider
with that interface, update any constructor/type hints to the interface, and
ensure the DI container is bound to resolve DiscordOAuthClient as the
implementation for DiscordOAuthService so both providers are resolved via
contracts.

In `@app-modules/integration-discord/composer.json`:
- Line 3: The package metadata has an empty description field ("description":
"") in composer.json; update the "description" value to a concise non-empty
string that summarizes the package (e.g., one short sentence describing the
Discord integration), ensuring the key remains "description" and the string is
properly quoted in composer.json.

In
`@app-modules/integration-discord/src/Providers/IntegrationDiscordServiceProvider.php`:
- Around line 11-13: The IntegrationDiscordServiceProvider currently has empty
register() and boot() methods; either remove the unused provider or wire the
Discord client into the container: in
IntegrationDiscordServiceProvider::register(), bind or singleton the
DiscordOAuthClient (the same way Twitch wiring does) so consumers can type-hint
DiscordOAuthClient for DI and tests can swap a mock; keep boot() only if you
need runtime setup (otherwise leave it empty or remove it) and ensure the
binding references the concrete class name DiscordOAuthClient and any required
factory/config values.

In `@app-modules/integration-twitch/composer.json`:
- Around line 8-15: The composer.json currently lists the test namespace under
"autoload" which causes test classes (He4rt\\IntegrationTwitch\\Tests\\) to be
loaded in production; move the "He4rt\\IntegrationTwitch\\Tests\\" entry from
the "autoload" -> "psr-4" block into an "autoload-dev" -> "psr-4" block so test
classes are only autoloaded in development, leaving the other entries
(He4rt\\IntegrationTwitch\\, Database\\Factories\\, Database\\Seeders\\)
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7063b63f-af9e-4a0c-923d-206428c45b5c

📥 Commits

Reviewing files that changed from the base of the PR and between a1234c5 and 7d5f0b8.

⛔ Files ignored due to path filters (1)
  • composer.lock is excluded by !**/*.lock
📒 Files selected for processing (30)
  • app-modules/identity/src/ExternalIdentity/Enums/IdentityProvider.php
  • app-modules/integration-discord/composer.json
  • app-modules/integration-discord/database/factories/.gitkeep
  • app-modules/integration-discord/database/migrations/.gitkeep
  • app-modules/integration-discord/database/seeders/.gitkeep
  • app-modules/integration-discord/src/OAuth/DiscordOAuthAccessDTO.php
  • app-modules/integration-discord/src/OAuth/DiscordOAuthClient.php
  • app-modules/integration-discord/src/OAuth/DiscordOAuthUser.php
  • app-modules/integration-discord/src/Providers/IntegrationDiscordServiceProvider.php
  • app-modules/integration-twitch/composer.json
  • app-modules/integration-twitch/database/factories/.gitkeep
  • app-modules/integration-twitch/database/migrations/.gitkeep
  • app-modules/integration-twitch/database/seeders/.gitkeep
  • app-modules/integration-twitch/src/Client/TwitchBaseClient.php
  • app-modules/integration-twitch/src/Contracts/TwitchService.php
  • app-modules/integration-twitch/src/OAuth/Client/TwitchOAuthClient.php
  • app-modules/integration-twitch/src/OAuth/Contracts/TwitchOAuthService.php
  • app-modules/integration-twitch/src/OAuth/DTO/TwitchOAuthAccessDTO.php
  • app-modules/integration-twitch/src/OAuth/DTO/TwitchOAuthDTO.php
  • app-modules/integration-twitch/src/Providers/IntegrationTwitchServiceProvider.php
  • app-modules/integration-twitch/src/Subscriber/Client/TwitchSubscribersClient.php
  • app-modules/integration-twitch/src/Subscriber/Contracts/TwitchSubscribersService.php
  • app-modules/integration-twitch/src/Subscriber/DTO/TwitchSubscriberDTO.php
  • app-modules/integration-twitch/src/Subscriber/Enum/SubscriptionTiersEnum.php
  • app-modules/integrations/composer.json
  • app-modules/integrations/phpstan.ignore.neon
  • app-modules/integrations/phpstan.neon
  • app-modules/integrations/src/Common/Contracts/TwitchService.php
  • app-modules/integrations/src/Providers/IntegrationsServiceProvider.php
  • composer.json
💤 Files with no reviewable changes (5)
  • app-modules/integrations/src/Common/Contracts/TwitchService.php
  • app-modules/integrations/src/Providers/IntegrationsServiceProvider.php
  • app-modules/integrations/phpstan.ignore.neon
  • app-modules/integrations/phpstan.neon
  • app-modules/integrations/composer.json

@danielhe4rt danielhe4rt merged commit 5d17543 into 4.x Mar 17, 2026
6 checks passed
@danielhe4rt danielhe4rt deleted the feat/integrations branch March 17, 2026 14:41
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