Project Overview
Understanding the AlKareem ERP codebase organization
The AlKareem ERP system follows a modular, domain-driven architecture. The codebase is organized to maintain clear separation of concerns with dedicated directories for each layer of the application.
Each business module (Accounts, Inventory, Purchase, etc.) has its own dedicated subdirectory in every layer.
Clear separation: Livewire → Services → Repositories → Models with events connecting modules.
Domain-specific logic isolated in Domain/ directory with strategies, adapters, and DTOs.
High-Level Structure
Root Structure
Top-level directory organization
📁 alkareem-erp/
├── 📁 app/ # Application source code
│ ├── 📁 Console/ # Artisan commands
│ ├── 📁 Domain/ # Domain-specific complex logic
│ ├── 📁 Events/ # Domain events (module-organized)
│ ├── 📁 Exceptions/ # Custom exceptions
│ ├── 📁 Helpers/ # Global helper functions
│ ├── 📁 Interfaces/ # Contracts & interfaces
│ ├── 📁 Listeners/ # Event listeners (auto-discovered)
│ ├── 📁 Livewire/ # Livewire components (UI layer)
│ ├── 📁 Models/ # Eloquent models (domain-organized)
│ ├── 📁 Notifications/ # System notifications
│ ├── 📁 Providers/ # Service providers
│ ├── 📁 Repositories/ # Data access layer
│ ├── 📁 Services/ # Business logic layer
│ └── 📁 View/ # View composers & components
│
├── 📁 config/ # Configuration files
│ ├── approvals.php # Approval notification templates
│ ├── lauthz.php # Casbin configuration
│ └── lauthz-rbac-model.conf # RBAC model definition
│
├── 📁 database/ # Database files
│ ├── 📁 migrations/ # Database migrations
│ ├── 📁 factories/ # Model factories
│ └── 📁 seeders/ # Database seeders
│
├── 📁 resources/ # Frontend resources
│ └── 📁 views/ # Blade templates
│
├── 📁 routes/ # Route definitions
│ ├── web.php # Main routes (includes module routes)
│ └── 📁 [modules]/ # Module-specific routes
│
└── 📁 tests/ # Test files
├── 📁 Feature/ # Feature tests
└── 📁 Unit/ # Unit tests
App Directory
Main application source code organization
The app/ directory contains all application code, organized by architectural layer
and then by business module within each layer.
Console Commands
Custom Artisan commands for code generation
📁 app/Console/Commands/
├── MakeLivewireWithService.php # Create Livewire + Service + Repository
├── MakeModuleSeeder.php # Create module-specific seeder
├── MakeRepository.php # Create repository class
└── MakeService.php # Create service class
MakeLivewireWithService
php artisan make:livewire-full ModuleName/ComponentName
Generates Livewire component with matching Service and Repository classes.
MakeRepository
php artisan make:repository ModuleName/EntityRepository
Creates a repository class in the appropriate module directory.
Domain Layer
Complex domain-specific business logic
📁 app/Domain/
├── 📁 Inventory/
│ └── 📁 Allocation/ # Stock allocation strategies
│ ├── 📁 Contracts/ # Interfaces
│ ├── 📁 Adapters/ # Implementations
│ ├── 📁 DTO/ # Data Transfer Objects
│ ├── 📁 Mappers/ # Data mappers
│ └── 📁 Strategies/ # Allocation strategies
│
├── 📁 PreSale/
│ └── # PreSale-specific domain logic
│
└── 📁 Purchase/
└── 📁 AdvanceAllocation/ # Supplier advance allocation
Domain Layer Purpose
The Domain layer houses complex business logic that doesn't fit neatly into a single Service. It follows Domain-Driven Design patterns:
- Contracts: Define interfaces for strategy implementations
- Adapters: Concrete implementations of contracts
- DTOs: Data Transfer Objects for clean data passing
- Strategies: Interchangeable algorithm implementations
Events & Listeners
Event-driven module communication
Events
📁 app/Events/
├── 📁 Accounts/
│ ├── VoucherCreated.php
│ └── ExpenseCreated.php
├── 📁 CashSale/
├── 📁 Inventory/
│ ├── TransferCreated.php
│ └── DeliveryVoucherCreated.php
├── 📁 Lease/
├── 📁 PreSale/
└── 📁 Purchase/
Listeners
📁 app/Listeners/
├── 📁 Accounts/
│ └── # GL transactions, voucher creation
├── 📁 CashSale/
├── 📁 Inventory/
│ └── # Stock transactions, warehouse
├── 📁 Lease/
├── 📁 PreSale/
└── 📁 Purchase/
Listeners are auto-discovered by Laravel using the ShouldBeDiscovered trait.
Livewire Components
UI layer components organized by module
📁 app/Livewire/
├── 📁 Actions/ # Reusable action components
├── 📁 Approvals/ # Approval workflow UI
├── 📁 Components/ # Shared UI components
├── 📁 Dashboard/ # Dashboard components
├── 📁 Forms/ # Reusable form components
│
├── 📁 Accounts/ # Accounts module UI
├── 📁 Inventory/ # Inventory module UI
├── 📁 Purchase/ # Purchase module UI
├── 📁 PreSale/ # PreSale module UI
├── 📁 CashSale/ # CashSale module UI
└── 📁 Lease/ # Lease module UI
Models
Eloquent models organized by business domain
📁 app/Models/
├── 📁 Core/ # User, Role, Branch, Company, etc.
├── 📁 Accounts/ # LevelOne, LevelTwo, Accounts, Voucher, etc.
├── 📁 Inventory/ # Item, Transfer, ReceivingVoucher, etc.
├── 📁 Purchase/ # Supplier, PurchaseOrder, PurchaseInvoice
├── 📁 PreSale/ # SaleQuotation, SaleBooking
├── 📁 CashSale/ # CashSaleInvoice, CashSaleCustomer
└── 📁 Lease/ # LeaseCustomer, LeaseProcessing, etc.
Key Models by Module
Core
User, Role, Branch, Company, Warehouse, Tax, Module, ModuleProcess, ApprovalSetup, ApprovalRequest, ProcessRule
Accounts
LevelOne, LevelTwo, LevelThree, Accounts, Voucher, Transaction, Expense, FundsTransfer, Budget, FinancialYear, BankAccount
Inventory
Category, Subcategory, Item, ItemVariant, Unit, Transfer, ReceivingVoucher, DeliveryVoucher, StockTransaction, WarehouseStockItem
Purchase
Supplier, PurchaseOrder, PurchaseInvoice, GoodsReceivedNote, SupplierPayment, SupplierAdvance, PurchaseReturn
Repositories
Data access layer abstraction
📁 app/Repositories/
├── 📁 Core/
├── 📁 Accounts/
├── 📁 Inventory/
├── 📁 Purchase/
├── 📁 PreSale/
├── 📁 CashSale/
└── 📁 Lease/
Repository Responsibilities
- Abstract database queries from business logic
- Handle complex joins and eager loading
- Prepare data for datatable display
- Single source for entity retrieval patterns
Services
Business logic orchestration layer
📁 app/Services/
├── 📁 Engine/
│ └── ApprovalEngineService.php # Central approval system
│
├── 📁 Core/
├── 📁 Accounts/
├── 📁 Inventory/
│ └── 📁 Engines/ # Specialized engines
│ ├── SerialManagementEngine.php
│ ├── StockValidationEngine.php
│ └── StockItemLifecycleEngine.php
│
├── 📁 Purchase/
├── 📁 PreSale/
├── 📁 CashSale/
├── 📁 Lease/
└── 📁 Reports/
Service Responsibilities
- • Orchestrate business operations
- • Handle transactions (DB::transaction)
- • Dispatch domain events
- • Coordinate approval workflows
Specialized Engines
- • ApprovalEngineService - Workflow orchestration
- • SerialManagementEngine - Serial number logic
- • StockValidationEngine - Stock checks
- • StockItemLifecycleEngine - Item state management
Configuration
Application configuration files
📁 config/
├── approvals.php # Approval notification templates
├── lauthz.php # Casbin configuration
└── lauthz-rbac-model.conf # RBAC model definition
approvals.php
Defines notification templates and messages for the approval workflow system.
lauthz.php
Laravel Casbin integration settings including adapter and model path configuration.
lauthz-rbac-model.conf
PERM model definition for role-based access control with hierarchical roles.
Database
Migrations, factories, and seeders
📁 database/
├── 📁 migrations/ # Database schema migrations
├── 📁 factories/ # Model factories for testing
└── 📁 seeders/
├── 📁 Core/
│ ├── PermissionSeeder.php # CRITICAL: Define permissions
│ ├── UserSeeder.php # CRITICAL: Map role permissions
│ ├── RolesSeeder.php
│ ├── BranchSeeder.php
│ ├── ModuleSeeder.php
│ └── ModuleProcessSeeder.php
├── 📁 Accounts/
├── 📁 Inventory/
├── 📁 Purchase/
├── 📁 PreSale/
├── 📁 CashSale/
└── 📁 Lease/
PermissionSeeder.php and
UserSeeder.php must be updated when adding new features
to ensure proper RBAC permission mapping.
Routes
Module-organized route definitions
📁 routes/
├── web.php # Main routes (includes module routes)
├── auth.php # Authentication routes
├── 📁 accounts/ # Account module routes
├── 📁 inventory/ # Inventory module routes
├── 📁 purchase/ # Purchase module routes
├── 📁 presale/ # PreSale module routes
├── 📁 cashsale/ # Cash Sale module routes
├── 📁 lease/ # Lease module routes
└── 📁 core/ # Core/Settings routes
Route Protection Pattern
All module routes use Casbin middleware for permission checking:
Route::middleware(['casbinAuth:admin,module.permission'])
->group(function () {
// Protected routes
});
Resources & Views
Frontend templates and assets
📁 resources/
└── 📁 views/
└── 📁 livewire/
└── 📁 components/
└── 📁 sidebarmenu/ # CRITICAL: Menu items with @canAccess
├── accountsitems.blade.php
├── inventoryitems.blade.php
├── purchaseitems.blade.php
├── presaleitems.blade.php
├── cashsaleitems.blade.php
├── leaseitems.blade.php
└── settingitems.blade.php
@canAccess('permission') directive for permission-based menu visibility.
Tests
Feature and unit tests using Pest
📁 tests/
├── 📁 Feature/ # Integration/Feature tests
└── 📁 Unit/ # Unit tests
Feature Tests
Test complete user workflows including HTTP requests, database interactions, and Livewire components.
Unit Tests
Test individual Service methods, Repository queries, and domain logic in isolation.
Running Tests
# Run all tests
php artisan test
# Run specific test file
php artisan test tests/Feature/Inventory/TransferTest.php
# Run with coverage
php artisan test --coverage