The problem
People forgot to scan out and night shifts crossed midnight, leaving incomplete or misdated records.
What I built
Two Python services in Docker: one listens to every scanner live and decides check-in vs check-out from the planned shift, the other closes stale records every night.
Key features
- Live capture from every active scanner
- Check-in vs check-out decided from the planned shift
- If a new shift starts while the last one is open, the old one closes at its planned end
- A rescan within an hour updates the check-out instead of adding a record
- Nightly cleanup closes records open for more than 16 hours
- Each scan is pushed to n8n
Under the hood
- Shift window runs from 4 hours before start to 8 hours after end; shifts that end before they start roll to the next day
- One thread per device with auto-reconnect every 30 seconds, and non-blocking webhooks
- GitHub Actions rebuilds the image and redeploys with docker compose on an internal runner