2023. 10. 5. 11:48ㆍ프로젝트
에이전시에서 처음으로 맡게된 프로젝트는 정품 시리얼을 등록하는 두 페이지 가량의 사용자 사이트와 어드민 사이트의 데이터 CRUD를 구현하는 것이었다.
1. Mysql
DB연동
그 중에서도 나에게 주어진 첫 업무는 svelte로 mysql을 연동하는 것이었다. svelte도 처음인데 mysql 연동까지 해야한다니 서버 페이지도 개발해야하는 줄은 몰랐던터라 당황스러웠지만 그래도 node를 조금 써봤던 덕에 쉽게 적응할 수 있었다.
스벨트는 다행히 리액트보다 훨씬 다루기 편했다. JS만 알면 누구든 쉽게 적응할 수 있는 프레임워크였다. 변수에 할당만 하면 state가 변경되고 양방향 바인딩이 가능하여 input값도 다루기 쉬웠다. 문제는 생태계가 좁아 참고할 수 있는 자료가 적다는 것 😐
mysql 연동은 라이브러리를 사용하여 진행하였다. 그러나 늘 그렇듯 이번에도 새로운 이슈가 발생하였다.
issue 발생
아무리 튜토리얼대로 해도 데이터가 불러와지지 않았다. 에러도 뜨지 않는 걸 보면 코드에는 문제가 없는 듯 했는데 영문을 몰라 몇 시간 동안 붙잡고 끙끙 댔다. 다른 분께서 알아보시더니 비동기라 데이터가 안나오는 것 같다고 mysql2 라이브러리를 사용해보라고 하셨다.
어디서나 있는 비동기 문제..
결과는 성공적이었다. 에러가 출력되는 것도 아니다보니 내가 혼자 깨닫기까지는 꽤 시간이 걸렸을 것 같다. 다음부터는 동일한 경우에 비동기 때문인지를 확인해 봐야겠다.
쿼리문 작성
연동을 끝낸 후에는 쿼리문을 작성하게 되었다. 아무래도 처음이다보니 쿼리문을 전달받아서 붙여넣기만 해보았는데 serial 테이블의 중복 데이터가 있는지를 검색하는 쿼리문이었다.
select count(*) as cnt from serial where serial=?
- ? 값은 다음 인자에 배열을 통해 넣는 방식
나중에는 검색을 통해 페이지네이션을 구현하는 쿼리까지도 직접 작성해보았는데 꽤 좋은 경험이 되었다.
select * from faq where "+joinWhere+" order by idx desc limit "+(params.limit * (params.page - 1))+","+params.limit+""
2. 이미지 업로드
다음으로 해야했던 업무는 영수증 이미지 heic 확장자를 jpg로 바꿔주는 작업을 해야했고, 추후에 canvas에서 여백이 검정색으로 변경되는 문제가 있어 해결했어야 했다.
heic 확장자 변환
이미지는 formData로 server에 전송하여 라이브러리로 변환을 시켰다. 문제는 응답받은 buffer를 이미지화 시키는 것이었는데 처음보는 개념이라 무척 애를 먹었다.
❓Buffer: 이미지나 동영상을 처리하는 작업을 할 때 데이터를 잘게 조각내어 쪼개고(chunk) 이러한 조각 데이터들을 어딘가에 채운 다음 전송하게 된다. 조각 데이터를 담는 공간을 buffer라고 하고 buffer가 다 찰때까지 기다리는 작업을 buffering이라고 한다. 그리고 buffer가 찰때까지 기다렸다가 전송하는 작업을 반복 하는 것을 Stream이라고 한다.
구글링을 하여 byte로 변환하여 binary파일로 만들고 blob으로 변환하는 방법까지는 찾아보았는데, 그 이후에 file로 만드는 과정이 꽤 어려웠다. 그 이후 작업은 다른 분이 도와주셨는데 blob을 File 객체로 변환한 후 DataTransfer객체로 만들어주면 해결되었다.
처음보는 유형들이었는데 한층 더 깊은 지식들을 알게되니 새롭고 뿌듯했다.
❓Binary: 0과 1로 구성된 이진코드를 의미한다.
❓Blob: Binary Large Object. 바이너리 데이터의 집합인 객체로 용량이 큰 데이터를 나타내는 객체이다. 이미지, 동영상 등의 데이터를 다룰 때 사용할 수 있는데 데이터 크기, 데이터 타입 등을 알아낼 수 있다.
canvas 여백
이미지를 업로드하고 미리보기를 canvas로 작업해주었는데 작은 이미지의 경우 계속해서 검정색 여백이 생성되었다. 리사이징 하는 코드가 잘못되었나 이리저리 수정해보다가 캔버스 사이즈가 계속해서 특정 사이즈(300x150)로 변환되는 것을 보고 검색해보니 drawImage 메소드를 사용할 때 네번째, 다섯번째 매개변수에 width, height 값을 적어주지 않으면 자동으로 300x150 사이즈로 적용된다는 것을 알았다.
그래서 해당 코드를 아래와 같이 변경해주고 해결!
ctx.drawImage(image, 0, 0, image.width, image.height)
이미지 로컬 저장
또 다시 이미지의 늪에 빠지게 되었다. 의뢰 사이트가 대대적인 리뉴얼을 거치면서 팝업, 배너, 공지 등등의 기능이 생겼는데 배너에 넣어야 할 이미지 용량이 커지면서 base64로 인코딩 하는 로직은 쓸 수 없게 되었다.
버켓 같은 저장소를 쓸 수 없다보니 결국 static 폴더 내에 임시저장 한 후 url을 저장하는 방법을 사용해야 했다. 클라이언트에서 이미지를 formData로 넘기고 서버에서 fs 모듈을 사용하여 파일을 생성해주었다. 경로를 불러와서 DB에 넘기면 끝!
이후에 해당 이미지가 어드민 사이트 도메인이다 보니 사용자 사이트에서 보이려면 설정을 해줘야 했다.
3. 메일 보내기
처음으로 메일 전송 기능도 개발해야 했는데 어드민 사이트에서 as접수 상태(as 접수, 입고 완료, 출고 완료 등)에 따라 메일을 보내줘야 했다. nodemailer 모듈을 사용하여 쉽게 구현할 수 있었다. 각각 as 상태를 서버로 보내고 서버에서는 request로 상태와 함께 받은 as id를 통해 DB에서 회원명, 주문번호, 출고 송장 번호 등을 가져와 메일 내용에 포함하여 전송되게 구현하였다.
4. 그 외 기능
이 밖에도 순서 바꾸기, 필터 기능, 페이지네이션, 슬라이드 등을 구현하였는데 개인 프로젝트로는 생각 못했던 새로운 기능들을 구현할 수 있어서 너무 좋은 경험이었다.
후기
새롭게 배운 것들이 많아 나에게 너무 좋은 경험이 되었던 프로젝트 였다. 그리고 새로운 기능들을 구현해가면서 또 한번 나는 디자인보다는 개발이 더 재밌구나를 느끼게 해준 계기가 되었다.
배포 후 외부 QA도 했어야 하지만 회사가 폐업하는 관계로 수정할 수 있는 기회가 없었던게 너무 아쉽다. (눈에 보이는 에러들이 많아서 볼때마다 속상하다)