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); } } }