libra/docs/stories/story-2.1-individual-client...

8.1 KiB

Story 2.1: Individual Client Account Management

Epic Reference

Epic 2: User Management System

User Story

As an admin, I want to create, view, edit, and search individual client accounts, So that I can manage client information and provide them platform access.

Story Context

Existing System Integration

  • Integrates with: Users table, Fortify authentication
  • Technology: Livewire Volt, Flux UI forms
  • Follows pattern: Admin CRUD patterns, class-based Volt components
  • Touch points: User model, admin dashboard
  • PRD Reference: Section 5.3 (User Management System), Section 16.1 (Database Schema)

Prerequisites from Epic 1

  • Users table with fields: name, email, password, user_type, national_id, phone, preferred_language, status
  • AdminLog model and admin_logs table for audit logging
  • Bilingual infrastructure (lang files, __() helper)

Acceptance Criteria

Create Individual Client

  • Form with required fields:
    • Full Name (required)
    • National ID Number (required, unique)
    • Email Address (required, unique)
    • Phone Number (required)
    • Password (admin-set, required)
    • Preferred Language (Arabic/English dropdown)
  • Validation for all required fields
  • Duplicate email/National ID prevention with clear error message
  • Password strength indicator (optional)
  • Success message on creation

List View

  • Display all individual clients (user_type = 'individual')
  • Columns: Name, Email, National ID, Phone, Status, Created Date
  • Pagination (10/25/50 per page)
  • Default sort by created date (newest first)

Search & Filter

  • Search by name, email, or National ID
  • Filter by status (active/deactivated/all)
  • Real-time search with debounce (300ms)
  • Clear filters button

Edit Client

  • Edit all client information
  • Cannot change user_type from this form
  • Validation same as create
  • Success message on update

View Client Profile

  • Display all client information
  • Show consultation history summary
  • Show timeline history summary
  • Quick links to related records

Quality Requirements

  • Bilingual form labels and messages
  • Proper form validation with error display
  • Audit log entries for all operations
  • Tests for CRUD operations

Technical Notes

Files to Create

resources/views/livewire/admin/clients/individual/
├── index.blade.php      # List view with search/filter/pagination
├── create.blade.php     # Create form
├── edit.blade.php       # Edit form
└── show.blade.php       # View profile page

User Model Scope

// In User model
public function scopeIndividual($query)
{
    return $query->where('user_type', 'individual');
}

Volt Component Structure

<?php

use App\Models\User;
use Livewire\Volt\Component;
use Livewire\WithPagination;

new class extends Component {
    use WithPagination;

    public string $search = '';
    public string $statusFilter = '';

    public function updatedSearch()
    {
        $this->resetPage();
    }

    public function with(): array
    {
        return [
            'clients' => User::individual()
                ->when($this->search, fn($q) => $q->where(function($q) {
                    $q->where('name', 'like', "%{$this->search}%")
                      ->orWhere('email', 'like', "%{$this->search}%")
                      ->orWhere('national_id', 'like', "%{$this->search}%");
                }))
                ->when($this->statusFilter, fn($q) => $q->where('status', $this->statusFilter))
                ->latest()
                ->paginate(10),
        ];
    }
};

Validation Rules

public function rules(): array
{
    return [
        'name' => ['required', 'string', 'max:255'],
        'national_id' => ['required', 'string', 'unique:users,national_id'],
        'email' => ['required', 'email', 'unique:users,email'],
        'phone' => ['required', 'string'],
        'password' => ['required', 'string', 'min:8'],
        'preferred_language' => ['required', 'in:ar,en'],
    ];
}

Admin Logging

// After creating user
AdminLog::create([
    'admin_id' => auth()->id(),
    'action_type' => 'create',
    'target_type' => 'user',
    'target_id' => $user->id,
    'new_values' => $user->only(['name', 'email', 'national_id']),
    'ip_address' => request()->ip(),
]);

Edge Cases & Error Handling

  • Validation failure: Display inline field errors using Flux UI error states
  • Duplicate email: Show "Email already exists" error on email field
  • Duplicate National ID: Show "National ID already registered" error
  • Empty search results: Display "No clients found" message with clear filters option

Testing Requirements

Test File Location

tests/Feature/Admin/IndividualClientTest.php

Test Scenarios

Create Client Tests

  • Can create individual client with all valid data
  • Cannot create client without required name field
  • Cannot create client without required email field
  • Cannot create client without required national_id field
  • Cannot create client without required phone field
  • Cannot create client with invalid email format
  • Cannot create client with duplicate email (existing user)
  • Cannot create client with duplicate national_id
  • Cannot create client with password less than 8 characters
  • Created client has user_type set to 'individual'
  • AdminLog entry created on successful creation

List View Tests

  • Index page displays only individual clients (not company/admin)
  • Pagination works with 10/25/50 per page options
  • Clients sorted by created_at desc by default

Search & Filter Tests

  • Can search clients by name (partial match)
  • Can search clients by email (partial match)
  • Can search clients by national_id (partial match)
  • Can filter clients by active status
  • Can filter clients by deactivated status
  • Clear filters resets search and filter

Edit Client Tests

  • Can edit existing client information
  • Edit form pre-populates with current values
  • Validation rules apply on edit (except unique for own record)
  • AdminLog entry created on successful update
  • Cannot change user_type via edit form

View Profile Tests

  • Profile page displays all client information
  • Profile shows consultation count/summary
  • Profile shows timeline count/summary

Testing Approach

use Livewire\Volt\Volt;

test('admin can create individual client', function () {
    $admin = User::factory()->admin()->create();

    Volt::actingAs($admin)
        ->test('admin.clients.individual.create')
        ->set('name', 'Test Client')
        ->set('email', 'client@example.com')
        ->set('national_id', '123456789')
        ->set('phone', '+970599123456')
        ->set('password', 'password123')
        ->set('preferred_language', 'ar')
        ->call('create')
        ->assertHasNoErrors();

    expect(User::where('email', 'client@example.com')->exists())->toBeTrue();
    expect(AdminLog::where('action_type', 'create')->exists())->toBeTrue();
});

Definition of Done

  • Create individual client form works
  • List view displays all individual clients
  • Search and filter functional
  • Edit client works with validation
  • View profile shows complete information
  • Duplicate prevention works
  • Audit logging implemented
  • Bilingual support complete
  • Tests pass for all CRUD operations
  • Code formatted with Pint

Dependencies

  • Story 1.1: Database schema with users table (user_type, national_id, status fields) and admin_logs table
  • Story 1.2: Authentication system with admin role, AdminLog model
  • Story 1.3: Bilingual infrastructure (translation files, __() helper)
  • Story 1.4: Base admin layout and navigation

Risk Assessment

  • Primary Risk: Duplicate National ID from different sources
  • Mitigation: Database unique constraint + form validation
  • Rollback: Remove user and notify if duplicate discovered

Estimation

Complexity: Medium Estimated Effort: 4-5 hours