Skip to content

Commit 273dd33

Browse files
jahoomaclaude
andcommitted
Fix bot-sweep FILTER clause param encoding
postgres-js can't encode a raw JS Date as an ad-hoc template parameter (it only knows the target type when drizzle recognises the column). The FILTER (WHERE finished_at >= $cutoff) clauses were throwing ERR_INVALID_ARG_TYPE at query time. Switch to an ISO string with an explicit ::timestamptz cast. Verified end-to-end against prod: identified 39 suspects / 17 creation clusters across 244 active+queued sessions, email delivered. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent d129b01 commit 273dd33

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

web/src/server/free-session/abuse-detection.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ export async function identifyBotSuspects(params: {
6363
const { logger } = params
6464
const now = new Date()
6565
const cutoff = new Date(now.getTime() - WINDOW_HOURS * 3600_000)
66+
// postgres-js can't encode a JS Date as an ad-hoc template parameter
67+
// (it only knows how when the driver recognises the target column's
68+
// type). Embed the ISO string with an explicit cast so the FILTER
69+
// clauses below go through cleanly.
70+
const cutoffIso = cutoff.toISOString()
6671

6772
const sessions = await db
6873
.select({
@@ -94,8 +99,8 @@ export async function identifyBotSuspects(params: {
9499
const msgStats = await db
95100
.select({
96101
user_id: schema.message.user_id,
97-
msgs24h: sql<number>`COUNT(*) FILTER (WHERE ${schema.message.finished_at} >= ${cutoff})`,
98-
distinctHours24h: sql<number>`COUNT(DISTINCT EXTRACT(HOUR FROM ${schema.message.finished_at})) FILTER (WHERE ${schema.message.finished_at} >= ${cutoff})`,
102+
msgs24h: sql<number>`COUNT(*) FILTER (WHERE ${schema.message.finished_at} >= ${cutoffIso}::timestamptz)`,
103+
distinctHours24h: sql<number>`COUNT(DISTINCT EXTRACT(HOUR FROM ${schema.message.finished_at})) FILTER (WHERE ${schema.message.finished_at} >= ${cutoffIso}::timestamptz)`,
99104
lifetime: sql<number>`COUNT(*)`,
100105
})
101106
.from(schema.message)

0 commit comments

Comments
 (0)