Forráskód Böngészése

feat: :sparkles: crud inicial provider e media

criacao estrutura inicial cruds provider e media
Gustavo Zanatta 1 hónapja
szülő
commit
1fc81fe6dc

+ 55 - 0
app/Http/Controllers/MediaController.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\MediaService;
+use App\Http\Requests\MediaRequest;
+use App\Http\Resources\MediaResource;
+use Illuminate\Http\JsonResponse;
+
+class MediaController extends Controller
+{
+    public function __construct(protected MediaService $service) {}
+
+    public function index(): JsonResponse
+    {
+        $items = $this->service->getAll();
+        return $this->successResponse(
+            payload: MediaResource::collection($items),
+        );
+    }
+
+    public function store(MediaRequest $request): JsonResponse
+    {
+        $item = $this->service->create($request->validated());
+        return $this->successResponse(
+            payload: new MediaResource($item),
+            message: __("messages.created"),
+            code: 201,
+        );
+    }
+
+    public function show(int $id): JsonResponse
+    {
+        $item = $this->service->findById($id);
+        return $this->successResponse(payload: new MediaResource($item));
+    }
+
+    public function update(MediaRequest $request, int $id): JsonResponse
+    {
+        $item = $this->service->update($id, $request->validated());
+        return $this->successResponse(
+            payload: new MediaResource($item),
+            message: __("messages.updated"),
+        );
+    }
+
+    public function destroy(int $id): JsonResponse
+    {
+        $this->service->delete($id);
+        return $this->successResponse(
+            message: __("messages.deleted"),
+            code: 204,
+        );
+    }
+}

+ 55 - 0
app/Http/Controllers/ProviderController.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\ProviderService;
+use App\Http\Requests\ProviderRequest;
+use App\Http\Resources\ProviderResource;
+use Illuminate\Http\JsonResponse;
+
+class ProviderController extends Controller
+{
+    public function __construct(protected ProviderService $service) {}
+
+    public function index(): JsonResponse
+    {
+        $items = $this->service->getAll();
+        return $this->successResponse(
+            payload: ProviderResource::collection($items),
+        );
+    }
+
+    public function store(ProviderRequest $request): JsonResponse
+    {
+        $item = $this->service->create($request->validated());
+        return $this->successResponse(
+            payload: new ProviderResource($item),
+            message: __("messages.created"),
+            code: 201,
+        );
+    }
+
+    public function show(int $id): JsonResponse
+    {
+        $item = $this->service->findById($id);
+        return $this->successResponse(payload: new ProviderResource($item));
+    }
+
+    public function update(ProviderRequest $request, int $id): JsonResponse
+    {
+        $item = $this->service->update($id, $request->validated());
+        return $this->successResponse(
+            payload: new ProviderResource($item),
+            message: __("messages.updated"),
+        );
+    }
+
+    public function destroy(int $id): JsonResponse
+    {
+        $this->service->delete($id);
+        return $this->successResponse(
+            message: __("messages.deleted"),
+            code: 204,
+        );
+    }
+}

+ 28 - 0
app/Http/Requests/MediaRequest.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+
+class MediaRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        $rules = [
+            'source' => 'sometimes|string',
+            'source_id' => 'sometimes|integer',
+            'name' => 'sometimes|nullable|string',
+            'path' => 'sometimes|string',
+            'url' => 'sometimes|nullable|string',
+            'user_id' => 'sometimes|nullable|exists:users,id',
+        ];
+
+        if ($this->isMethod('post')) {
+            $rules['source'] = 'required|string';
+            $rules['source_id'] = 'required|integer';
+            $rules['path'] = 'required|string';
+        }
+
+        return $rules;
+    }
+}

+ 175 - 0
app/Http/Requests/ProviderRequest.php

