Files
wotra/README.md

6.7 KiB

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

# Install frontend dependencies (first time only)
mise run install

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

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 run install Install frontend npm 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.