Features
Activity & notifications
Externa records domain and auth events with Spatie Activitylog, exposes an Activity Log admin page (and an AI query tool), and delivers file job outcomes through database notifications in the sidebar bell.
Related
Dashboard widgets that read activity: Dashboard. File jobs that emit notifications: File manager. Realtime bell / presence: Reverb & Echo. AI logging helpers: AI assistant model.
Spatie Activitylog
| Item | Detail |
|---|---|
| Package model | Spatie\Activitylog\Models\Activity |
| Config | config/activitylog.php |
| Env toggle | ACTIVITYLOG_ENABLED |
| Retention | clean_after_days = 365 |
| Default log name | default |
| Cleanup | Schedule::command('activitylog:clean')->daily() |
LogsApplicationActivity
Trait: App\Concerns\LogsApplicationActivity (wraps Spatie LogsActivity).
Options: logAll(), logOnlyDirty(), dontLogEmptyChanges(), useLogName('default').
Used on: User, UserGroup, Collection, CollectionField, CollectionItem, File, FileVersion, FileUpload.
Item editors surface a compact activity strip (last update + revisions/activity links). Field-level history remains in Item History, not Spatie attribute diffs.
Auth login / logout / failed
Registered in AppServiceProvider::registerAuthActivityListeners():
| Event | Log name | Activity event | Description / notes |
|---|---|---|---|
Illuminate\Auth\Events\Login | auth | login | User logged in; also updates last_login_at / last_login_ip |
Logout | auth | logout | User logged out |
Failed | auth | failed | Failed login attempt; causedByAnonymous(), property identifier |
AI activity
App\Ai\Support\AiActivityLogger writes log_name=ai with events ai_prompt, ai_response, ai_tool, ai_mutation.
Activity Log UI
| Item | Detail |
|---|---|
| Controller | App\Http\Controllers\Admin\ActivityLogController |
| Route | GET /activity-logs (activity-logs.index) |
| Middleware | auth, verified, permission:can-show-activity-logs |
| Permission | can-show-activity-logs |
| Page | resources/js/pages/admin/activity-logs/index.tsx |
Filters: search, user_id, event, log_name, date_from, date_to, optional subject_type + subject_id (used by the item form Activity link).
Filterable events:
created | updated | deleted | restored
login | logout | failed
ai_prompt | ai_response | ai_tool | ai_mutation
AI QueryActivityLogs
| Item | Detail |
|---|---|
| Tool | App\Ai\Tools\QueryActivityLogs |
| Gate | can-show-activity-logs |
| Limits | Default 25, max 50 |
| Dates | YYYY-MM-DD only |
| Events | Same set as the UI filters |
Registered on AppAssistant when the user has can-show-activity-logs.
Notifications (file jobs)
All use trait BroadcastsWithDatabase: via(['database']), plus broadcast when BROADCAST_CONNECTION is not log/null.
| Class | data.type | Emitted from |
|---|---|---|
App\Notifications\FileZipReadyNotification | file_zip_ready | PrepareFilesZipJob |
App\Notifications\FileZipFailedNotification | file_zip_failed | PrepareFilesZipJob |
App\Notifications\FileDuplicationCompletedNotification | file_duplication_completed | DuplicateFilesJob |
App\Notifications\FileDuplicationFailedNotification | file_duplication_failed | DuplicateFilesJob |
Zip-ready notifications point at download route files.zips.download.
Realtime delivery (Echo private channel App.Models.User.{id}) is documented in Reverb & Echo. When BROADCAST_CONNECTION is log/null, the sidebar bell keeps its 60s unread poll; with Reverb enabled there is no periodic poll — Echo .notification() updates the badge.
Bell API
| Item | Detail |
|---|---|
| Controller | App\Http\Controllers\NotificationController |
| Routes | routes/web.php |
| Middleware | auth + verified only — no activity-log permission |
| UI | NotificationsBell + NotificationsDrawer in the sidebar |
| Client | resources/js/lib/notifications-api.ts |
| Method | Path | Name | Behavior | | --- | --- | --- | | GET | /notifications | notifications.index | Paginate 20 | | GET | /notifications/unread-count | notifications.unread-count | Unread count | | POST | /notifications/read | notifications.read | Mark read |
There is no dedicated notification permission in PermissionEnum; any authenticated verified user can use the bell API for their own notifications.
Permissions summary
| Surface | Permission |
|---|---|
Activity Log page + QueryActivityLogs | can-show-activity-logs |
| Notifications bell / API | Authenticated + verified (no enum gate) |
Source map
| Concern | Location |
|---|---|
| Activity controller | app/Http/Controllers/Admin/ActivityLogController.php |
| Logging trait | app/Concerns/LogsApplicationActivity.php |
| Auth listeners | AppServiceProvider::registerAuthActivityListeners |
| AI query tool | app/Ai/Tools/QueryActivityLogs.php |
| Notifications | app/Notifications/FileZip*Notification.php, FileDuplication*Notification.php |
| Bell API | app/Http/Controllers/NotificationController.php |