Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.62% covered (success)
97.62%
41 / 42
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
AdminRolePlayCallTypeSettingsController
97.62% covered (success)
97.62%
41 / 42
80.00% covered (warning)
80.00%
4 / 5
11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 index
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 upsert
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
3
 isVengresoAdmin
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
 forbidden
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Http\Controllers\v2\Admin;
4
5use App\Http\Controllers\Controller;
6use App\Http\Models\Auth\Role;
7use App\Http\Models\RolePlayCallTypeSettings;
8use App\Http\Requests\v2\RolePlay\UpsertCallTypeSettingsRequest;
9use App\Http\Services\RolePlay\RolePlayCallTypeSettingsService;
10use Illuminate\Http\JsonResponse;
11use Illuminate\Http\Request;
12
13/**
14 * System-scope (CMC super-admin) controller for RolePlay call-type target
15 * duration defaults. Requires the VENGRESO_ADMIN role; the check is
16 * performed inline on each method to mirror RolePlayConfigController.
17 */
18class AdminRolePlayCallTypeSettingsController extends Controller
19{
20    public function __construct(
21        private readonly RolePlayCallTypeSettingsService $settingsService,
22    ) {}
23
24    /**
25     * List the system defaults for all supported call types. Missing rows
26     * are returned with the hard-coded fallback value so the CMC page can
27     * render a pre-filled form on first use.
28     */
29    public function index(Request $request): JsonResponse
30    {
31        if (! $this->isVengresoAdmin($request)) {
32            return $this->forbidden();
33        }
34
35        return response()->json([
36            'status' => 'success',
37            'data' => $this->settingsService->listRowsForScope(
38                RolePlayCallTypeSettings::SCOPE_SYSTEM,
39            ),
40        ]);
41    }
42
43    /**
44     * Upsert the system-wide default for one call type.
45     */
46    public function upsert(UpsertCallTypeSettingsRequest $request): JsonResponse
47    {
48        if (! $this->isVengresoAdmin($request)) {
49            return $this->forbidden();
50        }
51
52        if (! $request->isSupportedCallType()) {
53            return response()->json([
54                'status' => 'error',
55                'message' => 'Unsupported call type.',
56            ], 422);
57        }
58
59        $callType = $request->callType();
60        $targetSeconds = (int) $request->input('target_duration_seconds');
61
62        $row = $this->settingsService->upsert(
63            RolePlayCallTypeSettings::SCOPE_SYSTEM,
64            null,
65            $callType,
66            $targetSeconds,
67        );
68
69        return response()->json([
70            'status' => 'success',
71            'data' => [
72                'call_type' => $row->call_type,
73                'target_duration_seconds' => (int) $row->target_duration_seconds,
74                'scope' => RolePlayCallTypeSettings::SCOPE_SYSTEM,
75            ],
76        ]);
77    }
78
79    private function isVengresoAdmin(Request $request): bool
80    {
81        $user = $request->user();
82        if (! $user || ! method_exists($user, 'hasRole')) {
83            return false;
84        }
85
86        // Guard: CustomHasRoles::hasRole throws an \Error when the role row
87        // doesn't exist in the database. For an endpoint whose only purpose
88        // is role enforcement that must surface as 403, not 500.
89        try {
90            return (bool) $user->hasRole(Role::VENGRESO_ADMIN);
91        } catch (\Throwable $e) {
92            return false;
93        }
94    }
95
96    private function forbidden(): JsonResponse
97    {
98        return response()->json([
99            'status' => 'error',
100            'message' => 'Only Vengreso administrators can modify system defaults.',
101        ], 403);
102    }
103}