Skip to content

Documentation

Dashboard System Architecture

Comprehensive guide to the SveltyCMS dashboard system including widget architecture, customization, and audit log monitoring.

6/15/2026
19 min read Edit on GitHub

The SveltyCMS dashboard provides a powerful, customizable monitoring interface built on a modular widget system. It offers real-time system metrics, security monitoring, content management insights, and enterprise-grade audit logging capabilities.

This document outlines the complete dashboard architecture, widget system, and integration patterns.


System Overview

The dashboard is built on a flexible, grid-based widget system that allows administrators and users to create personalized monitoring interfaces tailored to their specific needs.

Core Architecture

%%{ init: { 'theme': 'neutral' } }%% graph TD subgraph "🖥️ Dashboard Frontend" A["Dashboard Page (+page.svelte)"] B["Widget Registry System"] C["Grid Layout Engine"] D["Drag & Drop System"] end subgraph "🔧 Widget Layer" E["base-widget.svelte"] F["Individual Widgets"] G["Widget Metadata"] H["Widget State Management"] end subgraph "📊 Data Sources" I["System Metrics APIs"] J["Audit Log Service"] K["Content APIs"] L["Security Services"] end subgraph "💾 Persistence" M["System Preferences"] N["User Preferences"] O["Widget Configurations"] end A --> B A --> C A --> D B --> E E --> F F --> G F --> H F --> I F --> J F --> K F --> L H --> M H --> N H --> O

Widget Architecture

Base Widget System

All dashboard widgets extend the base-widget.svelte component, which provides:

  • Standardized Layout: Consistent header, content area, and controls
  • State Management: Persistent widget configuration and data caching
  • Auto-refresh: Configurable polling intervals for live data
  • Error Handling: Graceful error states and retry mechanisms
  • Accessibility: Full keyboard navigation and screen reader support

Widget Registration

Widgets use dual discovery:

  1. Client (+page.svelte) — Vite import.meta.glob("./widgets/*.svelte") builds the runtime registry for lazy-loaded rendering.
  2. Server (+page.server.ts) — readdirSync scans all *.svelte files in widgets/ and dynamically imports widgetMeta for the widget picker.
// Client registry in +page.svelte
const modules = import.meta.glob("./widgets/*.svelte");

// Server discovery in +page.server.ts
const files = readdirSync(widgetsPath).filter(
  (file) => file.isFile() && file.name.endsWith(".svelte"),
);

Generative Dashboard

generativedashboard.svelte on the dashboard page provides an AI-assisted layout builder. It reuses the same widget registry and persists layouts through system-preferences.

Widget Metadata Schema

Each widget exports metadata for dashboard integration:

export const widgetMeta = {
  name: "Widget Display Name",
  icon: "mdi:icon-name",
  description: "Brief description for widget picker",
  defaultSize: { w: 2, h: 2 }, // Grid units
  category: "monitoring" | "logs" | "content" | "static",
};

Available Widget Categories

1. System Monitoring Widgets

Real-time system performance and health monitoring with adaptive h:1 compact / h:2+ rich layouts:

cpu-widget.svelte

  • Purpose: Live CPU usage monitoring with SVG sparklines and h:1 compact mode
  • Features: Multi-core visualization, load average, temperature alerts
  • Refresh: 2-second intervals for real-time monitoring
  • Size: 2x2 grid units (default)

memory-widget.svelte

  • Purpose: RAM and swap usage tracking
  • Features: Used/available memory, swap utilization, memory pressure alerts
  • Refresh: 5-second intervals
  • Size: 2x2 grid units

disk-widget.svelte

  • Purpose: Storage usage and I/O performance
  • Features: Multiple disk monitoring, free space alerts, I/O statistics
  • Refresh: 30-second intervals (storage changes slowly)
  • Size: 2x2 grid units

cache-monitor-widget.svelte

  • Purpose: Application cache performance monitoring
  • Features: Hit/miss ratios, MB/GB size display, per-category breakdown, h:1 compact summary
  • Refresh: 10-second intervals
  • Size: 2x1 grid units

unified-metrics-widget.svelteNew

  • Purpose: Comprehensive system performance and security overview
  • Features: 3-tier layout (h:1 compact, h:2 rich, h:3+ full), health scoring, SVG sparklines
  • Size: 2x3 grid units (default, pollInterval: 6s)

system-health-widget.svelte

  • Purpose: Overall system health status
  • Features: Aggregate health score, service status, uptime tracking
  • Refresh: 15-second intervals
  • Size: 3x1 grid units

database-pool-diagnostics.svelteNew

  • Purpose: Real-time database connection pool monitoring
  • Features:
    • Pool Statistics: Total, active, idle connections, waiting requests
    • Health Status: Visual health indicators (healthy/degraded/critical)
    • Utilization Metrics: Pool utilization percentage with color-coded progress bar
    • Smart Recommendations: Actionable optimization suggestions
    • Auto-refresh: 30-second intervals for up-to-date pool health
    • Integration: Uses DatabaseResilience system for diagnostics
  • Refresh: 30-second intervals
  • Size: 2x3 grid units
  • Role-Based: Admin-only access (requires admin role for pool diagnostics API)
  • API Endpoint: /api/database/pool-diagnostics

2. Security & Audit Widgets

Enterprise-grade security monitoring and compliance tracking:

audit-log-widget.svelteNew

  • Purpose: Real-time audit log monitoring and security event tracking
  • Features:
    • Admin View: System-wide security statistics, suspicious activity alerts
    • User View: Personal activity log, security notifications
    • Event Filtering: By type (auth, security, data), severity, time range
    • Real-time Alerts: Critical security events with immediate notifications
    • Compliance Ready: Structured logging for regulatory requirements
  • Refresh: 10-second intervals for security-critical monitoring
  • Size: 3x3 grid units (accommodates rich security data)
  • Role-Based: Dynamically adapts content based on user permissions

security-widget.svelte

  • Purpose: Advanced threat monitoring and incident response
  • Features: Threat level indicators, blocked IPs, CSP violations
  • Refresh: 5-second intervals for threat detection
  • Size: 3x3 grid units
  • API Endpoint: /api/dashboard/security

3. Content Management Widgets

Content and media monitoring for editorial workflows:

last5-content-widget.svelte

  • Purpose: Recent content creation and editing activity
  • Features: Collection-based content listing, author attribution
  • Refresh: Manual refresh (content changes less frequently)
  • Size: 2x3 grid units

last5-media-widget.svelte

  • Purpose: Recent media uploads and management
  • Features: Thumbnail previews, upload statistics, storage usage
  • Refresh: Manual refresh
  • Size: 2x3 grid units

4. System Information Widgets

Operational insights and system communication:

logs-widget.svelteEnhanced

  • Purpose: Filterable system log viewer
  • Features: Expandable cards, level filter, date range, text search, h:1 compact chips

system-messages-widget.svelteEnhanced

  • Purpose: System notifications with severity indicators
  • Features: Severity-colored accents (critical/error/warning/info), auto-detected links, clickable expand, h:1 compact chips

user-online-widget.svelteEnhanced

  • Purpose: Real-time online user presence

  • Features: Role badges (admin/editor/viewer), green presence dots, Gravatar support, h:1 compact avatar chips

  • Size: 2x1 grid units

performance-widget.svelte

  • Purpose: Application performance metrics and optimization insights
  • Features: Response times, throughput, performance trends
  • Refresh: 15-second intervals
  • Size: 3x2 grid units

unified-metrics-widget.svelte

  • Purpose: Consolidated system metrics overview
  • Features: Multi-metric dashboard, customizable thresholds
  • Refresh: 10-second intervals
  • Size: 4x2 grid units

Grid System & Customization

Responsive Grid Layout

The dashboard uses a 4-column responsive grid system:

  • Desktop (>1200px): 4 columns, full widget functionality
  • Tablet (768-1200px): 3 columns, condensed layouts
  • Mobile (<768px): 1 column, stacked vertically

Drag & Drop System

Users can customize their dashboard through intuitive drag-and-drop:

// Drag and drop implementation highlights
let dragState = $state({
  item: null,
  element: null,
  offset: { x: 0, y: 0 },
  isActive: false,
  gridPosition: { row: number, col: number },
});

function handleDragStart(event, widget) {
  dragState.item = widget;
  dragState.isActive = true;
  // Calculate grid position and visual feedback
}

function handleDrop(event) {
  // Update widget positions in system-preferences
  // Persist new layout configuration
}

Widget Sizing

Widgets support flexible sizing within the grid:

  • Minimum Size: 1x1 grid unit
  • Maximum Size: 4x4 grid units
  • Responsive Scaling: Automatic size adjustment on smaller screens
  • Aspect Ratio: Maintained during resize operations

Data Flow & Performance

Widget Data Loading

Each widget follows a standardized data loading pattern:

// Widget data loading lifecycle
async function loadWidgetData() {
  isLoading = true;
  error = null;

  try {
    // 1. Check cache (if enabled)
    const cachedData = getCache(cacheKey);
    if (cachedData && !isExpired(cachedData)) {
      return cachedData.data;
    }

    // 2. Fetch fresh data
    const response = await fetch(endpoint);
    const data = await response.json();

    // 3. Update cache
    setCache(cacheKey, data, cacheTTL);

    return data;
  } catch (err) {
    // 4. Handle errors with retry logic
    error = err.message;
    scheduleRetry();
  } finally {
    isLoading = false;
  }
}

Performance Optimizations

  • Lazy Loading: Widgets load components only when scrolling into view (Intersection Observer)
  • Smart Caching: Configurable TTL caching per widget category
  • Debounced Refresh: Prevents excessive API calls during rapid interactions
  • Progressive Enhancement: Core functionality works without JavaScript
  • Code Splitting: Each widget is a separate chunk, reducing initial bundle by 200-300KB
  • No Wrapper Components: Direct lazy loading eliminates unnecessary component layers

Lazy Loading Implementation

Dashboard implements native lazy loading without wrapper components for maximum performance:

// Integrated lazy loading in +page.svelte
let loadedWidgets = $state<Map<string, any>>(new Map());
let widgetObservers = new Map<string, IntersectionObserver>();

// Load widget when it becomes visible
function setupWidgetObserver(element: HTMLElement, params: [string, string]) {
  const [widgetId, componentName] = params;

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting && !loadedWidgets.has(widgetId)) {
          // Dynamic import when visible
          loadWidgetComponent(widgetId, componentName);
          observer.disconnect();
        }
      });
    },
    { rootMargin: "100px" }, // Preload 100px before visible
  );

  observer.observe(element);
  return { destroy: () => observer.disconnect() };
}

Benefits of Direct Integration:

  • 40% Faster: No wrapper component overhead
  • Type Safe: Direct TypeScript inference without prop drilling
  • Smaller Bundle: Eliminates 5KB of wrapper code
  • Simpler Debugging: Single component to trace
  • Better DX: One file to maintain instead of two

Performance Benchmarks

Based on production testing with 12 widgets:

  • Initial Load: < 500ms (dashboard shell only)
  • Widget Loading: 50-150ms per widget (as they scroll into view)
  • Total Bundle Reduction: ~250KB from lazy loading
  • Memory Usage: 60% lower than eager loading
  • Time to Interactive: < 1.2s on 3G connection

Widget Categories & Defaults

Widgets are categorized for optimal performance configuration:

export const WIDGET_DEFAULTS = {
  // Real-time monitoring (no cache, frequent updates)
  monitoring: {
    showRefreshButton: true,
    cacheKey: undefined,
    retryCount: 3,
    retryDelay: 1000,
  },

  // Activity logs (auto-poll, moderate caching)
  logs: {
    showRefreshButton: false,
    cacheKey: undefined,
    retryCount: 2,
    retryDelay: 1000,
  },

  // Content listings (cached, manual refresh)
  content: {
    showRefreshButton: false,
    cacheKey: (id: string) => `content-${id}`,
    cacheTTL: 120000, // 2 minutes
    retryCount: 3,
    retryDelay: 1000,
  },
};

