Skip to content

niels-emmer/time-keeper

Repository files navigation

Caution

This entire project was built by Claude Code (Sonnet 4.6). Initiated, and then guided by human (me) prompting, a steady stream of “ah, and can you also…” and two evenings of iterative back and forth. Started from an empty folder, it evolved under its own self-authored guidance system (the agent memory living in docs/), to a working app with the only human-written content in these opening paragraphs.

Credit where it is due: impressive speed, clean UI, and a solid overall architecture. It even keeps its documentation up-to-date unprompted, in both the repository and the Wiki. That documentation however, rarely mentions “security” which is not an accident. The code relies on unvetted libraries, has not been pentested, and could theoretically exfiltrate your toothbrush for all I know. See SECURITY.md for the details.

Time Keeper

A self-hosted personal work-timer PWA. Track time against named categories from any device, view weekly summaries, and copy them into Workday (or any time registration tool) with one click.

Runs as a PWA — installs to the macOS Dock and Android home screen with no app store required.

Screenshots

Track tab — category grid with active timer
Track — tap a category to start
Weekly tab — hours per category per day
Weekly — hours by category × day
Settings tab — categories and weekly goal
Settings — categories & weekly goal

Features

  • One-tap timer — tap a category to start, tap Stop to finish; starting a new category auto-stops the previous one
  • Weekly goal — configurable hours per week (0–40); shown in the top bar and weekly summary, drives the rounding cap
  • Weekly overview — time per category per day; click any cell to edit hours inline (totals update live as you type); export as CSV ready to paste into your time registration tool
  • End-of-day rounding — round tracked minutes up to the nearest 30 or 60 minutes (configurable), capped at your weekly goal
  • Light / dark / system theme — follows your OS preference by default; override per-device in Settings
  • PWA — installable on macOS and Android, runs in standalone mode (no browser chrome)
  • macOS status bar app — native Flutter app lives in the menu bar; icon shows active timer color + CODE hh:mm; click to open a popover panel with full Track / Weekly / Settings functionality
  • Self-hosted — runs in Docker, no external services or accounts required beyond your own Authentik instance

Tech stack

Layer Choice
Frontend React 18 + Vite + Tailwind CSS + shadcn/ui
Backend Node.js 22 + Express + Drizzle ORM
Database SQLite (better-sqlite3, WAL mode)
Auth Authentik embedded outpost via Nginx Proxy Manager forward auth
Container Docker Compose

Prerequisites

To deploy (production):

To develop locally:

Quick start (local development)

# 1. Install dependencies (requires Node 22+ and Yarn 4 via corepack)
corepack enable
yarn install

# 2. Start the backend (Terminal 1)
DEV_USER_ID=you@example.com yarn workspace @time-keeper/backend dev

# 3. Start the frontend (Terminal 2)
yarn workspace @time-keeper/frontend dev

Open http://localhost:5173. Auth is bypassed in dev mode — all data is stored under the DEV_USER_ID value.

Deployment

See docs/operations/deployment.md for the full guide, including:

  • Docker Compose setup
  • Nginx Proxy Manager configuration
  • Authentik provider and outpost setup

The short version:

  1. Clone the repo on your VPS
  2. docker compose up -d --build
  3. Create a Proxy Provider in Authentik (forward auth mode, external host = your domain)
  4. Add it to your existing proxy outpost
  5. Add a proxy host in NPM pointing to 192.168.x.x:38521 (your server's LAN IP) with the standard Authentik forward auth Advanced config

Documentation

Path Contents
Wiki Full user and operator documentation
AGENTS.md Entry point for AI coding agents
docs/memory/INDEX.md Architecture overview and session guide
docs/integration/auth.md Authentik + NPM wiring
docs/integration/docker.md Docker services and volumes
docs/integration/pwa.md Installing on macOS and Android
docs/integration/api-subdomain.md API subdomain setup for the native app
packages/macos_app/README.md macOS status bar app — build & setup
docs/operations/deployment.md Production deployment guide
docs/operations/runbooks.md Common break/fix procedures
SECURITY.md Security posture, risks, and dependency audit

Customising categories

Categories are managed in the app itself (Settings tab). Add one category per booking type you want to track. The optional "Workday code" field appears in the weekly copy output.

Multi-user support

The app is multi-user capable out of the box. Each user's data is fully isolated by the email address Authentik sets in the X-authentik-email header — no configuration required. Add users to your Authentik application and they each get their own independent set of categories and time entries.

There is no shared data, cross-user reporting, or admin interface — each user only ever sees their own data.

Attribution

Original idea and product direction by the author. All code, architecture, and debugging by Claude Code (Claude Sonnet 4.5 / Opus 4.6, Anthropic).

About

vibe-coded single-click time keeping

Resources

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors