Skip to content

Repository files navigation

OvertimeIQ

Time and overtime tracking where your work data never reaches my server.

overtimeiq.vercel.app

The idea

Every time tracker asks you to hand over a record of when you work, how long you work, and what you are paid for it. That is an unusually personal dataset to keep on somebody else's machine, and none of it needs to be there for the app to function.

So it is not there. OvertimeIQ keeps your shifts, jobs, rates and earnings in a SQLite database that runs in your browser through WebAssembly, and syncs that single file to your own Google Drive. The server never sees a shift. What it does hold is the minimum that genuinely cannot be local: who you are, whether your invite is valid, and whether you are on the paid plan.

Where it lives What lives there
SQLite in your browser, synced to your Google Drive Shifts, jobs, hourly rates, multipliers, holidays, every earnings figure
Supabase (Postgres) Account identity, invite tokens, waitlist, subscription state

If you stop using the app, the database file stays in your Drive and stays readable by anything that reads SQLite. There is no export to request.

How it works

  • Storage. sql.js compiles SQLite to WebAssembly and runs the whole engine client-side. The database is serialised to localStorage after each change, so a reload is instant and works offline.
  • Sync. One file, overtimeiq.db, on Google Drive. Modified-time checks before write, so a second device does not clobber the first.
  • Auth. Google OAuth with PKCE in the browser; the authorisation code is exchanged server-side, then traded for a Supabase session with signInWithIdToken. The Drive scope is requested at the same time, which is why sign-in and sync are one step rather than two.
  • Paid features. The server mints a short-lived ECDSA ES256 JWT; the client verifies it with WebCrypto against a public key shipped in the bundle. The entitlement is never written into the SQLite file, so copying the database to another machine does not copy the subscription.
  • Earnings. A pure-function engine with no database access, which is what makes the awkward parts testable: shifts that cross midnight are split into two segments so a Saturday-night shift is not paid the weekend multiplier for its Sunday-morning half. Weekend and holiday multipliers are per job.

Stack

Next.js 16 (App Router) · React 19 · TypeScript · Zustand · Tailwind CSS 4 · sql.js (SQLite/WASM) · Google Drive API v3 · Supabase · jose · Recharts · jsPDF and SheetJS for export · deployed on Vercel

Status

Invite-only while it is being built. supabase/schema.sql is the identity and billing schema and carries the same rule in a comment at the top: work data lives in SQLite on the user's Drive, never here.

Why it exists

I wanted the local-first architecture in something I would actually use daily rather than in a demo. Six architectures were considered before this one; the reasoning is written up at dev.to/deeshansharma.

About

Time and overtime tracker. Work data lives in a SQLite file on your own Google Drive; the server only handles auth. Next.js, sql.js, Supabase.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages