Add transferOwnership() method to the Workspace model that allows the current owner to transfer ownership to another existing workspace member. The method: - Verifies the new owner is an existing member - Demotes the current owner to admin role - Promotes the new owner to owner role - Updates team assignments when teams are in use - Wraps the role changes in a DB transaction - Dispatches WorkspaceOwnershipTransferred event - Throws WorkspaceOwnershipException for auth/validation failures New files: - Events/WorkspaceOwnershipTransferred.php - Exceptions/WorkspaceOwnershipException.php - tests/Feature/WorkspaceOwnershipTransferTest.php Fixes #35 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
76 lines
2 KiB
PHP
76 lines
2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Core\Tenant\Exceptions;
|
|
|
|
use Core\Tenant\Models\User;
|
|
use Core\Tenant\Models\Workspace;
|
|
use Exception;
|
|
|
|
/**
|
|
* Exception thrown when a workspace ownership transfer fails.
|
|
*/
|
|
class WorkspaceOwnershipException extends Exception
|
|
{
|
|
public function __construct(
|
|
string $message,
|
|
public readonly ?Workspace $workspace = null,
|
|
public readonly ?User $user = null,
|
|
int $code = 403,
|
|
?\Throwable $previous = null
|
|
) {
|
|
parent::__construct($message, $code, $previous);
|
|
}
|
|
|
|
/**
|
|
* The new owner is not a member of the workspace.
|
|
*/
|
|
public static function notAMember(Workspace $workspace, User $user): self
|
|
{
|
|
return new self(
|
|
message: "User {$user->id} is not a member of workspace {$workspace->id}. Only existing members can become owners.",
|
|
workspace: $workspace,
|
|
user: $user,
|
|
code: 422
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The user is already the owner.
|
|
*/
|
|
public static function alreadyOwner(Workspace $workspace, User $user): self
|
|
{
|
|
return new self(
|
|
message: "User {$user->id} is already the owner of workspace {$workspace->id}.",
|
|
workspace: $workspace,
|
|
user: $user,
|
|
code: 422
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The workspace has no current owner.
|
|
*/
|
|
public static function noCurrentOwner(Workspace $workspace): self
|
|
{
|
|
return new self(
|
|
message: "Workspace {$workspace->id} has no current owner.",
|
|
workspace: $workspace,
|
|
code: 500
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The requesting user is not authorised to transfer ownership.
|
|
*/
|
|
public static function unauthorised(Workspace $workspace, ?User $user = null): self
|
|
{
|
|
return new self(
|
|
message: 'Only the workspace owner can transfer ownership.',
|
|
workspace: $workspace,
|
|
user: $user,
|
|
code: 403
|
|
);
|
|
}
|
|
}
|