fix vibe engine audit findings: pg.Pool, plan replan, dead exclusions, legacy engine removal
Backend: - app.ts: switch shared pg.Client to pg.Pool with per-transaction clients (#205) - v2.routes.ts: replace plan instead of appending on replan, fixing self-duplication (#206) - session-director: populate recentExclusions, per-candidate ranking, batch repetition checks (#209/#211/#213/#215 + minor) - db.service.ts: claim-fusion watermark, legacy recommendation_batch engine removed (#216/#219/#232) - app.ts: drop test enqueue-job endpoint (#234) Frontend: - AudioEngine/Vibe/usePlaybackStore: dedupe completed feedback, gate feedback to vibe sessions, End Vibe stops playback, Keep toast, shuffle played-set (#207/#236/#237/#238/#239/#240) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,7 +74,7 @@ export default async function v2Routes(fastify: FastifyInstance, options: { dbSe
|
||||
// Replan if running low
|
||||
if (active.plan.length < 5) {
|
||||
const refill = await director.replan(userId, active.sessionId, active.plan, [next.trackId], active.seedTrackId ?? undefined);
|
||||
active.plan.push(...refill);
|
||||
active.plan = refill;
|
||||
}
|
||||
|
||||
await setActivePlan(userId, active);
|
||||
@@ -111,7 +111,7 @@ export default async function v2Routes(fastify: FastifyInstance, options: { dbSe
|
||||
if (active) {
|
||||
const playedTrackIds = [trackId];
|
||||
const refill = await director.replan(userId, active.sessionId, active.plan, playedTrackIds, active.seedTrackId ?? undefined);
|
||||
active.plan.push(...refill);
|
||||
active.plan = refill;
|
||||
await setActivePlan(userId, active);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
import { FastifyInstance } from 'fastify';
|
||||
import { DbService } from '../services/db.service.js';
|
||||
|
||||
export default async function vibeRoutes(fastify: FastifyInstance, options: { dbService: DbService }) {
|
||||
const { dbService } = options;
|
||||
|
||||
// Start a new vibe session
|
||||
fastify.post('/start', async (request, reply) => {
|
||||
const { seedTrackId } = request.body as { seedTrackId: string };
|
||||
if (!seedTrackId) {
|
||||
return reply.code(400).send({ error: 'seedTrackId is required' });
|
||||
}
|
||||
const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
|
||||
const batchId = await dbService.createVibeSession(userId, seedTrackId);
|
||||
return reply.send({ batchId });
|
||||
});
|
||||
|
||||
// Get the next chunk of tracks for the active session
|
||||
fastify.get('/next', async (request, reply) => {
|
||||
const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
|
||||
const activeSession = await dbService.getActiveVibeSession(userId);
|
||||
|
||||
if (!activeSession) {
|
||||
return reply.code(404).send({ error: 'No active vibe session found' });
|
||||
}
|
||||
|
||||
const tracks = await dbService.getNextVibeChunk(activeSession.batchId);
|
||||
|
||||
// Update the session timestamp to keep it alive
|
||||
await dbService.updateVibeSession(activeSession.batchId);
|
||||
|
||||
return tracks;
|
||||
});
|
||||
|
||||
// Start/return a chunk seeded by a genre (id or name) — no active session required.
|
||||
fastify.get('/from-genre', async (request, reply) => {
|
||||
const { genre } = request.query as { genre?: string };
|
||||
if (!genre) {
|
||||
return reply.code(400).send({ error: 'genre query param is required' });
|
||||
}
|
||||
const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
|
||||
const tracks = await dbService.getVibeChunkFromGenre(genre, userId);
|
||||
return tracks;
|
||||
});
|
||||
|
||||
// Current ACTIVE batch metadata for the user, or 404.
|
||||
fastify.get('/current', async (request, reply) => {
|
||||
const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
|
||||
const session = await dbService.getCurrentVibeSession(userId);
|
||||
if (!session) {
|
||||
return reply.code(404).send({ error: 'No active vibe session found' });
|
||||
}
|
||||
return reply.send(session);
|
||||
});
|
||||
|
||||
// Heartbeat: keep the active batch alive by bumping last_interaction_at.
|
||||
fastify.post('/heartbeat', async (request, reply) => {
|
||||
const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
|
||||
const updated = await dbService.heartbeatVibeSession(userId);
|
||||
if (!updated) {
|
||||
return reply.code(404).send({ error: 'No active vibe session found' });
|
||||
}
|
||||
return reply.send({ status: 'ok' });
|
||||
});
|
||||
|
||||
// End the vibe session
|
||||
fastify.post('/end', async (request, reply) => {
|
||||
const userId = (request.headers['x-user-id'] as string) || '00000000-0000-0000-0000-000000000000';
|
||||
const activeSession = await dbService.getActiveVibeSession(userId);
|
||||
|
||||
if (activeSession) {
|
||||
await dbService.endVibeSession(activeSession.batchId);
|
||||
}
|
||||
return reply.send({ status: 'session_ended' });
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user