@@ -0,0 +1,175 @@
+<?php
+
+namespace App\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Validation\Rule;
+use App\Enums\UserTypeEnum;
+
+class ProviderRequest extends FormRequest
+{
+    public function rules(): array
+    {
+        $providerId = $this->route('id');
+
+        $rules = [
+            'document' => [
+                'sometimes',
+                'string',
+                'regex:/^[0-9]{11}$|^[0-9]{14}$/',
+                function ($attribute, $value, $fail) use ($providerId) {
+                    if (!$this->isValidCpfCnpj($value)) {
+                        $fail(__('validation.custom.document.invalid'));
+                    }
+                },
+                Rule::unique('providers', 'document')
+                    ->ignore($providerId)
+                    ->whereNull('deleted_at'),
+            ],
+            'rg' => 'sometimes|nullable|string|max:20',
+            'user_id' => [
+                'sometimes',
+                'exists:users,id',
+                Rule::unique('providers', 'user_id')
+                    ->ignore($providerId)
+                    ->whereNull('deleted_at'),
+                function ($attribute, $value, $fail) {
+                    // Verifica se o user já está vinculado a um client
+                    if (\DB::table('clients')->where('user_id', $value)->whereNull('deleted_at')->exists()) {
+                        $fail(__('validation.custom.user_id.already_linked_to_client'));
+                    }
+                },
+            ],
+            'average_rating' => 'sometimes|nullable|numeric|min:0|max:5',
+            'total_services' => 'sometimes|integer|min:0',
+            'birth_date' => 'sometimes|nullable|date|before:today',
+            'selfie_verified' => 'sometimes|boolean',
+            'document_verified' => 'sometimes|boolean',
+            'is_approved' => 'sometimes|boolean',
+            'daily_price_8h' => 'sometimes|nullable|numeric|min:100|max:500',
+            'daily_price_6h' => 'sometimes|nullable|numeric|min:100|max:500',
+            'daily_price_4h' => 'sometimes|nullable|numeric|min:100|max:500',
+            'daily_price_2h' => 'sometimes|nullable|numeric|min:100|max:500',
+            'profile_media_id' => 'sometimes|nullable|exists:media,id',
+        ];
+
+        if ($this->isMethod('post')) {
+            $rules['document'] = [
+                'required',
+                'string',
+                'regex:/^[0-9]{11}$|^[0-9]{14}$/',
+                function ($attribute, $value, $fail) {
+                    if (!$this->isValidCpfCnpj($value)) {
+                        $fail(__('validation.custom.document.invalid'));
+                    }
+                },
+                Rule::unique('providers', 'document')->whereNull('deleted_at'),
+            ];
+            $rules['user_id'] = [
+                'required',
+                'exists:users,id',
+                Rule::unique('providers', 'user_id')->whereNull('deleted_at'),
+                function ($attribute, $value, $fail) {
+                    // Verifica se o user já está vinculado a um client
+                    if (\DB::table('clients')->where('user_id', $value)->whereNull('deleted_at')->exists()) {
+                        $fail(__('validation.custom.user_id.already_linked_to_client'));
+                    }
+                },
+            ];
+        }
+
+        return $rules;
+    }
+
+    /**
+     * Valida CPF ou CNPJ
+     */
+    private function isValidCpfCnpj(string $value): bool
+    {
+        $value = preg_replace('/[^0-9]/', '', $value);
+
+        if (strlen($value) === 11) {
+            return $this->isValidCpf($value);
+        } elseif (strlen($value) === 14) {
+            return $this->isValidCnpj($value);
+        }
+
+        return false;
+    }
+
+    /**
+     * Valida CPF
+     */
+    private function isValidCpf(string $cpf): bool
+    {
+        // Elimina CPFs inválidos conhecidos
+        if (preg_match('/(\d)\1{10}/', $cpf)) {
+            return false;
+        }
+
+        // Valida primeiro dígito verificador
+        for ($t = 9; $t < 11; $t++) {
+            for ($d = 0, $c = 0; $c < $t; $c++) {
+                $d += $cpf[$c] * (($t + 1) - $c);
+            }
+            $d = ((10 * $d) % 11) % 10;
+            if ($cpf[$c] != $d) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Valida CNPJ
+     */
+    private function isValidCnpj(string $cnpj): bool
+    {
+        // Elimina CNPJs inválidos conhecidos
+        if (preg_match('/(\d)\1{13}/', $cnpj)) {
+            return false;
+        }
+
+        // Valida primeiro dígito verificador
+        $length = strlen($cnpj) - 2;
+        $numbers = substr($cnpj, 0, $length);
+        $digits = substr($cnpj, $length);
+        $sum = 0;
+        $pos = $length - 7;
+
+        for ($i = $length; $i >= 1; $i--) {
+            $sum += $numbers[$length - $i] * $pos--;
+            if ($pos < 2) {
+                $pos = 9;
+            }
+        }
+
+        $result = $sum % 11 < 2 ? 0 : 11 - $sum % 11;
+
+        if ($result != $digits[0]) {
+            return false;
+        }
+
+        // Valida segundo dígito verificador
+        $length = $length + 1;
+        $numbers = substr($cnpj, 0, $length);
+        $sum = 0;
+        $pos = $length - 7;
+
+        for ($i = $length; $i >= 1; $i--) {
+            $sum += $numbers[$length - $i] * $pos--;
+            if ($pos < 2) {
+                $pos = 9;
+            }
+        }
+
+        $result = $sum % 11 < 2 ? 0 : 11 - $sum % 11;
+
+        if ($result != $digits[1]) {
+            return false;
+        }
+
+        return true;
+    }
+}

+ 37 - 0
app/Http/Resources/MediaResource.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use App\Models\Media;
+
+class MediaResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id' => $this->id,
+            'source' => $this->source,
+            'source_id' => $this->source_id,
+            'name' => $this->name,
+            'path' => $this->path,
+            'url' => $this->url,
+            'user_id' => $this->user_id,
+            'user' => $this->user,
+            'created_at' => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
+            'updated_at' => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),
+        ];
+    }
+
+    /**
+     * @param \Illuminate\Database\Eloquent\Collection<Media> $resource
+     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection<MediaResource>
+     */
+    public static function collection($resource): AnonymousResourceCollection
+    {
+        return parent::collection($resource);
+    }
+}

