hasWorkspaceColumn($model)) { return; } // Get current workspace (returns Workspace model instance) $workspace = Workspace::current(); if ($workspace) { $builder->where($model->getTable().'.workspace_id', $workspace->id); return; } // No workspace context available if ($this->shouldEnforceStrictMode($model)) { throw MissingWorkspaceContextException::forScope( class_basename($model) ); } // Non-strict mode: return empty result set (fail safe) $builder->whereRaw('1 = 0'); } /** * Check if the model has a workspace_id column. */ protected function hasWorkspaceColumn(Model $model): bool { $fillable = $model->getFillable(); $guarded = $model->getGuarded(); // Check if workspace_id is in fillable or not in guarded return in_array('workspace_id', $fillable, true) || (count($guarded) === 1 && $guarded[0] === '*') || ! in_array('workspace_id', $guarded, true); } /** * Determine if strict mode should be enforced for a model. */ protected function shouldEnforceStrictMode(Model $model): bool { // Check global strict mode setting if (! self::$strictModeEnabled) { return false; } // Check if model has opted out of strict mode if (property_exists($model, 'workspaceScopeStrict') && $model->workspaceScopeStrict === false) { return false; } // Check if running from console (CLI commands may need to work without context) if (app()->runningInConsole() && ! app()->runningUnitTests()) { return false; } return true; } /** * Extend the query builder with workspace-specific methods. */ public function extend(Builder $builder): void { // Add method to set workspace context for a query $builder->macro('forWorkspace', function (Builder $builder, Workspace|int $workspace) { $workspaceId = $workspace instanceof Workspace ? $workspace->id : $workspace; return $builder->withoutGlobalScope(WorkspaceScope::class) ->where($builder->getModel()->getTable().'.workspace_id', $workspaceId); }); // Add method to query across all workspaces (use with caution) $builder->macro('acrossWorkspaces', function (Builder $builder) { return $builder->withoutGlobalScope(WorkspaceScope::class); }); // Add method to get current workspace for a query $builder->macro('currentWorkspaceId', function (Builder $builder) { $workspace = Workspace::current(); return $workspace?->id; }); } }