7.9 KiB
7.9 KiB
Coding Conventions
Analysis Date: 2026-05-20
Naming Conventions
Files:
- Controllers: PascalCase (e.g.,
SirenController.php,AdminController.php,MapController.php)- Exception:
cctvController.phpuses lowercase — inconsistent with project convention
- Exception:
- Models: PascalCase singular (e.g.,
User.php) - Exports: PascalCase (e.g.,
WaterLevelExport.php,HourlyRainfallExport.php) - Notifications: PascalCase (e.g.,
ResetPasswordNotification.php) - Services: PascalCase (e.g.,
FcmService.php) - Middleware: PascalCase (e.g.,
AdminMiddleware.php,LocalizationMiddleware.php) - Form Requests: PascalCase (e.g.,
ProfileUpdateRequest.php,LoginRequest.php) - Migrations:
YYYY_MM_DD_HHMMSS_description_snake_case.php - Blade views:
snake_casedirectories +kebab-caseorsnake_casefiles (e.g.,layout/notification/rainfall.blade.php) - JavaScript:
camelCase.js(e.g.,homemap.js,graph.js,rfhistory.js)
Classes:
- PascalCase for all classes, following PSR-4 autoloading
- Controllers suffixed with
Controller(e.g.,RainfallController) - Exports suffixed with
Export(e.g.,HourlyRainfallExport)
Methods:
- camelCase (e.g.,
stationDisplay(),rainfallSum(),exportHistoricalWl())- Exception:
SirenHistory()uses PascalCase — inconsistent
- Exception:
- Public methods in controllers follow action naming:
index(),store(),update(),destroy(),edit()
Variables:
- camelCase for local variables (e.g.,
$stationFilter,$rainfallData,$displayDate) - camelCase for class properties (e.g.,
$stationid,$startDatein Export classes) $stationidused as one word (not$stationId) — project-specific convention
Database Tables:
- snake_case lowercase singular (e.g.,
station,rainfall,waterlevel,siren,notification,users) usersis the only plural table name
Columns:
- snake_case lowercase (e.g.,
stationid,active_time,access_level,login_attempts,is_blocked,cctv_link) - No consistent convention: some use compound words without underscore (e.g.,
stationid,waterlevel)
Code Style
Formatting:
.editorconfigpresent at both project root andsrc/- Indent: 4 spaces (no tabs, except Makefiles)
- Charset: UTF-8
- End of line: LF
- Trailing whitespace trimmed (except
.mdfiles) - YAML files: 2-space indent
- No ESLint or Prettier configured for JavaScript
Linting:
laravel/pintinstalled as dev dependency (PHP code style fixer)- No evidence of a
pint.jsonconfiguration file — using defaults - No frontend linting tools configured
Bracket Style:
- Opening braces on same line for classes and methods
- Control structures: opening brace on same line (K&R style)
- Multi-line function calls and arrays: trailing comma not consistently used
Import/Use Statement Organization:
- Laravel framework imports first
- Then third-party packages (e.g.,
Carbon,Maatwebsite\Excel,DomPDF) - Then application imports (e.g.,
App\Models\User,App\Services\FcmService) - Blank line between groups is not consistently applied
- Example from
WaterLevelController.php:use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Carbon\Carbon; // Add this for Export data to excel use App\Exports\WaterLevelExport; use Maatwebsite\Excel\Facades\Excel;
Docblock Usage:
- PHPDoc blocks present on model properties (
$fillable,$hidden,casts()) - Docblocks on factory methods and notification methods (Breeze scaffolded)
- Custom controllers use inline
//comments extensively rather than docblocks - Comment style in controllers follows a pattern:
// Function Retrieve Current Water Level Data public function index(Request $request) - Each SQL query is annotated with block comments:
// TABLE : STATION JOIN TABLE WATERLEVEL // COLUMN : name,datetime,waterlevel // INPUT : $stationCondition from resources/views/... // OUTPUT : resources/views/layout/waterlevel.blade.php
File Organization
How files are grouped:
- Controllers grouped by domain in flat structure under
app/Http/Controllers/ - API controllers in
app/Http/Controllers/Api/subdirectory - Auth controllers in
app/Http/Controllers/Auth/subdirectory (Breeze scaffolded) - Exports in
app/Exports/ - Services in
app/Services/ - Notifications in
app/Notifications/ - Views follow a
layout.{domain}naming pattern (e.g.,layout.rainfall,layout.admin.stationmgmt)
One class per file:
- Adhered to throughout — one class per file
Directory naming:
- All lowercase directories (e.g.,
Controllers/,Models/,Services/,Exports/) - Views use nested lowercase directories (e.g.,
layout/notification/history/)
Git Conventions
Branch naming:
- Only 2 commits in the repository — no discernible branch naming convention
Commit message patterns:
- Observed messages:
first commitfix: configuration docker-compose.yml
- The second commit suggests a possible
type: descriptionconvention (fix:, feat:, etc.)
Laravel-Specific Patterns
Eloquent Model Patterns:
- Only
User.phpexists as an Eloquent model (app/Models/User.php) HasFactoryandNotifiabletraits used on User$fillablearray for mass assignment (not$guarded)casts()method (Laravel 12 style) instead of$castsproperty- Custom notification override:
sendPasswordResetNotification()
Controller Patterns:
- Not resource controllers — methods are custom-named (e.g.,
stationDisplay(),userDisplay(),storeStation()) - Heavy use of raw SQL via
DB::select()andDB::table()instead of Eloquent ORM collect(DB::select(...))pattern to wrap raw SQL results into collections- Controller validation done inline with
$request->validate()— not consistently using Form Requests - Redirect pattern:
redirect()->back()->with('success', __('toast.key')) - View compact pattern:
return view('blade.path', compact('var1', 'var2'))
Form Request Usage:
ProfileUpdateRequestfor profile updates (app/Http/Requests/ProfileUpdateRequest.php)LoginRequestfor authentication (app/Http/Requests/Auth/LoginRequest.php)- Admin controller does inline
$request->validate()instead of Form Requests - Inconsistent: Form Requests exist but most validation is inline
Resource/API Resource Usage:
- Not used — API responses use
response()->json($data)directly - No API Resource classes defined
Policy Usage:
- Not used — authorization handled via custom
AdminMiddlewarecheckingaccess_level app/Http/Middleware/AdminMiddleware.phpchecksAuth::user()->access_level !== 1
Event/Listener Patterns:
- Not used — no events or listeners defined
- Notification push (FCM) is called directly from API controller
Route Patterns:
- Named routes used consistently:
->name('rainfall'),->name('stationmanagement.store') - Route grouping by middleware:
Route::middleware('auth'),Route::middleware(['admin']) - Admin routes use POST for updates (not PUT/PATCH) — non-RESTful
- API routes in
routes/api.phpwith no auth middleware
Localization:
- Bilingual: English (
en) and Bahasa Malaysia (bm) inresources/lang/ LocalizationMiddlewaresets locale via session__('key')helper used for translations in views and controllers
Middleware:
- Custom middleware registered in
bootstrap/app.php AdminMiddlewarefor admin-only routesLocalizationMiddlewarefor language switching
Export Pattern (Maatwebsite Excel):
- Export classes implement
FromCollection,WithHeadings,ShouldAutoSize - Constructor injection for filter parameters
- Raw SQL queries in
collection()method headings()method returns array of column names
PDF Export Pattern (DomPDF):
Pdf::loadView('blade.path', compact('data'))->setPaper('a4','potrait')- Note:
'potrait'is a typo — should be'portrait'(present in multiple files)
Convention analysis: 2026-05-20