From 3aada9949d51024a92a8b5c6cb70d12f9c3cac16 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 21 Dec 2025 19:59:48 +0000
Subject: [PATCH] =auth refactored via rest, referral system set up for Jane, some javascript consolidation

---
 inc/managers/ErrorHandler.php |  190 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 137 insertions(+), 53 deletions(-)

diff --git a/inc/managers/ErrorHandler.php b/inc/managers/ErrorHandler.php
index add4eda..166229e 100644
--- a/inc/managers/ErrorHandler.php
+++ b/inc/managers/ErrorHandler.php
@@ -186,33 +186,61 @@
      *
      * @return bool Whether it gets logged successfully
      */
-    public function log(string $component, string $message, array $context = [], string $severity = 'error'):bool
-    {
-        try {
-            // Normal queue-based logging
-            JVB()->queue()->queueOperation(
-                'error_log',
-                get_current_user_id(),
-                [
-                    'component' => $component,
-                    'message' => $message,
-                    'context' => $context,
-                    'severity' => $severity
-                ],
-                ['priority' => 'high']
-            );
+	public function log(string $component, string $message, array $context = [], string $severity = 'error'): array
+	{
+		try {
+			$table = $this->wpdb->prefix . BASE . 'error_log';
 
+			// Validate severity
+			if (!array_key_exists($severity, $this->error_levels)) {
+				$severity = 'error';
+			}
 
-            // Immediate notification for critical errors
-            if ($severity === 'critical') {
-                $this->notifyAdmin($component, $message, $context);
-            }
-            return true;
-        } catch (Exception $e) {
-            error_log("[edmonton.ink Error] Failed to log error: " . $e->getMessage());
-            return false;
-        }
-    }
+			// Extract info
+			$error_type = sanitize_text_field($context['error_type'] ?? $component);
+			$method = isset($context['method']) ? sanitize_text_field($context['method']) : null;
+			$page_url = isset($context['url']) ? esc_url_raw($context['url']) : null;
+			$user_id = get_current_user_id();
+			$user_was_logged_in = $user_id > 0 || (!empty($context['isLoggedIn']));
+
+			// Determine source from context
+			$source = isset($context['source']) ? $context['source'] :
+				(isset($context['url']) ? 'frontend' : 'backend');
+
+			$result = $this->wpdb->insert(
+				$table,
+				[
+					'error_type' => $error_type,
+					'component' => $component,
+					'method' => $method,
+					'page_url' => $page_url,
+					'message' => sanitize_textarea_field($message),
+					'context' => json_encode($context),
+					'severity' => $severity,
+					'user_id' => $user_id ?: null,
+					'user_was_logged_in' => $user_was_logged_in ? 1 : 0,
+					'source' => $source,
+					'created_at' => current_time('mysql')
+				],
+				['%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%s']
+			);
+
+			if ($result === false) {
+				error_log("[ErrorHandler] Database insert failed: " . $this->wpdb->last_error);
+				return ['success' => false, 'message' => $this->wpdb->last_error];
+			}
+
+			if ($severity === 'critical') {
+				$this->checkErrorThreshold($error_type, $component);
+			}
+
+			return ['success' => true, 'id' => $this->wpdb->insert_id];
+
+		} catch (Exception $e) {
+			error_log("[ErrorHandler Exception] " . $e->getMessage());
+			return ['success' => false, 'message' => $e->getMessage()];
+		}
+	}
 
     /**
      * @param string $component What class or function logs the error
@@ -227,42 +255,96 @@
         $subject = "[edmonton.ink Critical Error] {$component}";
         $body = "Error: {$message}\n\nContext: " . print_r($context, true);
 
-        return jvbMail($admin_email, $subject, $body);
+        return JVB()->email()->sendEmail($admin_email, $subject, $body);
     }
 
     /**
      * Gather summary of the most important errors
+	 * @param ?string $start_date Defaults to today
+	 * @param ?string $end_date Defaults to today
      * @return array
      */
