Showcase

Selected work.

A closer look at things I’ve built end-to-end. More case studies coming soon.

2025Solo — database, API, web, mobile & deployment

Clock-M

A multi-tenant SaaS platform for time tracking and team management — clock in/out, run projects, manage a team, and pull monthly reports.

Live app ↗Source: Private — available on request
Overview

Clock-M is a complete time-tracking and team-management product. People clock in and out, log breaks and trips, organise work into projects and tasks, run a team with proper roles and permissions, and export clean monthly reports — all in one place.

It’s multi-tenant: one account can belong to several team workspaces, and each team’s data stays cleanly separated. I built every layer myself — the database, the API, the web app, a mobile companion app, and the deployment that runs it in production.

Try the live demo

No signup needed — enter your email and I’ll send you a ready-to-use demo login for a fully populated team workspace.

Logs you straight into a populated team workspace — 6 people, ~2 months of time history, projects, tasks, clients, schedules and reports already filled in.

Screenshots
Clock-M dashboard with a live clock-in timer
Dashboard — live timer, breaks & trips, today’s tasks.
Clock-M native mobile app — timer screen
Mobile app — a React Native companion app.
Clock-M monthly report with per-day totals
Monthly report — per-day totals, Excel export.
Clock-M tasks page
Tasks — priorities, statuses, due dates, assignees.
Clock-M goals and projects board
Projects & goals — organised work with categories.
Clock-M team members and roles
Team — members, roles, invitations, permissions.
Clock-M absence requests
Absences — vacation & sick leave with approval flow.
Clock-M shift schedules
Schedules — recurring shifts for members & locations.
Clock-M clients list
Clients — track time against customers.
Clock-M locations
Locations — physical sites for on-site work.
Clock-M appearance settings
Theming — light/dark with multiple accent colors.
Clock-M language and region settings
i18n — 5 languages, per-user region settings.
What it does
⏱️

Time tracking

Clock in/out as work sessions, with nested breaks and trips. The live timer survives refreshes, restarts and the mobile app — it never drifts.

📊

Monthly reports

Per-day work, break and trip totals with drill-down into individual sessions, plus one-click Excel export.

🗂️

Projects & tasks

Projects with categories, links and docs; to-dos with priorities, statuses, due dates, assignees and drag-to-reorder.

👥

Team workspaces

Multi-tenant by design: own or join multiple teams, with owner / manager / employee roles, email invitations and role-based permissions.

🏖️

Absences & schedules

Request vacation or sick leave with attachments and a manager approval flow, and plan recurring shifts for members, clients and locations.

📁

File storage

Nested folders, previews, downloads and public share links, backed by S3-compatible cloud storage with per-team quotas.

🤖

AI assistant

An in-app chat assistant with streaming responses and project/file context, powered by the Claude API.

💳

Billing & GDPR

Stripe subscriptions with seat-based plans, plus self-service data export and account deletion. Available in 5 languages.

Engineering highlights
01

True multi-tenant data model

Every record (sessions, projects, notes, schedules, absences) is scoped to a person’s membership in a specific team — not just their user id. So the same person’s data stays cleanly isolated across all the teams they belong to.

02

Hand-written SQL, no ORM

All data access is hand-written, parameterized SQL on a shared PostgreSQL connection pool — full control over queries, joins and indexes. The schema is a normalized 34-table design with UUID keys and soft deletes.

03

Self-healing time tracking

Forgotten clock-ins are auto-closed (capped at 16 hours or end-of-day), and the live timer never trusts a local counter — it recomputes totals from server timestamps, so it’s drift-free across refreshes, restarts and the mobile app.

04

Direct-to-cloud uploads

The browser uploads files straight to object storage using short-lived signed URLs — the bytes never pass through the API server. Includes per-team storage quotas and client-side image compression.

05

Full auth lifecycle

Stateless JWT auth with email verification and password reset via single-use, expiring tokens. Account verification is re-checked on every request, not just at login — plus a founder-approval flow that stages destructive actions behind an email-confirmed token.

06

One contract for web & mobile

A single typed API client and shared types are reused by both the web app and the React Native mobile app — one source of truth for the whole API.

Tech stack
FrontendReact · TypeScript · Vite · Tailwind CSS · Jotai · TipTap · dnd-kit · Framer Motion
MobileReact Native (Expo) · shared SDK & types with the web app
BackendNode.js · Express · TypeScript · raw SQL (no ORM) · JWT · bcrypt
DatabasePostgreSQL — 34-table normalized schema, all-UUID keys, soft deletes
StorageS3-compatible object storage via signed URLs
AIClaude API (streaming responses)
PaymentsStripe — subscriptions, seats, billing portal
DeploymentDocker (multi-stage) · nginx · self-hosted on a VPS
TestingJest + supertest (backend) · Playwright (web e2e)