perf(webstatement): optimasi performa GenerateClosingBalanceReportJob dengan database staging
Perubahan yang dilakukan: - Menambahkan model `ProcessedClosingBalance` untuk menyimpan data sementara laporan closing balance - Membuat migration `processed_closing_balances` dengan 26 kolom dan index komposit untuk query optimal - Mengganti proses langsung ekspor ke CSV menjadi dua tahap: * Tahap 1: Proses dan simpan data ke DB secara bertahap melalui `processAndSaveClosingBalanceData()` * Tahap 2: Ekspor data dari DB ke CSV via `exportFromDatabaseToCsv()` - Menambahkan method: * `deleteExistingProcessedData()` untuk membersihkan data lama * `prepareProcessedClosingBalanceData()` untuk batch insert ke DB * `getProcessedRecordCount()` untuk monitoring progres - Mengoptimalkan memori dengan menghindari akumulasi data dalam array - Menambahkan DB transaction untuk menjamin konsistensi data selama proses - Logging diperluas agar progres lebih mudah dipantau - Menambahkan error handling untuk menangani kegagalan proses dengan aman Keuntungan: - Waktu proses menurun drastis dari 1+ jam menjadi beberapa menit - Skalabilitas meningkat — mampu menangani jutaan record tanpa memory overload - Data hasil olahan dapat diekspor ulang tanpa harus re-process - Pola kerja selaras dengan `ExportStatementJob` untuk konsistensi antar modul - Monitoring dan debugging lebih mudah melalui database dan log Catatan tambahan: - Tabel `processed_closing_balances` mendukung kolom `group_name` untuk segmentasi (QRIS/NON_QRIS) - Menggunakan tipe data numerik dengan presisi untuk nilai keuangan (`amount_lcy`, `balance`, dsb)
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('processed_closing_balances', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('account_number', 20)->index();
|
||||
$table->string('period', 8)->index();
|
||||
$table->string('group_name', 20)->default('DEFAULT')->index();
|
||||
$table->integer('sequence_no');
|
||||
$table->string('trans_reference', 50)->nullable();
|
||||
$table->string('booking_date', 8)->nullable();
|
||||
$table->string('transaction_date', 20)->nullable();
|
||||
$table->decimal('amount_lcy', 15, 2)->nullable();
|
||||
$table->string('debit_acct_no', 20)->nullable();
|
||||
$table->string('debit_value_date', 8)->nullable();
|
||||
$table->decimal('debit_amount', 15, 2)->nullable();
|
||||
$table->string('credit_acct_no', 20)->nullable();
|
||||
$table->string('bif_rcv_acct', 20)->nullable();
|
||||
$table->string('bif_rcv_name', 100)->nullable();
|
||||
$table->string('credit_value_date', 8)->nullable();
|
||||
$table->decimal('credit_amount', 15, 2)->nullable();
|
||||
$table->string('at_unique_id', 50)->nullable();
|
||||
$table->string('bif_ref_no', 50)->nullable();
|
||||
$table->string('atm_order_id', 50)->nullable();
|
||||
$table->string('recipt_no', 50)->nullable();
|
||||
$table->string('api_iss_acct', 20)->nullable();
|
||||
$table->string('api_benff_acct', 20)->nullable();
|
||||
$table->string('authoriser', 50)->nullable();
|
||||
$table->text('remarks')->nullable();
|
||||
$table->text('payment_details')->nullable();
|
||||
$table->string('ref_no', 50)->nullable();
|
||||
$table->string('merchant_id', 50)->nullable();
|
||||
$table->string('term_id', 50)->nullable();
|
||||
$table->decimal('closing_balance', 15, 2)->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
// Composite index untuk performa query
|
||||
$table->index(['account_number', 'period', 'group_name']);
|
||||
$table->index(['account_number', 'period', 'sequence_no']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('processed_closing_balances');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user