Kaynağa Gözat

add the connections

gdias 2 hafta önce
ebeveyn
işleme
1aa413aa4e

+ 1 - 0
log.txt

@@ -0,0 +1 @@
+[2026-06-06 17:07:27] INFO: Database connection established {"host":"51.79.79.8","port":"15432","name":"nettown_db"}

+ 49 - 9
models/AnalyticsSentimentDashboardModel.php

@@ -16,7 +16,7 @@ class AnalyticsSentimentDashboardModel
     public function getDashboardData(int $companyId, array $queryParams): array
     {
         $filters = $this->normalizeFilters($queryParams);
-        $summaryRange = $this->resolveRange($filters['timeframe']);
+        $summaryRange = $this->resolveRange($filters);
 
         return [
             'summaryCards' => $this->getSummaryCards($companyId, $filters, $summaryRange),
@@ -33,7 +33,22 @@ class AnalyticsSentimentDashboardModel
     private function normalizeFilters(array $queryParams): array
     {
         $timeframe = strtolower(trim((string) ($queryParams['timeframe'] ?? 'week')));
-        if (!in_array($timeframe, ['day', 'week', 'month'], true)) {
+        if (!in_array($timeframe, ['day', 'week', 'month', 'custom'], true)) {
+            $timeframe = 'week';
+        }
+
+        // Intervalo personalizado: aceita start_date/end_date no formato YYYY-MM-DD.
+        // Se as datas forem válidas, o timeframe é tratado como "custom" mesmo que
+        // não tenha sido enviado explicitamente.
+        $customStart = $this->parseDate((string) ($queryParams['start_date'] ?? ''));
+        $customEnd = $this->parseDate((string) ($queryParams['end_date'] ?? ''));
+        if ($customStart !== null && $customEnd !== null) {
+            $timeframe = 'custom';
+            if ($customEnd < $customStart) {
+                [$customStart, $customEnd] = [$customEnd, $customStart];
+            }
+        } elseif ($timeframe === 'custom') {
+            // "custom" sem datas válidas cai para o padrão semanal.
             $timeframe = 'week';
         }
 
@@ -51,24 +66,49 @@ class AnalyticsSentimentDashboardModel
             'timeframe' => $timeframe,
             'sentiment' => $sentiment,
             'aspect' => $aspect !== null ? mb_strtolower($aspect) : null,
+            'custom_start' => $customStart,
+            'custom_end' => $customEnd,
         ];
     }
 
-    private function resolveRange(string $timeframe): array
+    private function parseDate(string $value): ?\DateTimeImmutable
+    {
+        $value = trim($value);
+        if ($value === '') {
+            return null;
+        }
+
+        $date = \DateTimeImmutable::createFromFormat('!Y-m-d', $value);
+        $errors = \DateTimeImmutable::getLastErrors();
+        if ($date === false || ($errors !== false && ($errors['warning_count'] > 0 || $errors['error_count'] > 0))) {
+            return null;
+        }
+
+        return $date;
+    }
+
+    private function resolveRange(array $filters): array
     {
         $today = new \DateTimeImmutable('today');
+        $timeframe = $filters['timeframe'];
 
-        if ($timeframe === 'day') {
-            $start = $today;
-        } elseif ($timeframe === 'month') {
-            $start = $today->modify('-29 days');
+        if ($timeframe === 'custom' && $filters['custom_start'] !== null && $filters['custom_end'] !== null) {
+            $start = $filters['custom_start'];
+            $end = $filters['custom_end'];
         } else {
-            $start = $today->modify('-6 days');
+            if ($timeframe === 'day') {
+                $start = $today;
+            } elseif ($timeframe === 'month') {
+                $start = $today->modify('-29 days');
+            } else {
+                $start = $today->modify('-6 days');
+            }
+            $end = $today;
         }
 
         return [
             'start_datetime' => $start->format('Y-m-d 00:00:00'),
-            'end_exclusive_datetime' => $today->modify('+1 day')->format('Y-m-d 00:00:00'),
+            'end_exclusive_datetime' => $end->modify('+1 day')->format('Y-m-d 00:00:00'),
         ];
     }
 

+ 20 - 3
models/EvolutionOverviewModel.php

@@ -16,7 +16,8 @@ class EvolutionOverviewModel
     public function getOverviewData(int $companyId, array $queryParams = []): array
     {
         $anchorDate = $this->getAnchorDate($companyId);
-        $range = $this->resolveRange($anchorDate);
+        $period = $this->normalizePeriod($queryParams);
+        $range = $this->resolveRange($anchorDate, $period);
         $sentimentSeries = $this->getSentimentSeries($companyId, $range);
         $playbooksSeries = $this->getPlaybooksSeries($companyId, $range);
         $playbooksTotals = $this->buildPlaybooksTotals($playbooksSeries);
@@ -63,9 +64,25 @@ class EvolutionOverviewModel
         return new \DateTimeImmutable($anchorDate);
     }
 
-    private function resolveRange(\DateTimeImmutable $anchorDate): array
+    private function normalizePeriod(array $queryParams): string
     {
-        $startDate = $anchorDate->modify('-6 days');
+        $period = strtolower(trim((string) ($queryParams['period'] ?? 'week')));
+        if (!in_array($period, ['week', 'month', 'quarter'], true)) {
+            $period = 'week';
+        }
+
+        return $period;
+    }
+
+    private function resolveRange(\DateTimeImmutable $anchorDate, string $period): array
+    {
+        if ($period === 'quarter') {
+            $startDate = $anchorDate->modify('-89 days');
+        } elseif ($period === 'month') {
+            $startDate = $anchorDate->modify('-29 days');
+        } else {
+            $startDate = $anchorDate->modify('-6 days');
+        }
 
         return [
             'start_date' => $startDate->format('Y-m-d'),

+ 8 - 4
public/index.php

@@ -6,10 +6,14 @@ use Routes\Dispatcher;
 
 require __DIR__ . '/../vendor/autoload.php';
 
-$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
-$file = __DIR__ . $path;
-if (php_sapi_name() === 'cli-server' && is_file($file)) {
-    return false;
+// Fallback para servir arquivos estáticos apenas no servidor embutido do PHP
+// (`php -S ... -t public`). Sob outros SAPIs (CLI / servidor do FrameworkX) não
+// existe REQUEST_URI, então só acessamos essa chave dentro do modo cli-server.
+if (php_sapi_name() === 'cli-server') {
+    $path = parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH);
+    if ($path !== null && $path !== '' && is_file(__DIR__ . $path)) {
+        return false;
+    }
 }
 
 if (class_exists(Dotenv\Dotenv::class) && file_exists(__DIR__ . '/../.env')) {