fix(recommender): serve fallback tips to users with no integrations (#117)

The integration-token gate returned 422 for users with no connected
sources, blocking them from any tip. Users with no integrations now go
through the full orchestrator pipeline; if it fails (or returns nothing
because agent outputs are also empty), randomFallbackTip() fires and
serves a generic advice tip instead of an error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-13 09:54:54 +00:00
parent 56fda0d737
commit ad43a8f06a

View File

@@ -2,7 +2,7 @@ import { type Router as ExpressRouter, Router, Response } from 'express';
import { nanoid } from 'nanoid';
import { logger } from '../logger.js';
import { db } from '../db/index.js';
import { integrationTokens, tipFeedback, tipViews, tipScores, userPreferences } from '../db/schema.js';
import { tipFeedback, tipViews, tipScores, userPreferences } from '../db/schema.js';
import { eq, and, desc } from 'drizzle-orm';
import { requireAuth, AuthenticatedRequest } from '../middleware/session.js';
import { config } from '../config.js';
@@ -144,17 +144,6 @@ router.post('/recommend', requireAuth, async (req: AuthenticatedRequest, res: Re
const dayOfWeek = new Date().getDay();
const { recent_tip: recentTip } = req.body as { recent_tip?: string };
const anyToken = await db
.select({ id: integrationTokens.id })
.from(integrationTokens)
.where(eq(integrationTokens.userId, req.userId!))
.limit(1);
if (!anyToken.length) {
res.status(422).json({ error: 'No integrations connected' });
return;
}
const signals = await aggregator.fetchAll(req.userId!);
const t0 = Date.now();