Audit Log Widget Deep Dive

The new audit-log-widget represents the latest advancement in dashboard security monitoring:

Role-Based Functionality

Administrator View

// Admin users see comprehensive security overview
if (isAdmin && !showPersonalOnly) {
  // System-wide statistics
  const stats = await getAuditStatistics(7); // Last 7 days

  // Suspicious activity detection
  const suspicious = await getSuspiciousActivities(5);

  // All system events
  const events = await queryAuditLogs({ limit: 10 });
}

Regular User View

// Regular users see personal activity only
const personalEvents = await queryAuditLogs({
  actorId: currentUser.id,
  limit: 10,
});

Security Event Categories

The widget intelligently categorizes and displays events:

  • Authentication Events: Login attempts, 2FA changes, password resets
  • Security Events: Unauthorized access, privilege escalation, suspicious activity
  • Data Operations: Exports, imports, sensitive data access
  • System Events: Configuration changes, administrative actions

Real-Time Alerting

Critical security events trigger immediate visual alerts:

// Suspicious activity alert system
if (suspiciousEvents.length > 0) {
  // Show prominent alert banner
  // Highlight critical events in timeline
  // Trigger browser notifications (if permitted)
}

Integration Points

The audit widget seamlessly integrates with:

  • User Management System: Profile changes, role modifications
  • Authentication Service: Login events, 2FA status
  • Content Management: Data access, export operations
  • API Gateway: Token usage, rate limiting events

Dashboard API Endpoints

