Tasks — Technical Reference
This page covers the data models, completion lifecycle, and daily digest architecture behind the Tasks feature.
Data Models
tasks
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key |
workspace_id | uuid | FK → workspaces.id — tenant isolation (ON DELETE CASCADE) |
title | text | Required. Short description of the action item |
description | text | Optional detailed notes (defaults to empty string) |
due_date | timestamptz | When the task is due. Drives the dashboard widget and daily digest |
status | text | 'open' or 'completed' (CHECK constraint) |
contact_id | uuid | FK → contacts.id (ON DELETE SET NULL) — optional contact link |
deal_id | uuid | FK → deals.id (ON DELETE SET NULL) — optional deal link |
assigned_to | uuid | FK → user_profiles.id — assigned workspace member |
completed_at | timestamptz | Timestamp when marked as completed (NULL if open) |
reminder_sent_at | timestamptz | Used by the daily digest to prevent duplicate notifications |
created_by | uuid | FK → user_profiles.id — who created the task |
created_at | timestamptz | When the task was created |
updated_at | timestamptz | When the task was last modified |
Soft links: Contact and deal FKs use
ON DELETE SET NULL— if the linked contact or deal is deleted, the task survives as a general to-do item.
Architecture
Completion Lifecycle
| Action | Field Changes |
|---|---|
| Complete | status → 'completed', completed_at → current timestamp |
| Reopen | status → 'open', completed_at → NULL, reminder_sent_at → NULL |
Clearing reminder_sent_at on reopen ensures the task re-enters the daily digest cycle.
Task List Sorting
| View | Sort Order |
|---|---|
| Open tasks | due_date ASC (overdue first, soonest due next, no due date last). Secondary: created_at DESC |
| Completed tasks | completed_at DESC (most recently completed first) |
Cascading Contact / Deal Pickers
The task creation form implements intelligent cascading between the contact and deal dropdowns:
- Selecting a deal → auto-fills
contact_idwith the deal's linked contact - Selecting a contact → filters the deal dropdown to only show that contact's deals
- Changing the contact → clears any incompatible
deal_idselection
When creating from a Contact Detail page, contact_id is pre-filled.
When creating from a Deal Detail page, both deal_id and contact_id are pre-filled.
Deep Linking
Tasks support URL-based deep linking: /tasks?taskId=<id> automatically opens the task
detail view. This is used by Global Search to jump directly to a task from search results.
Completed Today Section
The "Completed Today" section displays tasks completed within the current day. Tasks are rendered with strikethrough text and reduced opacity. The section respects the active assignee filter — filtering to "My Tasks" shows only your completed tasks.
Present on four surfaces: /tasks page, dashboard widget, Contact Detail, Deal Detail.
Daily Digest Architecture
Cron Configuration
| Property | Value |
|---|---|
| Schedule | Daily at 8:00 AM US Central (1:00 PM UTC) |
| Cron expression | 0 13 * * * |
| Endpoint | /api/cron/task-digest |
| Authentication | Authorization: Bearer {CRON_SECRET} |
| Email type | Transactional (system notification) |
| Sender | PLATFORM_SENDER_EMAIL |
{
"path": "/api/cron/task-digest",
"schedule": "0 13 * * *"
}Digest Pipeline
- Authenticate — Verify
CRON_SECRETbearer token - Fetch eligible tasks — Query:
status = 'open',assigned_to IS NOT NULL,due_date ≤ end of today,reminder_sent_atis NULL or before today - Filter already-reminded — Exclude tasks where
reminder_sent_atmatches today - Group by user — Each user receives one email regardless of task count
- Build digest — Resolve user email via
auth.admin.getUserById(), classify tasks into "Due Today" and "Overdue", build HTML email - Send and stamp — Send via Resend, stamp
reminder_sent_aton all included tasks
Deduplication Logic
The reminder_sent_at field prevents duplicate emails within the same day. Overdue tasks
re-appear in the next day's digest because their reminder_sent_at will be yesterday's
date. Reopened tasks have reminder_sent_at cleared, so they immediately re-enter the
digest cycle.
Email Template
| Section | Style |
|---|---|
| Header | Green gradient (#059669 → #10b981), "Gordon CRM — Task Digest" |
| Greeting | Personalized: "Good morning, {first_name}!" |
| Overdue | Red heading (⚠️), red border, task title + contact/deal + original due date |
| Due Today | Standard heading (📋), task title + contact/deal |
| CTA | Green button → /tasks |
| Footer | "This is an automated notification from Gordon CRM." |
Related Cron Jobs
| Cron Job | Schedule | Purpose |
|---|---|---|
| Campaign Sweeper | Every 5 minutes | Process due campaign enrollments |
| Broadcast Sweeper | Every 5 minutes | Process scheduled broadcasts |
| Birthday Sweeper | Daily at 8:00 AM UTC | Fire birthday automation triggers |
| Task Digest | Daily at 1:00 PM UTC | Send daily task summary emails |
Automation Integration
The create_task automation action creates a task pre-linked to the triggering contact
with configurable fields:
title— Task title (supports template variables)description— Optional descriptionassigned_to— Workspace member to assigndue_date_offset— Number of days from trigger to set the due date
See Automations → Actions for the full specification.
Security
RLS Policies
| Operation | Policy |
|---|---|
| SELECT | All workspace members can view tasks |
| INSERT | All workspace members can create tasks |
| UPDATE | All workspace members can edit tasks |
| DELETE | Admin or Owner only |