feat(tenant): separate admin and storefront website types

This commit is contained in:
2026-09-17 14:25:46 -03:00
parent b9b5f8ec9c
commit 6bc784519f
31 changed files with 325 additions and 143 deletions

View File

@@ -6,37 +6,37 @@ use App\Domains\Integration\Models\Integration;
use App\Domains\Integration\Requests\ConfigureIntegrationRequest;
use App\Domains\Integration\Resources\IntegrationAssociationResource;
use App\Domains\Integration\Services\IntegrationAssociationService;
use App\Domains\Tenant\Models\WebsiteType;
use App\Domains\Tenant\Models\AdminWebsiteType;
use App\Http\Controllers\Controller;
class WebsiteTypeIntegrationController extends Controller
class AdminWebsiteTypeIntegrationController extends Controller
{
public function __construct(private readonly IntegrationAssociationService $service) {}
public function index(WebsiteType $websiteType)
public function index(AdminWebsiteType $adminWebsiteType)
{
return IntegrationAssociationResource::collection($websiteType->integrations()->with('integrationInstance')->get());
return IntegrationAssociationResource::collection($adminWebsiteType->integrations()->with('integrationInstance')->get());
}
public function show(WebsiteType $websiteType, string $integrationCode)
public function show(AdminWebsiteType $adminWebsiteType, string $integrationCode)
{
return new IntegrationAssociationResource($websiteType->integrations()->with('integrationInstance')->where('integration_code', $integrationCode)->firstOrFail());
return new IntegrationAssociationResource($adminWebsiteType->integrations()->with('integrationInstance')->where('integration_code', $integrationCode)->firstOrFail());
}
public function store(ConfigureIntegrationRequest $request, WebsiteType $websiteType, string $integrationCode)
public function store(ConfigureIntegrationRequest $request, AdminWebsiteType $adminWebsiteType, string $integrationCode)
{
$integration = Integration::query()->where('integration_code', $integrationCode)->firstOrFail();
return new IntegrationAssociationResource($this->service->configure(
$websiteType,
$adminWebsiteType,
$integration,
$request->validated('integration_data'),
));
}
public function destroy(WebsiteType $websiteType, string $integrationCode)
public function destroy(AdminWebsiteType $adminWebsiteType, string $integrationCode)
{
$this->service->detach($websiteType, $integrationCode);
$this->service->detach($adminWebsiteType, $integrationCode);
return response()->noContent();
}

View File

@@ -2,18 +2,19 @@
namespace App\Domains\Integration\Models;
use App\Domains\Tenant\Models\WebsiteType;
use App\Domains\Tenant\Models\AdminWebsiteType;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class WebsiteTypeIntegration extends Model
class AdminWebsiteTypeIntegration extends Model
{
protected $fillable = ['website_type_code', 'integration_code', 'integration_instance_id'];
protected $table = 'admin_website_type_integrations';
protected $fillable = ['admin_website_type_code', 'integration_code', 'integration_instance_id'];
/** @return BelongsTo<WebsiteType, $this> */
public function websiteType(): BelongsTo
/** @return BelongsTo<AdminWebsiteType, $this> */
public function adminWebsiteType(): BelongsTo
{
return $this->belongsTo(WebsiteType::class, 'website_type_code', 'codigo');
return $this->belongsTo(AdminWebsiteType::class, 'admin_website_type_code', 'codigo');
}
/** @return BelongsTo<Integration, $this> */

View File

@@ -34,9 +34,9 @@ class Integration extends Model
return $this->hasMany(ClientIntegration::class, 'integration_code', 'integration_code');
}
/** @return HasMany<WebsiteTypeIntegration, $this> */
/** @return HasMany<AdminWebsiteTypeIntegration, $this> */
public function websiteTypeIntegrations(): HasMany
{
return $this->hasMany(WebsiteTypeIntegration::class, 'integration_code', 'integration_code');
return $this->hasMany(AdminWebsiteTypeIntegration::class, 'integration_code', 'integration_code');
}
}

View File

