> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timetracker.in/llms.txt
> Use this file to discover all available pages before exploring further.

# SHARED FACTS

# SHARED FACTS — the canonical vocabulary for TimeTracker docs

**Every writer MUST read this file before writing a page.** It exists so 200 pages
cannot contradict each other. If a fact is here, use it verbatim. If a fact is NOT
here, go read the source code — never invent it.

Source repo: `/Users/jaseemabbas/Documents/Lemaistre Lab/Web/timetracker/timetracker-web-3`
Knowledge graph: `<repo>/.understand-anything/knowledge-graph.json` (2,955 nodes with summaries)
Graph query helper: `node <docs-repo>/.build/graph.mjs <command> <args>`

***

## 1. What the product is

TimeTracker is a client-work management platform for service businesses —
agencies, consultancies and professional-service teams of roughly 2 to 50 people.

It replaces the usual split stack of "a project tool + a time tracker + a budget
spreadsheet + an invoicing app" with one connected system.

**The one-line value:** every task carries both operational and financial context —
estimate, tracked time, billable value, cost, budget impact — so a business knows
whether a client project is still profitable before it becomes a problem.

**The signature workflow (memorise this chain):**

Client → Project → Task → Estimate → Time entry → Approval → Budget impact → Invoice → Payment

**Product name in prose:** "TimeTracker". Never "Time Tracker", never "TT".
**Website:** timetracker.in

***

## 2. The object model — say it this way every time

```
Workspace
 └── has Members (people with a Role)
      └── Members belong to Groups
 └── has Clients (the companies you bill)
      └── Clients have Projects
           └── Projects have Sections
                └── Sections hold Tasks
                     └── Tasks have Estimates, Assignees, Tags, Subtasks
 └── People track Time Entries against a Task or Project
      └── Time Entries roll up into a weekly Timesheet
           └── A Timesheet is Submitted, then Approved
                └── Approved billable time can become an Invoice
                     └── An Invoice receives Payments
 └── Time Entries also consume a Project Budget
      └── Budget + Cost rates produce Profitability
```

**Workspace is the tenant.** Everything lives inside exactly one workspace. A
workspace has a URL slug, and every in-app route starts with it:
`/{workspaceSlug}/projects`. A person can belong to several workspaces and
switches between them at `/spaces`.

***

## 3. The seven roles — EXACT names and labels

Role values in the system are lowercase snake\_case. The human label is title case.
**Never invent a role.** There are exactly seven.

| Value             | Label           | One-line description                                                         |
| ----------------- | --------------- | ---------------------------------------------------------------------------- |
| `owner`           | Owner           | Holds every permission, including deleting the workspace.                    |
| `admin`           | Admin           | Full workspace administrator. Everything except deleting the workspace.      |
| `project_manager` | Project Manager | Owns delivery: clients, projects, tasks, approvals, budgets, invoices.       |
| `finance`         | Finance         | Owns the money surface: invoices, payments, expenses, exports. Not delivery. |
| `member`          | Member          | A regular employee. Tracks time, works tasks, submits their own work.        |
| `contractor`      | Contractor      | Like Member but cannot see clients or build reports. Narrowest staff role.   |
| `client`          | Client          | An external client-portal contact. Holds **zero** internal capabilities.     |

**The hierarchy is a strict subset chain:**
`owner ⊇ admin ⊇ project_manager / finance ⊇ member ⊇ contractor ⊇ client`

Each lower role's capabilities are a subset of the role above it.

* Owner is a strict superset of Admin. The ONLY difference is `workspace.delete`.
* Project Manager and Finance are siblings, not ranked against each other. PM owns
  delivery; Finance owns money.
* Client has an empty capability set. A portal contact sees only what is explicitly
  shared with their client company.

**Invitable roles:** every role except `owner`. A `client` can only be invited from
that client company's detail page, because a portal contact must be tied to a
client company. Inviting a bare client with no company is rejected by the server.

***

## 4. Capabilities — the 66 named permissions

A capability (also called an "action") is a single named permission such as
`time.approve`. Roles are seeded with a set of capabilities. Workspaces can define
custom roles, and individual people can have specific capabilities denied.

**The full list, grouped:**

* **Workspace:** `workspace.updateSettings`, `workspace.delete`
* **People:** `member.invite`, `member.create`, `member.changeRole`, `member.remove`,
  `role.manage`, `invite.revoke`, `group.manage`, `audit.read`
* **Clients:** `client.view`, `client.manage`
* **Projects & tasks:** `project.manage`, `tag.manage`, `task.create`, `task.edit`,
  `task.delete`, `task.reviseEstimate`, `task.bulkEdit`
