Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
UpdateFundingRequestStatusAction
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 2
30
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 / 16
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5namespace App\Action\Funding;
6
7use App\Domain\Exception\ForbiddenException;
8use App\Domain\Exception\ValidationException;
9use App\Domain\Funding\Service\FundingRequestService;
10use App\Renderer\JsonRenderer;
11use App\Support\Row;
12use Psr\Http\Message\ResponseInterface;
13use Psr\Http\Message\ServerRequestInterface;
14
15/**
16 * Admin action on a funding request: mark it completed or rejected (FSC-21).
17 *
18 * POST /api/admin/funding-requests/{id}/status   body: { "status": "completed" | "rejected" }
19 */
20final readonly class UpdateFundingRequestStatusAction
21{
22    public function __construct(
23        private FundingRequestService $service,
24        private JsonRenderer $renderer,
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        $attributes = $request->getAttributes();
35        $role = Row::nullableString($attributes, 'userRole') ?? '';
36        if ($role !== 'admin' && $role !== 'super_admin') {
37            throw new ForbiddenException('Admin access required');
38        }
39
40        $fundingRequestId = (int)$args['id'];
41        $adminUserId = Row::int($attributes, 'userId');
42
43        $body = (array)$request->getParsedBody();
44        $status = Row::nullableString($body, 'status');
45        if ($status === null) {
46            throw new ValidationException('status is required');
47        }
48
49        $updated = $this->service->updateStatus($fundingRequestId, $status, $adminUserId);
50
51        return $this->renderer->json($response, [
52            'success' => true,
53            'message' => sprintf('Funding request marked as %s', (string)$updated->status),
54            'data' => ['fundingRequest' => $updated->toAdminArray()],
55        ]);
56    }
57}