Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

HH-Felidae Architecture

This document provides an overview of the HungryHub Felidae platform architecture.

System Overview

The HH-Felidae platform follows a microservices architecture with the following main components:

ServiceDescriptionHosting
hh-pegasusEnd-user frontend (customer-facing web app)Cloudflare Pages
hh-jaguarAdmin dashboard (CMS & management)Cloudflare Pages
hh-pumaSearch service (GraphQL + OpenSearch + BullMQ)Kubernetes (EKS)
hh-tigerCore backend (GraphQL + Multi-DB + BullMQ)Kubernetes (EKS)

Architecture Diagram

flowchart TB
    subgraph Users["👥 Users"]
        EndUser["End Users"]
        Admin["Admin Users"]
    end

    subgraph Cloudflare["☁️ Cloudflare"]
        direction TB
        
        subgraph CF_Pages["Cloudflare Pages"]
            Pegasus["hh-pegasus<br/>Astro"]
            Jaguar["hh-jaguar<br/>Nuxt.js"]
        end
    end

    subgraph AWS["☁️ AWS/Cloud Infrastructure"]
        subgraph ALB_Layer["Load Balancing"]
            ALB["AWS Application Load Balancer<br/>(hh-felidae)"]
        end

        subgraph EKS["Amazon EKS (Kubernetes)"]
            direction TB
            
            subgraph Puma_Services["hh-puma (Search Service)"]
                Puma["hh-puma<br/>Port: 4000<br/>Fastify + Mercurius GraphQL"]
                PumaInternal["hh-puma-internal<br/>Port: 4000<br/>(Worker Mode)"]
            end
            
            subgraph Tiger_Services["hh-tiger (Core Backend)"]
                Tiger["hh-tiger<br/>Port: 4000<br/>Fastify + Mercurius GraphQL"]
                TigerInternal["hh-tiger-internal<br/>Port: 4000<br/>(Worker Mode)"]
            end
        end

        subgraph Databases["Databases"]
            DB1[("db1<br/>MySQL (Legacy)<br/>Read-only")]
            DB2[("db2<br/>PostgreSQL<br/>Data Warehouse")]
            DB3[("db3<br/>PostgreSQL<br/>Core App DB")]
        end
        
        subgraph Cache_Queue["Cache & Queue"]
            Redis[("Redis<br/>Cache + BullMQ")]
            Kafka["Apache Kafka<br/>(Event Streaming)"]
        end
        
        subgraph Search["Search"]
            OpenSearch[("OpenSearch<br/>Restaurant Index")]
        end

        subgraph ML_Layer["ML & Recommendations"]
            Personalize["AWS Personalize<br/>(Recommendations)"]
            Metarank["Metarank<br/>(Ranking)"]
        end

        subgraph Storage["Storage"]
            R2["Cloudflare R2<br/>(File Storage)"]
            S3["AWS S3<br/>(Events & Data)"]
        end
    end

    %% User connections
    EndUser -->|"web.hungryhub.com"| Pegasus
    Admin -->|"jaguar.hungryhub.com"| Jaguar
    
    %% Frontend to Backend
    Pegasus -->|"GraphQL API"| ALB
    Jaguar -->|"GraphQL API"| ALB
    
    %% ALB Routing
    ALB -->|"search.hungryhub.com<br/>puma.hungryhub.com"| Puma
    ALB -->|"puma-internal.hungryhub.com"| PumaInternal
    ALB -->|"tiger.hungryhub.com"| Tiger
    ALB -->|"tiger-internal.hungryhub.com"| TigerInternal
    
    %% Service to Data connections
    Tiger --> DB1
    Tiger --> DB2
    Tiger --> DB3
    Tiger --> Redis
    Tiger --> Kafka
    
    Puma --> DB1
    Puma --> OpenSearch
    Puma --> Redis
    Puma --> Kafka
    
    %% Internal workers
    TigerInternal --> Redis
    TigerInternal --> Personalize
    TigerInternal --> Kafka
    TigerInternal --> S3
    
    PumaInternal --> Redis
    PumaInternal --> OpenSearch
    PumaInternal --> Kafka
    
    %% ML connections
    Tiger --> Metarank
    Puma --> Metarank
    
    %% Storage
    Tiger --> R2
    
    %% Data flow
    Kafka -.->|"Restaurant Updates"| OpenSearch
    Kafka -.->|"User Events"| Personalize

    %% Styling
    classDef cloudflare fill:#f48120,stroke:#333,color:#fff
    classDef aws fill:#ff9900,stroke:#333,color:#fff
    classDef k8s fill:#326ce5,stroke:#333,color:#fff
    classDef database fill:#336791,stroke:#333,color:#fff
    classDef service fill:#68b983,stroke:#333,color:#fff
    classDef storage fill:#569a31,stroke:#333,color:#fff
    
    class Pegasus,Jaguar cloudflare
    class ALB,Personalize aws
    class Puma,PumaInternal,Tiger,TigerInternal k8s
    class DB1,DB2,DB3,Redis,OpenSearch database
    class R2,S3 storage

Network Topology

