# melvinthomasdev/scribble-by-melvin-thomas architecture

> Architecture diagram of the GitHub repository melvinthomasdev/scribble-by-melvin-thomas, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-17). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/melvinthomasdev/scribble-by-melvin-thomas
- Repository: https://github.com/melvinthomasdev/scribble-by-melvin-thomas

## Overview

1. This repository is a monolithic Ruby on Rails application with a React-based frontend. The backend owns routing, persistence, business logic, background processing, and server-rendered/API responses; the frontend is bundled under `app/javascript` and consumes the Rails API.

2. The core domain is a content-management system centered on `Article`, `Category`, `Site`, `User`, and `Redirection`. Articles have versions, schedules, analytics/reporting, category assignment, slugs, authorship, and visit counts. Sites and users appear to be scoped together, suggesting multi-site or tenant-like separation.

3. There are two main user-facing surfaces. One is the authenticated dashboard under `app/javascript/src/components/Dashboard`, which handles article editing, categories, settings, analytics, and security. The other is the public interface under `app/controllers/api/v1/public` and matching React hooks/components, which exposes searchable/read-only article and category content.

4. The backend API is organized under `app/controllers/api/v1` and renders JSON through Jbuilder templates in `app/views/api/v1`. This API is the main contract for the React UI, with separate endpoints for articles, categories, users, sites, sessions, redirections, and article subresources such as schedules, versions, and reports.

5. Authentication and authorization are handled server-side in controller concerns like `authenticable`, `api_rescuable`, `redirectable`, and `set_honey_badger_context`. The frontend has route protection components such as `PrivateRoute` and an `Authenticate` wrapper, so the architecture splits access control between server enforcement and client navigation.

6. Business rules that are not simple CRUD are extracted into service objects under `app/services`. Important examples are article scheduling, deleting schedules, deleting categories, and seeding domain data. This keeps controllers thin and isolates workflow logic from the persistence layer.

7. Long-running or deferred work is handled by Sidekiq workers in `app/workers`. `ArticleSchedulingWorker` and `ReportsWorker` suggest asynchronous publication/scheduling and report generation flows, which likely update the database and then notify users when results are ready.

8. Real-time delivery is implemented with Action Cable. The `ReportDownloadChannel` on the Rails side and the matching JS consumer/channel code indicate a websocket-based notification path for report downloads, probably used by the analytics/reporting UI.

9. Reporting and analytics are a distinct subsystem. Articles have analytics JSON views, a PDF/HTML download view, and a dedicated reports controller. The dashboard analytics components and report download modal consume these endpoints and the websocket channel to drive report export workflows.

10. The frontend is organized as a React application with feature-oriented folders and custom React Query hooks. API wrappers live in `app/javascript/src/apis`, while reusable data-fetching hooks live in `app/javascript/src/hooks/reactQuery`; UI components consume those hooks instead of calling Rails directly.

11. Shared client-side infrastructure includes i18n, logging, local storage helpers, date utilities, and CSS/SCSS styling. The build is managed through Webpacker plus Babel, with Rails assets still present for images and manifests.

12. Data persistence is standard Rails/PostgreSQL, with Active Record models, migrations, validations, and factories/tests. Active Storage is enabled, so the app can store file attachments or generated artifacts, and Jbuilder templates serialize model data for API responses.

13. The app also includes operational scaffolding for Docker, Heroku-like deployment, Puma, and Sidekiq configuration. This indicates a production setup where the web server, job worker, and websocket server are separate processes sharing the same Rails codebase and database.

14. Overall, the best architecture diagram is a three-layer view: React client on top, Rails API/application in the middle, and PostgreSQL plus background/real-time services on the bottom. The main cross-cutting flows are authenticated dashboard CRUD, public content lookup, scheduled publication, and asynchronous report generation/download.

