# Settings: Time Tracking Page (`/settings/time-tracking`)

**Date:** 2026-06-01
**Status:** Draft
**Spec:** 169
**Tier:** All tiers
**Depends on:** `time-management`, `settings-module`, `foundation-auth-rbac`
**Referenced by:** `time-management`, `settings-module`, `mileage-logbook`

---

## Overview

Central configuration page for time tracking behavior. Spec 13 (`time-management`) defines the time tracking feature; this spec defines the `/settings/time-tracking` settings page that exposes its configuration knobs.

---

## Route

`/settings/time-tracking` — requires `settings:write` (view requires `settings:read`).

---

## Page Layout

```
┌──────────────────────────────────────────────────────────────┐
│  Settings > Time Tracking                                    │
│                                                              │
│  ── General ───────────────────────────────────────────────  │
│  Time rounding                                               │
│  [No rounding ▾]                                             │
│  No rounding · Nearest 5 min · Nearest 15 min · Nearest 30  │
│  Always round up (15 min) · Always round up (30 min)         │
│                                                              │
│  Example: 8m 40s → rounds to 9m (nearest 5) with current setting │
│                                                              │
│  Minimum billable duration                                   │
│  [0___] minutes   (0 = no minimum)                           │
│                                                              │
│  ── Idle Detection ─────────────────────────────────────────  │
│  Prompt after idle for    [10___] minutes                    │
│  ☑ Auto-pause on idle (prompt user when returning)           │
│  ☑ Show idle warning in timer widget                         │
│                                                              │
│  ── Overtime ───────────────────────────────────────────────  │
│  Standard hours per day    [8____]                           │
│  ☑ Flag entries exceeding daily limit in time reports        │
│  ☑ Require approval for overtime entries                     │
│                                                              │
│  ── Contractor Time ────────────────────────────────────────  │
│  ☑ Allow contractors to submit time entries                  │
│  Contractor time requires approval before billing            │
│  [Require approval ▾]  (or "Auto-approve")                   │
│                                                              │
│  ── Mileage & Vehicles ─────────────────────────────────────  │
│  ☑ Enable mileage logbook                                    │
│  Mileage rate:  ₪2.05 / km (2026 ITA rate)  [Update rate →] │
│  Vehicles:  [Manage vehicles →]                              │
│                                                              │
│  ── Integrations ───────────────────────────────────────────  │
│  ☑ Allow task magic link time tracking                       │
│    Team members can send a magic link to start timer         │
│    on a task from their email.                               │
│                                                              │
│                                [Save settings]               │
└──────────────────────────────────────────────────────────────┘
```

---

## Schema Delta

```sql
-- All columns added to tenant_settings
-- NOTE: tenant_settings.time_rounding (TEXT, CHECK none|nearest_5|nearest_15|nearest_30|up_15|up_30)
-- is defined by spec 13 (time-management) — NOT re-added here; this UI reads/writes it.

ALTER TABLE tenant_settings ADD COLUMN time_min_billable_minutes INTEGER NOT NULL DEFAULT 0;
  -- Minimum entry duration in minutes; 0 = no minimum

ALTER TABLE tenant_settings ADD COLUMN time_idle_threshold_minutes INTEGER NOT NULL DEFAULT 10;
  -- Minutes of inactivity before idle prompt (5–60)

ALTER TABLE tenant_settings ADD COLUMN time_auto_pause_on_idle BOOLEAN NOT NULL DEFAULT true;
  -- True = show "Resume or discard idle time?" on return

ALTER TABLE tenant_settings ADD COLUMN time_standard_hours_per_day NUMERIC(4,2) NOT NULL DEFAULT 8.0;
  -- Standard working hours/day for overtime flagging

ALTER TABLE tenant_settings ADD COLUMN time_flag_overtime BOOLEAN NOT NULL DEFAULT false;
  -- Flag entries exceeding standard_hours_per_day in reports

ALTER TABLE tenant_settings ADD COLUMN time_require_overtime_approval BOOLEAN NOT NULL DEFAULT false;
  -- Overtime entries require manager approval before billing

ALTER TABLE tenant_settings ADD COLUMN contractor_time_enabled BOOLEAN NOT NULL DEFAULT true;
  -- Allow contractors to submit time entries via contractor portal

-- NOTE: contractor APPROVAL policy is NOT defined here. The flag
-- tenant_settings.contractor_require_time_approval (BOOLEAN DEFAULT true) is owned by
-- time-management (wave 5) and edited via contractor-settings
-- (spec 148, /settings/contractors). This page does not duplicate it.

ALTER TABLE tenant_settings ADD COLUMN mileage_enabled BOOLEAN NOT NULL DEFAULT false;
  -- Enable mileage logbook module (spec 166)

ALTER TABLE tenant_settings ADD COLUMN time_magic_link_enabled BOOLEAN NOT NULL DEFAULT true;
  -- Allow task magic link time tracking (spec 13)
```

---

## API

```
GET  /api/settings/time-tracking
     → fetch current time tracking settings
       Response: { time_rounding, time_min_billable_minutes, time_idle_threshold_minutes,
                   time_auto_pause_on_idle, time_standard_hours_per_day, time_flag_overtime,
                   time_require_overtime_approval, contractor_time_enabled,
                   mileage_enabled, time_magic_link_enabled }
       (contractor approval policy is on /settings/contractors, spec 148 — not here)
       Requires: settings:read

PATCH /api/settings/time-tracking
      → update time tracking settings
        body: any subset of columns above
        Requires: settings:write
```

---

## Architecture Decisions

| Decision | Choice | Reason |
|----------|--------|--------|
| All columns on tenant_settings | Not a separate time_settings table | Consistent with other module settings (expenses, invoices); no benefit from separate table for ~10 columns |
| Idle threshold client-enforced | Not server-enforced | Idle detection requires Page Visibility API + keyboard/mouse events; client-side only; server stores the configured threshold |
| Overtime flagging informational | Not blocking | Overtime is common in project-based work; blocking submissions would frustrate legitimate entries; flagging in reports gives visibility without friction |
| Mileage behind toggle | Not always shown | Mileage adds complexity for freelancers who don't use it; opt-in keeps the default time tracking UI clean |
