generated from theradcoza/Laravel-Docker-Dev-Template
287 lines
5.8 KiB
Markdown
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
|