* **Rates:** `rate.manage`, `rate.viewBilling`, `rate.viewCost`
* **Time:** `time.track`, `time.edit`, `time.viewCost`, `time.submit`, `time.approve`,
  `time.adjust`, `period.close`, `time.viewOthers`, `time.editOthers`,
  `time.submitOnBehalf`, `time.reopenApproval`, `time.remind`
* **Money:** `budget.manage`, `invoice.manage`, `payment.record`
* **Expenses:** `expense.submit`, `expense.approve`, `expenseCategory.manage`
* **Time off:** `leave.request`, `leave.approve`, `leave.viewOthers`, `leave.managePolicy`
* **Reports:** `report.view`, `report.create`, `report.edit`, `report.manage`,
  `report.share`, `report.schedule`, `report.export`
* **Time clock:** `timecard.clock`, `timecard.view`, `timecard.manage`,
  `timecard.approve`, `timecard.submit`, `timecard.submitOnBehalf`, `timecard.reopen`
* **Planner:** `block.manage`, `block.manageOthers`
* **Admin & integrations:** `webhook.manage`, `data.export`, `billing.manage`,
  `location.manage`, `schedule.view`, `schedule.manage`

**Canonical page:** `/concepts/roles-and-capabilities`. Every other page links there
rather than re-explaining the model.

**Two rules writers get wrong:**

1. **A capability is not a scope.** `time.viewOthers` says you MAY view other people's
   time. *Supervision scope* says WHOSE time. A manager with `time.viewOthers` still
   only sees the people in their scope. Always separate the two.
2. **Owner-only actions** cannot be granted to anyone else, and some actions are
   deny-only overridable per person. Do not promise a capability can be freely moved
   between roles without checking `OVERRIDABLE_ACTIONS` and `OWNER_EXCLUSIVE_ACTIONS`
   in `src/modules/workspace/domain/permissions.ts`.

***

## 5. Apps (modules) — the 15 togglable areas

An **App** is a switchable area of the product. Workspace settings → Apps
(`/{slug}/settings/apps`) turns each on or off. Turning one off HIDES it; it never
deletes data.

They render in three groups: **Work**, **Money**, **Connections**.

| Key          | Label                   | Group       | On by default | Plan feature     | Requires           |
| ------------ | ----------------------- | ----------- | ------------- | ---------------- | ------------------ |
| `time`       | Time tracking           | Work        | Yes           | `time_tracking`  | `projects`         |
| `projects`   | Projects & tasks        | Work        | Yes           | `projects_tasks` | —                  |
| `timesheets` | Timesheets              | Work        | Yes           | `timesheets`     | `time`             |
| `reports`    | Reports                 | Work        | Yes           | *(none — free)*  | —                  |
| `schedules`  | Work schedules          | Work        | Yes           | `timesheets`     | —                  |
| `timecard`   | Time Clock              | Work        | **No**        | `attendance`     | `schedules`        |
| `timeoff`    | Time off                | Work        | Yes           | `time_off`       | —                  |
| `planner`    | Resource Planner        | Work        | Yes           | `planner`        | `projects`         |
| `location`   | Location rules          | Work        | **No**        | `location_rules` | —                  |
| `invoicing`  | Invoices                | Money       | Yes           | `invoicing`      | `projects`         |
| `expenses`   | Expenses                | Money       | Yes           | `expenses`       | `projects`         |
| `budgets`    | Budgets & profitability | Money       | Yes           | `budgets`        | `projects`, `time` |
| `portal`     | Client portal           | Connections | Yes           | `client_portal`  | `projects`         |
| `calendar`   | Calendar                | Connections | Yes           | `integrations`   | `planner`          |
| `webhooks`   | Webhooks & API          | Connections | Yes           | `integrations`   | —                  |

**Dependencies are enforced.** You cannot turn on Time Clock without Work schedules,
because expected minutes and absence detection resolve from the schedule. Turning
OFF a required app warns about the dependents it will take with it.

**Reports has no plan feature** — the app is on every plan. What the plan tiers is
the *depth*: custom reports, scheduling and export are Pro.

**The two gates are different things.** An app being OFF means hidden and gone from
the sidebar. A plan not including it means it STAYS in the sidebar and shows a
blurred paywall. Never conflate "turned off" with "not on your plan".

***

## 6. Plans — Free and Pro

There is one paid tier, **Pro**, on two cadences (monthly and yearly), plus a
permanent **Free** tier. Billing runs through Paddle as merchant of record, which
handles global tax and VAT.

**The dividing line is capture vs resolution.**

