Dalam dunia pengembangan perangkat lunak, teori tanpa praktik ibarat peta tanpa kompas. Artikel sebelumnya telah membahas konsep BRD, PRD, dan ERD secara umum. Kali ini, kita akan membedah sebuah aplikasi nyata — MyBlog — sebuah CMS (Content Management System) yang dibangun dengan Laravel 12, untuk melihat bagaimana ketiga dokumen tersebut terwujud dalam kode yang sesungguhnya.
Sekilas Tentang MyBlog
MyBlog adalah platform all-in-one untuk blogging, portfolio, dan company profile. Aplikasi ini dibangun menggunakan arsitektur MVC (Model-View-Controller) dengan spesifikasi sebagai berikut:
| Aspek |
Detail |
| Framework |
Laravel 12 |
| PHP Version |
≥ 8.2 |
| Frontend Build |
Vite + Blade Templates |
| Database |
MySQL (dengan fallback SQLite) |
| Storage Eksternal |
Google Drive |
| Total Models |
6 model |
| Total Controllers |
14 controller |
| Total Routes |
30+ endpoint |
Aplikasi ini memiliki dua sisi utama: sisi publik (untuk pengunjung/pembaca) dan sisi admin (untuk pengelola konten), dilengkapi dengan dashboard analytics, backup database ke Google Drive, dan SEO bawaan.
Anatomi Struktur Aplikasi
Sebelum masuk ke analisis BRD, PRD, dan ERD, mari kita pahami dulu anatomi tubuh aplikasi ini:
6 Model (Organ Utama)
- User — Pengguna/admin yang mengelola konten
- Article — Artikel/tulisan blog dengan status draft/published
- Category — Kategori pengelompokan artikel
- Portfolio — Proyek/karya yang ditampilkan
- Setting — Konfigurasi dinamis situs (key-value store dengan caching)
- ContactMessage — Pesan dari pengunjung melalui form kontak
14 Controller (Sistem Saraf)
Controller dibagi menjadi dua kelompok:
- Public (5 controller): HomeController, ArticleController, PortfolioController, SitemapController, dan base Controller
- Admin (9 controller): DashboardController, ArticleController, CategoryController, PortfolioController, SettingController, ContactController, AuthController, ProfileController, dan BackupController
Arsitektur Route (Peredaran Darah)
Route dibagi menjadi 3 grup besar:
- Public Routes — Tanpa autentikasi (homepage, about, contact, articles, portfolio, sitemap)
- Admin Auth Routes — Login dan logout
- Admin Protected Routes — Dilindungi middleware
auth (dashboard, CRUD konten, settings, backup)
BAGIAN 1: BRD — Business Requirements Document
Fokus: "Mengapa MyBlog dibangun?"
1.1 Latar Belakang
MyBlog dikembangkan sebagai platform CMS pribadi yang menggabungkan fungsi blog, company profile, dan portfolio. Aplikasi ini menjawab kebutuhan individu atau organisasi kecil yang ingin memiliki kehadiran digital profesional tanpa overhead CMS besar seperti WordPress.
1.2 Tujuan Bisnis
| Kode |
Tujuan |
Deskripsi |
| B1 |
Kehadiran Digital |
Menyediakan website profesional untuk branding personal/organisasi |
| B2 |
Knowledge Sharing |
Mempublikasikan artikel untuk berbagi pengetahuan |
| B3 |
Portfolio Showcase |
Menampilkan proyek dan karya yang telah diselesaikan |
| B4 |
Lead Generation |
Menerima pesan dari calon klien melalui contact form |
| B5 |
Content Control |
Memberikan kontrol penuh atas konten yang dipublikasikan |
| B6 |
Data Safety |
Menjamin keamanan data melalui backup ke Google Drive |
1.3 Stakeholder
| Stakeholder |
Peran |
Kepentingan Utama |
| Admin/Pemilik |
Mengelola seluruh konten dan pengaturan |
Kemudahan pengelolaan, analytics performa |
| Pengunjung/Pembaca |
Membaca artikel, melihat portfolio |
Pengalaman membaca yang baik, navigasi mudah |
| Calon Klien |
Melihat portfolio, mengirim pesan |
Informasi proyek lengkap, kontak mudah |
1.4 Ruang Lingkup (Scope)
Yang Termasuk (In-Scope):
- Manajemen artikel (CRUD) dengan kategori dan status publish/draft
- Manajemen portfolio dengan detail proyek lengkap
- Pengaturan situs dinamis (nama, tagline, sosial media, kontak)
- Contact form dengan manajemen pesan masuk
- Dashboard admin dengan analytics dan chart
- Autentikasi admin (login/logout) dan profil
- Backup database ke Google Drive
- SEO (XML Sitemap, slug URL)
Yang Tidak Termasuk (Out-of-Scope):
- Multi-user role management (hanya 1 level admin)
- Komentar pada artikel
- Registrasi pengguna publik
- E-commerce / pembayaran
- Newsletter / email marketing
- Multi-bahasa (i18n)
- API REST/GraphQL untuk integrasi eksternal
1.5 Business Rules
| Kode |
Aturan Bisnis |
| BR-01 |
Artikel hanya tampil di publik jika berstatus published dan published_at ≤ waktu sekarang |
| BR-02 |
Slug artikel, kategori, dan portfolio harus unik (digunakan sebagai URL identifier) |
| BR-03 |
Setiap artikel dimiliki oleh satu user dan dapat memiliki satu kategori |
| BR-04 |
Portfolio dapat ditandai sebagai featured dan memiliki urutan custom |
| BR-05 |
Pesan kontak memiliki status is_read untuk tracking |
| BR-06 |
Settings menggunakan caching 1 jam untuk performa optimal |
| BR-07 |
Upload gambar dibatasi: jpeg, png, jpg, gif, webp, maksimal 2MB |
| BR-08 |
Password admin minimal 8 karakter |
| BR-09 |
Backup database disimpan di Google Drive dengan format backup_YYYY-MM-DD_HH-mm-ss.sql |
| BR-10 |
URL yang tidak dikenali akan di-redirect ke homepage (fallback route) |
1.6 KPI (Key Performance Indicators)
Dashboard admin MyBlog menyediakan beberapa metrik KPI yang langsung terukur:
- Jumlah Artikel Terpublikasi — Mengukur produktivitas konten
- Total Views — Mengukur jangkauan pembaca
- Pesan Masuk (Unread) — Mengukur engagement pengunjung
- Top 5 Artikel — Mengidentifikasi konten paling populer
- Tren Publikasi Bulanan — Memantau konsistensi penerbitan
BAGIAN 2: PRD — Product Requirements Document
Fokus: "Apa yang dibangun di MyBlog?"
2.1 User Personas
Persona 1: Admin (Penulis/Pemilik)
- Deskripsi: Individu yang mengelola website pribadinya
- Goals: Menulis artikel, menampilkan portfolio, memantau performa konten
- Pain Points: Butuh CMS simpel tanpa overhead WordPress
Persona 2: Pengunjung (Pembaca)
- Deskripsi: Pembaca yang mengakses website untuk membaca artikel
- Goals: Membaca konten informatif, menemukan artikel berdasarkan kategori
- Pain Points: Loading lambat, navigasi rumit
Persona 3: Calon Klien
- Deskripsi: Orang yang tertarik dengan jasa/keahlian pemilik
- Goals: Melihat portfolio proyek, menghubungi pemilik
- Pain Points: Informasi portfolio sulit ditemukan
2.2 Daftar Fitur Lengkap
F-01: Halaman Publik
| Sub-Fitur |
Deskripsi |
Prioritas |
| Homepage |
Menampilkan 5 artikel terbaru yang sudah dipublikasi |
P0 |
| About Page |
Halaman tentang pemilik (konten dari settings) |
P0 |
| Contact Page |
Form kontak dengan validasi (nama, email, subjek, pesan) |
P0 |
F-02: Manajemen Artikel
| Sub-Fitur |
Deskripsi |
Prioritas |
| Create Artikel |
Form: judul, kategori, excerpt, konten, featured image, status |
P0 |
| Edit Artikel |
Edit semua field, replace featured image otomatis |
P0 |
| Delete Artikel |
Hapus artikel beserta featured image dari storage |
P0 |
| List Artikel |
Tabel dengan pagination (10/halaman) |
P0 |
| Status Draft/Published |
Auto-set published_at saat pertama kali dipublish |
P0 |
| View Counter |
Increment otomatis setiap artikel dibuka |
P1 |
| Related Articles |
Tampilkan 3 artikel terkait berdasarkan kategori |
P1 |
| Filter by Category |
Filter artikel berdasarkan kategori |
P1 |
F-03: Manajemen Kategori
| Sub-Fitur |
Deskripsi |
Prioritas |
| CRUD Kategori |
Create, Read, Update, Delete kategori |
P0 |
| Auto Slug |
Slug otomatis dari nama kategori |
P0 |
| Article Count |
Jumlah artikel per kategori pada halaman publik |
P1 |
F-04: Manajemen Portfolio
| Sub-Fitur |
Deskripsi |
Prioritas |
| CRUD Portfolio |
Create, Read, Update, Delete portfolio |
P0 |
| Detail Proyek |
Judul, deskripsi, konten, klien, URL, teknologi, tanggal selesai |
P0 |
| Featured Flag |
Tandai portfolio sebagai unggulan |
P1 |
| Custom Order |
Urutan tampilan portfolio bisa diatur manual |
P1 |
| Technologies (JSON) |
Array JSON untuk daftar teknologi yang digunakan |
P1 |
F-05: Contact Message Management
| Sub-Fitur |
Deskripsi |
Prioritas |
| Terima Pesan |
Simpan pesan dari form kontak publik |
P0 |
| List Pesan |
Daftar pesan dengan pagination + jumlah unread |
P0 |
| Baca Pesan |
Detail pesan, auto-mark as read saat dibuka |
P0 |
| Hapus Pesan |
Hapus pesan kontak |
P1 |
F-06: Admin Dashboard & Analytics
| Sub-Fitur |
Deskripsi |
Prioritas |
| Statistics Cards |
Total artikel, published, draft, views, kategori, portfolio, users, unread messages |
P0 |
| Chart: Artikel/Bulan |
Bar chart produksi artikel 12 bulan terakhir |
P1 |
| Chart: Artikel/Kategori |
Distribusi artikel per kategori |
P1 |
| Chart: Top 5 Artikel |
5 artikel dengan views terbanyak |
P1 |
| Publication Calendar |
Kalender visualisasi tanggal publikasi |
P2 |
F-07: Autentikasi & Profil Admin
| Sub-Fitur |
Deskripsi |
Prioritas |
| Login |
Autentikasi email & password dengan remember me |
P0 |
| Logout |
Session invalidation & token regeneration |
P0 |
| Edit Profil |
Update nama dan email admin |
P1 |
| Ganti Password |
Verifikasi password lama, konfirmasi password baru |
P1 |
F-08: Pengaturan Situs
| Sub-Fitur |
Deskripsi |
Prioritas |
| Identitas Situs |
Nama situs, tagline, deskripsi |
P0 |
| Info Kontak |
Email, telepon, alamat |
P1 |
| Media Sosial |
Facebook, Twitter, Instagram, TikTok, GitHub |
P1 |
| About Content |
Profil singkat dan profil lengkap (digunakan di halaman About) |
P1 |
F-09: Backup Database
| Sub-Fitur |
Deskripsi |
Prioritas |
| Create Backup |
Dump database MySQL lalu upload ke Google Drive |
P1 |
| List Backup |
Daftar file backup (nama, ukuran, tanggal) |
P1 |
| Download Backup |
Download file backup dari Google Drive |
P1 |
| PHP Fallback |
Dump via PHP jika mysqldump binary tidak tersedia |
P1 |
F-10: SEO
| Sub-Fitur |
Deskripsi |
Prioritas |
| XML Sitemap |
Auto-generate dari artikel dan kategori |
P1 |
| SEO Friendly URLs |
Slug-based URL untuk semua konten |
P0 |
| Fallback Route |
Redirect URL tidak dikenali ke homepage |
P2 |
2.3 Non-Functional Requirements
| Aspek |
Implementasi di MyBlog |
| Performance |
Settings di-cache 1 jam; Eager loading relasi (with()) mencegah N+1 query problem |
| Security |
Password hashing otomatis; Session regeneration saat login/logout; CSRF protection bawaan Laravel; Validasi input semua form |
| Scalability |
Arsitektur MVC standar; Key-value settings memungkinkan penambahan konfigurasi tanpa migrasi database |
| File Storage |
Featured images di storage/app/public/articles; Max upload 2MB; Format: jpeg, png, jpg, gif, webp |
BAGIAN 3: ERD — Entity Relationship Diagram
Fokus: "Bagaimana data MyBlog disimpan dan saling berhubungan?"
Berikut adalah analisis ERD yang langsung diekstrak dari migration files di source code MyBlog. Total ada 6 tabel custom + 6 tabel sistem Laravel.
3.1 Entitas dan Atribut
Tabel users
| Kolom |
Tipe |
Constraint |
Keterangan |
id |
BIGINT |
PK, Auto Increment |
Primary Key |
name |
VARCHAR(255) |
NOT NULL |
Nama pengguna |
email |
VARCHAR(255) |
NOT NULL, UNIQUE |
Email unik |
email_verified_at |
TIMESTAMP |
NULL |
Verifikasi email |
password |
VARCHAR(255) |
NOT NULL |
Hashed otomatis |
is_admin |
BOOLEAN |
DEFAULT false |
Penanda admin |
remember_token |
VARCHAR(100) |
NULL |
Remember me token |
Tabel categories
| Kolom |
Tipe |
Constraint |
Keterangan |
id |
BIGINT |
PK, Auto Increment |
Primary Key |
name |
VARCHAR(255) |
NOT NULL |
Nama kategori |
slug |
VARCHAR(255) |
UNIQUE |
URL-friendly identifier |
description |
TEXT |
NULL |
Deskripsi kategori |
Tabel articles
| Kolom |
Tipe |
Constraint |
Keterangan |
id |
BIGINT |
PK, Auto Increment |
Primary Key |
user_id |
BIGINT |
FK → users.id, CASCADE |
Penulis artikel |
category_id |
BIGINT |
FK → categories.id, SET NULL, NULL |
Kategori artikel |
title |
VARCHAR(255) |
NOT NULL |
Judul artikel |
slug |
VARCHAR(255) |
UNIQUE |
URL slug |
excerpt |
TEXT |
NULL |
Ringkasan singkat |
content |
LONGTEXT |
NOT NULL |
Konten HTML |
featured_image |
VARCHAR(255) |
NULL |
Path gambar |
status |
ENUM |
draft/published, DEFAULT draft |
Status publikasi |
published_at |
TIMESTAMP |
NULL |
Tanggal publikasi |
views |
INTEGER |
DEFAULT 0 |
Jumlah views |
Tabel portfolios
| Kolom |
Tipe |
Constraint |
Keterangan |
id |
BIGINT |
PK, Auto Increment |
Primary Key |
title |
VARCHAR(255) |
NOT NULL |
Judul proyek |
slug |
VARCHAR(255) |
UNIQUE |
URL slug |
description |
TEXT |
NOT NULL |
Deskripsi singkat |
content |
LONGTEXT |
NULL |
Detail proyek |
featured_image |
VARCHAR(255) |
NULL |
Gambar utama |
client_name |
VARCHAR(255) |
NULL |
Nama klien |
project_url |
VARCHAR(255) |
NULL |
Link proyek |
technologies |
JSON |
NULL |
Array teknologi |
completed_at |
DATE |
NULL |
Tanggal selesai |
is_featured |
BOOLEAN |
DEFAULT false |
Proyek unggulan |
order |
INTEGER |
DEFAULT 0 |
Urutan tampilan |
Tabel settings
| Kolom |
Tipe |
Constraint |
Keterangan |
id |
BIGINT |
PK, Auto Increment |
Primary Key |
key |
VARCHAR(255) |
UNIQUE |
Identifier setting |
value |
TEXT |
NULL |
Nilai setting |
Tabel contact_messages
| Kolom |
Tipe |
Constraint |
Keterangan |
id |
BIGINT |
PK, Auto Increment |
Primary Key |
name |
VARCHAR(255) |
NOT NULL |
Nama pengirim |
email |
VARCHAR(255) |
NOT NULL |
Email pengirim |
subject |
VARCHAR(255) |
NOT NULL |
Subjek pesan |
message |
TEXT |
NOT NULL |
Isi pesan |
is_read |
BOOLEAN |
DEFAULT false |
Status sudah dibaca |
3.2 Relasi Antar Entitas
| Relasi |
Tipe |
Keterangan |
| Users → Articles |
One-to-Many (1:N) |
Satu user menulis banyak artikel. ON DELETE CASCADE — hapus user = hapus semua artikelnya |
| Categories → Articles |
One-to-Many (1:N) |
Satu kategori memiliki banyak artikel. ON DELETE SET NULL — hapus kategori = artikel tetap ada, category_id jadi NULL |
| Portfolios |
Standalone |
Tidak memiliki relasi FK ke tabel lain |
| Settings |
Standalone |
Key-value store independen |
| Contact Messages |
Standalone |
Tabel independen untuk pesan pengunjung |
3.3 Desain Khusus yang Menarik
- Cascade vs Set Null: Perhatikan perbedaan strategi ON DELETE — artikel dihapus saat user dihapus (cascade), tapi artikel dipertahankan saat kategori dihapus (set null). Ini menunjukkan bahwa konten artikel lebih berharga daripada pengelompokan kategorinya.
- JSON Column: Kolom
technologies pada tabel portfolios menggunakan tipe JSON, memungkinkan penyimpanan array fleksibel tanpa tabel relasi terpisah.
- Key-Value Pattern: Tabel
settings menggunakan pola key-value store dengan caching, sehingga penambahan konfigurasi baru tidak memerlukan migrasi database.
- Soft Status: Artikel menggunakan ENUM
draft/published dikombinasikan dengan published_at timestamp, memberikan kontrol publikasi yang presisi — bahkan bisa dijadwalkan untuk publish di masa depan.
Kesimpulan
Melalui studi kasus MyBlog, kita bisa melihat bagaimana BRD, PRD, dan ERD bukan hanya dokumen teoritis, melainkan benar-benar tercermin dalam setiap baris kode aplikasi:
- BRD menjawab "mengapa" — kebutuhan branding digital, knowledge sharing, dan lead generation terwujud dalam fitur homepage, blog, portfolio, dan contact form.
- PRD menjawab "apa" — 10 fitur utama dengan 40+ sub-fitur terperinci, mulai dari CRUD konten hingga backup database, semuanya terimplementasi dalam 14 controller.
- ERD menjawab "bagaimana" — 6 tabel database dengan relasi yang terencana, constraint yang tepat, dan desain yang mempertimbangkan integritas data jangka panjang.
Dengan memahami ketiga lapisan ini secara bersamaan, kita tidak hanya belajar membuat aplikasi, tetapi juga belajar merancang aplikasi yang benar — dari visi bisnis hingga struktur data yang kokoh.