Contacts
Contacts Management
Manage crew members, vendors, and production contacts
Overview
The Contacts feature provides a centralized directory for all people involved in your productions — crew members, rental houses, vendors, and clients. Contacts can be linked to projects, assigned departments and roles, and synced across devices.
Requirements
Functional Requirements
| ID | Requirement | Acceptance Criteria | Priority | Source |
|---|---|---|---|---|
| REQ-CON-001 | The system shall allow CRUD operations on contacts (name, email, phone, company, role, department, notes) | Create → item appears; Update → changes persist after reload; Delete → item removed; Read → all fields display | Must | contacts |
| REQ-CON-002 | The system shall support profile picture upload with built-in crop tool (JPG, PNG, HEIC) | Select photo → crop tool opens; drag to reposition; save → thumbnail updates; supports JPG/PNG/HEIC; max 10 MB | Must | useContacts |
| REQ-CON-003 | The system shall allow assigning contacts to project crew roles (Director, DP, etc.) | Open project crew tab → add contact → role dropdown shown; assigned contact appears in crew list; linked to contact record | Must | useContacts |
| REQ-CON-004 | The system shall allow assigning contacts as rental house / vendor representatives | Open rental house → assign contact as rep; rep shown on rental communications; rep contact card linked | Should | useContacts |
| REQ-CON-005 | The system shall organize contacts by department (Camera, Grip, Light, Sound, Production, Art, HMU & Costume, Post Production, Other) | Select department → contacts grouped; filter by department → only matching shown; multi-department assignment supported | Must | useContactsPage |
| REQ-CON-006 | The system shall display a confirmation dialog before deleting a contact | Click delete → confirmation dialog with contact name; confirm → contact removed; cancel → no change | Must | useContacts |
| REQ-CON-007 | The system shall sync contacts across devices when cloud sync is enabled | Edit contact on device A → appears on device B after sync; delete on B → removed on A; offline edits → queued and synced on reconnect | Must | useContacts |
| REQ-CON-008 | The system shall auto-populate contact details on exported PDFs when contacts are assigned to crew roles | Assign contact as DP → export PDF → PDF shows contact name/phone/email in crew section; unassigned role → field blank on PDF | Should | useContacts |
| REQ-CON-009 | The system shall support merging duplicate contacts with field-by-field conflict resolution | Select 2 contacts → merge dialog shows; pick fields from each → merged contact created; originals deleted | Should | useContactMerge |
| REQ-CON-010 | The system shall display which projects each contact is assigned to | Open contact → project list shown; click project → navigates to workspace; unassigned contact → empty state | Should | useContactProjects |
| REQ-CON-011 | The system shall support a mobile-optimized drawer layout for contact editing on small screens | Screen <768px → editor opens as bottom drawer; swipe down → dismiss; landscape → sidebar layout | Should | useMobileDrawerBehavior |
Non-Functional Requirements
| ID | Requirement | Metric | Priority |
|---|---|---|---|
| NFR-CON-001 | Contact list shall render within 200ms for ≤500 contacts | Render time | Should |
| NFR-CON-002 | Contact forms shall validate inline without page reload | UX responsiveness | Should |
Data Requirements
- Required fields: Name (string, non-empty)
- Optional fields: Email, phone, company, role, department, notes, profile picture
- Persistence: IndexedDB → cloud sync
- Profile pictures: Stored in Supabase Storage with OPFS fallback for offline
Constraints & Limits
- Profile picture max file size: 10 MB (
useAvatarUpload.jsrejects anything larger) - Supported image formats: JPG, PNG, HEIC
- No duplicate-name enforcement (multiple contacts can share a name)
Offline Behavior
- Fully available offline — all CRUD operations work without network
- Profile picture upload queues for sync when offline
- Contact changes sync when connectivity is restored
Dependencies
- Requires: Authentication — contacts sync via cloud
- Required by: Collaboration — crew linked to contacts
Accessing Contacts
Click Contacts in the sidebar to open the contacts directory.
There is no follow-up reminder panel. Earlier revisions of this page described one — a panel listing contacts you had not reached in seven or more days, with urgency tints and a dismiss control. That feature was never built: nothing in the app records when a contact was last reached (there is no
lastContactedfield), there is no such component, and no matching copy exists in either translation catalogue. Contacts has no staleness tracking today.
Adding a Contact
- Click Add Contact in the top-right corner
- Choose the contact type with the toggle at the top of the editor:
- Person — a crew member, freelancer, or contact person. Has roles, a rate, union/certifications, and can be assigned to a company they work at.
- Company — a rental house, production company, vendor, or client. Has a name, address, and tax/banking details, but no roles. Switching to Company hides the person-only fields.
- Fill in the contact details:
| Field | Description | Required |
|---|---|---|
| Name | Full name (Person) or company name (Company) | Yes |
| Email address | No | |
| Phone | Phone number | No |
| Company | (Person only) the company they work at — pick an existing one or use New company to create and link one on the spot | No |
| Role | Job title or crew position (Person only) | No |
| Department | Production department (Camera, Grip, Light, Sound, Production, Art, HMU & Costume, Post Production, Other) (Person only) | No |
| Address | Street, house number, postal code, city, state/province, and country — each in its own field. Country is a searchable picker (stores the ISO country code, shows the localized name). | No |
| Notes | Additional context or remarks | No |
[!NOTE] Phone numbers are automatically normalized — invisible Unicode characters and full-width plus signs (+) are stripped to ensure consistent dialing and display.
[!NOTE] Structured address. The address is split into separate fields (street / house number / postal code / city / state / country). If a contact was saved earlier with a one-line address, the fields are pre-filled from it the first time you open the editor and flagged for a quick review — your original stays untouched until you save. The same split applies to your own account address in Settings → Account, which also feeds the sender block on invoices, quotes, and e-invoices (PEPPOL/ZUGFeRD).
- Click Save
Separating People & Companies
The directory keeps people and companies clearly apart:
- A segmented control above the list switches between All, People, and Companies (each shows a live count). The department filter chips (Camera, Grip, …) apply to People and hide in the Companies view.
- Assigning people to a company works both ways. On a person, set the Company field to record where they work — their detail then shows a “Works at →” link that jumps straight to the company. On a company, the People section lists everyone linked to it; add someone with the Add a person picker or remove them with the ✕. The two views always stay in sync.
On a phone
Below the tablet breakpoint the contact-type switch (All / People / Companies) and the department pills fold into a single Filters button carrying the number of filters you have set. Search, Select all and the result counter stay on screen. Tap Filters to choose a contact type and a department, then Show N contacts to apply. Departments are a People sub-filter and disappear under Companies. From 768 px up the toolbar is unchanged.
Departments & Roles
Contacts can be organized by department to reflect the production hierarchy. As of v0.204.1 there are eight first-class departments, each with a curated role list. The same registry drives the workspace crew editor, the call-sheet quick-add, the contact filter chips, and the PDF exports — so a role you select in one surface is grouped the same way everywhere.
| Department | Typical Roles |
|---|---|
| Camera | DoP, Camera Operator, B-Camera Operator, Steadicam Operator, Drone Operator, Phantom Tech, DIT, 1st AC, 2nd AC, Camera Trainee, Script Supervisor |
| Grip | Key Grip, Best Boy Grip, Dolly Grip, Rigging Grip, Crane Operator, Grip, Grip Trainee |
| Light | Key Gaffer, Gaffer, Best Boy Electric, Rigging Gaffer, Electrician, Lighting Programmer, Genny Operator |
| Sound | Sound Mixer, Boom Operator, Sound Assistant, Playback Operator |
| Production | Director, Assistant Director, 2nd AD, Producer, Executive Producer, Line Producer, Production Manager, Production Coordinator, Location Manager, Casting |
| Art | Production Designer, Art Director, Set Decorator, Props Master, Set Dresser, Construction Coordinator |
| HMU & Costume | Costume Designer, Costume Supervisor, Wardrobe, Hair & Makeup Artist, Hair Stylist, Makeup Artist |
| Post Production | Post Production Supervisor, Editor, Assistant Editor, Colorist, VFX Supervisor, VFX Artist, Sound Designer, Foley Artist, Composer |
[!NOTE] Legacy role names still work. Saved roles like "Director of Photography" or "Make-up Artist" continue to filter and group correctly — they're resolved to the closest canonical role on display. You don't need to re-type old contacts.
Multi-Role Support
Crew members can have multiple roles assigned within a project:
- One role is designated as the default role (displayed prominently)
- Additional roles are tracked for flexible crew scheduling
- Multi-role assignments sync to Supabase and appear across Contact Editor, Project Crew list, and exported PDFs
Using Contacts in Projects
Assigning Crew
In a project workspace, navigate to the General tab to assign crew members:
- Click a crew role slot (e.g., "Director of Photography")
- Search and select from your contacts
- The contact's name, phone, and email appear on the project
Promoting a Crew Member to a Contact
When a crew member on a project isn't linked to any contact in your directory, an "Add as contact" button appears next to their row. This creates a new contact pre-filled with their name and (if a role was entered) the right department, then links the crew row to the freshly-created contact in one step. The button stays disabled until you've entered a name — you'll see a hint explaining why.
This is the fast path for adding the runner / driver / freelancer you just typed in for one shoot to your permanent contacts directory.
Provider Association
Contacts can also serve as rental house or vendor contacts:
- Go to the Billing tab in a project
- Assign a contact as the representative for a provider
- Their details auto-populate in quotes and export documents
Profile Pictures
Each contact can have a profile picture:
- Click the avatar area on a contact card
- Upload an image (JPG, PNG, or HEIC)
- Crop the image using the built-in cropper
- The picture appears on contact cards and crew lists
Editing & Deleting
- Edit: Click a contact card to open the editor panel
- Delete: Click the delete icon — a confirmation dialog prevents accidental removal
Merging Duplicates
Contacts can pile up as duplicates — most often your own profile contact or connected-crew members synced from several devices.
- Automatic cleanup: When you open the app after updating, exact duplicates are consolidated automatically — your profile contact (kept as one), contacts linked to the same connected user, and contacts with the same email address. The kept contact inherits the others' details, and every reference (project crew, production company, provider assignments, owned gear, sub-rentals) points to it afterward. Nothing is deleted — merges can be undone.
- Merge all duplicates: On the Contacts page, a bar appears when several duplicate groups remain (including near-duplicates such as the same name and phone). One click merges them all, behind a confirmation, with an Undo button.
- Merge one at a time: The "Potential duplicate detected" banner still proposes merging a single likely pair for review.
Why duplicates used to come back after merging (fixed in v0.485.1)
Merging was never the problem — new copies were being created after the merge, and a new copy has an identity no earlier merge covers:
- On a new device, a new browser, or after a reset, your own contact card and one card per connected collaborator were filled in before the contact list had finished downloading. An empty list read as "this account has none", so a fresh card was written on every such start. Those writers now wait for the download to settle.
- Editing crew on a project matched an existing contact only on a character-for-character identical email or name — a different capitalisation, a stray space, an address folded in by an earlier merge, or typing the name before the email all created a second contact. Matching is now case- and whitespace-insensitive, also checks alternative addresses and alternative names, and a crew member pointing at a merged-away contact is re-linked to the surviving one.
- Background updates uploaded only a few fields of a contact. Contacts are stored encrypted, so the server replaces the whole record instead of merging single fields — every other field, including the "merged away" marker, was erased in the cloud, which is what revived old duplicates. Those updates now send the complete contact.
A one-time cleanup runs on the next start and folds the pile that accumulated in the meantime (same rules as automatic cleanup above: profile card, same connected user, identical email — undoable, nothing deleted).
Cloud Sync
When Cloud Sync is enabled, contacts sync automatically across your devices. Changes made offline are queued and synchronized when connectivity is restored.
Tips
- Use departments: Organize contacts by department for faster lookups on large productions
- Add company info: Helps differentiate contacts with similar names
- Link to projects early: Assign crew in the General tab so exported PDFs include contact details
- Profile pictures: Adding photos makes it easier to identify contacts on shared projects
Related Documentation
Merging notes (v0.334.1): your own profile contact can never be merged into another contact (that would orphan your identity sync) — merge the duplicate into your profile instead. Deleting a contact warns when it is still referenced as a project's production contact, crew member, gear provider, or sub-rental renter. vCard imports handle folded (multi-line) values from Apple/Google exports.
Last Updated: 2026-09-10 Version: 0.790.2
