Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
RemoteConfigController
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
7 / 7
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 show
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 update
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 updateSection
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 deleteSection
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 history
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 rollback
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace App\Http\Controllers\v2\Admin;
4
5use App\Http\Controllers\Controller;
6use App\Http\Models\RemoteConfig;
7use App\Http\Requests\v2\RemoteConfig\DeleteSectionRemoteConfigRequest;
8use App\Http\Requests\v2\RemoteConfig\IndexHistoryRemoteConfigRequest;
9use App\Http\Requests\v2\RemoteConfig\RollbackRemoteConfigRequest;
10use App\Http\Requests\v2\RemoteConfig\ShowRemoteConfigRequest;
11use App\Http\Requests\v2\RemoteConfig\UpdateRemoteConfigRequest;
12use App\Http\Requests\v2\RemoteConfig\UpdateSectionRemoteConfigRequest;
13use App\Http\Resources\v2\RemoteConfigHistoryResource;
14use App\Http\Resources\v2\RemoteConfigResource;
15use App\Http\Services\RemoteConfigService;
16use Illuminate\Http\JsonResponse;
17
18/**
19 * Admin Remote Config Controller
20 *
21 * Manages remote configuration for the Chrome extension.
22 * All endpoints require VENGRESO_ADMIN role.
23 */
24class RemoteConfigController extends Controller
25{
26    public function __construct(
27        private readonly RemoteConfigService $remoteConfigService
28    ) {}
29
30    /**
31     * Get the current remote config.
32     *
33     * @param  ShowRemoteConfigRequest  $request  Authorized admin request
34     *
35     * @response 200 {"result": {"version": "...", "linkedin_selectors": {...}, ...}}
36     */
37    public function show(ShowRemoteConfigRequest $request): RemoteConfigResource|JsonResponse
38    {
39        $config = $this->remoteConfigService->getCurrentFresh();
40
41        if (! $config) {
42            return response()->json(null);
43        }
44
45        return new RemoteConfigResource($config);
46    }
47
48    /**
49     * Full update of the remote config (all sections).
50     *
51     * @param  UpdateRemoteConfigRequest  $request  Validated admin request
52     *
53     * @response 200 {"result": {"version": "...", "linkedin_selectors": {...}, ...}}
54     */
55    public function update(UpdateRemoteConfigRequest $request): RemoteConfigResource
56    {
57        $validated = $request->validated();
58        $changedBy = $request->user()->email;
59        $description = $validated['change_description'] ?? null;
60
61        unset($validated['change_description']);
62
63        $config = $this->remoteConfigService->fullUpdate($validated, $changedBy, $description);
64
65        return new RemoteConfigResource($config);
66    }
67
68    /**
69     * Update a single config section.
70     *
71     * @param  UpdateSectionRemoteConfigRequest  $request  Validated admin request
72     * @param  string  $section  The section name (one of RemoteConfig::SECTIONS)
73     * @return RemoteConfigResource
74     *
75     * @response 200 {"result": {"version": "...", ...}}
76     */
77    public function updateSection(UpdateSectionRemoteConfigRequest $request, string $section): RemoteConfigResource|JsonResponse
78    {
79        if (! in_array($section, RemoteConfig::SECTIONS)) {
80            return response()->json(['error' => 'Invalid section'], 404);
81        }
82
83        $sectionData = $request->sectionData();
84        $changedBy = $request->user()->email;
85        $description = $request->validated()['change_description'] ?? null;
86
87        $config = $this->remoteConfigService->updateSection($section, $sectionData, $changedBy, $description);
88
89        return new RemoteConfigResource($config);
90    }
91
92    /**
93     * Delete (null out) a config section.
94     *
95     * @param  DeleteSectionRemoteConfigRequest  $request  Authorized admin request
96     * @param  string  $section  The section name to delete
97     * @return RemoteConfigResource
98     *
99     * @response 200 {"result": {"version": "...", ...}}
100     */
101    public function deleteSection(DeleteSectionRemoteConfigRequest $request, string $section): RemoteConfigResource|JsonResponse
102    {
103        if (! in_array($section, RemoteConfig::SECTIONS)) {
104            return response()->json(['error' => 'Invalid section'], 404);
105        }
106
107        $changedBy = $request->user()->email;
108        $description = $request->validated()['change_description'] ?? null;
109
110        $config = $this->remoteConfigService->deleteSection($section, $changedBy, $description);
111
112        return new RemoteConfigResource($config);
113    }
114
115    /**
116     * Get paginated config change history.
117     *
118     * @param  IndexHistoryRemoteConfigRequest  $request  Validated admin request
119     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
120     *
121     * @response 200 {"result": [{"version": "...", "changed_by": "...", ...}]}
122     */
123    public function history(IndexHistoryRemoteConfigRequest $request)
124    {
125        $perPage = $request->validated()['per_page'] ?? 20;
126
127        $history = $this->remoteConfigService->getHistory($perPage);
128
129        return RemoteConfigHistoryResource::collection($history);
130    }
131
132    /**
133     * Rollback to a previous config version.
134     *
135     * @param  RollbackRemoteConfigRequest  $request  Authorized admin request
136     * @param  string  $version  The version to rollback to
137     *
138     * @response 200 {"result": {"version": "...", ...}}
139     * @response 404 {"error": "Version not found"}
140     */
141    public function rollback(RollbackRemoteConfigRequest $request, string $version): RemoteConfigResource|JsonResponse
142    {
143        $changedBy = $request->user()->email;
144        $description = $request->validated()['change_description'] ?? null;
145
146        $config = $this->remoteConfigService->rollback($version, $changedBy, $description);
147
148        if (! $config) {
149            return response()->json(['error' => 'Version not found'], 404);
150        }
151
152        return new RemoteConfigResource($config);
153    }
154}