No description
  • PHP 53.5%
  • JavaScript 24.6%
  • Blade 16.6%
  • HTML 4.3%
  • CSS 0.9%
Find a file
2026-10-26 20:20:47 +07:00
.claude PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
.githooks F11+F13 dan modul inti M1: Engineering, Procurement, Gudang 2026-09-09 21:48:01 +07:00
.github/workflows PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
app PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
bootstrap Modul Recruitment HRD dan Portal Karir publik dua bahasa 2026-10-09 05:30:33 +07:00
config PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
database PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
deploy PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
docs PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
lang PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
portal PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
public PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
resources PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
routes PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
storage F0: scaffold Laravel 13 + konfigurasi dasar VMERP 2026-09-07 13:21:56 +07:00
tests PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
yard Peta 3D interaktif yard Batam (Yard 3D) 2026-10-09 05:31:00 +07:00
.editorconfig F0: scaffold Laravel 13 + konfigurasi dasar VMERP 2026-09-07 13:21:56 +07:00
.env.example PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
.gitattributes F0: scaffold Laravel 13 + konfigurasi dasar VMERP 2026-09-07 13:21:56 +07:00
.gitignore public/build ikut di git: server tidak perlu Node.js 2026-10-02 19:49:16 +07:00
.npmrc F0: scaffold Laravel 13 + konfigurasi dasar VMERP 2026-09-07 13:21:56 +07:00
artisan F0: scaffold Laravel 13 + konfigurasi dasar VMERP 2026-09-07 13:21:56 +07:00
composer.json Dependency aman untuk PHP 8.5 dan bebas advisory keamanan 2026-10-23 07:02:16 +07:00
composer.lock Dependency aman untuk PHP 8.5 dan bebas advisory keamanan 2026-10-23 07:02:16 +07:00
package-lock.json PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
package.json PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
phpunit.xml F1: fondasi database — 43 tabel, registry 311 permission, 49 role 2026-09-07 13:32:36 +07:00
pint.json F0: scaffold Laravel 13 + konfigurasi dasar VMERP 2026-09-07 13:21:56 +07:00
README.md PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
vite.config.js PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
vite.portal.config.js PHP 8.5.12 (PHP2Shell), modul HSE Safety Observation Card, halaman Dokumentasi 2026-10-23 06:55:28 +07:00
vite.yard.config.js Peta 3D interaktif yard Batam (Yard 3D) 2026-10-09 05:31:00 +07:00

VMERP — VME Enterprise Resource Planning

Sistem ERP internal PT. VME Process untuk perusahaan fabrikasi Oil & Gas. Mengintegrasikan 12 department operasional ke dalam satu platform data tunggal.

Dokumen kebutuhan docs/PRD.md
Rincian M0 docs/M0-BREAKDOWN.md
Keputusan arsitektur PRD Section 7.6 — ADR-001

Tech Stack

Layer Teknologi
Bahasa PHP 8.5 (minimal 8.5.12 — tambalan PHP2Shell)
Framework Laravel 13
Database PostgreSQL 17
Frontend Blade + Tailwind CSS 4 + Alpine.js 3
Build Vite
Excel maatwebsite/excel (PhpSpreadsheet)
PDF barryvdh/laravel-dompdf
Audit log spatie/laravel-activitylog

Menjalankan di Lokal (Laragon)

Prasyarat

  • Laragon dengan PHP 8.5.12+ dan PostgreSQL 15+
  • Composer 2.x
  • Node.js 20+

Ekstensi PHP wajib: pdo_pgsql, pgsql, mbstring, zip, gd, intl, fileinfo, openssl, curl.

Langkah

git clone <repo> vmerp
cd vmerp

composer install
npm install

cp .env.example .env
php artisan key:generate

Sesuaikan koneksi database di .env:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=vmerp
DB_USERNAME=postgres
DB_PASSWORD=<password lokal Anda>

