Skip to content

Conversation

@nolanpro
Copy link
Contributor

@nolanpro nolanpro commented Nov 26, 2025

Refactor how we switch tenants

ci:multitenancy
ci:deploy
ci:k8s-branch:remove-tenant-specific-cache


Note

Refactors tenant switching to set env/config per-tenant, adds cache settings prefixing and JSON-enabled tenants:verify, integrates DB switch task, and removes legacy bootstrap/queue Horizon listen logic.

  • Multitenancy Core:
    • Switching: ProcessMaker\Multitenancy\SwitchTenant now saves landlord config, sets APP_URL, updates app.instance, app.url, filesystem roots, lang path, decrypts and sets app.key, and resets logging; forgetCurrent() restores landlord paths/keys.
    • Cache Prefixing: New ProcessMaker\Multitenancy\PrefixCacheTask prefixes default cache and cache_settings store per-tenant; registered in config/multitenancy.php alongside SwitchTenantDatabaseTask.
    • Queues: New MakeQueueTenantAwareAction avoids exceptions when multitenancy is disabled; wired in config/multitenancy.php.
  • CLI:
    • tenants:verify: Adds --json output, structured tables/logging, expected per-tenant validations (paths, configs, env vars), and error aggregation.
  • App/Providers Cleanup:
    • Remove TenantBootstrapper integration and Application::bootstrapWith override; delete HorizonListen command and related Horizon bootstrap/event hooks from ProcessMakerServiceProvider.
  • Config/Tests:
    • Add MULTITENANCY=false to phpunit.xml.
    • Keep PackageManifest singleton override; no other provider registration changes.

Written by Cursor Bugbot for commit a64fbed. This will update automatically on new commits. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on December 21

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

}

$this->info('Current Tenant ID: ' . ($currentTenant?->id ?? 'NONE'));
\Log::warning('TenantsVerify: Current Tenant ID: ' . ($currentTenant?->id ?? 'NONE'));
Copy link

Choose a reason for hiding this comment

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

Bug: Debug logging to warning level left in diagnostic command

The command now writes \Log::warning() entries for informational output that was previously only displayed via $this->info() and $this->table(). Line 52 replaces console info output with a warning-level log entry, and line 173 adds warning-level logging for every row in the table output. Using warning-level logging for routine informational output in a diagnostic command will create unnecessary noise in production logs every time tenants:verify runs.

Additional Locations (1)

Fix in Cursor Fix in Web

$tenantSettingsPrefix = 'tenant_' . $tenant->getKey() . ':' . $this->originalSettingsPrefix;
config()->set('cache.stores.cache_settings.prefix', $tenantSettingsPrefix);
$this->storeName = 'cache_settings';
$this->setCachePrefix($cachePrefix);
Copy link

Choose a reason for hiding this comment

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

Bug: Wrong prefix passed to setCachePrefix for settings store

In makeCurrent(), $tenantSettingsPrefix is calculated as 'tenant_X:' + originalSettingsPrefix (e.g., 'tenant_X:settings') and the config is correctly set, but setCachePrefix() is called with $cachePrefix (just 'tenant_X:') instead. Similarly, in forgetCurrent(), $this->originalPrefix is passed instead of $this->originalSettingsPrefix. This causes the cache_settings store to have a mismatched prefix, potentially breaking cache isolation between tenants.

Additional Locations (1)

Fix in Cursor Fix in Web

config()->set('cache.stores.cache_settings.prefix', $tenantSettingsPrefix);
$this->storeName = 'cache_settings';
$this->setCachePrefix($cachePrefix);
}
Copy link

Choose a reason for hiding this comment

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

Bug: Parent's makeCurrent not called, originalPrefix never initialized

The makeCurrent method completely overrides the parent SpatiePrefixCacheTask without calling parent::makeCurrent($tenant). The parent class sets $this->originalPrefix to save the original cache prefix before applying tenant-specific values. Since the parent is never called, $this->originalPrefix remains uninitialized. When forgetCurrent() is called, it passes $this->originalPrefix (which is null/undefined) to setCachePrefix(), causing the cache prefix to be incorrectly reset instead of restoring the original landlord value.

Additional Locations (1)

Fix in Cursor Fix in Web

config()->set('cache.stores.cache_settings.prefix', $this->originalSettingsPrefix);
$this->storeName = 'cache_settings';
$this->setCachePrefix($this->originalPrefix);
}
Copy link

Choose a reason for hiding this comment

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

Bug: Default cache store prefix never restored when forgetting tenant

In forgetCurrent(), the first setCachePrefix call on line 26 operates on the wrong cache store. The storeName property is left at 'cache_settings' from the previous makeCurrent() call, so line 26 restores the cache_settings store instead of the default cache store. The default store's prefix is never restored to its original value. The code needs to reset storeName to its default value before the first setCachePrefix call, mirroring the order in makeCurrent() where the default store is handled first.

Fix in Cursor Fix in Web

@nolanpro nolanpro closed this Nov 26, 2025
@nolanpro nolanpro reopened this Nov 26, 2025
@processmaker-sonarqube
Copy link

Quality Gate passed Quality Gate passed

Issues
0 New issues
0 Fixed issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarQube

@vladyrichter
Copy link

QA server K8S was successfully deployed https://tenant-1.ci-be8634c205.engk8s.processmaker.net

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.

3 participants