ironoc

iRonoc Portfolio Application - Full Stack Architecture & Data Flows

This document delivers a comprehensive, highly granular technical breakdown of the iRonoc architecture. It spans the system architecture, frontend structure, granular backend service layer, and showcases deep functional flow sections for Donate Items, Portfolio Items, and Brews/Coffee subsystems.


1. High-Level System Architecture

The iRonoc portfolio platform is structured as a decoupled, multi-tier full-stack application. It integrates a high-performance Java 25 / Spring Boot backend (embedded Tomcat) with a responsive, client-side routed React 19 single-page application (SPA).

+---------------------------------------------------------------------------------------------------+
|                                       Client Web Browser                                          |
|  - Renders UI elements (React 19, Material UI 7, Bootstrap 5)                                     |
|  - Triggers Client-Side Routes, REST Calls, and real-time GraphQL Subscription streams            |
+-------------------------------------------------+-------------------------------------------------+
                                                  |
                                                  | HTTP / HTTPS / WSS (WebSockets)
                                                  v
+---------------------------------------------------------------------------------------------------+
|                                      Gateway / Proxy Layer                                        |
|  - Serves compiled, static frontend bundles (.js, .css, .html) from Tomcat /static mapping        |
|  - Reverse-proxies API endpoints (/api/*) and GraphQL gateways (/graphql) to active servlet hooks |
+-------------------------------------------------+-------------------------------------------------+
                                                  |
                                                  v
+---------------------------------------------------------------------------------------------------+
|                                Spring Boot Backend (Tomcat)                                       |
|                                                                                                   |
|   +---------------------------------------+       +-------------------------------------------+   |
|   |          REST Controllers             |       |            GraphQL Controllers            |   |
|   |  - DonateRestController               |       |  - DonateGraphqlController (Sinks.Many)   |   |
|   |  - CoffeeController                   |       |  - BrewGraphqlController                  |   |
|   |  - ActivityTrackingController         |       |  - PortfolioItemsResolver (QueryMapping)  |   |
|   +-------------------+-------------------+       +-------------------+-----------------------+   |
|                       |                                               |                           |
|                       +-----------------------+-----------------------+                           |
|                                               |                                                   |
|                                               v                                                   |
|   +-------------------------------------------------------------------------------------------+   |
|   |                         Granular Backend Service & Resolver Layer                         |   |
|   |  - GitDetailsService (GitHub REST engine)                                                 |   |
|   |  - CoffeesService (REST Coffee parser) / GraphQLClientService (Custom GraphQL Client)     |   |
|   |  - In-Memory Caches: GitRepoCacheService, GitProjectCacheService, CoffeeCacheService      |   |
|   |  - Resolvers: DonateItemsResolver, PortfolioItemsResolver                                 |   |
|   +-------------------------------------------+-----------------------------------------------+   |
|                                               |                                                   |
+-----------------------------------------------v---------------------------------------------------+
                                                |
                      +-------------------------+-------------------------+
                      |                                                   |
                      v                                                   v
+---------------------------------------+       +---------------------------------------+
|          AWS Secrets Manager          |       |           Third-Party APIs            |
| - Retrieves GitHub personal keys      |       | - GitHub API (Issues, Repositories)   |
| - Secures backend configurations      |       | - External Coffee API REST/GraphQLs   |
+---------------------------------------+       +---------------------------------------+

2. Technical Sequence & System Blueprint Diagrams

These diagrams can be visualized natively inside IntelliJ IDEA (using the diagram viewer plugin), GitHub, or standard markdown readers.

1. Granular System Design Blueprint (C4 Container-level Detail)

This container blueprint details the precise boundaries, filter intercepts, servlet mappings, and multi-thread caching layers inside the Spring Boot container.

flowchart TB
    subgraph ClientContainer [Client Browser Container]
        SPA[React 19 SPA]
        Apollo[Apollo Client Link Splitter]
        Axios[Axios / sendBeacon Client]
    end

    subgraph SecurityFilterLayer [Tomcat Servlet Security & Mapping Layer]
        CORS[CorsRegistry Filter Mappings]
        Limiter[Bucket4j Rate Limiting Interceptor]
        Dispatcher[Spring DispatcherServlet]
        SockHandler[GraphQlWebSocketHandler]
    end

    subgraph ControllerLayer [Controller Endpoint Mappings]
        REST[REST API Endpoints: Coffee, Donate, Activity]
        GraphQL[GraphQL Engine Mappings: @QueryMapping, @MutationMapping]
    end

    subgraph ServiceCore [Granular Backend Service & Cache Engines]
        GitService[GitDetailsService]
        CoffeeService[CoffeesService]
        CacheManager[In-Memory ConcurrentHashMap Cache Managers]
        GitRepoCache[GitRepoCacheService]
        GitProjCache[GitProjectCacheService]
        CoffeeCache[CoffeeCacheService]
        DonResolver[DonateItemsResolver]
        PortResolver[PortfolioItemsResolver]
        Sink[Reactor Sinks.Many Multicast Channel]
    end

    subgraph Datastore [Classpath JSON Datastore Layer]
        DiskDonate[(json/donate-items.json)]
        DiskBrews[(json/brews.json)]
        DiskPortfolio[(json/portfolio-items.json)]
        DiskWhitelist[(graphql/charities.txt)]
    end

    subgraph External [External Network boundaries]
        AWS[AWS Secrets Manager API]
        GitAPI[GitHub REST API v3]
        CoffeeAPI[Third-Party Coffee REST / GraphQL APIs]
    end

    SPA -->|GraphQL Queries| Apollo
    SPA -->|HTTP / Telemetry Beacons| Axios

    Apollo -->|POST /graphql| CORS
    Apollo -->|WS ws://localhost:8080/graphql| CORS
    Axios -->|PUT/GET /api/*| CORS

    CORS --> Limiter
    Limiter --> Dispatcher
    Limiter --> SockHandler

    Dispatcher --> REST
    Dispatcher --> GraphQL
    SockHandler --> GraphQL

    REST --> GitService
    REST --> CoffeeService
    GraphQL --> DonResolver
    GraphQL --> PortResolver
    GraphQL --> Sink

    GitService --> GitRepoCache
    GitService --> GitProjCache
    CoffeeService --> CoffeeCache

    GitRepoCache --> CacheManager
    GitProjCache --> CacheManager
    CoffeeCache --> CacheManager

    DonResolver --> DiskDonate
    DonResolver --> DiskWhitelist
    PortResolver --> DiskPortfolio

    GitService -->|GET Request / Bearer Token| GitAPI
    GitService -->|Query Access Tokens| AWS
    CoffeeService -->|GET Request| CoffeeAPI

2. Comprehensive UX Journey Flow

This flowchart maps the sequential UX transitions, modal interactions, loading states, and live interface updates available to the user.

flowchart TD
    Start([User Opens App]) --> Home[Renders Landing Page - Consistent Navy Theme]
    
    Home --> NavProjects{Navigates App}
    
    %% Projects UX Flow
    NavProjects -->|Projects Link| Projects[Renders RepoDetails]
    Projects --> LoadProjects[Check Cached Repository Data]
    LoadProjects -->|Miss / Load| ShowSpinner1[Display LoadingSpinner]
    ShowSpinner1 --> Hydrated1[Render Grid Cards with Repo Details]
    LoadProjects -->|Hit| Hydrated1
    Hydrated1 --> ClickRepo[User Clicks Specific Repo Card]
    ClickRepo --> Issues[Open RepoIssues Backlog]
    Issues --> Recharts[Display Interactive Recharts Bar Chart of Active Issues]

    %% Brews UX Flow
    NavProjects -->|Brews Link| CoffeeHome[Renders CoffeeHome]
    CoffeeHome --> LoadRecipes[Check In-Memory CoffeeCacheService]
    LoadRecipes -->|Miss| GetExtRecipes[Fetch Recipes from External Coffee API]
    GetExtRecipes --> JacksonParser[Deserialize & Map to CoffeeDomain via Jackson]
    JacksonParser --> Hydrated2[Render Coffee Carousel with preparation cards]
    LoadRecipes -->|Hit| Hydrated2

    %% Donate UX Flow
    NavProjects -->|Donate Link| Donate[Renders Donate Carousel]
    Donate --> HydrateDonate[Execute GET_DONATE_ITEMS Query]
    HydrateDonate --> LoadWhitelist[Filter On-Disk Charities via charities.txt Allowed List]
    LoadWhitelist --> RenderCarousel[Render Red Carousel Cards with Verified Charities]
    
    RenderCarousel --> OpenModal[User Clicks 'Add Charity' Button]
    OpenModal --> InputDetails[Input Charity Details in Registration Form]
    InputDetails --> ValidateForm{Form Fields Validated?}
    
    ValidateForm -->|Invalid format/year/protocol| FormError[Display Specific Warning message inside form]
    FormError --> InputDetails
    
    ValidateForm -->|Valid details| DispatchMutation[Submit addCharityOption Mutation to GraphQL Server]
    DispatchMutation --> CheckServerWhitelist{Name is Whitelisted in charities.txt?}
    
    CheckServerWhitelist -->|No / Fraud attempt| ServerError[Reject transaction & throw Validation error]
    ServerError --> Donate
    
    CheckServerWhitelist -->|Yes| PersistServer[Append details to json/donate-items.json]
    PersistServer --> SinkEmit[Emit next charity to Multicast Sink]
    
    SinkEmit --> PushWS[Push Event pushed instantly over ws://localhost:8080/graphql]
    PushWS --> UpdateState[Client subscription state appends new card dynamically]
    UpdateState --> RenderCarousel

3. Donate Subsystem: Mutation & WebSocket Broadcast Sequence

This sequence diagram tracks the full transactional life cycle when a user registers a new charity, from validation to real-time sync.

sequenceDiagram
    autonumber
    actor Client as Client Browser
    participant Controller as DonateGraphqlController
    participant Resolver as DonateItemsResolver
    participant Sink as Sinks.Many (Multicast Buffer)
    participant Disk as JSON Datastore

    Client->>Controller: Mutation: addCharityOption(...)
    activate Controller
    Controller->>Resolver: addDonateItem(Item)
    activate Resolver
    Resolver->>Resolver: Validate URL, Founding Year, & Email
    Resolver->>Resolver: Check charities.txt whitelist

    alt Item is Malformed or Exists
        Resolver-->>Controller: Return false (invalid transaction)
        Controller-->>Client: Return Failure Message
    else Item is Valid & New
        Resolver->>Disk: Persist payload to JSON datastore
        Resolver-->>Controller: Return true (success)
        deactivate Resolver

        Controller->>Sink: tryEmitNext(newItem)
        activate Sink
        Sink-->>Controller: Confirmed Emit to Multicast buffer
        deactivate Sink

        par Broadcast real-time WebSocket update
            Controller-->>Client: WebSocket push: donateItemsSubscription (newItem)
        and Acknowledge original client request
            Controller-->>Client: Return Success Message / DTO
            deactivate Controller
        end
    end

4. Brews/Coffee Retrieval & Caching Flow

This sequence diagram details the fallback and deserialization pipeline when querying coffee brewing instructions.

sequenceDiagram
    autonumber
    actor Client as Client Browser
    participant Controller as CoffeeController
    participant Cache as CoffeeCacheService
    participant Service as CoffeesService / GraphQLClient
    participant Ext as External Coffee APIs (REST/GraphQL)

    Client->>Controller: GET /api/coffees
    activate Controller
    Controller->>Cache: get()
    activate Cache

    alt Cache Hit (In-Memory Available)
        Cache-->>Controller: Return Cached CoffeeDomain List
        Controller-->>Client: Return JSON payload (<50ms response)
    else Cache Miss (Empty / Evicted)
        Cache-->>Controller: Return null
        deactivate Cache

        Controller->>Service: getCoffeeDetails() / fetchCoffeeDetails()
        activate Service
        Service->>Ext: Query remote REST/GraphQL resources
        activate Ext
        Ext-->>Service: Return raw payload (ingredients as text array)
        deactivate Ext

        Service->>Service: Custom Deserialization (IngredientsDeserializer)
        Service->>Service: Map payload to CoffeeDomain collection
        Service-->>Controller: Return mapped list
        deactivate Service

        Controller->>Cache: put(coffeeDomains)
        activate Cache
        Cache-->>Controller: Confirmed hydrate cache
        deactivate Cache

        Controller-->>Client: Return newly compiled JSON payload
        deactivate Controller
    end

3. Charity & Donation Subsystem (Primary Feature)

The Charity and Donation subsystem is a primary component of the iRonoc platform. It delivers real-time charity registration, cryptographic verification, and reactive synchronization between multiple client browsers and the datastore.

 [ Client: Donate.js ]        [ Spring Controllers ]       [ DonateItemsResolver ]      [ Datastore / Disk ]
           |                            |                             |                           |
           |---- GraphQL Query -------->|                             |                           |
           |   (getDonateItems)         |---- getDonateItems() ------>|                           |
           |                            |                             |---- load classpath ------>| [ donate-items.json ]
           |                            |                             |---- validate year/URLs -->| [ charities.txt ]
           |<--- JSON Charity List -----|<--- filtered list ----------|                           |
           |                            |                             |                           |
           |                            |                             |                           |
           |---- GraphQL Mutation ----->|                             |                           |
           |   (addCharityOption)       |---- addDonateItem(Item) --->|                           |
           |                            |                             |--- write to class resource| [ donate-items.json ]
           |                            |                             |                           |
           |                            |--- Sink: tryEmitNext()      |                           |
           |<--- Mutated Confirmation --|      (Broadcast to WS)      |                           |
           |                            |                             |                           |

1. User Interface (components/Donate.js)

The React frontend component renders a responsive Material-UI and Bootstrap grid layout of active, trusted charity options:

2. Backend API Architecture

3. Verification & Allowed Lists (Datastore Structure)

To preserve the security of the application and mitigate spam or malicious scripts (e.g. cross-site scripting inputs), the backend enforces strict validation criteria in DonateItemsResolver.java:

  1. The Trusted Allowed List (charities.txt): Located at src/main/resources/graphql/charities.txt. This contains the exact, trimmed, case-insensitive names of charities permitted to be displayed on the platform. If an added name does not exist in this list, registration is blocked.
  2. The JSON Datastore (donate-items.json): Located at src/main/resources/json/donate-items.json. Stores the details of the active, whitelisted charities in JSON format:
    {
      "alt": "Jack and Jill Foundation",
      "name": "The Jack and Jill Children's Foundation",
      "link": "https://www.jackandjill.ie",
      "donate": "https://www.jackandjill.ie/how-you-can-help/donate/",
      "img": "jack-and-jill-logo.png",
      "overview": "Provides direct funding and home nursing care to children with highly complex medical conditions.",
      "founded": 1997,
      "phone": "+353 (0) 45 894 538"
    }
    
  3. Structured Verification Engines:
    • Founding Year: Must be between 1000 and 2100.
    • URL Integrity: Links (link and donate) are parsed and verified using a strict HTTP/HTTPS pattern.
    • Contact Format: Phone numbers and emails are run through explicit formatting regex engines (checking international prefix structures and standard email structures).

4. How to Add Your Charity to the Platform

To register and demonstrate your charity on this platform:

  1. Ensure your charity’s name is whitelisted inside charities.txt.
  2. Add your charity’s detailed JSON block to json/donate-items.json or submit it via the frontend Donation portal.

📢 Important Security Notice: To protect users, only trusted charities are permitted. If your desired charity is not currently supported, please reach out directly to conorheffron on GitHub (username: conorheffron / @conorheffron) to submit your charity’s credentials and request to have its name appended to the trusted whitelisted (charities.txt) file.


4. Comprehensive Frontend Architecture

The frontend is built using React 19 (ES6+) as a Single-Page Application (SPA). It manages routing in the browser using React Router 7, performs data queries via REST (Axios/Fetch) or GraphQL (Apollo Client), and utilizes modern reactive UI controls.

1. Component Hierarchy and Rendering Topology

                                  +-------------------+
                                  |    App.js Entry   |
                                  |  (Router Engine)  |
                                  +---------+---------+
                                            |
                                  +---------v---------+
                                  |    AppNavbar.js   |
                                  | (Bootstrap/MUI 7) |
                                  +---------+---------+
                                            |
                  +-------------------------+-------------------------+
                  |                                                   |
                  v (Static/View routes)                              v (Dynamic/Functional routes)
        +---------+-----------+                             +---------+---------+
        | Static Presentation |                             | State & API Driven|
        +---------+-----------+                             +---------+---------+
                  |                                                   |
    +-------------+-------------+                       +-------------+-------------+
    |             |             |                       |             |             |
    v             v             v                       v             v             v
 About.js      Home.js     NotFound.js              Donate.js    CoffeeHome.js   RepoDetails.js
 (Profile)    (Landing)     (404 Page)            (Charity Grid)  (Brews list)   (Backlog View)
                                                        |             |             |
                                                        v             v             v
                                                 [Apollo Client]  [Fetch API]   [Axios REST]

2. Frontend Modules & Logical Roles


5. Granular Backend Service Layer

The backend uses a service-driven, cache-optimized structure to coordinate Spring Controllers with third-party networks and filesystem records.

       +---------------------------------------------------------------------------------+
       |                              Spring Controllers                                 |
       +-------+-------------------------+------------------------+------------------+---+
               |                         |                        |                  |
               v                         v                        v                  v
+--------------+--------------+ +--------+--------+ +-------------+-------------+ +--+----------------+
|       GitDetailsService     | |  BrewsResolver  | |     DonateItemsResolver   | |ActivityTracking   |
|  - Coordinates git calls    | | - Loads brews   | | - Loads, validates, lists | |     Service       |
|  - Thread-safe repository   | |   local JSON    | |   permitted charities     | | - Receives click  |
+--------------+--------------+ +--------+--------+ +-------------+-------------+ |   beacons         |
               |                         |                        |               +--+----------------+
        +------+------+                  v                        v                  |
        |             |         +-----------------+      +-----------------+         v
        v             v         |  Brews Datastore|      |  Charity Files  |  +------+------+
  +-----+---+   +-----+---+     | (json/brews.json|      | (charities.txt  |  | Activity    |
  |GitRepo  |   |GitProj  |     +-----------------+      |  donate-items)  |  | Datastore   |
  |  Cache  |   |  Cache  |                              +-----------------+  +-------------+
  +---------+   +---------+

1. Repository & Project Services (net.ironoc.portfolio.service)

2. Resolution Services (net.ironoc.portfolio.graph)

3. Client & Integration Services (net.ironoc.portfolio.client / net.ironoc.portfolio.aws)


6. Granular Functional Flows & Subsystem Pipelines

This section details how the platform executes its core workflows across the React client, Spring Controllers, Service Layer, and Datastores.

1. Portfolio Items Flow

This module parses and delivers static portfolio metrics and highlight carousels.

 [ Client: Portfolio.js ]       [ PortfolioController ]       [ PortfolioItemsResolver ]    [ Datastore / Disk ]
            |                              |                              |                            |
            |---- GraphQL Query ---------->|                              |                            |
            |   (portfolioItems)           |---- getPortfolioItems() ---->|                            |
            |                              |                              |--- load from classpath --->| [ portfolio-items.json ]
            |<--- JSON Portfolio list -----|<--- map to response List ----|                            |

The coffee subsystem coordinates external APIs, in-memory caches, local configurations, and custom Jackson deserializers to serve detailed brewing instructions.

 [ Client: CoffeeHome.js ]      [ CoffeeController ]        [ Coffee Services ]        [ Ext. Web / GraphQL ]
            |                             |                          |                           |
            |---- GET /api/coffees ------>|                          |                           |
            |                             |--- check cache --------->|                           |
            |                             |    (CoffeeCacheService)  |                           |
            |                             |    [Hit: return list]    |                           |
            |                             |                          |                           |
            |                             |    [Miss: fetch rest]--->|                           |
            |                             |                          |=== REST: fetch hot/ice ==>| [ https://api.sampleapis.com ]
            |                             |                          |<== Map to CoffeeDomain ===|
            |                             |                          |                           |
            |                             |    [Miss: fetch Graph]-->|                           |
            |                             |                          |=== GraphQL Client =======>| [ GraphQL Coffee Server ]
            |                             |                          |<== Map to Map<Str,Obj> ===|
            |<--- JSON Coffee Domain -----|<--- Update Cache --------|                           |

7. Test Standards and Metrics

To guarantee build safety and code correctness, the project enforces strict test coverage limits (Minimum 80% coverage on all modifications):