Lewati ke konten utama

BAB 58. CODING STANDARDS

Tujuan

Standar pengkodean memastikan kode konsisten, mudah dibaca, dan mudah dipelihara oleh seluruh anggota tim — baik sekarang maupun di masa depan.


Laravel — PSR-12

Backend TemuBelajar mengikuti standar PSR-12 (PHP Standard Recommendation) untuk konsistensi kode PHP.

Konvensi Penamaan

ItemConventionContoh
ClassPascalCaseRequestService
MethodcamelCasecreateRequest()
VariablecamelCase$studentId
ConstantUPPER_SNAKE_CASEMAX_ACTIVE_REQUESTS
Table DBsnake_case (plural)meeting_participants
Column DBsnake_casecreated_at, school_id
Route namekebab-caserequests.check-in
FilePascalCaseRequestController.php

Aturan Controller

// ✅ Controller yang benar — Thin Controller
class RequestController extends Controller
{
public function __construct(private RequestService $service) {}

public function store(CreateRequestRequest $request): JsonResponse
{
$dto = CreateRequestDTO::fromRequest($request);
$result = $this->service->createRequest($dto);
return RequestResource::make($result)->response()->setStatusCode(201);
}
}

// ❌ Anti-pattern — Fat Controller
class RequestController extends Controller
{
public function store(Request $request): JsonResponse
{
// Business logic TIDAK boleh di sini!
$student = Student::find($request->student_id);
if ($student->activeRequests()->count() >= 3) { ... }
// ... 100 baris logika bisnis
}
}

Aturan Service

  • Satu Service = satu tanggung jawab
  • Maksimal 200 baris per class (jika lebih, pecah jadi sub-service)
  • Setiap method harus dapat diuji secara unit

Aturan Repository

  • Tidak mengandung business rule
  • Hanya berisi query database
  • Semua query menggunakan Eloquent atau Query Builder (tidak ada raw SQL kecuali kasus khusus)

Flutter — Effective Dart

Frontend Flutter mengikuti Effective Dart guidelines.

Konvensi Penamaan

ItemConventionContoh
ClassPascalCaseRequestPage
WidgetPascalCaseBookingCard
ProvidercamelCase + suffixrequestListProvider
Filesnake_caserequest_page.dart
VariablecamelCasestudentId
ConstantlowerCamelCasemaxActiveRequests
Private_ prefix_controller

Aturan Widget

// ✅ Baik — Gunakan const, satu tanggung jawab
class BookingCard extends StatelessWidget {
const BookingCard({super.key, required this.booking});

final BookingEntity booking;


Widget build(BuildContext context) {
return Card(
child: Column(
children: [
Text(booking.subjectName),
Text(booking.tutorName),
],
),
);
}
}

// ✅ Baik — Satu file, satu widget utama
// request_card.dart → class RequestCard
// request_list_page.dart → class RequestListPage

Aturan File

  • Satu widget utama per file
  • File pages di presentation/pages/
  • File widgets di presentation/widgets/
  • File providers di providers/
  • Hindari BuildContext di business logic (use case, repository)

Komentar & Dokumentasi

/**
* Membuat request bantuan belajar baru.
*
* @param CreateRequestDTO $dto Data request yang sudah divalidasi
* @return Request Model request yang berhasil dibuat
* @throws MaxActiveRequestsException Jika siswa memiliki 3+ request aktif
*/
public function createRequest(CreateRequestDTO $dto): Request
/// Widget untuk menampilkan kartu booking.
///
/// Menampilkan nama tutor, mata pelajaran, jadwal, dan status booking.
class BookingCard extends StatelessWidget { ... }

Code Review Checklist

  • Tidak ada business logic di Controller
  • Ada unit test untuk logika baru
  • Tidak ada N+1 query
  • Cache digunakan untuk data yang sering diakses
  • Nama variabel/method deskriptif
  • Tidak ada print() atau dd() tertinggal
  • Semua input divalidasi
  • Error ditangani dengan tepat