Main entry points: [`app/controllers/api/v1`](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/controllers/api/v1) (API controllers), [`app/javascript/src/hooks/reactQuery`](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/hooks/reactQuery) (API hooks), [`db/schema.rb`](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/db/schema.rb) (PostgreSQL), [`app/services`](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/services) (Services)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["React client"]
  node_client_app["React app<br/>frontend SPA<br/>[App.jsx]"]
  node_client_dashboard["Dashboard<br/>admin UI"]
  node_client_public["Public UI"]
  node_client_api["API hooks<br/>data access"]
end

subgraph group_server["Rails app"]
  node_server_routes["API routes<br/>routing<br/>[routes.rb]"]
  node_server_controllers["API controllers<br/>request layer"]
  node_server_concerns["Controller concerns<br/>cross-cutting auth/error handling"]
  node_server_views["Jbuilder views<br/>json serialization"]
  node_server_models[("Domain models<br/>Active Record domain")]
  node_server_services["Services<br/>workflow logic"]
  node_server_workers["Workers<br/>async jobs"]
  node_server_channels["Action Cable<br/>realtime"]
  node_server_mailers["Mailers<br/>notifications"]
end

subgraph group_infra["Runtime infra"]
  node_infra_db[("PostgreSQL<br/>persistent store<br/>[schema.rb]")]
  node_infra_runtime["Process config<br/>deployment/runtime<br/>[puma.rb]"]
end

node_client_app -->|"renders"| node_client_dashboard
node_client_app -->|"renders"| node_client_public
node_client_dashboard -->|"fetches data"| node_client_api
node_client_public -->|"fetches data"| node_client_api
node_client_api -->|"calls"| node_server_routes
node_server_routes -->|"dispatches"| node_server_controllers
node_server_controllers -->|"uses"| node_server_concerns
node_server_controllers -->|"reads/writes"| node_server_models
node_server_controllers -->|"serializes"| node_server_views
node_server_models -->|"persists to"| node_infra_db
node_server_services -->|"encapsulates rules"| node_server_models
node_server_services -->|"updates"| node_infra_db
node_server_workers -->|"executes"| node_server_services
node_server_workers -->|"reads/writes"| node_infra_db
node_server_channels -->|"pushes updates"| node_client_api
node_server_channels -->|"runs on"| node_infra_runtime
node_server_views -->|"contracts with"| node_client_api
node_server_controllers -->|"enqueues"| node_server_workers
node_server_controllers -->|"notifies"| node_server_channels
node_infra_runtime -->|"connects to"| node_infra_db
node_server_mailers -->|"delivers via"| node_infra_runtime

