Files
bhoza-shift-manager/docs/audit-trail.md
2026-03-09 09:18:21 +00:00

287 lines
5.8 KiB
Markdown

# Audit Trail
This template includes a comprehensive audit trail system using [owen-it/laravel-auditing](https://github.com/owen-it/laravel-auditing) with Filament UI integration.
## What Gets Tracked
For every audited model:
- **Who** - User who made the change
- **What** - Model and record ID
- **When** - Timestamp
- **Changes** - Old values → New values
- **Where** - IP address, user agent
- **Module** - Which module the change belongs to
## Quick Start
Audit trail is set up during `make setup-laravel`. To add auditing to a model:
```php
use App\Traits\ModuleAuditable;
use OwenIt\Auditing\Contracts\Auditable;
class Product extends Model implements Auditable
{
use ModuleAuditable;
// Your model code...
}
```
That's it! All create, update, and delete operations are now logged.
## Viewing Audit Logs
Each module has an **Audit Log** page in its admin section:
```
📦 Stock Management
├── Dashboard
├── Products
└── Audit Log ← Click here
```
The audit log shows:
- Date/Time
- User
- Event type (created/updated/deleted)
- Model
- Old → New values
Click any entry to see full details including IP address and all changed fields.
## Configuration
### Per-Module Configuration
Each module has audit settings in its config file:
```php
// Config/stock_management.php
'audit' => [
'enabled' => true, // Enable/disable for entire module
'strategy' => 'all', // 'all', 'include', 'exclude', 'none'
'exclude' => [ // Fields to never audit
'password',
'remember_token',
],
],
```
### Strategies
| Strategy | Description |
|----------|-------------|
| `all` | Audit all fields (default) |
| `include` | Only audit fields in `$auditInclude` |
| `exclude` | Audit all except fields in `$auditExclude` |
| `none` | Disable auditing |
### Per-Model Configuration
Override in your model:
```php
class Product extends Model implements Auditable
{
use ModuleAuditable;
// Only audit these fields
protected $auditInclude = [
'name',
'price',
'quantity',
];
// Or exclude specific fields
protected $auditExclude = [
'internal_notes',
'cache_data',
];
}
```
## Audit Events
By default, these events are tracked:
- `created` - New record created
- `updated` - Record modified
- `deleted` - Record deleted
### Custom Events
Log custom events:
```php
// In your model or service
$product->auditEvent = 'approved';
$product->isCustomEvent = true;
$product->auditCustomOld = ['status' => 'pending'];
$product->auditCustomNew = ['status' => 'approved'];
$product->save();
```
## Querying Audits
### Get audits for a record
```php
$product = Product::find(1);
$audits = $product->audits;
// With user info
$audits = $product->audits()->with('user')->get();
```
### Get audits by user
```php
use OwenIt\Auditing\Models\Audit;
$userAudits = Audit::where('user_id', $userId)->get();
```
### Get audits by module
```php
$moduleAudits = Audit::where('tags', 'like', '%module:StockManagement%')->get();
```
### Get recent changes
```php
$recentChanges = Audit::latest()->take(50)->get();
```
## UI Customization
### Modify Audit Log Table
Edit `Filament/Resources/AuditLogResource.php` in your module:
```php
public static function table(Table $table): Table
{
return $table
->columns([
// Add or modify columns
Tables\Columns\TextColumn::make('custom_field'),
])
->filters([
// Add custom filters
Tables\Filters\Filter::make('today')
->query(fn ($query) => $query->whereDate('created_at', today())),
]);
}
```
### Add Audit Tab to Resource
Add audit history tab to any Filament resource:
```php
use Tapp\FilamentAuditing\RelationManagers\AuditsRelationManager;
class ProductResource extends Resource
{
public static function getRelations(): array
{
return [
AuditsRelationManager::class,
];
}
}
```
## Data Retention
### Pruning Old Audits
Add to `app/Console/Kernel.php`:
```php
protected function schedule(Schedule $schedule)
{
// Delete audits older than 90 days
$schedule->command('audit:prune --days=90')->daily();
}
```
Or run manually:
```bash
php artisan audit:prune --days=90
```
### Archive Before Delete
```php
// Export to CSV before pruning
Audit::where('created_at', '<', now()->subDays(90))
->each(function ($audit) {
// Write to archive file
Storage::append('audits/archive.csv', $audit->toJson());
});
```
## Disabling Auditing
### Temporarily
```php
// Disable for a single operation
$product->disableAuditing();
$product->update(['price' => 99.99]);
$product->enableAuditing();
// Or use without auditing
Product::withoutAuditing(function () {
Product::where('category', 'sale')->update(['on_sale' => true]);
});
```
### For Specific Model
```php
class CacheModel extends Model implements Auditable
{
use ModuleAuditable;
// Disable auditing for this model
public $auditEvents = [];
}
```
### For Entire Module
```php
// Config/module_name.php
'audit' => [
'enabled' => false,
],
```
## Troubleshooting
### Audits not being created
1. Model implements `Auditable` interface
2. Model uses `ModuleAuditable` trait
3. Check module config `audit.enabled` is true
4. Run `php artisan config:clear`
### User not being recorded
1. Ensure user is authenticated when changes are made
2. Check `config/audit.php` for user resolver settings
### Performance concerns
1. Use `$auditInclude` to limit tracked fields
2. Set up audit pruning for old records
3. Consider async audit processing for high-volume apps
## Security
- Audit records are **read-only** in the admin panel
- No create/edit/delete actions available
- Access controlled by module permissions
- Sensitive fields (password, tokens) excluded by default