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

18 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


Dev Agent Record

Status

Done

Agent Model Used

Claude Opus 4.5 (claude-opus-4-5-20251101)

File List

Created:

  • resources/views/livewire/admin/clients/individual/index.blade.php - List view with search/filter/pagination
  • resources/views/livewire/admin/clients/individual/create.blade.php - Create individual client form
  • resources/views/livewire/admin/clients/individual/edit.blade.php - Edit individual client form
  • resources/views/livewire/admin/clients/individual/show.blade.php - Client profile/view page
  • lang/en/clients.php - English translations for clients module
  • lang/ar/clients.php - Arabic translations for clients module
  • tests/Feature/Admin/IndividualClientTest.php - 32 comprehensive tests for CRUD operations

Modified:

  • app/Models/User.php - Added scopeIndividual() and scopeCompanies() scopes
  • routes/web.php - Added admin routes for individual clients CRUD
  • resources/views/components/layouts/app/sidebar.blade.php - Added User Management navigation for admins
  • lang/en/navigation.php - Added navigation translations for user management
  • lang/ar/navigation.php - Added Arabic navigation translations for user management

Change Log

Date Change Files
2025-12-26 Added User model scopes for individual and company clients app/Models/User.php
2025-12-26 Created bilingual translation files for clients module lang/en/clients.php, lang/ar/clients.php
2025-12-26 Created individual clients CRUD Volt components resources/views/livewire/admin/clients/individual/*.blade.php
2025-12-26 Added admin routes for individual clients management routes/web.php
2025-12-26 Added sidebar navigation for User Management resources/views/components/layouts/app/sidebar.blade.php
2025-12-26 Added navigation translations lang/en/navigation.php, lang/ar/navigation.php
2025-12-26 Created comprehensive test suite (32 tests) tests/Feature/Admin/IndividualClientTest.php

Completion Notes

  • All CRUD operations implemented with class-based Volt components following existing patterns
  • Bilingual support complete for all form labels, messages, and navigation
  • Search supports partial match on name, email, and national_id
  • Filter by status (active/deactivated/all) with clear filters functionality
  • Pagination with 10/25/50 per page options, sorted by created_at desc by default
  • Audit logging (AdminLog) implemented for create and update operations
  • Client profile page shows consultation and timeline counts with summary stats
  • All 32 tests pass covering create, list, search, filter, edit, view, and authorization
  • Full test suite (200 tests) passes with no regressions
  • Code formatted with Laravel Pint

Definition of Done Checklist

  • 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 (email and national_id unique validation)
  • Audit logging implemented (AdminLog entries for create/update)
  • Bilingual support complete
  • Tests pass for all CRUD operations (32 tests)
  • Code formatted with Pint

QA Results

Review Date: 2025-12-26

Reviewed By: Quinn (Test Architect)

Risk Assessment

Risk Level: LOW-MEDIUM

  • Not a security-critical feature (no auth/payment handling)
  • 32 tests added covering all CRUD operations
  • Diff is moderate (~700 lines across all new files)
  • First gate for this story (no previous FAIL)
  • 6 acceptance criteria sections with clear requirements

Code Quality Assessment

Overall: EXCELLENT

The implementation follows Laravel/Livewire best practices consistently:

  1. Architecture & Patterns

    • Class-based Volt components used correctly throughout
    • Proper use of WithPagination trait for list view
    • Clean separation of concerns with PHP logic in class block
    • Follows existing project patterns for admin components
  2. Code Structure

    • Consistent file organization in resources/views/livewire/admin/clients/individual/
    • User model scopes (scopeIndividual(), scopeCompanies()) properly implemented
    • Clean route definitions using Volt::route()
  3. Validation

    • Comprehensive rules for all form fields
    • Proper handling of unique constraints on edit (using Rule::unique()->ignore())
    • Custom error messages for duplicate email/national_id
  4. Audit Logging

    • AdminLog entries created for both create and update operations
    • Old and new values captured appropriately
    • IP address tracking implemented

Refactoring Performed

None required. Code is clean and follows project conventions.

Compliance Check

  • Coding Standards: ✓ Pint passes with --dirty flag
  • Project Structure: ✓ Files in correct locations per story spec
  • Testing Strategy: ✓ 32 tests covering all acceptance criteria
  • All ACs Met: ✓ See traceability matrix below

Requirements Traceability

Acceptance Criteria Test Coverage Status
AC1: Create form with all required fields admin can create individual client with all valid data, field validation tests
AC2: Validation for all required fields 5 tests for missing required fields
AC3: Duplicate email/National ID prevention cannot create client with duplicate email/national_id
AC4: Password strength indicator Optional per story - not implemented ⚠️ Optional
AC5: Success message on creation Tested via redirect assertion
AC6: List view individual clients only index page displays only individual clients
AC7: Columns display Verified via component assertions
AC8: Pagination 10/25/50 Component property perPage tested
AC9: Default sort by created_at desc clients sorted by created_at desc by default
AC10: Search by name/email/National ID 3 search tests with partial match
AC11: Filter by status can filter clients by active/deactivated status
AC12: Real-time search with debounce wire:model.live.debounce.300ms in template
AC13: Clear filters button clear filters resets search and filter
AC14: Edit all client information can edit existing client information
AC15: Cannot change user_type Edit form doesn't expose user_type field
AC16: Edit validation same as create validation rules apply on edit
AC17: Success message on update Tested via session flash + redirect
AC18: View client profile profile page displays all client information
AC19: Consultation history summary profile shows consultation count
AC20: Timeline history summary profile shows timeline count
AC21: Bilingual form labels Translation files complete (en/ar)
AC22: Proper form validation display Flux:error components used
AC23: Audit log entries Tests verify AdminLog entries
AC24: Tests for CRUD operations 32 tests pass

Improvements Checklist

All items completed by developer - no action required:

  • Proper validation rules with custom messages
  • Clean route structure with named routes
  • Bilingual translations complete
  • Sidebar navigation for admin users
  • AdminLog entries for audit trail
  • Proper eager loading with loadCount() for profile stats

Security Review

Status: PASS

  1. Authorization: Routes properly protected by admin middleware
  2. Authentication: Tests verify non-admin and unauthenticated access blocked
  3. Data Validation: All inputs validated server-side before processing
  4. Password Handling: Uses Hash::make() for password storage (proper bcrypt)
  5. Sensitive Data: national_id marked as hidden in User model

Performance Considerations

Status: PASS

  1. N+1 Prevention: Profile page uses loadCount() for relationship counts
  2. Pagination: Implemented with configurable per-page options
  3. Search: Uses database-level filtering, not PHP array filtering
  4. Eager Loading: Properly scoped queries with when() clauses

Maintainability Assessment

Status: PASS

  1. Single Responsibility: Each component handles one view/action
  2. DRY: Translation keys reused across components
  3. Testability: All operations fully testable via Volt::test()
  4. Documentation: Code is self-documenting with clear method names

Files Modified During Review

None. No refactoring was necessary.

Gate Status

Gate: PASS → docs/qa/gates/2.1-individual-client-account-management.yml

Ready for Done - All acceptance criteria met, comprehensive test coverage, no blocking issues found.

Future Recommendations for Dev Agent

The following items are not blocking but should be considered for future implementation:

  1. Password Strength Indicator (Optional)

    • File: resources/views/livewire/admin/clients/individual/create.blade.php
    • Description: AC4 in the story marked this as optional. Consider adding a visual password strength indicator (e.g., weak/medium/strong) using JavaScript or a Livewire reactive property.
    • Priority: Low
  2. Delete Client Functionality

    • File: resources/views/livewire/admin/clients/individual/index.blade.php
    • Description: The current story scope covers create, view, edit, and search only. Translation keys for delete already exist (clients.delete, clients.client_deleted). When requirements are clarified, add a delete action with confirmation modal and appropriate AdminLog entry.
    • Priority: Medium - implement when a future story requires it
    • Considerations:
      • Soft delete vs hard delete decision needed
      • Handle cascading relationships (consultations, timelines)
      • Add authorization check before deletion
      • Create test coverage for delete operation