+ 46 - 0
app/Http/Resources/ProviderResource.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
+use App\Models\Provider;
+
+class ProviderResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id' => $this->id,
+            'document' => $this->document,
+            'rg' => $this->rg,
+            'user_id' => $this->user_id,
+            'user' => $this->user,
+            'average_rating' => $this->average_rating,
+            'total_services' => $this->total_services,
+            'birth_date' => $this->birth_date ? Carbon::parse($this->birth_date)->format('Y-m-d') : null,
+            'selfie_verified' => $this->selfie_verified,
+            'document_verified' => $this->document_verified,
+            'is_approved' => $this->is_approved,
+            'daily_price_8h' => $this->daily_price_8h,
+            'daily_price_6h' => $this->daily_price_6h,
+            'daily_price_4h' => $this->daily_price_4h,
+            'daily_price_2h' => $this->daily_price_2h,
+            'profile_media_id' => $this->profile_media_id,
+            'profile_media' => $this->profileMedia,
+            'created_at' => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
+            'updated_at' => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),
+        ];
+    }
+
+    /**
+     * @param \Illuminate\Database\Eloquent\Collection<Provider> $resource
+     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection<ProviderResource>
+     */
+    public static function collection($resource): AnonymousResourceCollection
+    {
+        return parent::collection($resource);
+    }
+}

+ 45 - 0
app/Models/Media.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * @property int $id
+ * @property string $source
+ * @property int $source_id
+ * @property string|null $name
+ * @property string $path
+ * @property string|null $url
+ * @property int|null $user_id
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @property \Illuminate\Support\Carbon|null $deleted_at
+ * @property-read \App\Models\User|null $user
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Media newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Media newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Media onlyTrashed()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Media query()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Media withTrashed(bool $withTrashed = true)
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Media withoutTrashed()
+ * @mixin \Eloquent
+ */
+class Media extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $table = "media";
+
+    protected $guarded = ["id"];
+
+    /**
+     * @return BelongsTo
+     */
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class, "user_id");
+    }
+}

+ 83 - 0
app/Models/Provider.php

