SmartBioTrack
Multi-tenant attendance platform: staff clock in and out on the web, and the system works out lateness, overtime and absences under each company's own rules. Biometric and geo-fence checks come next.
- // 01_Role
- Team & backend lead
- Team of three. Owns the platform, security and reporting to management
- // 02_Timeline
- Aug 2026 – now
- Phase 3 of 8 on staging since 27 Oct
- // 03_Tech stack
- NestJS 11 / Next.js 16
- Prisma 7, PostgreSQL (Neon), pnpm + Turborepo
- // 04_Automated tests
- 1,100+
- 329 API unit, 196 end-to-end, 617 web (3 Nov 2026)
- STEP 01Clock inServer time only, never the device's. Location is recorded on every punch, ready for geo-fencing.
- STEP 02BreaksSeveral work sessions a day are allowed. Breaks are subtracted as unpaid time, in one place in the code.
- STEP 03Clock outA forgotten clock-out is left open and flagged for review. The system never invents a punch.
- STEP 04Day closesAn hourly job closes each day in the company's own time zone, marking absences and incomplete days.
The problem
Companies need attendance records they can pay from: who came in, when, how late, how much overtime, worked out the same way every time and under each company's own rules.Verify
What I led
I lead a team of three as backend lead. I own the platform and security work, review every backend change before it merges, and write the progress reports that go to management.
- 01
Auth & tenancy
Company sign-up, invitations, four roles, departments and offices, with every query scoped to the caller's company.
- 02
Attendance engine
Clock in and out, breaks, daily summaries, lateness, overtime, work rules, holidays and the end-of-day job.
- 03
Delivery
Eight-phase roadmap, an end-to-end test gate on every HTTP change, and plain-English reports to management.
Security review
When the authentication phase met its done bar, I ran a consultant-style review of our own code before building on it: 32 findings, 28 closed, including every urgent one. The automated test suite grew from 87 to 758 tests over that work.
- 01
Tokens out of reach
Refresh token moved to an httpOnly cookie and the access token kept in memory, with refresh-token reuse detection.
- 02
No account probing
Identical login errors with equalised timing (a decoy hash), plus per-account lockout after repeated failures.
- 03
Isolation on the server
Team leads once received the whole company's user list, filtered only in the browser. Scoping now happens in the API.
Key decisions
Attendance data ends up in payroll, so the design favours records that can't drift: append-only events, derived summaries, and a lock wherever two requests could race.
One lock stops the double clock-in
A double tap or two open tabs could both read "not clocked in" and both insert. Each punch now locks the user's row inside the transaction and reads the clock after the lock, so the second request waits and punches stay in order.
Punches are facts, summaries are derived
Clock events are append-only. Daily summaries are computed by a pure function from those events, so any day can be rebuilt and checked.
Each company keeps its own time
Times are stored in UTC, and each company's days are worked out in its own time zone, defaulting to Africa/Lagos.
Prove every guard by breaking it
Each protection is tested by removing it and watching a test fail. Removing the company-ownership check, for example, let another company's work rule attach to an office. A test now fails if that check ever goes.
Have a system to build?
Open to remote full-stack roles and high-impact engineering work.