@@ -33,9 +33,9 @@ class IntegrationInstance extends Model
return $this->hasMany(ClientIntegration::class);
}
/** @return HasMany<WebsiteTypeIntegration, $this> */
/** @return HasMany<AdminWebsiteTypeIntegration, $this> */
public function websiteTypeIntegrations(): HasMany
{
return $this->hasMany(WebsiteTypeIntegration::class);
return $this->hasMany(AdminWebsiteTypeIntegration::class);
}
}

View File

@@ -12,7 +12,7 @@ class IntegrationAssociationResource extends JsonResource
return [
'id' => $this->id,
'client_id' => $this->when(isset($this->client_id), $this->client_id),
'website_type_code' => $this->when(isset($this->website_type_code), $this->website_type_code),
'admin_website_type_code' => $this->when(isset($this->admin_website_type_code), $this->admin_website_type_code),
'integration_code' => $this->integration_code,
'integration_instance_id' => $this->integration_instance_id,
'integration_instance' => new IntegrationInstanceResource($this->whenLoaded('integrationInstance')),

View File

@@ -6,7 +6,7 @@ use App\Domains\Client\Models\Client;
use App\Domains\Integration\Models\ClientIntegration;
use App\Domains\Integration\Models\Integration;
use App\Domains\Integration\Models\IntegrationInstance;
use App\Domains\Integration\Models\WebsiteTypeIntegration;
use App\Domains\Integration\Models\AdminWebsiteTypeIntegration;
use App\Domains\Tenant\Models\Tenant;
use Exception;
use Illuminate\Http\Client\PendingRequest;
@@ -111,9 +111,9 @@ abstract class BaseIntegrationService
->where('integration_code', $this->integrationCode)
->first()?->integrationInstance;
if (! $this->integrationInstance && $this->tenant?->website_type_code) {
$this->integrationInstance = WebsiteTypeIntegration::with('integrationInstance')
->where('website_type_code', $this->tenant->website_type_code)
if (! $this->integrationInstance && $this->tenant?->admin_website_type_code) {
$this->integrationInstance = AdminWebsiteTypeIntegration::with('integrationInstance')
->where('admin_website_type_code', $this->tenant->admin_website_type_code)
->where('integration_code', $this->integrationCode)
->first()?->integrationInstance;
}

View File

@@ -6,15 +6,15 @@ use App\Domains\Client\Models\Client;
use App\Domains\Integration\Models\ClientIntegration;
use App\Domains\Integration\Models\Integration;
use App\Domains\Integration\Models\IntegrationInstance;
use App\Domains\Integration\Models\WebsiteTypeIntegration;
use App\Domains\Tenant\Models\WebsiteType;
use App\Domains\Integration\Models\AdminWebsiteTypeIntegration;
use App\Domains\Tenant\Models\AdminWebsiteType;
use Illuminate\Support\Facades\DB;
class IntegrationAssociationService
{
public function configure(Client|WebsiteType $owner, Integration $integration, array $integrationData): ClientIntegration|WebsiteTypeIntegration
public function configure(Client|AdminWebsiteType $owner, Integration $integration, array $integrationData): ClientIntegration|AdminWebsiteTypeIntegration
{
return DB::transaction(function () use ($owner, $integration, $integrationData): ClientIntegration|WebsiteTypeIntegration {
return DB::transaction(function () use ($owner, $integration, $integrationData): ClientIntegration|AdminWebsiteTypeIntegration {
$instance = IntegrationInstance::create([
'integration_code' => $integration->integration_code,
'name' => $integration->name.' / '.$this->ownerName($owner),
@@ -25,9 +25,9 @@ class IntegrationAssociationService
});
}
public function associate(Client|WebsiteType $owner, string $code, IntegrationInstance $instance): ClientIntegration|WebsiteTypeIntegration
public function associate(Client|AdminWebsiteType $owner, string $code, IntegrationInstance $instance): ClientIntegration|AdminWebsiteTypeIntegration
{
return DB::transaction(function () use ($owner, $code, $instance): ClientIntegration|WebsiteTypeIntegration {
return DB::transaction(function () use ($owner, $code, $instance): ClientIntegration|AdminWebsiteTypeIntegration {
$association = $owner->integrations()
->where('integration_code', $code)
->lockForUpdate()
@@ -62,7 +62,7 @@ class IntegrationAssociationService
});
}
public function detach(Client|WebsiteType $owner, string $code): void
public function detach(Client|AdminWebsiteType $owner, string $code): void
{
DB::transaction(function () use ($owner, $code): void {
$association = $owner->integrations()
@@ -91,7 +91,7 @@ class IntegrationAssociationService
}
}
private function ownerName(Client|WebsiteType $owner): string
private function ownerName(Client|AdminWebsiteType $owner): string
{
return $owner instanceof Client ? $owner->name : $owner->nombre;
}

View File

@@ -4,7 +4,7 @@ namespace App\Domains\Integration\Services;
use App\Domains\Client\Models\Client;
use App\Domains\Tenant\Models\Tenant;
use App\Domains\Tenant\Models\WebsiteType;
use App\Domains\Tenant\Models\AdminWebsiteType;
use Exception;
use Illuminate\Contracts\Mail\Factory as MailFactory;
use Illuminate\Contracts\Mail\Mailer;
@@ -79,7 +79,7 @@ class MailService extends BaseIntegrationService
string|array $recipient,
string $subject,
string $content,
Tenant|WebsiteType|null $brand = null,
Tenant|AdminWebsiteType|null $brand = null,
array $attachments = [],
): void {
if (! $this->mailer || ! $this->tenant) {
@@ -97,7 +97,7 @@ class MailService extends BaseIntegrationService
BLADE,
[
'branding' => $branding,
'headerLogoUrl' => $brand instanceof WebsiteType
'headerLogoUrl' => $brand instanceof AdminWebsiteType
? $brand->siteLogo?->getTemporaryUrl(1440)
: $brand->headerLogo?->getTemporaryUrl(1440),
'footerLogoUrl' => $brand->footerLogo?->getTemporaryUrl(1440),
@@ -128,9 +128,9 @@ class MailService extends BaseIntegrationService
}
/** @return array{name: string, primary_color: string, body_color: string, background_color: string, surface_color: string, header_bg_color: string, footer_bg_color: string} */
private function brandingFor(Tenant|WebsiteType $brand): array
private function brandingFor(Tenant|AdminWebsiteType $brand): array
{
if ($brand instanceof WebsiteType) {
if ($brand instanceof AdminWebsiteType) {
$brand->loadMissing(['siteLogo', 'footerLogo']);
return [

View File

@@ -2,16 +2,16 @@
use App\Domains\Integration\Controllers\ClientIntegrationController;
use App\Domains\Integration\Controllers\TelepagosWebhookController;
use App\Domains\Integration\Controllers\WebsiteTypeIntegrationController;
use App\Domains\Integration\Controllers\AdminWebsiteTypeIntegrationController;
use App\Domains\Integration\Models\Integration;
use Illuminate\Support\Facades\Route;
Route::middleware(['auth:sanctum', 'can:manage,'.Integration::class])->group(function (): void {
Route::prefix('website-types/{websiteType:codigo}/integrations')->group(function (): void {
Route::get('/', [WebsiteTypeIntegrationController::class, 'index']);
Route::get('/{integration_code}', [WebsiteTypeIntegrationController::class, 'show']);
Route::put('/{integration_code}', [WebsiteTypeIntegrationController::class, 'store']);
Route::delete('/{integration_code}', [WebsiteTypeIntegrationController::class, 'destroy']);
Route::prefix('admin-website-types/{adminWebsiteType:codigo}/integrations')->group(function (): void {
Route::get('/', [AdminWebsiteTypeIntegrationController::class, 'index']);
Route::get('/{integration_code}', [AdminWebsiteTypeIntegrationController::class, 'show']);
Route::put('/{integration_code}', [AdminWebsiteTypeIntegrationController::class, 'store']);
Route::delete('/{integration_code}', [AdminWebsiteTypeIntegrationController::class, 'destroy']);
});
Route::group(['prefix' => 'clients/{client}/integrations'], function () {