Side Project
BeThere: Face-Verified Live-Presence Attendance System
A smart attendance web app that verifies real presence: scan a venue QR that rotates every 30 seconds, then a server-side face-liveness check confirms it is really you, all verified from raw frames.

Overview
BeThere is a full-stack smart attendance system I designed and built end to end to solve one problem: making attendance genuinely hard to fake. Instead of signing a sheet or tapping a card, a person scans a code that a screen at the venue rotates every 30 seconds (proving they are physically there), then passes a short face-liveness check that a server verifies from raw camera frames (proving it is really them). It is two repositories: a React (Vite) frontend that runs the QR scanner, camera capture, the admin venue-code display, and the dashboards, and an Express + PostgreSQL backend that does all verification server-side and runs the background jobs. It is live at bethere.manuru.dev and open-sourced under MIT.
The Problem
The problem Attendance systems are easy to game. Sign-in sheets get filled in by a friend, ID cards get tapped by someone else, and GPS check-ins are trivially spoofed or shared from home. Face recognition on its own is not enough either: you can replay a photo, submit a pre-computed face descriptor, or screenshot a QR code and send it to someone somewhere else. I wanted a system where the two things that actually matter, that you are physically at the venue and that it is really you, live, are both proven on the server and cannot be faked by tampering with the client, while staying a plain web app with nothing to install.
The Solution
Presence is proven by a rotating venue code: each event has a server-side secret, and the screen at the location shows a QR that changes every 30 seconds. The codes are stateless, time-windowed HMAC-SHA256 hashes, so rotation needs no database writes and a screenshotted code is stale within seconds. Identity is a two-step handshake: a fail-fast preflight checks the venue code, enrollment, and session window, then issues a randomized action sequence (turn, blink, smile) with a single-use challenge token. The client uploads raw frames, and the server verifies from the pixels that the actions happened, that the face matches the enrolled template, that it is not a replayed descriptor, and that it is one continuous person, before recording PRESENT or LATE. Failed attempts are kept as flagged evidence plus an anomaly for review. Biometrics are handled carefully: enrollment requires explicit consent, the 128-dimension face template is AES-256-GCM encrypted at rest and decrypted only in memory at match time, and a scheduled retention sweep purges dormant templates, expired tokens, challenges, and evidence. Recurring events auto-generate their sessions through a BullMQ + Redis pipeline that runs in-process or as a separate worker. Auth is cookie-only JWT access and refresh tokens with refresh-token rotation and replay-as-theft detection, a per-request session-epoch check for instant revocation, passwordless OTP login, optional 2FA, and rate limiting, with every check-in and biometric action written to an append-only audit log. The frontend uses TanStack Query with a silent-refresh axios interceptor (no tokens in JS-readable storage), an in-app @zxing QR scanner, HEIC-to-JPEG conversion for iPhone captures, and Recharts dashboards.