Activity Tracker
Time tracking and billing system for interior design projects.
This document describes the Activity Tracker - a time tracking and billing system designed for interior design firms.
Overview
The Activity Tracker helps design firms:
- Track designer time via Google Calendar integration
- Bill clients accurately with automatic project association
- Manage project teams with role-based access
- Group households (e.g., spouses) under shared projects
- Generate invoices from tracked activities
How Designers Use It
┌─────────────────────────────────────────────────────────────────────────┐ │ TYPICAL WORKFLOW │ │ │ │ 1. Designer creates a calendar event │ │ "Meeting with Smith about kitchen renovation" │ │ │ │ 2. Opens the Google Calendar addon │ │ - Detects "Smith" from the event title │ │ - Shows matching projects for Smith clients │ │ │ │ 3. Designer selects the project │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ● Smith Kitchen Remodel │ │ │ │ ○ Smith Guest House │ │ │ │ ○ Smith - General (catch-all) │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 4. Activity is saved with duration, rate, and description │ │ │ └─────────────────────────────────────────────────────────────────────────┘
Key Concepts
Organizations
Each design firm is an "organization" in the system. All their data (clients, projects, activities) is private and separate from other firms.
Clients & Households
Individual Clients are people like "Anna Lyon" or "Chris Lyon" with their own contact info.
Households group related people together:
- "Anna & Chris Lyon" household
- Both can view shared projects
- One billing address for the household
Client Types track business relationships:
| Type | Description |
|---|---|
| Client | Standard design client |
| Partner | Business partners, referral sources |
| Reseller | Trade/wholesale customers |
Projects
Projects are the work being done:
- "Lyon Kitchen Remodel"
- "Lyon Master Bathroom"
Each project has:
- A client or household association
- A team of designers with roles
- Activities (time entries) logged against it
General Projects are automatic catch-alls:
- Created for each client
- Hold activities that aren't assigned to a specific project
- Can be reassigned later
Project Team Roles
| Role | What They Can Do |
|---|---|
| Owner | Lead designer - full control |
| Admin | Manage project settings and team |
| Member | View and contribute (log time) |
| Viewer | Read-only access |
| Client | Client access to view progress |
Activities
Activities are time entries:
- Designer who did the work
- Start/end time with timezone (TIMESTAMPTZ for proper DST handling)
- Activity date (auto-generated from start time in America/Chicago timezone)
- Duration in minutes
- Hourly rate (captured at time of entry)
- Billable or non-billable
- Description of work performed
Activities Page (WebApp)
The Activities page provides a comprehensive view of all tracked time entries for the organization.
Header Toolbar
The toolbar at the top provides quick access to:
- Filter Toggle - Opens/closes the filter sidebar with a badge showing active filter count
- Date Range Picker - Select date ranges with presets (Today, Past 7 Days, This Month, etc.)
Filter Sidebar
A collapsible sidebar on the left side of the page containing checkbox filters:
| Filter | Description |
|---|---|
| Clients | Filter by one or more clients |
| Projects | Filter by projects (cascades from client selection) |
| Designers | Filter by team members who performed the work |
| Activity Types | Filter by activity type (meetings, design time, etc.) |
| Billable | Show only billable or non-billable activities |
| Invoiced Status | Filter by billed/unbilled status |
Each filter group supports:
- Internal search (for groups with many options)
- "Show all" expansion (defaults to showing first 10 items)
- Individual clear buttons per group
- "Clear" button in header to reset all filters
Activities Table
The main data table displays:
| Column | Description | Editable |
|---|---|---|
| Date | Activity date | No |
| Client | Client name (from project) | Yes (change client) |
| Project | Project name | Yes (reassign) |
| Type | Activity type with color indicator | Yes |
| Billable | Billable status toggle | Yes |
| Description | Work description | Yes |
| Designer | Team member who performed work | No |
| Duration | Time in hours | Yes |
| Rate | Hourly rate | Yes |
| Total | Calculated amount (duration × rate) | No |
| Statement | Invoice/statement reference | No |
Table Features
- Column Visibility - Show/hide columns via View settings
- Column Reordering - Drag and drop to reorder columns
- Pagination - Configurable rows per page (25, 50, 100, 200, 500)
- Row Selection - Select multiple activities for bulk actions
- Inline Editing - Edit many fields directly in the table
- Optimistic Updates - Changes appear immediately while saving
Inline Editing
Most fields can be edited directly in the table:
- Click on a field to edit
- Changes save automatically
- Calendar events update when description/duration/type changes
Bulk Actions
When rows are selected:
- Generate Statement - Create PDF invoices from selected unbilled activities
- Bulk Update Status - Change billing status for multiple activities at once
Saved Views
Save your filter configurations as named views for quick access later.
Creating a Saved View
- Set up your filters (clients, dates, designers, etc.)
- Click "Save View" in the toolbar
- Enter a name for the view
- Click Save
Using Saved Views
- Load - Select a saved view from the dropdown to restore its filters
- Set Default - Mark a view as default to load it automatically
- Rename - Change the view name
- Delete - Remove views you no longer need
Saved views are personal to each user and persist across sessions.
Project Rates
Designer hourly rates can be locked in per project, allowing different rates for different engagements.
Rate Priority
When calculating activity costs, the system checks rates in this order:
- Client Special Rate - If the client has special pricing enabled
- Project-Specific Rate - Locked in when designer is added to project
- Designer Default Rate - From team member settings
How Project Rates Work
When a project is created:
- All designers with hourly rates > $0 are automatically added as project members
- Their current rate is locked in for that project
- Rate changes in team settings don't affect existing project assignments
Managing Project Rates
From the project detail page (Rates tab):
- View rates - See each designer's project-specific rate
- Edit rates - Click to change a designer's rate for this project
- Add designers - Add team members not yet on the project
- Remove designers - Remove a designer from the project
Example
Emilie's default rate is $150/hour. When she joins the "Smith Kitchen" project, her rate is locked at $150. If her default rate later increases to $175, the Smith Kitchen project still uses $150 - but any new projects she joins will use $175.
Billing Workflow
1. Review Activities
Admins see all activities in a table view:
- Filter by client, project, date range
- Filter to show only unbilled activities
- See totals and billing status
2. Reassign Stray Activities
Activities in "General" projects can be moved:
- Click on Project cell to reassign to a specific project
- Click on Client cell to move to a different client's General project
3. Generate Statements
Select activities and generate billing:
- Grouped by project automatically
- PDF statements created
- Uploaded to Google Drive
4. Track Invoices
After billing:
- Activities marked as "billed"
- Invoice number and link attached
- Won't appear in "unbilled" reports
Reports & Insights
| Report | What It Shows |
|---|---|
| Activity Summary | Total hours and revenue by date range |
| By Designer | Hours and revenue per team member |
| By Project | Hours and revenue per project |
| By Client | All activities across client's projects |
| Unbilled Activities | Work not yet invoiced |
| General Project Activities | Unassigned work needing review |
Google Integration
Calendar
- Activities created from calendar events
- Event color matches activity type
- Changes sync back to calendar (description, duration, type)
Drive
- Statements uploaded to organized folders
- Structure:
/Year/Month/ClientName_Statement_Number.pdf - Shareable links stored automatically
Configuration
Activity Types
Each organization configures their own types:
- "Design Time - Billable"
- "Meeting"
- "Travel Time"
- "Administrative"
Each type has:
- Name and color
- Default billable setting
- Display order
Designer Rates
Each designer has a current hourly rate stored in organization_designers:
- Used as default when designer is added to a project
- Rate is locked in per designer/project in
organization_project_members.hourly_rate - Different designers on the same project can have different rates
- When rates change (e.g., Jan 1 increase), existing project assignments keep their original rate
- Example: Emilie's rate goes from $130 to $150 on Jan 1:
- Lyon Kitchen project (joined in December): stays at $130
- New Smith Bathroom project (joined in January): gets $150
Invoice Numbering
The system tracks invoice numbers per organization:
- Separate counters for production and testing environments
- Atomic increment to prevent duplicates
- Auto-initializes when first invoice is created
Access Control
| Who | What They Can Do |
|---|---|
| Team Members | View/create activities for their org |
| Designers | See their own activities and assigned projects |
| Project Admins | Manage their project's team |
| Org Admins | Full access to all org data |
| Clients | View their project progress (read-only) |
Technical Implementation
Database
Activities are stored in organization_activities with:
- Full timezone support (TIMESTAMPTZ)
- Automatic activity_date generation in America/Chicago timezone
- RLS policies for organization-level access control
- Optimized queries via Postgres functions
URL-Based Filters
All filters are persisted in the URL:
- Shareable filtered views
- Browser back/forward navigation works
- Page refresh preserves filters
Performance
- Server-side pagination with configurable page sizes
- React Query for client-side caching and background updates
- Optimistic UI updates for instant feedback
- Skeleton loading states during initial load
Current Status
| Feature | Status |
|---|---|
| Activities List View | Complete |
| Filter Sidebar | Complete |
| Inline Editing | Complete |
| Calendar Sync (read/write) | Complete |
| Statement Generation | Complete |
| Statements Dashboard | Complete |
| Group By Client View | Complete |
| Saved Views | Complete |
| Project Rates | Complete |
| Time Insights Dashboard | Complete |
Related Documentation
- Time Insights - Dashboard for analyzing time tracking data
- Programs Overview - Information about program-based feature access
