📣 TL;DR
Your staff won’t be flagged for “overtime” after staying back 5 minutes anymore. The 1-hour buffer now actually works, thanks to a sneaky string bug I caught and squashed. Past records? Cleaned. System? Smarter. You? Less annoyed.
😤 The Problem
ClockIn was being a little dramatic — handing out overtime for trivial extra minutes. A 10-minute scheduled shift + 35-minute actual time? Suddenly showing 25 minutes overtime. Drama.
This wasn’t how it was supposed to work. I had a 1-hour buffer in place. But that buffer? Ignored. Why? Because JavaScript was doing its thing:
"0.17" + 1 = "0.171" // Thanks, type coercion.
Yep — it concatenated instead of calculating. Rookie move, JS.
🧠 The Diagnosis
Primary Culprit: String Concatenation from Database
My code assumed scheduledHours
was a number. It wasn’t. It was a string. And instead of:
0.17 + 1 = 1.17 ✅
I got:
"0.17" + 1 = "0.171" ❌
Multiply that by hundreds of shifts per week and boom — chaos.
Other Headaches I Found
-
Historical records = wrong overtime.
-
Overtime logic duplicated in multiple places = multiplied problems.
-
Frontend was innocent — it just displayed the bad data it received.
🔧 The Fix
🧼 1. Server Logic Cleaned
const scheduledHoursNum = parseFloat(scheduledHours) || 0;
Used this across the board. I now force JavaScript to act like a responsible adult.
Also added conditional logic:
-
Regular shift? Apply buffer.
-
Reclock shift? No buffer. You’re already working OT.
🗃️ 2. Database Cleanup
Ran a SQL update to correct every past overtime entry that didn’t respect the buffer.
UPDATE attendance
SET overtime_hours = GREATEST(0, actual_hours - (scheduled_hours + 1.0))
...
No record left behind.
🔁 3. Server Restarted
Because no fix is complete until someone yells, “Just restart the server!”
🧪 Testing (Yes, We Did It)
I’ve tested everything — from 5-minute shifts to 15-hour shifts.
Scheduled | Actual | Result |
---|---|---|
10 min | 35 min | ✅ 0 overtime |
8 hrs | 10 hrs | ✅ 1h overtime |
8 hrs | 8.5 hrs | ✅ 0 overtime |
10 hrs | 15 hrs | ✅ 4h overtime |
8/8 tests passed. Zero bugs survived.
📊 Before vs After: The Glow-Up
Example: Micro Shift
Step | Before | After |
---|---|---|
Scheduled (h) | “0.17” | 0.17 |
Buffer (h) | 1 | 1 |
Threshold | “0.171” ❌ | 1.17 ✅ |
Actual (h) | 0.59 | 0.59 |
Overtime | 0.42 ❌ | 0 ✅ |
📘 The New Rules (How Overtime Really Works)
Regular Sessions
Overtime Threshold = Scheduled Hours + Buffer (1h)
-
8h scheduled + 1h buffer = 9h threshold
-
10h actual → 1h OT
-
8.5h actual → 0 OT
Re-clock Sessions
Buffer = 0
Overtime = Actual - Scheduled
Why? Because re-clocked time is already extra. You’re not getting grace here.
🛡️ What I’ve Learned (a.k.a. Prevention Plan)
-
Always
parseFloat()
database values. Always. -
Check your types before doing math. JS is sneaky.
-
Write test cases that make your future self proud.
-
Fix historical data. Don’t just patch the present.
-
Build a checklist for every overtime-related code change.
✅ Impact Recap
Benefit | Description |
---|---|
Buffer works properly | 1-hour grace period is now enforced |
Data fixed | Past overtime errors corrected |
UI accurate | No more weird overtime in admin or staff views |
Employee trust | People no longer punished for staying 5 mins late |
Reports clean | Overtime now reflects actual work done |
Final Thoughts
This bug was a classic case of “looks fine until you do the math.” But now, your team won’t get phantom overtime for breathing near the clock-out button. The system is smarter, the data is cleaner, and everyone can chill (or work extra — for real overtime pay).
Incase you missed where do i began : Building a Web-Based Clocking System: A 48-Hour Sprint (and a Latte or Two)