flowchart LR
    subgraph Internet["Internet"]
        Client["Client Browser"]
    end
    
    subgraph Cloudflare["Cloudflare Edge"]
        direction TB
        DNS["DNS (Proxied)"]
        Pages["Cloudflare Pages"]
    end
    
    subgraph AWS_VPC["AWS VPC"]
        subgraph Public["Public Subnet"]
            ALB["ALB<br/>hh-felidae"]
        end
        
        subgraph Private["Private Subnet"]
            EKS_Nodes["EKS Worker Nodes"]
            RDS["Databases"]
            ElastiCache["ElastiCache Redis"]
            OpenSearch["OpenSearch"]
        end
    end
    
    Client --> DNS
    DNS --> Pages
    DNS --> ALB
    ALB --> EKS_Nodes
    EKS_Nodes --> RDS
    EKS_Nodes --> ElastiCache
    EKS_Nodes --> OpenSearch

Service Communication

flowchart LR
    subgraph Frontend["Frontend Apps"]
        Pegasus["hh-pegasus<br/>(User App)"]
        Jaguar["hh-jaguar<br/>(Admin)"]
    end
    
    subgraph Backend["Backend Services"]
        Tiger["hh-tiger<br/>(Core API)"]
        Puma["hh-puma<br/>(Search API)"]
    end
    
    subgraph Async["Async Processing"]
        TigerWorker["hh-tiger-internal<br/>(Background Jobs)"]
        PumaWorker["hh-puma-internal<br/>(Index Workers)"]
    end
    
    Pegasus -->|"GraphQL<br/>(search queries)"| Puma
    Pegasus -->|"GraphQL<br/>(core operations)"| Tiger
    Jaguar -->|"GraphQL<br/>(admin operations)"| Tiger
    
    Tiger -->|"BullMQ Jobs"| TigerWorker
    Puma -->|"BullMQ Jobs"| PumaWorker
    
    Tiger <-->|"Internal API"| Puma

Domain Routing

DomainServiceDescription
web.hungryhub.comhh-pegasusMain user-facing website
jaguar.hungryhub.comhh-jaguarAdmin dashboard
search.hungryhub.comhh-pumaSearch GraphQL API (alias)
puma.hungryhub.comhh-pumaPuma GraphQL API
puma-internal.hungryhub.comhh-puma-internalPuma internal/worker
tiger.hungryhub.comhh-tigerTiger GraphQL API
tiger-internal.hungryhub.comhh-tiger-internalTiger internal/worker

Kubernetes Deployment Structure

flowchart TB
    subgraph EKS["Amazon EKS Cluster"]
        subgraph NS["Namespace: hungryhub"]
            subgraph Puma_Deploy["hh-puma Deployment"]
                PumaService["Service: hh-puma<br/>ClusterIP:4000"]
                PumaPods["Pods: hh-puma<br/>Replicas: N"]
            end
            
            subgraph PumaInt_Deploy["hh-puma-internal Deployment"]
                PumaIntService["Service: hh-puma-internal<br/>ClusterIP:4000"]
                PumaIntPods["Pods: hh-puma-internal<br/>WORKER_ENABLED=true"]
            end
            
            subgraph Tiger_Deploy["hh-tiger Deployment"]
                TigerService["Service: hh-tiger<br/>ClusterIP:4000"]
                TigerPods["Pods: hh-tiger<br/>Replicas: N"]
            end
            
            subgraph TigerInt_Deploy["hh-tiger-internal Deployment"]
                TigerIntService["Service: hh-tiger-internal<br/>ClusterIP:4000"]
                TigerIntPods["Pods: hh-tiger-internal<br/>WORKER_ENABLED=true"]
            end
            
            ConfigMaps["ConfigMaps:<br/>hh-puma-config<br/>hh-tiger-config"]
        end
        
        Ingress["Ingress: hh-felidae<br/>(ALB Controller)"]
    end
    
    ALB["AWS ALB"] --> Ingress
    Ingress --> PumaService
    Ingress --> PumaIntService
    Ingress --> TigerService
    Ingress --> TigerIntService
    
    PumaService --> PumaPods
    PumaIntService --> PumaIntPods
    TigerService --> TigerPods
    TigerIntService --> TigerIntPods
    
    ConfigMaps -.-> PumaPods
    ConfigMaps -.-> PumaIntPods
    ConfigMaps -.-> TigerPods
    ConfigMaps -.-> TigerIntPods

Technology Stack

Frontend (Cloudflare Pages)

  • hh-pegasus: Astro, TailwindCSS
  • hh-jaguar: Nuxt.js, vue-shadcn/ui, TailwindCSS, TanStack Query, urql GraphQL

Backend (Kubernetes)

  • hh-puma: Fastify, Mercurius GraphQL, OpenSearch, BullMQ, Kafka
  • hh-tiger: Fastify, Mercurius GraphQL, Drizzle ORM (Multi-DB), BullMQ, AWS Personalize

Infrastructure

  • DNS/CDN: Cloudflare (proxied)
  • Load Balancer: AWS Application Load Balancer
  • Container Orchestration: Amazon EKS (Kubernetes)
  • Databases: MySQL (legacy), PostgreSQL (warehouse + app)
  • Cache/Queue: Redis + BullMQ
  • Search: OpenSearch
  • Event Streaming: Apache Kafka
  • ML/Recommendations: AWS Personalize, Metarank
  • File Storage: Cloudflare R2, AWS S3