Activities — Developer Guide
Mirror of the Companies developer guide / Contacts developer guide. Prefer copying those patterns over inventing new ones.
Backend layout
| Piece | Path |
|---|---|
| Models | app/Models/Activity.php, ActivityNote, ActivityActivity |
| Enums | ActivityTypeEnum, ActivityActivityTypeEnum |
| Service | app/Services/Tenant/ActivityService.php (+ ScopesToAssignee) |
| Controller | app/Http/Controllers/Tenant/Api/V1/ActivityController.php |
| Requests | app/Http/Requests/Tenant/Api/V1/Activity/* |
| Resources | app/Http/Resources/Tenant/Api/V1/Activity/* |
| Policy | app/Policies/ActivityPolicy.php |
| Events | app/Events/Activity*.php |
| Subscriber | app/Listeners/ActivityEventSubscriber.php (audit + assignment notification) |
| Notifications | app/Notifications/Tenant/Activity/ActivityAssignedNotification.php |
| Link rules | LinkableContact, LinkableLead, LinkableCompanyForActivity, EligibleActivityAssignee |
| Tests | tests/Feature/Tenant/Activity/ActivityTest.php |
App\Models\Activity is the CRM engagement record. It is distinct from Spatie activity_log and from per-module timeline models (ContactActivity, LeadActivity, etc.).
Domain notes
- Assignee scoping via
ScopesToAssigneewithactivities.assign. activities.force.deleteis not granted to any default role — owner/superadmin only.- At least one of
contact_id/company_id/lead_idis required; each FK is validated for module entitlement + assignee scope on the related record. - On create/complete (and when related FKs change on update), mirrors
crm_activity_logged/crm_activity_completedonto related Contact/Company/Lead timelines when those modules are entitled. - Soft delete; completion via
POST .../complete(can:activities.complete). Completion is not writable through generic update.
Permissions
activities.view | create | update | delete | restore | force.delete | assign | completeStaff defaults include activities.view + activities.complete (same pattern as Tasks).
Routes use module:activities then can:activities.* / policies.
API (tenant)
Base: /api/tenant/v1 — full reference tenant-v1-activities.md.
Frontend
| Piece | Path |
|---|---|
| Page | src/pages/activities/activities-page.tsx |
| Form | activity-form-dialog.tsx |
| Detail | activity-detail-sheet.tsx |
| Service | activityService in src/api/services.ts |
| Nav | permission: activities.view, module: 'activities' (after Meetings) |
| Dashboard | RecentCrmActivitiesWidget (recent_activities) + create_activity quick action |
Tests
bash
php artisan test --compact tests/Feature/Tenant/Activity/ActivityTest.php
npm run typecheck && npm run lint && npm run build
npm run test:e2e:activitiesLogging
- Spatie
LogsActivityonActivity(log nameactivities) - Domain
activity_activitiestimeline PlatformAuditServiceviaActivityEventSubscriber