From f97ed6da04027ca3f84484fce657e4696f75a15d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Tue, 25 Aug 2026 17:41:43 +0200 Subject: [PATCH] Fix session timeline query, bump to 0.2.1 getSessionTimeline() grouped/ordered by a bare `bucket` identifier, assuming SQLite would resolve it against the SELECT list's alias - it doesn't in this generated query, so every /sessions/:id page and /api/stats/sessions/:id/timeline request failed with "no such column: bucket". Fixed by reusing the actual bucket expression object in groupBy/orderBy instead of referencing it by name. Verified against a seeded session - previously every request, now correct bucketed data. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01W8WkFF5ppURBAB918593Eb --- lib/db/queries/stats.ts | 12 +++++++++--- package.json | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/db/queries/stats.ts b/lib/db/queries/stats.ts index 45484e8..2ee40b7 100644 --- a/lib/db/queries/stats.ts +++ b/lib/db/queries/stats.ts @@ -37,9 +37,15 @@ export async function getSessionsSummary() { } export async function getSessionTimeline(playSessionId: number, bucketMs = 1000) { + // Reuse the same expression object (not a `sql`bucket`` alias reference) + // in groupBy/orderBy - drizzle doesn't emit a literal `AS bucket` that + // SQLite's GROUP BY/ORDER BY could resolve a bare "bucket" identifier + // against, so referencing it by name causes "no such column: bucket". + const bucket = sql`(${sessionEvents.tsMs} / ${bucketMs}) * ${bucketMs}`; + return db .select({ - bucket: sql`(${sessionEvents.tsMs} / ${bucketMs}) * ${bucketMs}`, + bucket, sessionDeviceId: sessionEvents.sessionDeviceId, slotLabel: sessionDevices.slotLabel, avgValue: sql`avg(${sessionEvents.value})`, @@ -48,8 +54,8 @@ export async function getSessionTimeline(playSessionId: number, bucketMs = 1000) .from(sessionEvents) .innerJoin(sessionDevices, eq(sessionEvents.sessionDeviceId, sessionDevices.id)) .where(and(eq(sessionEvents.playSessionId, playSessionId), ne(sessionEvents.commandType, "stop"))) - .groupBy(sql`bucket`, sessionEvents.sessionDeviceId) - .orderBy(sql`bucket`); + .groupBy(bucket, sessionEvents.sessionDeviceId) + .orderBy(bucket); } export async function getDeviceUsageStats() { diff --git a/package.json b/package.json index 265ca58..69a2a24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sexy", - "version": "0.2.0", + "version": "0.2.1", "private": true, "scripts": { "dev": "next dev",