Commit Graph

11 Commits

Author SHA1 Message Date
31535e944d fix: move embed to repo root; make build sequential
- Move embed_prod.go/embed_dev.go out of cmd/wotra/ into root-level
  assets_prod.go / assets_dev.go (package assets). go:embed paths
  must be relative to the source file; cmd/wotra/ cannot reach
  ../../web/build.
- Update cmd/wotra/main.go to import the root assets package.
- Change mise.toml build task from parallel depends to sequential
  shell commands (build:web then build:go) so the frontend is always
  compiled before the Go embed runs.
2026-05-01 09:39:52 +02:00
a8a4ea0d4f M9.1: wire sync logging into all mutation paths
- Add LogClosedDayDelete and LogClosedWeekDelete to SyncStore
- Inject syncStore into EntryService; log Start, Stop, StopByID,
  Update, CreateInterval, Delete, AutoStopStalledEntries
- Inject syncStore into DayService; log CloseDay, MarkDay, ReopenDay,
  and the recomputeWeek closed-week upsert
- Inject syncStore into SettingsService; log Upsert, UpdateSettings,
  DeleteSettings
- Add LogClosedWeek/LogClosedWeekDelete calls in WeekService.CloseWeek
  and ReopenWeek
- Update main.go and all service test helpers for new constructor signatures
- All Go tests and 19 Vitest tests pass
2026-04-30 22:57:02 +02:00
d8366f5c25 Add sync redesign with offline fallback (M9)
- Migration 003: adds logged_at to sync_log for TTL pruning; migrates
  settings_history to UUID TEXT PK with updated_at column
- SyncStore: Prune() deletes rows older than 30d and writes a '_pruned'
  marker at the boundary version; Pull() calls Prune lazily and returns
  ErrSyncStale (410) when the client's since_version is behind the marker
- sync_handler.go: GET /api/sync/pull?since=N; POST /api/sync/push with
  last-updated_at-wins conflict resolution for entries, balance_adjustments,
  settings_history; closed_days/closed_weeks skipped (server-only mutations)
- router.go: passes entryStore, adjustmentStore, settingsStore to SyncHandler
- settings_store.go: UUID PK, updated_at column, Upsert() for push path
- settings_service.go: generates UUID on create, sets updated_at on update
- settings_handler.go: ID params changed from int64 to string
- domain.go: Settings.ID string, Settings.UpdatedAt added
- client.ts: all mutation methods catch TypeError (offline) and fall back
  to Dexie write + outbox enqueue; crypto.randomUUID() for offline creates;
  Settings.id type changed to string
- db.ts: Dexie v3 — settings_history key path changed to string UUID;
  upgrade handler clears table for repopulation via pull
- sync.ts: real pushOutbox to POST /api/sync/push; pullChanges uses GET
  with ?since=N; 410 triggers coldStart() + retry; coldStart() wipes all
  tables and resets last_version
- 4 new Go store tests covering normal pull, stale client, empty prune,
  client-ahead-of-marker; all tests pass (store + service, 19 Vitest)
2026-04-30 22:50:33 +02:00
3214f48a6f Add balance adjustments (M8)
- New balance_adjustments table with CRUD store, sync logging, and service methods
- SQL migrations restructured: embed fs.FS from internal/store/migrations/, apply in order via user_version
- WeekService.Balance combines closed-weeks delta + adjustments delta; BalanceSummary breakdown
- Four REST routes: GET/POST /api/balance/adjustments, PUT/DELETE /api/balance/adjustments/{id}
- Dexie schema v2 + sync apply cases for balance_adjustments
- API client: BalanceAdjustment type, balance namespace (list/create/update/delete)
- utils: composeDeltaMs / decomposeDeltaMs helpers + 8 new Vitest tests (19 total, all passing)
- History page: balance card breakdown line + full adjustments section with inline add/edit/delete
2026-04-30 21:50:57 +02:00
47c7a97d47 fix: keep closed week snapshot in sync when days change
When a day is closed, re-closed, or reopened, DayService now
recomputes worked_ms and delta_ms on the closed week containing
that day (if the week is already closed). This prevents stale
delta values after editing entries and re-closing a day.

- DayService.recomputeWeek: sums worked_ms from all closed_days
  in the week, updates closed_weeks row preserving expected_ms
- NewDayService now takes ClosedWeekStore
- WeekKeyForDayKey exported helper (used by DayService)
- TestWeekSnapshotUpdatesWhenDayReopened regression test
2026-04-30 18:16:22 +02:00
c675a7b01d fix: skip untracked workdays when closing a week
Previously any past workday without a closed_days record blocked week
close. Now only days that actually have entries require an explicit
close. Empty workdays count as 0h worked, which is reflected in the
weekly delta automatically.

- WeekService.CloseWeek: after finding no closed_days record, check
  whether the day has any entries; only error if it does
- NewWeekService: takes EntryStore to support the above check
- Updated TestCloseWeekMissingDayFails to reflect the new semantic
  (test now creates entries on Friday but leaves it unclosed)
2026-04-30 17:59:04 +02:00
4a328ad6cc feat(m5): PWA service worker, offline Dexie store, outbox, sync endpoints 2026-04-30 16:47:27 +02:00
df04d9d7a9 feat(m4): SvelteKit frontend - today, week, history, settings views 2026-04-30 16:45:00 +02:00
d0ef0387f2 feat(m3): week close, overtime/undertime delta, frozen settings snapshot 2026-04-30 16:39:42 +02:00
4a0e0c8318 feat(m2): settings history, close day, holiday/vacation/sick marking 2026-04-30 16:37:56 +02:00
3aa068efd2 feat(m1): backend scaffold - entries CRUD, start/stop, auth, migrations 2026-04-30 16:35:06 +02:00