오늘도 오자마자 할일을 빠르게 정리하고 아래와 같은 일정을 만들었다.
~08:30 일정 정리 완료 08:58 (세부 사항 정리로 인한 지연)
~09:30 postInsert 메서드 추가
~10:30 게시글 첨부파일, 썸네일 추가 및 조회 확인
~11:30 게시글 버튼 로직 관리(수정,삭제, 확인 등)
~12:30 점심시간
~13:30 삭제 기능 및 메서드 추가
~14:30 수정 페이지 추가 및 하단 첨부파일 변경 확인
~15:30 수정 메서드 추가
~16:00 수정 후 게시판 반영 안된 경우 리로딩
~17:00 get, insert 테스트코드 작성
~18:00 delete, update 테스트코드 작성
~19:00 저녁시간
~20:00 커뮤니티 유저 버튼 접근 불가 처리
~21:00 pmd 처리
~22:00 scanner 처리
5.31 할일
1.게시판 글 등록 메서드 처리
2.게시판 보기 첨부파일 및 썸네일 추가(파트너 확인)
3.게시판 보기 상태 하단 수정, 삭제 버튼 생성(ismodify를 통한 추가 페이지 관리)
4.삭제 기능 추가 및 버튼 isdelete를 통한 2중 확인 진행
5.수정 기능 추가 및 수정 내부 첨부파일 삭제 가능, 저장/취소 버튼 확인
6.수정 후 전체 게시판 글 리로딩(?)
7.생성,수정,삭제, 조회 메서드 테스트코드 작성
8.커뮤니티 유저 버튼 조회 불가 처리(버튼 가시성?)
9.pmd 진행
10.scanner 진행
@toast = 글 등록, 수정, 삭제시
내부사용자 추가
console.log 및 debug 지우기
ppt 내부 사용 자료 정리
글을 작성하려고 했지만 도저히 문제가 해결되지 않았는데
오랬만에 보는 DML 초과 메세지였다.
LIMIT_USAGE_FOR_NS Number of DML statements: 1 out of 0 ******* CLOSE TO LIMIT
해당 문제는 이미 겪어봤기 때문에 with sharing도 without으로 변경해보고
(cacheable=true)도 제거해봤지만 문제가 해결되지 않았다.
사실 정답은 가까이 있었는데
트랜잭션 문제가 발생하려면 이미 사용중이어야 하고
wire를 통해 지속적 접근이 이어지고 있기 때문에 처리가 불가능한 것이었다.
2차 과제 때는 wire를 써도 무방했던 이유가 update, insert등의 작업을 직접 하는 것이 아니라
각 org에 변경된 내용을 받아서 처리하기 때문에(??) 가능했던 것 같고
이번에는 이유는 정확히 모르지만 어쨌든 트랜잭션 충돌 때문이라고 이해하고
wire를 사용하지 않고 게시글을 불러오는 방법을 확인했다.
다행히 connectedCallback이라는 생명주기함수(?)가 있어서
해당 방식으로 부를 경우 wire의 도움 없이도 시작할 때 게시판을 불러올 수 있었다.
connectedCallback() {
this.loadBoardPosts();
}
loadBoardPosts() {
getBoardPosts()
.then((result) => {
this.boardPosts = result;
this.boardPostsMap = this.createBoardPostsMap(result);
})
.catch((error) => {
console.error(error);
});
}
createBoardPostsMap(data) {
const mapData = {};
for (let i = 0; i < data.length; i++) {
mapData[data[i].Id] = data[i];
}
return mapData;
}
이번 과제에서도 this를 자주 빼먹고 오류를 발생시켰는데
함수를 작동시킬 때도 this를 써야 한다는 사실을 잊고 데이터 생성 메세지만 자꾸 보내다가
this.을 함수에도 붙여야 한다는 것을 문득 떠올렸다..
inset부분을 마무리하고 글 생성시 toast가 출력되고 생성창이 닫히게 마무리한 다음
게시판에서 썸네일과 첨부파일을 확인할 수 있는 기능을 추가하려고 했다.
일단 get 메서드에서 어제 추가한 첨부파일 id,name 혼합 필드를 가져온 다음
해당 부분을 잘게 쪼개서 배열 부분에 담아줬다.
다운로드 링크가 조금 문제였지만 어제 작성한 링크에 붙여 사용하고
아래와 같이 다운로드 처리를 진행해서 해결했다.
downloadFile(event){
const versionId = event.currentTarget.dataset.versionid;
const name = event.currentTarget.dataset.name;
const downloadUrl = DOWNLOAD_URL + versionId;
const link = document.createElement('a');
link.href = downloadUrl;
link.download = name;
link.target = '_blank';
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
버튼 로직 관리는 생각보다 간단하게 처리할 수 있었는데
버튼을 감싼 div 태그에 if:true, if:false를 통해 수정/삭제, 삭제 확인/취소 버튼을 만들 수 있었다.
수정은 모달 창 자체를 변경시켰는데 isUpdate의 값에 따라
false의 경우 기존 listView 모달을 볼 수 있고
true가 되는 경우 listUpdate 모달을 볼 수 있게 된다.
업데이트를 하려고 하다가 일정에 delete를 먼저 하기로 했기 때문에
수정, 수정확인, 삭제, 삭제확인 등의 버튼들을 만들고 동작을 확인했으니
이제 다시 삭제 기능 구현을 진행하기로 했다.
삭제 메서드에는 이번에도 값이 제대로 넘어가지 않았는데
아무래도 배포하는 과정 사이에 딜레이가 있어서 그런건지
이전 방식과 유사하게 진행했지만 에러가 발생해서 돌다가
다시 예전 방식을 시도해보니 정상적으로 작동했다..
//js
deletePost(){
deleteBoardPost({postId:this.selectedBoardPost.Id})
.then((result)=>{
if(result === 'done'){
this.dispatchEvent(
new ShowToastEvent({
title: "게시글 삭제",
message: "성공적으로 게시글이 삭제되었습니다.",
variant: "success"
})
);
this.closeDetailModal();
this.loadBoardPosts();
}
})
}
//apex
@AuraEnabled
public static String deleteBoardPost(String postId) {
BoardPost__c bp = new BoardPost__c(Id = postId);
if(Schema.sObjectType.BoardPost__c.isDeletable()) {
delete bp;
}
return 'done';
}
수정을 진행하려고 하는데 취소를 할 경우 내부 파일 처리에 대해 고민을 많이 했는데
생각해보면 그렇게 대단한 일이 아니었다.
이미 해당 파일의 원본은 boardPosts 및
해당 데이터를 레코드 아이디에 맵핑한 boardPostsMap이 있었기 때문에
this.xxx인 값들에 모두 할당해주고 업데이트 데이터로 사용하거나
취소를 누를 경우 게시글을 처음 눌렀을 때 처럼 초기화해주면 되는 것이었다.
수정 부분을 클릭할 경우 this.xxx에 값들을 하나씩 넣어주고 확인하니
값들이 제대로 들어가는 모습을 확인할 수 있었다.
다만 수정 도중 나간 다음 생성하기 버튼을 누를 경우 잔존 데이터가 보였는데
이 문제는 데이터가 적은 상태에서 게시글 읽기 상태를 종료할 때 초기화할 데이터가 적었기 때문에
몇 안되는 데이터만 정리해줘서 생긴 문제로
아래와 같이 모달을 닫을 때 중요 데이터들을 초기화해줬다.
closeDetailModal() {
this.selectedBoardPost = null;
this.attachedFiles = [];
this.isDelete = false;
this.isUpdate = false;
this.title = '';
this.content = '';
this.grade = 'Partner';
this.isAllRegionsChecked = true;
this.selectedRegions = [];
}
중간에 파트너 계정으로 테스트를 했는데
충격적이게도 모든 글이 다시 다 보이는 모습을 보고 당황해서 원인을 생각해보니
without sharing을 적용했기 때문인 것 같았다.
다시 with sharing을 적용하고 지정된 게시글만 볼 수 있는 것은 확인했지만
메서드 전송이 실패하지 않을까 걱정했는데
아무 무리 없이 정상 작동하는 모습을 보니
without sharing은 아까의 문제에 전혀 영향을 주지 않고
wire의 유무가 영향을 주는 것 같았다.
테스트를 하며 업로드를 할 때마다 ContentVersion이 쌓이기 때문에
해당 데이터들을 한번에 지우려고 했지만 지워지지 않았다.
여러가지 문제에 대한 내용이 있었지만 결론만 말하자면
처음 들어있는 세일즈포스 로고를 지울 수 없는 문제였기 때문에
ContentDocument에서 id ≠ logoId 방식으로 전체 데이터를 조회하고 삭제했다.
update도 무난하게 마무리할 수 있었고
이제 남은 작업은 테스트코드, pmd, 커뮤니티 유저 버튼 접근 불가, scanner, ppt 뿐이지만
남은 시간도 업무시간 기준으로는 7시간밖에 남지 않아서 서둘러야 한다.
커뮤니티유저 접근 제한을 고민해보니 현재 유저의 프로필만 알 수 있다면
허용을 해야 하는지 아닌지를 쉽게 알 수 있다는 판단을 하게 되었고
결국 또 아래의 메서드를 생성해서 현재 프로필명을 받아올 수 밖에 없었다.
@AuraEnabled
public static String getProfile() {
Id currentUserProfileId = UserInfo.getProfileId();
String profileName = [SELECT Name FROM Profile WHERE Id =: currentUserProfileId].Name;
return profileName;
}
일단 프로필을 받아온 것을 기반으로 컨스트럭터 내부에 넣어 초기 세팅으로 넣어줬고
해당 값을 바탕으로 버튼을 감싸는 div를 만들고 if:true 설정을 걸어주니
성공적으로 관리자에게는 보이고 사용자는 보이지 않았다.
다만 해당 코드는 메서드를 사용해서 다시 테스트코드 작성을 진행했고
메서드 후 pmd 자체가 남은게 없었기 때문에 pmd는 바로 통과되었고
scanner 또한 별 무리없이 해결할 수 있었다.
sfdx scanner:run --target "**/default/**" --format "html" --outfile "C:\\Users\\Yohan\\Desktop\\ScannerFile.html"
과제 내용을 확인하던 중 내부사용자가 필요하다는 이야기를 듣고
직원을 만들려고 했으나 여태 시도한 기록들이 발목을 잡아서
유저들을 하나 하나 처리하면서 라이센스를 확보하고
그래도 에러가 발생해서 CRM 관련 기능들을 제거하니 정상적으로 유저를 생성할 수 있었다.
하지만 유저를 생성하고 커뮤니티 멤버에 해당 프로필을 등록했음에도 로그인이 되지 않았는데
직원들은 로그인 페이지 하단의 직원 로그인을 누르면 자동 로그인이 되는 모습을 볼 수 있었다.
로그인을 하고도 권한이 없어서 조회가 안된다는 내용을 확인했는데
당연히 OWD가 문제라고 생각하고 얼른 들어가봤지만
OWD는 내부사용자에게 충분한 권한을 주고 있었고
프로필 자체가 기본프로필이라 커스텀 오브젝트에 대한 권한이 없었던 문제였다.
프로필을 클론해서 다시 생성한 다음 해당 프로필에 권한을 부여했지만
그럼에도 게시판 내용이 보이지 않았는데
다행히 에러메세지는 콘솔에 찍히게 남겨뒀었기 때문에
메서드 권한이 없다는 내용이 출력되는 것을 볼 수 있었고
클래스 메서드를 프로필에 추가해줌으로서 마지막 문제를 해결할 수 있었다.
내부사용자까지 해결한 다음
코드를 순회하면서 console, debug를 모두 삭제하고
클래스들 내부 줄 간격까지 정리하고 나니
남은 것은 ppt와 페이지네이션인데
ppt를 완성하고 시간이 남으면 페이지네이션을 해보기로 했다.
ppt를 작성하려고 하니 템플릿이 문제인데
30분이나 확인하다가 포기하고 이전 템플릿을 조금 보완하기로 했다.
부트캠프 동기분이 중간에 뭐하냐고 하셔서 ppt하려고 한다니까
글꼴 등에 대한 소소한 팁을 주셔서 조금 더 개선된 모습이 나올 것 같았다.
메인, 과제소개, 목차를 작성하고 나니
당장 더 진행하기 어려운게 기능소개, 작동시연, 트러블슈팅인데
해당 내용들은 현재 작성한 3차 과제 글들을 전부 읽거나
현재 메서드 내용을 모두 보면서 클래스, 메서드를 확인하는 등
대규모 확인 작업이 진행되어야 하는데 이미 10시가 넘었기 때문에
이만 마무리하고 퇴근하기로 했다.
(1).백준 21212번 Cakes는 재료 x만큼이 필요할 때 y만큼의 잔여량이 주어지고
해당 x1, x2, x3....xn까지의 모든 재료가 다 존재해야 1개의 케이크를 만들 수 있다고 할 때
총 몇개의 케이크를 만들 수 있는지를 묻는 문제였다.
문제를 해결하기 위해 각 재료별로 몇개까지 만들 수 있는지를 Math.floor로 구해준 다음
모인 배열의 값을 Math.min을 통해 최소값을 뽑아 문제를 해결했다.
const input = `3
100 500
2 5
70 1000`.split('\n')
const result = []
for(let i = 1 ; i < input.length ; i++){
const [a, b] = input[i].split(' ').map(Number)
result.push(Math.floor(b/a))
}
console.log(Math.min(...result))'회고' 카테고리의 다른 글
| [수습일지] - 68 (0) | 2023.06.02 |
|---|---|
| [수습일지] - 67 (0) | 2023.06.01 |
| [수습일지] - 65 (0) | 2023.05.30 |
| [수습일지] - 64(석가탄신일 대체공휴일) (0) | 2023.05.29 |
| [수습일지] - 63(주말) (0) | 2023.05.28 |
