Lads Africa Code Guide
Lads Africa Code Guide
Table of Contents
1. General Coding Best Practices (Deep Dive with Examples) .................................................. 6
Structure & Readability ....................................................................................................... 6
Follow PSR Standards ...................................................................................................... 6
Use Meaningful Names .................................................................................................... 7
Avoid Deep Nesting (Use Early Returns) ........................................................................... 7
Limit Method Size (20-30 Lines Max) ................................................................................. 8
Avoid Duplicate Code (DRY Principle) .............................................................................. 8
1.2 Error Handling & Logging .............................................................................................. 10
Use Exceptions (Not Silent Failures) .............................................................................. 10
Log Meaningful Errors .................................................................................................... 10
1.3 Constants & Configs .................................................................................................... 11
Avoid Magic Numbers/Strings ........................................................................................ 11
2. Laravel-Specific Guidelines (Deep Dive with Examples) .................................................... 12
2.1 MVC Structure & Responsibilities ................................................................................ 12
Keep Controllers Thin .................................................................................................... 12
Combining Services and Repositories ............................................................................ 13
Architecture Overview ................................................................................................... 14
Use FormRequest for Validation .................................................................................... 17
2.2 Database & Eloquent ................................................................................................... 18
Use Efficient Querying (Avoid N+1) ................................................................................. 18
Prefer Eloquent Over Query Builder................................................................................ 18
Use Scopes for Reusable Queries .................................................................................. 19
2.3 API Development ......................................................................................................... 20
Use API Resources for JSON Responses ......................................................................... 20
Return Proper HTTP Status Codes..................................................................................... 20
2.4 Middleware & Requests ............................................................................................... 21
Use Middleware for Cross-Cutting Concerns ................................................................. 21
3. Git & Version Control Best Practices (Deep Dive with Examples) ....................................... 23
3.1 Branching Strategy ....................................................................................................... 23
Use Git Flow (Modified) .................................................................................................. 23
3.2 Commit Message Standards ........................................................................................ 24
Use Conventional Commits ........................................................................................... 24
2
This checklist is mandatory for all PRs
3
This checklist is mandatory for all PRs
4
This checklist is mandatory for all PRs
5
This checklist is mandatory for all PRs
// Good (PSR-12)
class UserService
{
public function getUserById(int $userId): ?User
{
return User::find($userId);
}
}
// Bad (Non-PSR-12)
class userService{
function getUserById($userId){
return User::find($userId);
}
}
• PHP-CS-Fixer
6
This checklist is mandatory for all PRs
if (!$user->isActive()) {
return;
}
if (!$order->isValid()) {
return;
7
This checklist is mandatory for all PRs
Bad Practice:
Good Practice:
{
$this->validateOrder();
$total = $this->calculateTotal();
$this->createOrder($total);
$this->sendConfirmation();
}
function getActiveAdminUsers() {
return User::where('role', 'admin')->where('active', true)->get();
}
8
This checklist is mandatory for all PRs
// Usage
User::admin()->get();
User::admin()->where('active', true)->get();
9
This checklist is mandatory for all PRs
Bad Practice:
try {
$user = User::find($id);
} catch (Exception $e) {
// Silent catch (hides errors)
}
Good Practice:
try {
$user = User::findOrFail($id);
} catch (ModelNotFoundException $e) {
Log::error("User not found: " . $e->getMessage());
throw new CustomException("User not found", 404);
}
Log::error("Failed");
10
This checklist is mandatory for all PRs
Bad Practice:
if ($user->status === 1) {
// What does "1" mean?
}
Good Practice:
// In User model
const STATUS_ACTIVE = 1;
const STATUS_INACTIVE = 0;
Dos Don’t
Use PSR-12 formatting Mix camelCase and snake_case
Keep methods small (~20 lines) Write 100-line mega-functions
Throw descriptive exceptions Swallow errors silently
Log with context Log generic "Error occurred"
Reuse code (DRY) Copy-paste logic everywhere
11
This checklist is mandatory for all PRs
• Validate input
• Call Services/Repositories
• Return responses
12
This checklist is mandatory for all PRs
$order = Order::create([...]);
return response()->json($order);
}
}
13
This checklist is mandatory for all PRs
Architecture Overview
✓ Repositories: Handle all data access logic by interacting with the database.
✓ Services: Contain business logic, utilizing repositories to perform complex operations.
✓ Controllers: Act as intermediaries, managing requests and responses, while delegating business
operations to services.
Implementation Steps
// Additional methods...
}
14
This checklist is mandatory for all PRs
class ProductService {
protected $productRepository;
15
This checklist is mandatory for all PRs
Benefits
✓ Readability: Separates concerns clearly, making the code easier to understand.
✓ Maintainability: Isolates changes to specific parts of the codebase.
✓ Testability: Allows for isolated testing of services and repositories by mocking dependencies.
16
This checklist is mandatory for all PRs
// app/Http/Requests/CreateUserRequest.php
class CreateUserRequest extends FormRequest
{
public function rules()
{
return [
'email' => 'required|email',
'password' => 'required|min:8',
];
}
}
// In Controller
public function store(CreateUserRequest $request)
{
// No need to validate manually
}
17
This checklist is mandatory for all PRs
$users = User::all();
foreach ($users as $user) {
echo $user->posts->count(); // Queries DB on each loop!
}
Good (Eager Loading):
$users = User::with('posts')->get();
foreach ($users as $user) {
echo $user->posts->count(); // No additional queries
}
DB::table('users')
->where('active', 1)
->get();
Good (Eloquent):
User::where('active', true)->get();
Exception: Use Query Builder for complex joins or bulk updates.
18
This checklist is mandatory for all PRs
19
This checklist is mandatory for all PRs
return response()->json([
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
]);
// app/Http/Resources/UserResource.php
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
];
}
}
// In Controller
return new UserResource($user);
20
This checklist is mandatory for all PRs
// app/Http/Middleware/LogRequests.php
class LogRequests
{
public function handle($request, $next)
{
Log::info('Request:', [
'url' => $request->url(),
'method' => $request->method(),
]);
return $next($request);
}
}
Register in app/Http/Kernel.php:
protected $middleware = [
\App\Http\Middleware\LogRequests::class,
];
21
This checklist is mandatory for all PRs
22
This checklist is mandatory for all PRs
3. Git & Version Control Best Practices (Deep Dive with Examples)
This section establishes strict Git guidelines to maintain a clean, collaborative codebase with
traceable changes.
Example Workflow:
Prohibited:
23
This checklist is mandatory for all PRs
Examples:
Good Practice
Bad Practice
Tools:
• commitlint (enforces format)
• cz-cli (interactive commit helper)
24
This checklist is mandatory for all PRs
2. Descriptive Title
5. Passing CI Pipeline
Description
Related Issue
Testing
1. Checkout branch
2. Run `php artisan test`
3. Verify feature X works
25
This checklist is mandatory for all PRs
# Interactive rebase
26
This checklist is mandatory for all PRs
# Before PR submission
git pull --rebase origin develop
Why?
• Keeps history linear
• Avoids merge commits in feature branches
Exception:
Use --no-ff merges for develop → staging to preserve feature groupings:
git checkout staging
git merge --no-ff develop
Required Exclusions:
.env
.phpunit.result.cache
storage/framework/cache/*
vendor/
node_modules/
Best Practice:
27
This checklist is mandatory for all PRs
# From main
# After fixes
# Revert safely
28
This checklist is mandatory for all PRs
Enforcement Tools
1. Pre-commit Hooks
2. CI Pipeline Checks
▪ Linked issue
▪ Passing tests
▪ Approvals
▪ Require:
▪ 1+ approvals
▪ Status checks
▪ Signed commits
29
This checklist is mandatory for all PRs
// routes/web.php
Route::post('/user', function (Request $request) {
User::create([
'name' => $request->name, // No validation!
'email' => $request->email,
]);
});
// In Controller
public function store(StoreUserRequest $request)
{
User::create($request->validated()); // Only safe data
}
30
This checklist is mandatory for all PRs
Critical Validations:
• email → email:rfc,dns (strict format)
• File uploads → mimes:jpg,png|max:2048
• JSON APIs → Use $request->json()->all()
31
This checklist is mandatory for all PRs
Allowed Exceptions:
• Raw SQL only with DB::raw() + bindings:
32
This checklist is mandatory for all PRs
• Password hashing
• CSRF protection
• Session management
Required Practices:
1. Password Rules:
Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
2. Role/Permission Packages:
Good (Gates/Policies):
// app/Policies/OrderPolicy.php
public function delete(User $user, Order $order)
{
return $user->isAdmin() || $order->user_id === $user->id;
}
// In Controller
$this->authorize('delete', $order);
33
This checklist is mandatory for all PRs
• md5(), sha1()
34
This checklist is mandatory for all PRs
2. Tokens:
35
This checklist is mandatory for all PRs
Dangerous (Avoid):
{!! $userInput !!} <!-- Raw HTML - Only for trusted content -->
CSRF Tokens
Required in Forms:
Run
<form method="POST">
@csrf <!-- Mandatory -->
</form>
API Exemption:
• Only if using stateless auth (JWT/Sanctum)
36
This checklist is mandatory for all PRs
$request->validate([
'avatar' => 'required|file|mimes:jpg,png|max:1024',
]);
// Store with random filename
$path = $request->file('avatar')->store('avatars', 's3');
Banned Practices:
37
This checklist is mandatory for all PRs
• No raw SQL?
2. Authentication
• Passwords hashed?
3. Configuration
• No secrets in code?
• .env gitignored?
4. APIs
• Rate-limited?
• Tokens secure?
5. Dependencies
• No vulnerable packages?
38
This checklist is mandatory for all PRs
39
This checklist is mandatory for all PRs
// Tests/Unit/UserServiceTest.php
public function test_creates_user()
{
$countBefore = User::count();
(new UserService())->createUser('[email protected]');
$this->assertEquals($countBefore + 1, User::count()); // Hits real DB!
}
Key Rules:
• Mock database, external APIs, and filesystem
• Test one behavior per method
• Achieve 100% path coverage for critical logic
40
This checklist is mandatory for all PRs
// tests/Feature/UserApiTest.php
public function test_user_registration()
{
$response = $this->postJson('/api/register', [
'email' => '[email protected]',
'password' => 'Str0ngP@ss',
]);
$response->assertStatus(201)
->assertJsonStructure(['id', 'email']);
$this->assertDatabaseHas('users', [
'email' => '[email protected]',
]);
}
Required Checks:
• Authentication/authorization
41
This checklist is mandatory for all PRs
$this->actingAs($admin)
->get('/admin/orders')
->assertOk()
->assertJsonCount(5, 'data');
}
Best Practices:
• Define factory states for common roles (admin(), withOrders())
42
This checklist is mandatory for all PRs
Generate Report:
CI Blocking Rules:
43
This checklist is mandatory for all PRs
Non-Deterministic Tests
Over-Mocking
44
This checklist is mandatory for all PRs
Bad Names:
• testCreateUser() (vague)
• testCase1() (meaningless)
1. Unit Tests
2. Feature Tests
3. Data
4. CI
• Is coverage enforced?
45
This checklist is mandatory for all PRs
This section provides high-impact database optimization strategies for Laravel applications,
focusing on query efficiency, data structure, and retrieval patterns.
For Relationships:
Performance Gain:
• 40-60% faster queries on tables with 20+ columns
• 30% memory reduction in PHP
$users = User::query()
->select('id', 'name')
->where('active', true)
->cursorPaginate(perPage: 20, columns: ['id', 'name']);
46
This checklist is mandatory for all PRs
Key Differences:
Example Scenario:
An e-commerce site displaying order_count on user profiles.
Normalized (Slow):
Denormalized (Fast):
1. Add column:
// Migration
$table->integer('order_count')->default(0);
2. Update via observer:
// app/Observers/OrderObserver.php
public function created(Order $order)
{
$order->user->increment('order_count');
}
3. Query becomes:
When to Denormalize:
• Read/Write ratio > 100:1
• Aggregations (count, sum) used in hot paths
47
This checklist is mandatory for all PRs
User::where('last_name', 'Doe')
->where('company_id', 5)
->get();
Solution:
1. Create composite index:
// Migration
$table->index(['last_name', 'company_id']);
2. Verify usage:
Indexing Rules:
User::where('first_name', 'John')
->orWhere('last_name', 'Doe')
->get();
48
This checklist is mandatory for all PRs
Better Solutions:
Option 1: Union Queries
// Query
User::whereFullText(['first_name', 'last_name'], 'John Doe');
49
This checklist is mandatory for all PRs
Good Practice:
User::chunk(200, function ($users) {
$users->each->update([...]);
});
For Deletions:
User::where('inactive', true)->chunkById(100, function ($users) {
$users->each->delete();
});
Memory Comparison:
50
This checklist is mandatory for all PRs
// Migration
Schema::create('audit_logs', function (Blueprint $table) {
$table->id();
$table->date('logged_at');
$table->string('event');
})->partitionBy('RANGE', function ($partition) {
$partition->year('logged_at')->from(2020)->to(2025);
});
Benefits:
1. Queries:
• Pagination implemented
2. Indexes:
3. Structure:
4. Tools:
51
This checklist is mandatory for all PRs
Key Tools:
• MySQL slow_query_log
Real-World Example
Before Optimization:
// Profile page loads in 1200ms
$user = User::find($id); // SELECT *
$posts = $user->posts()->get(); // SELECT * + N+1 for comments
$stats = [
'posts_count' => $posts->count(), // In-memory count
'likes_count' => $posts->sum('likes') // In-memory sum
];
After Optimization:
52
This checklist is mandatory for all PRs
Benefits
Implementation Steps
Periodic Updates
• Implement scheduled tasks (e.g., Cron jobs in Laravel) to update these sub tables regularly.
• Ensure data consistency and freshness by choosing appropriate update intervals.
53
This checklist is mandatory for all PRs
Example Implementation
$aggregatedData = DB::table('sales')
->selectRaw('product_id, DATE(created_at) as report_date,
SUM(amount) as total_sales, COUNT(*) as units_sold')
->groupBy('product_id', 'report_date')
->get();
Considerations
• Accuracy: Ensure that calculations are precise and reflect the source data.
• Storage: Weigh the benefits against storage costs to determine feasibility.
• Maintenance: Regularly review and update the table structures and logic to align with
changing business needs.
54
This checklist is mandatory for all PRs
Optimizations Applied:
2. Denormalized counters
4. Eliminated N+1
55
This checklist is mandatory for all PRs
Treat Livewire components as stateful controllers for the frontend, keep their logic focused and design for
performance and security.
Component Modularity
Best Practice:
Good Practice:
// Modular structure
Defer loading or rendering of non-critical portions of the UI until the user needs to see them (for example,
heavy data tables or reports).
56
This checklist is mandatory for all PRs
State Management
Best Practice:
For cross-component state or persistence across page reloads, use Livewire’s $state or external
stores.
Good Practice
Bad Practice
<input wire:model="search">
Why:Default wire:model triggers a request every keystroke, often resulting in excessive backend load and
latency.
Always paginate large data sets, use Eloquent select() to retrieve only required fields, eager load only
necessary relationships among others.
57
This checklist is mandatory for all PRs
Good Practice
Bad Practice
public function render()
{
$users = User::all(); // Fetches all columns, all users
return view('livewire.user-list', compact('users'));
}
Good Practice
use Livewire\Attributes\Computed;
#[Computed]
public function todos()
{
return Auth::user()->todos()->select('title', 'content')->get();
}
In Blade:
@foreach ($this->todos as $todo)
<li>{{ $todo->title }}</li>
@endforeach
Why: Ensures every request applies constraints, avoids leaking unwanted columns
58
This checklist is mandatory for all PRs
$post->update([...]);
}
use Livewire\Attributes\Locked;
#[Locked]
public $id;
59
This checklist is mandatory for all PRs
Relation::morphMap([
'post' => 'App\Models\Post',
]);
Good Practice
public $email, $name;
60
This checklist is mandatory for all PRs
Blade Security/XSS
Best Practice:
Rely on Blade’s escape behavior—always use {{ $var }} instead of {!! $var !!} unless the
data is properly sanitized and safe.
public $photo;
Summary Table
61
This checklist is mandatory for all PRs
Red Flags:
• Controllers > 100 lines
• DB::raw() without parameter binding
8.2 Security
Input & Data Handling
62
This checklist is mandatory for all PRs
8.3 Performance
Database Optimization
PHP Optimization
63
This checklist is mandatory for all PRs
Edge Cases
• PSR-12 compliance
Git Hygiene
64
This checklist is mandatory for all PRs
8.6 Frontend
Blade/JavaScript
• No inline scripts/styles (use Laravel Mix)
API Responses
8.7 Documentation
1. Pre-Review Checks
2. Review Process
3. Approval Criteria
65
This checklist is mandatory for all PRs
Tool Purpose
PHPStan Static analysis (bugs, types)
Laravel Pint PSR-12 style checking
GitHub Actions Run tests/linters on PR
SonarQube Code quality metrics
Security Risk: Raw SQL detected in UserRepository.php. Use ->where() with binding.
Post-Review Actions
1. Approved PRs:
2. Rejected PRs:
66
This checklist is mandatory for all PRs
Metric Target
Test coverage ≥80% (critical paths)
Query count per page ≤15 (non-cached)
Page load time ≤500ms (cached)
PHP memory usage ≤50MB/request
67
This checklist is mandatory for all PRs
68
This checklist is mandatory for all PRs
Don’t ignore exceptions; handle them properly to prevent unexpected application crashes.
Don't Silence Errors
✓ Avoid using error suppression operators like @. Always handle errors appropriately.
Don’t Use Inline Styles or Scripts in Blade
✓ Keep styles and scripts in separate CSS and JS files.
Don’t Hardcode URLs
✓ Use Laravel’s route and URL helpers to generate paths dynamically.
Don’t Use Magic Numbers
✓ Avoid using unexplained numbers in code; define them as constants with meaningful
names.
Don’t Ignore Code Formatting Standards
✓ Consistently follow a coding standard (like PSR-12) for formatting.
Don’t Overuse Globals or Static Methods
✓ Avoid excessive use of global state or static methods; they can lead to code that's hard to
test and maintain.
Don't Mix HTML and PHP
✓ Avoid mixing PHP with HTML in controllers; keep views responsible for rendering.
Don’t Allow Complex Logic in Migrations
✓ Keep logic out of migrations to prevent issues with rolling back or re-running them.
Don’t Skip Authentication and Authorization Checks
✓ Always verify user permissions and roles before performing sensitive operations.
Don’t Ignore Performance Implications
✓ Be mindful of memory and processing inefficiencies, especially in loops and database
queries.
69