Panduan alur coding — Mading Online (fullstack SMK RPL)

Memahami frontend React + backend API Express untuk majalah dinding digital sekolah: alur sistem, alur coding, dan alur folder/file. Selaras dengan kode di project Mading Online dan PERENCANAAN.md.

0 Gambaran project (tiga folder utama)

Mading Online/             ← folder project (buka di VS Code / Cursor)
├── database/                ← schema.sql + seed.sql (PostgreSQL, DB: mading)
├── backend/                 ← API Express + pg     → http://localhost:5000
└── frontend/                ← React + Vite         → http://localhost:5173
Yang dijalankanTerminalPerintahURL
Databasepsql import schema & seedPostgreSQL :5432
API1cd backend lalu npm run dev:5000
Web2cd frontend lalu npm run dev:5173

Jalankan kedua terminal (backend + frontend) — web butuh API sudah hidup dulu.

Penting: dashboard penulis/admin di browser tidak bisa mengambil data jika backend mati — akan muncul error seperti Failed to fetch atau pesan dari apiFetch.

1 Frontend ↔ Backend — mading digital (baca ini dulu)

1.1 Dua “aplikasi” terpisah

LapisanTeknologiTugas
FrontendReact (Vite) + BootstrapBeranda, list/detail post, form login/daftar, dashboard
BackendExpress + PostgreSQLAuth JWT, CRUD post, kelola penulis, kirim JSON

Browser hanya menampilkan React. React memanggil API lewat apiFetch ke http://localhost:5000/api/....

1.2 Login — dari tombol sampai dashboard

