From 2f9254d8d80d2378f034fd17e000788c04445292 Mon Sep 17 00:00:00 2001 From: iMercy Date: Tue, 12 May 2026 08:45:55 -0400 Subject: [PATCH 1/4] enh: Use formrequest in store and update methods --- .../API/v1/TransactionController.php | 55 ++----------------- app/Http/Requests/StoreTransactionRequest.php | 49 +++++++++++++++++ .../Requests/UpdateTransactionRequest.php | 44 +++++++++++++++ 3 files changed, 97 insertions(+), 51 deletions(-) create mode 100644 app/Http/Requests/StoreTransactionRequest.php create mode 100644 app/Http/Requests/UpdateTransactionRequest.php diff --git a/app/Http/Controllers/API/v1/TransactionController.php b/app/Http/Controllers/API/v1/TransactionController.php index 3ff48cb..fbb269a 100644 --- a/app/Http/Controllers/API/v1/TransactionController.php +++ b/app/Http/Controllers/API/v1/TransactionController.php @@ -7,8 +7,6 @@ use App\Jobs\RecurrentTransactionJob; use App\Models\RecurringTransactionRule; use App\Models\Transaction; -use App\Rules\Iso8601DateTime; -use App\Rules\ValidateClientId; use App\Services\FileService; use App\Services\RecurringTransactionService; use Illuminate\Http\JsonResponse; @@ -291,33 +289,10 @@ enum: ['daily', 'weekly', 'monthly', 'yearly'] /** * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function store(Request $request): JsonResponse + public function store(StoreTransactionRequest $request): JsonResponse { - $validationResult = $this->validateRequest($request, [ - 'client_id' => ['nullable', 'string', new ValidateClientId()], - 'amount' => 'required|numeric|min:0.01', - 'type' => 'required|string|in:income,expense', - 'description' => 'nullable|string', - 'datetime' => ['nullable', new Iso8601DateTime()], - 'created_at' => ['nullable', new Iso8601DateTime()], - 'group_id' => 'nullable|integer|exists:groups,id', - 'party_id' => 'nullable|integer|exists:parties,id', - 'wallet_id' => 'required|integer|exists:wallets,id', - 'categories' => 'nullable|array', - 'is_recurring' => 'nullable|boolean', - 'recurrence_period' => 'nullable|string|in:daily,weekly,monthly,yearly', - 'recurrence_interval' => 'nullable|integer|min:1', - 'recurrence_ends_at' => ['nullable', 'date', 'after:today', new Iso8601DateTime()], - 'categories.*' => 'integer|exists:categories,id', - 'files' => 'nullable|array', - 'files.*' => 'file|mimes:' . FileService::ALLOWED_EXTENSIONS . '|max:' . FileService::MAX_KILOBYTES, - ]); - - if (! $validationResult['isValidated']) { - return $this->failure($validationResult['message'], $validationResult['code'], $validationResult['errors']); - } - $data = $validationResult['data']; + $data = $request->validated(); $user = $request->user(); if (! empty($data['client_id'])) { @@ -611,31 +586,9 @@ public function show($transactionId, Request $request): JsonResponse /** * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function update(Request $request, $transactionId): JsonResponse + public function update(UpdateTransactionRequest $request, $transactionId): JsonResponse { - $validationResult = $this->validateRequest($request, [ - 'client_id' => ['nullable', 'string', new ValidateClientId()], - 'amount' => 'nullable|numeric|min:0.01', - 'type' => 'nullable|string|in:income,expense', - 'datetime' => ['nullable', new Iso8601DateTime()], - 'description' => 'nullable|string', - 'party_id' => 'nullable|integer|exists:parties,id', - 'wallet_id' => 'sometimes|integer|exists:wallets,id', - 'group_id' => 'nullable|integer|exists:groups,id', - 'categories' => 'nullable|array', - 'categories.*' => 'integer|exists:categories,id', - 'is_recurring' => 'nullable|boolean', - 'recurrence_period' => 'nullable|string|in:daily,weekly,monthly,yearly', - 'recurrence_interval' => 'nullable|integer|min:1', - 'recurrence_ends_at' => ['nullable', 'date', 'after:today', new Iso8601DateTime()], - 'updated_at' => ['nullable', new Iso8601DateTime()], - ]); - - if (! $validationResult['isValidated']) { - return $this->failure($validationResult['message'], $validationResult['code'], $validationResult['errors']); - } - - $validatedData = $validationResult['data']; + $validatedData = $request->validated(); $recurringTransactionData = []; if (isset($validatedData['is_recurring']) && $validatedData['is_recurring']) { diff --git a/app/Http/Requests/StoreTransactionRequest.php b/app/Http/Requests/StoreTransactionRequest.php new file mode 100644 index 0000000..86a2aed --- /dev/null +++ b/app/Http/Requests/StoreTransactionRequest.php @@ -0,0 +1,49 @@ +|string> + */ + public function rules(): array + { + return [ + 'convert_myself_to_transfer' => 'sometimes|boolean', + 'client_id' => ['nullable', 'string', new ValidateClientId()], + 'amount' => 'required|numeric|min:0.01', + 'type' => 'required|string|in:income,expense', + 'description' => 'nullable|string', + 'datetime' => ['nullable', new Iso8601DateTime()], + 'created_at' => ['nullable', new Iso8601DateTime()], + 'group_id' => 'nullable|integer|exists:groups,id', + 'party_id' => 'nullable|integer|exists:parties,id', + 'wallet_id' => 'required|integer|exists:wallets,id', + 'categories' => 'nullable|array', + 'categories.*' => 'integer|exists:categories,id', + 'is_recurring' => 'nullable|boolean', + 'recurrence_period' => 'nullable|string|in:daily,weekly,monthly,yearly', + 'recurrence_interval' => 'nullable|integer|min:1', + 'recurrence_ends_at' => ['nullable', 'date', 'after:today', new Iso8601DateTime()], + 'files' => 'nullable|array', + 'files.*' => 'file|mimes:' . FileService::ALLOWED_EXTENSIONS . '|max:' . FileService::MAX_KILOBYTES, + 'from_wallet_id' => 'required_if:convert_myself_to_transfer,true|integer|exists:wallets,id', + ]; + } +} diff --git a/app/Http/Requests/UpdateTransactionRequest.php b/app/Http/Requests/UpdateTransactionRequest.php new file mode 100644 index 0000000..4c6ee82 --- /dev/null +++ b/app/Http/Requests/UpdateTransactionRequest.php @@ -0,0 +1,44 @@ +|string> + */ + public function rules(): array + { + return [ + 'client_id' => ['nullable', 'string', new ValidateClientId()], + 'amount' => 'nullable|numeric|min:0.01', + 'type' => 'nullable|string|in:income,expense', + 'datetime' => ['nullable', new Iso8601DateTime()], + 'description' => 'nullable|string', + 'party_id' => 'nullable|integer|exists:parties,id', + 'wallet_id' => 'sometimes|integer|exists:wallets,id', + 'group_id' => 'nullable|integer|exists:groups,id', + 'categories' => 'nullable|array', + 'categories.*' => 'integer|exists:categories,id', + 'is_recurring' => 'nullable|boolean', + 'recurrence_period' => 'nullable|string|in:daily,weekly,monthly,yearly', + 'recurrence_interval' => 'nullable|integer|min:1', + 'recurrence_ends_at' => ['nullable', 'date', 'after:today', new Iso8601DateTime()], + 'updated_at' => ['nullable', new Iso8601DateTime()], + ]; + } +} From 8407052c303d41e4ba359caf5ad33b3e14b6ccd8 Mon Sep 17 00:00:00 2001 From: iMercy Date: Wed, 3 Jun 2026 06:34:22 -0400 Subject: [PATCH 2/4] fix: Reset branch to dev and cherry pick form request changes --- app/Http/Controllers/API/v1/TransactionController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Http/Controllers/API/v1/TransactionController.php b/app/Http/Controllers/API/v1/TransactionController.php index fbb269a..7dd998a 100644 --- a/app/Http/Controllers/API/v1/TransactionController.php +++ b/app/Http/Controllers/API/v1/TransactionController.php @@ -15,6 +15,8 @@ use OpenApi\Attributes as OA; use Symfony\Component\HttpKernel\Exception\HttpException; use Throwable; +use App\Http\Requests\StoreTransactionRequest; +use App\Http\Requests\UpdateTransactionRequest; #[OA\Tag(name: 'Transactions', description: 'Endpoints for managing transactions')] class TransactionController extends ApiController From 53de2ff4947dc853b2e985a5704954ccda7edcbe Mon Sep 17 00:00:00 2001 From: iMercy Date: Mon, 8 Jun 2026 06:56:30 -0400 Subject: [PATCH 3/4] feat: Ensure failure method returns response with success msg n errors in store n upd8 --- app/Http/Controllers/API/ApiFormRequest.php | 30 +++++++++++++++++++ app/Http/Requests/FileImportApiRequest.php | 4 +-- app/Http/Requests/FixFailedImportsRequest.php | 4 +-- app/Http/Requests/ImportAnalyzeRequest.php | 4 +-- app/Http/Requests/ImportConfirmRequest.php | 4 +-- app/Http/Requests/StoreTransactionRequest.php | 5 ++-- .../Requests/UpdateTransactionRequest.php | 5 ++-- 7 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 app/Http/Controllers/API/ApiFormRequest.php diff --git a/app/Http/Controllers/API/ApiFormRequest.php b/app/Http/Controllers/API/ApiFormRequest.php new file mode 100644 index 0000000..498ebfc --- /dev/null +++ b/app/Http/Controllers/API/ApiFormRequest.php @@ -0,0 +1,30 @@ +json([ + 'success' => false, + 'message' => __('Server failed to validate request.'), + 'errors' => $validator->errors()->toArray(), + ], 422); + + throw new HttpResponseException($response); + } +} diff --git a/app/Http/Requests/FileImportApiRequest.php b/app/Http/Requests/FileImportApiRequest.php index b7309f4..f3b77f1 100644 --- a/app/Http/Requests/FileImportApiRequest.php +++ b/app/Http/Requests/FileImportApiRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests; -use Illuminate\Foundation\Http\FormRequest; +// use Illuminate\Foundation\Http\FormRequest; -class FileImportApiRequest extends FormRequest +class FileImportApiRequest extends ApiFormRequest { /** * Get the validation rules that apply to the request. diff --git a/app/Http/Requests/FixFailedImportsRequest.php b/app/Http/Requests/FixFailedImportsRequest.php index 71e7db4..597f1f6 100644 --- a/app/Http/Requests/FixFailedImportsRequest.php +++ b/app/Http/Requests/FixFailedImportsRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests; -use Illuminate\Foundation\Http\FormRequest; +// use Illuminate\Foundation\Http\FormRequest; -class FixFailedImportsRequest extends FormRequest +class FixFailedImportsRequest extends ApiFormRequest { /** * Get the validation rules that apply to the request. diff --git a/app/Http/Requests/ImportAnalyzeRequest.php b/app/Http/Requests/ImportAnalyzeRequest.php index f40fda9..e3a8d33 100644 --- a/app/Http/Requests/ImportAnalyzeRequest.php +++ b/app/Http/Requests/ImportAnalyzeRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests; -use Illuminate\Foundation\Http\FormRequest; +// use Illuminate\Foundation\Http\FormRequest; -class ImportAnalyzeRequest extends FormRequest +class ImportAnalyzeRequest extends ApiFormRequest { public function rules(): array { diff --git a/app/Http/Requests/ImportConfirmRequest.php b/app/Http/Requests/ImportConfirmRequest.php index 35e0d37..ff7d0b4 100644 --- a/app/Http/Requests/ImportConfirmRequest.php +++ b/app/Http/Requests/ImportConfirmRequest.php @@ -2,9 +2,9 @@ namespace App\Http\Requests; -use Illuminate\Foundation\Http\FormRequest; +// use Illuminate\Foundation\Http\FormRequest; -class ImportConfirmRequest extends FormRequest +class ImportConfirmRequest extends ApiFormRequest { public function rules(): array { diff --git a/app/Http/Requests/StoreTransactionRequest.php b/app/Http/Requests/StoreTransactionRequest.php index 86a2aed..9860178 100644 --- a/app/Http/Requests/StoreTransactionRequest.php +++ b/app/Http/Requests/StoreTransactionRequest.php @@ -5,9 +5,10 @@ use App\Rules\Iso8601DateTime; use App\Rules\ValidateClientId; use App\Services\FileService; -use Illuminate\Foundation\Http\FormRequest; -class StoreTransactionRequest extends FormRequest +// use Illuminate\Foundation\Http\FormRequest; + +class StoreTransactionRequest extends ApiFormRequest { /** * Determine if the user is authorized to make this request. diff --git a/app/Http/Requests/UpdateTransactionRequest.php b/app/Http/Requests/UpdateTransactionRequest.php index 4c6ee82..a31fef9 100644 --- a/app/Http/Requests/UpdateTransactionRequest.php +++ b/app/Http/Requests/UpdateTransactionRequest.php @@ -4,9 +4,10 @@ use App\Rules\Iso8601DateTime; use App\Rules\ValidateClientId; -use Illuminate\Foundation\Http\FormRequest; -class UpdateTransactionRequest extends FormRequest +// use Illuminate\Foundation\Http\FormRequest; + +class UpdateTransactionRequest extends ApiFormRequest { /** * Determine if the user is authorized to make this request. From 6db5100b54a64a3ae870debba94d3326816147d5 Mon Sep 17 00:00:00 2001 From: iMercy Date: Mon, 8 Jun 2026 07:20:30 -0400 Subject: [PATCH 4/4] fix: Move apiformrequest to form requests folder --- app/Http/{Controllers/API => Requests}/ApiFormRequest.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/Http/{Controllers/API => Requests}/ApiFormRequest.php (100%) diff --git a/app/Http/Controllers/API/ApiFormRequest.php b/app/Http/Requests/ApiFormRequest.php similarity index 100% rename from app/Http/Controllers/API/ApiFormRequest.php rename to app/Http/Requests/ApiFormRequest.php