The dashboard handler (src/routes/api/[...path]/handlers/dashboard.ts) exposes 13 RESTful sub-routes under /api/dashboard/*. All require session authentication and the dashboard:read permission (mapped in ENDPOINT_PERMISSIONS). Paths use kebab-case (system-info, last5-content, online-user).

Authentication & Multi-tenancy

Requests pass through the API dispatcher (+server.ts) which enforces authentication and checkEndpointPermission before reaching the dashboard handler. All dashboard widgets respect multi-tenancy:

  • Tenant-scoped queries use locals.tenantId for every database operation
  • System-wide widgets (health, metrics, system-info) return global data visible to all tenants
  • Per-tenant widgets (last5-content, audit, security) filter results by locals.tenantId
  • Dashboard layout preferences are stored per-user per-tenant (compound key tenantId:userId)
  • Cache keys include tenantId to prevent cross-tenant cache leakage

Widget developers adding new dashboard endpoints must include tenantId in all database queries:

// ✅ Correct: dashboard handler passes tenantId
const result = await dbAdapter.crud.findMany("collection", {
  tenantId: event.locals.tenantId, // ← Required for tenant isolation
  ...otherFilters,
});

// ❌ Wrong: missing tenantId — returns ALL tenants' data
const result = await dbAdapter.crud.findMany("collection", otherFilters);

Endpoint Reference

1. GET /api/dashboard/health

System health check for dashboard widgets.

Authentication: Required (dashboard:read)

Response:

{
	"overallStatus": "READY" | "DEGRADED" | "INITIALIZING" | "FAILED" | "IDLE",
	"timestamp": "2025-01-20T10:30:00Z",
	"uptime": 3600,
	"components": {
		"database": { "status": "healthy", "responseTime": 5 },
		"cache": { "status": "healthy" }
	}
}

Status Codes:

  • 200: System is READY or DEGRADED
  • 503: System is INITIALIZING, FAILED, or IDLE

Use Case: Load balancer health checks, uptime monitoring


2. GET /api/dashboard/metrics

Performance metrics from the MetricsService.

Authentication: Required (session cookie)

Query Parameters:

  • detailed (boolean): Include system metrics (memory, uptime)

Response:

{
  "requests": { "total": 1523, "success": 1498, "errors": 25 },
  "auth": { "logins": 342, "failures": 12, "logouts": 298 },
  "cache": { "hits": 8543, "misses": 432 },
  "sessions": { "active": 23, "total": 342 },
  "system": {
    // Only if detailed=true
    "memory": { "used": 2147483648, "total": 8589934592 },
    "uptime": 3600000
  }
}

Use Case: performance-widget, unified-metrics-widget


3. GET /api/dashboard/system-info

Comprehensive system information: CPU, memory, disk, and OS.

Authentication: Required (dashboard:read)

Query Parameters:

  • type (string): Filter by type (cpu, disk, memory, network, os, process, or all)

Caching: 1-second TTL to prevent excessive system calls

Response:

{
  "cpuInfo": {
    "model": "Intel Core i7-9750H",
    "cores": 12,
    "speed": 2600,
    "usage": 45.3,
    "loadAverage": [2.1, 1.8, 1.5],
    "history": [42.1, 43.5, 45.3]
  },
  "memoryInfo": {
    "total": 17179869184,
    "used": 12884901888,
    "free": 4294967296,
    "swapTotal": 2147483648,
    "swapUsed": 1073741824
  },
  "diskInfo": {
    "mounts": [
      {
        "filesystem": "/dev/sda1",
        "size": 512110190592,
        "used": 256055095296,
        "available": 256055095296,
        "capacity": 50,
        "mounted": "/"
      }
    ]
  }
}

Use Case: cpu-widget, memory-widget, disk-widget, system-health-widget


4. GET /api/dashboard/logs

System logs with ANSI color conversion to HTML.

Authentication: Required (session cookie)

Query Parameters:

  • level (string): Filter by log level (error, warn, info, debug)
  • search (string): Search within log messages
  • startDate (ISO 8601): Filter logs after this date
  • endDate (ISO 8601): Filter logs before this date
  • page (number): Page number (default: 1)
  • limit (number): Results per page (max: 100, default: 50)

Features:

  • ANSI color codes converted to HTML <span> elements
  • Supports compressed log files (.gz, .br)
  • Pagination for large log files
  • Real-time log tailing

Response:

{
  "logs": [
    {
      "timestamp": "2025-01-20T10:30:15",
      "level": "info",
      "message": "User logged in",
      "messageHtml": "<span style='color:#00ff00'>User logged in</span>"
    }
  ],
  "total": 1523,
  "page": 1,
  "totalPages": 31
}

Use Case: logs-widget


5. GET /api/dashboard/last5-content

Recent content from all collections via LocalCMS.collections.search.

Authentication: Required (dashboard:read)

Query Parameters:

  • limit (number): Number of items (max: 50, default: 5)

Features:

  • Multi-collection aggregation across all tenant collections
  • Sorted by updatedAt (newest first)
  • Tenant-scoped queries

Response:

[
  {
    "id": "post-123",
    "title": "Latest Blog Post",
    "collection": "posts",
    "createdAt": "2025-01-20T10:00:00Z",
    "createdBy": "john.doe",
    "status": "published"
  }
]

Use Case: last5-content-widget


6. GET /api/dashboard/last5media

Recent media files from the media library.

Authentication: Required (session cookie)

Features:

  • Database adapter integration
  • Tenant-scoped queries
  • File metadata (size, modified date, MIME type)

Response:

[
  {
    "name": "hero-image.jpg",
    "size": 2457600,
    "modified": "2025-01-20T09:45:00Z",
    "type": "image/jpeg",
    "url": "/media/hero-image.jpg"
  }
]

Use Case: last5-media-widget


7. GET /api/dashboard/online-user

Currently online users derived from active sessions (getAllActiveSessions).

Authentication: Required (dashboard:read)

Features:

  • Active session tracking (no synthetic random durations)
  • Username and avatar display
  • Online time formatting (“2h 15m”)
  • Sorted by longest online time first

Response:

{
  "onlineUsers": [
    {
      "id": "user-123",
      "name": "John Doe",
      "avatarUrl": "/avatars/john.jpg",
      "onlineTime": "2h 15m",
      "onlineMinutes": 135
    }
  ]
}

Use Case: user-online-widget


8. GET /api/dashboard/system-messages

System messages derived from audit logs.

Authentication: Required (dashboard:read)

Query Parameters:

  • limit (number): Number of messages (max: 50, default: 5)

Features:

  • Tail reading from log files
  • Log parsing with structured output
  • Default message when no logs available
  • Message prioritization by severity

Response:

[
  {
    "id": "msg-1",
    "title": "System Update",
    "message": "New version deployed successfully",
    "level": "info",
    "timestamp": "2025-01-20T10:30:00Z",
    "type": "system"
  }
]

Use Case: system-messages-widget


9. GET /api/dashboard/cache-metrics

Cache performance metrics from CacheMetrics service.

Authentication: Required (session cookie)

Methods:

  • GET: Retrieve cache metrics
  • DELETE: Reset all cache metrics (admin only)

Response:

{
  "overall": {
    "hits": 8543,
    "misses": 432,
    "hitRate": 95.2,
    "size": 2147483648
  },
  "byCategory": {
    "content": { "hits": 5234, "misses": 123 },
    "media": { "hits": 2109, "misses": 234 },
    "system": { "hits": 1200, "misses": 75 }
  },
  "byTenant": {
    "tenant-1": { "hits": 4321, "misses": 198 },
    "tenant-2": { "hits": 4222, "misses": 234 }
  },
  "recentMisses": [{ "key": "content:post-123", "timestamp": "2025-01-20T10:30:00Z" }],
  "timestamp": "2025-01-20T10:30:15Z"
}

Use Case: cache-monitor-widget


10. GET /api/dashboard/audit

Flat audit event feed for the audit-log widget.

Authentication: Required (dashboard:read)

11. GET /api/dashboard/security

Security incident statistics and active threats.

Authentication: Required (dashboard:read)

12. GET /api/dashboard/scim

SCIM provisioning status for the scim-status widget.

Authentication: Required (dashboard:read)


API Testing

Dashboard APIs have integration test coverage:

Test File: tests/integration/api/dashboard.test.ts

Coverage by Endpoint:

  • /health: 3 tests (status codes, component health, structure)
  • /metrics: 3 tests (basic metrics, detailed mode, validation)
  • /systemInfo: 6 tests (type filtering, caching, multi-platform)
  • /logs: 5 tests (pagination, filtering, search, ANSI colors)
  • /last5Content: 4 tests (content structure, limits, sorting)
  • /last5media: 3 tests (media structure, empty handling)
  • /online_user: 4 tests (user list, sorting, current user)
  • /systemMessages: 4 tests (message structure, limits, defaults)
  • /cache-metrics: 6 tests (metrics structure, categories, hit rates)

Running Dashboard Tests:

# Requires running development server
bun run dev
bun test tests/integration/api/dashboard.test.ts

Authentication in Tests:

// All tests use authenticated session
beforeAll(async () => {
  const loginRes = await fetch("http://localhost:5173/api/auth/login", {
    method: "POST",
    body: JSON.stringify({ email: "admin@example.com", password: "admin123" }),
  });
  const cookies = loginRes.headers.get("set-cookie");
  authCookie = cookies?.split(";")[0] || "";
});

Customization & Extension

Adding New Widgets

  1. Create Widget File: src/routes/(app)/dashboard/widgets/my-widget.svelte
  2. Export Metadata: Include widgetMeta object
  3. Extend base-widget: Use provided component infrastructure
  4. Auto-Registration: Widget appears automatically in picker

Widget Development Best Practices

// Example widget structure
<script lang="ts" module>
  export const widgetMeta = {
    name: 'My Custom Widget',
    icon: 'mdi:chart-line',
    description: 'Custom monitoring widget',
    defaultSize: { w: 2, h: 2 }
  };
</script>

<script lang="ts">
  // Widget logic, data loading, state management
</script>

<base-widget {label} {size} {onSizeChange}>
  {#snippet children()}
    <!-- Widget content -->
  {/snippet}
</base-widget>

Configuration Persistence

Widget configurations are automatically persisted:

// System preferences store widget layouts
system-preferences: {
	preferences: [
		{
			id: 'widget-123',
			component: 'audit-log-widget',
			size: { w: 3, h: 3 },
			position: { x: 0, y: 0 },
			config: { showPersonalOnly: false }
		}
	];
}

Security Considerations

Widget Security Model

  • Permission-Based Rendering: Widgets respect user role limitations
  • Data Isolation: Users can only access authorized data
  • Secure Endpoints: All widget APIs protected by authentication
  • XSS Prevention: All user content properly sanitized

Audit Trail Integration

All dashboard interactions are logged through the audit system:

  • Widget additions/removals
  • Configuration changes
  • Data access patterns
  • Security threshold breaches

Real-Time Data Streaming

Dashboard widgets receive live updates via svelte-realtime, which provides WebSocket-based streaming with SSE fallback. The integration lives in src/live/:

  • system.ts — Bridges the internal EventBus to connected WebSocket clients with tenant isolation. System events (content changes, user activity, cache invalidations) stream to all authorized dashboard widgets.
  • chat.ts — Real-time AI chat for the dashboard co-pilot. Uses per-room streaming with individual access controls.
  • ws-platform.ts — Shared WebSocket platform reference for global broadcasting. Initialized by src/hooks.ws.ts during server startup.
// Dashboard widget subscribing to real-time events
import { events } from "$live/system";

$effect(() => {
  const stream = events();
  stream.subscribe((event) => {
    // event contains: type, payload, timestamp, tenantId
    updateWidgetData(event);
  });
});

CDN Cache Purging

When content is published or media is updated, src/services/cdn/cdn-service.ts automatically purges the Cloudflare CDN cache to ensure global edge consistency:

import { cdnService } from "@services/cdn/cdn-service";

// Purge specific content by tags (surgical invalidation)
await cdnService.purge({ tags: ["collection:posts", "entry:abc123"] });

// Purge entire zone (use sparingly)
await cdnService.purge({ everything: true });

The service reads credentials from config/private.ts (CF_API_TOKEN, CF_ZONE_ID, CF_PURGE_MODE) and operates non-blocking — purge calls fire in the background without delaying the API response.

Security Alerting & SIEM Integration

src/services/security/monitoring-service.ts provides real-time anomaly detection with webhook-based alerting for external security systems:

import { securityMonitor } from "@services/security/monitoring-service";

// Start monitoring (called during server boot)
securityMonitor.start();

// Configure SIEM webhook (JSON, CEF, or LEEF format)
securityMonitor.configureWebhook({
  url: "https://siem.company.com/ingest",
  secret: "webhook-signing-key",
  format: "cef",
  enabled: true,
});

// Check monitoring status for dashboard widget
const status = securityMonitor.getStatus();
// { isMonitoring, alertCount, unacknowledgedCount, activeRules, eventCounts }

Five anomaly detection rules run automatically: brute force detection, unusual access patterns, permission escalation attempts, rapid session creation, and token abuse detection. Each rule has configurable thresholds and cooldown periods to prevent alert fatigue.

Planned Enhancements

  • Custom Widget Builder — Visual widget creation interface for non-developers
  • Export Capabilities — Dashboard screenshot and CSV/JSON data export
  • PWA Support — Installable mobile dashboard with offline capability
  • Service Worker Caching — Offline access to static dashboard assets

Conclusion

The SveltyCMS dashboard system provides a powerful, flexible foundation for monitoring and managing all aspects of the CMS platform. With the addition of comprehensive audit logging capabilities, administrators and users have unprecedented visibility into system operations, security events, and content management activities.

The modular widget architecture ensures the dashboard can evolve with changing requirements while maintaining optimal performance and user experience across all device types and user roles.


Related

dashboardwidgetsmonitoringaudit-logsarchitecturecustomization
Was this page helpful?