Codebase dazoapp dikerjakan turun-temurun tanpa standar koding dan tanpa code review. Pola yang ada bukan keputusan desain — jangan ditiru secara otomatis. Tapi yang dominan aman diikuti.
Backend
| Aspek | Pola dominan | Pemakaian |
|---|---|---|
| Response API | response()->json() | 1.028 hit |
| Response halaman | Inertia::render() | 124 hit |
| Ambil user | auth()->user() | 416 hit |
| (hindari) | Auth::user() | 33 hit |
| Business logic | Mayoritas di controller | 9 service tidak konsisten dipakai |
| Helper global | app/Helpers/helpers.php | autoload via composer.json "files" |
Response API
// BENAR — pola dominan
return response()->json([
'status' => true,
'data' => $order,
'message' => 'Order created',
], 201);
// BENAR — untuk halaman
return Inertia::render('Order/Show', [
'order' => $order,
]);Untuk fitur baru — tulis di service
Controller sudah bengkak (OrderController.php 2.987 baris, ContactController.php 2.403, ProductController.php 2.017). Tulis logic baru di app/Services/, bukan di controller.
Ada 9 service yang sudah ada:
| Service | Baris | Fungsi |
|---|---|---|
DigitalStoreService.php | 1.750 | Digital store + checkout |
WalletService.php | 352 | Wallet, balance, transaksi |
RegistrationLinkService.php | 559 | Registration link + tracking |
DokuApiService.php | 290 | DOKU API wrapper |
DigitalProductService.php | 269 | Pengiriman produk digital |
AuthService.php | 217 | Auth + OTP |
GeoIPService.php | 313 | Geolokasi IP |
DeviceService.php | 31 | Helper device |
TurnstileService.php | 19 | Cloudflare Turnstile |
Frontend
| Aspek | Pola dominan | Pemakaian |
|---|---|---|
| Vue API | <script setup> | 144 dari 234 halaman |
| Form/navigasi | Inertia useForm | 86 file |
| API call luar Inertia | axios langsung | 42 file |
| (sebaiknya) | services/axiosInstance.js | 1 file |
| State | Pinia (sidebarStore.js) | — |
| (legacy) | Vuex | 4 file (theme customizer) |
| Alias | @/ → resources/js | lihat vite.config.js |
Untuk kode Vue baru
<script setup>
import { useForm } from '@inertiajs/vue3'
import { Head, Link } from '@inertiajs/vue3'
const form = useForm({
name: '',
email: '',
})
const submit = () => form.post('/api/contact', {
preserveScroll: true,
})
</script>
<template>
<form @submit.prevent="submit">
<!-- ... -->
</form>
</template>API call di luar Inertia
Pakai services/axiosInstance.js — sudah menangani JWT + refresh otomatis:
import axiosInstance from '@/services/axiosInstance'
const { data } = await axiosInstance.get('/api/orders')Penamaan
Campur aduk — ini kondisi nyata, bukan standar yang harus ditiru:
| Gaya | Contoh | Lokasi |
|---|---|---|
| PascalCase | Components/, Modal.vue | Komponen (dominan) |
| kebab-case | nav-bar.vue, nav-bar-livechat.vue | Layout (warisan) |
| camelCase | followupLiveChat.vue | Sebagian Pages |
Typo yang terlanjur dipakai
Jangan perbaiki tanpa diminta — akan memecah import:
Toltip.vue(harusnya Tooltip)AccordionGrup.vue(harusnya AccordionGroup)ContentSyarat&Ketentuan.vue— ada&di nama file
Untuk file baru
- Komponen:
PascalCase.vue - Util:
camelCase.js - Halaman:
PascalCase.vue
Bahasa
Komentar, variabel, dan commit bercampur Indonesia/Inggris.
- Balas user dalam Bahasa Indonesia
- Untuk kode, ikuti bahasa file yang sedang diedit
- Jangan mengganti bahasa komentar yang sudah ada
God component — hati-hati
| Baris | File |
|---|---|
| 9.668 | resources/js/Pages/Order/Main.vue |
| 5.681 | resources/js/Pages/LiveChat/Index.vue |
| 4.692 | resources/js/Pages/Product/CreateEdit.vue |
| 4.438 | resources/js/Pages/DigitalStore/Index.vue |
| 4.367 | resources/js/Pages/DigitalStore/StorePreview.vue |
Komponen kembar — cek dulu sebelum buat
Pola duplikasi yang ada:
| Jenis | Varian yang ada |
|---|---|
| Modal | Modal, ModalComponent, ModalDefault, AlertModal, ConfirmsModal, ConfirmsModalBot |
| Loader | Loader, Loading, ContentLoader, ContentLoading, Shimmer, NavbarLoading, SidebarLoading |
| Navbar | nav-bar, nav-bar-livechat, nav-bar-welcome, navbar-welcome (perhatikan dua penamaan berbeda) |
| Input teks | Input, TextInput, BaseInput |
| Number input | NumberInput, NumberInputV2 |
Duplikasi dari tidak adanya review
| Jenis | Contoh |
|---|---|
| Library chart | 4: apexcharts, chart.js, echarts, amcharts5 |
| Editor | 3: ckeditor5 + varian, quill |
| Carousel | 4: swiper, hooper, vue3-carousel, vueperslides |
| Avatar | 3: @lossendae/vue-avatar, vue-avatar, vue3-avatar |
| Date/time | 3: date-fns, moment, Intl manual |
Saat menambah library, cek dulu apakah sudah ada yang serupa. Jangan tambah varian ke-5.
Helper tumpang tindih
Ada tiga modul helper dengan duplikasi:
| Modul | Baris | Isi |
|---|---|---|
state/helpers.js | 602 | Format tanggal, currency, URL, SweetAlert, guard pesan WA |
global.js | 147 | URL service + format (gitignored, lihat Environment) |
utils/ | 127 | markdown.js, normalizationText.js |
Duplikat: formatDateOnly, getPageCardWidth ada di helpers.js dan global.js. timeAgo (global) vs getTimeAgoString (helpers) melakukan hal yang sama.
Langkah berikutnya
- Butuh auth? Baca Auth & JWT.
- Butuh query? Baca Multi-tenant.
- Butuh panggil service? Baca External Services.