Branch Management Architecture
This document describes the architectural design of the Branch Management module, which follows enterprise-level Laravel patterns.
Architecture Patterns
The Branch module implements three key architectural patterns:
1. Repository Pattern
Abstracts data access logic and provides a clean interface for data operations.
Location: app/Repositories/BranchRepository.phpInterface: app/Contracts/Repositories/BranchRepositoryInterface.php
Responsibilities:
- Database query construction
- Data filtering and sorting
- CRUD operations
- Validation of query parameters
Example:
$branches = $this->branchRepository->getAllWithFilters(
search: 'Main',
sortField: 'name',
sortDirection: 'asc'
);2. Service Layer Pattern
Orchestrates business logic and coordinates between repositories and actions.
Location: app/Services/BranchService.php
Responsibilities:
- Business logic orchestration
- Coordinating actions
- Providing high-level API for controllers
- Transaction management (if needed)
Example:
$branch = $this->branchService->createBranch([
'name' => 'Main Clinic',
'code' => 'MAIN',
// ...
]);3. Action Pattern
Single-purpose classes that perform specific operations.
Location: app/Actions/Branch/
Available Actions:
StoreBranchAction- Creates a new branchUpdateBranchAction- Updates an existing branchDeleteBranchAction- Deletes a branch (with validation)ToggleBranchStatusAction- Toggles branch active status
Responsibilities:
- Single responsibility per action
- Reusable across different contexts
- Encapsulated business rules
Example:
try {
$this->deleteBranchAction->execute($branch);
} catch (BranchHasUsersException $e) {
// Handle exception
}Architecture Layers
┌─────────────────────────────────────────┐
│ Presentation Layer │
│ - API Resources (BranchResource) │
│ - Vue Components (Index, Show) │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ Controller Layer │
│ - HTTP Request/Response handling │
│ - Route parameter binding │
│ - BranchController │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ Form Request Layer │
│ - Input validation │
│ - StoreBranchRequest │
│ - UpdateBranchRequest │
│ - ToggleBranchStatusRequest │
└─────────────────┬───────────────────────┘
│
┌─────────────────▼───────────────────────┐
│ Service Layer │
│ - Business logic orchestration │
│ - BranchService │
└─────────────────┬───────────────────────┘
│
┌────────┴────────┐
│ │
┌────────▼────────┐ ┌─────▼──────────────┐
│ Action Layer │ │ Repository Layer │
│ - StoreBranch │ │ - Interface │
│ - UpdateBranch │ │ - Implementation │
│ - DeleteBranch │ │ - Query building │
│ - ToggleStatus │ │ - Data filtering │
└─────────────────┘ └─────┬──────────────┘
│
┌───────▼────────┐
│ Model Layer │
│ - Branch │
│ - User │
└────────────────┘File Structure
app/
├── Actions/
│ └── Branch/
│ ├── StoreBranchAction.php
│ ├── UpdateBranchAction.php
│ ├── DeleteBranchAction.php
│ └── ToggleBranchStatusAction.php
├── Contracts/
│ └── Repositories/
│ └── BranchRepositoryInterface.php
├── Exceptions/
│ └── BranchHasUsersException.php
├── Http/
│ ├── Controllers/
│ │ └── Admin/
│ │ └── BranchController.php
│ ├── Requests/
│ │ └── Branch/
│ │ ├── StoreBranchRequest.php
│ │ ├── UpdateBranchRequest.php
│ │ └── ToggleBranchStatusRequest.php
│ └── Resources/
│ ├── BranchResource.php
│ ├── BranchCollection.php
│ └── UserResource.php
├── Models/
│ └── Branch.php
├── Providers/
│ └── RepositoryServiceProvider.php
├── Repositories/
│ └── BranchRepository.php
└── Services/
└── BranchService.php
resources/
└── js/
├── composables/
│ └── useBranches.ts
├── pages/
│ └── admin/
│ └── branches/
│ ├── Index.vue
│ ├── Show.vue
│ └── components/
│ ├── BranchForm.vue
│ ├── BranchesHeader.vue
│ └── DeleteDialog.vue
└── types/
└── resources.tsAPI Resources
BranchResource
Transforms Branch model into consistent JSON structure.
Location: app/Http/Resources/BranchResource.php
Fields:
- Basic info: id, code, name, address, phone, email
- Status: is_active
- Relationships: users (when loaded), users_count
- Timestamps: created_at, updated_at (ISO8601 format)
Usage:
// Single resource
return new BranchResource($branch);
// Collection
return BranchResource::collection($branches);UserResource
Transforms User model with proper data hiding and relationship loading.
Location: app/Http/Resources/UserResource.php
Features:
- Hides sensitive data (password, tokens, secrets)
- Conditionally loads relationships
- Formats dates to ISO8601
- Includes role and permission information
Frontend Architecture
TypeScript Types
All Laravel Resources have matching TypeScript interfaces.
Location: resources/js/types/resources.ts
Interfaces:
BranchResource- Matches Laravel BranchResourceUserResource- Matches Laravel UserResourceBranchFormData- Form input dataUserFormData- User form input data
Composables
Reusable Vue composition functions for branch operations.
Location: resources/js/composables/useBranches.ts
Exports:
BranchinterfaceUserinterfaceBranchFormDatainterfaceuseBranches()composable function
Functions:
createBranch()- Create new branchupdateBranch()- Update existing branchdeleteBranch()- Delete branchtoggleBranchStatus()- Toggle active status
Vue Components
Index.vue
Main branch listing page with:
- Server-side search and filtering
- Sortable table columns
- Create/Edit/Delete dialogs
- Flash message display
- Responsive design
Show.vue
Branch detail page with:
- Branch information card
- Statistics card
- Assigned users table
- Edit and delete actions
- Status toggle
Components
BranchForm.vue- Reusable form for create/editBranchesHeader.vue- Page header with search and create buttonDeleteDialog.vue- Confirmation dialog for deletion
Benefits
1. Separation of Concerns
Each layer has a specific responsibility, making the code easier to understand and maintain.
2. Testability
- Repositories can be mocked for testing services
- Actions can be tested independently
- Services can be tested with mock repositories and actions
3. Reusability
- Actions can be used in different contexts (CLI, Jobs, etc.)
- Repositories can be swapped (e.g., for caching)
- Resources provide consistent API responses
4. Maintainability
- Changes in one layer don't affect others
- Easy to add new features
- Clear structure for new developers
5. Type Safety
- TypeScript interfaces match Laravel Resources
- Compile-time type checking in frontend
- Better IDE support and autocomplete
Adding New Features
Backend
- Add method to Repository interface and implementation
- Create Action class if needed
- Add method to Service
- Update Controller to use Service
- Create/update Form Request for validation
- Update Resource if response structure changes
Frontend
- Update TypeScript types if needed
- Add composable function if needed
- Create/update Vue component
- Test with new data structure
Best Practices
- Always use the Service layer - Controllers should only delegate to services
- Keep Actions simple - One responsibility per action
- Use Form Requests - Validate input at the request level
- Use Resources - Always transform data through resources
- Type everything - Use TypeScript interfaces for all data structures
- Test at each layer - Unit tests for actions, integration tests for services
Future Enhancements
- Add caching layer in Repository
- Implement event dispatching in Actions
- Add audit logging in Service layer
- Create Data Transfer Objects (DTOs)
- Add query builders for complex filters