Seluruh URL dipaksa https:// secara bawaan (URL::forceScheme('https') di AppServiceProvider::boot()). Laragon dan php artisan serve berjalan tanpa sertifikat TLS, jadi matikan hanya di .env lokal — jangan disalin ke server:

VMERP_FORCE_HTTPS=false

Buat database lalu jalankan migration:

createdb -h 127.0.0.1 -U postgres -E UTF8 vmerp
php artisan migrate --seed

Jalankan aplikasi:

npm run dev
php artisan serve

Akses http://localhost:8000 — atau http://vmerp.test bila memakai auto-virtualhost Laragon.

Akun awal

Dibuat oleh SuperAdminSeeder. Kredensial ada di database/seeders/SuperAdminSeeder.php dan wajib diganti sebelum dipakai di staging/production.


Portal Karir (Recruitment)

Halaman publik tempat pelamar mengirim lamaran — salah satu dari dua bagian VMERP tanpa login (yang lain: form Safety Observation Card). Lamaran yang masuk dinilai, diverifikasi, lalu dijadikan karyawan oleh HRD di dalam ERP.

Alamat

Path Isi
/karir/ Formulir lamaran 4 langkah: posisi → biodata, selfie & KTP → CV & sertifikat → pengalaman kerja
/karir/?posisi={slug} Formulir dengan posisi sudah terpilih — untuk tautan di iklan lowongan
/karir/lowongan/{slug} Detail lowongan (dibuka di tab baru, tombol salin tautan, kartu pratinjau WhatsApp/LinkedIn)
?lang=en Tambahkan pada alamat mana pun untuk versi bahasa Inggris (bawaan: Indonesia)
/api/karir/lowongan API publik: lowongan yang dibuka
/api/karir/lowongan/{slug} API publik: satu lowongan
/api/karir/lowongan/{slug}/header Gambar header iklan (1000 × 200)
/api/karir/lamaran API publik: kirim lamaran (POST, dibatasi per IP)

Di dalam ERP: HRD › Job Vacancy (lowongan & gambar header) dan HRD › Applicant Register (penilaian, verifikasi, Jadi Karyawan).

Contoh lokal: http://localhost:8000/karir/ · http://localhost:8000/karir/lowongan/welder-batam-vac260001.

Menyalakan

Portal mati secara bawaan. Nyalakan di .env, lalu (di server) php artisan optimize:

VMERP_CAREER_PORTAL_ENABLED=true

Email konfirmasi pelamar memakai MAIL_* — bawaan log hanya menulis ke storage/logs.

Folder

