Contacts & Fields
Track keeps first-class records for three entity types: contacts (people), companies (organizations), and deals (opportunities). Each gets a detail page, custom fields, and a linked activity timeline.
Contacts
A contact is a person. Default fields:
| Field | Type | Notes |
|---|---|---|
name | text | Required. |
email | text | Unique per workspace. |
phone | text | Formatted E.164 on save. |
title | text | Job title. |
company_id | FK → companies | Optional link to employer. |
owner_id | FK → users | Who owns the relationship. |
tags | text[] | Free-form tags. |
notes | text | Freeform internal note. |
Companies
A company is an organization — a customer, vendor, partner, or prospect. Default fields:
| Field | Type | Notes |
|---|---|---|
name | text | Required. |
domain | text | Canonical domain (e.g., acme.com). Used for email dedup. |
industry | text | |
size | text | 1–10, 11–50, 51–200, etc. |
parent_id | FK → companies | Parent company for subsidiaries. |
owner_id | FK → users |
Deals
A deal is an opportunity moving through a pipeline. Default fields:
| Field | Type | Notes |
|---|---|---|
name | text | Required. |
value_cents | int | Deal value in minor units. |
currency | text | ISO 4217 code. |
stage_id | FK → board_stages | Current pipeline stage. |
close_date | date | Expected close. |
probability | numeric | 0–100. Inherits from stage if unset. |
primary_contact_id | FK → contacts | |
company_id | FK → companies | |
owner_id | FK → users |
Custom fields
Add fields from Settings → Custom Fields. Supported types:
- Text (short, long)
- Number (integer, decimal)
- Date, DateTime
- Boolean
- Single-select (dropdown)
- Multi-select
- URL
- Currency
- Link (to another contact, company, or deal)
Custom fields appear automatically in:
- Record detail forms
- List view columns (toggleable)
- Filters and saved views
- CSV exports
- Automation triggers and conditions
No schema migration is required — custom fields are stored in a
structured jsonb column and validated at the application layer.
Linking records
Records link to each other through foreign keys (built-in) or through Link custom fields (user-defined).
- Contact → Company is a built-in one-to-many relationship.
- Company → Company (parent/child) supports one level of hierarchy; use custom fields for deeper nesting.
- Deal → Contact(s) supports a primary contact plus any number of additional contacts via a join table.
Merging duplicates
If you end up with two records that should be one (usually after a CSV import), open either record → ... menu → Merge. Pick the canonical record. Track merges fields (preferring the canonical value where both exist), moves all linked records, and preserves the full activity timeline on the merged record.
A merge is logged to audit_log — you can see which user merged
what and when.
Bulk operations
From list view, shift-click or range-select multiple rows. The bulk action bar supports:
- Assign owner
- Add or remove tags
- Update a field value
- Export selection to CSV
- Delete (soft-delete — deleted records are recoverable for 30 days)
Importing from CSV
Open the board and go to Board Settings → Import / Export → Import CSV. Pick a CSV (up to 25 MB / 100k rows / 200 columns). Track walks you through five steps: pick → parse → preview → import → result.
In the preview step:
- Column mapping — every CSV column is matched to a board field. Track auto-matches in three tiers (exact label, exact field id, fuzzy with edit distance ≤ 2). You can override any pick or choose "Ignore this column" for fields you don't want imported. The same board field can't be the target of two CSV columns.
- Match existing rows by — pick a field (typically Email) that uniquely identifies a record. Leave it blank to insert every row as new.
- When a match is found — choose Skip (keep existing, drop incoming) or Update (overlay the existing row's values from the CSV).
- Target group — when the board has groups, pick one for every imported row, or "Map from column" to route rows by a CSV column. New group names in that column are auto-created.
You can also import a CSV or JSON file as a brand-new board from the sidebar's "Add new board → Import from file…" entry. JSON imports must come from another Track deployment's Export JSON button. If the JSON references users that don't exist on the destination, those person-field values are cleared and you get a warning.
Recent imports & undo
Every import is recorded as an import batch for 7 days so you can roll it back. Find the list under Board Settings → Import / Export → Recent imports.
Each entry shows the import mode (create or append), how long ago
it ran, and the row count, with an Undo action that:
- For a
createimport — deletes the entire imported board, including its fields, groups, and rows. The action prompts you to confirm before doing anything destructive. - For an
appendimport that only inserted rows — removes exactly the rows that were added. Pre-existing contacts on the board are untouched. - For an
appendimport that updated existing rows — restores those rows to their pre-import values from the snapshot taken at import time, and removes any rows the same import inserted.
After 7 days the batch disappears from the list and undo is no longer available — but the rows themselves stay in place.