Skip to main content
Back to ScopeForged

ScopeForged Documentation

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

Core Business Features/Client Management

Client Management Guide

Last Updated: 2026-01-12 Status: Implemented Plan Reference: 005-client-management.md, 070-client-management-improvement.md


Overview

The Client Management system allows administrators to create, manage, and organize client organizations. Each client represents a company or individual that uses the portal. Clients can have multiple users (contacts), projects, and invoices associated with them.


Table of Contents

  1. Accessing Client Management
  2. Features
  3. How to Use
  4. Client Users
  5. Technical Architecture
  6. Related Features

Accessing Client Management

Access PointLocationURLRole
Client ListAdmin sidebar/admin/clientsAdmin
Create ClientClient list page/admin/clients/createAdmin
View ClientClient row/admin/clients/{id}Admin
Edit ClientClient detail page/admin/clients/{id}/editAdmin

Note: Client users access their organization data through the portal dashboard and project views, not a dedicated clients page.

Permissions

ActionAdminClient User
View all clients
View own client
Create client
Edit client
Delete client
Manage client users

Features

Client Profile

  • Company name and contact information
  • Address details (street, city, state, ZIP, country)
  • Phone number and email
  • Website URL
  • Active/inactive status
  • Notes field for internal information

Client Users

  • Multiple users per client
  • User-client association via pivot table
  • Client users access portal with scoped permissions

Client Status

  • Active: Full access to portal
  • Inactive: No portal access

Client Statistics

  • Total projects count
  • Active projects count
  • Total invoices
  • Outstanding invoice amount
  • Total paid amount

How to Use

Creating a New Client

  1. Navigate to Admin → Clients
  2. Click "Create Client" button
  3. Fill in the required fields:
    • Company Name (required)
    • Email (required)
  4. Fill in optional fields:
    • Contact name
    • Phone number
    • Address details
    • Website
    • Notes
  5. Set status to Active or Inactive
  6. Click "Create Client"

Viewing Client Details

  1. Navigate to Admin → Clients
  2. Click on a client name or "View" button
  3. View client information including:
    • Contact details
    • Associated projects
    • Invoice history
    • Client users
    • Activity log

Editing a Client

  1. Navigate to Admin → Clients → [Client]
  2. Click "Edit" button
  3. Modify desired fields
  4. Click "Update Client"

Deleting a Client

  1. Navigate to Admin → Clients → [Client]
  2. Click "Delete" button
  3. Confirm deletion in modal

Warning: Deleting a client may affect associated projects and invoices.


Advanced Features

Bulk Operations

Perform actions on multiple clients simultaneously.

  1. Navigate to Admin → Clients
  2. Select clients using checkboxes
  3. Choose bulk action:
    • Archive: Mark selected clients as inactive
    • Activate: Mark selected clients as active
    • Delete: Remove selected clients
// Using ClientBulkController
use App\Http\Controllers\Admin\ClientBulkController;

// Routes
Route::post('clients-bulk/archive', [ClientBulkController::class, 'archive']);
Route::post('clients-bulk/activate', [ClientBulkController::class, 'activate']);
Route::post('clients-bulk/delete', [ClientBulkController::class, 'delete']);

Export Clients

Export client data in multiple formats.

  1. Navigate to Admin → Clients
  2. Click "Export" dropdown
  3. Select format:
    • CSV: Spreadsheet-compatible format
    • JSON: Developer-friendly format
// Using ClientExportService
use App\Services\ClientExportService;

$service = new ClientExportService();

// Export all clients to CSV
$csvContent = $service->toCsv(Client::all());

// Export to JSON
$jsonContent = $service->toJson(Client::all());

// Get import template
$template = $service->getImportTemplate();

Import Clients

Import clients from CSV files.

  1. Navigate to Admin → Clients
  2. Click "Import" button
  3. Download template (optional)
  4. Upload CSV file with client data
  5. Review import results

Required CSV columns: name, email

Optional columns: phone, address, status

// Using ClientImportService
use App\Services\ClientImportService;

$service = new ClientImportService();

// Validate CSV before import
$errors = $service->validateCsv($fileContents);

// Import clients
$results = $service->fromCsv($fileContents, $importedBy);
// Returns ['success' => [...], 'errors' => [...]]

Merge Clients

Combine two clients into one, transferring all relationships.

  1. Navigate to Admin → Clients → [Source Client]
  2. Click "Merge" button
  3. Select target client
  4. Review merge preview:
    • Users to transfer
    • Projects to transfer
    • Invoices to transfer
    • Conversations to transfer
  5. Confirm merge

Note: The source client is deleted after merge.

// Using ClientMergeService
use App\Services\ClientMergeService;

$service = new ClientMergeService();

// Preview merge
$preview = $service->preview($sourceClient, $targetClient);

// Execute merge
$targetClient = $service->merge($sourceClient, $targetClient);

Configuration

Client management settings in config/client-management.php:

return [
    'bulk' => [
        'enabled' => true,
        'max_clients' => 100,
        'operations' => [
            'archive' => true,
            'activate' => true,
            'delete' => true,
        ],
    ],
    'import' => [
        'enabled' => true,
        'max_rows' => 1000,
        'required_columns' => ['name', 'email'],
        'default_status' => 'active',
    ],
    'export' => [
        'enabled' => true,
        'formats' => ['csv', 'json'],
    ],
    'merge' => [
        'enabled' => true,
        'transfer_users' => true,
        'transfer_projects' => true,
        'transfer_invoices' => true,
        'transfer_conversations' => true,
    ],
];

