인디 개발자 클럽

인디 개발자 클럽

혼자서 또는 극소수의 팀원들과 프로덕트를 만들고 있는 개발자 분들을 위한 클럽입니다.

공개 373 멤버

가이드라인

["현재 프로덕트를 만들고 있는 인디 개발자 분이라면 누구든 환영입니다. 목적이 창업 준비든, 사이드프로젝트이든 관계 없어요.","혼자 개발하면서 생기는 질문, 고민거리, 푸념, 삽질기, 배운 점, 개발 로그 등을 자유롭게 공유해주세요."]

이연수

이연수

의료 플랫폼(WEB PACS) 개발 도전기(1단계)

안녕하세요. 개인 프로젝트로 의료 플랫폼(WEB PACS) 개발에 도전하고 있는 웹개발자(프론트엔드) 이연수입니다. 개발 도전에 대한 로그를 남기고 싶어 이렇게 글을 쓰게 되었습니다.

[목표] 의료(다산업군) AI 연구 지원을 위한 WEB PACS(Workspace, Viewer, AI 연동)

[단계] 1단계

[상태] 의료 영상데이터(파일) - DICOM(.dcm) : CT, MRI, PET 등 binary 분석 및 출력

[언어] TypeScript(Node), React(라이브러리), Next.js(프레임워크)

우선 다소 생소하실 수 있는 의료 영상데이터 DICOM(.dcm) 파일을 설명 드리고자 합니다. 다양한 의료 영상촬영 장치(CT, MRI, PET 등)에서 장치로부터 파일(데이터) 표준 프로토콜이 적용된 의료 영상데이터(파일)이 DICOM(.dcm)으로 생성됩니다. 프로토콜은 디지털 영상전송 표준 의원회에서 DICOM 데이터(파일) 표준을 정하여 관리되고 있습니다.

우선, 저는 해당 파일을 오픈소스를 사용하지 않고, 직접 오픈소스와 표준 내용을 참고하여 개발하는 것을 목표로 하고 있습니다. 그렇다 보니 파일의 binary 코드를 확보하여 분석하는 것을 시작하였습니다.

binary.PNG

파일을 열어보면, 1byte(8bit)로 파일 바이트 저장 순서(Byte Order)에 맞춰 리틀 에디안(Little-endian)과 빅 에디안(Big-endian)으로 저장됩니다. 순서에 따라 바이트를 읽는 방식이 달라지기 때문에 해당 부분도 유의 깊게 살펴보았습니다.

바이트를 ASCII로 변형된 부분을 확인하였을 때, DICOM 파일은 메타정보에 File Preamble(더미 바이트) - 128Byte, DICOM prefix("DICM") - 4Byte, File Meta Elements(파일 메타 요소) - NByte로 구성되어 있었습니다.

위 정보를 확보 후 웹에서 로컬 DICOM 파일을 로드 할 수 있도록 인터페이스를 다음과 같이 구현하였습니다.

캡처2.PNG

이 후 파일을 ArrayBuffer로 읽어 Uint8Array로 형변환을 하여, BufferStream을 구성하였습니다. 위에서 분석한 파일 binary 길이에 맞춰 데이터 offset(여백)과 length(길이)를 계산하고, DICOM 표준에서 제공하는 File Meta Elements(파일 메타 요소)의 메타 요소 태그(Tag)정보, 요소 유형(VR)정보, 데이터 길이 등을 추출하여, 메타데이터를 확보하였습니다. 태그 정보는 DICOM 표준에서 정의되어 있는데 약 3,400개 정도로 해당 정보의 이름(설명)을 위해 dictionary(사전)을 .json 파일로 만들어 맵핑하는 작업을 수행하였습니다.

캡처3.PNG

해당 정보를 파일 데이터와 맵핑하여 요소 이름을 표현하고, File Meta Elements(파일 메타 요소)에서 추출한 데이터 여백과 길이(offset, length)를 ByteStream에 적용하여, Character(String), Uint16, Uint32, Float, Double 등 요소 유형(VR)정보에 맞춰 데이터 값을 아래와 같이 확보하였습니다.

캡처4.PNG

DICOM 파일의 경우 이미지 영상 데이터를 2D, 3D 표현(추출)하기 위해 포함된 의료정보(환자정보 포함) 및 이미지 Pixel Data에 대한 다양한 정보를 메타정보에 포함하고 있습니다. 따라서 모든 메타정보에 대한 이해와, 그래픽 표현을 위한 색(광학), 압축(이미지), 사이즈, 방향(유클리드 공간) 등 수학적 계산이 필요한 것 같습니다.

지금까지 다소 마이너하지만, 개인적으로 기술을 정리하기 위해 진행하고 있는 의료 플랫폼(WEB PACS) 개발 도전기(1단계)를 로그글로 간략하게 남겼네요.

긴 글 읽어 주셔서 감사합니다. : )

다양한 분야의 AI Vision 영상(이미지) 처리를 연구하며, 개인 프로젝트(기술 정리)를 수행할 것 같아요~ 관련 부분에 관심 있으시면 편하게 커피챗 요청주세요~

9
1
이병우

이병우

[MOM 투표 서비스] 카카오톡 OG태그 반영 실패

문제 상황

기존에 테스트로 사용하던 OG태그 이미지를 바꿔야 했습니다. 함께하는 디자이너 친구가 만들어 주었던 이미지를 적용하여 배포하고, 바로 카카오톡으로 저한테 서비스 링크를 보내보았습니다. 그런데 기존 이미지가 그대로 있더라구요! 배포가 잘 안되었나 싶어 다시 수정해서 재배포 후 테스트를 해도 그대로였습니다.

해결 과정

유추가 되는 문제는 아무래도 캐시 밖에 없었죠. 혹시나싶어 카카오톡 설정에서 대화방 내에 이런 OG 태그에 관한 캐시만 지우는 기능이 있나 찾아보았는데, 역시나 대화 내용과 이미지를 삭제하는 옵션 밖에 없었습니다. 이건 테스트 삼아 건들 수 있는 기능이 아니었죠… 그래서 어떻게든 서칭을 하며 방법을 찾아보려 했습니다. 그리고 역시 비슷한 질문들을 발견할 수 있었고, 카카오 개발자센터에서 해당 캐시만 초기화할 수 있는 공유 디버거를 제공하고 있었습니다!

스크린샷 2024-01-16 오전 10.05.23.png

카카오스토리 공유시 이미지 캐쉬는 어떻게 지우나요?

Og tag 내용(description)을 수정했는데 반영이 안되네요

마치며

개발에서는 내가 처음 겪는 문제란 존재하지 않는다고 하더군요. 이번에도 역시 실감했습니다! 익숙하지 않은 문제를 마주해도 키워드를 잘 잡아 해결법을 더 빨리 발견할 수 있는 역량을 키워야겠습니다.

6
0
박주혜

박주혜

퍼스트펭귄 클럽과 함께한 2월 프로젝트 정산🐧

2월 2일, 3개월 다니던 회사에서 나왔고, 나에게 소속과 '브랜드 마케터'라는 키워드가 사라졌다. 사실 너무나도 갑작스러운 퇴사라 준비한 건 아무것도 없고, 나에게 남은 건 '퇴사자'라는 키워드와 진행하던 사이드 프로젝트정도였다.

0227_퍼스트펭귄 클럽과 함께한 2월 프로젝트 정산.png

계획이 없다면 무조건 지르고 보자


퇴사전, 무작정 디스콰이엇에 자기소개를 올렸는데 생각보다 너무 관심을 많이 주셔서 트랜딩까지 타게 되었다.
이 글을 보고서 많은 분들이 디스콰이엇에 가입을 하기도 했고, 또 많은 분들이 먼저 연락을 주셔서 퇴사 후 침울했던 기분이 조금 나아졌던 것 같다.

image.png


이후 1달이라는 시간동안 어떻게 살아야할지 엄청난 고민을 했다.
하지만, 명확한 답은 아직까지 찾지 못한 상태다.

그렇기 때문에 2월에 참 많은 시도를 했던 것 같다.

2월에 시도하고 만들었던 성과

  • 디스콰이엇 -1 to 0 클럽 참가

  • 학점은행제 학사 학위 취득을 위한 솔루션 '회사끝나고' MVP 개발 마무리 + 홈페이지 작업 마무리 (중국 사이드 프로젝트 한국화 진행중)

  • 전라북도 부안에서의 '로컬 프로젝트' 준비 및 새로운 팀 빌딩 + 지원사업 선정 및 신사업사관학교+전라북도 활성화 사업 도전 시작

  • 1주일만에 스타트업 초기 입사자를 위한 '온보딩' 프로그램 기획부터 개발까지 마무리 (3월 초반에 런칭 후 디스콰이엇에 공유 예정)

  • 퍼스트펭귄 클럽 참가 및 매일 데일리로그 공유

  • 잠시 쉬고 있었던 인스타그램, 네이버 블로그 활성화 및 뉴스레터/네트워킹 프로그램 기획 마무리단계

  • 디스콰이엇에 주 1회 이상 메이커로그 or 짧스콰이엇 업로드

  • 13명의 시니어 멘토(중국, 한국)와의 만남을 통한 시니어 프로덕트 연구 방향성 설정 및 151명의 고객들과의 인터뷰를 통해 아이디어 구체화

  • 대학원 합격 및 등록 진행 (고대하던 학교 MBA 과정 합격)

모아두었던 자금과 대회를 통해서 얻었던 자산이 사실 흘러넘쳐서 주머니 사정 상관없이 무작정 하고싶은것 하나하나 다 도전하기 시작했고, 아직 눈에 보이는 성과는 뚜렷하게 없지만 앞으로의 성과를 위한 틀을 잡은 것 같다.

2월, 가장 기뻤던 성과

일단 가장 눈물나게 기뻤던 점은 원하는 교수님이 계신 대학원에 합격했다는 것이다.

사업도 물론 중요하지만, 공부 또한 또한 나에게 매우 중요한 역할을 한다는 것을 최근에 다시한번 깨달았다.

다들 대학원을 고를 때 상위권 대학교 or 내가 가고자 하는 분야의 탑인 대학교로 석사를 진학하고자 하지만, 나는 내가 배우고자 하는 교수님이 명확하게 있었다.
상위권 대학에 계셨기 때문에 당연하게도 학점 관리는 필수였고, 직장을 다니며 대학원 준비+창업 준비를 같이 병행했었다.

지금까지 2년동안 열심히 노력했던 성과를 본 것 같기도 했고, 또 대학원에서 어떤 연구를 진행할지, 어떤 공부를 할지 너무 두근두근거린다.

20살의 나이에 창업을 준비하면서 대학원에 가는 이유는 이 뿐만 아니라, 하나의 주제로 꾸준히 공부를 하는 방법을 배우기 위해서도 있고 기본적으로 일 끝나고 공부하는 걸 너무나 좋아해서 그런 것도 있다.

2월, 가장 인상 깊었던 활동 : 퍼스트펭귄

퍼스트펭귄 클럽, 디스콰이엇을 통해서 알게 되었고 또 -1 to 0 프로그램을 통해 기본적인 나와 팀원들에 대한 확신을 만든 후 시도했던 2번째 프로그램이다.

@황민정 님이 만드셔서 운영하고 계신 클럽인데, 어찌하다보니 먼저 연락을 받게 되었고 커피챗을 진행한 후 클럽에 합류하게 되었다.

진행 방법은 단순했다.

"내가 오늘 실천한 내용 슬랙(slack)을 통해 공유하기"
이외에 정보공유, 팀 활동 등이 있었고 모각작(모두 각자 작업)도 있었다. -> 지금 퍼스널 브랜딩으로 도전 2일차중

1주일 정도 진행한 후 느낀점은 생각보다 매일매일 꾸준히 올리는 것은 너무 어렵다는거?

1일 1피드 올리는 크리에이터 분들이 너무 대단하다고 느껴졌다.

매일 업로드하는게 힘든 게 내가 하루에 하는 양이 그렇게 많지 않다.
그리고 콘텐츠화를 어떻게 시켜야할지, 글을 쓰는 것이 정말 어려웠다.
추가로 하루 시간을 내가 엄청나게 비효율적으로 쓴다는 사실이 모두 드러난다는 점?

실제로 주말에도 작업을 했으나 하루씩 밀려서 업로드했다. (밤샘 작업을 했던 것도 있지만)

또, 열심히 실천하는 분들과 같이 달리다보니 자극받아서 더 열심히 무언가를 하고 싶다 느끼고, 글을 쓰게 되는 것 같다.
퍼스트펭귄 클럽에는 다양한 배경을 가진 분들이 계시는데 매일 올리시는 내용을 읽고 여러가지로 자극을 받는중이다.

image.png

3월 계획 및 목표 수립

3월에는 크게는 전북 부안에서 로컬 크리에이터 겸 로컬 사업 아이템에 집중해볼 예정이다. 2월에는 테스트삼아 부안에서 거주해봤는데 서울보다 인프라나 교통수단 면에서 불편한 점이 있지만, 지원사업 및 발전 시킬만한 페인포인트 (아이템, 지역상생)들이 정말 많고, 또 협업쪽에서도 크게 열려있어 부안에서 5개월 정도 프로젝트 형식으로 거주하기로 했다.

중국에서의 활동, 기존 초기가설검증에 대한 마무리를 할 예정이고
준비하고 있던 큰 시험, 작은 시험들을 마무리 할 예정이다.

3월에는 더 성장한 모습, 수치화된 결과로, comming soon!🥹


13
4
이연수

이연수

프론트엔드 기술 스택 정리하며, 개인 포트폴리오(프로젝트) 준비.

안녕하세요. 웹 개발 7년차에 접어들고 있는 개발자입니다.

최근까지 의료 AI 회사의 플랫폼 개발을 담당하다 퇴사 후 프리랜서로 일을 진행하고 있습니다. 백엔드 개발자로 시작하여, 프론트엔드 개발자로 전향하고, 지금은 기술 스택을 쌓으며 다음 스탭을 준비하고 있습니다.

혼자 프로젝트를 개인 포트폴리오 형태로 준비하고 있습니다. 그동안 업무에서 쌓아왔던 기술을 정리하려고 합니다.

캡처.PNG

현재는 노션(Notion)과 유사한 기능의 WYSIWYG(Rich Text Editor)를 개발하고자 개발을 진행하고 있습니다. 아래에서 설명 드릴 WEB PACS(의료영상저장전송시스템)가 완성되면, 의료(AI 판독문, 인허가 문서 등), AI 연구, 필요한 문서 템플릿 등을 개발하여 연동하는 작업을 목표로 개발하고 있습니다.

앞에서 말씀드린 의료 AI 관련 분야에서 수행하였던, WEB PACS(의료영상저장전송시스템)을 오픈소스 도움 없이 vision(Graphic) 개발에 .dcm(DICOM)파일을 binary 수준까지 연구하여 표현하는 프로젝트를 진행 하려합니다. 주로 의료 AI를 연구하시는 연구자에게 Data Labeling(ROI - 흥미영역)에 대한 어노테이션 툴과 작업된 의료 AI(모델)을 연결하여 병변 분류, 표시 등이 가능한 연구 플랫폼 구성을 프로젝트에 포함하여 작업 하려합니다.

의료분야에 대해 혹은 의료공학을 전문적으로 배운 것이 아니기에 데이터 전처리 플러그인 개발과 AI(모델)에 서빙과 하이퍼 파라미터 등 전반적인 연동에 필요한 조언이 필요한 상태입니다.

그리고 의료 데이터가 가진 특수성(민감 데이터, 보안)을 고려한 WebRTC(Web Real-Time Communication)을 활용하여 데이터 반출 없이 원격진료, 원격판독 등의 기술 개발도 진행해보려고 합니다.

프로젝트를 진행하고 계신 의료, 산업, 교육 등 다양한 분야의 AI, 웹 관련 개발자 분들과 많이 소통하고 정보를 공유하면 좋겠다고 생각하고 있습니다.

클럽 가입 후 첫 글이라 진행중인 개인 프로젝트 소개와 간략한 제 소개를 하였습니다.

앞으로 잘 부탁드립니다~

(편안하게 스몰톡을 위한 커피톡 환영입니다.)

8
2
이병우

이병우

프로덕트 개선에 챗GPT 활용하기

현재 만들고 있는 프로덕트를 개선하기 위해 챗GPT와 대화를 나눠봤습니다. 그동안 개발이 막힐 때만 챗GPT한테 질문을 했었는데, 이렇게도 활용할 수 있다는 생각은 못 했었네요! 업무 과정에서 챗GPT를 활용하는 방법 뉴스레터와 ChatGPT로 프로덕트 디자인 시간을 줄일 수 있을까 아티클을 읽고, 한번 실제로 제가 만들고 있는 프로덕트에 대해 물어보았습니다.

우선 어떤 서비스인지 한 문장으로 알려주고, 왜 이 서비스를 구상하게 되었는지 문제 상황과 핵심적인 특징들을 정리하여 알려주었습니다. 그리고 서비스 이름을 알려주고, 저와 함께 서비스를 만들고 있는 프로덕트 디자이너라는 역할을 부여했죠.

결론적으로, 저의 프롬프트가 미숙해서인지 혹은 3.5의 한계인지 만족스러운 답변은 얻지 못했습니다. 하지만 잠깐 해본 건데도 큰 장점을 느꼈습니다! 챗GPT에게 잘 전달하기 위해 저도 서비스의 기획적인 부분을 한 번 더 잘 정리 해보게 되었고, 함께 서비스에 대해 의견을 나눠보는 행위 자체에서 제가 발상을 좀 더 넓힐 수 있는 계기가 되었기 때문입니다. 역시 질문하는 역량을 키워야겠습니다. 또한… 4.0을 빨리 사용하고 싶단 생각이 드네요!

5
0
이현석

이현석

서비스 상위 기획시 고려해야 할 것들에 대입해보니

해빗팩토리 정윤호 대표님이 서비스 상위 기획시 고려해야 할 것들이라는 내용을 페이스북에 공유해주셨어요. Frequency, Pain Level, Benefit / Incentives, 네트워크 효과, 피드백 이렇게 다섯가지를 말씀해주셨는데 새로운 서비스를 기획하는 사람은 읽어보면 크게 도움이 될 것 같아요.

사실 치킨랭크를 찾아주시는 분들이 적어서 요즘 좀 아쉬워하고 있었어요. 그런데 이 다섯가지를 대입해보니 사용자가 적은 이유를 좀 알겠더라고요.

  1. Frequency: 치킨을 시켜 먹는건 자주 하는 일이지만, 치킨 먹기 전에 어떤 치킨이 인기있고 새로나왔는지 찾아보는 건 기존에 사람들이 하던 일이 아니에요.

  2. Pain Level: Pain이 작아요. 먹던 치킨 먹는 건 안전해요. 못 먹어봤지만 맛있는 치킨이 뭔지 몰라도 여전히 즐거운 치킨 생활을 할 수 있어요.

  3. Benefit / Incentives: 금전적 이익을 주거나 비용을 아껴주는 서비스는 아니에요. .

  4. 네트워크 효과: 혼자쓰면 유용하지 않아요. 사용자가 만들 수 있는 컨텐츠가 순위 밖에 없어요.

  5. 피드백: 페북의 '좋아요' 같이 사용자가 피드백을 받을만한 기능이 없어요.

낙제점을 받은것 같아 잠시 기분이 다운되기도 했지만

한편으로는 좋은 지도를 한 장 얻은 것 같아 기분이 좋기도 해요.

예를 들어, 다음으로 넣으려고 했던 기능 중 하나가 도감 기능인데 이걸 만들면 '네트워크 효과에 좋겠구나'라는 식으로 생각할 수 있으니까요.

조금씩 달라져보겠습니다~

아 일단 배포자동화부터 끝내고.. (거의 일주일째 삽질 중)

치킨랭크

당신의 최애 치킨은 무엇인가요?

6
0
애리

애리

키오스크 디자인 어렵지 않아요🙌

저는 프로덕트에 맞는 컨셉을 연구하며 디자인하는 것을 좋아하는 디자이너 박애리입니다.

신입일 당시 회사에 입사했을 때의 마음가짐은 딱 두 가지였어요. 첫 번째는 “피해끼지치 말자” 두 번째는 “도움이 되자” 였습니다. 제가 디자이너의 길을 택한 이유는 일하면서 느낀 바들이 커요. 제가 디자인한 것이 실제로 사용됐을 때의 나오는 기쁨, 그 하나인 거 같아요. 저는 외부 키오스크 UI의 리디자인을 맡았어요.  컨셉을 정하기 전에 저는 두 가지를 고려했습니다. 주 타겟층이 학생과 학부모라는 것 그리고 브랜드 색상인 보라색을 키오스크에 잘 녹여 낼 수 있어야 한다는 것이었어요.

“이 브랜드는 어떤 방식으로 primary 색상을 사용했을까?”

“어떻게 하면 버튼을 누른 후 이어지는 수많은 인터페이스 대한 거부감을 없앨 수 있을까?”

키오스크 디자인은 우리가 주로 사용하는 앱, PC의 환경과는 아주 달라요.

제게는 더욱 생소할뿐더러 처음 맡은 큰 프로젝트이다 보니 밖에서 봤던 수많은 키오스크를 보면 📸 늘 사진을 찍었어요. 키오스크만 보면 저도 모르게 분석했습니다. 그때는 하나의 일이라고 생각했지만 지금 와서 생각해보니 영감을 얻기 위해서였고 모든 과정에 큰 재미를 느꼈던 거 같아요.

Frame 427318970.png

“어떤 것이 접근성이 높은 디자인일까?”

Frame 10968.png

  1. 사용자의 인지 분석

    보통 키오스크를 사용하는 사람들은 대게 연령대가 다양하고 노년층, 심지어 젊은 층조차 여전히 생소하다고 느끼는 부분들이 있어요. 스터디카페 용 키오스크는 보통 매장에 있는 상품을 선택하고 계산하는 시스템뿐만 아니라 학생들이 입실하고 프로그램을 선택하고 코스를 구매하기 등 다양한 흐름이 있기에 각각 사용자들이 첫 페이지부터 원하는 목적을 달성하기까지의 모든 순서에 대해서 어렵지 않게 디자인해야 한다고 생각했어요.

e3aff49b433cea28606ba102cff3f8fd86ccc3137e5f56e0e564280556b2aa08.webpb23f7cdd7623ac4c70985cb8b8aa5ca613817dd11cd834b1851cba7d776ddc88.webp

  1. 사용자의 시선 분석

    사용자들이 키오스크 화면을 인식할 때의 시선 방식을 생각하며 각 기능을 그에 맞게 디자인했어요. 큰 화면의 키오스크를 사용할 때 사용자의 시선은 손끝과 같이 움직이고 시선은 보통 정면 혹은 옵션을 선택할 시에는 왼쪽에서 오른쪽 그리고 중 가운데로 시선이 움직이는 것을 고려를 해서 그에 맞게 각 페이지의 핵심정보 및 입력창을 배치하고 색상 또한 그에 맞게 고려하여 전체적으로 디자인의 통일감을 유지하려고 노력했어요.

Frame 10964.png

  1. 귀여운 일러스트

    브랜드의 primary 색상인 보라색을 사용하여 다양한 아이콘 그리고 귀여운 일러스트를 만들었고 더욱 더 친근감있는 키오스크로 리디자인 했어요. 첫 화면부터 느끼는 어려움을 버리고 브랜드의 색깔과 타겟층을 고려한 디자인으로 개선했어요.


✔️한 가지 배운 것이 있다면 브랜딩에 대한 이해도를 높이기 위해선 디자이너가 기획에 꼭 참여해야 한다는 점이에요. ✔️ 아쉬운 점은🥲 기획 부분에 다양한 아이디어를 더 ‘신나게’ 참여하지 못한 점이에요. 디자이너가 개발에 대한 지식을 갖는다면 UX를 고려하게 되듯이 디자이너가 UX를 알면 디자인 컨셉 그리고 더 나아가 브랜딩까지의 깊이를 알 수 있다는 점이었어요.

신입 때 맡은 큰 프로젝트로 인해 그 이후에 디자인에 대한 약간의 자신감을 갖게 됐어요✨

앞으로의 저의 계획은 다양한 프로덕트를 더 깊이 있게 만들고 싶다는 점과 더 폭넓은 경험들을 쌓고 싶어요.

커핏챗 나누는 것 좋아하니 언제든지 요청해주세요! 환영합니다 🙂

9
9
이현석

이현석

배포 자동화를 준비하고 있어요

소식이 뜸했지요?

그간 아무것도 안한 건 아니에요.

연휴에도 꾸준히 하루 30분씩 작업하고 있어요.

공유할만한 새 기능이 딱히 없었어요.

새 기능 개발은 안하고 배포 자동화 준비를 3일째하고 있었거든요.

사실 아직 서버 한 대라 수동으로 해도 5초면 배포가능해요.

그럼에도 자동화를 하려는 이유는

github actions 쓰는 방법을 익히고 싶기 때문이에요.

그동안 못해본거 해보는거, 이런게 또 사이드 프로젝트의 의미 아니겠어요?

스크린샷 2024-02-17 오전 7.03.08.png

암튼 엄청 헤매고 있습니다 ㅎㅎㅎ

스크린샷 2024-02-17 오전 7.03.25.png

그래도 일단은 테스트 돌리고

테스트 통과하면 프론트엔드 빌드하는것 까지 성공한 상태에요.

이제 남은 작업은 서버로 코드를 보내는 작업이 남았어요.

별일 없어도 또 와서 소식 남길게요~

그럼 즐거운 치킨 생활, 즐거운 주말 되세요!

치킨랭크

당신의 최애 치킨은 무엇인가요?

10
4
자허토르테

자허토르테

2024년 개인 프로젝트 제작기 (2)

🗣️ 이번의 이야기

저번에는 프로젝트의 계기와 그 준비 과정에 대한 이야기를 적었다.

photo-1522435229388-6f7a422cd95b.jpg

여기서는 1주차에서 기본 요소라고 생각한 페이지들을 구현하면서 배우거나 알게 된 점들을 적어보고자 한다.

Next.JS가 아닌 Vite로 진행하니까 구현할 때, 설정 면에서 차이점을 느끼기도 했고, 또 하다 보니까 Firebase나 styled-components 등 이미 익숙하다고 생각했던 것에도 고민하거나 헤멘 부분들이 나오기도 했다.

그 중에는 진짜 글자 하나 때문에 발생한 사소한 실수도 있었는데, 그런 것까지도 이번에는 잊지 말자고 생각해 이렇게 글로 남겨봤다.

⚠️ Vite에서 환경 변수를 불러올 때의 주의점

Next.JS 등을 사용할 당시에 env 파일에 배치한 환경 변수를 불러올 때, 보통 process.env.(변수명)으로 불러왔던 기억이 있다.

