load->library(array('JournalDescriptionService','AuditService'));} public function run(){if(strtolower((string)getenv('APP_ENV'))==='production'){echo "Ditolak: backfill ini khusus Development.\n";return;}$rows=$this->db->where("COALESCE(ref_type,'') NOT IN ('','manual_journal')",null,false)->not_like('keterangan','[AUTO]','after')->order_by('id')->get('journals')->result();$count=0;$this->db->trans_begin();try{foreach($rows as$j){$lines=$this->db->select('account_id,debit,kredit')->where('journal_id',$j->id)->get('journal_details')->result_array();if(!$lines)continue;$new=$this->journaldescriptionservice->build((array)$j,$lines);$this->db->where('id',$j->id)->update('journals',array('keterangan'=>$new));$this->auditservice->record('development_repair','journal',$j->id,'enrich_automatic_description',array('keterangan'=>$j->keterangan),array('keterangan'=>$new),null);$count++;}if(!$this->db->trans_status())throw new RuntimeException('Backfill gagal.');$this->db->trans_commit();echo "Selesai: {$count} keterangan jurnal otomatis diperkaya.\n";}catch(Throwable$e){$this->db->trans_rollback();echo 'Gagal: '.$e->getMessage()."\n";exit(1);}} public function verify(){$missing=$this->db->where("COALESCE(ref_type,'') NOT IN ('','manual_journal')",null,false)->not_like('keterangan','[AUTO]','after')->count_all_results('journals');echo($missing?'[FAIL] ':'[OK] ').'automatic_descriptions_without_standard='.$missing."\n";if($missing)exit(1);} }