[Siswa buka http://localhost:5173/login]
        │
        ▼
Login.jsx  →  authService.login()  →  POST /api/auth/login
        │                              body: { email, password }
        ▼
authController.login  →  cek bcrypt  →  JWT + user.role ("admin" | "author")
        │
        ▼
setAuth(token, user)  →  localStorage: "token" + "user"
        │
        ▼
Navigate sesuai role:
  admin  → /dashboard/admin
  author → /dashboard/author
        │
        ▼
ProtectedRoute cek getUser().role  →  DashboardLayout (sidebar + konten)

1.3 Satu halaman = React + endpoint API

Contoh panel penulis menulis post (/dashboard/author/post/tambah):

Di browser (frontend)Di server (backend)
FormPost.jsx — form judul, ringkasan, isi, rubrik, gambarPOST /api/post (multipart, field gambar)
Dashboard penulis — daftar post milik sendiriGET /api/post/mine
Edit postPUT /api/post/:id
Hapus postDELETE /api/post/:id

Semua request yang butuh login memakai header:

Authorization: Bearer <token dari localStorage>

Diatur otomatis di frontend/src/services/api.js (apiFetch).

1.4 Peta URL frontend ↔ API backend

Area / halamanFile halamanAPI utama
Berandapages/public/Home.jsxGET /api/post?limit=...
List Post (+ filter rubrik)ListPost.jsxGET /api/post?kategori=...
Detail PostDetailPost.jsxGET /api/post/:id
Daftar / LoginDaftar.jsx, Login.jsxPOST /api/auth/register, /login
Dashboard Penulisauthor/Dashboard.jsxGET /api/post/mine
Tulis / Edit Postauthor/FormPost.jsxCRUD /api/post
Dashboard Adminadmin/Dashboard.jsxagregat dari list users + post
Kelola Post (admin)admin/ListPost.jsx, dll./api/admin/post
Kelola Penulisadmin/ListUser.jsx, dll./api/admin/users
Profildashboard/Profil.jsxGET/PUT /api/auth/me

Routing: frontend/src/routes/index.jsx. Pemanggilan API: services/authService.js + services/postService.js.

1.5 Komponen frontend yang dipakai ulang

FileFungsi
components/layout/PublicLayout.jsxNavbar + footer beranda / list / detail
components/layout/DashboardLayout.jsxSidebar + area konten panel
components/auth/ProtectedRoute.jsxBlokir jika belum login / role salah
components/post/PostTable.jsxTabel daftar post di dashboard
components/ConfirmModal.jsxKonfirmasi hapus
constants/site.jsNama web, rubrik, branding hardcode
services/api.jsapiFetch, token, imageUrl

Alur CRUD post penulis:

  1. getMyPosts() → tabel di Dashboard.
  2. Tulis PostFormPostcreatePost(FormData).
  3. EditFormPost + updatePost(id, FormData).
  4. HapusConfirmModaldeletePost(id) → reload daftar.

2 Alur sistem (besar — siapa ngapain)

2.1 Diagram umum fullstack

┌─────────────┐     HTTP (JSON)      ┌─────────────┐     SQL      ┌────────────┐
│   Browser   │ ◄──────────────────► │   Backend   │ ◄──────────► │ PostgreSQL │
│  React Vite │   localhost:5000     │   Express   │              │ DB: mading │
│    :5173    │                      │             │              │            │
└─────────────┘                      └─────────────┘              └────────────┘

2.2 Tiga “pengguna” sistem

PenggunaFrontendBackendKeterangan
Pengunjung/, /post, /post/:idGET /api/post, GET /api/post/:idTanpa login
Penulis/daftar, /login/dashboard/author/*/api/auth/*, /api/post (CRUD milik sendiri)JWT role author
Admin/login/dashboard/admin/*/api/admin/...JWT role admin (dari seed)

2.3 Empat rubrik majalah dinding

Rubrik (kategori)Arti di mading sekolah
Berita SekolahKegiatan, event, info sekolah
ArtikelTulisan / opini / edukasi (default)
KreatifPuisi, cerpen, karya kreatif
PrestasiJuara, penghargaan

Filter di UI: link ke /post?kategori=...tidak ada route /kategori/:slug.

2.4 Alur admin mengelola mading

  1. Buat DB + import: database/schema.sql, database/seed.sql.
  2. Isi backend/.env (salin dari .env.example).
  3. Terminal 1: cd backendnpm run dev. Terminal 2: cd frontendnpm run dev.
  4. Login di /login dengan akun seed admin.
  5. Dashboard → lihat ringkasan penulis & post.
  6. Kelola: semua post (CRUD), data penulis (edit/hapus), profil sendiri.

2.5 Alur penulis (singkat)

  1. Daftar di /daftar (nama, email, kelas, jurusan, password) → role author.
  2. Login → redirect /dashboard/author.
  3. Tulis post → upload gambar opsional → muncul di beranda/list publik.
  4. Edit / hapus hanya post milik sendiri (/api/post/mine + CRUD).

3 Alur coding (satu request masuk sampai keluar)

3.1 Backend — urutan eksekusi (MVC API)

Browser / React (apiFetch)
    → server.js                 (Express, CORS, JSON body, static /uploads)
    → routes/auth|post|admin    (cocokkan URL + method)
    → middlewares/              (authMiddleware, loadUser, requireRole, multer)
    → controllers/              (validasi, aturan bisnis, status HTTP)
    → models/                   (query SQL parameterized)
    → config/db.js              (pool PostgreSQL / pg)
    → respons JSON { success, message, data? } balik ke React

Kenapa urutannya begitu? Route = peta URL, controller = logika, model = data. Ganti query cukup sentuh models/.

3.2 Frontend — urutan eksekusi

Halaman (mis. ListPost.jsx / FormPost.jsx)
    → postService.getPosts() / createPost()
    → api.js apiFetch()          (tambah Bearer token, base URL + /api)
    → fetch → backend
    → setState → render UI
    → komponen (PostTable, ConfirmModal, …)

Konfigurasi: frontend/.envVITE_API_URL=http://localhost:5000 (tanpa /api di akhir; path /api ditambah di apiFetch).

3.3 Contoh: penulis klik “Hapus post”

LangkahLapisanApa yang terjadi
1UIConfirmModal → konfirmasi
2postService.jsDELETE /api/post/5 + Bearer
3routes/postRoutes.js→ middleware auth + role author → postController.remove
4MiddlewareCek JWT + role === author
5ControllerPastikan post milik user login, hapus file gambar jika ada
6ModelDELETE FROM posting WHERE id = $1 (milik author)
7UIReload daftar getMyPosts()
Admin hapus post: alurnya sama, tetapi lewat DELETE /api/admin/post/:idadminPostController (boleh hapus post siapa saja).

4 Alur folder & file (mulai baca dari mana)

4.1 Pohon folder backend

backend/
├── server.js                      ← ① PINTU MASUK
├── .env                           ← ② PORT, JWT_SECRET, DB_*, FRONTEND_URL
├── config/db.js                   ← ③ pool PostgreSQL
├── routes/authRoutes.js           ← ④ /api/auth
├── routes/postRoutes.js           ← ⑤ /api/post
├── routes/adminRoutes.js          ← ⑥ /api/admin
├── middlewares/authMiddleware.js  ← JWT, loadUser, requireRole
├── middlewares/uploadMiddleware.js← multer → uploads/post/
├── controllers/                   ← logika + JSON
├── models/userModel.js, postModel.js
├── utils/response.js, helpers.js, fileHelper.js
└── uploads/post/

4.2 Pohon folder frontend

frontend/src/
├── main.jsx, App.jsx              ← ①② mount + AppRoutes
├── routes/index.jsx               ← ③ semua <Route>
├── services/api.js                ← ④ apiFetch + token
├── services/authService.js, postService.js
├── components/layout/, auth/, post/
├── pages/public/                  ← beranda, list, detail, login, daftar
├── pages/dashboard/author/        ← panel penulis
├── pages/dashboard/admin/         ← panel admin
└── constants/site.js              ← branding & rubrik

4.3 Urutan belajar (siswa)

UrutanBaca / kerjakanKenapa
1Import DB + jalankan backend & frontend + buka berandaPahami hasil dulu
2routes/index.jsx + Home.jsx + ListPost.jsxURL browser ↔ API publik
3api.js + postService.js + authService.jsCara React memanggil backend
4routes/postRoutes.js + authRoutes.jsDaftar endpoint
5postController.js + authController.jsLogika setelah request masuk
6postModel.js + userModel.jsSQL & tabel posting / users
7server.js + authMiddleware.jsServer menyambungkan semuanya
8Panel author lalu admin — bandingkan /api/post vs /api/adminPahami beda hak akses

4.4 Peran folder vs MVC

FolderPeranCatatan
routes/RoutingURL → middleware → controller
controllers/ControllerValidasi + JSON
models/ModelSQL dengan $1, $2, … (pg)
middlewares/FilterAuth, role, upload
config/InfrastrukturKoneksi DB, bukan bisnis mading

View HTML tidak ada di API — tampilan ada di React, backend hanya JSON.

5 Ringkasan endpoint

Base: http://localhost:5000/api

5.1 Auth — /api/auth

MethodPathAuthFungsi
POST/registerTidakDaftar penulis (role dipaksa author)
POST/loginTidakLogin → JWT + data user
GET/meBearerProfil user login
PUT/meBearerUpdate profil sendiri

5.2 Post — /api/post

MethodPathAuthFungsi
GET/TidakDaftar post (?kategori=&limit=&offset=)
GET/:idTidakDetail post
GET/mineBearer authorPost milik penulis login
POST/Bearer authorBuat post (+ upload gambar)
PUT/:idBearer authorUpdate post milik sendiri
DELETE/:idBearer authorHapus post milik sendiri

5.3 Admin — /api/admin

Semua route di bawah router.use(authMiddleware, loadUserMiddleware, requireRole("admin")).

MethodPathFungsi
GET/usersDaftar penulis
GET/PUT/DELETE/users/:idDetail / ubah / hapus penulis
GET/POST/postDaftar / tambah post (semua)
GET/PUT/DELETE/post/:idDetail / ubah / hapus post mana pun

6 Hak akses (matriks singkat)

AksiPublikPenulisAdmin
Baca postyayaya
Daftar akunya → author
Create / update / delete postmilik sendirisemua post
Kelola penulisya
Update profil sendiriyaya
Keamanan: role tidak diubah lewat UI/API. Admin hanya dari seed. SQL selalu parameterized. Upload gambar maks sesuai UPLOAD_MAX_MB (default 2 MB).

7 File SQL & database

FileFungsi
database/schema.sqlEnum role & rubrik, tabel users + posting
database/seed.sqlAdmin + penulis contoh + post contoh mading
database/dbdiagram.sqlReferensi diagram relasi (opsional)
# Contoh setup (Windows / PowerShell sesuaikan path)
psql -U postgres -c "CREATE DATABASE mading;"
psql -U postgres -d mading -f database/schema.sql
psql -U postgres -d mading -f database/seed.sql

Akun seed lab: admin admin@sekolah.sch.id / Admin123! — ganti di produksi.

Nama file model: postModel.js. Nama tabel di DB: posting.

8 Upload gambar post

TopikNilai
Folder penyimpananbackend/uploads/post/
Akses filehttp://localhost:5000/uploads/post/<namafile>
Author uploadPOST/PUT /api/post (field form gambar)
Admin uploadPOST/PUT /api/admin/post (field yang sama)
MiddlewareuploadMiddleware.jsuploadPost.single("gambar")
Path di DBBentuk /uploads/post/...
Tampil di ReactimageUrl(path) di api.js (+ placeholder jika kosong)

9 Ringkasan satu kalimat

Mading Online: React di :5173 menampilkan beranda & dashboard, lalu memanggil JSON API di :5000/api (/auth, /post, /admin) dengan JWT sesuai role.

Backend: setiap request mengalir server.jsroutesmiddlewarescontrollersmodels → PostgreSQL, lalu balik sebagai JSON ke React.