Skip to content

Migrate time tracking provider from Milltime to Kleer API #74

@ponbac

Description

@ponbac

Summary

Replace Milltime as Toki's time-tracking backing service with Kleer (api.kleer.se) while keeping Toki's current user-facing time-tracking workflows intact.

Context

Kleer has provided API docs and a test company for integration work. Toki already uses a provider abstraction (TimeTrackingClient), but current auth, data mapping, and UI wording are still Milltime-specific.

Goals

  • Use Kleer as the backend for Toki time tracking.
  • Keep existing Toki flows working:
    • List projects/activities
    • Start/stop/save timer
    • Create/edit/delete time entries
    • Fetch time entries and status/lock behavior used by UI
  • Remove Milltime-specific auth and provider assumptions from backend/frontend.

In Scope

  • Implement a new Kleer outbound adapter implementing TimeTrackingClient.
  • Replace Milltime factory wiring with Kleer-aware factory/service creation.
  • Migrate authentication flow from username/password cookies to Kleer token + company id.
  • Map Kleer event/project/activity/status models into current Toki domain models.
  • Update UI/auth copy and cookie/session handling to be provider-neutral or Kleer-specific.
  • Update config/env validation and docs to remove Milltime requirements.

Proposed API Mapping (Kleer -> Toki)

  • Projects:
    • GET /v1/company/{companyId}/client-project?filter=active
  • Activities:
    • GET /v1/company/{companyId}/activity
    • (optionally combine with project activity restrictions from client-project payloads)
  • Current user id (required for event calls):
    • GET /v1/company/{companyId}/user/me
  • Time entries (events):
    • Create: PUT /v1/company/{companyId}/event
    • List: GET /v1/company/{companyId}/event?...
    • Read: GET /v1/company/{companyId}/event/{eventId}
    • Update: POST /v1/company/{companyId}/event/{eventId}
    • Delete: DELETE /v1/company/{companyId}/event/{eventId}
  • Status/lock state:
    • GET /v1/company/{companyId}/event/statuses?userId=...&fromDate=...&toDate=...
    • Status enum from XSD: Open, Approved, Certified

Backend Work Items

  • Add KleerAdapter under outbound adapters implementing TimeTrackingClient.
  • Add Kleer auth/session credential handling in factory:
    • remove dependency on Milltime credential cookies (mt_*)
    • support token/company id storage and refresh/validation flow
  • Update domain mapping logic:
    • map Kleer event status to Toki AttestLevel
    • map Kleer event ids and optional project references to existing TimeEntry model
  • Revisit TimeInfo generation:
    • preserve current API contract consumed by frontend
    • derive or provide fallback values where Kleer has no direct equivalent
  • Wire router/app state to new factory implementation.
  • Remove Milltime-only env assertions and encryption key requirement where no longer needed.

Frontend Work Items

  • Replace Milltime login form (username/password) with Kleer credential inputs (token/company id) and corresponding validation.
  • Remove Milltime cookie checks/cleanup logic (mt_*) from time-tracking store.
  • Update user-facing strings and provider links from "Milltime" to Kleer/provider-neutral naming.
  • Keep existing time-tracking views functional with mapped Kleer data (attestLevel, editability, summaries).

Risks / Open Questions

  • TimeInfo parity: Kleer docs do not expose a direct Milltime-equivalent flex-time endpoint in the reviewed material.
  • Event project reference appears optional in XSD (client-project minOccurs=0), while Toki currently assumes project-present entries.
  • Need product/UX decision on exact lock/flex behavior if underlying data differs from Milltime.

Acceptance Criteria

  • Time-tracking authentication succeeds using Kleer credentials (no Milltime cookies required).
  • Projects and activities load from Kleer.
  • Timer save creates a Kleer event and persists local timer history links.
  • Create/edit/delete time entry endpoints work against Kleer events.
  • Time entry list renders with correct project/activity names, status mapping, and edit lock behavior.
  • Frontend no longer shows Milltime-specific wording or login requirements.
  • Backend starts without requiring Milltime-specific env vars.

Sources

Current Toki references

  • toki-api/src/domain/ports/outbound/time_tracking.rs
  • toki-api/src/domain/services/time_tracking.rs
  • toki-api/src/adapters/outbound/milltime/mod.rs
  • toki-api/src/factory.rs
  • toki-api/src/routes/time_tracking/calendar.rs
  • app/src/lib/api/queries/time-tracking.ts
  • app/src/lib/api/mutations/time-tracking.ts
  • app/src/hooks/useTimeTrackingStore.tsx
  • app/src/routes/_layout/time-tracking/index.tsx
  • app/src/routes/_layout/time-tracking/-components/not-locked-alert.tsx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions