mega-plant/app/api/clock/scan/route.ts
David 8f3a74cf6e Job cards oil path, Fuel tab diesel-only, Mechanic role, Plant Register QR column
- Job cards scanner: oil QR books litres + vehicle (no odo/photo), bundled onto the
  vehicle's job card (open job now, or the next job started the same day)
- Fuel tab is diesel only; /api/clock/oil-out added
- Users: Full / Clock-in user / Mechanic; mechanics see only Fuel + Job cards
- Plant Register: QR code column (double-click to set), kept across re-seeds and
  used when matching scans

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 13:44:01 +02:00

16 lines
1.1 KiB
TypeScript

import { clockAccess, clockFailure, clockJson } from '@/lib/clock-api';
import { ClockRepeat, saveClock } from '@/lib/clock';
import { clockPB, clockStore } from '@/lib/clock-store';
export async function POST(request:Request) {
try {
const user=await clockAccess(request);if(user instanceof Response)return user;
if(user.access==='mechanic')return Response.json({error:'Mechanics cannot clock in or out.'},{status:403});
let body:unknown;try{body=await request.json();}catch{return Response.json({error:'Supply valid JSON.'},{status:400});}
const event=await saveClock(clockStore(await clockPB()),body,user.user.id);
return clockJson({id:event.id,employeeName:event.employee_name,employeeNo:event.employee_no,direction:event.direction,at:event.scanned_at,sessionMinutes:event.session_minutes});
}catch(e){
// A repeat read is not a failure: the scan that counts is already saved, so say which one.
if(e instanceof ClockRepeat)return Response.json({error:e.message,repeat:{employeeName:e.employeeName,direction:e.last.direction,at:e.last.scanned_at}},{status:409,headers:{'Cache-Control':'no-store'}});
return clockFailure(e);
}
}