Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
DeleteUserAction
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 2
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __invoke
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3declare(strict_types=1);
4
5namespace App\Action\SuperAdmin;
6
7use App\Domain\Auth\Data\UserAuthData;
8use App\Domain\Exception\ConflictException;
9use App\Domain\Exception\ForbiddenException;
10use App\Domain\Exception\NotFoundException;
11use App\Domain\SuperAdmin\Service\SuperAdminService;
12use App\Renderer\JsonRenderer;
13use Psr\Http\Message\ResponseInterface;
14use Psr\Http\Message\ServerRequestInterface;
15
16/**
17 * Delete a user and all associated data (investor, account, loans, transactions).
18 * Only available in local, dev, and test environments.
19 */
20final readonly class DeleteUserAction
21{
22    public function __construct(
23        private JsonRenderer $renderer,
24        private SuperAdminService $service,
25    ) {}
26
27    /**
28     * @param array<string, string> $args
29     * @param ServerRequestInterface $request
30     * @param ResponseInterface $response
31     */
32    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
33    {
34        // Block in production
35        $appEnv = $_ENV['APP_ENV'] ?? 'dev';
36        if ($appEnv === 'prod') {
37            throw new NotFoundException('This endpoint is not available in production');
38        }
39
40        // Verify super_admin role
41        $user = $request->getAttribute('user');
42        if (!$user instanceof UserAuthData || $user->role !== 'super_admin') {
43            throw new ForbiddenException('Super admin access required');
44        }
45
46        $userId = (int)$args['id'];
47
48        // Prevent self-deletion
49        if ($userId === $user->userId) {
50            throw new ConflictException('Cannot delete your own account');
51        }
52
53        $deleted = $this->service->deleteUser($userId);
54
55        return $this->renderer->json($response, [
56            'success' => true,
57            'message' => sprintf('User %d and all associated data deleted', $userId),
58            'data' => $deleted,
59        ]);
60    }
61}