Architecture Diagram - martinmendozadev/StateForce GitHub Wiki
🏗️ StateForce System Architecture
This document outlines the high-level architecture of the StateForce platform, a real-time emergency resource management system. It's designed for operational use by state-level public safety and emergency response entities, emphasizing real-time data synchronization, reliability, and secure access.
📖 1. Overview
StateForce is architected as a monolithic Ruby on Rails application, augmented with modern frontend technologies for a responsive, real-time user experience and a robust backend for asynchronous processing.
Core Technologies:
- Backend: Ruby on Rails
- Frontend: Hotwire (Turbo, Stimulus), TailwindCSS
- Real-time: ActionCable (WebSockets), Turbo Streams
- Background Jobs: Sidekiq
- Database: PostgreSQL
- Caching & Messaging: Redis
- Authentication: Devise with OmniAuth (Google OAuth2)
- Authorization: Pundit
Key Architectural Goals:
- Real-time Collaboration: Provide immediate updates and synchronized views for all concurrent users.
- High Availability & Resilience: Ensure the system remains operational during critical incidents.
- Scalability: Allow the system to grow in terms of users, data, and features.
- Security: Implement robust role-based access control, data protection, and auditability.
- Interoperability: Integrate seamlessly with essential external services and data sources.
- Maintainability: Employ clean code practices and a well-defined structure for ease of development and updates.
📊 2. Architecture Diagram
The following diagram illustrates the main components and their interactions within the StateForce platform:
graph TD
subgraph UserLayer ["User Layer"]
U["End User (Emergency Personnel via Browser)"]
end
subgraph ClientApp ["Client Application (Browser)"]
A["User Interface (Hotwire: Turbo Drive/Frames/Streams, StimulusJS, TailwindCSS)"]
end
subgraph ApplicationServer ["StateForce Backend (Ruby on Rails)"]
B1["API Endpoints & Controllers (MVC)"]
B2["Models (ActiveRecord, Business Logic, Validations)"]
B3["Views & Presenters (ERB, Turbo Streams Generation)"]
B4["ActionCable (WebSocket Communication for Real-time Features)"]
B5["ActiveJob (Background Job Interface)"]
B6["Authentication (Devise + OmniAuth for Google OAuth2)"]
B7["Authorization (Pundit for Role-Based Access Control)"]
B8["Service Objects / Interactors (Complex Business Operations)"]
end
subgraph AsyncProcessing ["Asynchronous Processing Infrastructure"]
C1["Sidekiq Workers (Multiple Processes/Threads)"]
C2["Redis (Sidekiq Queues, Cache, ActionCable Pub/Sub)"]
end
subgraph DataStore ["Data Persistence"]
D1["PostgreSQL (Primary Database: Incidents, Users, Resources, Audit Logs)"]
end
subgraph ExternalIntegrations ["External Services & Integrations"]
E1["Google OAuth2 (Identity Provider)"]
E2["ArcGIS API (Emergency Facility Data, Geocoding, Mapping Services)"]
E3["Notification Services (e.g., Email, SMS Gateways)"]
end
%% User Interaction
U -- "Interacts with" --> A;
%% Client-Server Interaction
A -- "HTTP Requests (GET, POST, etc.) / Turbo Drive & Frames" --> B1;
B1 -- "Serves HTML, JSON / Generates Turbo Streams" --> B3;
B3 -- "HTML / Turbo Streams (UI Updates)" --> A;
B4 -- "Pushes Real-time Updates (WebSockets)" --> A;
A -- "Establishes WebSocket Connection" --> B4;
%% Backend Logic & Data Flow
B1 -- "Utilizes" --> B2;
B1 -- "Orchestrates via" --> B8;
B8 -- "Encapsulates Logic, Uses" --> B2;
B1 -- "Triggers Async Tasks via" --> B5;
B1 -- "Handles Authentication via" --> B6;
B1 -- "Enforces Authorization via" --> B7;
%% Data Interaction
B2 -- "CRUD Operations (ORM)" --> D1;
B8 -- "Data Manipulation via Models" --> B2;
%% Background Processing
B5 -- "Enqueues Jobs into" --> C2;
C1 -- "Dequeues & Processes Jobs from" --> C2;
C1 -- "Interacts with Models" --> B2;
C1 -- "May directly access" --> D1;
C1 -- "Calls External APIs like" --> E2;
C1 -- "Sends Notifications via" --> E3;
%% External Service Interactions
B6 -- "Redirects for Auth / Handles Callbacks from" --> E1;
B1 -- "Requests Data from (or via B8/C1)" --> E2;
%% Redis Usage for other purposes
B4 -- "Uses for Pub/Sub (Broadcasting)" --> C2;
ApplicationServer -- "Optionally uses for Caching" --> C2;
🧩 3. Component Breakdown
🖥️ Client Application (Browser)
- User Interface (UI): Built with HTML, styled by TailwindCSS for a utility-first approach to design.
- Hotwire (Turbo + Stimulus):
- Turbo Drive: Accelerates navigation by fetching and rendering pages without full reloads.
- Turbo Frames: Decompose pages into independent segments that can be lazily loaded or updated.
- Turbo Streams: Deliver partial page updates over WebSockets (via ActionCable) or in HTTP responses, enabling real-time UI changes.
- StimulusJS: Provides lightweight JavaScript structure for client-side interactions and enhancements.
🔧 Application Server (Ruby on Rails Monolith)
- Controllers: Handle incoming HTTP requests, interact with models and services, and select appropriate views or Turbo Stream responses.
- Models (ActiveRecord): Represent business entities (Users, Incidents, Resources), manage data persistence, enforce validations, and contain core business logic.
- Views & Presenters (ERB): Generate HTML content. Turbo Streams are often generated here to update specific parts of the client UI.
- ActionCable: Manages WebSocket connections for bi-directional, real-time communication between clients and the server, powering features like live dashboards and collaborative editing.
- ActiveJob: A framework for declaring background jobs and integrating with various queuing backends (Sidekiq in this case).
- Authentication (Devise + OmniAuth): Secures user access. Devise handles session management and standard authentication, while OmniAuth integrates with Google OAuth2 for federated identity.
- Authorization (Pundit): Implements Role-Based Access Control (RBAC) using policies to define user permissions for specific actions and resources.
- Service Objects / Interactors: Encapsulate complex business operations or workflows, keeping controllers and models lean.
⚙️ Asynchronous Processing Infrastructure
- Sidekiq: A high-performance background processing framework that uses Redis for its job queue. Handles tasks like sending notifications, generating reports, processing external API calls, and performing audit logging without blocking web requests.
- Redis: An in-memory data store used by Sidekiq for job queuing, by ActionCable for its Pub/Sub mechanism in multi-server setups, and potentially for application-level caching.
🗃️ Data Persistence
- PostgreSQL: The primary relational database storing all core application data, including user accounts, incident details, resource statuses, and audit logs. Utilizes transactions, foreign key constraints, and indexes for data integrity and performance.
🔌 External Services & Integrations
- Google OAuth2: Provides secure authentication and identity verification, allowing users to log in with their existing Google accounts.
- ArcGIS API: Used to fetch and display geospatial data, such as emergency facility locations, hospital information, and potentially for geocoding or routing services.
- Notification Services: Integrations with email and SMS gateways with Twilio for sending alerts and communications, triggered by Sidekiq jobs.
🔒 4. Security Considerations
- Authentication: Strong authentication enforced via Google OAuth2, leveraging multi-factor authentication (MFA) if enabled on user Google accounts.
- Authorization: Granular permissions managed by Pundit policies, ensuring users can only access data and perform actions appropriate for their roles.
- Data Protection:
- HTTPS enforced for all communication.
- Sensitive data at rest in PostgreSQL should be encrypted where appropriate.
- Regular data backups and a disaster recovery plan.
- Input Validation: Rigorous validation at model and controller levels to prevent common web vulnerabilities (XSS, SQLi).
- Dependency Management: Weekly gems update and libraries to patch known vulnerabilities.
- Audit Trails: Comprehensive logging of user actions and system events for accountability and forensic analysis.
- Rate Limiting & Throttling: Implemented for public-facing endpoints or sensitive operations to prevent abuse.
📈 5. Future Considerations & Scalability
- Horizontal Scaling:
- Application Servers: Deploy multiple instances of the Rails application (Puma workers/servers) behind a load balancer.
- Sidekiq Workers: Increase the number of Sidekiq processes/dynos to handle higher job throughput.
- Database Scaling:
- Read Replicas: Offload read-heavy queries to PostgreSQL read replicas.
- Connection Pooling: Efficiently manage database connections using PgBouncer.
- Caching Strategies: Implement more extensive caching as fragment caching, Russian doll caching, Redis for query results to reduce database load and improve response times.
- Content Delivery Network (CDN): Serve static assets as images via a Cloudinary CDN to reduce latency for users.
- Service Extraction (Microservices): If parts of the monolith become overly complex or have distinct scaling needs, consider extracting them into separate services.
- Enhanced Observability: Integrate advanced monitoring, logging, and tracing tools (e.g., Prometheus, Grafana, New Relic, Datadog) for better insight into system performance and health.
- API Development:
- Public API: Expose a versioned, secure, read-only (or write) API for integration with other systems or for third-party dashboards.
- GraphQL: Consider GraphQL for more flexible data fetching for future client applications.
- Disaster Recovery & Business Continuity: Formalize and regularly test disaster recovery plans.
This architecture document comprehensively outlines the StateForce platform's design and serves as a technical reference for development and scaling.