Architecture Overview - dlangkip/epidash GitHub Wiki

Architecture Overview

This page provides a detailed explanation of EpiDash's architectural design, component interactions, and design patterns. This overview will help developers understand the system design principles and how the various parts work together.

System Architecture Diagram

EpiDash Architecture

Note: Upload your architecture diagram to the wiki for proper display

Architectural Pattern

EpiDash follows a layered architecture with elements of MVC (Model-View-Controller) pattern, designed for clarity, maintainability, and separation of concerns. The architecture consists of the following layers:

Presentation Layer (View)

The presentation layer is responsible for rendering the user interface and handling user interactions.

Components:

  • HTML Templates: Located in the root and includes directories
  • CSS Styles: Located in the assets/css directory
  • JavaScript UI Handlers: Event listeners and DOM manipulations

Responsibilities:

  • Rendering data visualizations
  • Capturing user inputs
  • Displaying alerts and notifications
  • Managing responsive layout
  • Providing interactive elements

Application Layer (Controller)

The application layer coordinates the application, processes commands, and directs data flow between the user interface and the data layer.

Components:

  • JavaScript Modules: Main application logic in assets/js
  • Event Handlers: User interaction processing
  • State Management: Central application state in main.js

Responsibilities:

  • Processing user inputs
  • Orchestrating data flow
  • Managing application state
  • Coordinating UI updates
  • Handling application events

Data Access Layer (Model)

The data access layer handles data retrieval, processing, and persistence operations.

Components:

  • PHP API Endpoints: Located in the api directory
  • Data Processing Functions: In process_data.php
  • Data Generation: Mock data generation in connection.php
  • Database Interactions: Optional database connectivity

Responsibilities:

  • Data retrieval from sources
  • Data filtering and aggregation
  • Response formatting
  • Error handling
  • Database interactions (when configured)

Communication Flow

The communication flow between layers follows this sequence:

  1. User Interaction

    • User interacts with the UI (selects filters, date ranges, etc.)
    • Event listeners in the Application Layer capture these interactions
  2. API Request

    • Application Layer constructs API requests with parameters
    • Requests are sent to the Data Access Layer endpoints
  3. Data Processing

    • Data Access Layer retrieves and processes data
    • Filtering, aggregation, and calculations are performed
    • Response is formatted as JSON
  4. Response Handling

    • Application Layer receives and processes the response
    • State is updated with new data
  5. UI Update

    • Presentation Layer receives update notifications
    • Charts, tables, and metrics are refreshed with new data

Key Design Patterns

EpiDash implements several design patterns to maintain clean architecture:

1. Module Pattern

JavaScript code is organized into functional modules with specific responsibilities:

// Example of module pattern in charts.js
function initializeTrendsChart() {
    // Implementation
}

function updateTrendsChart() {
    // Implementation
}

// Exposed functions that become part of the public API

2. Observer Pattern

The application uses a variation of the observer pattern for state changes:

// When state changes, observers (charts, tables) are updated
function updateDashboard() {
    // Notify all observers (components) of state change
    updateMetricsCards();
    updateQuickStats();
    updateDataTable();
    updateCharts();
}

3. Factory Pattern

Chart creation follows a factory pattern approach:

// Factory function to create charts
function initializeCharts() {
    initializeTrendsChart();
    initializeRegionChart();
    initializeAgeChart();
    initializeRecoveryChart();
}

4. Strategy Pattern

Data retrieval strategies are selected based on configuration:

// Different strategies for data retrieval
if ($dataSource === 'mock' || $dataSource === 'both') {
    $mockData = generateMockData(1000);
    // Process mock data
}

if ($dataSource === 'database' || $dataSource === 'both') {
    // Process database data
}

Component Interactions

Chart Component Interaction

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Interfaceβ”‚     β”‚  Chart.js     β”‚     β”‚  Application  β”‚
β”‚   (HTML/CSS)  │◄─────  Renderers    │◄─────    State      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚
                                                   β”‚
                                           β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                                           β”‚  API Client   β”‚
                                           β”‚   Functions   β”‚
                                           β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚
                                                   β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Data Sources β”‚     β”‚  Data Process β”‚     β”‚  PHP API      β”‚
β”‚ (Mock/DB)     │────►│   Functions   │────►│  Endpoints    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Filter System Interaction

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Filter UI     β”‚     β”‚  Filter Event β”‚     β”‚  Dashboard    β”‚
β”‚ Components    │────►│  Handlers     │────►│  State        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚
                                                   β”‚
                                           β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                                           β”‚ applyFilters  β”‚
                                           β”‚   Function    β”‚
                                           β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚
                                                   β”‚
                                           β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                                           β”‚ updateDashbrd β”‚
                                           β”‚   Function    β”‚
                                           β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚
                                            β”Œβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”
                                            β”‚      β”‚      β”‚
                                      β”Œβ”€β”€β”€β”€β”€β–Όβ”€β” β”Œβ”€β”€β–Όβ”€β”€β” β”Œβ”€β–Όβ”€β”€β”
                                      β”‚Charts β”‚ β”‚Tableβ”‚ β”‚Mapsβ”‚
                                      β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜

Front-End Architecture

The front-end architecture is organized around these key components:

1. Dashboard Layout

The main container that holds all UI components:

  • Header with navigation and controls
  • Sidebar with filters
  • Main content area with visualizations
  • Data table section
  • Footer with information

2. State Management

Centralized in the dashboardState object with:

  • Filter settings
  • Raw and filtered data
  • Pagination state
  • Chart references
  • Metrics and quick stats

3. Event System

A pub/sub-like event system that:

  • Captures user interactions
  • Propagates state changes
  • Triggers UI updates
  • Manages asynchronous operations

4. Visualization Engine

Built on Chart.js and Leaflet:

  • Consistent initialization pattern
  • Data mapping functions
  • Update mechanisms
  • Interactive features
  • Responsive sizing

Back-End Architecture

The back-end architecture is based on these components:

1. API Endpoints

RESTful endpoints that:

  • Accept query parameters
  • Validate input data
  • Process requests
  • Format responses
  • Handle errors

2. Data Providers

Abstract the data source with:

  • Mock data generator
  • Database connector
  • Data transformation logic
  • Filtering capabilities
  • Aggregation functions

3. Configuration System

Environment-based configuration:

  • .env file for environment variables
  • Config constants for application settings
  • Feature flags for functionality control
  • Data source configuration
  • Error handling settings

Data Flow Detailed Sequence

1. User adjusts filters in the UI
   β”‚
2. Event listeners capture filter changes
   β”‚
3. Filter values saved to dashboardState.filters
   β”‚
4. applyFilters() called when "Apply" button clicked
   β”‚
5. API request constructed with filter parameters
   β”‚
6. get_data.php receives request with parameters
   β”‚
7. Data source determined (mock/database/both)
   β”‚
8. Raw data retrieved from selected source
   β”‚
9. Server-side filtering applied based on parameters
   β”‚
10. Filtered data returned as JSON
    β”‚
11. Data assigned to dashboardState.data.filtered
    β”‚
12. Metrics calculated from filtered data
    β”‚
13. updateDashboard() called to refresh UI
    β”‚
14. All visualization components updated
    β”‚
15. New data displayed to user

Modularity and Extension Points

The architecture provides several extension points for future development:

1. New Visualizations

New chart types can be added by:

  • Creating HTML container in index.php
  • Adding initialization function in charts.js
  • Adding update function in charts.js
  • Registering in the initialization sequence

2. New Filters

Additional filters can be implemented by:

  • Adding UI controls in sidebar.php
  • Adding state properties in dashboardState
  • Extending filter logic in applyFilters()
  • Adding event listeners in setupEventListeners()

3. New API Endpoints

The API can be extended with new endpoints by:

  • Creating new PHP files in the api directory
  • Following the established request/response pattern
  • Adding appropriate data processing functions
  • Documenting in the API Reference

4. New Data Sources

Additional data sources can be integrated by:

  • Adding source options in the configuration
  • Implementing connector functions
  • Extending the data source selection logic
  • Adding appropriate data transformations

Architectural Considerations

Performance

The architecture addresses performance through:

  • Efficient data filtering (both server and client-side)
  • Pagination for large datasets
  • Selective rendering of UI components
  • Optimized chart updates
  • Browser caching of static assets

Security

Security considerations include:

  • Input validation for all API parameters
  • Output sanitization for all displayed data
  • .env file protection
  • Error handling that prevents information disclosure
  • Prepared statements for database queries

Scalability

The system is designed for scalability with:

  • Clear separation of concerns
  • Modular component design
  • Abstracted data access layer
  • Configurable data sources
  • Stateless API design

Maintainability

Maintainability is ensured through:

  • Consistent coding patterns
  • Logical file organization
  • Descriptive function and variable names
  • Appropriate comments
  • Centralized configuration

Deployment Architecture

For production deployments, the recommended architecture is:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Load Balancer   β”‚     β”‚ Web Servers   β”‚     β”‚ Database      β”‚
β”‚ (Optional)      │────►│ (Apache/Nginx)│────►│ (MySQL)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                       β”‚ EpiDash       β”‚
                       β”‚ Application   β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Conclusion

The EpiDash architecture provides a solid foundation for an epidemiological data dashboard with:

  • Clear separation of concerns for maintainability
  • Modular design for extensibility
  • Intuitive data flow for understandability
  • Multiple extension points for future development
  • Performance considerations for user experience
  • Security measures for data protection

This architecture enables developers to understand, maintain, and extend the application while preserving its core functionality and design principles.