click node_client_app "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/app/javascript/src/App.jsx"
click node_client_dashboard "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/components/Dashboard"
click node_client_public "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/components/Dashboard/EndUserInterface"
click node_client_api "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/hooks/reactQuery"
click node_server_routes "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/config/routes.rb"
click node_server_controllers "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/controllers/api/v1"
click node_server_concerns "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/controllers/concerns"
click node_server_views "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/views/api/v1"
click node_server_models "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/models"
click node_server_services "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/services"
click node_server_workers "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/workers"
click node_server_channels "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/channels"
click node_server_mailers "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/mailers"
click node_infra_db "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/db/schema.rb"
click node_infra_runtime "https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/config/puma.rb"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_client_app,node_client_dashboard,node_client_public,node_client_api toneBlue
class node_server_routes,node_server_controllers,node_server_concerns,node_server_views,node_server_models,node_server_services,node_server_workers,node_server_channels,node_server_mailers toneAmber
class node_infra_db,node_infra_runtime toneMint
```

## Components

### React client

Frontend app, hooks, and UI surfaces

- [React app](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/app/javascript/src/App.jsx): frontend SPA · Bundled React client that drives the dashboard and public-facing UI. · `app/javascript/src/App.jsx`
- [Dashboard](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/components/Dashboard): admin UI · Authenticated content-management surface for articles, categories, settings, and analytics. · `app/javascript/src/components/Dashboard`
- [Public UI](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/components/Dashboard/EndUserInterface): public UI · Read-only search and browsing experience for published content. · `app/javascript/src/components/Dashboard/EndUserInterface`
- [API hooks](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/javascript/src/hooks/reactQuery): data access · React Query hooks and API wrappers used by the client to talk to Rails. · `app/javascript/src/hooks/reactQuery`

### Rails app

Controllers, models, services, views, jobs, and realtime

- [API routes](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/config/routes.rb): routing · Rails routing entrypoint for authenticated API, public API, and sidekiq/websocket endpoints. · `config/routes.rb`
- [API controllers](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/controllers/api/v1): request layer · Versioned Rails controllers for articles, categories, sites, users, sessions, redirections, and public content. · `app/controllers/api/v1`
- [Controller concerns](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/controllers/concerns): cross-cutting auth/error handling · Shared controller behavior for authentication, rescue handling, redirects, logging, and context. · `app/controllers/concerns`
- [Jbuilder views](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/views/api/v1): json serialization · API response templates and report download view rendered by Rails. · `app/views/api/v1`
- [Domain models](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/models): Active Record domain · Core content-management entities: articles, categories, sites, users, and redirections. · `app/models`
- [Services](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/services): workflow logic · Business workflows for scheduling, deletion, and seeding extracted from controllers. · `app/services`
- [Workers](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/workers): async jobs · Sidekiq-backed background jobs for scheduling and reports. · `app/workers`
- [Action Cable](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/channels): realtime · Websocket channel used for report download notifications. · `app/channels`
- [Mailers](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/tree/main/app/mailers): notifications · Rails mail delivery layer for transactional or operational email. · `app/mailers`

### Runtime infra

Database, background jobs, websockets, and deployment config

- [PostgreSQL](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/db/schema.rb): persistent store · Primary relational database backing the Rails models and job state. · `db/schema.rb`
- [Process config](https://github.com/melvinthomasdev/scribble-by-melvin-thomas/blob/main/config/puma.rb): deployment/runtime · Puma, Sidekiq, Cable, Docker, and environment configuration for production and local execution. · `config/puma.rb`

## Connections

- React app → Dashboard: renders · Main client app composes the authenticated dashboard surface.
- React app → Public UI: renders · Main client app also hosts the public browsing/search experience.
- Dashboard → API hooks: fetches data · Dashboard screens load and mutate content through hooks and API wrappers.
- Public UI → API hooks: fetches data · Public screens query read-only endpoints through the same client layer.
- API hooks → API routes: calls · React requests are routed to the Rails API and public endpoints.
- API routes → API controllers: dispatches · Routes resolve to versioned API controllers and public controllers.
- API controllers → Controller concerns: uses · Controllers share authentication, rescue, redirect, and logging concerns.
- API controllers → Domain models: reads/writes · Controllers orchestrate persistence and domain behavior through Active Record models.
- API controllers → Jbuilder views: serializes · API controllers render JSON and report responses through Jbuilder templates.
- Domain models → PostgreSQL: persists to · Active Record stores core CMS data in the database.
- Services → Domain models: encapsulates rules · Service objects implement domain workflows around articles, categories, schedules, and seeds.
- Services → PostgreSQL: updates · Workflow services apply multi-step changes to persisted data.
- Workers → Services: executes · Background jobs invoke service objects for deferred work.
- Workers → PostgreSQL: reads/writes · Jobs update persisted scheduling/reporting state.
- Action Cable → API hooks: pushes updates · Action Cable supports websocket-driven report download notifications consumed by the client.
- Action Cable → Process config: runs on · Websocket delivery depends on the Rails runtime process.
- Jbuilder views → API hooks: contracts with · JSON templates define the payloads consumed by hooks and UI components.
- API controllers → Workers: enqueues · Controllers trigger asynchronous scheduling and report generation.
- API controllers → Action Cable: notifies · Reporting flows can notify the client through Action Cable.
- Process config → PostgreSQL: connects to · Web, worker, and cable processes share the database.
- Mailers → Process config: delivers via · Mailers operate within the Rails application process and deployment setup.
