diff --git a/backend/app/Models/Gateway.php b/backend/app/Models/Gateway.php new file mode 100644 index 00000000..d7b58f9c --- /dev/null +++ b/backend/app/Models/Gateway.php @@ -0,0 +1,15 @@ + */ + use HasFactory; + + protected $guarded = ['id']; +} diff --git a/backend/app/Models/GatewayCategory.php b/backend/app/Models/GatewayCategory.php new file mode 100644 index 00000000..dd1e29df --- /dev/null +++ b/backend/app/Models/GatewayCategory.php @@ -0,0 +1,15 @@ + */ + use HasFactory; + + protected $guarded = ['id']; +} diff --git a/backend/app/Models/Payment.php b/backend/app/Models/Payment.php new file mode 100644 index 00000000..f4d1f85a --- /dev/null +++ b/backend/app/Models/Payment.php @@ -0,0 +1,15 @@ + */ + use HasFactory; + + protected $guarded = ['id']; +} diff --git a/backend/app/Models/PaymentStatus.php b/backend/app/Models/PaymentStatus.php new file mode 100644 index 00000000..b173c343 --- /dev/null +++ b/backend/app/Models/PaymentStatus.php @@ -0,0 +1,15 @@ + */ + use HasFactory; + + protected $guarded = ['id']; +} diff --git a/backend/app/User/Controllers/DocumentationController.php b/backend/app/User/Controllers/DocumentationController.php new file mode 100755 index 00000000..7c6b8092 --- /dev/null +++ b/backend/app/User/Controllers/DocumentationController.php @@ -0,0 +1,42 @@ +user(); + + foreach ($request->documents as $document) { + $user->documents()->create([ + 'title' => $document['title'], + 'url' => FileFacade::save($document['file'], "/{$user->id}/documents", $document['title']), + ]); + } + + return $this->successResponse(); + } + + public function edit(EditRequest $request): JsonResponse + { + $user = Auth::guard('web')->user(); + + foreach ($request->documents as $document) { + $user->documents()->sync(); + } + + return $this->successResponse(); + } +} diff --git a/backend/app/User/Requests/Documentation/EditRequest.php b/backend/app/User/Requests/Documentation/EditRequest.php new file mode 100755 index 00000000..25c3e1d2 --- /dev/null +++ b/backend/app/User/Requests/Documentation/EditRequest.php @@ -0,0 +1,31 @@ + + */ + public function rules(): array + { + return [ + 'documents' => 'required|array', + 'documents.*.file' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048', + 'documents.*.title' => 'required|string', + ]; + } +} diff --git a/backend/app/User/Requests/Documentation/UploadRequest.php b/backend/app/User/Requests/Documentation/UploadRequest.php new file mode 100755 index 00000000..b832c916 --- /dev/null +++ b/backend/app/User/Requests/Documentation/UploadRequest.php @@ -0,0 +1,31 @@ + + */ + public function rules(): array + { + return [ + 'documents' => 'required|array', + 'documents.*.file' => 'required|file|mimes:pdf,jpg,jpeg,png|max:2048', + 'documents.*.title' => 'required|string', + ]; + } +} diff --git a/backend/database/factories/GatewayCategoryFactory.php b/backend/database/factories/GatewayCategoryFactory.php new file mode 100644 index 00000000..facefb5e --- /dev/null +++ b/backend/database/factories/GatewayCategoryFactory.php @@ -0,0 +1,24 @@ + + */ +class GatewayCategoryFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/backend/database/factories/GatewayFactory.php b/backend/database/factories/GatewayFactory.php new file mode 100644 index 00000000..f8029ab5 --- /dev/null +++ b/backend/database/factories/GatewayFactory.php @@ -0,0 +1,24 @@ + + */ +class GatewayFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/backend/database/factories/PaymentFactory.php b/backend/database/factories/PaymentFactory.php new file mode 100644 index 00000000..8bfd4911 --- /dev/null +++ b/backend/database/factories/PaymentFactory.php @@ -0,0 +1,24 @@ + + */ +class PaymentFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/backend/database/factories/PaymentStatusFactory.php b/backend/database/factories/PaymentStatusFactory.php new file mode 100644 index 00000000..390010db --- /dev/null +++ b/backend/database/factories/PaymentStatusFactory.php @@ -0,0 +1,24 @@ + + */ +class PaymentStatusFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/backend/database/migrations/2026_05_17_053830_create_payment_statuses_table.php b/backend/database/migrations/2026_05_17_053830_create_payment_statuses_table.php new file mode 100644 index 00000000..754a8790 --- /dev/null +++ b/backend/database/migrations/2026_05_17_053830_create_payment_statuses_table.php @@ -0,0 +1,28 @@ +id(); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('payment_statuses'); + } +}; diff --git a/backend/database/migrations/2026_05_17_053831_create_gateway_categories_table.php b/backend/database/migrations/2026_05_17_053831_create_gateway_categories_table.php new file mode 100644 index 00000000..16ee53ea --- /dev/null +++ b/backend/database/migrations/2026_05_17_053831_create_gateway_categories_table.php @@ -0,0 +1,28 @@ +id(); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('gateway_categories'); + } +}; diff --git a/backend/database/migrations/2026_05_17_053832_create_gateways_table.php b/backend/database/migrations/2026_05_17_053832_create_gateways_table.php new file mode 100644 index 00000000..faab5d50 --- /dev/null +++ b/backend/database/migrations/2026_05_17_053832_create_gateways_table.php @@ -0,0 +1,38 @@ +id(); + $table->foreignId('user_id')->constrained('users'); + $table->string('username'); + $table->string('name'); + $table->string('domain'); + $table->string('tax_id'); + $table->string('bank_name'); + $table->string('account_holder'); + $table->string('logo')->nullable(); + $table->string('iban'); + $table->foreignId('category_id')->constrained('gateway_categories'); + $table->string('category_name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('gateways'); + } +}; diff --git a/backend/database/migrations/2026_05_17_053833_create_payments_table.php b/backend/database/migrations/2026_05_17_053833_create_payments_table.php new file mode 100644 index 00000000..0bf5cc2e --- /dev/null +++ b/backend/database/migrations/2026_05_17_053833_create_payments_table.php @@ -0,0 +1,38 @@ +id(); + $table->foreignId('user_id')->constrained('users'); + $table->string('username'); + $table->uuid('track_id'); + $table->string('amount'); + $table->string('currency'); + $table->string('callback_url'); + $table->dateTime('expires_at'); + $table->foreignId('status_id')->constrained('payment_statuses'); + $table->string('status_name'); + $table->ipAddress('ip'); + $table->foreignId('gateway_id')->constrained('gateways'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('payments'); + } +}; diff --git a/backend/database/seeders/GatewayCategorySeeder.php b/backend/database/seeders/GatewayCategorySeeder.php new file mode 100644 index 00000000..6e41f3b8 --- /dev/null +++ b/backend/database/seeders/GatewayCategorySeeder.php @@ -0,0 +1,17 @@ +controller(DocumentationController::class) ->group(function () { Route::get('/', 'index')->name('index'); - Route::post('confirm', 'confirm')->name('confirm'); - Route::post('reject', 'reject')->name('reject'); + Route::post('confirm/{user}', 'confirm')->name('confirm'); + Route::post('reject/{user}', 'reject')->name('reject'); Route::get('files/{user}', 'files')->name('files'); }); +Route::prefix('user_management') + ->middleware(['auth:expert', 'permission:user-management']) + ->name('user_management.') + ->controller(UserManagementController::class) + ->group(function () { + Route::get('/', 'index')->name('index'); + Route::post('/', 'store')->name('store'); + Route::get('/{user}', 'show')->name('show'); + Route::post('/{user}', 'update')->name('update'); + Route::delete('/{user}', 'destroy')->name('destroy'); + }); +Route::prefix('roles') + ->name('roles.') + ->middleware(['auth:expert', 'permission:role-management']) + ->controller(RoleManagementController::class) + ->group(function () { + Route::get('/', 'index')->name('index'); + Route::post('/', 'store')->name('store'); + Route::get('/{role}', 'show')->name('show'); + Route::post('/{role}', 'update')->name('update'); + Route::delete('/{role}', 'destroy')->name('destroy'); + }); +Route::prefix('permissions') + ->name('permissions.') + ->middleware(['auth:expert', 'permission:permission-management']) + ->controller(PermissionManagementController::class) + ->group(function () { + Route::get('/', 'index')->name('index'); + Route::post('/', 'store')->name('store'); + Route::get('/{permission}', 'show')->name('show'); + Route::post('/{permission}', 'update')->name('update'); + Route::delete('/{permission}', 'destroy')->name('destroy'); + }); +Route::prefix('expert') + ->name('expert.') + ->middleware(['auth:expert', 'permission:expert-management']) + ->controller(ExpertManagementController::class) + ->group(function () { + Route::get('/', 'index')->name('index'); + Route::post('/', 'store')->name('store'); + Route::get('/{expert}', 'show')->name('show'); + Route::post('/{expert}', 'update')->name('update'); + Route::delete('/{expert}', 'destroy')->name('destroy'); + }); + Route::prefix('profile') ->name('profile.') ->middleware('auth')