Task Templates & Groups (Developer)
This doc describes the implemented Task Templates and Task Template Groups system: data model, endpoints, ordering, and tenant scoping.
Mental Modelβ
TaskTemplate: Reusable definition for a single task.TaskTemplateGroup: Ordered list of templates (group-defined ordering). Templates can belong to multiple groups.Task: The actual task instance attached to a Job or Leg.
Data Modelβ
TaskTemplateβ
Key fields:
name(required): internal keytitle(required): display titledescriptionscope:system | companyparentCompany: null for system templatesappType:trucking | serviceRepair | allindustry:trucking | service_repair | generalappliesTo:job | leg | bothcategory,order- requirement flags:
required,requiresPhoto,requiresSignature,requiresNote autoApply(template-level)active
TaskTemplateGroupβ
Key fields:
groupKey(unique per scope+tenant usage)scope:system | companyparentCompany(required for company-scoped groups)- targeting:
appType,industry,appliesTo active- ordered members:
templates: [{ templateId, order }] - auto-apply:
autoApply,autoApplyMode,triggerRules
Ordering Rulesβ
- Group ordering is defined by
TaskTemplateGroup.templates[].order. - When a group is applied, each created
Task.orderuses:member.order ?? template.order ?? 0
API Endpoints (v1)β
Templatesβ
POST /api/v1/tasks/templatesGET /api/v1/tasks/templatesPUT /api/v1/tasks/templates/:templateIdDELETE /api/v1/tasks/templates/:templateId
Groupsβ
GET /api/v1/tasks/template-groupsPOST /api/v1/tasks/template-groupsPUT /api/v1/tasks/template-groups/:groupIdDELETE /api/v1/tasks/template-groups/:groupId
Apply Groupβ
POST /api/v1/tasks/job/:jobId/apply-groupPOST /api/v1/tasks/leg/:legId/apply-group
Body:
{
"groupKey": "pickup_checklist",
"appType": "trucking",
"mode": "dedupe"
}
Modes:
dedupe: skip templates already applied to that job/leg (bytemplateId)override: delete existing tasks for those templates on that job/leg then recreate
Tenant Isolation / Scope Resolutionβ
When applying a group, the API prefers:
- Company-scoped group:
{ scope: "company", parentCompany } - Otherwise fallback to system-scoped group:
{ scope: "system", parentCompany: null }
Backwards Compatibility Notesβ
- Some older template data may not have
title; group-apply usestemplate.title || template.nameas a safe fallback when creatingTask.title.