perf(oauth): Redis-cache getTokenCustomer to eliminate uncached DB hit on every ChatGPT API call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Garfield
2026-05-17 20:02:02 -04:00
parent 4746c4ee1c
commit 423dc89c94
2 changed files with 9 additions and 2 deletions

View File

@@ -22,7 +22,7 @@ spec:
fsGroup: 1000
containers:
- name: hermes-mcp
image: localhost:32000/hermes-mcp@sha256:0132eade2173eae3428a24757d2228253acf3f924f7a6c7a061f088e8d0dc891
image: localhost:32000/hermes-mcp@sha256:c65ffbbf87a8741c1c9d79e1b39be735535871a9968c680c2c8ff3fb108acfb0
imagePullPolicy: Always
securityContext:
allowPrivilegeEscalation: false

View File

@@ -1,6 +1,7 @@
import crypto from 'crypto';
import type { RowDataPacket } from 'mysql2/promise';
import { getPool, isPoolReady } from './db.js';
import redis from './redis.js';
const AUTH_CODE_EXPIRY_MS = 10 * 60 * 1000; // 10 minutes
const TOKEN_EXPIRY_MS = 24 * 60 * 60 * 1000; // 24 hours
@@ -298,13 +299,19 @@ export async function validateAccessToken(tokenValue: string): Promise<boolean>
export async function getTokenCustomer(tokenValue: string): Promise<{ customerId: string } | null> {
try {
const cacheKey = `oauth:token:${tokenValue}`;
const cached = await redis.get(cacheKey);
if (cached) return { customerId: cached };
const pool = getPool();
const [rows] = await pool.execute<RowDataPacket[]>(
'SELECT customer_id FROM oauth_tokens WHERE token = ? AND expires_at > NOW()',
[tokenValue]
);
if (!Array.isArray(rows) || rows.length === 0 || !rows[0].customer_id) return null;
return { customerId: rows[0].customer_id as string };
const customerId = rows[0].customer_id as string;
await redis.setEx(cacheKey, 60, customerId);
return { customerId };
} catch (err) {
console.error('[oauth] getTokenCustomer error:', err);
return null;