logicspike/docs

gateway

Gateway — System Overview

Last Updated: 2026-05-14 Status: Active Service: apps/gateway Live URL: https://api.vlozi.app Dev URL: http://localhost:8788

The Gateway is the single public entry point for every Vlozi API call. No downstream Worker (blog, brain, media, etc.) is reachable from the internet — all traffic must pass through the Gateway first.


1. What the Gateway Does

Responsibility How
Rate limiting Fixed-window counter per IP, KV-backed in production
CORS enforcement Strict origin whitelist for dashboard; open * for public SDK routes
JWT authentication Verifies RS256 access tokens via @repo/core-auth
API-key authentication SHA-256 hash lookup with 3-tier cache (memory → KV → DB)
PBAC service-access check assertServiceAccess from @repo/core-access
Subscription gate Blocks paid features when tenant is canceled, past_due, or trialing+expired
Request forwarding Cloudflare Service Bindings — zero public-internet hop
Identity injection Appends x-tenant-id, x-user-id, x-user-permissions, x-user-services
Trace correlation Generates x-request-id UUID per authenticated request

2. Technology Stack

Layer Technology
Runtime Cloudflare Workers (edge, V8 isolate)
Framework Hono v4
Service routing Cloudflare Service Bindings (internal, no network overhead)
Persistent state Cloudflare KV (RATE_LIMIT_KV)
Database Neon Postgres via @neondatabase/serverless + Drizzle ORM
Build / deploy Wrangler v4
Type safety TypeScript — @cloudflare/workers-types

3. System Topology

Full infrastructure map — every client type, every middleware layer with its data sources, every downstream service.


4. Full Request Processing Pipeline

Every decision the Gateway makes, in order. Every diamond is a conditional branch; red terminals are rejections.

4.1 Phase 1 — Rate Limit + CORS

4.2 Phase 2 — Authentication

4.3 Phase 3 — PBAC, Subscription Guard, and Proxy


5. Project File Structure

apps/gateway/
├── wrangler.toml              # Worker config: name, bindings, KV, routes
├── package.json
├── tsconfig.json
├── .env                       # Local dev vars (gitignored)
└── src/
    ├── index.ts               # App root: middleware order, route mounting, /health
    ├── context.ts             # Hono ContextVariableMap augmentation
    ├── types.ts               # GatewayBindings type (all env bindings)
    ├── db/
    │   └── client.ts          # createCoreDb() — neon-http Drizzle handle
    ├── middleware/
    │   ├── rate-limit.middleware.ts    # Fixed-window rate limiter (KV + memory)
    │   ├── auth.middleware.ts          # JWT RS256 verification
    │   ├── api-key.middleware.ts       # API-key lookup with 3-tier cache
    │   ├── access.middleware.ts        # PBAC service-entitlement check
    │   └── subscription.middleware.ts  # Billing-state gate
    ├── routes/
    │   ├── blog.proxy.ts        # /blog/admin/* (JWT) + /blog/public/* (API key)
    │   ├── media.proxy.ts       # /media/upload/* + /media/files/* (JWT)
    │   ├── manager.proxy.ts     # /manager/* (JWT, with public-path exceptions)
    │   ├── content.proxy.ts     # /content/* (JWT + subscription)
    │   ├── brain.proxy.ts       # /brain/* (JWT + subscription)
    │   ├── contacts.proxy.ts    # /contacts-intel/* (JWT + subscription)
    │   ├── newsletter.proxy.ts  # /newsletter/* (JWT) + /newsletter/public/* (API key / open)
    │   ├── comms.proxy.ts       # /comms/* (JWT + subscription)
    │   └── chatbot.proxy.ts     # /chatbot/* (JWT + subscription)
    └── utils/
        ├── proxy.utils.ts       # proxyFetch, proxyResponseArgs, buildDownstreamHeaders
        └── logger.ts            # logSystem / logError / logInfo (structured JSON)

6. Environment Bindings Reference

6.1 Service Bindings (Worker-to-Worker, zero-latency)

Binding Downstream Worker
BLOG_SERVICE logicspike-blog-service
MEDIA_SERVICE logicspike-media
MANAGER_SERVICE logicspike-manager
CONTENT_ENGINE_SERVICE logicspike-content-engine
BRAIN_SERVICE logicspike-brain-service
CI_SERVICE logicspike-contact-intelligence
NL_SERVICE logicspike-newsletter
COMMS_SERVICE logicspike-communication
CE_SERVICE logicspike-chat-engine

6.2 KV Namespaces

Binding KV Key Prefix Purpose
RATE_LIMIT_KV rl:{ip} Rate-limit counters per IP
RATE_LIMIT_KV ak:{sha256(key)} API-key lookup cache

Both use the same KV namespace. The rl: and ak: prefixes prevent key collisions.

6.3 Secrets

Set via wrangler secret put (production) or .dev.vars (local — never commit).

Variable Type Purpose
JWT_PUBLIC_KEY RS256 PEM string Verifies access tokens issued by manager
GATEWAY_SECRET Random string Shared secret forwarded as x-gateway-key to downstream workers
DATABASE_URL Neon connection string API-key lookups + subscription checks
DEBUG "true" / unset Enables trace logging and debug endpoints

7. CORS Policy

Two tiers of CORS are applied in order in src/index.ts:

7.1 Public SDK Routes (open *)

Route Allowed methods
/blog/public/* GET, OPTIONS
/newsletter/public/* POST, OPTIONS

7.2 All Other Routes (strict whitelist)

https://go.vlozi.app          (seller dashboard)
https://vlozi.app             (marketing site)
https://www.vlozi.app
https://docs.vlozi.app
https://logicspike-office.vercel.app   (legacy — remove after DNS cutover)
https://logicspike.com                 (legacy)
https://app.logicspike.com             (legacy)
http://localhost:3000
http://localhost:3001
http://localhost:3002

8. Health Check

GET /health

Returns 200 OK with a JSON object indicating whether every binding is present. No auth required.

{
  "status": "ok",
  "env": {
    "BLOG_SERVICE": true,
    "MANAGER_SERVICE": true,
    "JWT_PUBLIC_KEY": true,
    "RATE_LIMIT_KV": true
  }
}

gateway