Phase 2c: 전 11모듈 per-service 레거시 구조 분해·확장 (실동작 유지)

- 10개 모듈(au py rc st lg cl mm vl mg cm)을 ac 템플릿대로 분해:
  svc/ 30 서비스 .pgc + 카피북 .h, 얇은 <mod>_svr 디스패처
  dbio/ ~25 .pgc(+.h), batch/ ~17 .pgc, run/ ~17 .sh (모듈마다)
- 파일: svc 330 + dbio 276 + batch 187 + run 187, 총 소스 1602본
- 서비스별 고유 실로직(정규화 md5), build.sh 자동발견(inline/split 양립)
- 통합 검증: build DONE modules=11 servers=11 batches=187, 12서버 runok,
  333 서비스 AVAIL, 매입체인 XA 커밋(status=S), prepared_xacts=0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
forge-bot 2026-07-19 11:58:44 +00:00
parent c3b99a8b75
commit fd8b418c6e
1404 changed files with 30322 additions and 5994 deletions

View file

@ -0,0 +1,37 @@
/*
* vl_appr_audit_batch.pgc - 승인 누락 매입 감사 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_appr_audit_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM purchase p
WHERE p.biz_date = :h_bizdate
AND NOT EXISTS (SELECT 1 FROM approval a WHERE a.purchase_id = p.purchase_id);
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_appr_audit_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_appr_audit_batch COMMIT: bizdate=%s 승인누락=%ld\n", h_bizdate, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,39 @@
/*
* vl_balance_batch.pgc - 가맹점 대차 불일치 점검 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_balance_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_pnet, h_snet; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_pnet FROM purchase
WHERE biz_date = :h_bizdate AND status = 'S';
if (sqlca.sqlcode < 0) { fprintf(stderr, "SEL1 FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_snet FROM settlement
WHERE biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_balance_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_balance_batch COMMIT: bizdate=%s 매입=%ld 정산=%ld delta=%ld\n", h_bizdate, h_pnet, h_snet, h_pnet - h_snet);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,35 @@
/*
* vl_bin_check_batch.pgc - 미등록 BIN 사용 매입 점검 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_bin_check_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM mm_bin WHERE status <> 'ACTIVE';
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_bin_check_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_bin_check_batch COMMIT: 비활성BIN=%ld\n", h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,36 @@
/*
* vl_check_sweep_batch.pgc - 당일 검증로그 실패 스윕 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_check_sweep_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM vl_check_log
WHERE biz_date = :h_bizdate AND result_code <> 0;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_check_sweep_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_check_sweep_batch COMMIT: bizdate=%s 실패=%ld\n", h_bizdate, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,38 @@
/*
* vl_cross_batch.pgc - 교차검증(매입+승인+가맹점) 결측 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_cross_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM purchase p
WHERE p.biz_date = :h_bizdate
AND (NOT EXISTS (SELECT 1 FROM approval a WHERE a.purchase_id = p.purchase_id)
OR NOT EXISTS (SELECT 1 FROM merchant m WHERE m.merchant_id = p.merchant_id));
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_cross_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_cross_batch COMMIT: bizdate=%s 결측=%ld\n", h_bizdate, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,48 @@
/*
* vl_dup_scan_batch.pgc - 중복 매입 스캔 배치 (커서 + 의심적재) (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_dup_scan_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_merch[64]; long h_amt, h_cnt; long sid;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE dsc CURSOR FOR
SELECT merchant_id, amount, count(*) FROM purchase
WHERE biz_date = :h_bizdate GROUP BY merchant_id, amount HAVING count(*) > 1;
EXEC SQL OPEN dsc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
for (;;) {
EXEC SQL FETCH dsc INTO :h_merch, :h_amt, :h_cnt;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE dsc; tpabort(0); return 1; }
sid = vldb_insert_suspect(0, "DUP", "WARN", "중복 매입 의심", h_bizdate);
if (sid < 0) { EXEC SQL CLOSE dsc; tpabort(0); return 1; }
rows++;
}
EXEC SQL CLOSE dsc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_dup_scan_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_dup_scan_batch COMMIT: bizdate=%s 중복그룹=%ld\n", h_bizdate, rows);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,36 @@
/*
* vl_expiry_batch.pgc - 카드 만료 의심거래 점검 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_expiry_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM vl_suspect
WHERE rule_code = 'EXPIRY' AND biz_date = :h_bizdate;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_expiry_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_expiry_batch COMMIT: bizdate=%s 만료의심=%ld\n", h_bizdate, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,35 @@
/*
* vl_format_batch.pgc - 가맹점ID 형식 위반 점검 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_format_batch
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt;
EXEC SQL END DECLARE SECTION;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM merchant
WHERE length(merchant_id) < 4 OR length(merchant_id) > 16;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_format_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_format_batch COMMIT: 형식위반=%ld\n", h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,39 @@
/*
* vl_ledger_recon_batch.pgc - 원장-매입 순액 대사 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_ledger_recon_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_pnet, h_lsum; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT coalesce(sum(net),0) INTO :h_pnet FROM purchase
WHERE biz_date = :h_bizdate AND status = 'S';
if (sqlca.sqlcode < 0) { fprintf(stderr, "SEL1 FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
EXEC SQL SELECT coalesce(sum(amount),0) INTO :h_lsum FROM ledger
WHERE biz_date = :h_bizdate AND entry_type = 'SETTLELINK';
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_ledger_recon_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_ledger_recon_batch COMMIT: bizdate=%s 매입순액=%ld 원장합=%ld delta=%ld\n", h_bizdate, h_pnet, h_lsum, h_pnet - h_lsum);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,37 @@
/*
* vl_limit_scan_batch.pgc - 한도 초과 매입 스캔 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_limit_scan_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM purchase p
JOIN merchant m ON m.merchant_id = p.merchant_id
WHERE p.biz_date = :h_bizdate AND p.amount > m.daily_limit;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_limit_scan_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_limit_scan_batch COMMIT: bizdate=%s 한도초과=%ld\n", h_bizdate, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,35 @@
/*
* vl_refinteg_batch.pgc - 참조무결성(가맹점 orphan) 검사 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_refinteg_batch
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt;
EXEC SQL END DECLARE SECTION;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM purchase p
WHERE NOT EXISTS (SELECT 1 FROM merchant m WHERE m.merchant_id = p.merchant_id);
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_refinteg_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_refinteg_batch COMMIT: orphan=%ld\n", h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,46 @@
/*
* vl_report_batch.pgc - 심각도별 의심거래 리포트 배치 (커서) (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_report_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
char h_bizdate[16], h_sev[8]; long h_cnt;
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE rpc CURSOR FOR
SELECT severity, count(*) FROM vl_suspect
WHERE biz_date = :h_bizdate GROUP BY severity ORDER BY severity;
EXEC SQL OPEN rpc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
for (;;) {
EXEC SQL FETCH rpc INTO :h_sev, :h_cnt;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE rpc; tpabort(0); return 1; }
rows++;
}
EXEC SQL CLOSE rpc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_report_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_report_batch COMMIT: bizdate=%s 심각도구간=%ld\n", h_bizdate, rows);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,38 @@
/*
* vl_settle_recon_batch.pgc - 정산 불일치 대사 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_settle_recon_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt; char h_bizdate[16];
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM purchase p
WHERE p.biz_date = :h_bizdate AND p.status = 'S'
AND p.net <> coalesce((SELECT sum(s.net) FROM settlement s
WHERE s.purchase_id = p.purchase_id), 0);
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_settle_recon_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_settle_recon_batch COMMIT: bizdate=%s 정산불일치=%ld\n", h_bizdate, h_cnt);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,46 @@
/*
* vl_suspect_close_batch.pgc - 노후 의심거래 자동 종결 배치 (커서) (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_suspect_close_batch [DAYS]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_sid, h_days = (argc > 1) ? atol(argv[1]) : 30;
EXEC SQL END DECLARE SECTION;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
EXEC SQL DECLARE scc CURSOR FOR
SELECT suspect_id FROM vl_suspect
WHERE status = 'OPEN' AND created_at < now() - (:h_days || ' days')::interval;
EXEC SQL OPEN scc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "OPEN FAIL [%d]\n", sqlca.sqlcode); tpabort(0); return 1; }
for (;;) {
EXEC SQL FETCH scc INTO :h_sid;
if (sqlca.sqlcode == 100) break;
if (sqlca.sqlcode < 0) { EXEC SQL CLOSE scc; tpabort(0); return 1; }
if (vldb_close_suspect(h_sid) < 0) { EXEC SQL CLOSE scc; tpabort(0); return 1; }
rows++;
}
EXEC SQL CLOSE scc;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_suspect_close_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_suspect_close_batch COMMIT: days=%ld 종결=%ld\n", h_days, rows);
tpclose(); tpterm();
return 0;
}

View file

@ -0,0 +1,37 @@
/*
* vl_threshold_batch.pgc - 임계 초과 매입 규칙 점검 배치 (XA).
*
* ATMI client: tpinit/tpopen open the ECPG XA RM, tpbegin starts ONE global
* transaction; the 검증 SELECT/집계 runs on that branch, then tpcommit drives XA 2PC.
* Usage: vl_threshold_batch [YYYY-MM-DD]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <atmi.h>
#include "vl_dbio.h"
int main(int argc, char **argv)
{
long rows = 0; (void)rows; (void)argc; (void)argv;
EXEC SQL BEGIN DECLARE SECTION;
long h_cnt, thr = 50000000; char h_bizdate[16], sev[8] = "ERROR";
EXEC SQL END DECLARE SECTION;
strncpy(h_bizdate, (argc > 1) ? argv[1] : "2026-07-19", sizeof(h_bizdate)-1); h_bizdate[sizeof(h_bizdate)-1] = 0;
if (tpinit(NULL) < 0) { fprintf(stderr, "tpinit FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpopen() < 0) { fprintf(stderr, "tpopen FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (tpbegin(60, 0) < 0) { fprintf(stderr, "tpbegin FAIL: %s\n", tpstrerror(tperrno)); return 1; }
if (vldb_get_rule("AMT_MAX", &thr, sev) < 0) { thr = 50000000; }
EXEC SQL SELECT count(*) INTO :h_cnt FROM purchase
WHERE biz_date = :h_bizdate AND amount > :thr;
if (sqlca.sqlcode < 0) { fprintf(stderr, "vl_threshold_batch FAIL [%d] %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc); tpabort(0); return 1; }
if (tpcommit(0) < 0) { fprintf(stderr, "tpcommit FAIL: %s\n", tpstrerror(tperrno)); tpabort(0); return 1; }
printf(">>> vl_threshold_batch COMMIT: bizdate=%s 임계=%ld 초과=%ld\n", h_bizdate, thr, h_cnt);
tpclose(); tpterm();
return 0;
}