# Architecture

**Analysis Date:** 2026-01-11

## Pattern Overview

**Overall:** Hybrid Microservices with Shared Monolithic Database

**Key Characteristics:**
- Service-oriented architecture with distinct service boundaries
- Monolithic Rails backend transitioning to modern React frontend
- Shared PostgreSQL database across all services
- Real-time communication via WebSocket gateway with Protocol Buffers
- Async messaging via RabbitMQ/AMQP between services

## Layers

**Presentation Layer (Frontend):**
- Purpose: User interface and client-side logic
- Contains: React 16 SPA with Redux Toolkit state management
- Location: `jam-ui/src/`
- Entry Point: `jam-ui/src/index.js` → `Main.js` (providers) → `App.js` (layout router)
- Depends on: Rails API (`web/`) via REST, WebSocket gateway for real-time
- Used by: End users via browser at `http://beta.jamkazam.local:4000`
- Current Status: Under development. This is mostly a UI update of the legacy front end (web)

**API Layer (Backend):**
- Purpose: REST API endpoints, request processing, authentication
- Contains: Rails 4.2.8 controllers, responders, error handling
- Location: `web/app/controllers/` (83 API controller files)
- Base Controller: `api_controller.rb` provides auth, error handling, response formatting
- Depends on: Shared business logic gem (`ruby/`), PostgreSQL
- Used by: React frontend, mobile apps, third-party integrations

**Real-time Communication Layer:**
- Purpose: WebSocket connections for live session updates
- Contains: EventMachine-based WebSocket server with Protocol Buffer messaging
- Location: `websocket-gateway/`
- Protocol: Protocol Buffers (`.proto` definitions in `pb/src/client_container.proto`)
- Bridge: `jam-ui/src/jamClientProxy.js` manages native C++ client communication via QWebChannel
- Depends on: Shared Ruby gem, WebSocket protocol
- Used by: React frontend, native desktop client

**Shared Business Logic Layer:**
- Purpose: Centralized models, validations, domain logic
- Contains: ActiveRecord models (217 files), managers, message factory
- Location: `ruby/lib/jam_ruby/` (shared gem embedded via local path)
- Key Files: `ruby/lib/jam_ruby/models/` (217 model files), `message_factory.rb`, `connection_manager.rb`
- Depends on: Rails frameworks, PostgreSQL
- Used by: All services (web, admin, websocket-gateway)

**Data Layer:**
- Purpose: Persistent storage
- Contains: PostgreSQL schema, migrations
- Location: `db/up/` (403+ migration files)
- ORM: ActiveRecord models in `ruby/lib/jam_ruby/models/`
- Depends on: PostgreSQL server
- Used by: All services via ActiveRecord

## Data Flow

**REST API Request (Example: Fetch User Profile):**

1. User action in React component (e.g., `JKUserProfile.js`)
2. Redux dispatch or direct API call via `apiFetch()` (`jam-ui/src/helpers/rest.js`)
3. HTTP request to Rails controller (e.g., `api_users_controller.rb`)
4. Controller uses shared business logic (`ruby/lib/jam_ruby/models/user.rb`)
5. ActiveRecord query to PostgreSQL database
6. Response serialized (RABL template or JSON)
7. Redux store updated (`jam-ui/src/store/features/*.js`)
8. Component re-renders with new data

**Real-time Session Flow (Example: Join Music Session):**

1. Native C++ desktop client sends message
2. Proxied through `jamClientProxy.js` (QWebChannel tunnel to frontend)
3. WebSocket message to gateway (`websocket-gateway/`)
4. Protocol Buffer decoding → Rails backend logic
5. Async processing via Resque jobs or AMQP messages
6. State changes persisted to PostgreSQL
7. Broadcast back to all session participants via WebSocket
8. Protocol Buffer encoding → Frontend updates Redux state

**State Management:**
- Redux Toolkit for global app state (sessions, tracks, user, notifications)
- Context API for UI state (native client connection, media player, global settings)
- WebSocket for real-time state synchronization

## Key Abstractions

**Component (React):**
- Purpose: UI building blocks with JK prefix for brand-specific components
- Examples: `JKDashboardMain.js`, `JKSessionModal.js`, `JKJamTrackPlayer.js` in `jam-ui/src/components/`
- Pattern: Functional components with hooks, prop destructuring, Redux integration

**Hook (React):**
- Purpose: Reusable stateful logic
- Examples: `useJamServer.js` (26KB, WebSocket orchestration), `useJamTrack.js`, `useGearUtils.js` in `jam-ui/src/hooks/`
- Pattern: `use*` naming convention, returns state and handlers

**Controller (Rails):**
- Purpose: Handle HTTP requests, route to business logic
- Examples: `api_sessions_controller.rb`, `api_jam_tracks_controller.rb`, `api_users_controller.rb` in `web/app/controllers/`
- Pattern: RESTful actions, inherit from `api_controller.rb`, use responders

**Model (Rails/ActiveRecord):**
- Purpose: Domain objects with validations and business rules
- Examples: `user.rb` (3,078 lines), `music_session.rb` (1,481 lines), `jam_track.rb` in `ruby/lib/jam_ruby/models/`
- Pattern: ActiveRecord associations, scopes, state machines (AASM)

**API Service Function:**
- Purpose: Frontend-to-backend communication abstractions
- Examples: `getSession(id)`, `joinSession(options)`, `updateUser(id, data)` in `jam-ui/src/helpers/rest.js`
- Pattern: Promise-based, wraps `apiFetch()`, returns resolved/rejected promises

## Entry Points

**Frontend Entry:**
- Location: `jam-ui/src/index.js`
- Triggers: Browser loads page at `http://beta.jamkazam.local:4000`
- Responsibilities: Render React app, wrap with providers (Redux, Context), route to layouts

**Backend API Entry:**
- Location: `web/config/routes.rb` (51KB route definitions)
- Triggers: HTTP request to `/api/*` endpoints
- Responsibilities: Route to controller actions, apply middleware, return JSON responses

**WebSocket Gateway Entry:**
- Location: `websocket-gateway/` (EventMachine server)
- Triggers: WebSocket connection from client
- Responsibilities: Maintain persistent connections, decode/encode Protocol Buffers, broadcast messages

**Shared Library Entry:**
- Location: `ruby/lib/jam_ruby.rb`
- Triggers: Required by Rails services
- Responsibilities: Load all models, managers, and shared utilities

## Error Handling

**Strategy:** Exceptions bubble to top-level handler, logged and returned as JSON errors

**Patterns:**
- Controllers use `api_controller.rb` base class for centralized error handling
- Frontend catches promise rejections from `apiFetch()`, displays user-friendly errors
- Background jobs (Resque) retry on transient failures, log permanent failures
- WebSocket errors logged server-side, client notified via error messages

## Cross-Cutting Concerns

**Logging:**
- Rails logger for backend (stdout in development, files in production)
- Console logging in React frontend (removed in production builds)
- Bugsnag for error tracking (API key configured in `web/config/application.rb`)
- InfluxDB for time-series metrics (configured but disabled for production)

**Validation:**
- ActiveRecord validations in model layer (`ruby/lib/jam_ruby/models/*`)
- React Hook Form for frontend form validation
- API parameter validation in controllers

**Authentication:**
- Devise for user authentication (session-based cookies)
- OAuth via OmniAuth (Facebook, Google, Twitter)
- Session sharing between `www.jamkazam.local` (Rails) and `beta.jamkazam.local` (React) via `remember_token` cookie

---

*Architecture analysis: 2026-01-11*
*Update when major patterns change*
