Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
UpdatePlanRequest
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
2 / 2
3
100.00% covered (success)
100.00%
1 / 1
 rules
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
2
 messages
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace App\Http\Requests\v2\Plan\Admin;
4
5use App\Http\Models\Plans;
6use App\Http\Requests\v2\Parameter\Concerns\AuthorizesVengresoAdmin;
7use Illuminate\Foundation\Http\FormRequest;
8use Illuminate\Validation\Rule;
9
10/**
11 * Request for updating an existing plan (admin).
12 *
13 * @property string|null $title The plan title
14 * @property string|null $identifier Unique plan identifier
15 * @property string|null $stripe_id Stripe price ID
16 * @property array|null $stripe_obj Stripe object data
17 * @property array|null $features Legacy features array
18 * @property string|null $hubspot_name HubSpot plan name
19 * @property bool|null $has_fly_learning Whether FlyLearning is available
20 * @property int|null $user_custom_prompts Custom prompts limit
21 * @property int|null $user_persona_available Number of personas allowed
22 * @property bool|null $can_disable_flygrammar Whether user can disable FlyGrammar
23 * @property int|null $flycut_deployment FlyCut deployment daily quota
24 * @property int|null $flygrammar_actions FlyGrammar actions daily quota
25 * @property int|null $prompts_per_day AI prompts daily quota
26 * @property int|null $regenerate_count AI regeneration limit
27 * @property array|null $flycuts_features Legacy FlyCuts features array
28 * @property string|null $stripe_product_id Stripe product ID
29 * @property bool|null $stripe_sync_enabled Whether to sync to Stripe
30 */
31class UpdatePlanRequest extends FormRequest
32{
33    use AuthorizesVengresoAdmin;
34
35    /**
36     * Get the validation rules that apply to the request.
37     *
38     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
39     */
40    public function rules(): array
41    {
42        $planId = $this->route('plan')?->_id ?? $this->route('plan');
43
44        $plan = $this->route('plan');
45        $pricingVersion = $plan instanceof Plans ? $plan->pricing_version : null;
46
47        return [
48            'title' => 'sometimes|string|max:255',
49            'identifier' => [
50                'sometimes',
51                'string',
52                'max:100',
53                'regex:/^[a-z][a-z0-9-]*$/',
54                Rule::unique('plans', 'identifier')
55                    ->ignore($planId, '_id')
56                    ->where(function ($query) use ($pricingVersion) {
57                        return $query->where('pricing_version', $pricingVersion);
58                    }),
59            ],
60            'stripe_id' => 'nullable|string|max:255',
61            'stripe_obj' => 'nullable|array',
62            'features' => 'nullable|array',
63            'hubspot_name' => 'nullable|string|max:255',
64            'has_fly_learning' => 'sometimes|boolean',
65            'user_custom_prompts' => 'sometimes|integer|min:-1',
66            'user_persona_available' => 'sometimes|integer|min:-1',
67            'can_disable_flygrammar' => 'sometimes|boolean',
68            'flycut_deployment' => 'sometimes|integer|min:-1',
69            'flygrammar_actions' => 'sometimes|integer|min:-1',
70            'prompts_per_day' => 'sometimes|integer|min:-1',
71            'regenerate_count' => 'sometimes|integer|min:-1',
72            'flycuts_features' => 'nullable|array',
73            'stripe_product_id' => 'nullable|string|max:255',
74            'stripe_sync_enabled' => 'sometimes|boolean',
75        ];
76    }
77
78    /**
79     * Get custom messages for validator errors.
80     *
81     * @return array<string, string>
82     */
83    public function messages(): array
84    {
85        return [
86            'identifier.regex' => 'The identifier must start with a letter and contain only lowercase letters, numbers, and hyphens.',
87            'identifier.unique' => 'A plan with this identifier already exists.',
88        ];
89    }
90}