Skip to content

Tasks — Developer Guide

Mirror of the Leads developer guide. Prefer copying Leads patterns over inventing new ones.

Backend layout

PiecePath
Modelsapp/Models/Task.php, TaskNote, TaskActivity
Enumsapp/Enums/Tenant/TaskStatusEnum (includes waiting; Open label To Do), TaskPriorityEnum, TaskActivityTypeEnum
Serviceapp/Services/Tenant/TaskService.php (+ ScopesToAssignee)
Controllerapp/Http/Controllers/Tenant/Api/V1/TaskController.php
Requestsapp/Http/Requests/Tenant/Api/V1/Task/*
Resourcesapp/Http/Resources/Tenant/Api/V1/Task/*
Policyapp/Policies/TaskPolicy.php (changeDueDatetasks.change_due_date)
Eventsapp/Events/Task*.php
Subscriberapp/Listeners/TaskEventSubscriber.php (audit + notifications)
Notificationsapp/Notifications/Tenant/Task/* — assign/complete/reopen: mail+database; due/overdue: database; daily digest: mail only (TaskDueDigestNotification)
Digest deliverytask_digest_deliveries + TaskDigestDeliveryService; TrackTaskDueDigestDelivery on NotificationSent / NotificationFailed
Scheduled duecrm:send-due-notifications every 5 minutes (onOneServer); tenant setting task_reminder_time (Daily Reminder Time)
Teststests/Feature/Tenant/Task/TaskTest.php, tests/Feature/Tenant/Notification/TaskDueDigestNotificationTest.php

Domain notes

  • Assignee scoping via ScopesToAssignee with tasks.assign.
  • Updating due_at after create requires tasks.change_due_date (enforced in TaskService / policy). Initial due_at on create is allowed without that permission.
  • Board columns are one per TaskStatusEnum case.

Permissions

config/tenant-permissions.php:

tasks.view | create | update | delete | assign | complete | change_due_date

Routes use module:tasks then can:tasks.* / policies.

API (tenant)

Base: /api/tenant/v1 — full reference tenant-v1-tasks.md.

MethodPathPermission
GET/tasksview
GET/tasks/statsview
GET/tasks/boardview
POST/taskscreate
GET/tasks/{task}view
PUT/tasks/{task}update (+ change_due_date when changing due_at)
DELETE/tasks/{task}delete
POST/tasks/{task}/assignassign
POST/tasks/{task}/completecomplete
POST/tasks/{task}/reopencomplete
POST/tasks/{task}/notesupdate
GET/tasks/{task}/timelineview

Auth login/me include modules: string[] for SPA gating.

Frontend

PiecePath
Pagesrc/pages/tasks/tasks-page.tsx (board default + list)
Formtask-form-dialog.tsx
Detailtask-detail-sheet.tsx (Comments + History; DnD status pending until Save)
Shared boardsrc/components/crm/kanban-board.tsx
ServicetaskService in src/api/services.ts
Navpermission: tasks.view, module: 'tasks'

Tests

bash
# Backend
php artisan test --compact tests/Feature/Tenant/Task/TaskTest.php

# Frontend E2E
npm run test:e2e:tasks

Logging

  • Spatie LogsActivity on Task (log name tasks)
  • Domain task_activities timeline
  • PlatformAuditService via TaskEventSubscriber

Intentional differences from Leads

LeadsTasks
Stages + independent statusStatus + priority enums (no stages)
Follow-upsNone
Assignment history tableTimeline only
export / convertcomplete / change_due_date
Board by stageBoard by status

Official documentation for the SaleOS SaaS Platform.