* **Free = record your work.** Anyone can track time, fill a timesheet, submit an
  expense, request leave, and clock in and out.
* **Pro = resolve it.** Only a paying workspace can APPROVE any of it, invoice it,
  or take it out of the product as a file.

**Free features:** `time_tracking`, `projects_tasks`, `timesheets`, `attendance`,
`time_off`, `expenses`.

**Pro adds:** `approvals`, `planner`, `location_rules`, `invoicing`, `payments`,
`budgets`, `profitability`, `client_portal`, `advanced_reports`, `integrations`,
`exports`.

**Free seat limit: 3 people.** The 4th person is the paid wall.

Seats count **people with access, not just staff**: every active membership of every
role PLUS every outstanding invitation. An open invite is access. A client-portal
contact is a login like any other, so portal contacts count toward seats.

**Being over the cap is legal and never punished.** A 5-person workspace that drops
to Free keeps all 5 people working. The rule bounds only the NEXT add — blocked
while the count is at or above 3, allowed again if someone leaves.

**A lapse never destroys data.** A Free workspace accumulates submissions it cannot
clear, and clears the whole backlog the day it pays.

**`profitability` is an honest half-gate.** It gates exactly one write: setting a
**cost** rate. Cost, revenue and margin already recorded stay readable on Free.
Billing rates stay free to set. Who may SEE those numbers is a capability question
(`time.viewCost`, `rate.viewCost`), never a plan question.

***

## 7. Statuses — the exact sets

Never invent a status. These are the real ones.

**Timesheet:** `draft` → `submitted` → `approved` / `rejected`, plus `locked`.
Approved time is locked so only an admin can change it.

**Invoice:** `draft`, `sent`, `viewed`, `partially_paid`, `paid`, `overdue`, `void`.
Allowed transitions:

* `draft` → sent, void
* `sent` → viewed, partially\_paid, paid, overdue, void
* `viewed` → partially\_paid, paid, overdue, void
* `partially_paid` → paid, overdue, void
* `overdue` → partially\_paid, paid, void
* `paid` and `void` are terminal.

**Expense:** `draft`, `submitted`, `approved`, `rejected`, `invoiced`.

**Leave request:** `pending`, `approved`, `rejected`.

**Task:** tasks move through per-project **Sections**, which the project defines.
Filters also expose a `status` field with values including `todo`, `in_progress`,
`done`. Sections are the user-facing concept; explain sections first.

**Budget kind:** `hours` or `money`. **Periodicity:** `one_time` or `monthly`
(a monthly budget is a recurring retainer).

***

## 8. Terms readers confuse — always disambiguate

Write a short "X vs Y" block wherever these appear.

| A              | B                  | The difference                                                                                                                                       |
| -------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Estimate       | Budget             | An estimate is on a **task** — how long the work should take. A budget is on a **project** — the ceiling of hours or money for the whole engagement. |
| Billable rate  | Cost rate          | Billable is what you CHARGE the client. Cost is what the person COSTS you. Margin is the gap.                                                        |
| Billable       | Non-billable       | Whether an hour can appear on an invoice. Non-billable hours are still tracked and still count toward a timesheet.                                   |
| Timer entry    | Manual entry       | A timer runs live and stops. A manual entry is typed after the fact. Both produce the same time entry.                                               |
| Submitted      | Approved           | Submitted means the person is finished and has sent the week for review. Approved means a reviewer accepted it and the time is locked.               |
| Role           | Capability         | A role is a named bundle. A capability is one named permission inside it.                                                                            |
| Capability     | Supervision scope  | Capability = MAY you. Scope = for WHOM. Both must pass.                                                                                              |
| App turned off | Not on your plan   | Off = hidden entirely. Not on plan = visible with a paywall.                                                                                         |
| Schedule       | Tracked time       | A schedule is what someone is EXPECTED to work. Tracked time is what they actually did. Timesheets compare the two.                                  |
| Time Clock     | Time tracking      | Time Clock records presence at work (clock in / out). Time tracking records hours against a task.                                                    |
| Archive        | Trash              | Archive hides finished work but keeps it reachable and reportable. Trash is a staging area before permanent deletion, and is restorable.             |
| Project        | Client             | A client is the company you bill. A project is one engagement for that client. One client, many projects.                                            |
| Group          | Project membership | A group is a standing team of people. Project membership is who works on one project.                                                                |

***

## 9. The example cast — REUSE THESE across every page

Do not invent new companies or people. Consistency is what makes the docs feel
like one product.

**The workspace: `Northwind Studio`** — a 12-person digital agency. Slug `northwind`.

**People:**

| Name          | Role            | Notes                                                |
| ------------- | --------------- | ---------------------------------------------------- |
| Maya Ellis    | Owner           | Founder. Sets up the workspace.                      |
| Tom Whitfield | Admin           | Operations lead.                                     |
| Priya Raman   | Project Manager | Runs client delivery. Approves timesheets.           |
| Daniel Okafor | Finance         | Sends invoices, records payments.                    |
| Sarah Lin     | Member          | Senior designer. The default "person tracking time". |
| Jonas Bergman | Member          | Developer.                                           |
| Ana Ferreira  | Contractor      | Freelance copywriter, part-time.                     |
| Ruth Castillo | Client          | Portal contact at Bluebird Coffee.                   |

**Clients and projects:**

| Client           | Project          | Shape                              |
| ---------------- | ---------------- | ---------------------------------- |
| Bluebird Coffee  | Website Redesign | Fixed money budget, \$40,000       |
| Bluebird Coffee  | Monthly Retainer | Recurring monthly budget, 40 hours |
| Harbor Logistics | Mobile App       | Hours budget, 600 hours            |
| Fenwick Legal    | Brand Refresh    | Small project, no budget           |

**Standard numbers — use these so arithmetic matches across pages:**

* Sarah Lin billable rate: **$100/hour**. Cost rate: **$45/hour**.
* Jonas Bergman billable rate: **$120/hour**. Cost rate: **$60/hour**.
* Ana Ferreira (contractor) billable rate: **$80/hour**. Cost rate: **$55/hour**.
* Workspace currency: **USD**.
* A standard week is **40 hours**, Monday to Friday, 9:00–17:00.

**Worked example everyone can reuse:**

> Sarah tracks 3 hours on "Homepage wireframes" for Bluebird Coffee — Website
> Redesign. Her billable rate is $100/hour, so the entry is worth **$300\*\* to the
> project. Her cost rate is $45/hour, so it costs Northwind **$135\*\*. The margin on
> those 3 hours is **\$165**.

***

## 10. Voice and writing rules

* **Reading level: 8th grade.** Short sentences. Simple words. One idea per sentence.
* **Second person.** "You create a project." Not "the user creates a project."
* **Present tense.** "The timer stops." Not "the timer will stop."
* **Say the outcome first**, then the steps.
* **En dash (–) only.** Never an em dash. Never a hyphen used as a separator.
* **Never say "simply", "just", "easy", "obviously".**
* **Never invent UI.** If you did not see the button in the source, do not describe it.
* **Every number must be arithmetically correct.** Check your maths.
* Use **bold** for UI labels: click **Save**. Use `code` for values and keys.
* Prefer a short table over a long paragraph.
* Paragraphs are 1–3 sentences. Never a wall of text.

**Do NOT document (out of scope, decided):**

* Biometric attendance devices (eSSL / ZKTeco) — a private client-specific module
* `convex/lib/customModules.ts` and any custom module
* The v1 → v3 migration tooling
* The `/dev/emails` route
* Internal architecture, Convex function names, file paths, or the tech stack.
  These are USER docs. A reader never sees a table name.

***

## 11. Mintlify page format

Every `.mdx` file starts with frontmatter:

```mdx theme={null}
---
title: "How to approve a timesheet"
description: "Review a submitted timesheet, approve or reject it, and understand what happens to the time once it is locked."
---
```

* `title` — matches real search intent. Sentence case. Under 60 characters.
* `description` — 120–160 characters, useful to a human AND a search engine. Never
  keyword stuffing. It is the meta description.

**Components available** (use them where they genuinely help, do not decorate):

```mdx theme={null}
<Steps>
  <Step title="Open the project">Go to **Projects** and pick the project.</Step>
  <Step title="Set the budget">Click **Budget**, then enter the amount.</Step>
</Steps>

<Note>Useful aside.</Note>
<Tip>A better way to do something.</Tip>
<Warning>Something that loses data or money.</Warning>
<Info>Neutral context.</Info>

<CardGroup cols={2}>
  <Card title="Billable rates" icon="dollar-sign" href="/rates/billable-rates">
    What you charge a client per hour.
  </Card>
</CardGroup>

<AccordionGroup>
  <Accordion title="Can I approve my own timesheet?">Answer.</Accordion>
</AccordionGroup>

<Tabs>
  <Tab title="Owner">…</Tab>
  <Tab title="Member">…</Tab>
</Tabs>
```

**Every page ends with a "Related guides" section** — a `<CardGroup>` or a short
bullet list of 3–6 internal links. Internal links are absolute paths with no
extension: `/timesheets/submit-a-timesheet`.

**Standard page skeleton** (adapt, do not force):

1. One or two sentences answering the reader's question immediately.
2. `## What is X?` — plain definition.
3. `## When to use it` — realistic situations.
4. `## How it works` — the concept.
5. `## How to <do the thing>` — `<Steps>`.
6. `## Example` — use the cast from section 9.
7. `## Options and settings` — every field and control.
8. `## Permissions` — which roles and capabilities.
9. `## What happens next` — downstream effects.
10. `## Common questions` — `<AccordionGroup>`, real search questions.
11. `## Troubleshooting` — real problems.
12. `## Related guides` — internal links.

***

## 11a. Corrections found while writing — DO NOT regress these

These were all verified against source after the first draft. Several contradict what
a reasonable person would assume, which is exactly why they are written down.

**Workspace**

* **The slug cannot be renamed.** No mutation writes it after creation. Renaming the
  workspace does **not** change the URL, which is why old links keep working. Never
  warn a reader to "change it early".
* **There is no self-service "leave workspace" control.** Someone with `member.remove`
  removes you, or you delete your account.
* Editable workspace settings are exactly: name, base currency, timezone, date format,
  time format, week start, trash retention, timesheet period, invoice sender.

**Rates**

* **There is no workspace default rate.** The resolver has a fifth tier but nothing
  ever supplies it. The real chain is **task → project member → person → client**,
  then unresolved. A missing rate is *unpriced*, never \$0.
* Cost rates have exactly **one** tier: the person.
* **Finance holds no rate capabilities at all** – no `rate.manage`, no
  `rate.viewBilling`, no `rate.viewCost` – yet holds `invoice.manage` and
  `payment.record`. Counter-intuitive, and true.

**Roles and permissions**

* `ACTIONS` is **66**. The role editor shows \~62 checkboxes because owner-exclusive and
  non-assignable actions are not offered. Say 66 for capabilities, and explain the
  editor's count where it appears.
* **Only Owner and Client are locked.** Admin, Project Manager, Finance, Member and
  Contractor are editable, renameable and deletable despite their `System` badge.
* **Supervision scope has five levels**: `none`, `project`, `group`, `project_group`,
  `workspace`. Only `workspace` widens PROJECT reach; the middle three differ only in
  which PEOPLE you reach.
* Per-person exceptions are **subtractive only**, and today the only exposed switch is
  **Clock in and out**. `OVERRIDABLE_ACTIONS` is a per-project *grant* for
  `task.reviseEstimate` – the opposite of a deny. Do not describe it as one.
* You see a client only when you can see one of their projects. There is no client scope.

**Statuses**

* Timesheets have **two layers**: the entry chain (`draft → submitted → approved →
  locked → invoiced`) and the submission aggregate (`submitted / approved /
  changes_requested / withdrawn`). `rejected` is **derived**, never stored. Rejecting
  and reopening both land on `changes_requested`.
* Leave has a fourth status, `withdrawn`, alongside pending / approved / rejected.
* **Nothing sets an invoice to `viewed` or `overdue`.** Only send, void and payment
  re-derivation move an invoice. Document the transition table, but say so honestly.

**Plans**

* Trial is 14 days, granted per person on their **first** workspace.
* `past_due` has a 7-day grace period, then Free.
* Trash retention is selectable: 7 / 14 / 30 / 60 / 90 days, default **30**.

**Notifications**

* **There is no full-page Inbox** – the bell popover is the whole surface (50 rows,
  badge caps at 99+).
* `/settings/notifications` is the **workspace defaults** page. Personal settings live
  on the profile.
* **Digests have no user-facing control.** Do not invent a toggle. Quiet hours are gone.

**Product gaps to write around, not describe**

* No bulk importer exists (no CSV, no Toggl/Clockify/Harvest).
* No project templates reachable in the UI.
* No workspace FX-rate screen – only the per-invoice exchange-rate section.
* Invoice Terms/Notes are stored but never rendered.
* `Auto-create time entries` on leave policies and holidays is not wired to time entries.

## 12. Accuracy contract

You have full tool access to the product repo. **Ground every claim.**

* Read the actual page component under `src/app/[workspaceSlug]/…` for what is on screen.
* Read `src/modules/<domain>/ui/` for the forms, fields, filters and dialogs.
* Read `src/modules/<domain>/domain/` for the rules, states and maths.
* Query the graph for a fast orientation: `node .build/graph.mjs tag <tag>`.

If you cannot confirm a behaviour from the source, **leave it out**. A missing
sentence is fine. A wrong sentence is not — this product is a system of record for
time and money, and a wrong doc costs a customer real money.
