8 Commits a41c089525 ... 63b203a4d0

Autor SHA1 Mensaje Fecha
  Ranghetti 63b203a4d0 Merge branch 'main' into feature-monitoramento hace 2 semanas
  Ranghetti 78c0a9444f Configurações Docker hace 2 semanas
  Ranghetti 4ddcc5c0ba Lista de monitramento do oorderbook apenas quando preview hace 2 semanas
  Ranghetti 18ba04ca61 Rotina para listar o monitoramento a partir das ordens hace 1 mes
  Ranghetti 4d9fc45029 Ajuste de percistencia do campo preview hace 1 mes
  Ranghetti 39be6423d9 Ajuste na nomenclatura hace 1 mes
  Ranghetti 7dce1bb5fe Ajuste na nomenclatura hace 1 mes
  Ranghetti 81eeb1fe72 implementação do crud para cpr monitoring e configuração para rodar via docker hace 1 mes

+ 7 - 0
.dockerignore

@@ -0,0 +1,7 @@
+.env
+.env.*
+**/.env
+**/.env.*
+
+build
+*.deb

+ 27 - 0
Dockerfile

@@ -0,0 +1,27 @@
+FROM php:8.2-cli
+
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends \
+        git \
+        unzip \
+        bash \
+        sed \
+        libpq-dev \
+        postgresql-client \
+    && docker-php-ext-install pdo_pgsql \
+    && rm -rf /var/lib/apt/lists/*
+
+COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
+
+WORKDIR /app
+
+COPY composer.json composer.lock* ./
+RUN composer install --no-interaction --no-progress
+
+COPY . .
+
+RUN rm -f /app/.env || true
+
+RUN chmod +x /app/bin/setup || true
+
+CMD ["bash", "-lc", "sed -i 's/\r$//' /app/bin/setup && chmod +x /app/bin/setup && /app/bin/setup && php /app/public/index.php"]

+ 61 - 0
controllers/CprMonitoringCreateController.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Exceptions\ValidationException;
+use Respect\Validation\Validator as val;
+use Services\CprMonitoringService;
+
+class CprMonitoringCreateController
+{
+    private CprMonitoringService $service;
+
+    public function __construct()
+    {
+        $this->service = new CprMonitoringService();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $userId = (int)($request->getAttribute('api_user_id') ?? 0);
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+
+        if ($userId <= 0 || $companyId <= 0) {
+            return ResponseLib::sendFail('Unauthorized', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            val::key('cpr_id', val::intType()->positive())
+                ->key('description', val::stringType()->notEmpty()->length(1, 5000))
+                ->key('link', val::stringType()->notEmpty()->length(1, 2048))
+                ->key('preview', val::boolType(), false)
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail('Validation failed: ' . $e->getFullMessage(), [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        $cprId = (int)$body['cpr_id'];
+        $preview = isset($body['preview']) ? (bool)$body['preview'] : false;
+        $description = (string)$body['description'];
+        $link = (string)$body['link'];
+
+        try {
+            $created = $this->service->create($cprId, $preview, $description, $link);
+        } catch (\InvalidArgumentException $e) {
+            return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400);
+        } catch (\PDOException $e) {
+            if (($e->getCode() ?? '') === '23503') {
+                return ResponseLib::sendFail('CPR not found', ['cpr_id' => $cprId], 'E_NOT_FOUND')->withStatus(404);
+            }
+            return ResponseLib::sendFail('Failed to create cpr monitoring: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to create cpr monitoring: ' . $e->getMessage(), [], 'E_INTERNAL')->withStatus(500);
+        }
+
+        return ResponseLib::sendOk($created, 'S_CREATED');
+    }
+}

+ 53 - 0
controllers/CprMonitoringDeleteController.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Exceptions\ValidationException;
+use Respect\Validation\Validator as val;
+
+use Services\CprMonitoringService;
+
+class CprMonitoringDeleteController
+{
+    private CprMonitoringService $service;
+
+    public function __construct()
+    {
+        $this->service = new CprMonitoringService();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $userId = (int)($request->getAttribute('api_user_id') ?? 0);
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+
+        if ($userId <= 0 || $companyId <= 0) {
+            return ResponseLib::sendFail('Unauthorized', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            val::key('id', val::intType()->positive())
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail('Validation failed: ' . $e->getFullMessage(), [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        $id = (int)$body['id'];
+
+        try {
+            $deleted = $this->service->delete($id);
+        } catch (\InvalidArgumentException $e) {
+            return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to delete cpr monitoring: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        return $deleted
+            ? ResponseLib::sendOk(['deleted' => true], 'S_DELETED')
+            : ResponseLib::sendFail('Cpr monitoring Not Found', [], 'E_DATABASE')->withStatus(204);
+    }
+}

+ 52 - 0
controllers/CprMonitoringGetController.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Exceptions\ValidationException;
+use Respect\Validation\Validator as val;
+use Services\CprMonitoringService;
+
+class CprMonitoringGetController
+{
+    private CprMonitoringService $service;
+
+    public function __construct()
+    {
+        $this->service = new CprMonitoringService();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $userId = (int)($request->getAttribute('api_user_id') ?? 0);
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+
+        if ($userId <= 0 || $companyId <= 0) {
+            return ResponseLib::sendFail('Unauthorized', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            val::key('id', val::intType()->positive())
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail('Validation failed: ' . $e->getFullMessage(), [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        $id = (int)$body['id'];
+
+        try {
+            $row = $this->service->getById($id);
+        } catch (\InvalidArgumentException $e) {
+            return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to fetch cpr monitoring: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        return $row
+            ? ResponseLib::sendOk($row)
+            : ResponseLib::sendFail('Cpr monitoring not found', [], 'E_NOT_FOUND')->withStatus(404);
+    }
+}

+ 52 - 0
controllers/CprMonitoringListController.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Exceptions\ValidationException;
+use Respect\Validation\Validator as val;
+use Services\CprMonitoringService;
+
+class CprMonitoringListController
+{
+    private CprMonitoringService $service;
+
+    public function __construct()
+    {
+        $this->service = new CprMonitoringService();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $userId = (int)($request->getAttribute('api_user_id') ?? 0);
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+
+        if ($userId <= 0 || $companyId <= 0) {
+            return ResponseLib::sendFail('Unauthorized', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            val::key('cpr_id', val::intType()->positive())
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail('Validation failed: ' . $e->getFullMessage(), [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        $cprId = (int)$body['cpr_id'];
+
+        try {
+            $rows = $this->service->listByCprId($cprId);
+        } catch (\InvalidArgumentException $e) {
+            return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to list cpr monitoring: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        return $rows
+            ? ResponseLib::sendOk($rows)
+            : ResponseLib::sendFail('Cpr monitoring not found', [], 'E_DATABASE')->withStatus(204);
+    }
+}

+ 62 - 0
controllers/CprMonitoringUpdateController.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Exceptions\ValidationException;
+use Respect\Validation\Validator as val;
+use Services\CprMonitoringService;
+
+class CprMonitoringUpdateController
+{
+    private CprMonitoringService $service;
+
+    public function __construct()
+    {
+        $this->service = new CprMonitoringService();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $userId = (int)($request->getAttribute('api_user_id') ?? 0);
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+
+        if ($userId <= 0 || $companyId <= 0) {
+            return ResponseLib::sendFail('Unauthorized', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            val::key('id', val::intType()->positive())
+                ->key('preview', val::optional(val::boolType()), false)
+                ->key('description', val::optional(val::stringType()->notEmpty()->length(1, 5000)), false)
+                ->key('link', val::optional(val::stringType()->notEmpty()->length(1, 2048)), false)
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail('Validation failed: ' . $e->getFullMessage(), [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        $id = (int)$body['id'];
+        $preview = array_key_exists('preview', $body) ? (bool)$body['preview'] : null;
+        $description = array_key_exists('description', $body) ? (string)$body['description'] : null;
+        $link = array_key_exists('link', $body) ? (string)$body['link'] : null;
+
+        if ($preview === null && $description === null && $link === null) {
+            return ResponseLib::sendFail('Validation failed: nothing to update', [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        try {
+            $updated = $this->service->update($id, $preview, $description, $link);
+        } catch (\InvalidArgumentException $e) {
+            return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400);
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to update cpr monitoring: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        return $updated
+            ? ResponseLib::sendOk($updated, 'S_UPDATED')
+            : ResponseLib::sendFail('Cpr monitoring Not Found or Not Updated', [], 'E_DATABASE')->withStatus(204);
+    }
+}

+ 85 - 0
controllers/OrderbookCprMonitoringListController.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Models\CprMonitoringModel;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Exceptions\ValidationException;
+use Respect\Validation\Validator as val;
+
+class OrderbookCprMonitoringListController
+{
+    private \PDO $pdo;
+    private CprMonitoringModel $monitoringModel;
+
+    public function __construct()
+    {
+        if (!isset($GLOBALS['pdo']) || !$GLOBALS['pdo'] instanceof \PDO) {
+            throw new \RuntimeException('Global PDO connection not initialized');
+        }
+
+        $this->pdo = $GLOBALS['pdo'];
+        $this->monitoringModel = new CprMonitoringModel();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $userId = (int)($request->getAttribute('api_user_id') ?? 0);
+        $companyId = (int)($request->getAttribute('api_company_id') ?? 0);
+
+        if ($userId <= 0 || $companyId <= 0) {
+            return ResponseLib::sendFail('Unauthorized', [], 'E_VALIDATE')->withStatus(401);
+        }
+
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            val::key('orderbook_id', val::intType()->positive())
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail('Validation failed: ' . $e->getFullMessage(), [], 'E_VALIDATE')->withStatus(400);
+        }
+
+        $orderbookId = (int)$body['orderbook_id'];
+
+        try {
+            $stmt = $this->pdo->prepare(
+                'SELECT
+                    t.cpr_id,
+                    w.company_id AS wallet_company_id
+                 FROM "orderbook" o
+                 LEFT JOIN "token" t ON t.token_id = o.token_id
+                 LEFT JOIN "wallet" w ON w.wallet_id = o.wallet_id
+                 WHERE o.orderbook_id = :orderbook_id
+                 LIMIT 1'
+            );
+            $stmt->execute(['orderbook_id' => $orderbookId]);
+            $row = $stmt->fetch(\PDO::FETCH_ASSOC) ?: null;
+
+            $cprId = (int)($row['cpr_id'] ?? 0);
+            $walletCompanyId = (int)($row['wallet_company_id'] ?? 0);
+
+            if ($cprId <= 0) {
+                return ResponseLib::sendFail('CPR not found for orderbook', ['orderbook_id' => $orderbookId], 'E_NOT_FOUND')->withStatus(404);
+            }
+
+            if ($walletCompanyId <= 0) {
+                return ResponseLib::sendFail('Wallet not found for orderbook', ['orderbook_id' => $orderbookId], 'E_NOT_FOUND')->withStatus(404);
+            }
+
+            if ($companyId !== 1 && $walletCompanyId !== $companyId) {
+                return ResponseLib::sendFail('Forbidden', [], 'E_FORBIDDEN')->withStatus(403);
+            }
+
+            $rows = $this->monitoringModel->listByCprIdPreviewOnly($cprId);
+
+        } catch (\Throwable $e) {
+            return ResponseLib::sendFail('Failed to list cpr monitoring: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
+        }
+
+        return $rows
+            ? ResponseLib::sendOk($rows)
+            : ResponseLib::sendFail('Cpr monitoring not found', [], 'E_DATABASE')->withStatus(204);
+    }
+}

+ 27 - 0
migrations/20260328_add_cpr_monitoring_table.sql

@@ -0,0 +1,27 @@
+BEGIN;
+
+CREATE TABLE IF NOT EXISTS "cpr_monitoring" (
+  "cpr_monitoring_id" SERIAL PRIMARY KEY,
+  "cpr_id" INTEGER NOT NULL,
+  "cpr_monitoring_preview" BOOLEAN NOT NULL DEFAULT FALSE,
+  "cpr_monitoring_description" TEXT NOT NULL,
+  "cpr_monitoring_link" TEXT NOT NULL
+);
+
+DO $$
+BEGIN
+  IF NOT EXISTS (
+    SELECT 1
+    FROM pg_constraint
+    WHERE conname = 'cpr_monitoring_cpr_id_fkey'
+  ) THEN
+    ALTER TABLE "cpr_monitoring"
+      ADD CONSTRAINT cpr_monitoring_cpr_id_fkey
+      FOREIGN KEY ("cpr_id") REFERENCES "cpr"("cpr_id")
+      ON DELETE CASCADE;
+  END IF;
+END $$;
+
+CREATE INDEX IF NOT EXISTS idx_cpr_monitoring_cpr_id ON "cpr_monitoring"("cpr_id");
+
+COMMIT;

+ 156 - 0
models/CprMonitoringModel.php

@@ -0,0 +1,156 @@
+<?php
+
+namespace Models;
+
+class CprMonitoringModel
+{
+    private \PDO $pdo;
+
+    public function __construct()
+    {
+        if (!isset($GLOBALS['pdo']) || !$GLOBALS['pdo'] instanceof \PDO) {
+            throw new \RuntimeException('Global PDO connection not initialized');
+        }
+
+        $this->pdo = $GLOBALS['pdo'];
+    }
+
+    public function getById(int $id): ?array
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT
+                cpr_monitoring_id AS id,
+                cpr_id,
+                cpr_monitoring_preview AS preview,
+                cpr_monitoring_description AS description,
+                cpr_monitoring_link AS link
+             FROM "cpr_monitoring"
+             WHERE cpr_monitoring_id = :id
+             LIMIT 1'
+        );
+        $stmt->execute(['id' => $id]);
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+        return $row ?: null;
+    }
+
+    public function listByCprId(int $cprId): array
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT
+                cpr_monitoring_id AS id,
+                cpr_id,
+                cpr_monitoring_preview AS preview,
+                cpr_monitoring_description AS description,
+                cpr_monitoring_link AS link
+             FROM "cpr_monitoring"
+             WHERE cpr_id = :cpr_id
+             ORDER BY cpr_monitoring_id DESC'
+        );
+        $stmt->execute(['cpr_id' => $cprId]);
+
+        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
+    }
+
+    public function listByCprIdPreviewOnly(int $cprId): array
+    {
+        $stmt = $this->pdo->prepare(
+            'SELECT
+                cpr_monitoring_id AS id,
+                cpr_id,
+                cpr_monitoring_preview AS preview,
+                cpr_monitoring_description AS description,
+                cpr_monitoring_link AS link
+             FROM "cpr_monitoring"
+             WHERE cpr_id = :cpr_id
+               AND cpr_monitoring_preview = TRUE
+             ORDER BY cpr_monitoring_id DESC'
+        );
+        $stmt->execute(['cpr_id' => $cprId]);
+
+        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
+    }
+
+    public function create(int $cprId, bool $preview, string $description, string $link): array
+    {
+        $stmt = $this->pdo->prepare(
+            'INSERT INTO "cpr_monitoring" (
+                cpr_id,
+                cpr_monitoring_preview,
+                cpr_monitoring_description,
+                cpr_monitoring_link
+             )
+             VALUES (:cpr_id, :preview, :description, :link)
+             RETURNING cpr_monitoring_id'
+        );
+
+        $stmt->bindValue(':cpr_id', $cprId, \PDO::PARAM_INT);
+        $stmt->bindValue(':preview', $preview, \PDO::PARAM_BOOL);
+        $stmt->bindValue(':description', $description, \PDO::PARAM_STR);
+        $stmt->bindValue(':link', $link, \PDO::PARAM_STR);
+
+        $stmt->execute();
+
+        $id = (int)$stmt->fetchColumn();
+
+        return [
+            'id' => $id,
+            'cpr_id' => $cprId,
+            'preview' => $preview,
+            'description' => $description,
+            'link' => $link,
+        ];
+    }
+
+    public function update(int $id, ?bool $preview = null, ?string $description = null, ?string $link = null): ?array
+    {
+        $fields = [];
+        $params = ['id' => $id];
+
+        if ($preview !== null) {
+            $fields[] = 'cpr_monitoring_preview = :preview';
+            $params['preview'] = $preview;
+        }
+        if ($description !== null) {
+            $fields[] = 'cpr_monitoring_description = :description';
+            $params['description'] = $description;
+        }
+        if ($link !== null) {
+            $fields[] = 'cpr_monitoring_link = :link';
+            $params['link'] = $link;
+        }
+
+        if (!$fields) {
+            return null;
+        }
+
+        $sql = 'UPDATE "cpr_monitoring" SET ' . implode(', ', $fields) . ' WHERE cpr_monitoring_id = :id';
+        $stmt = $this->pdo->prepare($sql);
+
+        $stmt->bindValue(':id', $id, \PDO::PARAM_INT);
+        if (array_key_exists('preview', $params)) {
+            $stmt->bindValue(':preview', $params['preview'], \PDO::PARAM_BOOL);
+        }
+        if (array_key_exists('description', $params)) {
+            $stmt->bindValue(':description', $params['description'], \PDO::PARAM_STR);
+        }
+        if (array_key_exists('link', $params)) {
+            $stmt->bindValue(':link', $params['link'], \PDO::PARAM_STR);
+        }
+
+        $ok = $stmt->execute();
+        if (!$ok) {
+            return null;
+        }
+
+        return $this->getById($id);
+    }
+
+    public function delete(int $id): bool
+    {
+        $stmt = $this->pdo->prepare('DELETE FROM "cpr_monitoring" WHERE cpr_monitoring_id = :id');
+        $stmt->execute(['id' => $id]);
+
+        return $stmt->rowCount() > 0;
+    }
+}

+ 8 - 0
public/index.php

@@ -89,6 +89,7 @@ $app->post('/orderbook/filter', $authJwt, \Controllers\OrderbookFilterController
 $app->post('/orderbook/payment', $authJwt, \Controllers\OrderbookPaymentController::class);
 $app->post('/orderbook/cancel', $authJwt, \Controllers\OrderbookUpdateStatusController::class);
 $app->post('/orderbook/transfer', $authJwt, \Controllers\OrderbookTransferController::class);
+$app->post('/orderbook/monitoring/list', $authJwt, \Controllers\OrderbookCprMonitoringListController::class);
 $app->post('/harvest/list', $authJwt, \Controllers\HarvestListController::class);
 
 // Documents (JWT-protected)
@@ -105,4 +106,11 @@ $app->post('/b3/cpr/register', $authJwt, $onlyCompany1Or2, \Controllers\B3CprReg
 $app->post('/b3/payment/confirm', $authJwt, \Controllers\PaymentConfirmController::class);
 $app->post('/cpr/fast-track', \Controllers\CprFastTrackController::class);
 
+// CPR monitoring
+$app->post('/cpr/monitoring/create', $authJwt, \Controllers\CprMonitoringCreateController::class);
+$app->post('/cpr/monitoring/get', $authJwt, \Controllers\CprMonitoringGetController::class);
+$app->post('/cpr/monitoring/list', $authJwt, \Controllers\CprMonitoringListController::class);
+$app->post('/cpr/monitoring/update', $authJwt, \Controllers\CprMonitoringUpdateController::class);
+$app->post('/cpr/monitoring/delete', $authJwt, \Controllers\CprMonitoringDeleteController::class);
+
 $app->run();

+ 85 - 0
services/CprMonitoringService.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace Services;
+
+use Models\CprMonitoringModel;
+
+class CprMonitoringService
+{
+    private CprMonitoringModel $model;
+
+    public function __construct()
+    {
+        $this->model = new CprMonitoringModel();
+    }
+
+    public function create(int $cprId, bool $preview, string $description, string $link): array
+    {
+        if ($cprId <= 0) {
+            throw new \InvalidArgumentException('Invalid cpr_id');
+        }
+
+        $description = trim($description);
+        $link = trim($link);
+
+        if ($description === '') {
+            throw new \InvalidArgumentException('Invalid description');
+        }
+
+        if ($link === '') {
+            throw new \InvalidArgumentException('Invalid link');
+        }
+
+        return $this->model->create($cprId, $preview, $description, $link);
+    }
+
+    public function getById(int $id): ?array
+    {
+        if ($id <= 0) {
+            throw new \InvalidArgumentException('Invalid id');
+        }
+
+        return $this->model->getById($id);
+    }
+
+    public function listByCprId(int $cprId): array
+    {
+        if ($cprId <= 0) {
+            throw new \InvalidArgumentException('Invalid cpr_id');
+        }
+
+        return $this->model->listByCprId($cprId);
+    }
+
+    public function update(int $id, ?bool $preview = null, ?string $description = null, ?string $link = null): ?array
+    {
+        if ($id <= 0) {
+            throw new \InvalidArgumentException('Invalid id');
+        }
+
+        if ($description !== null) {
+            $description = trim($description);
+            if ($description === '') {
+                throw new \InvalidArgumentException('Invalid description');
+            }
+        }
+
+        if ($link !== null) {
+            $link = trim($link);
+            if ($link === '') {
+                throw new \InvalidArgumentException('Invalid link');
+            }
+        }
+
+        return $this->model->update($id, $preview, $description, $link);
+    }
+
+    public function delete(int $id): bool
+    {
+        if ($id <= 0) {
+            throw new \InvalidArgumentException('Invalid id');
+        }
+
+        return $this->model->delete($id);
+    }
+}