@@ -0,0 +1,83 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * @property int $id
+ * @property string $document
+ * @property string|null $rg
+ * @property int $user_id
+ * @property float|null $average_rating
+ * @property int $total_services
+ * @property string|null $birth_date
+ * @property bool $selfie_verified
+ * @property bool $document_verified
+ * @property bool $is_approved
+ * @property float|null $daily_price_8h
+ * @property float|null $daily_price_6h
+ * @property float|null $daily_price_4h
+ * @property float|null $daily_price_2h
+ * @property int|null $profile_media_id
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @property \Illuminate\Support\Carbon|null $deleted_at
+ * @property-read \App\Models\User $user
+ * @property-read \App\Models\Media|null $profileMedia
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Provider newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Provider newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Provider onlyTrashed()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Provider query()
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Provider withTrashed(bool $withTrashed = true)
+ * @method static \Illuminate\Database\Eloquent\Builder<static>|Provider withoutTrashed()
+ * @mixin \Eloquent
+ */
+class Provider extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $table = "providers";
+
+    protected $guarded = ["id"];
+
+    /**
+     * Get the attributes that should be cast.
+     *
+     * @return array<string, string>
+     */
+    protected function casts(): array
+    {
+        return [
+            "birth_date" => "date",
+            "selfie_verified" => "boolean",
+            "document_verified" => "boolean",
+            "is_approved" => "boolean",
+            "average_rating" => "decimal:1",
+            "daily_price_8h" => "decimal:2",
+            "daily_price_6h" => "decimal:2",
+            "daily_price_4h" => "decimal:2",
+            "daily_price_2h" => "decimal:2",
+            "total_services" => "integer",
+        ];
+    }
+
+    /**
+     * @return BelongsTo
+     */
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class, "user_id");
+    }
+
+    /**
+     * @return BelongsTo
+     */
+    public function profileMedia(): BelongsTo
+    {
+        return $this->belongsTo(Media::class, "profile_media_id");
+    }
+}

+ 50 - 0
app/Services/MediaService.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\Media;
+use Illuminate\Database\Eloquent\Collection;
+
+class MediaService
+{
+    public function getAll(): Collection
+    {
+        return Media::query()
+            ->with(['user'])
+            ->orderBy("created_at", "desc")
+            ->get();
+    }
+
+    public function findById(int $id): ?Media
+    {
+        return Media::with(['user'])->find($id);
+    }
+
+    public function create(array $data): Media
+    {
+        return Media::create($data);
+    }
+
+    public function update(int $id, array $data): ?Media
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        $model->update($data);
+        return $model->fresh(['user']);
+    }
+
+    public function delete(int $id): bool
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return false;
+        }
+
+        return $model->delete();
+    }
+}

+ 50 - 0
app/Services/ProviderService.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Services;
+
+use App\Models\Provider;
+use Illuminate\Database\Eloquent\Collection;
+
+class ProviderService
+{
+    public function getAll(): Collection
+    {
+        return Provider::query()
+            ->with(['user', 'profileMedia'])
+            ->orderBy("created_at", "desc")
+            ->get();
+    }
+
+    public function findById(int $id): ?Provider
+    {
+        return Provider::with(['user', 'profileMedia'])->find($id);
+    }
+
+    public function create(array $data): Provider
+    {
+        return Provider::create($data);
+    }
+
+    public function update(int $id, array $data): ?Provider
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return null;
+        }
+
+        $model->update($data);
+        return $model->fresh(['user', 'profileMedia']);
+    }
+
+    public function delete(int $id): bool
+    {
+        $model = $this->findById($id);
+
+        if (!$model) {
+            return false;
+        }
+
+        return $model->delete();
+    }
+}

+ 31 - 0
database/migrations/2026_02_04_000001_create_media_table.php

@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::create('media', function (Blueprint $table) {
+            $table->id();
+            $table->string('source');
+            $table->integer('source_id');
+            $table->string('name')->nullable();
+            $table->text('path');
+            $table->text('url')->nullable();
+            $table->unsignedBigInteger('user_id')->nullable();
+            $table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
+            $table->timestamps();
+            $table->softDeletes();
+            
+            $table->index('user_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('media');
+    }
+};

+ 41 - 0
database/migrations/2026_02_04_000002_create_providers_table.php

@@ -0,0 +1,41 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    public function up(): void
+    {
+        Schema::create('providers', function (Blueprint $table) {
+            $table->id();
+            $table->string('document');
+            $table->string('rg')->nullable();
+            $table->unsignedBigInteger('user_id')->unique();
+            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
+            $table->decimal('average_rating', 2, 1)->nullable();
+            $table->integer('total_services')->default(0);
+            $table->date('birth_date')->nullable();
+            $table->boolean('selfie_verified')->default(false);
+            $table->boolean('document_verified')->default(false);
+            $table->boolean('is_approved')->default(false);
+            $table->decimal('daily_price_8h', 10, 2)->nullable();
+            $table->decimal('daily_price_6h', 10, 2)->nullable();
+            $table->decimal('daily_price_4h', 10, 2)->nullable();
+            $table->decimal('daily_price_2h', 10, 2)->nullable();
+            $table->unsignedBigInteger('profile_media_id')->nullable();
+            $table->foreign('profile_media_id')->references('id')->on('media')->onDelete('set null');
+            $table->timestamps();
+            $table->softDeletes();
+            
+            $table->index('document');
+            $table->index('user_id');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::dropIfExists('providers');
+    }
+};

+ 12 - 0
database/seeders/PermissionSeeder.php

@@ -70,6 +70,18 @@ class PermissionSeeder extends Seeder
                         "bits" => 271,
                         "children" => [],
                     ],
+                    [
+                        "scope" => "config.provider",
+                        "description" => "Configurações de Prestadores",
+                        "bits" => 271,
+                        "children" => [],
+                    ],
+                    [
+                        "scope" => "config.media",
+                        "description" => "Configurações de Mídia",
+                        "bits" => 271,
+                        "children" => [],
+                    ],
                 ],
             ],
         ];

