Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
AIPromptController
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
7 / 7
7
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
 index
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 show
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 store
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 update
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 destroy
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 products
100.00% covered (success)
100.00%
3 / 3
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\AIPrompts;
7use App\Http\Requests\v2\AIPrompt\DestroyAIPromptRequest;
8use App\Http\Requests\v2\AIPrompt\IndexAIPromptRequest;
9use App\Http\Requests\v2\AIPrompt\ShowAIPromptRequest;
10use App\Http\Requests\v2\AIPrompt\StoreAIPromptRequest;
11use App\Http\Requests\v2\AIPrompt\UpdateAIPromptRequest;
12use App\Http\Resources\v2\AIPromptResource;
13use App\Http\Services\AIPromptService;
14use Illuminate\Http\JsonResponse;
15use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
16
17/**
18 * Controller for managing AI prompt configurations.
19 *
20 * Only accessible by users with the VENGRESO_ADMIN role.
21 * Provides CRUD operations for the ai_prompts collection,
22 * which stores prompt templates used by FlyRewrite, FlyPost,
23 * and other AI features.
24 */
25class AIPromptController extends Controller
26{
27    public function __construct(
28        private AIPromptService $aiPromptService
29    ) {}
30
31    /**
32     * Get all AI prompts with optional product filtering.
33     *
34     * Returns prompts ordered by newest first (created_at desc).
35     *
36     * @param  IndexAIPromptRequest  $request  Validated request with optional product filter
37     *
38     * @response 200 {
39     *   "result": {
40     *     "data": [
41     *       {
42     *         "id": "684c1ce8dca2c6351807ec23",
43     *         "product": "paragraph_rewrite",
44     *         "name": "improve-writing",
45     *         "model": "gemini-2.0-flash-001:streamGenerateContent",
46     *         "version": 1,
47     *         "temperature": 0.6,
48     *         "tokens": 3500,
49     *         "top_p": 0.8,
50     *         "mission": "Rephrase the text...",
51     *         "context": "FlyRewrite helps users...",
52     *         "persona": null,
53     *         "instructions": ["Correct grammar...", "Improve sentence structure..."],
54     *         "examples": [{"input": "...", "output": "..."}],
55     *         "constraints": ["Keep the tone consistent..."],
56     *         "output_instructions": null,
57     *         "threshold": null,
58     *         "is_grounding": false,
59     *         "include_hashtags_prompt": null,
60     *         "exclude_hashtags_prompt": null,
61     *         "include_emojis_prompt": null,
62     *         "exclude_emojis_prompt": null,
63     *         "existent_content_instructions": null,
64     *         "existent_content_constraints": null,
65     *         "youtube_url_mission": null,
66     *         "blog_url_mission": null,
67     *         "youtube_url_instructions": null,
68     *         "blog_url_instructions": null,
69     *         "created_at": 1718278600,
70     *         "updated_at": 1718278600
71     *       }
72     *     ]
73     *   }
74     * }
75     */
76    public function index(IndexAIPromptRequest $request): AnonymousResourceCollection
77    {
78        $aiPrompts = $this->aiPromptService->getAll(
79            product: $request->input('product')
80        );
81
82        return AIPromptResource::collection($aiPrompts);
83    }
84
85    /**
86     * Get a single AI prompt by ID.
87     *
88     * @param  ShowAIPromptRequest  $request  Validated request (authorization only)
89     * @param  AIPrompts  $aiPrompt  The AI prompt to retrieve (route model binding)
90     *
91     * @response 200 {
92     *   "result": {
93     *     "data": {
94     *       "id": "684c1ce8dca2c6351807ec23",
95     *       "product": "paragraph_rewrite",
96     *       "name": "improve-writing",
97     *       "...": "..."
98     *     }
99     *   }
100     * }
101     */
102    public function show(ShowAIPromptRequest $request, AIPrompts $aiPrompt): AIPromptResource
103    {
104        return new AIPromptResource($aiPrompt);
105    }
106
107    /**
108     * Create a new AI prompt.
109     *
110     * @param  StoreAIPromptRequest  $request  Validated request with AI prompt data
111     *
112     * @response 201 {
113     *   "result": {
114     *     "data": {
115     *       "id": "684c1ce8dca2c6351807ec23",
116     *       "product": "paragraph_rewrite",
117     *       "name": "new-action",
118     *       "...": "..."
119     *     }
120     *   }
121     * }
122     */
123    public function store(StoreAIPromptRequest $request): JsonResponse
124    {
125        $aiPrompt = $this->aiPromptService->create($request->validated());
126
127        return (new AIPromptResource($aiPrompt))
128            ->response()
129            ->setStatusCode(201);
130    }
131
132    /**
133     * Update an existing AI prompt.
134     *
135     * @param  UpdateAIPromptRequest  $request  Validated request with update data
136     * @param  AIPrompts  $aiPrompt  The AI prompt to update (route model binding)
137     *
138     * @response 200 {
139     *   "result": {
140     *     "data": {
141     *       "id": "684c1ce8dca2c6351807ec23",
142     *       "product": "paragraph_rewrite",
143     *       "name": "improve-writing",
144     *       "...": "..."
145     *     }
146     *   }
147     * }
148     */
149    public function update(UpdateAIPromptRequest $request, AIPrompts $aiPrompt): AIPromptResource
150    {
151        $aiPrompt = $this->aiPromptService->update($aiPrompt, $request->validated());
152
153        return new AIPromptResource($aiPrompt);
154    }
155
156    /**
157     * Delete an AI prompt.
158     *
159     * @param  DestroyAIPromptRequest  $request  Validated request (authorization only)
160     * @param  AIPrompts  $aiPrompt  The AI prompt to delete (route model binding)
161     *
162     * @response 204 No content
163     */
164    public function destroy(DestroyAIPromptRequest $request, AIPrompts $aiPrompt): JsonResponse
165    {
166        $this->aiPromptService->delete($aiPrompt);
167
168        return response()->json(null, 204);
169    }
170
171    /**
172     * Get available product types for AI prompts.
173     *
174     * @response 200 {
175     *   "result": {
176     *     "data": ["paragraph_rewrite", "sentence_rewrite", "fly_post", "watch_youtube"]
177     *   }
178     * }
179     */
180    public function products(): JsonResponse
181    {
182        return response()->json([
183            'data' => $this->aiPromptService->getProducts(),
184        ]);
185    }
186}