Folder Isi
portal/ Sumber — index.html (formulir), lowongan.html (detail), src/ (JS, CSS, kamus ID/EN di i18n.js)
public/karir-app/ Hasil build — ikut di-commit, jangan diedit manual
routes/public.php Route publik /karir/*, /api/karir/*, /soc, /api/soc/* (PublicGuard + throttle, tanpa auth)
app/Http/Controllers/Career/ API publik & penyaji halaman portal
app/Services/Recruitment/ Penyimpan lamaran, penilaian, Jadi Karyawan, olah gambar header
storage/app/applicants/ Berkas pelamar (selfie, KTP, CV, sertifikat) — privat

Halaman /karir/... selalu disajikan Laravel dari public/karir-app/. Folder hasil build sengaja tidak bernama karir: folder bernama sama dengan route membuat server memotong awalan path, dan /karir/lowongan/{slug} tidak ditemukan.

Build

npm run build:portal   # setelah mengubah portal/ — ikutkan public/karir-app/ dalam commit
npm run dev:portal     # server pengembangan portal (http://localhost:5180/karir-app/)

Server produksi tidak butuh Node.js: hasil build ikut di git.

Safety Observation Card (HSE)

Form publik tempat karyawan melaporkan observasi keselamatan — tindakan/kondisi tidak aman, near miss, praktik baik — tanpa login, biasanya dari ponsel lewat QR yang ditempel di yard. Pertanyaannya disusun HSE sendiri di ERP; kartu yang masuk ditinjau HSE.

Path Isi
/soc Form observasi (dua bahasa, ?lang=en)
/api/soc/form API publik: pertanyaan aktif, project & area
/api/soc/observasi API publik: kirim kartu (POST, dibatasi per IP)

Di dalam ERP: HSE › Form SOC (susun pertanyaan: jawaban singkat, paragraf, pilihan ganda, kotak centang, dropdown, ya/tidak, skala, angka, tanggal, jam, foto, judul bagian · tautan, QR, poster cetak) dan HSE › Safety Observation (daftar kartu, tinjauan status & catatan HSE, export dengan satu kolom per pertanyaan).

Nyalakan di .env (mati secara bawaan, terpisah dari Portal Karir): VMERP_SOC_PORTAL_ENABLED=true. Pertanyaan awal — dari kartu "Safety Observations Card - Online" HSE VME (docs/hse soc.docx) — diisi php artisan db:seed --class=SocQuestionSeeder; seeder ini hanya mengisi Form SOC yang masih kosong, jadi susunan yang sudah diubah HSE tidak pernah tertimpa. Sumber halamannya portal/soc.html + portal/src/soc.js, ikut npm run build:portal.


Dokumentasi

Halaman Dokumentasi di ERP (/dokumentasi, menu Dokumentasi) terbuka untuk setiap user yang login. Daftar dokumennya di config/documentation.php; setiap dokumen satu view di resources/views/docs/pages/.

Dokumen Path Sumber
General Flowchart /dokumentasi/general-flowchart docs/flowchart/general-flowchart.cjs → node docs/flowchart/general-flowchart.cjs membangkitkan ulang SVG-nya
Video Alur Kerja /dokumentasi/video-alur-kerja resources/docs/media/alur-kerja-vmerp.mp4 — dirender dari storage/app/video/general-flowchart/ (lihat scenes.js)
Product Requirements (PRD) /dokumentasi/prd docs/PRD.md, dirender langsung (tabel, daftar isi, diagram mermaid) — mengubah berkasnya cukup

Dokumen Markdown baru cukup didaftarkan dengan 'source' => 'docs/NAMA.md' di config/documentation.php. Video dan gambar dokumentasi disimpan di resources/docs/media/ dan wajib didaftarkan di kunci media config yang sama.

Struktur Direktori

app/
├── Http/
│   ├── Controllers/{Department}/   12 department + Career (portal publik)
│   ├── Requests/{Department}/      Form Request validation
│   └── Middleware/                 CheckPrivilege, PublicGuard, SetProjectContext
├── Models/                         Eloquent
├── Policies/                       Otorisasi per model
├── Services/
│   ├── Import/                     Import Engine generik
│   ├── Export/                     Export Engine generik
│   ├── Approval/                   Approval Engine berjenjang
│   ├── Privilege/                  Resolver hak akses efektif
│   └── Progress/                   Kalkulasi progress fabrikasi
├── Repositories/                   Query agregasi & laporan
├── Jobs/                           Import besar, export, report
├── Observers/                      Kolom audit otomatis
└── Traits/                         HasAuditColumns, Approvable

database/
├── migrations/
├── seeders/
└── templates/                      Template Excel import per modul

resources/views/
├── layouts/                        app, auth, print, public
├── components/                     x-data-table, x-filter-bar, dst
└── {department}/

portal/                             Portal Karir & form SOC — sumber frontend publik
public/
├── build/                          Aset ERP hasil build (ikut di git)
└── karir-app/                      Portal Karir & form SOC hasil build (ikut di git)

storage/app/
├── imports/                        Arsip file import per batch
├── documents/                      Drawing, foto, sertifikat
├── applicants/                     Berkas pelamar: selfie, KTP, CV, sertifikat (privat)
└── exports/

Konvensi

Rincian lengkap ada di PRD Section 7.4. Ringkasnya:

  • Controller tipis — validasi di Form Request, logika di Service, query kompleks di Repository
  • Wajib with() untuk relasi yang tampil di tabel — mencegah N+1
  • Dilarang menyusun SQL dengan konkatenasi string; raw query wajib memakai parameter binding
  • Blade {{ }} (auto-escape); {!! !!} wajib melewati review
  • Tabel snake_case jamak, kolom snake_case, PK id, FK {table_singular}_id
  • Model PascalCase tunggal
  • Kolom audit wajib di tabel transaksi — diisi otomatis lewat observer

Quality Gate

Kode tidak dinyatakan layak merge oleh penilaian manual, melainkan oleh dua gerbang yang sama-sama harus lulus: code style (Pint · PSR-12) dan seluruh test.

Pasang git hook (sekali per clone)

composer hooks

Perintah itu mengarahkan core.hooksPath ke folder .githooks/ yang ikut ter-commit, sehingga seluruh anggota tim memakai hook yang sama:

Hook Kapan Yang dijalankan
pre-commit tiap commit Pint hanya pada berkas PHP yang di-stage, hasil perapiannya ikut di-stage
pre-push tiap push Pint seluruh repositori + php artisan test

Pemisahannya disengaja: commit tetap ringan, tetapi tidak ada kode gagal yang sampai ke remote. Dalam keadaan darurat hook dapat dilewati dengan git push --no-verify — dan pipeline CI tetap akan menangkapnya.

Perintah

composer lint          # rapikan code style
composer lint:check    # periksa saja, tidak mengubah berkas
composer test          # feature & unit test
composer check         # gerbang penuh: lint:check + test

Pipeline

.github/workflows/ci.yml menjalankan gerbang yang sama pada setiap push dan pull request ke master dan develop, di atas PostgreSQL 17 — versi yang sama dengan produksi.

Wajib dilakukan saat repositori dipasang di GitHub: aktifkan branch protection pada master dan develop, lalu tetapkan job Quality Gate sebagai required status check. Tanpa itu pipeline hanya memberi tanda merah tanpa menghalangi merge.

Kewajiban pengujian setiap modul

Setiap modul CRUD wajib punya feature test yang menurunkan Tests\Support\CrudModuleTestCase dengan tiga skenario minimal:

  1. akses ditolak tanpa hak (403), dan datanya tetap utuh
  2. CRUD berhasil dengan hak
  3. satu aturan bisnis utama modul tersebut

Skenario ketiga dideklarasikan abstract, sehingga modul tidak dapat lolos hanya dengan mewarisi. Contoh penerapannya ada di tests/Feature/Crud/SupplierModuleTest.php.

Kewajiban ini ditagih otomatis oleh tests/Feature/Foundation/ModuleTestCoverageTest.php: begitu ada modul CRUD baru yang route-nya tidak disebut satu berkas uji pun, pipeline gagal dan merge tertahan. Test yang sama juga memastikan tidak ada route CRUD yang lolos tanpa middleware privilege.


Perintah yang Sering Dipakai

php artisan migrate:fresh --seed     # reset database dari nol
php artisan queue:work               # worker antrean (import besar, export, report)
php artisan schedule:work            # scheduler (alert, retensi data, refresh MV)
php artisan optimize:clear           # bersihkan seluruh cache

Catatan Keamanan

  • Folder excel/ berisi data operasional nyata dari department dan tidak di-commit ke Git.
  • Berkas pelamar di storage/app/applicants/ bersifat privat — hanya dapat diunduh lewat controller ber-otorisasi, tidak pernah lewat URL langsung.
  • Portal Karir publik (/karir/*) berjalan di route group terpisah tanpa middleware ERP. Lihat PRD Section 10.10.1.6 dan risiko R-16.