Skip to main content
Back to ScopeForged

ScopeForged Documentation

Technical documentation, guides, and feature references for the ScopeForged client portal.

Admin & Compliance/Admin Tools

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

  1. Accessing Admin Tools
  2. Admin Tools Dashboard
  3. Bulk Operations
  4. Undo System
  5. Toast Notifications
  6. Admin Search
  7. Saved Filters
  8. Admin Audit Trail
  9. System Maintenance
  10. Technical Architecture
  11. Testing
  12. Related Features

Accessing Admin Tools

Access PointLocationURLRole
Admin Tools DashboardAdmin sidebar/admin/toolsAdmin
Bulk OperationsAdmin sidebar/admin/bulk-operationsAdmin
Admin SearchHeader search bar/admin/admin-searchAdmin
Audit TrailAdmin sidebar/admin/audit-trailAdmin
Saved FiltersFilter dropdown/admin/saved-filtersAdmin
System HealthTools menu/admin/system/healthAdmin
Cache ManagementTools menu/admin/system/cacheAdmin

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

ComponentDescription
Stats GridActive admins, actions today, pending approvals
Undoable ActionsRecent actions that can be undone
Recent ActivityLatest 20 activity log entries
System HealthDatabase, cache, storage, queue status
Quick ActionsLinks 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

ModelSupported Actions
UsersActivate, Deactivate, Delete, Export
ClientsActivate, Deactivate, Delete, Export
ProjectsArchive, Restore, Update Status, Delete, Export
InvoicesUpdate 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

MethodEndpointDescription
GET/admin/bulk-operations/modelsList supported models
GET/admin/bulk-operations/{model}/actionsGet actions for model
POST/admin/bulk-operations/executeExecute bulk action
POST/admin/bulk-operations/undoUndo a bulk action
GET/admin/bulk-operations/undoableGet 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

  1. Undoable actions generate an undo_token with 5-minute TTL
  2. Original data is captured before changes
  3. Use the token to reverse the action

Undoable Actions

ActionUndo Behavior
DeleteRestores soft-deleted records
ArchiveReverts to original status
Update StatusRestores previous status
Activate/DeactivateToggles 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

TypeColorUse Case
successGreenSuccessful operations
errorRedFailed operations
warningYellowWarnings, cautions
infoBlueInformational 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

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
}

Optimized for autocomplete, returns limited results per model.

GET /admin/admin-search/quick?q=searchterm
GET /admin/admin-search/clients?q=acme&limit=50

Search Configuration

ModelSearchable Fields
Usersname, email
Clientsname, email, phone
Projectsname, description
Invoicesinvoice_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

OperatorSQL EquivalentDescription
equals=Exact match
not_equals!=Not equal
containsLIKE %...%Contains substring
starts_withLIKE ...%Starts with
ends_withLIKE %...Ends with
greater_than>Greater than
less_than<Less than
greater_or_equal>=Greater or equal
less_or_equal<=Less or equal
inIN (...)In list
not_inNOT INNot in list
is_nullIS NULLIs null
is_not_nullIS NOT NULLIs not null
betweenBETWEENBetween 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

MethodEndpointDescription
GET/admin/saved-filters?model=clientsList filters for model
POST/admin/saved-filtersCreate new filter
GET/admin/saved-filters/{model}/fieldsGet available fields
PUT/admin/saved-filters/{id}Update filter
DELETE/admin/saved-filters/{id}Delete filter
POST/admin/saved-filters/{id}/set-defaultSet as default

Admin Audit Trail

Overview

All admin actions are logged with full context for compliance and troubleshooting.

Logged Information

FieldDescription
user_idAdmin who performed action
actionAction type (create, update, delete, etc.)
model_typeAffected model class
model_idAffected record ID
changesBefore/after values for updates
ip_addressAdmin's IP address
user_agentBrowser information
metadataAdditional 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

MethodEndpointDescription
GET/admin/audit-trailView audit log index
GET/admin/audit-trail/logsGet logs as JSON
GET/admin/audit-trail/summaryActivity summary
GET/admin/audit-trail/filter-optionsAvailable filters
GET/admin/audit-trail/{type}/{id}Logs for specific model
GET/admin/audit-trail/exportExport logs
POST/admin/audit-trail/cleanupClean 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

ToolPurpose
Clear CacheClear all caches
Clear View CacheClear compiled views
Clear Route CacheClear route cache
Clear Config CacheClear config cache
Warm CachePre-populate caches

Queue Management

ActionDescription
View pending jobsSee queued items
Retry failed jobsRe-process failures
Clear failed jobsRemove failed jobs
Pause queueStop processing
Resume queueStart processing

Log Management

ActionDescription
View logsBrowse log files
Download logsExport log files
Clear old logsRemove old entries
Search logsFind 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

ControllerLocationPurpose
AdminToolsControllerAdmin/Dashboard and stats
BulkOperationsControllerAdmin/Bulk action execution
AdminSearchControllerAdmin/Global search
AdminAuditControllerAdmin/Audit trail
SavedAdminFilterControllerAdmin/Saved filters

Services

ServicePurpose
BulkActionServiceExecute bulk operations
UndoServiceHandle undo operations
AdminSearchServiceCross-model search
AdminAuditServiceAudit logging

Models

ModelPurpose
AdminAuditLogAudit trail entries
SavedAdminFilterSaved filter configs
BulkActionLogBulk 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

  1. Always backup before destructive operations
  2. Use dry run for imports first
  3. Check filters before bulk operations
  4. Verify row counts before proceeding
  5. Keep undo tokens available for 5 minutes

For Performance

  1. Run bulk ops off-peak hours
  2. Use queued jobs for large operations
  3. Batch large imports into chunks
  4. Clear caches after major changes

Troubleshooting

IssueSolution
Undo token expiredExecute operation again if needed
Bulk action times outUse smaller batches
Search returns no resultsCheck search field configuration
Filter not applyingVerify field and operator compatibility

FeatureRelationship
AuthorizationAdmin role required
Background JobsAsync operations
Activity LoggingLogs tool usage
ReportsData export
AnalyticsSystem metrics
Audit & ComplianceAudit tools