Vite에서 환경 변수를 불러올 때는 그 형식이 좀 다르다는 걸 깨달았다.

  1. 일단 env 파일에서는 변수명 앞에 VITE_라는 접두사를 붙이자.

Untitled (19).png

Vite 내에서 사용할 환경 변수를 정의하고 싶다면, ‘VITE_’라는 접두사를 붙여야 한다. (envPrifix를 통해서 접두사 규칙을 변경할 수 있는데, 그게 아니라면 저 접두사를 꼭 붙여주자.)

  1. 환경 변수를 받아올 때에는 process.env.(변수명)이 아닌 import.meta.env.(변수명)이다.

Untitled (18).png

Vite에서 환경 변수를 쓸 때는 위의 이미지처럼import.meta.env.(변수명)으로 불러와 써야한다.

왜 이렇게 써야하는지, 변경할 수는 없는지 궁금해서 찾아봤지만 별다른 언급을 찾지 못해서 이대로 써야하는 것이 규칙인 듯 하니 Vite로 프로젝트를 하는 사람들은 이 점을 주의하는 게 좋겠다.

📩 Vite에서 public 폴더 경로에 있는 파일을 불러오는 방법

프로젝트 내 이미지 파일이나 svg 등 에셋들은 전부 public 폴더에서 관리하고 있다.

Vite에서는 참 고맙게도 public 폴더 자체에 대한 접근 경로를 따로 설정할 필요 없이 public 디렉토리를 바로 바라보도록 적용되어있다.

위와 같이 public 디렉토리가 기본적인 설정으로 되어있어서, 해당 디렉토리 내 추가 경로만 작성해주면 원하는 에셋을 가져올 수 있다.

🤦 env 파일에 배치한 Firebase API 변수 값을 받아오지 못 하는 문제

결과부터 말하자면, env 파일 내 환경 변수를 불러올 때 글자 하나를 지우지 않아서 발생한 문제였다.

정말 단순한 문제이지만, 오답 노트처럼 또 실수하지 않기 위해 남긴다.

Untitled (17).png

환경 변수에서 value 값 뒤에는 객체를 만들 때처럼 다음 key와 분리하기 위해 ‘,’를 찍을 필요가 없다.

바로 다음 줄로 넘어가서 다음 key와 value를 입력하면 되는데, 습관적으로 ‘,’를 찍은 바람에 나중에 API 테스트를 할 때 콘솔창에 Firebase의 API key가 없다는 경고가 나왔다.🤦

Untitled (16).png

사소한 문제지만, 그래도 안 짚고 가는 것보다 짚고 가는 게 중요하니 주의해두자.

❓ TypeScript에서 **try-catch** 문의 **error** 인수의 타입이 unknown이라고?

프로젝트 내에서 Firebase의 모듈을 데이터 처리를 할 때는 try-catch 문을 사용해여 에러 관리를 하고 있다.

근데 catch 문 안에서 error 메시지를 처리하려고 하니, error의 타입이 unknown으로 찍히고 있다는 것을 깨달았다.

Untitled (15).png

그냥 string으로 변환하면 되겠지-라고 생각하다가, 돌이켜보니 어라? 하고 급 호기심이 생겼다.

  • 왜 unknown인 걸까?

  • 그럼 해당 타입을 고려해서 예외 처리를 어떻게 진행하면 좋을까?

우선 왜 unknown인가에 대한 답을 찾기 위해서 구글링을 해봤는데, unknown인 타입 상태에서 어떻게 하면 문제를 해결할 수 있는가와 연관된 글은 많고, 왜 unknown으로 적용된 것인지에 대한 글은 찾기 힘들었다.

결국, 이 경우엔 ChatGPT의 힘을 빌려서 알아봤는데..

Untitled (14).png

결과적으로 catch 문 속에서 어떤 타입의 오류가 발생할지 모르므로 안정성 및 예측 가능성을 고려해 해당 타입이 디폴트로 적용된 것이라는 내용이었다.

단, 타입이 이런 만큼 error의 값을 제대로 사용하려면 타입을 명확하게 처리해야 한다. 안 그러면 아래와 같은 이슈가 발생한다.

Untitled (13).png

자, 이제 error의 타입이 왜 unknown인지 알았으니, 예외 처리를 진행해보고자 한다.

‘왜?’ 라는 글은 찾기 힘들었어도, ‘어떻게?’ 라는 글은 많아서 둘러봤는데 대다수의 글이 ‘타입 좁히기/내로잉(Narrowing)’을 이용해 문제를 해결했다.

Object is of type 'unknown'

위의 글에서 catch 문의 error 인자값을 처리하는 방법으로 instanceof를 활용했다.

instanceof란 대상이 ****어떤 class나 생성자 함수를 사용하여 생성됐는지를 판단해주는 연산자이다.

(한동안 잊고 있었다가 예전에 이고잉 님의 강의를 보면서 정리했던 내용이 있는데, 궁금한 사람은 해당 내용을 참고해주길 바란다.)

이 연산자를 이용해서, error 인자에서 받아오는 값이 Error class를 가지고 있는지 분간하여 예외 처리를 진행하면 된다.

Untitled (12).png

기본적으로 흔히 우리가 자주 보는 Uncaught Error와 같이 콘솔에서 찍히는 에러들은 Error class를 가지고 있다.

따라서 이에 해당하는 친구들을 if문을 통해 분류하고, 아닌 친구들은 우선 문자열로 변환해 반환되게 임시로 처리했다.

지금 당장은 이 정도면 충분할 것 같다.

추후 프로젝트가 어느 정도 진행되면 Sentry를 배치할 예정인데, 양식을 만들고 나서 수정해도 늦지는 않을 거다.

🤔 Firebase Auth 템플릿의 작업 URL 처리, 그리고 페이지 렌더 이슈…

이렇게만 보면 어떤 문제인가 싶은데, 우선 Firebase Auth의 이메일 템플릿을 적용할 수 있는 부분은 이번 프로젝트에서 크게 두 가지로 갈린다.

  • 이메일 주소 인증을 위한 이메일 (본인 인증)

  • 가입한 이메일 주소를 통해 비밀번호 재설정 링크를 받을 이메일 (비밀번호 변경)

두 이메일은 같은 작업 URL을 공유하게 되는데, 받은 이메일을 통해 들어가야 하는 path가 각기 다른 점 때문에 작업 URL을 분리할 수 없다는 단점이 발생했다.

  • 이메일 주소 인증: /signupcomplete

  • 비밀번호 재설정: /findpassword

만약 이메일 주소 인증 경로(‘~~/signupcomplete’)로 작업 URL을 설정했을 시, 위의 두 케이스에서 보내주는 템플릿 메시지 내 URL은 아래와 같이 적용된다.

Untitled (11).png

이 경우, 비밀번호 재설정도 이메일 주소 인증 페이지로 이동하게 된다는 단점이 발생한다.

결국 어떤 식으로 동일한 작업 URL을 유지하게 할 것이냐가 문제 해결의 포인트인데, 이전 프로젝트에서는 하나의 페이지에서 switch-case를 이용해 경우에 따라 다른 컴포넌트들을 받아오게 했다.

하지만 이제와서 보니 case에 엮일 컴포넌트들을 다 배치해야 하는 만큼 무겁지 않을까? 비효율적이지 않을까? 라는 의문이 들어 좋은 방법이 아니라고 생각했다.

그렇다면 이번엔 차라리 공용으로 쓸 새로운 path를 추가하고 Custom Hook을 이용해 케이스에 따라 다른 path로 redirect 해주는 건 어떨까? 라고 생각해 쌈마이하게 방법을 바꿨다.

Untitled (10).png

redirect라는 path를 추가한 다음, Custom Hook에서는 진입한 링크의 params 중에 mode의 값이 이메일 인증이냐, 비밀번호 재설정이냐에 따라 react-router-dom의 useNavigate를 통해서 페이지를 redirect하도록 유도했다.

Untitled (9).png

보통이라면 그냥 useNavigate를 활용해서 보내주면 되겠지? 라고 생각하고 경로를 추가해서 바로 보내줬는데… 페이지로 이동은 되지만 렌더가… 바로 되지 않았다.

ezgif-2-824514c18a.gif

콘솔을 확인해보니 에러로 나오는 사항도 없었기 때문에 왜 이런 일이 생겼는지 솔직히 아직도 원인을 모르겠다.. 누군가 알려줬으면!

어쨌든 문제는 해결해야 하니까, ‘어떻게 하면 될까?’라고 고민하던 중에 혹시 렌더 타이밍이 너무 빠른 걸까? 싶어서 아래와 같이 setTimeout을 배치하고 시도해봤다.

Untitled (8).png

그래서 테스트 결과는 아래와 같이 문제 없이 redirect되면서, 페이지 렌더링도 잘 적용됐다.

ezgif-5-20eb812dab.gif

정말로 렌더 타이밍이 너무나도 빨라서 그런 걸까?

문제가 해결됐으니 만족스럽긴 한데, 정확한 원인을 모르니 체기가 남은 느낌이 든다...

😖 useLayoutEffect의 Dependency Array가 비어있는 데도 두 번 돈다?

이메일 인증 완료 처리와 관련하여 위의 이슈와는 별개로 인증 완료 페이지에 처음 진입 시, 의존성 배열(dependency array)를 비워놔도 useLayoutEffect 속 로직이 한 번 더 동작하는 것을 깨달았다.

그러다보니 첫 동작 시에 인증은 완료되지만, 렌더 후에 한 번 더 인증 절차가 작동하게 되는 이슈가 발생했다.

다행히 Firebase 쪽에서는 비활성화된 코드라면서 에러를 내뱉고 동작을 막아줘서 큰 문제가 되지는 않는데, 그럼에도 한 번만 동작하면 되는 것을 두 번 동작되고 그러니 의도한 그림과는 달라서 이 부분을 해결해보고 싶었다.

Untitled (7).png

예전에 useEffect와 useLayoutEffect를 공부했을 때, 둘의 차이점은 렌더링 전/후를 기준으로 첫 동작 시점에 차이가 있다는 것 뿐이었고 의존성 배열에 대해선, 두 훅 모두 비어있다면 첫 동작만 실행된다는 공통점이 있다는 걸 기억하고 있다.

혹시 내가 잘못 알고 있었나..? 싶어서 일단 useLayoutEffect 훅 내 코드에 문제가 없던 건 아닌지 고쳐보기로 했다.

우선 인증 처리 함수를 useLayoutEffect 외부에서 생성해, 해당 함수를 useLayoutEffect 안에서 호출하도록 했다.

const applyActionCodeAndVerifiedAccount = useCallback(async () => {
  const actionCode = await searchParams.get("actionCode");
  if (actionCode === null) {
    throw new Error("The Action Code is invalid.");
  }
  await applyActionCode(auth, actionCode);
},[auth, searchParams]);

useLayoutEffect(() => {
  applyActionCodeAndVerifiedAccount();
}, [applyActionCodeAndVerifiedAccount]);

이 때, 외부로 뺀 함수 applyActionCodeAndVerifiedAccount는 렌더링이 될 때마다 유지되는 게 아니라 새로 생성되는데 그러면 useLayoutEffect도 해당 함수가 변화한 것을 인지하고 리렌더링을 일으키므로 잘못하다간 무한 리렌더링을 유발할 수 있다.

그래서, 함수에 useCallback을 적용하여 더 이상 렌더링이 일어나지 않게 방지했다.

(아, 참고로 저렇게 처리를 안 하면 React가 The ‘~~~’ function makes the dependencies of useLayoutEffect Hook change on every render.라면서 친절하게 수정하라고 경고해준다.^^)

저렇게 함으로서 함수도 변경되는 사항이 없을테니 한 번만 돌 것이라 생각하고 테스트해봤는데.. 똑같이 한 번 더 돌아서 에러가 내뱉어지는 건 여전했다.

Untitled (6).png

이러다보니 아예 함수를 useLayoutEffect 안에 넣어, 훅 내부에서만 돌도록 하면 될까? 라고 생각했지만, 이거도 생각해보니까 useLayoutEffect 속 내용이 두 번 도는 건 변함이 없다.

사고가 마비된 느낌이라서, 잠시 쉬었다가 다시 곰곰히 생각해봤는데..

그럼 사실 useLayoutEffect는 문제가 없고 외부의 요인에서 문제가 있는 건가? 🤔

접근을 다르게 보고 검색을 시도해봤더니 아래와 같은 블로그 글이 보였다.

