feat: wire brain service to platform gateway

- Gateway proxies /api/brain/* to brain-api:8200/api/* via pangolin network
- User identity injected via X-Gateway-User-Id header
- Brain app registered in gateway database (sort_order 9)
- Added to GATEWAY_KEY_SERVICES for dashboard integration
- Tested: health, config, list, create all working through gateway

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yusuf Suleman
2026-04-01 16:32:53 -05:00
parent c9e776df59
commit 2072c359aa
34 changed files with 16745 additions and 1379 deletions

View File

@@ -22,6 +22,7 @@ SHELFMARK_URL = os.environ.get("SHELFMARK_URL", "http://shelfmark:8084")
SPOTIZERR_URL = os.environ.get("SPOTIZERR_URL", "http://spotizerr-app:7171")
BUDGET_URL = os.environ.get("BUDGET_BACKEND_URL", "http://localhost:3001")
TASKS_URL = os.environ.get("TASKS_BACKEND_URL", "http://tasks-service:8098")
BRAIN_URL = os.environ.get("BRAIN_BACKEND_URL", "http://brain-api:8200")
# ── Service API keys (for internal service auth) ──
INVENTORY_SERVICE_API_KEY = os.environ.get("INVENTORY_SERVICE_API_KEY", "")

View File

@@ -188,7 +188,7 @@ def handle_dashboard(handler, user):
conn.close()
# Services that use gateway-injected API keys (not per-user tokens)
GATEWAY_KEY_SERVICES = {"inventory", "reader", "books", "music", "budget", "tasks"}
GATEWAY_KEY_SERVICES = {"inventory", "reader", "books", "music", "budget", "tasks", "brain"}
widgets = []
futures = {}

View File

@@ -8,7 +8,7 @@ import bcrypt
from config import (
DB_PATH, TRIPS_URL, FITNESS_URL, INVENTORY_URL,
MINIFLUX_URL, SHELFMARK_URL, SPOTIZERR_URL, BUDGET_URL, TASKS_URL,
MINIFLUX_URL, SHELFMARK_URL, SPOTIZERR_URL, BUDGET_URL, TASKS_URL, BRAIN_URL,
)
@@ -129,6 +129,13 @@ def init_db():
conn.commit()
print("[Gateway] Added tasks app")
# Ensure brain app exists
brain = c.execute("SELECT id FROM apps WHERE id = 'brain'").fetchone()
if not brain:
c.execute("INSERT INTO apps VALUES ('brain', 'Brain', 'brain', '/brain', ?, 9, 1, NULL)", (BRAIN_URL,))
conn.commit()
print("[Gateway] Added brain app")
# Seed admin user from env vars if no users exist
import os
user_count = c.execute("SELECT COUNT(*) FROM users").fetchone()[0]

View File

@@ -303,6 +303,11 @@ class GatewayHandler(ResponseMixin, BaseHTTPRequestHandler):
if user:
headers["X-Gateway-User-Id"] = str(user["id"])
headers["X-Gateway-User-Name"] = user.get("display_name", user.get("username", ""))
elif service_id == "brain":
# Inject user identity for the brain service
if user:
headers["X-Gateway-User-Id"] = str(user["id"])
headers["X-Gateway-User-Name"] = user.get("display_name", user.get("username", ""))
elif user:
svc_token = get_service_token(user["id"], service_id)
if svc_token: