From 171e6c349295b5be36934b1970f7356b4977a58a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 6 Feb 2026 21:49:08 +0000 Subject: [PATCH] Return actual error message from shifts/start for debugging https://claude.ai/code/session_01Rf47gNAgM7jDstC4bvffzw --- src/routes/api/shifts/start/+server.ts | 108 +++++++++++++------------ 1 file changed, 57 insertions(+), 51 deletions(-) diff --git a/src/routes/api/shifts/start/+server.ts b/src/routes/api/shifts/start/+server.ts index a22aba7..62584aa 100644 --- a/src/routes/api/shifts/start/+server.ts +++ b/src/routes/api/shifts/start/+server.ts @@ -4,68 +4,74 @@ import { operators, shifts } from '$lib/server/db/schema'; import { eq, and, isNull } from 'drizzle-orm'; import { verifyPasscode, checkRateLimit, clearRateLimit, logAuthFailure, createOperatorSession, rehashIfPlaintext } from '$lib/server/auth'; import { dev } from '$app/environment'; +import { logger } from '$lib/server/logger'; import type { RequestHandler } from './$types'; export const POST: RequestHandler = async ({ request, cookies, getClientAddress }) => { - const clientIp = getClientAddress(); - const rateCheck = await checkRateLimit(`shift-start:${clientIp}`); - if (!rateCheck.allowed) { - return json( - { error: 'Too many login attempts. Try again later.' }, - { status: 429, headers: { 'Retry-After': String(rateCheck.retryAfterSeconds) } } - ); - } + try { + const clientIp = getClientAddress(); + const rateCheck = await checkRateLimit(`shift-start:${clientIp}`); + if (!rateCheck.allowed) { + return json( + { error: 'Too many login attempts. Try again later.' }, + { status: 429, headers: { 'Retry-After': String(rateCheck.retryAfterSeconds) } } + ); + } - const { operatorId, passcode } = await request.json(); + const { operatorId, passcode } = await request.json(); - if (!operatorId || !passcode) { - return json({ error: 'Operator ID and passcode required' }, { status: 400 }); - } + if (!operatorId || !passcode) { + return json({ error: 'Operator ID and passcode required' }, { status: 400 }); + } - const [operator] = await db - .select() - .from(operators) - .where(and(eq(operators.id, operatorId), eq(operators.isActive, true))); + const [operator] = await db + .select() + .from(operators) + .where(and(eq(operators.id, operatorId), eq(operators.isActive, true))); - if (!operator) { - logAuthFailure('/api/shifts/start', String(operatorId), clientIp); - return json({ error: 'Invalid credentials' }, { status: 401 }); - } + if (!operator) { + logAuthFailure('/api/shifts/start', String(operatorId), clientIp); + return json({ error: 'Invalid credentials' }, { status: 401 }); + } - const valid = await verifyPasscode(passcode, operator.passcode); - if (!valid) { - logAuthFailure('/api/shifts/start', String(operatorId), clientIp); - return json({ error: 'Invalid credentials' }, { status: 401 }); - } + const valid = await verifyPasscode(passcode, operator.passcode); + if (!valid) { + logAuthFailure('/api/shifts/start', String(operatorId), clientIp); + return json({ error: 'Invalid credentials' }, { status: 401 }); + } - await clearRateLimit(`shift-start:${clientIp}`); - rehashIfPlaintext('operators', operatorId, operator.passcode).catch(() => {}); + await clearRateLimit(`shift-start:${clientIp}`); + rehashIfPlaintext('operators', operatorId, operator.passcode).catch(() => {}); - const [existingShift] = await db - .select() - .from(shifts) - .where(and(eq(shifts.operatorId, operatorId), isNull(shifts.endedAt))); + const [existingShift] = await db + .select() + .from(shifts) + .where(and(eq(shifts.operatorId, operatorId), isNull(shifts.endedAt))); - let shift = existingShift; - if (!existingShift) { - const [newShift] = await db - .insert(shifts) - .values({ - operatorId - }) - .returning(); - shift = newShift; - } + let shift = existingShift; + if (!existingShift) { + const [newShift] = await db + .insert(shifts) + .values({ + operatorId + }) + .returning(); + shift = newShift; + } - const sessionToken = await createOperatorSession(operatorId); - cookies.set('operatorSession', sessionToken, { - path: '/', - httpOnly: true, - sameSite: 'lax', - secure: !dev, - maxAge: 60 * 60 * 24 - }); + const sessionToken = await createOperatorSession(operatorId); + cookies.set('operatorSession', sessionToken, { + path: '/', + httpOnly: true, + sameSite: 'lax', + secure: !dev, + maxAge: 60 * 60 * 24 + }); - const { passcode: _, ...safeOperator } = operator; - return json({ operator: safeOperator, shift }); + const { passcode: _, ...safeOperator } = operator; + return json({ operator: safeOperator, shift }); + } catch (err) { + logger.error({ err, endpoint: '/api/shifts/start' }, 'shift_start_error'); + return json({ error: String(err) }, { status: 500 }); + } };