chore: acquire-core migration monorepo (legacy C + Spring Boot target skeleton)
Some checks failed
ci / build (push) Failing after 2s
Some checks failed
ci / build (push) Failing after 2s
TxCore/ECPG legacy 매입·정산 C 슬라이스(빌드검증) + Spring Boot 멀티모듈 골격(mvn test green) + MIGRATION.md 전환룰 + CI(boot 빌드).
This commit is contained in:
commit
ff0b0b60a2
31 changed files with 2208 additions and 0 deletions
45
legacy/app/include/acq_util.h
Normal file
45
legacy/app/include/acq_util.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* acq_util.h - 공통 유틸리티 (일자/금액/전문) 선언
|
||||
*/
|
||||
#ifndef ACQ_UTIL_H
|
||||
#define ACQ_UTIL_H
|
||||
|
||||
#include "msg_layout.h"
|
||||
|
||||
/* ---- util_date.c : 일자/영업일 ---- */
|
||||
/* YYYYMMDD 형식 유효성 검사. 유효=1, 아니면 0 */
|
||||
int date_is_valid(const char *yyyymmdd);
|
||||
/* 요일 계산 (0=일 ... 6=토). 실패 시 -1 */
|
||||
int date_weekday(const char *yyyymmdd);
|
||||
/* 주말(토/일) 여부. 1=주말 */
|
||||
int date_is_weekend(const char *yyyymmdd);
|
||||
/* 다음 영업일(주말 건너뜀)을 out(YYYYMMDD, 최소 9바이트)에 기록. 0=성공 */
|
||||
int date_next_business(const char *yyyymmdd, char *out);
|
||||
/* 오늘 일자를 YYYYMMDD 로 out 에 기록 */
|
||||
void date_today(char *out);
|
||||
|
||||
/* ---- util_amount.c : 금액/통화 ---- */
|
||||
/* zero-pad 금액 문자열(len 폭)을 long 으로 파싱. 실패 시 <0 */
|
||||
long amount_parse(const char *field, int len);
|
||||
/* long 금액을 폭 len 의 zero-pad 문자열로 out 에 기록. 0=성공 */
|
||||
int amount_format(long amount, char *out, int len);
|
||||
/* 원화 콤마 포맷 (예: 12500 -> "12,500"). out 은 32바이트 권장 */
|
||||
void amount_format_won(long amount, char *out, int outlen);
|
||||
/* 금액 범위 검증 (1 이상, 한도 이하). 1=유효 */
|
||||
int amount_is_valid(long amount);
|
||||
|
||||
/* ---- util_msg.c : 전문 pack/unpack ---- */
|
||||
/* 고정폭 필드를 널종료 문자열 out 으로 복사(우측 공백 trim). */
|
||||
void msg_field_copy(char *out, const char *field, int len);
|
||||
/* 널종료 문자열 src 를 폭 len 필드에 좌측정렬/우측공백으로 기록 */
|
||||
void msg_field_set(char *field, const char *src, int len);
|
||||
/* 숫자 문자열 src 를 폭 len 필드에 zero-pad 로 기록 */
|
||||
void msg_field_set_num(char *field, const char *src, int len);
|
||||
/* 100바이트 raw 버퍼를 acq_msg_t 로 매핑(길이검증). 0=성공 */
|
||||
int msg_unpack(acq_msg_t *msg, const char *raw, int rawlen);
|
||||
/* acq_msg_t 를 raw(최소 MSG_ACQ_LEN) 로 직렬화. 0=성공 */
|
||||
int msg_pack(const acq_msg_t *msg, char *raw, int rawlen);
|
||||
/* 필수항목(전문구분/가맹점/카드/금액/일자) 존재 검증. 0=성공 */
|
||||
int msg_validate(const acq_msg_t *msg);
|
||||
|
||||
#endif /* ACQ_UTIL_H */
|
||||
54
legacy/app/include/msg_layout.h
Normal file
54
legacy/app/include/msg_layout.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* msg_layout.h - 카드 매입 전문(電文) 고정길이 레이아웃
|
||||
*
|
||||
* 대외/대내 전문은 고정길이 위치기반(positional) 구조다. 각 필드는
|
||||
* 널 종료가 없는 고정폭 char 배열이며, 숫자 필드는 좌측 zero-padding
|
||||
* (예: 거래금액 000000012500). util_msg.c 가 pack/unpack 을 담당한다.
|
||||
*/
|
||||
#ifndef MSG_LAYOUT_H
|
||||
#define MSG_LAYOUT_H
|
||||
|
||||
/* 전문구분 코드 */
|
||||
#define MSG_TYPE_RECV "0200" /* 매입요청(수신) */
|
||||
#define MSG_TYPE_RESP "0210" /* 매입응답 */
|
||||
#define MSG_TYPE_RECON "0500" /* 정산/대사 */
|
||||
|
||||
/* 응답코드 */
|
||||
#define RESP_OK "0000" /* 정상 */
|
||||
#define RESP_INVALID "9001" /* 항목오류 */
|
||||
#define RESP_NOMERCH "9002" /* 가맹점 없음 */
|
||||
#define RESP_SYSERR "9999" /* 시스템 오류 */
|
||||
|
||||
/*
|
||||
* 매입 요청 전문 헤더 + 바디 (총 MSG_ACQ_LEN 바이트)
|
||||
* 필드 순서/폭이 곧 와이어 포맷이므로 재배치 금지.
|
||||
*/
|
||||
typedef struct {
|
||||
char msg_type[4]; /* 전문구분 4 */
|
||||
char trans_code[6]; /* 거래코드 6 */
|
||||
char merch_id[15]; /* 가맹점번호 15 */
|
||||
char card_no[16]; /* 카드번호(마스킹) 16 */
|
||||
char approval_no[9]; /* 승인번호 9 */
|
||||
char amount[12]; /* 거래금액 12 (zero-pad, 원) */
|
||||
char txn_date[8]; /* 거래일자 8 (YYYYMMDD) */
|
||||
char txn_time[6]; /* 거래시각 6 (HHMMSS) */
|
||||
char inst_month[2]; /* 할부개월 2 (00=일시불) */
|
||||
char resp_code[4]; /* 응답코드 4 */
|
||||
char filler[18]; /* 예비 18 */
|
||||
} acq_msg_t; /* 합계 100 바이트 */
|
||||
|
||||
#define MSG_ACQ_LEN ((int)sizeof(acq_msg_t)) /* = 100 */
|
||||
|
||||
/* 필드 폭 상수 (unpack 검증용) */
|
||||
#define FLD_MSG_TYPE_LEN 4
|
||||
#define FLD_TRANS_CODE_LEN 6
|
||||
#define FLD_MERCH_ID_LEN 15
|
||||
#define FLD_CARD_NO_LEN 16
|
||||
#define FLD_APPROVAL_LEN 9
|
||||
#define FLD_AMOUNT_LEN 12
|
||||
#define FLD_TXN_DATE_LEN 8
|
||||
#define FLD_TXN_TIME_LEN 6
|
||||
#define FLD_INST_LEN 2
|
||||
#define FLD_RESP_LEN 4
|
||||
|
||||
#endif /* MSG_LAYOUT_H */
|
||||
47
legacy/app/include/purchase_dbio.h
Normal file
47
legacy/app/include/purchase_dbio.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* purchase_dbio.h - 매입/정산 DBIO 인터페이스
|
||||
*
|
||||
* 서비스/배치 코드는 SQL 을 직접 다루지 않고 이 함수들을 호출한다.
|
||||
* 구현은 app/dbio/purchase_dbio.pgc (ECPG).
|
||||
*/
|
||||
#ifndef PURCHASE_DBIO_H
|
||||
#define PURCHASE_DBIO_H
|
||||
|
||||
/* 매입 상태 코드 */
|
||||
#define PUR_ST_RECV "R" /* 접수(수신) */
|
||||
#define PUR_ST_MATCHED "M" /* 대사완료 */
|
||||
#define PUR_ST_UNMATCH "U" /* 대사불일치 */
|
||||
#define PUR_ST_SETTLED "S" /* 정산완료 */
|
||||
|
||||
/* 매입 레코드 (purchase 테이블 1행) */
|
||||
typedef struct {
|
||||
char appr_no[10]; /* 승인번호 PK */
|
||||
char merch_id[16]; /* 가맹점번호 */
|
||||
char card_no[17]; /* 카드번호 */
|
||||
long amount; /* 거래금액(원) */
|
||||
char txn_date[9]; /* 거래일자 YYYYMMDD */
|
||||
char status[2]; /* 상태코드 */
|
||||
} purchase_rec_t;
|
||||
|
||||
/* DB 연결/해제 (배치/데몬 기동 시). target 은 "db@host" 또는 NULL */
|
||||
int dbio_connect(const char *target);
|
||||
int dbio_disconnect(void);
|
||||
|
||||
/* 매입 접수 INSERT. 0=성공 */
|
||||
int purchase_insert(const purchase_rec_t *rec);
|
||||
/* 승인번호로 단건 조회. 0=성공, TX_ENOENT=없음 */
|
||||
int purchase_select_by_appr(const char *appr_no, purchase_rec_t *out);
|
||||
/* 상태 갱신. 0=성공 */
|
||||
int purchase_update_status(const char *appr_no, const char *status);
|
||||
|
||||
/*
|
||||
* 승인원장(approval) 에서 승인번호+금액 일치 여부 확인.
|
||||
* 0=일치, TX_ENOENT=불일치/없음.
|
||||
*/
|
||||
int approval_match(const char *appr_no, long amount);
|
||||
|
||||
/* 정산집계(settlement) upsert. 가맹점/일자별 금액 누적. 0=성공 */
|
||||
int settlement_accumulate(const char *merch_id, const char *biz_date,
|
||||
long amount);
|
||||
|
||||
#endif /* PURCHASE_DBIO_H */
|
||||
Reference in a new issue