Time Settings
Workspace defaults — week start, rounding, runaway-timer threshold, auto-submit, default rate, currency, and rate overrides.
Path: /time/settings. The page uses the standard ModuleSettingsLayout with sub-tabs.
Screenshot needed — /time/settings General tab with the workspace defaults form
General
Single form, persisted in the time_tracking_settings table (one row per workspace, lazy-created on first read).
| Setting | Default | Effect |
|---|---|---|
| Week start day | Monday (1) | Drives the timesheet grid columns; 0–6 (Sunday=0) |
| Rounding minutes | 0 (no rounding) | Granularity to round timer-stopped entries to (5, 6, 15, 30) |
| Rounding strategy | Nearest | nearest / up / down |
| Default billable | false | Whether new entries default to billable |
| Require description | false | Forces non-empty description on every entry |
| Allow future entries | false | If false, refuses entries with log_date > today |
| Auto-submit day-of-week | unset | (Pro) If set, the cron auto-submits last week's drafts on this day |
| Default hourly rate | 0 | Fallback when no override matches |
| Default currency | USD | Currency stamped when no override matches |
| Default weekly hours | 40 | Utilization denominator when People isn't subscribed |
| Runaway timer hours | 12 | Free: notify-only when a timer runs past this. (Pro) Auto-stop when runaway_timer_hours_auto_stop is on. |
| Idle minutes | 10 | Threshold (minutes of inactivity) before the idle prompt opens while a timer is running. See Timer → Idle detection. |
| Pomodoro focus minutes | 25 | Length of a focus session in Pomodoro mode. |
| Pomodoro break minutes | 5 | Length of a short break (between focus sessions). |
| Pomodoro long break minutes | 15 | Length of a long break (after every 4th focus). |
| Onboarding dismissed at | unset | Set automatically when the user dismisses the onboarding checklist on /time (auto-set when ≥80% complete). |
| Required fields | [] | Any combination of description / project / tags enforced server-side on create + update. Empty = no gate. See Timer → Required-fields gate. |
| Restrict tag creation | false | When on, only workspace admins can create new tags. Members pick from existing tags only. |
| Reminder enabled | false | Master switch for tracking reminders (see below). |
| Reminder min daily hours | unset | When set, members below this threshold get an email + in-app nudge the next morning. |
| Reminder min weekly hours | unset | Same as daily, evaluated each Monday for the prior week. |
| Reminder send time UTC | 9 | Hour-of-day (0–23 UTC) when the reminder cron fires. |
The runaway-timer threshold is per-workspace, not per-user. If your team has occasional 14-hour deploy days, raise it before the cron starts auto-stopping legitimate sessions.
Entry locking
Path: /time/settings → Entry Locking card.
| Setting | What |
|---|---|
| Lock date | An ISO date. Entries on or before this date become immutable for non-admin users. Workspace admins / owners can still edit (e.g. fix a payroll entry after lock). Set the date and save; clear it to lift the lock. |
When a lock date is set, every create / update / delete server action checks entry.log_date <= lock_date and rejects the write with a clear error message for non-admins. The check applies regardless of surface (timer, manual, API, calendar-import convert).
Locked entries display a 🔒 Lock indicator in List view. The Edit / Delete / Split actions are hidden; the Copy timer link action stays active so a locked entry can still be re-played as a fresh entry.
This is separate from the per-entry approval lock: an approved entry (locked_at set by the approval trigger) is locked individually regardless of the workspace lock date.
Tracking reminders
Path: /time/settings → General form → Reminders section.
When reminder_enabled is on, the daily cron at the configured reminder_send_time_utc evaluates each workspace member:
- Daily: if yesterday's tracked hours <
reminder_min_daily_hours, send a reminder email + in-app notification. Skipped on weekends and on days the user has already tracked above the threshold. - Weekly: every Monday, if last week's total <
reminder_min_weekly_hours, send a weekly reminder.
Reminders surface inside Workestra (notification bell) and in email — no Slack DM yet (planned).
A user who tracks zero on day N and zero on day N+1 gets one reminder, not two — the cron de-duplicates to avoid nag fatigue.
Audit log
Path: /time/settings/audit-log (admins only). Lists every state-changing action on time_entries rows: create, update, delete, split, lock, submit, approve, reject.
| Filter | What |
|---|---|
| User ID | Limit to a specific actor (the user who made the change, not the entry's owner) |
| Action | Dropdown: created / updated / deleted / split / locked / submitted / approved / rejected — or "All actions" |
| Date from / to | Action timestamp window |
Each row expands to show the before / after diff for update events: the original hours / log_date / description / project_id / billable / tags vs. the new values. For on-behalf-of writes, the diff also includes on_behalf_of so the trail names the target user.
Pagination: 50 rows per page, ordered newest first.
Rates
Pro — requires Finance subscription.
Top-down rate-resolution chain — see Rates & Billing for full priority logic.
UI on /time/settings/rates is structured top-to-bottom in priority order:
- Workspace default — fallback for everyone (the card at the top)
- User / project rate overrides — most-specific-wins matrix below
- Per-task rate overrides (P1-9) — bottom section. The 5th, most specific level: when a time entry is on a task, a task-rate override beats the project + user combination.
Each section: Add row → pick scope, set rate / currency / effective dates → save. Inline edit; soft-confirm delete.
Constraints:
- User / project overrides must set at least one of
user_idorproject_id - Per-task rate is keyed on
task_idonly - Effective date range must be valid (
from≤toif both set)
Approvers
(Pro) Multi-level approval routes — the heart of the Time Pro approval flow. See Approvals for routing semantics.
UI on /time/settings/approvers shows every route grouped by scope (user / team / project / workspace). Each row:
- Scope (e.g. "Team: Engineering")
- Levels (1, 2, 3, …) with the approver + optional fallback per level
- Edit / delete buttons
The free tier still uses the simpler model: anyone with time:approve permission can approve any submitted timesheet. To grant approval rights:
- Go to Teams → Roles
- Edit (or create) a role
- Check the
time:approvepermission - Assign the role to the relevant users
Workspace admins automatically have time:approve regardless of role.
Integrations
Three sub-tabs: Native integrations, Browser extensions, Webhooks.
Native integrations
External calendars (Google / Outlook / iCal) connect from here. See Calendar Import for the full flow. Disconnect with one click.
Browser extensions
Direct download buttons for Chrome and Firefox + a list of supported apps the extension injects into. See Browser Extension.
Webhooks
The webhooks UI. See Integrations for full event list and delivery semantics.
Per webhook row:
- Name — friendly label
- URL — endpoint to receive POSTs
- Secret — generated once (visible in a one-time dialog after save), used for HMAC signing
- Events — multi-select from the available event list
- Enabled toggle
- Test button — fires a synthetic
webhook.testevent - Delivery log — last 50 attempts with status, response code, response body
Don't roll your own outbound webhooks elsewhere — the factory handles HMAC, retries, dead-letter queuing, and the daily delivery cron. Hitting it manually defeats those guarantees.
Permissions
Time-tracking-specific permissions:
| Permission | Default role | Effect |
|---|---|---|
time:read | member | View own entries |
time:read_all | manager / admin | View team entries |
time:write | member | Log time, edit own entries |
time:approve | manager / admin | Approve / reject timesheets and entries |
time:settings | admin | Edit workspace defaults |
time:invoice | finance / admin | Use the invoice bridge |
Configure these on the Teams → Roles page.
Database tables (advanced — for admins / devs)
If you ever need to inspect the underlying data, the time module owns these tables:
| Table | What's in it |
|---|---|
time_entries | Every entry (timer + manual + imported + API). Has cost_rate + locked_at columns. |
timesheets | Per-week containers, one per (user, period_start). Has current_approver_user_id for chain progress. |
time_tracking_settings | One row per workspace, the General-tab settings (incl. lock_date, required_fields, reminder_*, restrict_tag_creation). |
time_rate_overrides | The user / project rate-overrides matrix (bill + cost rate columns). |
time_task_rates | Per-task rate overrides (P1-9, the 5th rate level). |
time_approval_routes | (Pro) Multi-level approval routes per scope. |
time_entry_activities | Per-entry activity feed (status changes, hour edits, billable toggles). |
time_calendar_imports | Ghost-block events from connected calendars + their conversion state. |
time_goals | Per-user / per-project hour targets. |
time_favorites | Per-user pinned quick-start entries. |
time_report_schedules | Per-saved-view email-delivery configs. |
time_webhooks | Configured outbound webhooks. |
time_webhook_deliveries | Delivery attempts log. |
All workspace-scoped via RLS.
Next steps
Time Integrations
Where Time Tracking shows up across the rest of Workestra, plus webhooks, AI tools, and the public REST API.
Browser Extension
Chrome MV3 + Firefox WebExtension — start / stop the Workestra timer from any web app, with Start-timer buttons injected into Jira, Linear, Asana, Notion, GitHub.