101 lines
2.7 KiB
Markdown
101 lines
2.7 KiB
Markdown
|
|
# Activity Log
|
||
|
|
|
||
|
|
All domain write operations are logged through `ActivityLogService`, which wraps [Spatie Laravel Activity Log](https://spatie.be/docs/laravel-activitylog).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Channel
|
||
|
|
|
||
|
|
All events are written to the `lunar` log channel. Query them with:
|
||
|
|
|
||
|
|
```php
|
||
|
|
use Spatie\Activitylog\Models\Activity;
|
||
|
|
|
||
|
|
Activity::on($subject)->get();
|
||
|
|
Activity::causedBy($staff)->get();
|
||
|
|
Activity::inLog('lunar')->get();
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
Inject `ActivityLogService` and call the relevant method after each operation:
|
||
|
|
|
||
|
|
```php
|
||
|
|
use App\Services\Logging\ActivityLogService;
|
||
|
|
|
||
|
|
public function __construct(private ActivityLogService $activityLog) {}
|
||
|
|
|
||
|
|
// Creation
|
||
|
|
$this->activityLog->created($model, ['name' => $name, 'type' => $type]);
|
||
|
|
|
||
|
|
// Update — pass old state and new state separately
|
||
|
|
$this->activityLog->updated($model, ['name' => $old], ['name' => $new]);
|
||
|
|
|
||
|
|
// Deletion
|
||
|
|
$this->activityLog->deleted($model, ['name' => $model->name, 'reason' => $reason]);
|
||
|
|
```
|
||
|
|
|
||
|
|
The actor is always resolved from `auth('staff')->user()` at call time — do not pass it explicitly.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Properties Shape
|
||
|
|
|
||
|
|
| Method | `properties` key | Contents |
|
||
|
|
|---|---|---|
|
||
|
|
| `created` | `attributes` | New state snapshot |
|
||
|
|
| `updated` | `old` + `attributes` | Previous state and new state |
|
||
|
|
| `deleted` | `attributes` | Context at time of deletion (name, reason, etc.) |
|
||
|
|
| `failed` | `attributes` | Context at time of failure (service, error message, etc.) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## What Gets Logged
|
||
|
|
|
||
|
|
### Appointments
|
||
|
|
|
||
|
|
| Action | Method | Key properties |
|
||
|
|
|---|---|---|
|
||
|
|
| Book | `created` | `staff_id`, `date`, `start_time`, `end_time`, `customer` |
|
||
|
|
| Cancel | `deleted` | `date`, `reason` |
|
||
|
|
| Reassign | `updated` | old `staff` id → new `staff` id |
|
||
|
|
| Reschedule | `updated` | old `date`/`start_time`/`end_time` → new values |
|
||
|
|
|
||
|
|
### Customers
|
||
|
|
|
||
|
|
| Action | Method | Key properties |
|
||
|
|
|---|---|---|
|
||
|
|
| Elorus sync success | `updated` | `elorus_id`, `elorus_synced_at` |
|
||
|
|
| Elorus sync failure | `failed` | `service: elorus`, `error` |
|
||
|
|
|
||
|
|
### Availability
|
||
|
|
|
||
|
|
| Action | Method | Key properties |
|
||
|
|
|---|---|---|
|
||
|
|
| Create schedule | `created` | `name`, `frequency`, `type` |
|
||
|
|
| Create one-day schedule | `created` | `name`, `type`, `date` |
|
||
|
|
| Update schedule | `updated` | old name/frequency/type → new values |
|
||
|
|
| Delete schedule | `deleted` | `name` |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Adding New Events
|
||
|
|
|
||
|
|
Follow the existing pattern — log immediately after the operation succeeds, before returning:
|
||
|
|
|
||
|
|
```php
|
||
|
|
$record = $this->doSomething();
|
||
|
|
$this->activityLog->created($record, ['relevant' => 'context']);
|
||
|
|
return $record;
|
||
|
|
```
|
||
|
|
|
||
|
|
For updates, capture the old state **before** mutating:
|
||
|
|
|
||
|
|
```php
|
||
|
|
$old = ['name' => $record->name];
|
||
|
|
$record->update(['name' => $newName]);
|
||
|
|
$this->activityLog->updated($record, $old, ['name' => $newName]);
|
||
|
|
```
|