puyu-pe/sipro-internal-api-laravel

Laravel bridge package for the internal /internal/v1 API.

Maintainers

Package info

github.com/puyu-pe/sipro-internal-api-laravel

pkg:composer/puyu-pe/sipro-internal-api-laravel

Statistics

Installs: 9

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

1.0.2 2026-03-25 07:30 UTC

This package is auto-updated.

Last update: 2026-03-25 07:31:18 UTC


README

Bridge Laravel 12 para exponer /internal/v1 reutilizando puyu-pe/sipro-internal-api-core.

Integración en un SaaS Laravel 12

No requiere tocar bootstrap/app.php (usa package autodiscovery).

  1. Instalar paquete
composer require puyu-pe/sipro-internal-api-laravel
  1. Publicar configuración
php artisan vendor:publish --tag=sipro-internal-api-laravel-config
  1. Configurar llaves HMAC

En .env, define tus secretos y luego mapea keyId => secret en config/sipro-internal-api-laravel.php.

Ejemplo de enfoque:

'hmac' => [
    'keys' => [
        'saas-main' => env('SIPRO_INTERNAL_API_HMAC_SECRET_MAIN'),
        'saas-rotated' => env('SIPRO_INTERNAL_API_HMAC_SECRET_ROTATED'),
    ],
],
  1. Implementar adapters de tenant en tu SaaS

Skeleton sugerido:

<?php

declare(strict_types=1);

namespace App\InternalApi\Adapters;

use PuyuPe\SiproInternalApiCore\Contracts\Adapter\TenantCloneAdapterInterface;
use PuyuPe\SiproInternalApiCore\Contracts\Adapter\TenantLifecycleAdapterInterface;
use PuyuPe\SiproInternalApiCore\Contracts\Adapter\TenantProvisioningAdapterInterface;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\ProvisionPayloadDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\ProvisionResponseDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\TenantExportRequestDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\TenantExportResponseDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\TenantImportRequestDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\TenantImportResponseDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\TenantLifecycleRequestDTO;
use PuyuPe\SiproInternalApiCore\Contracts\Dto\TenantLifecycleResponseDTO;
use PuyuPe\SiproInternalApiLaravel\Exceptions\TenantAdapterException;

final class SaaSProvisioningAdapter implements TenantProvisioningAdapterInterface
{
    public function createTenant(ProvisionPayloadDTO $dto): ProvisionResponseDTO
    {
        // 1) Validar reglas de negocio de tu SaaS.
        // 2) Crear tenant en BD/sistemas.
        // 3) Retornar payload adicional para response.
        return new ProvisionResponseDTO(
            appKey: $dto->project->appKey ?? '',
            projectCode: $dto->project->code,
            database: 'db_name',
            status: 'created',
            provisionedAt: gmdate('c'),
            dbHost: null,
            migrated: false,
            seeded: false,
            systemParametersUpdated: false,
            usersCreated: 0,
            executionTimeMs: 0,
            warnings: []
        );
    }
}

final class SaaSLifecycleAdapter implements TenantLifecycleAdapterInterface
{
    public function warnTenant(string $appKey, TenantLifecycleRequestDTO $dto): TenantLifecycleResponseDTO
    {
        return new TenantLifecycleResponseDTO($appKey, $dto->projectCode, 'debt', 'D');
    }

    public function suspendTenant(string $appKey, TenantLifecycleRequestDTO $dto): TenantLifecycleResponseDTO
    {
        return new TenantLifecycleResponseDTO($appKey, $dto->projectCode, 'suspended', 'S');
    }

    public function activateTenant(string $appKey, TenantLifecycleRequestDTO $dto): TenantLifecycleResponseDTO
    {
        return new TenantLifecycleResponseDTO($appKey, $dto->projectCode, 'normal', 'N');
    }
}

final class SaaSCloneAdapter implements TenantCloneAdapterInterface
{
    public function exportTenant(string $appKey, TenantExportRequestDTO $dto): TenantExportResponseDTO
    {
        return new TenantExportResponseDTO($appKey, $dto->projectCode ?? '', 'exported', null, []);
    }

    public function importTenant(string $appKey, TenantImportRequestDTO $dto): TenantImportResponseDTO
    {
        return new TenantImportResponseDTO($appKey, $dto->projectCode ?? '', 'imported', null, []);
    }
}

Si necesitas utilidades para provisioning (crear BD, setear system params, etc.), puedes extender AbstractTenantProvisioningAdapter.

  1. Configurar adapters con el FQCN
'adapter' => [
    'provisioning_class' => env('SIPRO_INTERNAL_API_PROVISIONING_ADAPTER_CLASS', App\InternalApi\Adapters\SaaSProvisioningAdapter::class),
    'lifecycle_class' => env('SIPRO_INTERNAL_API_LIFECYCLE_ADAPTER_CLASS', App\InternalApi\Adapters\SaaSLifecycleAdapter::class),
    'clone_class' => env('SIPRO_INTERNAL_API_CLONE_ADAPTER_CLASS', App\InternalApi\Adapters\SaaSCloneAdapter::class),
],

En local/testing, si adapter.provisioning_class, adapter.lifecycle_class o adapter.clone_class está vacío, no existe o no implementa su interfaz, el package lanza una excepción clara al boot para facilitar diagnóstico temprano.

  1. Rutas disponibles
  • POST /internal/v1/tenants
  • POST /internal/v1/tenants/{appKey}:warn
  • POST /internal/v1/tenants/{appKey}:suspend
  • POST /internal/v1/tenants/{appKey}:activate
  • POST /internal/v1/tenants/{appKey}:export
  • POST /internal/v1/tenants/{appKey}:import