AlpineTime
A time-tracking app for a small Swiss company. FastAPI, Vue 3, PostgreSQL. Wrote the spec, built the thing, learned what the spec missed.
Web app for tracking hours against clients, projects, and tasks — with billing reports that include MWST. Three or four employees, one timezone, CHF only. The constraint set is narrow enough to make real decisions rather than hedge for every possible case.
Self-built because I wanted to work through the full problem first. A spec document and a running system are different objects — the system is where the questions get concrete. Once the first version is running in our own company, I’ll know what to commission to clients and what to warn them about.
Currently in alpha. Not in production. The interesting parts — overlap detection, rate snapshotting, token handling — are done. The UI still has rough edges.
The entries below cover the spec and constraint work, the backend, and the frontend, in that order.
AlpineTime: frontend — Vue 3, composables, i18n from day one
Vue 3 + TypeScript + PrimeVue. Silent token refresh, error codes mapped to i18n keys, composables keeping pages under 100 lines. German UI from the first component.
AlpineTime: backend — FastAPI, async ORM, rate resolution
FastAPI with SQLAlchemy 2.0 async. The interesting parts: overlap detection with user-driven resolution, rate snapshotting, and MWST applied at report total rather than per line.
AlpineTime: what the spec went through before touching code
Seven versions of the spec before the first commit. The Swiss constraints — MWST, nDSG, Europe/Zurich, German UI — decided most of the architecture before any code was written.