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.in2. The object model — say it this way every time
/{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.
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.
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 astime.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
/concepts/roles-and-capabilities. Every other page links there
rather than re-explaining the model.
Two rules writers get wrong:
- A capability is not a scope.
time.viewOtherssays you MAY view other people’s time. Supervision scope says WHOSE time. A manager withtime.viewOthersstill only sees the people in their scope. Always separate the two. - 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_ACTIONSandOWNER_EXCLUSIVE_ACTIONSinsrc/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.
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.
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, voidsent→ viewed, partially_paid, paid, overdue, voidviewed→ partially_paid, paid, overdue, voidpartially_paid→ paid, overdue, voidoverdue→ partially_paid, paid, voidpaidandvoidare terminal.
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.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:
Clients and projects:
Standard numbers — use these so arithmetic matches across pages:
- Sarah Lin billable rate: 45/hour.
- Jonas Bergman billable rate: 60/hour.
- Ana Ferreira (contractor) billable rate: 55/hour.
- Workspace currency: USD.
- A standard week is 40 hours, Monday to Friday, 9:00–17:00.
Sarah tracks 3 hours on “Homepage wireframes” for Bluebird Coffee — Website Redesign. Her billable rate is 300** to the project. Her cost rate is 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
codefor values and keys. - Prefer a short table over a long paragraph.
- Paragraphs are 1–3 sentences. Never a wall of text.
- Biometric attendance devices (eSSL / ZKTeco) — a private client-specific module
convex/lib/customModules.tsand any custom module- The v1 → v3 migration tooling
- The
/dev/emailsroute - 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:
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.
<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):
- One or two sentences answering the reader’s question immediately.
## What is X?— plain definition.## When to use it— realistic situations.## How it works— the concept.## How to <do the thing>—<Steps>.## Example— use the cast from section 9.## Options and settings— every field and control.## Permissions— which roles and capabilities.## What happens next— downstream effects.## Common questions—<AccordionGroup>, real search questions.## Troubleshooting— real problems.## 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.removeremoves 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.
- 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, norate.viewBilling, norate.viewCost– yet holdsinvoice.manageandpayment.record. Counter-intuitive, and true.
ACTIONSis 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
Systembadge. - Supervision scope has five levels:
none,project,group,project_group,workspace. Onlyworkspacewidens 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_ACTIONSis a per-project grant fortask.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.
- Timesheets have two layers: the entry chain (
draft → submitted → approved → locked → invoiced) and the submission aggregate (submitted / approved / changes_requested / withdrawn).rejectedis derived, never stored. Rejecting and reopening both land onchanges_requested. - Leave has a fourth status,
withdrawn, alongside pending / approved / rejected. - Nothing sets an invoice to
viewedoroverdue. Only send, void and payment re-derivation move an invoice. Document the transition table, but say so honestly.
- Trial is 14 days, granted per person on their first workspace.
past_duehas a 7-day grace period, then Free.- Trash retention is selectable: 7 / 14 / 30 / 60 / 90 days, default 30.
- There is no full-page Inbox – the bell popover is the whole surface (50 rows, badge caps at 99+).
/settings/notificationsis 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.
- 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 entrieson 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>.