-    protected function gatherErrorSummary():array
-    {
-        $yesterday = date('Y-m-d H:i:s', strtotime('-24 hours'));
+	public function gatherErrorSummary(?string $start_date = null, ?string $end_date = null): array
+	{
+		$table = $this->wpdb->prefix . BASE . 'error_log';
 
-        // Get most frequent errors
-        $frequent_errors = $this->wpdb->get_results($this->wpdb->prepare(
-            "SELECT error_type, component, message, COUNT(*) as count
-             FROM {$this->tableName}
-             WHERE created_at > %s
-             GROUP BY error_type, component, message
-             ORDER BY count DESC
-             LIMIT 20",
-            $yesterday
-        ));
+		if (!$start_date) {
+			$start_date = gmdate('Y-m-d 00:00:00', strtotime('-1 day'));
+		}
+		if (!$end_date) {
+			$end_date = gmdate('Y-m-d 23:59:59');
+		}
 
-        // Get most recent critical errors
-        $critical_errors = $this->wpdb->get_results($this->wpdb->prepare(
-            "SELECT * FROM {$this->tableName}
-             WHERE severity = 'critical' AND created_at > %s
-             ORDER BY created_at DESC
-             LIMIT 5",
-            $yesterday
-        ));
+		// Most frequent error patterns (deduplicated by component/method/message)
+		$frequent = $this->wpdb->get_results($this->wpdb->prepare(
+			"SELECT
+            component,
+            method,
+            error_type,
+            message,
+            severity,
+            source,
+            COUNT(*) as count,
+            SUM(CASE WHEN user_was_logged_in = 1 THEN 1 ELSE 0 END) as logged_in_count,
+            SUM(CASE WHEN user_was_logged_in = 0 THEN 1 ELSE 0 END) as logged_out_count,
+            MIN(created_at) as first_seen,
+            MAX(created_at) as last_seen
+         FROM {$table}
+         WHERE created_at BETWEEN %s AND %s
+         GROUP BY component, method, error_type, message, severity, source
+         ORDER BY count DESC, severity DESC
+         LIMIT 10",
+			$start_date,
+			$end_date
+		));
 
-        return [
-            'frequent' => $frequent_errors,
-            'critical' => $critical_errors
-        ];
-    }
+		// Critical errors
+		$critical = $this->wpdb->get_results($this->wpdb->prepare(
+			"SELECT
+            component,
+            method,
+            error_type,
+            message,
+            source,
+            COUNT(*) as count,
+            SUM(CASE WHEN user_was_logged_in = 1 THEN 1 ELSE 0 END) as logged_in_count,
+            SUM(CASE WHEN user_was_logged_in = 0 THEN 1 ELSE 0 END) as logged_out_count,
+            MIN(created_at) as first_seen,
+            MAX(created_at) as last_seen
+         FROM {$table}
+         WHERE created_at BETWEEN %s AND %s AND severity = 'critical'
+         GROUP BY component, method, error_type, message, source
+         ORDER BY count DESC
+         LIMIT 5",
+			$start_date,
+			$end_date
+		));
+
+		// Overall stats
+		$stats = $this->wpdb->get_row($this->wpdb->prepare(
+			"SELECT
+            COUNT(*) as total_errors,
+            COUNT(DISTINCT CONCAT(component, '-', COALESCE(method, ''), '-', error_type)) as unique_error_types,
+            SUM(CASE WHEN user_was_logged_in = 1 THEN 1 ELSE 0 END) as logged_in_errors,
+            SUM(CASE WHEN user_was_logged_in = 0 THEN 1 ELSE 0 END) as logged_out_errors,
+            SUM(CASE WHEN source = 'frontend' THEN 1 ELSE 0 END) as frontend_errors,
+            SUM(CASE WHEN source = 'backend' THEN 1 ELSE 0 END) as backend_errors,
+            SUM(CASE WHEN severity = 'critical' THEN 1 ELSE 0 END) as critical_count,
+            SUM(CASE WHEN severity = 'error' THEN 1 ELSE 0 END) as error_count,
+            SUM(CASE WHEN severity = 'warning' THEN 1 ELSE 0 END) as warning_count
+         FROM {$table}
+         WHERE created_at BETWEEN %s AND %s",
+			$start_date,
+			$end_date
+		));
+
+		return [
+			'frequent' => $frequent,
+			'critical' => $critical,
+			'stats' => $stats,
+			'date_range' => ['start' => $start_date, 'end' => $end_date]
+		];
+	}
 
     /**
      * Send daily error summary email to administrator
@@ -330,7 +412,7 @@
         $body .= "View detailed error logs in the dashboard: {$admin_url}\n\n";
 
         // Send the email
-        $sent = jvbMail($admin_email, $subject, $body, 'ERROR SUMMARY');
+        $sent = JVB()->email()->sendEmail($admin_email, $subject, $body, 'ERROR SUMMARY');
 
         // Log that summary was sent
         if ($sent) {
@@ -426,6 +508,8 @@
 
     }
 
+
+
     protected function buildParams(WP_REST_Request $request):array {
         $allowedSeverity = [
             'all',

--
Gitblit v1.10.0