Managing Client Users

  1. Navigate to Admin → Clients → [Client]
  2. Scroll to "Client Users" section
  3. Click "Add User" to associate existing user
  4. Or click "Create User" to create new client user
  5. To remove: Click "Remove" next to user

Client Users

User-Client Association

Users can be associated with one or more clients. This is managed through the client_user pivot table.

Adding a User to a Client

// In controller or service
$client->users()->attach($user->id);

// With pivot data
$client->users()->attach($user->id, ['role' => 'primary']);

Checking User Access

// Check if user belongs to client
$user->belongsToClient($client);

// Get all clients for a user
$user->clients;

// Get all users for a client
$client->users;

Technical Architecture

Model

Location: app/Models/Client.php

class Client extends Model
{
    protected $fillable = [
        'company_name',
        'contact_name',
        'email',
        'phone',
        'address',
        'city',
        'state',
        'zip',
        'country',
        'website',
        'notes',
        'is_active',
    ];

    protected $casts = [
        'is_active' => 'boolean',
    ];
}

Relationships

// Client model
public function users(): BelongsToMany
{
    return $this->belongsToMany(User::class);
}

public function projects(): HasMany
{
    return $this->hasMany(Project::class);
}

public function invoices(): HasMany
{
    return $this->hasMany(Invoice::class);
}

Controller

Location: app/Http/Controllers/Admin/ClientController.php

MethodRouteDescription
index()GET /admin/clientsList all clients
create()GET /admin/clients/createShow create form
store()POST /admin/clientsCreate client
show()GET /admin/clients/{client}View client
edit()GET /admin/clients/{client}/editShow edit form
update()PUT /admin/clients/{client}Update client
destroy()DELETE /admin/clients/{client}Delete client

Routes

// Admin routes (routes/web.php)
Route::prefix('admin')->middleware(['auth', 'admin'])->group(function () {
    Route::resource('clients', Admin\ClientController::class);
});

// Portal routes
Route::prefix('portal')->middleware(['auth'])->group(function () {
    Route::get('clients', [Portal\ClientController::class, 'index'])->name('portal.clients.index');
    Route::get('clients/{client}', [Portal\ClientController::class, 'show'])->name('portal.clients.show');
});

Database Schema

Table: clients

ColumnTypeDescription
idbigintPrimary key
company_namestringCompany/organization name
contact_namestringPrimary contact name
emailstringContact email
phonestringPhone number
addressstringStreet address
citystringCity
statestringState/province
zipstringZIP/postal code
countrystringCountry
websitestringWebsite URL
notestextInternal notes
is_activebooleanActive status
created_attimestampCreation date
updated_attimestampLast update

Pivot Table: client_user

ColumnTypeDescription
client_idbigintForeign key to clients
user_idbigintForeign key to users
created_attimestampAssociation date

Views

ViewPathPurpose
Indexresources/views/admin/clients/index.blade.phpClient list
Createresources/views/admin/clients/create.blade.phpCreate form
Showresources/views/admin/clients/show.blade.phpClient details
Editresources/views/admin/clients/edit.blade.phpEdit form
Portal Indexresources/views/portal/clients/index.blade.phpClient's view

Form Validation

Location: app/Http/Requests/ClientRequest.php

public function rules(): array
{
    return [
        'company_name' => 'required|string|max:255',
        'contact_name' => 'nullable|string|max:255',
        'email' => 'required|email|max:255',
        'phone' => 'nullable|string|max:50',
        'address' => 'nullable|string|max:255',
        'city' => 'nullable|string|max:100',
        'state' => 'nullable|string|max:100',
        'zip' => 'nullable|string|max:20',
        'country' => 'nullable|string|max:100',
        'website' => 'nullable|url|max:255',
        'notes' => 'nullable|string',
        'is_active' => 'boolean',
    ];
}

Scopes and Query Helpers

Available Scopes

// Only active clients
Client::active()->get();

// Only inactive clients
Client::inactive()->get();

// Search by name or email
Client::search('acme')->get();

// With project count
Client::withCount('projects')->get();

Dependencies

FeatureRelationship
AuthorizationClientPolicy controls access
AuthenticationUser login required

Complementary Features

FeatureDescription
Project ManagementProjects belong to clients
InvoicingInvoices belong to clients
Activity LoggingLogs client changes
File SharingFiles scoped to client projects

Best Practices

For Administrators

  1. Use descriptive company names for easy identification
  2. Keep contact information updated for notifications
  3. Use notes field for internal context
  4. Deactivate rather than delete clients with history
  5. Assign primary contact as first client user

For Developers

  1. Always use policies for authorization
  2. Eager load relationships to avoid N+1 queries
  3. Use scopes for common query patterns
  4. Validate input using Form Request classes

Troubleshooting

IssueSolution
Client not appearingCheck is_active status
User can't see clientVerify user-client association
Can't delete clientCheck for associated projects/invoices
Validation errorsReview required fields

See Also