Wotra — Working Time Tracker

A self-hosted working time tracker with a Go backend and a Svelte PWA frontend. Offline-capable, single-binary deploy.

Features

  • Start / Stop time tracking with an optional note.
  • Close days: merges all entries (worked_ms = sum of durations, breaks excluded).
  • Mark days as holiday, vacation, or sick (auto-credits expected daily hours).
  • Close weeks: computes overtime/undertime against a frozen snapshot of your expected hours.
  • Settings history: change hours/week with an effective_from date — past closed weeks are unaffected.
  • PWA + offline: works without a network connection; syncs via IndexedDB outbox when back online.
  • CSV export: entries, days, weeks.
  • Midnight guard: running entries are automatically stopped at 23:59:59 if they cross midnight.

Quick Start

Tool versions are declared in mise.toml. Install mise and run mise install once to get the correct Go and Node versions.

Development

# Start both servers (Go API + Vite dev server)
mise run dev
# Go API:  http://localhost:8080
# Vite UI: http://localhost:5173 (with /api proxy)

Note: Dependencies are automatically installed when needed. If you want to manually trigger dependency installation, run mise deps.

AUTH_TOKEN defaults to devtoken in mise.toml. Override it by setting the variable in your environment before running.

Open http://localhost:5173, go to Settings, enter your token.

Production (single binary)

mise run build        # builds web/ then embeds it in the Go binary

AUTH_TOKEN=mysecrettoken ./wotra
# open http://localhost:8080

All tasks

Task Description
mise run build Build production binary (web + Go)
mise run build:web Build Svelte frontend only
mise run build:go Build Go binary only
mise run dev Start API + UI dev servers concurrently
mise run dev:api Start Go API server only
mise run dev:ui Start Vite dev server only
mise run test Run all Go tests
mise deps Install/update project dependencies
mise run clean Remove build artifacts

Configuration (environment variables)

Variable Default Description
AUTH_TOKEN required Bearer token for API access
PORT 8080 HTTP port
DB_PATH wotra.db SQLite database file path
TZ UTC Timezone for day/week key calculation

API Reference

All API endpoints require Authorization: Bearer <token> except /healthz.

Entries

Method Path Description
POST /api/entries/start Start tracking
POST /api/entries/{id}/stop Stop a specific entry
GET /api/entries?from=&to= List entries by date
PUT /api/entries/{id} Edit start/end/note
DELETE /api/entries/{id} Soft-delete an entry

Days

Method Path Description
GET /api/days?from=&to= List closed days
POST /api/days/{day}/close Close a day (merge entries)
POST /api/days/{day}/mark Mark as holiday/vacation/sick
DELETE /api/days/{day}/close Reopen a closed day

Weeks

Method Path Description
GET /api/weeks?from=&to= List closed weeks
POST /api/weeks/{week}/close Close a week (compute overtime)
DELETE /api/weeks/{week}/close Reopen a closed week

Week key format: YYYY-Www (e.g. 2024-W03).

Settings

Method Path Description
GET /api/settings Current effective settings
PUT /api/settings Add a new settings version
GET /api/settings/history All settings history

Export

Method Path Description
GET /api/export/entries.csv Export entries as CSV
GET /api/export/days.csv Export days as CSV
GET /api/export/weeks.csv Export weeks as CSV

Sync

Method Path Description
POST /api/sync/pull Pull changes since a version
POST /api/sync/push Push local changes (advisory)

Health

Method Path Description
GET /healthz Unauthenticated health

Architecture

┌─────────────────────────┐         ┌──────────────────────────┐
│   Svelte PWA (client)   │ ◄─────► │    Go service (API)      │
│  - IndexedDB (Dexie)    │  HTTPS  │  - REST/JSON endpoints   │
│  - Service Worker       │  JSON   │  - Business logic        │
│  - Sync outbox          │         │  - SQLite (modernc)      │
└─────────────────────────┘         └──────────────────────────┘

See PLAN.md for the full design document.

Development Notes

  • Go module: github.com/wotra/wotra
  • SQLite driver: modernc.org/sqlite (pure Go, no CGO)
  • Day boundary: entries must not cross midnight; the server auto-stops any running entry at 23:59:59 local time.
  • Settings history: effective_from lets you change hours/week without rewriting past closed weeks.
  • Overtime: stored as a signed delta_ms on each closed_weeks row. Frozen at close time.
Description
Working Time Tracker
Readme 297 KiB
Languages
Go 56.8%
Svelte 28.4%
TypeScript 14%
Dockerfile 0.5%
JavaScript 0.2%
Other 0.1%