[개발일지 #3] UseEffect는 왜 두번 실행되는걸까?

한 마디로, React에서 내부 로직을 엄격하게 검사하기 위한 StrictMode의 영향이라는 듯 하다. 그래서 StrictMode를 지워보고 테스트해봤다.

Untitled (5).png

깔끔하게 해결이 됐다.. 휴, Hook과 관련하여 내가 여태까지 잘못 알고 있었나 싶어서 걱정했는데 다행히 틀리진 않은 것 같다.

아무튼 원인을 알았으니 StrictMode를 지우고.. 쓰려고 했는데 내부 코드까지 검사해준다는데 개발 당시에는 지우지 않아도 괜찮을 것 같아서 유지하기로 했다.

🔍 닉네임 글자 검사를 Byte 수로 체크하면 안되는 걸까?

이번 프로젝트는 다국어 지원을 염두해두고 있는데, 그러다보니 닉네임과 관련하여 고민이 생겼다.

‘사람마다 닉네임을 지을 언어가 다 다를텐데 이걸 어떻게 처리하는 게 좋을까’라는 부분이었는데 이에 대한 해결책으로는 Byte로 계산해서 처리하자! 라고 답이 쉽게 나왔다.

흔히 기억하기로 영어랑 숫자는 1바이트이고, 한글이나 일본어, 한자는 2바이트라는 이야기를 건너건너 들은 적이 있어서 그렇게 처리하면 되겠지? 라고 생각했는데…

Untitled (4).png

…정말 안일한 생각이었다는 걸 반성한다. 뭐든지 건너 들었다고 해서 ‘이거면 되겠지?’라고 생각하지 말고, 검증을 해보자.

  1. 우선 string을 Byte로 계산하고 싶은데 방법이 있을까?

있다. Blob 인스턴스를 통해 string을 UTF-8로 인코딩해서 Byte 수를 계산하면 된다.

Get Byte size of the string in Javascript

function countStringConvertToBytes(string) {
    return new Blob([string]).size;
}

이렇게 하면 string이 총 몇 Byte인지를 알 수 있다.

  1. 그래서 영어와 숫자는 1 Byte, 일본어랑 한국어는 정말 2Byte일까?

결과는 아래 이미지로 대체하겠다.

Untitled (3).png

‘16 Byte로 제한하면 되겠지’라고 단순하게 접근한 내 스스로가 원망스럽다..

이렇게 될 경우, 한글과 일본어는 의도와 다르게 5글자까지 입력이 될 것이고, 영어와 숫자는 혼합하더라도 16자까지 입력은 가능하다.

여기서 더 케이스를 생각해본다면..

  • 차라리 24 Byte로 늘리는 건?

    • 영문, 숫자도 24글자 입력되는 건 너무 긴 것 같다.

  • 그렇다면 영어랑 숫자만 있다면 16Byte로 제한하는 건?

    • 사이에 한글이나 일본어가 들어간 순간의 예외 처리는?

      • x지죤너구리x 같은 닉네임의 처리는?

Untitled (2).png

이러다보니 답이 도저히 나오지 않았고, 끝내 대안을 두 가지 정리해봤다.

  • 영어와 숫자로만 닉네임을 만들 수 있도록 하여 16자까지 입력 가능하도록.

  • 혹은 이메일 주소의 아이디 부분을 닉네임으로 강제로 부여하도록.

그 밖에도 정규식으로 해결볼 수 있지 않을까? 라는 생각도 해봤는데, 이건 ChatGPT를 통해서 좀 핑퐁해봐야 할 것 같고… 닉네임이 쓰이는 페이지가 현재로서는 메인 페이지 밖에 없어서 우선은 2안으로 진행하기로 했다.

사실 1안이 가장 Best라고 생각하고 있는데, 우선은 기능 추가 전까지는 2안을 유지하고, 분명 닉네임을 더 쓸 수 있는 요소가 추가되면 1안으로 바로 되돌릴 수 있도록 유연하게 생각하기로 했다.

💅 styled-components의 prop 처리 - Transient Prop?

공용 버튼 컴포넌트를 제작한 후, 페이지에 배치를 하던 중에 bgColor라는 props을 만든 뒤, ‘돌아가기’ 버튼의 배경색을 변경해야 해서 해당 prop에 ‘invalid’로 값을 적용했던 적이 있었다.

그러더니 콘솔에서 다음과 같은 에러가 출력했다.

Untitled.png

해당 에러가 발생하는 이유는 bgColor라는 저 Prop이 DOM에 있는 HTML 요소들에 직접적으로 연결될 수 있다는 건데, 에러 메시지 쪽에서는 이런 문제를 방지하기 위해 스펠링을 모두 소문자 케이스로 변경하라고 하지만, props를 카멜 케이스로 쓰도록 규칙을 잡아놨으니 그건 좀 어려울 것 같았다.

다른 방법이 있을까 구글링을 해봤는데, prop의 앞에 달러 사인(’$’)을 붙여 해당 Prop이 HTML 요소에는 직접 관여하지 않으며, 오로지 styled-components에서만 쓰인다고 알리는, transient prop을 사용하라는 글들이 많았다.

Transient Props in styled-components

[ React ] styled-component에 props 보낼 때 나오는 warning 해결

Transient이 어떤 뜻인지 사전에서 알아보니 ‘일시적인, 순간적인, 일시적으로 머무르는’이라는 의미를 가지고 있다.

즉, ‘일시적인 프로퍼티’라는 건데 styled-components 문서를 보면 그 설명이 더 잘 나와있다.

스타일이 지정된 구성 요소에서 사용하도록 의도된 prop이 기본 React 노드로 전달되거나 DOM 요소로 렌더링되는 것을 방지하려면 prop 이름 앞에 달러 기호($)를 붙여 임시 prop으로 전환할 수 있습니다.

styled-components: API Reference

이걸 이용하면 styled-components에서만 사용하는 Prop을 DOM 요소에 직접 반영되는 문제를 피할 수 있다.

export type ButtonColorProp = {
  $bgColor?: "primary" | "invalid";
};
const Wrapper = styled.button<ButtonColorProp>`
  background-color: ${(props) =>
  isButtonBgColorPrimaryOrInvalid(props.$bgColor)};
`
export default function Button(props: ButtonProp) {
  const { text, type, bgColor, onClick } = props;
  return (
    <StButton.Wrapper type={type} $bgColor={bgColor} onClick={onClick}>
      {text}
    </StButton.Wrapper>
  );
}

이번 프로젝트에서 사용한 코드 중 일부인데, 버튼의 색을 경우에 따라 다르게 바꿔야 할 필요가 있다보니 위와 같이 작성하였다.

bgColor라는 Prop은 DOM 요소에는 없는 속성이니 이런 식으로 Transient Prop을 통해 styled-components에서만 반영되어서 쓰도록 해 DOM 요소에 영향을 주는 것을 방지했다.

한편, Transient Prop 관련 내용을 찾다보니 해당 기능을 사용할 때의 주의점을 정리해주신 분이 계셨는데 위의 기능을 쓰려는 사람들은 한 번 읽어보는 것이 좋을 것 같다.

Untitled (1).png

[styled-components] Transient props($propName) 사용 시 주의할 점 (feat. shouldForwardProp)

🎙️ 다음 이야기는…

1주차에서 하고 싶은 말을 다 했으니, 이제 2주차 내용을 정리하기 시작해야겠다.

2주차에는 메인 페이지와 준비물 생성에 관한 이야기를 작성하고자 한다. 슬슬 Firestore 배치도 진행하고, 준비물을 어떤 구조로 저장하고 받아올지도 생각해봐야 하고…

한 고비 산을 넘겼더니 다음 고비 산이 떡하니 나를 맞이해주고 있는데 그 산을 넘어가면 조금이라도 성장한 내가 있겠지? 긍정적으로 생각하고 작업에 집중해야겠다.

au revoir!

🔖 참고 자료
Vite-Vite의 환경 변수와 모드

Vite-envPrifix

Vite-public 디렉토리

[09/29] 'Uncaught ReferenceError: process is not defined' error

Object is of type 'unknown'

Get a catch block error message with TypeScript

TypeScript에서 catch block error message 사용하기

'instanceof'로 클래스 확인하기

A Complete Guide to useEffect — overreacted

React.js - exhaustive-deps-warning, react, react-hook

Get Byte size of the string in Javascript

Transient Props in styled-components

[ React ] styled-component에 props 보낼 때 나오는 warning 해결

[styled-components] Transient props($propName) 사용 시 주의할 점 (feat. shouldForwardProp)

1
0
최영원

최영원

오픈 소스 프로젝트로 먹고살 수 있을까?

안녕하세요 클럽에 합류한 기념으로 자기소개 드려요.

헬스케어 분야에서 AI 연구원으로 일하다가, 이제는 세상에 임팩트를 줄 수 있는 오픈 소스 프로젝트를 만들고 싶어 혼자 프로덕트를 만들고 있는 최영원입니다.

요즘 저는 오픈 소스 프로젝트를 키워가면서도 먹고 살 수 있도록 비즈니스 모델을 찾는데 고심하고 있어요.

AI 연구자로 주 분야는 vision 입니다. 예측 모델과 생성형 모델을 모두 다루며 특히 구조가 있는 데이터와 AI-human 협업 연구에 집중했으며, 요즘은 pruning에 특히 집중하고 있습니다.

2016년부터 AI 연구를 진행하면서 약 9년간의 트렌드를 가까이서 지켜봤기에, 꼭 vision 쪽이 아니어도 AI 관련해서는 나름 할 수 있는 이야기를 쌓아왔다고 생각합니다. (저도 핫한 LLM 하고 싶어요!)

통계학으로 박사 학위를 받았고, 미국 UCLA 병원 영상의학과에서 메디컬 현장에 AI를 적용하기 위한 연구를 진행 했습니다.

박사과정 중 메디컬 분야에서 2016년, 2017년 MICCAI 학회의 뇌경색 병변 예측 첼린지에 저희 팀이 2년 연속 1위를 하면서 메디컬 분야와의 인연이 시작 되었어요.

2016년이면 AI가 이제 막 유명해지기 시작할 때인데, 시기를 잘 탔다고 생각하고 있습니다 ;) 덕분에 미국에서 포닥 자리를 잡을 수 있었습니다.

스마트폰 얼굴 인식 프로젝트를 진행하면서, 개인별 얼굴 생성에 대한 생성형 AI 논문으로 ICML 2021에 1저자로 논문을 개재한 적도 있습니다. 데이터의 구조에 집중한 연구였는데, 지금까지도 가장 관심있는 연구 분야입니다.

요즘 생각과 AI 연구에 대한 사담을 나누는 걸 정말 좋아해요.

연구자로 가장 큰 낙도 다른 연구실 사람들과 두서없는 커피챗이었는데, 이제는 혼자 일하다 보니 커피챗 나눌 사람이 없네요. ㅠ

디스콰이엇에서 커피챗 나눌 수 있는 분을 찾아 헤메고 있어요!

18
10
이병우

이병우

[MOM 투표 서비스] 데이터 설계 우여곡절기



최초 구상

이전 글에서와 같이, 투표를 생성하여 투표하기를 할 때 어떤 데이터가 필요할지 러프하게 생각해 보았습니다. 가장 단번에 떠오르는 것은, 투표받을 사람과 각 사람 별 투표 개수였습니다. 데이터는 항상 받아서 클라이언트에 적용하기만 했지, 직접 만드는 것은 정말이지 일자무식이었습니다… 우선 interface를 만들어 나갔습니다. 그런데 생각해 보니 투표는 만든 유저 별로 다르게 생성되어야 하기 때문에 vote라는 콜렉션에서 무엇을 기준으로 다른 문서가 생성되게 할지도 생각해 봐야 했습니다. 이것은 투표를 만든 유저의 uid를 받아 각각 유니크하게 만들 수 있었습니다. 그리고 투표 생성 일시 정도가 떠올랐죠.

스크린샷 2024-02-14 오후 11.38.21.png그렇게 처음에는

  • 투표받을 사람: String[]

  • 투표 개수: Number

  • 유저 ID: String(uid)

  • 생성 일시: Date

이런 식으로 데이터를 생각해보았고, 클라이언트에서 구현해보았습니다. 투표를 생성할 때 받을 수 있도록 방법을 찾아보았는데, Firestore에 데이터를 추가하는 방법은 정말… 정말로 간단했습니다! Firebase를 클라이언트에 초기 셋팅 해주었으면, Firebase의 메서드만 사용하면 될 뿐이었죠.(Cloud Firestore에 데이터 추가 | Firebase)

구상했던 대로 vote 컬렉션에 문서를 생성해보았습니다.

시각화를 통한 개선

그제서야 부족한게 무엇인지 눈에 들어왔습니다. DB에 데이터가 들어가니 허전한 것들이 보이더군요. 머리 속에서 생각만하는 걸로는 허점이 많이 들어났고 정리가 잘 되지 않았습니다. 역시 도식화가 필요했습니다. 저는 다른 개발자들처럼 멋지게 다이어그램을 그리는 것이 어려웠기 때문에... 가장 익숙한 피그마에서 낙서처럼 프로토타입 캡쳐 이미지에 데이터를 끄적이면서 구상하기 시작했습니다. 이 과정을 통해 왜 시각화가 필요한지 진정으로 깨닫게 되었습니다! 흐름에 따라 배치를 해보니 필요한 것들과 데이터의 생성 및 업데이트에 대해 좀 더 명확히 머릿속에 들어왔습니다.

우선 투표받을 사람은 이름만 있으면 되는게 아니라 각 이름 별로 개수를 카운팅 해야 했습니다. 즉, 투표받을 사람의 이름과 투표 개수를 담을 객체 배열이 되어야 했죠. 또한, 투표 상태가 필요했습니다. 최소한 진행 중인 상태와 종료인 상태를 가를 수 있어야 했죠. 이런 식으로 완전 부실한 상태로 뼈대를 만들어, 일일이 테스트해보며 무엇이 부족한지를 떠올리면서 부족한 데이터들을 만들어 갔습니다. 그렇게 만든 데이터로

  1. 후보자 등록 → 투표 등록 완료(데이터 생성)

  2. 투표하기 → 투표 완료(데이터 업데이트)

이 단순한 플로우를 수행하는 것도 저에게는 여간 어려운 일이 아니었습니다… 등록한 투표에 들어가 후보자를 선택하여 투표하기를 완료했을 때 선택된 후보자의 투표 개수만 카운트를 올리는 것부터 난관이었고, 이 플로우를 하다 보니 동시에 총 투표 개수도 올려줘야 한다는 것을 알게 되어 수정하고… 소위 말해 굉장한 삽질이었죠. 이 과정 중에 생각해 본 적 없지만 테스트를 하다보니 필요한 데이터들을 추가적으로 더 많이 구상하게 되었습니다. 가령 가장 투표 개수를 많이 받은 후보자를 우승자로 나타내는 데이터나, 투표 문서의 id 등이 있었습니다. 최초 설계 이후에도 기능들을 구현하며 기획을 추가 및 조정하는 등 많은 변화가 있었죠.


마치며

이렇게 근본 없이 데이터를 설계하다 보니 우여곡절이 많았는데, 문득 백엔드를 하시는 분들의 설계 구상 방식이 궁금해졌고, 새삼 대단하게 여겨졌습니다..! 저는 단순한 설계에도 너무 오랜 시간을 소요하긴 했지만, 이 과정이 무척 재밌었습니다! 추상적인 나의 생각이 데이터가 되어, 화면에서 변화를 나타내고 데이터베이스에 쌓여 유의미한 결과물을 보여줄 수 있는 재료가 되는 이 흐름의 매력에 빠져버렸습니다! 물론 이 역할만이 다가 아니겠지만, 이 분야에 대해 좀 더 많이 경험하고 더욱 공부하고 싶어지는 계기가 되었습니다.

2
0
자허토르테

자허토르테

2024년 개인 프로젝트 제작기 (1)

💭 개인 프로젝트를 다시 시작하다.

회사에서 6개월 동안 일을 하고 계약 만료로 그만두게 됐다.

이후에는 지쳐있던 멘탈을 관리해야겠다 싶어 한동안 코드를 멀리하고 12월에는 여행을 다니고, 1월에는 많은 분들과의 커피챗을 나누면서 개인적인 시간들을 보냈다.

그렇게 기력이 조금씩 회복되니 취업도 다시 생각해야 하고, 조금씩 코드를 다시 잡아야겠다는 생각이 들면서 사고치기 주도 개발(?)에 따라 오랜만에 개인 프로젝트를 시작하기로 했다.

이번 프로젝트의 계기는 12월에 진행했던 18박 19일의 배낭 여행이었다.

하도 숙박을 여러 곳에서 머물게 되다 보니 놓고 가거나, 잃어버린 물건이 없는지 짐 체크는 여행 중의 일상이었다.

그러다보니 언제부턴가 준비물 리스트를 종이에 써서 체크하며 다녔는데, 매번 이 종이를 꺼내서 체크하는 게 나중가서는 귀찮게 느껴지기 시작했다.

여행에서 돌아오고 나니 이 때의 경험을 기반으로 프로젝트로 만들고 싶다고 생각했다.

하지만, 1월은 여전히 기력이 없어서 좀 더 다양한 분들과 이야기를 나누면서 휴식을 취했고, 2월이 되어서야 본격적으로 프로젝트를 건드리기 시작했다.

시작 전에 혹시나 있을까 싶어 레퍼런스도 찾아봤는데 여행 관련 플랫폼에서도 관련 기능을 지원해주는 곳이 없는 것 같아서 적은 수요는 그래도 있을 것이라고 판단했다. (후에 초링(@earthloverdev) 님과 커피챗에서 ‘트리플’에 관련 기능이 있다는 걸 들었다..ㅋㅋ)

Untitled.png(트리플의 여행 준비 체크리스트. 엄청 깔끔하다..)

이번 프로젝트의 이름은 ‘준비물 챙겼어?’이고, 이번 프로젝트의 목표는 다음과 같이 결정했다.

  • 당연히 최소 목표는 런칭이다.

  • 작업하면서 그 과정들을 블로그에 서술해보고자 한다.

  • 여행 커뮤니티에 홍보를 올리고, 1달 동안 MAU 10명 이상을 유지해볼 것.

  • 꾸준하게 고객의 이야기를 듣고 기능을 개선해나갈 것.

    • 기회가 되면 웹 앱으로의 변환도 고려해보자. (React-Native의 Webview 기능을 통해서)

작년에 진행한 프로젝트 경험에서 많은 걸 느껴서 그런지, 기획-디자인-개발-마케팅까지 모두 혼자 힘으로 하는 프로젝트를 이번에도 이뤄내보고 싶었다.

다만 저번에는 유지에 실패한 만큼 이를 반면교사 삼아 꾸준하게 관리할 수 있는 프로젝트로 만들어보고 싶다.

✌️ 초기 기술 의사 결정

이번 프로젝트의 초기 기술 선택은 아래와 같이 했다.

  • TypeScript

    • 요즘은 어느 모집 공고를 봐도 필수로 적혀있는 것 같다.

    • 앞으로도 TypeScript와는 계속 친해져야 하고, 잘 이해하면서 쓰고 싶어서 선택했다.

  • Vite

    • [2024-02-16 수정] 댓글의 김무용 님께서 말씀해주신 대로 Next.js는 프레임워크이고 Vite는 빌드 도구이다. 잘못된 비교 내용을 작성했어서 내용을 정정했다.

    • 폴더명으로 라우팅을 구축하는 Next.JS보다는 Create React App과 React-Router-Dom을 이용해 원하는 path와 원하는 컴포넌트를 연결짓는 방식을 선호한다.
      그래서, 이번 프로젝트는 빌드 도구를 통해서 직접 React 환경을 구축하기로 했다.

    • Vite를 쓴 이유는 Webpack과 달리 프로젝트를 구축하는 시간이 덜하다는 점이었다.
      Webpack으로 초기 세팅을 했을 당시, 세세한 옵션들까지 다 설정하는 것 때문에 시간이 오래 걸렸는데, Vite는 필요한 라이브러리만 결정하면 기본 세팅을 완료해주니 React 프로젝트를 시작하는 게 굉장히 편했다.

    • 아울러 Webpack보다 빌드 시간이 더 빠르다는 특징도 많이들 언급해주셔서 Webpack 기반인 Creact React App을 이용해 프로젝트를 진행했던 사항과 달리 이번엔 Vite를 기반으로 React 프로젝트를 진행해보고 싶었다.

  • Jotai

    • 상태 관리는 지금도 고민중이지만, 지난 경험을 돌이켜볼 때 이번 프로젝트에서도 클라이언트 내에서 관리할 값이 많지 않을 것이라고 생각했다.

    • Recoil은 저번 프로젝트에서 써봤으므로 이번엔 Jotai를 써보기로 했다. (zustand나 Redux Toolkit은 이번 프로젝트에서 쓰기엔 store로 관리할 만큼 큰 규모가 필요하지 않을 거라고 판단했다.)

  • Firebase

    • 한 번 먹어본 맛이 가장 익숙하고 좋은 맛이라고 했다.

    • 사실 Supabase를 추천해주신 분들이 계셨는데, 프로젝트가 한 계정 당 2개까지만 무료로 제한된다는 이야기를 듣고 접어뒀다.

      • 본 프로젝트가 이용자가 많아져 마이그레이션에 대한 고민이 생기거나, 다른 대규모 프로젝트를 계획하게 된다면 그때 써보지 않을까?

  • styled-components

    • 이전에 CSS-in-JS를 쓰는 이유에 대해서 고민한 적이 있다.

      • 이 방식을 쓰는 건 단순히 컴포넌트의 재사용성 때문에 쓰는 거였을까?

      • 돌이켜보면 특정 값만 props를 통해서 변경하면 되는, 재사용성보다는 상태 변화에 따라 즉각적인 값 변화가 가능해서 쓴 것에 큰 장점이라고 판단했었다.

      • 그래서 이번에도 무난하게(?) styled-components를 선택하기로 했다.

    • 근데, 가장 큰 이유는 이런 css 라이브러리들이 Window OS에서 이슈가 있는 듯 하다..

      • 서버 컴포넌트에서 기능을 적용해봤지만 되지 않고, ‘use client’를 입력해 클라이언트 컴포넌트로 적용해야만 기능이 잘 작동됐다.

      • 원인이 궁금해서 이슈들을 찾아봤지만, 이 이슈들이 closed라고 해도 내 쪽에서는 계속 발생했으며 일부 이슈 수정 방향에 대해서 다른 사람들이 만든 패키지들을 설치하라는 것도 있었는데 이럴 경우는 package.json이 지저분해질 걸 생각하니 좋지 않다고 생각했다.

      • 그런 이유에서 사실 드랍했는데, 지금 글을 쓰면서 생각해보니 지금 작업하는 환경이 Vite이고 CSR이라서 생각해보면 문제되지 않는 이슈….잖아?🤦

        • 이럴거면 진작 쓸 걸 그랬다, 으흑흑….

        • 하지만, 이미 진행이 좀 된 상태라… 나중에 마이그레이션 하게 된다면 고민해봐야겠다(…)

        • 혹시나지만 이러니 나한테 맥 쓰라는 사람 있으면 돈 없는 백수에게 사줄 거 아니면 그런 말 하지 맙시다ㅂㄷㅂㄷ

  • i18n-next

    • 이 라이브러리는 희망사항으로 설치했던 건데, 해외에도 이용자가 있으면 좋겠다는 바람이 있어서 설치해보고 적용해보기로 했다.

    • 언어 지원 기능을 구현한다는 가정 하에 기회가 된다면 해외 쪽 홍보도 해보고 싶은데.. 이건 게스트하우스 연줄을 이용해봐야겠다..(될 지, 안 될 지 모르겠지만!)

우선 기초 라이브러리는 추후에 또 변경이 있을 수는 있지만, 이렇게 시작하기로 했다.

추가로 좀 더 생각하고 있다면 만든 걸 가지고 React-Native로 옮긴 뒤 WebView로 써먹고 싶다는 건데 그건 일단 정착이 되고 나서 생각해도 늦지 않다..^^

지금은 구현하고 런칭부터 하는 것까지가 목표다.

🎨 대략적인 디자인 그려보기

요즘 여러 UI 관련 사이트에서 다양한 앱을 구경한 덕분인지, 디자인에 필요한 요소들이 어떤 것인지 판단되는 것들이 생기니까 디자인 초안은 생각보다 빠르게 그려낼 수 있었다.

다만 체크리스트니까 TodoList 기반의 웹사이트라고 해도, 이왕이면 쓰는 사람들이 좋아할 만한 디자인이었으면 좋겠다고 생각해 약간 욕심을 부렸는데, 이게 오히려 개인적으로는 화를 자초한 듯한 느낌이 든다..^^ (넣을 기능이 많아졌다는 이야기이다…😭)

스크린샷 2024-02-12 210657.png

색상에 대해서는 파란색으로 테마를 잡았는데, ‘도전’이나 ‘자유’를 의미한다고 해서 여행을 준비하는 사람들의 이미지와 어울릴 거라 생각하고 이쪽으로 결정했다.

현재 디자인은 아래 링크를 통해서 구경할 수 있다.

많이 부족하지만 일단 현재는 이 정도로 하고 추가할 게 있으면 조금씩 늘려갈 예정이다.

https://www.figma.com/file/p7uM1yZSHFh05LIsu5L0tj/개인-프로젝트?type=design&node-id=12%3A45&mode=design&t=WIrWKTVSY1NqLCB1-1

기획서는 공책에만 써두고 디지털로 옮겨놓지 않았는데, 요 figma 문서에 모든 기획 내용이 다 담도록 할 예정이다.

어느 정도 가닥이 잡힌 뒤에는 추후 ReadMe나 github wiki를 통해서도 작성해 두려고 한다.

👍 1주차에 한 작업들

  • 기본 요소 페이지 제작

    웹 사이트에서 기본 요소라고 했을때 떠오르는 것들이 몇 가지가 있다. (물론 사람마다 다르겠지만…)

    • 로그인, 회원가입, 비밀번호 찾기, 비밀번호 변경

    이번 주는 디자인 초안을 완료한 뒤, 바로 위의 페이지들의 구현을 진행했다.

    스크린샷 2024-02-14 161322.png

    figma의 Dev Mode가 결제자들을 대상으로만 지원해준다는 걸 듣고 좀 아쉬웠는데.. 어차피 기획, 디자인, 개발까지 다 하는 입장에서 생각해보면 사실 혼자서 모든 정보를 다 알고 있으니 큰 문제는 되지 않으리라.

    아무튼 개인적으로 필요한 값들은 figma에 별도로 메모해서 기록해뒀다.

  • 폴더 및 파일 구조에 대해서

    1. 케밥 케이스

    이번 폴더 구조에서 특이점이 있다면 파일명이 ‘케밥 케이스’로 되어있다는 건데, 처음에는 카멜 케이스나 파스칼 케이스를 쓰려고 했지만 이런 부분에서는 어디는 대문자로, 어디는 소문자로 쓰여서 통일성이 없다는 생각이 계속 들었다.

    이 부분에 대한 고민을 하고 있었는데, 마선생(@horse_sensei) 님께서 케밥 케이스를 말씀해주셨다.

    https://x.com/horse_sensei/status/1754095580274700321?s=20

    확실히 이 방식을 차용하니 생각했던 고민들이 다 해결되어서 만족스러웠다. 고마워요, 마선생 님!😄

    1. 같은 파일명

    이번 프로젝트에선 하나의 컴포넌트와 엮어있는 사항들은 전부 같은 이름을 차용하기로 했다. 아래의 이미지처럼 말이다.

    스크린샷 2024-02-14 162713.png

    위와 같이 컴포넌트명이 동일하다면, 엮어있는 hooks나 styles, types 등도 같은 파일명을 쓰도록 했다.

    이런 식이라면 해당 컴포넌트는 같은 이름으로 된 파일들에서만 관리된다는 걸 알 수 있고, 또 이슈 수정 시 컴포넌트를 특정하여 트래킹하기도 쉬울 거라고 판단했다.

    단, input, button과 같은 공용으로 쓰이는 요소들에 대해서는 common이라는 폴더에서 따로 관리하기로 했다.

    스크린샷 2024-02-14 163524.png

    1. 정책(policy) 폴더

    이번 폴더 구조에서 특이점인 폴더가 있는데 policies, 즉 정책을 가리키는 폴더이다.

    이 부분은 전에 회사를 다닐 때, 잠시 계시다 떠나신 시니어 개발자 분께서 코드는 내용이 무엇인지 읽히는 게 명확해야 한다고 말씀해주시면서 조건을 관리할 때 이런 식으로 하면 좋을 것 같다고 제안해주셨던 방이었다.

    스크린샷 2024-02-15 011118.png스크린샷 2024-02-15 011006.png확실히 여러가지 조건문을 놔둔 채로 있는 것보다 함수명을 명확히 작성하여 해당 코드가 뭘 의미하고 싶은지를 알 수 있도록 하는 게 보기 좋다고 생각했고, 이 방법을 언젠가 차용해서 프로젝트에 써 먹고 싶다고 생각했는데 때마침 이번에 기회가 됐으니 각 페이지 별, 그리고 common폴더에 policies라는 폴더를 만들어 따로 관리하도록 했다.

  • 코드에 대해서

    1. 합성 컴포넌트에 대해서

    이전 회사에서 같이 일했던 이트루(@lxxtrue16) 님께서 어드민 페이지를 작업했을 당시, 그 밖에도 특정 기능을 만드셨을 당시에 Object.assign 메소드를 차용한 합성 컴포넌트 방식으로 코드를 짜신 것을 본 적이 있었다.

    ([Object.assign은 두 개의 객체를 합쳐 하나의 새로운 객체로 반환해주는 메소드이다.](https://www.notion.so/2022-11-23-JavaScript-2-cf08027413c94888944a4c6c4c141a2e?pvs=21))

    당시에는 그 방식이 솔직히 귀에 들어오고, 눈에 보이던 상황이 아니었고(일에 쫓겨서 생각이 들어올 뇌의 용량이 없었다... 죄송함다…!!🤦), 나중에 작업하셨던 코드를 보고 그 때 이야기를 해주신 것이 생각나서 뒤늦게 관련 내용을 찾던 중에 아래의 글을 발견하고 읽어봤다.

    합성 컴포넌트로 재사용성 극대화하기 | 카카오엔터테인먼트 FE 기술블로그

    합성 컴포넌트의 장점은 하나의 메인 컴포넌트에 귀속되는 서브 컴포넌트들을 포함시켜, 필요한 사항에 맞춰 서브 컴포넌트들을 이용해 다양한 방식으로 커스텀 할 수 있다.

    스크린샷 2024-02-14 170828.png스크린샷 2024-02-14 170846.png

    이렇게 하면 하나의 기능에 대해서 다양한 방식으로 만드는 것이 가능하므로 재사용 하기에도 좋고, 컴포넌트 자체에도 유연성이 보장된다.

    다만, 현재 프로젝트에서는 재사용되는 컴포넌트가 위의 Description과 같은 하나의 Common 컴포넌트로 관리해서 해당 컴포넌트 자체를 통짜로 가져와 쓰고 있다보니 위에서 설명한 합성 컴포넌트의 의의가 현재 프로젝트 내에서는 굉장히 얕다는 문제점이 있지만...

    그럼에도 불구하고 이 방식을 채택한 이유는 필요에 따라 예외 케이스가 발생했을 때 이용해볼 수 있다고 생각했으며, 그게 아니더라도 UI 컴포넌트 요소 자체를 그룹핑하기에도 좋은 방법이라고 판단했다.

    따라서 현재 각 페이지 및 요소에 따른 컴포넌트들은 합성 컴포넌트 방식을 차용해서 코드를 짜고 있다.

    1. Custom Hook 배치

    솔직히 말하자면 회사를 다니기 전까지 Custom Hook이라는 걸 스스로 만들어 본 적이 없었다.

    웨잇세컨드에서 했던 것은 타인이 만든 코드를 참고해서 한 것 뿐이라 어디까지나 맛보기라는 느낌이었고, 실제 업무에서 Custom Hook을 접했을 당시에는 이를 어떻게 만들어야 할 지 전혀 감이 오지 않았다.

    때문에 회사를 다니면서 다른 사람들이 코드를 짜는 방식을 보고, 직접 이것저것 시도해보고 나서야 Custom Hook에 익숙해질 수가 있었다.

    이번에 컴포넌트를 만들 때 결심한 것은 하나의 컴포넌트 위에서 return 위의 코드는 무조건 Custom Hook으로만 배치하여 컴포넌트만 보게 만들자는 생각이었다.

    스크린샷 2024-02-14 172430.png

    이렇게 함으로서 컴포넌트 안에서는 컴포넌트만 볼 수 있고, 훅에서는 기능과 관련한 코드만 볼 수 있으니 깔끔하게 구역 정리가 가능하다.

    1. 디자인 시스템? 규격화?

    디자인 시스템? 이라고 이야기하기도 부끄럽지만, UI 등을 이번에 작업할 때 규격화를 해두면 나중에 특정 값을 모두 다 변경할 사항이 있을 때 이를 통해 다 같이 바꿀 수 있으므로 관리하기에 편할 거라는 생각이 들었다.

    이전 회사에서 퇴사하셨던 분 중에 디자이너 분과 함께 디자인 시스템을 연구하셨던 분이 계셨는데, 이분이 정리하셨던 유틸 방식이 개인적으로 엄청 좋았고 배울 점이 많았다.

    그래서인지 스스로 만들 프로젝트에서도 그분의 방식을 차용해보고 싶었고, 때마침 그 방식을 이번 프로젝트에서도 사용해보기로 했다.

    스크린샷 2024-02-14 173013.png

    위처럼 객체에 하나의 케이스를 묶어 놓은 뒤, 스타일에서 이 객체를 불러와 특정 key을 적용함으로서 객체 속에 담겨있는 스타일 요소를 한꺼번에 불러올 수 있다.

    스크린샷 2024-02-14 173134.png

    지금은 위처럼 폰트만 관리하고 있는데, 추후에 색상 등도 이쪽으로 해서 통일성을 가질 수 있도록 반영해 놓으려고 한다.


🎙️ 다음 이야기는…

초기 세팅은 언제나 많은 생각을 하게 만드는 것 같다.

만들면서 이 내용, 저 내용을 기록해두다보니 하고 싶은 말은 너무 많은데, 읽는 사람이 지루해지지 않을 정도의 글을 쓰려고 하니 분량이 참 쉽지가 않아서, 이번 글은 여기까지 쓰기로.

다음 이야기는 1주차에 하면서 몰랐던 것들, 헤멘 것들에 대한 간단한 것들을 정리해보려고 한다.

Vite의 환경 변수 설정이라던가, TypeScript의 try-catch문 내 catch 부분의 error 인자 타입에 관한 내용이라던가, 닉네임 란을 포기한 이야기 등 프로젝트를 구현하면서 고민했던 것들을 좀 더 정리하는 시간을 가져보고자 한다.

뒤늦게지만 이렇게 시동을 건 만큼, 이번 프로젝트도 좋은 결과를 만들어 낼 수 있기를.

Adios!

https://github.com/DrunkenNeoguri/project-elements

2
4
박경현

박경현

AI 소소하게 활용해보기

[동심일기]

어릴 때 다들 그림일기 써 본 경험이 있지 않으신가요?

오늘 있었던 일을 간단하게 쓰면 AI가 대신 그림을 그려주고 친구들과 공유해볼 수 있는 서비스입니다.

서비스 링크: https://dongsim.site

[AI를 활용해볼 수 있을까?]

갈수록 AI가 발전하고 있고 AI를 활용한 서비스들도 엄청나게 쏟아져 나오고 있습니다.

재작년 말부터 프로그래밍을 공부하던 저의 입장에서 AI의 발전이 무섭기도 했지만 잘만 활용하면 오히려 좋은 결과를 가져다 줄 수도 있지 않을까라는 생각이 들었습니다.

그래서 거창하지 않고 소소하게 일상을 공유할 수 있는 서비스를 만들어 보고 싶었습니다.

인스타그램 스토리를 보다보면 한번씩 친구들이 MBTI 테스트나 성격테스트 결과를 공유하는 것을 종종 볼 수 있습니다. MBTI 테스트의 폼은 동일하나 어떤 틀에 맞춰 해석하느냐, 디자인은 어떤가 등에 따라 마치 유행처럼 주기적으로 돌고 도는 것을 볼 수 있었습니다.

그래서 [사용자들의 공감 + AI 활용] 으로 사용자들끼리 공유하면서 유행이 될 수 있는 무언가를 만들어보고 싶었습니다.

[공감할 수 있는 무언가]

그러던 와중 우연히 아래와 같은 그림을 보았습니다.

그림일기.jpeg

(그림일기는 삐뚤빼뚤한 글씨와 그림이 포인트 아닙니까)

그림을 그려주는 서비스는 많이 있죠.

하지만 어릴적 쓰던 그림일기와 같은 느낌으로 만들면 동심을 자극할 수 있지 않을까… 라는 생각이 들어서 동심일기를 만들기 시작했습니다.

또한 생성형 AI의 특성상 인풋에 대해 어떤 아웃풋이 나올까라는 궁금증도 많았구요. (도파민 중독?)

어쩌면 상황과 정말 맞는 그림이 나와서 소소한 웃음을 줄 수 있을까? 라는 상상을 하면서요.

저는 프론트엔드를 공부하고 있었고 마침 동생은 백엔드 개발자였기 때문에 시간 날때마다 조금씩 만들어 나갔습니다.

<초기 시안>

초기 디자인.png

초기에는 모던한 디자인으로 만들고 싶었지만 이도저도 아닌 느낌이라 최대한 심플한 디자인으로 바꾸었습니다.

<변경된 시안>

스크린샷 2024-02-14 오후 5.10.44.png

그림일기의 느낌은 손글씨체가 정말 중요하게 작용하다고 생각했습니다.

그러던 와중 슈퍼맨이 돌아왔다에 출연한 대한민국만세 중 만세의 필체로 만든 글씨체가 있어 적용했습니다.

이렇게 자투리 시간을 활용해서 짧은 시간에 서비스를 만들어볼 수 있었습니다.

[AI는 어려워]

일기 내용은 100자 이내로 설정했고 일기 내용은 다음과 같은 과정을 거쳐서 사용자에게 보여줍니다.

한글로 일기 작성 → open ai api를 통해 영어로 번역 → hugging face에 있는 모델(https://huggingface.co/nerijs/pixel-art-xl)을 사용하여 그림 생성

AI는 그림을 정말 잘 그려줍니다.

퀄리티는 일반인이 그린 것보다 훨씬 높다고해도 과언이 아닐 정도죠.

하지만 오히려 동심일기에 맞는 병맛 그림체(?)를 찾는 일이 정말 어려웠습니다.

특히 일기 특성상 고유명사가 많이 사용되는데 이것을 AI는 인식을 제대로 못해서 엉뚱한 그림이 나오는 일이 허다했구요. 그나마 픽셀아트가 옛날 느낌을 줄 수 있을 것 같아 이미 모델링 된 api를 활용했습니다.

더 나은 방법을 찾고 있는 중이긴 하지만 아직은 찾지못했습니다… ㅎㅎ

혹시라도 엉뚱한 그림이 나오더라도 너그러운 마음으로 이해부탁드려요 .. 🥲

[동심일기를 만들면서 느낀점]

  1. 빠른 피드백 반영

빨리 만든 서비스인만큼 사용자 피드백도 바로바로 반영할 수 있어서 에러 처리나 공유 방식, 프롬프트 등을 조금씩 수정해나갈 수 있었습니다.

  1. 서비스를 만드는 목적

개발자라면 기술적으로 무언가를 계속 해보고 싶은 생각이 많이 듭니다.

어떤 기술을 내가 만드는 서비스에 적용하는 것이 정말로 필요한지 아닌지 어느순간 잊어버리게되는 때도 있었던 것 같습니다.

만약 동심일기를 서비스 관점에서 바라보지 않고 취업준비 포트폴리오용으로 생각했다면 작성된 일기들을 모아보는 피드, 베스트 그림일기 등 여러가지 시도를 해보았을 것입니다.

하지만 ‘누구나 소소한 재미를 얻을 수 있는 서비스를 빠르게 구현하는 것’이 목적이었기 때문에 딱 필요한 만큼의 기능만 개발하고 피드백을 통해 살을 붙여나가는 방향으로 생각을 더욱 굳히게 되는 프로젝트가 아니었나 생각이 듭니다.

그냥 지금 이대로 누군가가 재미로 사용하고 공유하는 정도만으로도 동심일기의 목적은 달성한 것이니까요 ㅎㅎ

5ff665750aca4f3f87d03d196db46a59.jpeg

이 그림이 다시 생각이 나네요 😂

동심일기

오늘 일기를 그림으로 생성해주는 서비스입니다.

6
4
김경환

김경환

작은 앱, 스케줄러가 앱스토어 생산성 차트 12위에 올랐습니다 💪

‘일정 관리’를 돕는 작은 달력 앱 ‘스케줄러’가 최근 앱스토어 생산성 차트 12위에 올랐습니다 😆 2024년 1월에는 주요 월간 지표도 2023년 12월 대비 2배 이상 성장했습니다. 지난 2년 동안의 노력이 조금씩 빛을 발하고 있는 것 같아 기쁩니다.

‘작은 앱’을 만들며 하고 있는 가장 값진 경험은, '작은 앱'을 지지해주시는 사용자 분들과 함께 고민하며 앱을 개선해 나가는 경험이 아닐까 싶습니다. 디자이너이자 개발자인 제가 ‘직접’ 사용자 분들과 소통하고 앱의 방향성을 조정해 나가는 건 참 놀라운 경험입니다.

그 과정에서 ‘작은 앱’의 형태는 어때야 하는지 점점 더 명확해지고 있어서 참 좋습니다 😊

 

스케줄러 앱

https://apps.apple.com/kr/app/id6467635137

IMG_5497.PNG
15
6
정동성

정동성

안녕하세요~

저는 디지털헬스케어 분야에서 9년째 사업개발과 전략기획을 담당해오고 있습니다.

디지털헬스케어 분야가 참 유망하면서도 어려운 분야 인데요, 그 중에서도 가장 큰 어려움은 사용자가 얼마 쓰지 않고 이탈해버린다는게 아닐까 싶습니다.

저는 이 문제를 게임요소와 연결하여 해결해보고 싶은 작은 소망이 있어요.

그래서 사이드프로젝트, 사내벤처, 창업 등 다양한 형태의 추진 방법을 열어두고 초기 단계 팀빌딩을 통하여 MVP 개발까지를 함께 하실 기획자와 개발자 분을 모시고 싶습니다. (아직 저 혼자에요!)

저는 투자유치와, M&A, 국책과제 및 각종 용역 사업들을 만들고 수행해 본 경험이 있어요.

하여, 사업화를 초기부터 염두에 두고 이 프로젝트를 추진해보고자 합니다

관심이 있으신가요?

아래 메일 주소로 연락을 주셔도 좋고, 얼굴뵙고 간단한 커피챗도 좋습니다(수도권)

Eco_eko@naver.com

관심과 궁금한 사항이 조금이라도 있으시면 편하게 부담없이, 익명 게시판에 글쓰듯이, 친한 옆 친구에게 대화를 걸 듯 편하게 말씀주세요!

아주 가볍고 편안하게 같이 대화를 시작하는 것부터 같이 해보길 희망합니다!

많은 관심 부탁드립니다

ps. 아참, 혹시라도 제 역할에서의 도움이 필요하신 분이 있으시다면 말씀주세요~ 도움이 되는 부분이 없을지 같이 고민해보겠습니다

감사합니다~

4
1
이현석

이현석

뭐먹지? 기능을 추가했어요

스크린샷 2024-02-10 오전 6.40.01.png

왠지 그런 날이 있잖아요.

뭘 골라야할지 모르겠고 그냥 누가 딱! 정해줬음 하는 날.

그럴 때를 위해 '뭐먹지?' 기능을 추가했습니다.

지금은 그냥 단순 랜덤 추천이에요.

앞으로 조금씩 더 똑똑하게 만들어보려해요.

그럼 새해 복 많이 받으시고

새해에도 즐거운 치킨 생활되세요~

치킨랭크

당신의 최애 치킨은 무엇인가요?

7
0
이향저향

이향저향

이향저향 출시 후기

안녕하세요.

저희는 한눈에 보는 향수 정보, 이향저향을 만들어가고 있습니다.

프로젝트를 개발하며 발생한 수많은 에러의 눈물으로 성장한 개발자

평생 쓸 글 최근에 다써가며 여러 채널 구석구석 뛰어다니는 마케터

창의력과 트렌디함을 모두 겸비한 팔레트 위의 마술사 디자이너

총 3명의 대학생 팀원으로 이루어진 저희 팀은 이향저향을 통해 국내 향수시장에 변화를 만들어보고자 합니다.

[그래서 '이향저향'이란?]

향수가 궁금하긴 한데 뭘 사야 할지 막막하고, 막상 백화점에서 직원에게 여쭤보자니 부담스럽고, 종류도 너무 많은데 정보는 다 흩어져 있어서 일일이 다른 사이트에 들어가서 검색하기는 번거로웠던 경험이 있으실 텐데요.

이와 같은 향수 관련 정보에 대한 접근의 불편함을 해결하고자 직접 만든 프로덕트, 이향저향을 소개합니다:)

- 검색을 통한 손쉬운 향수와 브랜드 정보 획득

이향저향에서는 지속력, 계열, 포함 향료 등의 향수와 향수 브랜드에 최적화된 정보를 다양한 조건에 맞게 검색하여 접할 수 있습니다.

- 국내에서 가장 빠르고 간편하게 접할 수 있는 향수 관련 최신소식

출시, 팝업 스토어, 할인 등과 같은 국내외의 다양한 향수 및 브랜드의 소식들을 이향저향이라는 하나의 플랫폼에서 가장 빠르게 접할 수 있습니다.

['이향저향' 왜 만들었어?]

무작정 팀으로 모인 저희는 창업과 관련된 지식은 하나도 갖고있지 않았어요.

그러다 보니 실제로 서비스 기획 과정에서 몹시 중요한 고려사항들을 배제하고 서비스의 주제와 방향성을 선정하였고, 결국 현실적인 문제점들에 직면하곤 했습니다.

이러한 과정을 통해 저희 팀은 아래 3가지를 만족시키는 서비스 주제를 선정해보기로 했어요.

1. 시장 내의 유저들이 겪고 있는 불편함이 존재한다.

2. 불편함의 해결이 수익실현으로 이어질 수 있다.

3. 팀원 모두가 공감하는 주제이다.

공교롭게도 저희 팀원들은 모두 ‘향덕’이었고, 향수 시장 내의 불편함을 느껴왔었기에, 이향저향이라는 서비스 주제를 선정할 수 있었습니다.

[개발은 어떻게?]

플랫폼 형태의 이향저향을 기획대로 실현하기 위해서는 개발이 필수적이었어요.

하지만 코딩 경험이 있는 팀원은 단 한 명. 그마저도 C, Python을 학교 강의를 통해 배운 정도가 전부였죠.

이와는 모순되게 저희 팀은 빠르게 프로덕트를 출시하여 시장의 검증을 받고 싶었습니다.

그래서 개발자는 기획의 방향이 잡히는대로 HTML, CSS, 자바스크립트의 학습을 시작했습니다.

또한 프레임워크를 위해 새 언어의 학습을 하기에는 시간이 촉박하였기에, 학습한 자바스크립트를 최대한 효율적으로 사용하기로 하였습니다.

따라서 프론트엔드에서는 가장 대중적인 React 라이브러리를, 백엔드에서는

Node.js 프레임워크를 사용하게 되었어요.

이러한 개발자의 노력에, 이향저향은 성공적으로 세상에 모습을 드러낼 수 있었습니다.

[재미있었던 점들]

기획부터 서비스 출시, 그리고 마케팅까지 모든 것을 팀 내에서 스스로 해내는 모든 과정이 재미있었습니다.

그 과정 속에서도 웹서비스를 처음으로 배포한 날과 같이 큰 변화와 성공이 있던 순간들이 유난히 기억에 남는 것 같습니다.

특히 마케터인 제 개인적으로는 각종 콘텐츠들을 기획하여 인스타그램 큐레이션 활동을 시작하고, 이 콘텐츠들에 대해 사람들의 긍정적인 반응을 듣는 과정이 너무 즐거웠어요.

추후 지속적으로 서비스를 확장해나가는 과정에서도 이런 변화와 성공의 순간들을 최대한 많이 만들어보고 싶어요.

[힘들었던 점들]

- 개발과 배포 사이의 간극

프로덕트 개발 과정에서 가장 어려웠던 점은 개발과 배포 사이 지식의 간극을 매우는 일이었어요.

앞서 말했듯이 이번 프로덕트를 위해 웹개발에 대한 공부를 시작했고, 실제 배포 경험이 없었습니다.

프론트엔드와 백엔드 모두를 혼자 다루기에도 벅찬데, 개발 환경과 배포 환경의 차이로 인해 에러가 발생하는 순간들은 개발자를 엄청나게 괴롭혔어요.

하지만 이러한 혹독한 과정을 통해 배포 환경의 구축에 대해 정말 많은 점들을 배울 수

있었습니다.

- 재학 중인 대학생들의 스케줄 관리

모두 대학생인 저희 팀은 직전 학기 학업과 프로젝트의 진행을 병행하였습니다.

그렇다 보니 각자가 프로젝트 진행에 힘쓰는 시간과 팀원 모두가 만나는 시간을 조율하는 과정에서 많은 어려움을 겪었어요.

잠을 조금씩 줄여가며 이러한 문제점을 해결하려는 개개인의 노력이 합쳐져 이러한 어려움을 최소화할 수 있었습니다.

[앞으로 '이향저향'은?]

현재의 이향저향은 향수에 대한 정보와 향수 시장 내 이벤트들을 손쉽게 접하는 채널의 역할을 하고 있습니다.

저희 팀은 단순히 향수 관련 정보의 획득에서 더 나아가, 개인별 시향기를 관리하고 사용자들의 향수 리뷰 분석을 통한 맞춤형 향수 추천을 통해 향수와 관련된 모든 활동이 단 하나의 플랫폼, 이향저향에서 이루어질 수 있도록 업데이트할 예정입니다.

그 꿈을 이루기 위해 당장 걸어야 할 첫 걸음을 시향기 작성 및 열람 기능으로 생각하고 있어요.

이향저향

한눈에 보는 향수 정보, 이향저향

9
1
니떡국 내떡국

니떡국 내떡국

주니어가 사이드 프로젝트를 하기 전까지 몰랐던 세 가지


안녕하세요! 니떡국 내떡국 개발팀입니다. 니떡국 내떡국(이하 니떡내떡)은 떡국에 고명을 올려주는 방식으로 새해 덕담을 나누는 온라인 롤링페이퍼 서비스입니다!

이전에는 니떡내떡 팀의 프로젝트 시작과 과정에 대한 간단한 글로 찾아뵈었는데요,

이번 메이커로그에서는 사이드 프로젝트를 하며 느꼈던 점과 그것들을 구체적으로 어떻게 적용했는지를 공유해 보고자 합니다.

6명의 주니어들은 어떤 문제를 깨닫고, 그걸 해결 하기 위해 어떤 노력을 했을까요?


1. 사람도, 코드도 완벽할 수 없다.

프론트엔드 팀원끼리 Next.js 공부를 같이 시작했다가, 뭘 만들면서 공부해볼까? 하고 의견을 나눴던게 프로젝트의 시발점이 되었어요.

사용하는 기술 스택인 넥스트와 테일윈드를 모두가 처음 써보는 상황이었기 때문에 초반 러닝커브가 큰 편이었습니다.

따라서 완벽하게 학습하고, 100% 최적화된 코드를 짜기는 어려운 상황이었어요.

중꺾마.png

그래서 ‘일단 구현하는 것’을 목표로 하고, 리팩토링은 완성된 이후에 진행하기로 했습니다.

그냥 공부만 하는 것보다 구현을 하면서 공부하니 이게 어떻게 적용되는지 눈으로 직접 볼 수 있어 이해에도 많은 도움이 됐고, 추후 리팩토링을 하면서는 리팩토링된 코드가 왜 더 효율적인지 더 크게 체감할 수 있었어요.

또한 코드뿐만 아니라 결과물을 기간 내 런칭하기 위해 기획 단계에서도 우선순위를 적용했습니다.

최우선적으로 구현되어야 하는 디자인/기능을 상/중/하로 나눠 우선순위가 높은 요소부터 함께 작업을 진행했어요.

중요도를 모두가 공유하니 이 업무가 왜 빨리 끝나야 하는지에 대한 같은 이해가 생겨 의사소통에도 도움이 되었습니다.

2. 사람 일은 한치 앞도 모른다.

뭔가를 만들어보자! 며 함께 모였지만 ‘사이드’ 프로젝트이다보니 누군가는 현업에, 또 누군가는 갑작스러운 일정이 생기는 날도 존재했습니다.

당장 오늘 점심도 뭘 먹어야 할지 모르는 것처럼 당연한 일이라고 생각합니다.

하지만 프로젝트를 완수해야 하니, 개인 일정을 상세하게 서로 공유해 개발 기간과 주차별 목표를 명확하게 설정했습니다.

프로젝트 일정 캘린더.png

(👆🏻 프로젝트를 기획하며 함께 설정했던 개발 기간)

또한 업무 공유를 위해 현업에서 많이 사용하는 Jira를 사용해보았는데요!

jira.gif

해야할 일이 생겨도 일감 등록이 간단해 쉽게 기록할 수 있었고, 진행 상황을 시각적으로 파악할 수 있는 칸반보드 덕에 매 주 목표치 대비 진도율을 명시적으로 확인할 수 있어 협업에 큰 도움이 되었습니다.

공유한 일정을 기반으로 촉박하지도, 과하게 여유롭지도 않게 개발 기간을 설정해 두었고 서로 진행도를 항상 공유했기 때문에 어느 지점에서 딜레이가 생겨도 큰 무리 없이 목표 기간 내에 개발을 완수할 수 있었습니다.

3. 백지장을 맞들면 당연히 낫다.

현업과 병행하거나 여러 개의 프로젝트에 참여하고 있는 팀원도 있기 때문에 서로 바쁘다는걸 인지 하고 있었습니다.

하지만 방해할까봐 걱정되어 꼭 필요한 질문을 미루지는 않기로 약속했어요.

자유롭게 의견을 공유하고 질문하는 분위기를 만들기 위해 서로 적극적으로 말을 나눴습니다.

또한 사는 지역이 달라 온라인으로 작업할 수 밖에 없는데 그러다보면 결국 내가 담당한 파트만 혼자 개발하게 되는 경우가 종종 있었습니다.

그래서 함께 작업하는 분위기를 만들기 위해 디스코드를 만들어 화면 공유를 켜놓고 모여서 각자 작업을 진행하곤 했습니다.

Untitled.png

화면 공유로 서로 어떤 작업을 진행하고 있는지 확인하고, 의견도 바로 나누며 혼자가 아니라 공동의 목표를 향해 작업하고 있다는 좋은 시너지 효과가 났어요!


프로젝트가 끝나면 이번에는 어떤 것을 잘했고, 아쉬웠는지, 그리고 그 과정은 어땠는지 복기하는 시간을 가져보곤 하는데요.

무엇보다 이번 프로젝트는 서로 존중하고 한 발 물러서며 의견을 경청하는 경험을 했기 때문에 다음에 다른 분들과 협업을 하더라도 이 태도를 바탕으로 진행할 수 있을 것 같아요.

여기까지 긴 글 읽어주셔서 감사합니다!

메이커 선배님들의 협업 팁이나, 어떠한 일화가 있었는지 남겨주신다면 경청하고 또 배워가도록 하겠습니다.

이스터에그.png

(👆🏻 용용이의 새해 복 인사 이스터에그를 찾으셨나요?ㅎㅎ)

새해 복 많이 받으시고 행복한 하루 되세요!

니떡국 내떡국

2024년 설날을 맞이해 롤링페이퍼에 마음을 담아요!🩵

7
1
니떡국 내떡국

니떡국 내떡국

주니어지만 사이드 프로젝트는 하고 싶어 (ft. 니떡내떡 개발 후기)


안녕하세요! 니떡국 내떡국 개발팀입니다. 니떡국 내떡국(이하 니떡내떡)은 떡국에 고명을 올려주는 방식으로 2024년 새해 덕담을 나누는 온라인 롤링페이퍼 서비스입니다!

니떡내떡의 개발팀은 디자이너 1명, 비전공 개발자 5명의 0~2년 차의 주니어입니다.

주니어끼리 얘기하다 보면 ‘사이드 프로젝트 하고는 싶은데 무엇을 어떻게 해야 할지 잘 모르겠다!’는 말을 많이 듣곤 했는데요!

평소 디스콰이엇의 메이커로그를 즐겁게 읽었고 ‘나도 뭔가를 만들어서 여기에 과정을 공유해 보고 싶다!’ 고 생각 해왔던 만큼,

니떡내떡을 배포 과정을 공유한 이 글이 또 다른 주니어분들께 도움이 되길 바랍니다.


사이드 프로젝트 그거 어떻게 하는 건데

study.jpg

사이드 프로젝트의 시작을 가로막는 진입 장벽! 바로 주제 선정입니다.

프로덕트를 만든다면 남들과 다른 주제여야 할 것 같고, 신박한 기능이 있어야 할 것 같아 도전을 망설이곤 했습니다.

그러다 부트캠프 동기인 프론트엔드 팀원들끼리 스터디를 하다가, 사용자가 우리밖에 없더라도 뭔가 만들어 배포해 보자! 는 이야기를 나누게 되었는데요.

이렇게 완벽하지 않아도 일단 뭐라도 해보자는 목적으로 시작한게 니떡내떡의 우연한 시작이었습니다. (그리고 그때는 정말 간단하게 구현할 줄 알았죠 🫨)

브레인스토밍 중 다가오는 설날의 덕담을 나눌 수 있는 뭔가를 만들면 어떨까? 하는 의견이 나왔고, 가장 상징적인 떡국에 고명을 올려 덕담을 나눈다는 컨셉을 좁혀갔습니다.

그 후 배포 날짜를 설날 2주 전으로 확정한 뒤 개발 기간에 맞게 기획을 추려내며 니떡국 내떡국의 개발을 시작하게 되었습니다!

어떻게 해야 '즐겁게' 협업할 수 있을까?

혼자 개발하면 본인 마음대로 진행할 수 있지만 다른 사람과 함께한다면 일정뿐만 아니라 의사소통, 결과물을 정리하는 방식까지도 맞춰가게 됩니다.

몇십 년을 같이 보낸 가족과도 가끔 트러블이 생기는 날이 있는데, 가족도 아닌 다른 팀원과도 그런 순간이 올 수 있지 않을까요?

저희는 이왕 하는 거 즐겁게, 잘 협업하기 위해 아래의 두 가지는 지키기로 약속했습니다.

첫째, 항상 듣는 사람의 입장에서 생각하고 서로를 존중하는 것입니다.

말씀드린 것과 같이 니떡내떡팀의 프론트엔드 팀원들은 모두 부트캠프 동기이고, 디자이너, 백엔드 팀원도 부트캠프를 통해 만난 인연입니다.

프로젝트 시작 전 팀원들끼리 함께 정했던 것은 업무와 친목은 별개이니 공과 사를 구분하자는 것이었어요.

니떡내떡 팀원들이 만난 지 1년이 다 되어가지만 아직도 서로에게 존댓말, 높임말을 쓰고 ‘~님’ 호칭을 유지하는 것도 그 이유인데요,

존댓말을 쓰니 서로 단어 사용에 더 주의하게 되었고, 자연스럽게 서로 존중하는 분위기를 조성할 수 있었습니다.

둘째, 함께하는 시간을 꼭 만드는 것입니다.

하루 종일 공부한 이후나 퇴근 후에는 쉬고 싶은 게 너무나도 당연합니다. 또, 내 의지와 상관없이 아픈 날도 있죠.

‘사이드’ 프로젝트이다 보니 팀원마다 사이드에 투자할 수 있는 시간이 모두 다른데요,

니떡내떡팀은 정기 회의 시간뿐만 아니라 주 1~2회 특정 요일은 같이 작업을 진행하는 날로 정해 그 시간만큼은 꼭 작업할 수 있도록 규칙을 정했습니다.

이렇게 일정 시간은 프로젝트에 할애할 수 있도록 고정된 작업시간이 있었기에, 팀원의 자유 시간도 어느 정도 함께 보장할 수 있었어요.

그리고 설날 2주 전 배포라는 공통의 목표가 있었고 기획 범위도 그에 맞췄기 떄문에, 과한 무리 없이 원활하게 일정을 진행할 수 있었습니다.

경험은 없지만 프로젝트는 잘 만들고 싶어

치즈덕_짤.png

(출처 : 나봄(@azzi_01)작가님 블로그)

니떡내떡 팀원은 취준생, 신입, 저 연차의 주니어들이기 때문에 아직 시야가 넓지 않았습니다..

사용자가 아닌 실제 유저에게 배포하는 메이커의 입장이 되어 가장 중점을 둔 부분은 '내가 만든 게 나만 이해하는 프로덕트가 되게 하지 말자’는 것이었습니다.

따라서 UI/UX를 담당하는 디자이너 팀원이 잘 이해할 수 있는 흐름인지 다각도로 고민해 기획과 디자인을 진행했고,

개발 팀원 또한 내가 코드로 구현한 부분이 기획에 잘 맞는지, 이 부분을 우리만 아는 게 아니라 사용자도 잘 따라올 수 있을지를 계속 고민하며 함께 의견을 나눴습니다.

덕분에 간단하지만 룰렛, 사진촬영 등의 재미 요소를 넣은 롤링페이퍼를 만들 수 있었고 긍정적인 피드백도 많이 들려와 보람찬 경험이었습니다☺️


위의 과정을 거치며 니떡내떡이 오픈한지 10일, 설날까지도 5일이 남았습니다!

그동안 니떡내떡은 유저 피드백을 받기도 하고, 새로운 업데이트를 하며 니떡내떡을 가꾸는 시간을 보냈습니다.

오픈을 하고 나니, 오픈했다고 끝이 아니라 그 다음 과정을 진행하는 것도 오픈만큼 어렵고 중요하다는 생각이 들어요.

한 달이라는 개발 기간 동안 고생한 팀원들의 한 마디를 나누며 글을 마무리하도록 하겠습니다.

다음번엔 니떡내떡 팀이 사이드 프로젝트를 하며 느꼈던 핵심 세 가지와, 그것들을 구체적으로 어떻게 적용했는지 풀어보는 글로 다시 찾아뵙겠습니다!

1_영은.png

짧은 기간 동안 서로에게 덕담을 주고받는 ‘니떡국 내떡국’을 만들기 시작하면서 공유 과정에 대한 고민을 많이 했어요. 내떡국을 공유하는 과정에서 이목을 끌만한 요소가 있어야 했기에, 떡국에 덕담을 남길 수 있는 필수 기능 외에도 덕담을 남기면 친구 캐릭터와 내 캐릭터가 사진을 촬영할 수 있도록 설계했어요. 결과적으로는 캐릭터에 대한 유저들의 반응이 예상보다 더 좋아서 뿌듯했어요. 또 프로젝트 진행 중에 생겨나는 고민들을 해결해 나가면서 디자이너로서도, 팀원으로서도 성장할 수 있었어요!

2_경록.png

혼자서 4명의 프론트엔드 개발자들의 작업을 서포팅 해야 하다 보니 부담감이 없지는 않았습니다. 하지만 오히려 백엔드 리소스가 적다는 것 때문에 큰 욕심부리지 않을 수 있었고 제공해야 하는 기능의 최소 스펙이 무엇인지 파악하는데 집중했었어요. 그 결과 프론트엔드 분들에게 적은 공수로 최대한 빠르게 API를 제공할 수 있었던 것 같아요. 사실 무엇보다도 백엔드 리소스가 부족하다는 사실을 모두가 인지하고 원래는 백엔드가 해야 하는 작업들이지만 프론트에서 대신 처리해 주고 많이 도와주셔서 무사히 프로젝트를 완성할 수 있었던 것 같습니다.

3_한솔.png

일정관리, 세팅, 공통 컴포넌트 등의 작업을 진행했는데 다들 시간을 쪼개서 진행하는 프로젝트기 때문에 어떻게 해야 효율적으로 구성할 수 있을까? 를 많이 고민하는 시간을 가졌습니다. 또 룰렛에도 많은 공을 들였는데 재밌다는 피드백을 받아서 뿌듯했어요. 다 같이 공식 문서를 찾아가며 새로운 스택을 적용해낸 프론트 팀원들, 너무 귀여운 UI/UX를 담당해 주신 디자이너님과 바쁘신데도 완벽하게 서버를 총괄해 주신 백엔드 팀원 모두에게 감사합니다.

4_유리.png

넥스트와 테일 윈드라는 처음 사용하는 스택으로 메인 페이지 및 인증 사진 촬영 기능 등을 개발하게 되었습니다. 개발하면서 크로스 브라우징(카카오 인앱 등)을 적용하는 과정에서 중간에는 포기하고 특정 브라우저에서만 실행되도록 유저에게 안내 메시지를 표시하도록 우회하는 방법을 찾을까 싶었지만 결국 해내면서 더 성장할 수 있는 계기가 되었습니다. 너무 보람찼고 하나씩 만들어가면서 개발이 즐겁다고 느꼈습니다.

5_주영.png

개발자로 일하면서 가장 즐거운 순간은 저희가 만든 서비스를 사람들이 사용할 때인 것 같아요. 설날이면 늘 주변 분들과 덕담을 나누는데 롤링페이퍼처럼 보낼 수 있다면 재미있겠다 생각하던 차에 마침 Next.js를 새롭게 공부해야 할 일이 생겼고 해당 기술로 서비스를 구현해야겠다 결심했습니다. 가장 좋은 학습 방법은 직접 서비스를 구현해 보는 것이라고 생각했거든요. 개인적으로 업무와 병행하기 어렵기도 했지만 업무와 별개로 또 다른 활력소가 된 경험이었습니다!! 서비스 규모가 너무 작지 않을까? 업무와 병행하기 어렵지 않을까? 고민하시는 분들이 있다면 꼭 프로덕트를 고민하고 완성하는 경험을 해보셨으면 좋겠어요! 팀원 모두들 애정이 많은 프로젝트라 아이디어가 엄청 많이 나왔었는데요. 내년에도 서비스 할수있게 된다면 더 많은 요소들을 담은 서비스를 만들어 나가고싶어요.

6_희제.png

Next.js를 처음 공부하며 프로젝트를 개발하는 거라 걱정이 많이 됐지만 팀원들끼리 적극적인 의사소통을 하며 합을 맞춰갔고 원활한 협업을 할 수 있었습니다. 그래서 오류가 생겨도 같이 고민해 줄 수 있는 팀원들이 있었기에 거리낌 없이 구현할 수 있었고 부딪치며 도전적으로 접근할 수 있었던 것 같아요. 이번 프로젝트를 하면서 같이 성장하며 팀원 모두가 재밌어하는 프로젝트를 하게 되어서 즐거운 시간이었습니다.


읽어주셔서 감사합니다. 새해 복 많이 받으세요!🎉

니떡국 내떡국

2024년 설날을 맞이해 롤링페이퍼에 마음을 담아요!🩵

5
0