ES03 - Host, Tenant and Session Hydration

Summary

This document outlines the process of hydrating a context throughout the echo’s pipeline to allow downstream handlers and middlewares to extract tenant-related information without having to repeatedly query cache or databases.

Pipeline Diagram

The following diagram was drawn by an LLM.

Client (browser / iPad / POS terminal)
          |
          | HTTPS request
          v
[Public Internet]
          |
          v
    VPS Public IP
          |
          |
          v
Caddy (Docker container, internal on :80)
          |
          |
          v
Echo / Go Backend (Docker container)
          |
          +--> [CORSMiddleware]
          |      - Dynamic CORS middleware to adapt to what current tenants
          |        there are registered with us.
          |      - Uses Valkey for caching.
          |
          +--→ [HostHydrate Middleware]  <--- Reads Host header
          |      - Extracts tenant_id from subdomain (e.g. twinbells)
          |      - Validates domain suffix
          |      - Sets c.Set("tenant_id", "twinbells")
          |      - Sets c.Set("is_pos", true) if prefixed with POS
          |
          +--→ [SessionHydrate Middleware]
          |      - Reads session cookie
          |      - Loads session from Valkey
          |      - Handles stale session here with rotated_to
          |      - Sets c.Set("session", sessionData)
          |
          +--> [TenantHydrate Middleware]
          |      - Reads sessionData from SessionHydrate.
          |      - If not a guest, collect permissions if they are on a tenant's
          |        host or POS host.
          |      - Sets c.Set("permissions", permissions)
          |
          +--> [HasPermission Middleware] (OPTIONAL)
          |      - Reads permissions from TenantHydrate
          |      - Blocks with 403 Forbidden if not enough permissions.
          |
          v
Route Handler (e.g. /menus, /orders, /inventory)
          |
          +--→ Uses c.Get("tenant_id") and c.Get("session")
          |      - Fetches menus / data for the correct tenant
          |      - Applies permissions from session
          |
          v
Response back through Caddy → Nginx → Client

The rationale for this is to allow tenant-level scoping in all endpoints, so clients don’t have to keep appending a query parameter like ?tenant_id=edbdf736-1c2d-4035-8e70-81f1afd76bbf every time they want to retrieve something, which is rather ugly in my opinion.


Back to top

© Nguyệt Ánh 2025. Licensed under CC BY-SA 4.0.

This site uses Just the Docs, a documentation theme for Jekyll.