출근하자마자 메일이 쌓여 있어서 상당히 당황했는데
다행히(?) 플로우 에러 메일만 15개였고 추가 업무 관련 메일은 아니었다.
메일을 확인해본 결과 20여분 넘게 작성이 불가능한 예전 데이터를 사용 시도했는데
메뉴얼에 개발서버라서 예전 데이터가 섞여 있기 때문에
필수값이 없는 데이터는 에러가 발생한다고 작성해둬서 그런지
내부를 확인해보니 플로우 에러를 발생시키던 수십차례 시도 중간 중간에
생성된 레코드들을 확인할 수 있었고
그것을 보고 메뉴얼 내용과 에러 발생 원인을 고객사에서 파악했고
해당 부분을 넘기고 계속해서 레코드를 잘 생성했음을 확인했기 때문에
추가 안내 메일 작성을 하지 않아도 될 것 같았다.
트리거를 통해 잠금처리 기능을 구현했는데
잠금 처리는 생각보다 어렵지 않았고
해당 레코드의 하위 레코드(Line Item?)들의 수량을 처리해야 했는데
그것 또한 예전에 다른 데이터의 삭제시 Master-Detail의 하위 데이터 삭제 함수가 있기 때문에
그 함수 호출을 통해 편하게 해결할 수 있었다.
거절로 상태 변경시 하위 품목들의 수량이 정상적으로 복구되는 것을 확인하였고
재요청이 가능한 것까지 확인한 다음 뭔가 아쉬웠던 필터 부분 수정으로 돌아갔다.
벌써 2개월이 지난 것 같은데
처음 작성할 때는 전체 흐름을 모르고 요청사항 구현만 진행했기 때문에
가져오는 값들의 범위가 해당 개체 전체 레코드 대상이었는데
그 뒤로 타입값에 따라 요청사항을 가져오는 리스트의 필터를 적용하려고 했는데
이미 해당 사항과 유사한 고민을 했었기 떄문에
요청이 필요한 시점이 되면 변경되는 상태일 때 필수로 들어가는 값들이 있는지 필터로 체크했고
바로 위에서 언급된 수량 관리를 통해 종료되었는지 또한 체크를 해서 필요한지 다시 의문이 들었다.
하지만 완전 새로 시작하는 것이 아니라
기존 시스템을 대체하는 방식으로 진행되는 것이기 때문에
기존 데이터에서 종료단계에 있더라도 수량 관리 적용이 달라서 종료인지 확인할 수 없고
“취소”상태도 존재했는데 해당 값들 또한 불러와지는 것을 알 수 있었다.
결국 필터를 추가했는데 생각보다 너무 간단하게
해당 상태 코드값만 알면 Object.Status == ‘상태코드’ 형태로 필터를 수정할 수 있었고
현재 잘 조회되고 있는 레코드의 상태값을 변경해준 결과
해당 레코드는 필터에 걸려서 나오지 않는 것을 확인할 수 있었다.
다음 작업은 추가 필드를 SAP 인터페이스에 추가한 다음
해당 인터페이스를 개발에서 운영으로 끌어올리는 작업을 진행해야 했다.
중간에 Org Browser에서 한번에 가져오는 기능이 작동하지 않았는데
원인을 파악해보니 아래의 두 경고 파일들이 있었는데
삭제를 할 때 자동 생성되는 메타데이터 파일은 지우지 않고
기존에 생성된 클래스 또는 트리거만 삭제해서
메타데이터 파일을 보고 이게 뭔지 헷갈려서 터져버리는 문제였다.
“Expected source files for type 'ApexClass’”
“Expected source files for type 'ApexTrigger’”
해당 메타데이터 파일들을 지워주니
Org Browser 기능이 문제없이 작동했고
전체 class를 가져올 수 있었다.
SAP에서 추가된 필드를 인터페이스하고
해당 내용을 운영서버로 적용했다.
처음에는 어떻게 하는지 감이 잡히지 않아서
운영서버에서 직접 코드를 수정했는데 다행히(?) 배포가 되지 않았기 때문에
개발서버에서 작성하고 테스트코드가 정상적으로 작동하는지 확인한 다음
운영서버 적용을 시작했다.
1단계는 아웃바운드 변경 집합에 등록하는 것으로
바꿀 클래스 등을 등록해야 한다.
클래스만 등록하고 테스트코드는 등록하지 않아도 되는 경우가 있는데
이전에 이미 테스트코드가 같이 등록된 상태로 테스트코드의 변경이 없다면
클래스만 등록해서 해당 코드와 기존의 테스트코드가 돌아간 다음 유효성을 판별한다.
아웃바운드 등록을 완료했으면 다음 단계로 넘어가야 하는데
2단계는 바로 인바운드 변경 집합에서 유효성 확인이다.
테스트클래스로 유효성확인이 자연스럽게 진행되고 나면
3단계인 배포를 진행하면 된다.
배포의 경우 유효성 확인을 하지 않고 바로 배포를 눌러도
유효성 확인 → 배포로 넘어간다고는 하는데 배포를 바로 눌러보기는 무서워서 아직 안해봤다.
추가적인 팁을 주셨는데
테스트클래스를 정상적으로 작성해도 에러가 발생할 수 있는데
그렇게 되는 가장 큰 이유는 개발서버와 운영서버의 차이 때문이다.
특정 필드들이 운영에서는 필수가 되거나
트리거, 플로우가 존재할 수 있는데 해당 플로우로 다른 것들을 변경할 경우
권한이 부족해서 테스트 자체가 에러로 터져버릴 수 있는 것이다.
에러가 발생할 경우 당황하지 말고 운영서버와 개발서버의 차이점이나
운영서버의 작동을 확인해서 운영에 맞게 테스트코드를 작성하면 된다.
개발서버에서 에러가 발생하는 코드라도
운영서버에 배포할 때 75%의 커버리지만 만들 수 있다면 되기 때문에
개발이 아닌 운영서버 기준으로 테스트코드를 생각해야 한다는 것을 기억하자
도중에 처리 기준이 명확하지 않은 부분에 대해서 이야기했는데
필드를 추가하면 인지할 수 있고 나중에 필터를 거는 등의 작업이 가능하기 때문에
필드를 추가하라고 하셨다.
확인해보니 이미 2주 전에 말이 나왔을 때 추가했었는데
이 필드는 우리가 다룰 예정이 있는지 확실하지는 않기 때문에
오히려 운영에 먼저 올려도 괜찮을 것 같아서 팀장님에게 물어보고 운영에 반영했다.
대량의 데이터를 처리하는데
이전 시스템 내부에서 처리되던 부분을 대체하기 위한 프로젝트였기 때문에
예전에 정상적으로 처리된 데이터는 굳이 다시 처리할 필요가 없는데
어떤 기준으로 해당 데이터를 가져올지에 대해 고민이 많았다.
결국 이사님에게 문의드리니 해당 부분은 우리가 결정하기보다
고객사에서 결정하는게 맞기 때문에 문의 메일을 보내라고 하셨고
기준일을 운영서버에 반영되는 시점으로 정할지
아니면 고객사에서 정확하게 희망하는 시간이 있는지에 대한 문의메일을 작성했다.
//날짜비교할 때 참고할 내용
SELECT OwnerId, CreatedDate
FROM Opportunity
WHERE CreatedDate > 2014-06-28T22:01:02.000Z
락이 걸린 데이터의 처리도 문제였는데
전혀 상관없는 데이터의 락이 걸려서 그 하위 데이터까지 락이 걸렸기 떄문에
결론적으로는 플로우가 터져버리는 일이 발생했는데
문의가 오기 전 플로우 에러 안내 메일을 통해 원인을 파악할 수 있었다.
해당 데이터의 락을 하나의 트랜잭션 내부에서 잠깐 푼 다음
수정하고 다시 락을 거는 방식으로 진행해야 했는데
말처럼 그냥 진행하면 되는 것이 아니라 락이 걸린 이유에 대해 확인하고
락이 처리하지 않겠다는 의미인지를 파악하느라 시간이 많이 걸렸다.
완벽한 원인을 파악하지는 못했지만
락이 걸리는 이유는 승인절차 관련으로 파악하고
일단 수량이 변경되도록 진행했다.
막상 락을 풀려고 하니 락을 풀어야 하는 대상은 필요한 대상의 Master 레코드였고
해당 값을 가져오는 시점도 꼬여있었다.
하나의 데이터의 락을 풀고 다시 하는 과정 자체는 오래 걸리지 않지만
해당 레코드에 관여하는 다른 트리거들 또한 전부 락을 임시로 풀고 다시 잠궈야 했기 때문에
다시 해당 트리거들의 진행 절차를 파악하느라 추가적으로 시간을 소모했다.
또한 레코드의 디테일(Master-detail의)이었기 때문에
하나의 처리에도 동일한 레코드 아이디가 여러번 나올 수 있었는데
해당 방식을 처리하는 방법으로 Map을 사용하기로 하고
Map의 valuse()와 keySet()방식을 비교해보다가 시간을 조금 더 사용했다.
Map<String, String> a = new Map<String, String>();
a.put('a','a');
a.put('b','b');
a.put('a','a');
a.put('a','a');
System.debug(a);
for(String b : a.keySet()){
System.debug(b);
}
오늘도 재미있고 유익한 하루였다.
(1).백준 9086번 문자열은 주어진 케이스들에서
각 글자의 첫번째와 마지막 글자를 합쳐서 출력해야 하는 문제였다.
첫번째 값은 당연히 index 0번째로 접근할 수 있었고
마지막 값은 길이 -1(인덱스의 시작이 0이라)으로 접근할 수 있었다.
const input = `3
ACDKJFOWIEGHE
O
AB`.split('\n')
const result = []
for(let i = 1 ; i < input.length ; i++){
result.push(input[i][0] + input[i][input[i].length-1])
}
console.log(result.join('\n'))
'회고' 카테고리의 다른 글
[개발일지] - 57(주말) (0) | 2023.08.26 |
---|---|
[개발일지] - 56 (0) | 2023.08.25 |
[개발일지] - 54 (0) | 2023.08.23 |
[개발일지] - 53 (0) | 2023.08.22 |
[개발일지] - 52 (2) | 2023.08.21 |