Admin Tools & Utilities Guide
Last Updated: 2026-01-17 Status: Implemented Plan Reference: 027-admin-tools-utilities.md, 055-admin-tools-enhancement.md
Overview
Admin Tools & Utilities provides system administrators with powerful tools for managing the portal, performing bulk operations, system maintenance, and troubleshooting. These tools help maintain system health and streamline administrative tasks.
Key Features:
- Dashboard showing activity, system health, and pending actions
- Bulk operations with undo capability
- Admin action audit trail
- Advanced search across all models
- Saved filter configurations
- Toast notifications for operation feedback
- System maintenance tools
Table of Contents
- Accessing Admin Tools
- Admin Tools Dashboard
- Bulk Operations
- Undo System
- Toast Notifications
- Admin Search
- Saved Filters
- Admin Audit Trail
- System Maintenance
- Technical Architecture
- Testing
- Related Features
Accessing Admin Tools
Navigation
| Access Point | Location | URL | Role |
|---|---|---|---|
| Admin Tools Dashboard | Admin sidebar | /admin/tools | Admin |
| Bulk Operations | Admin sidebar | /admin/bulk-operations | Admin |
| Admin Search | Header search bar | /admin/admin-search | Admin |
| Audit Trail | Admin sidebar | /admin/audit-trail | Admin |
| Saved Filters | Filter dropdown | /admin/saved-filters | Admin |
| System Health | Tools menu | /admin/system/health | Admin |
| Cache Management | Tools menu | /admin/system/cache | Admin |
Permissions
Only users with Admin role can access admin tools. Super admin may be required for some destructive operations.
Admin Tools Dashboard
Accessing the Dashboard
Navigate to Admin > More > Admin Tools or visit /admin/tools.
Dashboard Components
| Component | Description |
|---|---|
| Stats Grid | Active admins, actions today, pending approvals |
| Undoable Actions | Recent actions that can be undone |
| Recent Activity | Latest 20 activity log entries |
| System Health | Database, cache, storage, queue status |
| Quick Actions | Links to cache, activity, audit, system info |
Routes
// Admin Tools routes
Route::prefix('tools')->name('tools.')->group(function () {
Route::get('/', [AdminToolsController::class, 'index'])->name('index');
Route::get('stats', [AdminToolsController::class, 'stats'])->name('stats');
});
Bulk Operations
Available Models
| Model | Supported Actions |
|---|---|
| Users | Activate, Deactivate, Delete, Export |
| Clients | Activate, Deactivate, Delete, Export |
| Projects | Archive, Restore, Update Status, Delete, Export |
| Invoices | Update Status, Send, Mark Paid, Delete, Export |
Bulk Actions Reference
For Users:
{
"activate": { "label": "Activate", "undoable": true },
"deactivate": { "label": "Deactivate", "undoable": true },
"delete": { "label": "Delete", "undoable": true },
"export": { "label": "Export", "undoable": false }
}
For Projects:
{
"archive": { "label": "Archive", "undoable": true },
"restore": { "label": "Restore", "undoable": false },
"update_status": { "label": "Change Status", "undoable": true },
"delete": { "label": "Delete", "undoable": true }
}
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/bulk-operations/models | List supported models |
| GET | /admin/bulk-operations/{model}/actions | Get actions for model |
| POST | /admin/bulk-operations/execute | Execute bulk action |
| POST | /admin/bulk-operations/undo | Undo a bulk action |
| GET | /admin/bulk-operations/undoable | Get undoable actions |
Execute Bulk Action
POST /admin/bulk-operations/execute
Content-Type: application/json
{
"model": "clients",
"action": "delete",
"ids": [1, 2, 3],
"params": {}
}
Response:
{
"success": true,
"processed": 3,
"failed": 0,
"message": "Delete completed for 3 item(s)",
"undo_token": "uuid-here",
"undo_expires_at": "2026-01-10T10:05:00Z"
}
Service Usage
use App\Services\Admin\BulkActionService;
$bulkService = app(BulkActionService::class);
// Get supported models
$models = $bulkService->getSupportedModels();
// Get actions for model
$actions = $bulkService->getActionsForModel('clients');
// Execute action
$result = $bulkService->execute(
model: 'clients',
action: 'deactivate',
ids: [1, 2, 3],
params: []
);
// Result contains:
// - success: bool
// - processed: int
// - failed: int
// - message: string
// - undoToken: ?string
// - undoExpiresAt: ?string
Undo System
How It Works
- Undoable actions generate an
undo_tokenwith 5-minute TTL - Original data is captured before changes
- Use the token to reverse the action
Undoable Actions
| Action | Undo Behavior |
|---|---|
| Delete | Restores soft-deleted records |
| Archive | Reverts to original status |
| Update Status | Restores previous status |
| Activate/Deactivate | Toggles is_active flag |
Undo API
POST /admin/bulk-operations/undo
Content-Type: application/json
{
"token": "uuid-undo-token"
}
Response:
{
"success": true,
"message": "Restored 3 item(s)",
"restored": 3,
"failed": 0
}
Viewing Undoable Actions
GET /admin/bulk-operations/undoable
Response:
{
"undoable": [
{
"id": 1,
"undo_token": "uuid",
"action": "delete",
"model": "clients",
"processed_count": 3,
"undo_expires_at": "2026-01-10T10:05:00Z",
"created_at": "2026-01-10T10:00:00Z"
}
]
}
Service Usage
use App\Services\Admin\UndoService;
$undoService = app(UndoService::class);
// Undo by token
$result = $undoService->undo($token);
// Get undoable actions for current user
$actions = $undoService->getUndoableActions();
Toast Notifications
Component Location
resources/views/components/toast-notifications.blade.php
Usage in JavaScript
// Show success toast
window.dispatchEvent(new CustomEvent('toast', {
detail: {
message: 'Operation completed',
type: 'success'
}
}));
// Show error toast
window.dispatchEvent(new CustomEvent('toast', {
detail: {
message: 'Operation failed',
type: 'error'
}
}));
// Show undoable toast
window.dispatchEvent(new CustomEvent('toast', {
detail: {
message: '3 items deleted',
type: 'success',
undoable: true,
undoToken: 'uuid-token'
}
}));
// Toast with details
window.dispatchEvent(new CustomEvent('toast', {
detail: {
message: 'Export started',
details: 'You will be notified when complete',
type: 'info',
persistent: true // Doesn't auto-dismiss
}
}));
Toast Types
| Type | Color | Use Case |
|---|---|---|
| success | Green | Successful operations |
| error | Red | Failed operations |
| warning | Yellow | Warnings, cautions |
| info | Blue | Informational messages |
Features
- Auto-dismiss with progress bar (5 seconds default)
- Undo button for undoable actions
- Manual dismiss with X button
- Stack multiple toasts
- Dark mode support
Admin Search
Global Search
Search across all models (users, clients, projects, invoices) from a single query.
GET /admin/admin-search?q=searchterm&limit=20
Response:
{
"query": "searchterm",
"results": {
"users": {
"label": "Users",
"icon": "user",
"items": [
{
"id": 1,
"label": "John Smith",
"subtitle": "john@example.com",
"url": "/admin/users/1",
"metadata": { "role": "admin" }
}
],
"total": 5
},
"clients": { ... },
"projects": { ... },
"invoices": { ... }
},
"total": 15
}
Quick Search
Optimized for autocomplete, returns limited results per model.
GET /admin/admin-search/quick?q=searchterm
Model-Specific Search
GET /admin/admin-search/clients?q=acme&limit=50
Search Configuration
| Model | Searchable Fields |
|---|---|
| Users | name, email |
| Clients | name, email, phone |
| Projects | name, description |
| Invoices | invoice_number, notes |
Saved Filters
Overview
Save and reuse filter configurations for any supported model.
Create Saved Filter
POST /admin/saved-filters
Content-Type: application/json
{
"name": "High Value Projects",
"model": "projects",
"filters": [
{
"field": "status",
"operator": "equals",
"value": "active"
}
],
"is_default": false,
"is_shared": true
}
Available Operators
| Operator | SQL Equivalent | Description |
|---|---|---|
equals | = | Exact match |
not_equals | != | Not equal |
contains | LIKE %...% | Contains substring |
starts_with | LIKE ...% | Starts with |
ends_with | LIKE %... | Ends with |
greater_than | > | Greater than |
less_than | < | Less than |
greater_or_equal | >= | Greater or equal |
less_or_equal | <= | Less or equal |
in | IN (...) | In list |
not_in | NOT IN | Not in list |
is_null | IS NULL | Is null |
is_not_null | IS NOT NULL | Is not null |
between | BETWEEN | Between two values |
Available Fields by Model
Users:
- name (text)
- email (text)
- role (select: admin, client)
- created_at (date)
- email_verified_at (boolean)
Clients:
- name (text)
- email (text)
- phone (text)
- status (select: active, inactive)
- created_at (date)
Projects:
- name (text)
- status (select: draft, active, completed, archived)
- client_id (relation)
- start_date (date)
- end_date (date)
Invoices:
- invoice_number (text)
- status (select: draft, sent, paid, overdue)
- client_id (relation)
- total (number)
- issued_at (date)
- due_date (date)
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/saved-filters?model=clients | List filters for model |
| POST | /admin/saved-filters | Create new filter |
| GET | /admin/saved-filters/{model}/fields | Get available fields |
| PUT | /admin/saved-filters/{id} | Update filter |
| DELETE | /admin/saved-filters/{id} | Delete filter |
| POST | /admin/saved-filters/{id}/set-default | Set as default |
Admin Audit Trail
Overview
All admin actions are logged with full context for compliance and troubleshooting.
Logged Information
| Field | Description |
|---|---|
| user_id | Admin who performed action |
| action | Action type (create, update, delete, etc.) |
| model_type | Affected model class |
| model_id | Affected record ID |
| changes | Before/after values for updates |
| ip_address | Admin's IP address |
| user_agent | Browser information |
| metadata | Additional context |
Action Types
const ACTION_TYPES = [
'create' => 'Created',
'update' => 'Updated',
'delete' => 'Deleted',
'restore' => 'Restored',
'archive' => 'Archived',
'bulk_action' => 'Bulk Action',
'export' => 'Exported',
'import' => 'Imported',
'login' => 'Logged In',
'logout' => 'Logged Out',
'settings_change' => 'Changed Settings',
'permission_change' => 'Changed Permissions',
];
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /admin/audit-trail | View audit log index |
| GET | /admin/audit-trail/logs | Get logs as JSON |
| GET | /admin/audit-trail/summary | Activity summary |
| GET | /admin/audit-trail/filter-options | Available filters |
| GET | /admin/audit-trail/{type}/{id} | Logs for specific model |
| GET | /admin/audit-trail/export | Export logs |
| POST | /admin/audit-trail/cleanup | Clean old logs |
Query Audit Logs
GET /admin/audit-trail/logs?user_id=1&action=delete&date_from=2026-01-01&date_to=2026-01-10
Activity Summary
GET /admin/audit-trail/summary?date_from=2026-01-01&date_to=2026-01-10
Response:
{
"date_range": {
"from": "2026-01-01",
"to": "2026-01-10"
},
"summary": {
"total_actions": 150,
"unique_users": 5,
"by_action": {
"create": 50,
"update": 80,
"delete": 20
},
"by_model": {
"User": 30,
"Client": 60,
"Project": 40,
"Invoice": 20
},
"by_day": {
"2026-01-05": 25,
"2026-01-06": 30
}
}
}
Log Cleanup
Clean up logs older than specified days (minimum 30, maximum 365).
POST /admin/audit-trail/cleanup
Content-Type: application/json
{
"days_to_keep": 90
}
System Maintenance
Cache Management
| Tool | Purpose |
|---|---|
| Clear Cache | Clear all caches |
| Clear View Cache | Clear compiled views |
| Clear Route Cache | Clear route cache |
| Clear Config Cache | Clear config cache |
| Warm Cache | Pre-populate caches |
Queue Management
| Action | Description |
|---|---|
| View pending jobs | See queued items |
| Retry failed jobs | Re-process failures |
| Clear failed jobs | Remove failed jobs |
| Pause queue | Stop processing |
| Resume queue | Start processing |
Log Management
| Action | Description |
|---|---|
| View logs | Browse log files |
| Download logs | Export log files |
| Clear old logs | Remove old entries |
| Search logs | Find specific entries |
Technical Architecture
Database Tables
admin_audit_logs:
id BIGINT PRIMARY KEY
user_id BIGINT REFERENCES users(id)
action VARCHAR(255)
model_type VARCHAR(255) NULLABLE
model_id BIGINT NULLABLE
changes JSON NULLABLE
ip_address VARCHAR(45) NULLABLE
user_agent TEXT NULLABLE
metadata JSON NULLABLE
created_at TIMESTAMP
updated_at TIMESTAMP
INDEX (model_type, model_id)
INDEX (action)
INDEX (created_at)
saved_admin_filters:
id BIGINT PRIMARY KEY
user_id BIGINT REFERENCES users(id)
name VARCHAR(255)
model VARCHAR(255)
filters JSON
is_default BOOLEAN DEFAULT FALSE
is_shared BOOLEAN DEFAULT FALSE
created_at TIMESTAMP
updated_at TIMESTAMP
INDEX (user_id, model)
bulk_action_logs:
id BIGINT PRIMARY KEY
user_id BIGINT REFERENCES users(id)
model VARCHAR(255)
action VARCHAR(255)
affected_ids JSON
original_data JSON NULLABLE
status VARCHAR(50)
undo_token UUID UNIQUE NULLABLE
undo_expires_at TIMESTAMP NULLABLE
processed_count INTEGER DEFAULT 0
failed_count INTEGER DEFAULT 0
error_details JSON NULLABLE
created_at TIMESTAMP
updated_at TIMESTAMP
INDEX (undo_token)
INDEX (user_id, created_at)
Controllers
| Controller | Location | Purpose |
|---|---|---|
AdminToolsController | Admin/ | Dashboard and stats |
BulkOperationsController | Admin/ | Bulk action execution |
AdminSearchController | Admin/ | Global search |
AdminAuditController | Admin/ | Audit trail |
SavedAdminFilterController | Admin/ | Saved filters |
Services
| Service | Purpose |
|---|---|
BulkActionService | Execute bulk operations |
UndoService | Handle undo operations |
AdminSearchService | Cross-model search |
AdminAuditService | Audit logging |
Models
| Model | Purpose |
|---|---|
AdminAuditLog | Audit trail entries |
SavedAdminFilter | Saved filter configs |
BulkActionLog | Bulk action tracking |
Testing
Running Tests
# Run admin tools tests
php artisan test tests/Feature/AdminToolsTest.php
# Run all admin-related tests
php artisan test --filter=Admin
Test Coverage
- Dashboard access control
- Stats API endpoint
- Recent activity display
- System health checks
- Undoable actions display
- Active admin counting
- Actions today counting
- Bulk operation execution
- Undo functionality
- Saved filter CRUD
Security Considerations
Dangerous Operations
Operations requiring extra confirmation:
- Delete all records
- Truncate tables
- Clear all data
- Restore from backup
Audit Trail
All admin tool usage is logged:
- Who performed action
- What was affected
- When it happened
- Result status
- IP address and browser
Undo Token Security
- Tokens are UUID format
- 5-minute expiration
- User verification required
- Token becomes invalid after use
Best Practices
For Safety
- Always backup before destructive operations
- Use dry run for imports first
- Check filters before bulk operations
- Verify row counts before proceeding
- Keep undo tokens available for 5 minutes
For Performance
- Run bulk ops off-peak hours
- Use queued jobs for large operations
- Batch large imports into chunks
- Clear caches after major changes
Troubleshooting
| Issue | Solution |
|---|---|
| Undo token expired | Execute operation again if needed |
| Bulk action times out | Use smaller batches |
| Search returns no results | Check search field configuration |
| Filter not applying | Verify field and operator compatibility |
Related Features
| Feature | Relationship |
|---|---|
| Authorization | Admin role required |
| Background Jobs | Async operations |
| Activity Logging | Logs tool usage |
| Reports | Data export |
| Analytics | System metrics |
| Audit & Compliance | Audit tools |