Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
51 / 51 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
| StoreAIPromptRequest | |
100.00% |
51 / 51 |
|
100.00% |
2 / 2 |
2 | |
100.00% |
1 / 1 |
| rules | |
100.00% |
40 / 40 |
|
100.00% |
1 / 1 |
1 | |||
| messages | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Http\Requests\v2\AIPrompt; |
| 4 | |
| 5 | use App\Http\Models\AIPrompts; |
| 6 | use App\Http\Requests\v2\Parameter\Concerns\AuthorizesVengresoAdmin; |
| 7 | use Illuminate\Foundation\Http\FormRequest; |
| 8 | use Illuminate\Validation\Rule; |
| 9 | |
| 10 | /** |
| 11 | * Request for creating a new AI prompt. |
| 12 | * |
| 13 | * @property string $product The product identifier (paragraph_rewrite, sentence_rewrite, fly_post, watch_youtube) |
| 14 | * @property string $name The action/prompt name (e.g., improve-writing, humanize, change-tone) |
| 15 | * @property string|null $model The AI model identifier (e.g., gemini-2.0-flash-001:streamGenerateContent) |
| 16 | * @property int $version The prompt version number (default: 1) |
| 17 | * @property float|null $temperature The model temperature setting (0.0 to 2.0) |
| 18 | * @property int|null $tokens The maximum token limit |
| 19 | * @property float|null $top_p The top_p sampling parameter (0.0 to 1.0) |
| 20 | * @property string|null $mission The mission/goal of the prompt |
| 21 | * @property string|null $context The context description for the AI |
| 22 | * @property string|null $persona The persona description for the AI |
| 23 | * @property array<string>|null $instructions List of instructions for the AI |
| 24 | * @property array<array{input: string, output: string, hashtags?: bool|null, emojis?: bool|null, language?: string|null, length?: string|null}>|null $examples Input/output examples with optional hashtags, emojis, language, and length metadata (used by fly_post) |
| 25 | * @property array<string>|null $constraints List of constraints for the AI |
| 26 | * @property array<string>|null $output_instructions Output formatting instructions |
| 27 | * @property float|null $threshold Score threshold (used for sentence_rewrite/score) |
| 28 | * @property bool|null $is_grounding Whether to enable Google Search grounding (default: false) |
| 29 | * @property string|null $include_hashtags_prompt Prompt for including hashtags |
| 30 | * @property string|null $exclude_hashtags_prompt Prompt for excluding hashtags |
| 31 | * @property string|null $include_emojis_prompt Prompt for including emojis |
| 32 | * @property string|null $exclude_emojis_prompt Prompt for excluding emojis |
| 33 | * @property string|null $existent_content_instructions Instructions for regeneration |
| 34 | * @property array<string>|null $existent_content_constraints Constraints for regeneration |
| 35 | * @property string|null $youtube_url_mission Mission for YouTube-based posts |
| 36 | * @property string|null $blog_url_mission Mission for blog-based posts |
| 37 | * @property array<string>|null $youtube_url_instructions Instructions for YouTube-based posts |
| 38 | * @property array<string>|null $blog_url_instructions Instructions for blog-based posts |
| 39 | */ |
| 40 | class StoreAIPromptRequest extends FormRequest |
| 41 | { |
| 42 | use AuthorizesVengresoAdmin; |
| 43 | |
| 44 | /** |
| 45 | * Get the validation rules that apply to the request. |
| 46 | * |
| 47 | * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> |
| 48 | */ |
| 49 | public function rules(): array |
| 50 | { |
| 51 | return [ |
| 52 | 'product' => ['required', 'string', Rule::in(AIPrompts::PRODUCTS)], |
| 53 | 'name' => 'required|string|max:255', |
| 54 | 'model' => 'nullable|string|max:255', |
| 55 | 'version' => 'sometimes|integer|min:1', |
| 56 | 'temperature' => 'nullable|numeric|min:0|max:2', |
| 57 | 'tokens' => 'nullable|integer|min:1', |
| 58 | 'top_p' => 'nullable|numeric|min:0|max:1', |
| 59 | 'mission' => 'nullable|string', |
| 60 | 'context' => 'nullable|string', |
| 61 | 'persona' => 'nullable|string', |
| 62 | 'instructions' => 'nullable|array', |
| 63 | 'instructions.*' => 'string', |
| 64 | 'examples' => 'nullable|array', |
| 65 | 'examples.*.input' => 'required_with:examples|string', |
| 66 | 'examples.*.output' => 'required_with:examples|string', |
| 67 | 'examples.*.hashtags' => 'nullable|boolean', |
| 68 | 'examples.*.emojis' => 'nullable|boolean', |
| 69 | 'examples.*.language' => 'nullable|string|max:100', |
| 70 | 'examples.*.length' => 'nullable|string|max:100', |
| 71 | 'constraints' => 'nullable|array', |
| 72 | 'constraints.*' => 'string', |
| 73 | 'output_instructions' => 'nullable|array', |
| 74 | 'output_instructions.*' => 'string', |
| 75 | 'threshold' => 'nullable|numeric|min:0|max:1', |
| 76 | 'is_grounding' => 'sometimes|boolean', |
| 77 | 'include_hashtags_prompt' => 'nullable|string', |
| 78 | 'exclude_hashtags_prompt' => 'nullable|string', |
| 79 | 'include_emojis_prompt' => 'nullable|string', |
| 80 | 'exclude_emojis_prompt' => 'nullable|string', |
| 81 | 'existent_content_instructions' => 'nullable|string', |
| 82 | 'existent_content_constraints' => 'nullable|array', |
| 83 | 'existent_content_constraints.*' => 'string', |
| 84 | 'youtube_url_mission' => 'nullable|string', |
| 85 | 'blog_url_mission' => 'nullable|string', |
| 86 | 'youtube_url_instructions' => 'nullable|array', |
| 87 | 'youtube_url_instructions.*' => 'string', |
| 88 | 'blog_url_instructions' => 'nullable|array', |
| 89 | 'blog_url_instructions.*' => 'string', |
| 90 | ]; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Get custom messages for validator errors. |
| 95 | * |
| 96 | * @return array<string, string> |
| 97 | */ |
| 98 | public function messages(): array |
| 99 | { |
| 100 | return [ |
| 101 | 'product.required' => 'The product is required.', |
| 102 | 'product.in' => 'The product must be one of: '.implode(', ', AIPrompts::PRODUCTS), |
| 103 | 'name.required' => 'The prompt name is required.', |
| 104 | 'temperature.min' => 'The temperature must be at least 0.', |
| 105 | 'temperature.max' => 'The temperature must not exceed 2.', |
| 106 | 'top_p.min' => 'The top_p must be at least 0.', |
| 107 | 'top_p.max' => 'The top_p must not exceed 1.', |
| 108 | 'tokens.min' => 'The tokens must be at least 1.', |
| 109 | 'version.min' => 'The version must be at least 1.', |
| 110 | ]; |
| 111 | } |
| 112 | } |