+ 2 - 0
database/seeders/UserTypePermissionSeeder.php

@@ -34,6 +34,8 @@ class UserTypePermissionSeeder extends Seeder
                         ['scope' => 'config.city', 'bits' => 1],
                         ['scope' => 'config.country', 'bits' => 1],
                         ['scope' => 'config.state', 'bits' => 1],
+                        ['scope' => 'config.provider', 'bits' => 271],
+                        ['scope' => 'config.media', 'bits' => 271],
                     ];
                     $this->seedUserTypePermissions($userPermissions, UserTypeEnum::USER->value);
                     break;

+ 6 - 0
lang/en/validation.php

@@ -180,6 +180,12 @@ return [
         'attribute-name' => [
             'rule-name' => 'custom-message',
         ],
+        'document' => [
+            'invalid' => 'The CPF or CNPJ provided is invalid.',
+        ],
+        'user_id' => [
+            'already_linked_to_client' => 'This user is already linked to a client.',
+        ],
     ],
 
     /*

+ 6 - 0
lang/es/validation.php

@@ -180,6 +180,12 @@ return [
         'attribute-name' => [
             'rule-name' => 'mensaje-personalizado',
         ],
+        'document' => [
+            'invalid' => 'El CPF o CNPJ proporcionado es inválido.',
+        ],
+        'user_id' => [
+            'already_linked_to_client' => 'Este usuario ya está vinculado a un cliente.',
+        ],
     ],
 
     /*

+ 6 - 0
lang/pt/validation.php

@@ -181,6 +181,12 @@ return [
         'attribute-name' => [
             'rule-name' => 'mensagem-personalizada',
         ],
+        'document' => [
+            'invalid' => 'O CPF ou CNPJ informado é inválido.',
+        ],
+        'user_id' => [
+            'already_linked_to_client' => 'Este usuário já está vinculado a um cliente.',
+        ],
     ],
 
     /*

+ 14 - 0
routes/authRoutes/media.php

@@ -0,0 +1,14 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\MediaController;
+
+Route::get('/media', [MediaController::class, 'index'])->middleware('permission:config.media,view');
+
+Route::post('/media', [MediaController::class, 'store'])->middleware('permission:config.media,add');
+
+Route::get('/media/{id}', [MediaController::class, 'show'])->middleware('permission:config.media,view');
+
+Route::put('/media/{id}', [MediaController::class, 'update'])->middleware('permission:config.media,edit');
+
+Route::delete('/media/{id}', [MediaController::class, 'destroy'])->middleware('permission:config.media,delete');

+ 14 - 0
routes/authRoutes/provider.php

@@ -0,0 +1,14 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\ProviderController;
+
+Route::get('/provider', [ProviderController::class, 'index'])->middleware('permission:config.provider,view');
+
+Route::post('/provider', [ProviderController::class, 'store'])->middleware('permission:config.provider,add');
+
+Route::get('/provider/{id}', [ProviderController::class, 'show'])->middleware('permission:config.provider,view');
+
+Route::put('/provider/{id}', [ProviderController::class, 'update'])->middleware('permission:config.provider,edit');
+
+Route::delete('/provider/{id}', [ProviderController::class, 'destroy'])->middleware('permission:config.provider,delete');