Kumpulan perubahan yang udah numpuk di working tree: refactor Setup (Gate/Vehicle/Member), rapihin memberin & stiker, service parking baru (ParkingUtilsServices, NetworkService), model/migration lot-parking & DHCP reservation, dan fitur baru Intercom (controller/model/migration/ view). ReportTransaksiController versi lokal ini WIP (~90%, masih didebug) - versi yang bener ada di server, jadi dikeluarin dari git (ditambahin ke .gitignore) biar gak numpuk nindihin punya server pas git pull di sana. Sekalian keluarin dump mentah tabel softseting (1.8MB, nyasar ke-commit), file .bak, dan arsip ad-hoc (api.tgz, c.zip) yang emang bukan source code. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EAJc2mrpj2cSTe4oowLPzQ
181 lines
5.5 KiB
PHP
181 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Parking;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class SetupController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$status = $this->status();
|
|
|
|
return view('welcome', ['isReady' => $this->isReady($status)]);
|
|
}
|
|
|
|
public function setup()
|
|
{
|
|
$status = $this->status();
|
|
|
|
if ($this->isReady($status)) {
|
|
return redirect()->route('login');
|
|
}
|
|
|
|
return view('setup', compact('status'));
|
|
}
|
|
|
|
public function run()
|
|
{
|
|
if ($this->isReady($this->status())) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Setup database sudah selesai dan tidak perlu dijalankan ulang.',
|
|
], 403);
|
|
}
|
|
|
|
DB::beginTransaction();
|
|
|
|
try {
|
|
// 1. pgcrypto
|
|
if (!$this->checkPgcrypto()) {
|
|
DB::statement('CREATE EXTENSION IF NOT EXISTS pgcrypto');
|
|
}
|
|
|
|
// 2. Kolom tabel pegawai
|
|
$this->ensurePegawaiColumn('id', "ALTER TABLE pegawai ADD COLUMN id SERIAL PRIMARY KEY");
|
|
$this->ensurePegawaiColumn('email', "ALTER TABLE pegawai ADD COLUMN email VARCHAR(64)");
|
|
$this->ensurePegawaiColumn('email_verified_at', "ALTER TABLE pegawai ADD COLUMN email_verified_at VARCHAR(64)");
|
|
$this->ensurePegawaiColumn('remember_token', "ALTER TABLE pegawai ADD COLUMN remember_token VARCHAR(64)");
|
|
|
|
// 3. View users
|
|
if (!$this->checkUsersView()) {
|
|
DB::statement("
|
|
CREATE OR REPLACE VIEW users AS
|
|
SELECT
|
|
id,
|
|
nomer,
|
|
nama,
|
|
username,
|
|
crypt(password, gen_salt('bf')) AS password,
|
|
email,
|
|
email_verified_at,
|
|
foto,
|
|
bisalogin,
|
|
status,
|
|
statusabsen,
|
|
level_pegawai,
|
|
remember_token
|
|
FROM pegawai
|
|
");
|
|
}
|
|
|
|
// 4. Kolom veri_time
|
|
if (!Schema::hasColumn('transaksi_parkir', 'veri_time')) {
|
|
Schema::table('transaksi_parkir', function ($table) {
|
|
$table->timestamp('veri_time')->nullable();
|
|
});
|
|
}
|
|
|
|
// 5. Laravel database sessions for authenticated web requests.
|
|
if (!Schema::hasTable('sessions')) {
|
|
Schema::create('sessions', function ($table) {
|
|
$table->string('id')->primary();
|
|
$table->unsignedBigInteger('user_id')->nullable()->index();
|
|
$table->string('ip_address', 45)->nullable();
|
|
$table->text('user_agent')->nullable();
|
|
$table->longText('payload');
|
|
$table->integer('last_activity')->index();
|
|
});
|
|
}
|
|
|
|
DB::commit();
|
|
|
|
// return redirect()->back()->with('success', 'Setup berhasil dijalankan ✅');
|
|
return response()->json([
|
|
'success' => true,
|
|
'redirect' => url('/login') // ganti ke /dashboard kalau mau
|
|
]);
|
|
|
|
} catch (\Throwable $e) {
|
|
DB::rollBack();
|
|
// return redirect()->back()->with('error', $e->getMessage());
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
private function status(): array
|
|
{
|
|
return [
|
|
'pgcrypto' => $this->checkPgcrypto(),
|
|
'pegawai_columns' => $this->checkPegawaiColumns(),
|
|
'users_view' => $this->checkUsersView(),
|
|
'veri_time' => Schema::hasColumn('transaksi_parkir', 'veri_time'),
|
|
'sessions' => Schema::hasTable('sessions'),
|
|
];
|
|
}
|
|
|
|
private function isReady(array $status): bool
|
|
{
|
|
return $status['pgcrypto']
|
|
&& $status['users_view']
|
|
&& $status['veri_time']
|
|
&& $status['sessions']
|
|
&& !in_array(false, $status['pegawai_columns'], true);
|
|
}
|
|
|
|
/* =========================
|
|
Helper
|
|
========================= */
|
|
|
|
private function checkPgcrypto()
|
|
{
|
|
// $result = DB::select("
|
|
// SELECT 1
|
|
// FROM pg_extension
|
|
// WHERE extname = 'pgcrypto'
|
|
// ");
|
|
|
|
// return !empty($result);
|
|
try {
|
|
DB::select("SELECT digest('test','sha1')");
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private function checkPegawaiColumns()
|
|
{
|
|
return [
|
|
'id' => Schema::hasColumn('pegawai', 'id'),
|
|
'email' => Schema::hasColumn('pegawai', 'email'),
|
|
'email_verified_at' => Schema::hasColumn('pegawai', 'email_verified_at'),
|
|
'remember_token' => Schema::hasColumn('pegawai', 'remember_token'),
|
|
];
|
|
}
|
|
|
|
private function checkUsersView()
|
|
{
|
|
$result = DB::select("
|
|
SELECT 1
|
|
FROM information_schema.views
|
|
WHERE table_name = 'users'
|
|
");
|
|
|
|
return !empty($result);
|
|
}
|
|
|
|
private function ensurePegawaiColumn($column, $sql)
|
|
{
|
|
if (!Schema::hasColumn('pegawai', $column)) {
|
|
DB::statement($sql);
|
|
}
|
|
}
|
|
}
|