<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>be-kid.log</title>
        <link>https://velog.io/</link>
        <description>멋진 개발자 되기</description>
        <lastBuildDate>Tue, 21 Oct 2025 02:08:22 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>be-kid.log</title>
            <url>https://velog.velcdn.com/images/be-kid/profile/129d4cc6-6aef-4514-a013-96172d966c55/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. be-kid.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/be-kid" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[왜 채용 공고를 올려놓으시는 거죠?]]></title>
            <link>https://velog.io/@be-kid/%EC%99%9C-%EC%B1%84%EC%9A%A9-%EA%B3%B5%EA%B3%A0%EB%A5%BC-%EC%98%AC%EB%A0%A4%EB%86%93%EC%9C%BC%EC%8B%9C%EB%8A%94-%EA%B1%B0%EC%A3%A0</link>
            <guid>https://velog.io/@be-kid/%EC%99%9C-%EC%B1%84%EC%9A%A9-%EA%B3%B5%EA%B3%A0%EB%A5%BC-%EC%98%AC%EB%A0%A4%EB%86%93%EC%9C%BC%EC%8B%9C%EB%8A%94-%EA%B1%B0%EC%A3%A0</guid>
            <pubDate>Tue, 21 Oct 2025 02:08:22 GMT</pubDate>
            <description><![CDATA[<p>채용 공고를 보고 맞춰서 열심히 이력서를 수정해서 제출함</p>
<p>읽지를 않음</p>
<p>? 이미 뽑혀서 그런걸까 ?</p>
<p>예를들어 10군데 넣으면 8군데는 안 읽음</p>
<p>뭐임?</p>
<p>이력서 수정하는게 무의미하게 느껴짐</p>
<p>그나마 읽은 2군데도 읽기만 하고 아무런 액션이 없음</p>
<p>스트레스</p>
<p>그냥 복붙으로 마구잡이로 넣어야되나 싶음</p>
<p>그냥 다른 직업을 알아봐야하나 ?</p>
<p>예전엔 그래도 서류탈락이어도 꼬박꼬박 알려줬던거 같은데.</p>
<p>심지어 채용 플랫폼이면 불합격 버튼 하나만 누르면 되는거 아닌가? 이전 직장 다닐때 그렇게 봤던거 같은데</p>
<p>인사 담당자들 사이에서는 읽씹 안읽씹이 유행인건가?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[흐음]]></title>
            <link>https://velog.io/@be-kid/%ED%9D%90%EC%9D%8C</link>
            <guid>https://velog.io/@be-kid/%ED%9D%90%EC%9D%8C</guid>
            <pubDate>Fri, 17 Oct 2025 08:02:13 GMT</pubDate>
            <description><![CDATA[<p>어제는 기능따고 담주 도로주행 교육 예약해놓고 왔다.
그리고 드디어 간이대지급금을 받았다. 8개월만에..
나머지 금액은 이제 소송으로 넘어가야한다. 후 ;;</p>
<p>이력서도 좀 넣고 프로젝트 하던거 마저 해볼까하는데 뭔가
막상 만들어놓고 나니 별로 재밌는 프로젝트가 아닌거 같다.
생각한 것 만큼의 비주얼이 안나와서 그런가.</p>
<p>또 다른것도 좀 구상하면서 지금하던거 다듬어봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[너무 많이 놀았다!]]></title>
            <link>https://velog.io/@be-kid/%EB%84%88%EB%AC%B4-%EB%A7%8E%EC%9D%B4-%EB%86%80%EC%95%98%EB%8B%A4</link>
            <guid>https://velog.io/@be-kid/%EB%84%88%EB%AC%B4-%EB%A7%8E%EC%9D%B4-%EB%86%80%EC%95%98%EB%8B%A4</guid>
            <pubDate>Tue, 14 Oct 2025 08:14:55 GMT</pubDate>
            <description><![CDATA[<p>연휴를 너무 즐겨버렸다!</p>
<p>언제는 미루고 미루던 운전면허 취득을 위해 기능 수업 2시간 듣고 와서 뻗어버렸고</p>
<p>오늘이 되어서야 다시 주섬주섬.. 해야할 일들을 한다.</p>
<p>이제야 체불임금확인서가 나와서 (4월에 신청함) 간이대지급금 신청도 하고 ..</p>
<p>또 채용공고 올라온거 없나 확인하고 지원해놨던거 열람한 곳 없나 또 보고</p>
<p>하지만 여전히 열람하지 않는다. 왜 안읽는지 궁금하다 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[쉽지가 않다]]></title>
            <link>https://velog.io/@be-kid/%EC%89%BD%EC%A7%80%EA%B0%80-%EC%95%8A%EB%8B%A4</link>
            <guid>https://velog.io/@be-kid/%EC%89%BD%EC%A7%80%EA%B0%80-%EC%95%8A%EB%8B%A4</guid>
            <pubDate>Thu, 02 Oct 2025 08:19:44 GMT</pubDate>
            <description><![CDATA[<p>디테일한 부분들을 건들이게 될수록 쉽지않아지는것 같다. (당연한 소리)</p>
<p>지금 하는것이 어느정도 정리가 되면 전체적으로 코드 리뷰나 정리를 해봐야할 듯.</p>
<p>이전에 회사에서 했던 프로젝트들을 다시 구현해보고 싶은 생각도 든다.</p>
<p>그때의 나와 지금의 나는 다르니깐 !</p>
<p>그리고 회사가 망해서 어차피 안돌아가고 있는 서비스들이기도 하고.</p>
<p>어서 뇌를 다시 말랑하게 해주어야겠다 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[gemini 버려]]></title>
            <link>https://velog.io/@be-kid/gemini-%EB%B2%84%EB%A0%A4</link>
            <guid>https://velog.io/@be-kid/gemini-%EB%B2%84%EB%A0%A4</guid>
            <pubDate>Wed, 01 Oct 2025 08:09:33 GMT</pubDate>
            <description><![CDATA[<p>마인드맵이 너무 느리게 만들어지는 문제를 해결하려하는데</p>
<p>gemini의 무한 삽질로 화가 날대로 나버려서</p>
<p>결국 gemini를 버리고 cursor로 넘어와서 다시 해봤다</p>
<p>지금 나랑 떠들고 있는 모델은 GPT-5 인듯 </p>
<p>근데 너무 잘한다. 속도도 다르고 뭐랄까 훨씬 똑똑하다</p>
<p>미친거같다 진즉 얘네랑 할걸 ㅎ</p>
<p>gemini는 이제 바이바이</p>
<p>둘다 무료플랜인데 이렇게 차이가 난다니 .. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[잘가는가싶더니~]]></title>
            <link>https://velog.io/@be-kid/%EC%9E%98%EA%B0%80%EB%8A%94%EA%B0%80%EC%8B%B6%EB%8D%94%EB%8B%88</link>
            <guid>https://velog.io/@be-kid/%EC%9E%98%EA%B0%80%EB%8A%94%EA%B0%80%EC%8B%B6%EB%8D%94%EB%8B%88</guid>
            <pubDate>Mon, 29 Sep 2025 10:15:28 GMT</pubDate>
            <description><![CDATA[<p>어제오늘은 전체적인 UX/UI 개선(?)과 세부 기능들 이것저것 수정했다. 여기까진 순조로웠다.</p>
<p>그런데 지금 마인드맵을 띄우는게 너무 오래걸려서 이부분 개선하려고 하는데 문제가 되는 부분과 개선 방법은 명확한데 gemini가 자꾸 헛돈다 ㅎㅎ</p>
<p>지금 상태는 마인드맵으로 보여줄 때 마다 유사도를 확인하느라 오래 걸리는거라 이걸 미리 저장해둘 수 있게 수정하려고 하는데 gemini가 자꾸 멍청한 짓을 한다. 답답해 죽을 지경</p>
<p>그래서 일단 다시 문제가 발생하기 전으로 돌아가서 처음부터 다시 해보려고 한다. 후 ;; 잘굴러가는가 싶더니 한번씩 이렇게 옆구르기를 하네</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사이드프로젝트 with Gemini]]></title>
            <link>https://velog.io/@be-kid/%EC%82%AC%EC%9D%B4%EB%93%9C%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-with-Gemini</link>
            <guid>https://velog.io/@be-kid/%EC%82%AC%EC%9D%B4%EB%93%9C%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-with-Gemini</guid>
            <pubDate>Thu, 25 Sep 2025 08:56:53 GMT</pubDate>
            <description><![CDATA[<p>gemini와 사이드 프로젝트를 시작한지 2주가 조금 넘은듯 하다.
이제 대충 핵심 기능들만 작동하는 정도로 만들어졌다.</p>
<p>사실 이렇게 오래 걸릴것도 아닌거 같은데 중간에 삽질 좀 하고
무료 버전으로 하다보니 하루 제한도 걸리고 이력서도 넣어야되고~ (핑계)
또 3번은 다 뒤집어 부수고 다시 만들고 했지 아마</p>
<p>그래서 조금 오래 걸리긴 했다.</p>
<p>처음엔 chat gpt랑 내 아이디어에 대해 이야기하며 기획이나 구현 방법을 구체화했다.</p>
<p>우선 내가 만들고 싶었던 것은 블로그처럼 글을 쓸 수 있는데, 내가 쓴 글들을 마인드맵처럼 보여주는 것</p>
<p>gpt는 OpenAI Embedding을 사용해 글을 벡터화하고 Supabase(pgvector)로 유사도 검색을 해 이를 프론트에서 띄워서 보여주면 된다고 했다.</p>
<p>처음엔 무작정 gemini에게 하나씩 명령했다. 뭐뭐해라 이거해라 저거해라
그랬더니 애가 정신을 못차린다. 자기가 뭐하고 있는지 모르는 듯한 얼빵한 대답들과 일처리.
세팅 단계부터 삐걱거리고 제대로 되는게 없어서 폐기처분하고 다시 시작
한번은 백엔드랑 프론트엔드를 gemini를 각각 실행시키니 서로 파악이 안돼서 또 폐기처분
결국 gpt랑 같이 GEMINI.md 만들고 하나의 gemini로 진행!</p>
<p>내가 뭐하고 싶은지 처음부터 끝까지 최대한 상세하게 설명하고 어떤 순서로 구현할건지 물어보고 한번 더 점검 !</p>
<p>내가 생각하기엔 회원가입/로그인 먼저 구현해야될 것 같은데 이놈이 또 포스팅 먼저 하겠다고 해서 헛소리하지 말라고 하고 회원가입/로그인 먼저 구현하기 시작했다.</p>
<p>이렇게 몇번의 삽질 후에는 그나마 순조롭게 진행이 되기는 했는데 그래도 중간중간 오류에 대한 해결이 아쉽긴하다. 자꾸 엉뚱한 곳에서 삽질해서 결국 내가 원인 찾아서 알려줘서 수정하도록 시킨다. 공짜 토큰 아껴야지 </p>
<p>이제는 아직 구현되지 않은 디테일한 부분들 구현, 엉망인 UI/UX 개선, 성능 개선 작업을 이어나갈 예정이다. 그리고 계속 미뤄왔던 테스트 코드 부분도 좀 같이 공부를 해야겠다. </p>
<p>NestJS + React + MySQL + OpenAI + Supabase </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사이드 프로젝트 ~ing]]></title>
            <link>https://velog.io/@be-kid/%EC%82%AC%EC%9D%B4%EB%93%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-ing</link>
            <guid>https://velog.io/@be-kid/%EC%82%AC%EC%9D%B4%EB%93%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-ing</guid>
            <pubDate>Wed, 24 Sep 2025 11:42:05 GMT</pubDate>
            <description><![CDATA[<p>ㅎㅎ 이제야 백엔드 1차적으로 완료했다. 이제 프론트로 넘어간다.</p>
<p>이번에도 역시 gemini와 함께 프론트 진행하는데 백엔드 때 보다 프론트쪽 작업을 훨씬 수월하게 하는 느낌이다. 체계가 좀 더 잘 잡혀있는 느낌이랄까</p>
<p>뭔가 빠르게 사용가능한 수준으로 만들 수 있을 것 같은 느낌 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/22]]></title>
            <link>https://velog.io/@be-kid/922</link>
            <guid>https://velog.io/@be-kid/922</guid>
            <pubDate>Mon, 22 Sep 2025 11:49:11 GMT</pubDate>
            <description><![CDATA[<p>gemini와의 작업이 길어질수록 애가 멍청해지는 것 같다.</p>
<p>예를들면 A라는 에러를 해결하고 그 다음 단계 구현으로 넘어갔는데</p>
<p>여기서 B라는 에러가 났다고 했을때, 어느 순간 보면 gemini는</p>
<p>A 에러에 대해 이야기하고 있다.</p>
<p>내가 직접 다시 우리 B 에러 해결하고 있다고 얘기해줘야 정신차리고 다시 일한다</p>
<p>정신을 차린건지는 모르겠다.</p>
<p>그러다 C를 하고 있다가 또 A에 대해 이야기한다. 수준이 의심된다.</p>
<p>... </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/19]]></title>
            <link>https://velog.io/@be-kid/919</link>
            <guid>https://velog.io/@be-kid/919</guid>
            <pubDate>Fri, 19 Sep 2025 10:15:49 GMT</pubDate>
            <description><![CDATA[<p>프로젝트 초기화시키고 다시 하는 중..
이번엔 좀 더 단계를 세분화 시켜서 gemini에게 인지시키고 작업을 진행해본다</p>
<p>확실히 전보다는 매끄럽게 진행되는 느낌
어느정도로 상세히 설명해줘야하는지 조금씩 감이 잡히는 느낌이다.</p>
<p>밥먹어! 보다는 오른손으로 숟가락 잡고 밥그릇의 밥을 퍼서 입으로 넣어! 라고 해야 알아 먹는듯 ? ㅎㅎ 좀 과장 보태서</p>
<p>하지만 아직 뭔가 오류가 생겼을때 삽질하는건 사람일아 비슷한듯 ~ </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/17 요즘들어 ]]></title>
            <link>https://velog.io/@be-kid/917-%EC%9A%94%EC%A6%98%EB%93%A4%EC%96%B4</link>
            <guid>https://velog.io/@be-kid/917-%EC%9A%94%EC%A6%98%EB%93%A4%EC%96%B4</guid>
            <pubDate>Wed, 17 Sep 2025 13:51:30 GMT</pubDate>
            <description><![CDATA[<p>올해 초? 부터 지원서를 계속 넣고 있는데
최근 몇 달 들어서는 이상할 정도로 지원서를 열람도 안하거나 읽은 후 답변이 없는 경우가 많다. 답변이라는게 탈락 문자나 메일을 말하는게 아니라 원티드를 예로 들면 불합격 처리라도 할 수 있는데 그것 조차 안한다.. 
나만 그런걸지도 모르지만 굉장히 답답하다.
뭐.. 불합격 통보가 미안하기라도 한걸까 .. ..?
그건 그렇다 쳐도.. 열람 조차 안하는건 .. ? 왜 공고 올린건지 ...
시간들여서 이력서 작성해서 (필요한 부분만 수정하는거긴 하지만) 제출해놨는데
읽지도 않으면 굉장히 허탈하다.. 너무함... 올린지 하루만에 채용을 해버린건지?
선착순 이벤트였던건가 ~ </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/16]]></title>
            <link>https://velog.io/@be-kid/916</link>
            <guid>https://velog.io/@be-kid/916</guid>
            <pubDate>Tue, 16 Sep 2025 07:37:43 GMT</pubDate>
            <description><![CDATA[<p>어제는 민방위 다녀와서 채용공고만 좀 보고 말았다.</p>
<p>오늘은 오전부터 gemini 시켜서 프로젝트 해보고 있는데 좀 답답하다.</p>
<p>내가 잘 못 시켜먹는걸수도 있는데 ㅋㅋ;</p>
<p>온전히 다 시키는거는 나랑 좀 안맞는듯</p>
<p>내가 개발을 하면서 서브로 이용하는게 훨씬 나을거같다.</p>
<p>오늘은 거의 아무것도 진행을 못했다.</p>
<p>swagger를 사용하려고 해봐라 시켰는데 뭐 로그인(아이디, 비밀번호)까지는</p>
<p>잘 작동했는데 포스트 작성하려니까 토큰을 인식을 못한다.</p>
<p>문제는 이거 해결하라고 했더니 계속 서버를 다시 실행시켜봐라, 로그를 찍어볼테니 출력되는걸 알려달라, 터미널로 명령어 입력해봐라 이것만 무한 반복이다.</p>
<p>속터져서 꺼지라고 했다. 내가 해결하는게 빠를듯.</p>
<p>자세히는 아직 못봤는데 auth 어딘가 잘못된게 있겠지 싶다. 후 ;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/12]]></title>
            <link>https://velog.io/@be-kid/912</link>
            <guid>https://velog.io/@be-kid/912</guid>
            <pubDate>Fri, 12 Sep 2025 08:17:33 GMT</pubDate>
            <description><![CDATA[<p>gemini에게 시키면서 만들고 있던게 영 마음에 들지 않아서 다시 해보려고 구조 같은거 부터 명확하게 정리하고 있다. 엉망진창으로 명령하면서 만들게하니까 에러도 엄청나고 제대로 흘러가는 느낌이 안든다.
확실히 내가 명확하게 정리해줘야 알아먹고 잘 수행할 것 같다. 아직까지는 내가 직접하는게 좀 더 나을 것 같은 느낌. 근데 아마 속도차이가 엄청나겠지.
그리고 전체적으로 한번에 설명을 해줘야 애가 뻘짓안하고 수행하는듯</p>
<p>오늘도 이력서 하나 넣었다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/11]]></title>
            <link>https://velog.io/@be-kid/911</link>
            <guid>https://velog.io/@be-kid/911</guid>
            <pubDate>Thu, 11 Sep 2025 09:15:43 GMT</pubDate>
            <description><![CDATA[<p>gemini 시켜서 프로젝트하려고 했던거 만들어보고 있다.
아직 ai써서 만드는게 익숙하지 않아서 그런지 순탄하지는 않다.</p>
<p>아마 수차례 뿌시고 다시하고 반복해야 제대로 써먹을 수 있지 않을까 하는 느낌 ~ ?</p>
<p>이제 이력서 좀 넣고 공부해야겠디.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/9]]></title>
            <link>https://velog.io/@be-kid/99</link>
            <guid>https://velog.io/@be-kid/99</guid>
            <pubDate>Tue, 09 Sep 2025 07:40:38 GMT</pubDate>
            <description><![CDATA[<p>아이고 참내
얼마나 됐다고 나태해지고 있는지 
지난주 면접 본 곳은 월요일에 결과 알려주겠다했는데 아직 소식이 없다
안된거겠지 그럼 .. 불합이라도 알려주면 좋을텐데 희망고문 ㅜ</p>
<p>다시 마음 다잡고 오늘은 프로젝트 기본적인 것들 세팅
하도 오랜만에 하려니까 머리속이 백지다
구직하면서도 꾸준히 좀 해둘걸</p>
<p>그간 해놨던것들 보면서 다시 기억 좀 되살리면서 해야겠다</p>
<p>지원서도 다시 넣고..
빨리 취직 못하면 우선 다른 일이라도 하면서 돈을 벌어야한다. .</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/5]]></title>
            <link>https://velog.io/@be-kid/95</link>
            <guid>https://velog.io/@be-kid/95</guid>
            <pubDate>Fri, 05 Sep 2025 13:52:05 GMT</pubDate>
            <description><![CDATA[<p>어제 면접 보고 운동하고
오늘은 조금 느긋하게 작업했다
많이는 못했지만 대충 구조 좀 짜보고
좀 더 구체화한 정도 .. 
내일은 디비 설계도 좀 해보고 가능하면 개발도 시작해야겠당</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[9/3]]></title>
            <link>https://velog.io/@be-kid/93</link>
            <guid>https://velog.io/@be-kid/93</guid>
            <pubDate>Wed, 03 Sep 2025 07:57:47 GMT</pubDate>
            <description><![CDATA[<p>너무 오랜만에 면접 기회가 생겨서 준비 중이다.
뭔가 다시 제대로 해보쟈! 해놓고 바로 이러니까 웃기긴한데 어찌되었든 열심히 해봐야지</p>
<p>안내문자에 있는 내용만 봐서는 짧은 시간동안 코테와 면접을 보는듯한데, 어떤 식으로 진행될지 예상이 잘 안된다. 더 긴장된다. ㅎㄷㄷ</p>
<p>중간중간 쉬는 느낌으로 개인 프로젝트 구체화를 더하고있다. 평범한 주제긴하지만 재미있게 만들어보고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[25년 9월 1일의 다짐]]></title>
            <link>https://velog.io/@be-kid/25%EB%85%84-9%EC%9B%94-1%EC%9D%BC%EC%9D%98-%EB%8B%A4%EC%A7%90</link>
            <guid>https://velog.io/@be-kid/25%EB%85%84-9%EC%9B%94-1%EC%9D%BC%EC%9D%98-%EB%8B%A4%EC%A7%90</guid>
            <pubDate>Mon, 01 Sep 2025 10:43:10 GMT</pubDate>
            <description><![CDATA[<p>2년 5개월간 다니던 회사가 망해서 월급 3개월치와 퇴직금도 못받고 나왔다.
그리고 6개월 이상 지났지만 다시 취직하지는 못하고 있다. 면접을 몇 차례 보기는 했지만 모두 떨어졌다. 어설프게 살아온 내 잘못인 것 같다. 최근 들어서는 서류 통과 조차도 안되고 있다. 급작스럽게, 엄청난 속도로 발전하고 있는 AI 때문이라고 탓하면서 점점 의욕만 잃어간다. 개발자를 계속하는게 맞나? 빨리 다른 기술이라도 배워야하나? 근데 나는 개발하는거 재밌는데.. </p>
<p>지푸라기라도 잡는 심정으로 개발자 기술 면접 노트라는 책을 사서 읽고 있는데, 뭔가 막 내 문제점이 뭐였는지 알거 같고 다시 해보면 될 것 같다는 생각이 든다. 그래서 다시 힘내서 해보기로 했다. 이 글은 내가 또 포기하려고 할 때 창피하려고 쓰는 글.</p>
<p>오늘은 그래서 앞으로 하루를 어떻게 보낼지 계획도 하고 이력서도 수정하고(책에서 배운걸 참고해서) 생각만 하고 있던 개인 프로젝트도 구체화시켜봤다. 다들 치열하게 살고있는데 가만히 누워서 뭐가 될리가 없으니깐.</p>
<p>최소한 2일에 한번은 아무 글이라도 작성하기로 마음먹었다. 앞으로 진행할 개인 프로젝트에 필요한 일이기도 하다. 정신차리고 다시 시작해보자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[푸시알림 날리기]]></title>
            <link>https://velog.io/@be-kid/%ED%91%B8%EC%8B%9C%EC%95%8C%EB%A6%BC-%EB%82%A0%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@be-kid/%ED%91%B8%EC%8B%9C%EC%95%8C%EB%A6%BC-%EB%82%A0%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Thu, 23 May 2024 07:58:50 GMT</pubDate>
            <description><![CDATA[<p>-뚱땅뚱땅 평화로운(?) 푸시알림 기능 개발 시간-</p>
<p>예약 발송 기능이 필요해 방법을 알아보고 있었다.</p>
<p>어찌저찌 구글링을 통해 NestJS Task Scheduling - Dynamic timeouts에 대해 알게 되었다 !</p>
<p>스케줄러는 이미 사용해본 경험이 있었는데(매일 @@시 ##분 마다 동작 등), 동적으로 필요에 따라 생성했다 없앴다 할 수도 있었다니 ! (문서를 끝까지 읽어본 적이 없는 사람)</p>
<p>사용 방법은 어렵지 않아서 내가 원하는 타이밍에 푸시알림을 발송할 수 있게 되었다.
너무너무 단순하다! <a href="https://docs.nestjs.com/techniques/task-scheduling#dynamic-timeouts">진짜로</a></p>
<p>즉시 발송과 예약 발송 모두 잘 작동하는 것을 확인하고 필요한 곳 마다(6~7군데 정도) 알림 발송 코드를 때려 박았는데, 막상 이렇게 해놓고 나니 나중에 수정이 필요하거나 또 푸시알림이 필요한 곳이 생기면 같은 작업을 반복해야한다고 생각하니 좀 간지가 안나는 것 같아서 정리를 좀 하기로 했다.</p>
<p>일단 내가 원하는 것이 무엇인가 정리</p>
<ul>
<li>&quot;특정 상황&quot;에 유저에게 푸시알림을 보내야함 (FCM 사용)</li>
<li>즉시발송/예약발송</li>
<li>현재는 6~7가지 상황이 있지만 점점 늘어날 수 있음</li>
<li>특별한 경우를 제외하고 어드민 페이지에서 푸시알림을 관리하고 싶음</li>
<li>발송상황, 발송타이밍, 메시지 내용 관리 / 발송 내역 관리 등</li>
<li>위 내용은 단일 대상에게 자동으로 보내는 알림. 다수에게 보내는 수동 알림은 따로 처리</li>
</ul>
<p>필요한 api 마다 푸시알림을 쏘는 코드를 심는 것 보다는 한 지점(?)에서 처리하고 싶었는데 그러기 위해선 어떤 요청이 들어왔는지 구분하고 푸시알림이 필요한 요청 및 상황인지 판단, 알맞은 대상 및 내용 구성을 할 수 있어야 했다.</p>
<p>어떤 요청인지(&quot;특정 상황&quot;)는 요청 end point로 구분할 수 있다.</p>
<p>발송 대상은 요청에 jwt 토큰도 있고 앱에서 오는 요청이 아닌 경우(서비스 특성 상 서버가 임베디드와도 통신 중) 식별 가능한 데이터가 함께 담겨 있어 어렵지 않았다.</p>
<p>내용 역시 왔다갔다하는 데이터들로 충분히 구성할 수 있다.</p>
<p>즉시발송/예약발송은 0초 뒤 발송, n초 뒤 발송 으로 설정이 가능하다.</p>
<p>이런 점들을 바탕으로 DB를 꾸려보았다. 푸시알림을 보내길 원하는 상황과 내용을 미리 등록해둘 수 있도록.</p>
<pre><code class="language-typescript">{
   알림발송상황: &quot;유저가 ~~한 상황&quot;;
   endPoint: &quot;/request/endpoint&quot;;
   n밀리초뒤발송: 300000;
   푸시알림제목: &quot;이것은&quot;;
   푸시알림내용: &quot;name씨에게 보내는 푸시알림&quot;;
   내용에들어가는변수이름: [&quot;name&quot;];
   클릭시이동url: &quot;어디어디&quot;;
}</code></pre>
<p>문제는 한 곳에서 처리하려면 과연 그 한 곳은 어디로 해야 좋을까 였다. 미들웨어, 인터셉터 등 뭔가 이것저것 알긴 아는데 정확한 작동 방식이나 그런 것을 아직 완전히 깨우치지 못한 상태라 GPT씨에게 상담 요청을 했다.</p>
<p>위 상황들을 죽 설명하고 어쩌면 좋을지 물어보니 그(?)(그녀?) 역시 미들웨어나 인터셉터에 심을 것을 추천해주었는데, 간단한 테스트와 모든 데이터를 처리한 뒤 응답을 보내기 직전에 푸시알림을 쏘고 싶다는 추가 질문으로 인터셉터를 활용하는 것으로 확정을 지었다.</p>
<p>이렇게 내가 원하던 대로 &#39;한 곳&#39; 까지 정해졌다.</p>
<p>-뚱땅뚱땅 코딩 타임-</p>
<p>그렇게 뚱땅뚱땅 코드를 작성해놓고 테스트를 하다보니 문제점들이 발견되었다.</p>
<ul>
<li>n시간 뒤 어떤 사람에게 발송하도록 예약해둔 메시지를 만약 그 사람이 특정 조건을 만족한 경우 예약을 취소해야 함</li>
<li>예약을 해둔 메시지들이 만약 서버가 재시작되면 스케줄러가 초기화되면서 사라짐</li>
</ul>
<p>여러 고민과 GPT씨와의 상담 끝에 두 가지 문제점 모두 스케줄러와 DB를 함께 활용해 해결할 수 있다는 결론을 내렸다.</p>
<p>첫번째 문제는 고유한 예약 번호와 함께 푸시알림 내역을 저장해뒀다가 원하는 상황에 예약을 취소할 수 있도록 했다. 예약을 취소하게 되는 상황은 당장에는 한가지 상황 뿐이라 중앙처리 말고 해당 api에서 하도록 했다.</p>
<p>나중에 조금 더 발전시킬 필요가 있을 것 같다.</p>
<p>두번째 문제는 발송 상태[발송완료/발송예약/발송취소]를 함께 저장해뒀다가 OnApplicationBootstrap을 사용해 서버가 재시작될 때 발송예약 상태인 메시지들을 다시 스케줄러에 집어넣어주도록 했다.</p>
<p>어차피 발송 내역을 저장하기로 해서 DB도 이미 구성해뒀기 때문에 몇 개의 필드만 더 추가하면서 사건을 해결할 수 있었다.</p>
<p>대략적인 형태</p>
<pre><code class="language-typescript">import { Injectable, OnApplicationBootstrap } from &#39;@nestjs/common&#39;;
import { firebaseAdmin } from &#39;src/config/firebase.config&#39;;
import { SchedulerRegistry } from &#39;@nestjs/schedule&#39;;
@Injectable()
export class PushMessageService implements OnApplicationBootstrap {
    constructor(private readonly schedulerRegistry: SchedulerRegistry) {}

     async onApplicationBootstrap() {
        // 발송예약 상태인 메시지들을 다시 스케줄러에 등록
    }

      async fcmSendMessage(message, sendAfterMilliSeconds, timeoutName, history) {
        const timeout = setTimeout(async () =&gt; {
            await firebaseAdmin
                .messaging()
                .sendEachForMulticast(message)
                .then((res) =&gt; {
                    console.log(&#39;success: &#39;, res);
            })
            .catch((err) =&gt; {
                console.log(&#39;error: &#39;, err);
            });        
            // history(발송내역)를 사용해 에약발송인 경우 발송예약 &amp;gt; 발송완료로 업데이트
            // ~ code ~

            // 발송한 뒤에 스케줄러에서 삭제
             this.schedulerRegistry.deleteTimeout(timeoutName);
              }, sendAfterMilliSeconds);
          this.schedulerRegistry.addTimeout(timeoutName, timeout);
    }

      async sendAutoPushMessage(endPoint) {
        // 인터셉터에서 호출해 사용
        // 푸시알림 보낼지 말지 판단 후 내용 구성해 발송 예약
    }
}</code></pre>
<p>이런식으로 구현을 해놓았지만 솔직히 지금도 마음에 썩 들지는 않아서 계속 고민 중이다. 조금 더 깔끔하게 할 수 있을 것 같은데 막 아이디어가 떠오르지는 않아서 다른거 할 거 하면서 계속 지켜보는 중이다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[BEB03 마지막 프로젝트를 마치고]]></title>
            <link>https://velog.io/@be-kid/BEB03-%EB%A7%88%EC%A7%80%EB%A7%89-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A5%BC-%EB%A7%88%EC%B9%98%EA%B3%A0</link>
            <guid>https://velog.io/@be-kid/BEB03-%EB%A7%88%EC%A7%80%EB%A7%89-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A5%BC-%EB%A7%88%EC%B9%98%EA%B3%A0</guid>
            <pubDate>Thu, 02 Jun 2022 08:32:53 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/be-kid/post/4752ef7a-55a3-4bc4-a761-887726044197/image.jpeg" alt=""></p>
<p>2022년 5월 3일 화요일 팀 편성부터 2022년 5월 31일 화요일 발표까지, 4주하고도 하루의 BEB 3기의 마지막 프로젝트가 끝이났다.</p>
<p>마지막 프로젝트는 각자 자유롭게 아이디어를 제안하고 관심이 가는 아이디어에 참여해 팀이 이루어졌다. 나는 아이디어 발표 전날인 5월 2일, 운동을 하다 떠오른 온라인 저지를 적어냈고 두 분이 참여하겠다 하셔서 내가 팀장이 되어 셋이서 프로젝트를 진행하게 되었다.</p>
<p>처음 프로젝트 아이디어를 제안했을 때는 구체화되지 않은 단순한 형태였다.</p>
<h4 id="프로젝트-아이디어-초기">프로젝트 아이디어 (초기)</h4>
<ul>
<li>토큰 인센티브 기반의 온라인 저지</li>
<li>문제 출제 (NFT)</li>
<li>문제 출제, 문제 풀이, 질문에 대한 답변(채택) 등으로 토큰 수급</li>
<li>문제 평가(좋은 문제, 나쁜 문제 등), 정답률 등 누적되는 데이터를 반영한 출제자 인센티브</li>
<li>자체 대회 주최 가능<ul>
<li>그룹 생성, 문제 출제 후 참가자 모집 (참여시 토큰 제출)</li>
<li>모인 토큰을 대회 후 순위에 따라 재분배</li>
<li>주최자(그룹 생성자, 문제 출제자 등)들에게도 일부 지급</li>
<li>대회 종료 후 문제는 전체에 공개</li>
</ul>
</li>
<li>대회 이외의 연습용 그룹 생성 가능(토큰x)<ul>
<li>직접 문제 출제 혹은 이미 출제되어 있는 문제에서 선택 가능</li>
<li>코테 환경 연습 등을 위한 옵션</li>
<li>학교, 학원 등에서 시험, 과제, 스터디 등 다양하게 활용</li>
</ul>
</li>
</ul>
<h3 id="5월-3일--5월-31일-기록을-바탕으로-정리">5월 3일 ~ 5월 31일 기록을 바탕으로 정리</h3>
<h4 id="5월-3일-첫-회의">5월 3일 첫 회의.</h4>
<p>이 날은 약 3시간 정도 회의를 하며 아이디어를 조금 더 구체화시켰다. 우리 사이트를 이용하는 유저들의 실력 향상과 유저들에게 알맞은 보상, 인센티브를 지급한다는 것을 목적으로 이런저런 아이디어를 이야기했다. 또 전체적인 구조를 그려보며 역할을 나누었다.
다행히 각자 맡아보고 싶은 영역이 명확해서 깔끔하게 나눌 수 있었다. 우리 서비스는 클라이언트, 채점 서버, 메인 서버, 데이터베이스, 컨트랙트로 구성하기로 했고 나는 채점 서버를 구현한 뒤에 메인 서버 작업으로 합류하기로 했다.</p>
<p>우리는 우선 가장 필수적인 기능들을 구현하기로 했다. 이외의 컨텐츠나 토큰 이코노미 등은 꾸준히 회의를 하며 정해가기로 했다. 필수 기능은 문제 출제, 문제 풀이, 채점, 마이페이지(지갑 연결 등)로 정리되었고 12일까지 이 기능들을 구현하기로 했다.</p>
<h4 id="5월-3일--5월-8일-채점-서버-구현">5월 3일 ~ 5월 8일 채점 서버 구현</h4>
<p>회의를 마치고 그날 저녁부터 바로 채점 서버 구현을 시작했다. 오픈 소스를 사용할 수도 있었지만 한 번 직접 만들어보고 싶었다. 그래서 일단은 자바스크립트 코드 채점을 목표로 하고 떠오르는 방법들을 하나하나 시도해보았다.</p>
<p>처음 아이디어는 request로 들어온 코드로 js 파일을 쓰고 호출해서 사용하는 것이었는데 테스트를 해보니 코드가 바뀌어 요청이 들어와도 가장 첫 요청에 들어온 코드로 쓰여진 파일로만 계속 결과가 나왔다. 파일의 내용이 바뀌어도 결과 값은 항상 처음 들어온 코드가 실행되고 나온 값이었다.
이런저런 검색 도중 import가 문제인가 싶어 동적으로 import하기 위해 import()를 사용했지만 결과는 같았다. 파일을 생성하고 결과를 출력한 뒤에 바로 삭제를 해보았지만 이 역시 처음 생성된 파일을 기억하고 있는 것인지 같은 결과만 나왔다. 파일을 읽어오는 부분을 함수화도 시켜보고 사용된 모든 변수를 null로 초기화도 시켜봤지만 모두 실패했다.</p>
<p>그렇게 4일이 되었고 그냥 오픈소스나 API를 사용할까하는 생각으로 검색을 하다가 repl it이라는 온라인 코딩 사이트의 API를 발견했지만 현재는 사라진 듯 했다.. 다시 한 번 채점 서버 구현을 시도하다가 생성하는 파일의 이름이 바뀌었을 때 원하는 결과가 나오는 것을 확인할 수 있었다. 그래서 Date() 함수를 사용해 호출되는 시점의 시간을 파일 이름으로 정해주어 해결할 수 있었다.</p>
<p>이후에는 테스트 케이스를 차례로 넣으며 결과를 얻어내기 위해 고민을 했는데 최대한 단순하게 해결하고 싶어서 메인 함수는 항상 이름이 solution 이도록 했다. 마지막 부분에 export 만 추가해 solution 함수를 호출하고 테스트 케이스를 넣어서 실행시키는 방식으로 해결하기 위해서 였다. 작동이 잘 되는 것을 확인하고서는 채점 서버는 메인 서버로부터 유저의 코드와 해당 문제의 테스트 케이스를 받아 채점 결과를 반환해줄 수 있도록 했다.</p>
<p>6일 회의에서 함께 백엔드를 맡은 팀원분이 타입스크립트로 구현해보는 것이 어떻겠냐는 제안을 받았고, 사실 나도 어느정도 그것에 대해 생각하고 있었기 때문에 바로 승낙을 했다. 그래서 7일, 8일에는 타입스크립트를 공부하며 채점 서버를 타입스크립트로 바꾸는 작업을 했다. 어설프지만 어떻게든 돌아가도록 만들기는 했다..
타입스크립트로 변환하는 과정에서 js 파일을 생성하고 가져오는 부분에서 package.json에 &quot;type&quot;:&quot;module&quot;을 쓰면 에러가 나서 import를 require로 바꾸어야했다.</p>
<p>또 6일 회의에서는 우리 서비스에 대한 컨셉이 잡혔다. 어쩌다보니 콜로세움이라는 얘기가 나오게 되었고, 초기 아이디어였던 그룹 생성, 대회 주최가 아닌 출제되는 문제 하나하나에 토큰을 걸고 경쟁하는 방식의 문제 풀이가 우리의 메인 컨텐츠가 되었다. 하지만 고수들의 독식이나 난이도 문제, 문제 자체의 오류 등 넘어야할 산이 많다는 것 또한 회의에서 계속 언급되었다. </p>
<h4 id="5월-9일--5월-11일-메인-서버-합류-api-구현">5월 9일 ~ 5월 11일 메인 서버 합류, API 구현</h4>
<p>아직 채점 서버에서 유저의 코드가 무한 루프가 돌거나 실행 시간이 너무 오래걸릴 때의 처리를 하지 못하는 문제점을 해결하지는 못했지만 아주 단순하게 작동을 하기는 하니 (사실 해결할 방법이 떠오르지 않았던 것도 있다) 메인 서버로 넘어가 작업을 시작했다. 메인 기능인 문제 출제, 풀이 제출 API를 우선 구현하기로 했고 클라이언트 담당 팀원분과 이야기하며 API 문서를 작성했다.</p>
<p>회의에서는 컨텐츠에 대해 재미있는 아이디어도 더 나오고 (문제가 랜덤으로 출제되고 연속으로 많이 맞출수록 더 큰 보상을 획득하는 등의 컨텐츠) 부정 행위나, 오류가 있는 문제의 수정 등에 대한 논의가 이루어졌다. 사실 이런 부분들은 직접 서비스를 해본적이 없어 막연하고 마땅한 해결책을 내놓기가 어려웠다. 끊임없이 함께 고민해보기로 하며 우선은 기능 구현에 집중하기로 했다. 다 고민해놔도 기능 구현이 되지 않으면 소용이 없으니까.</p>
<h4 id="5월-12일-프로젝트-컨셉-및-토큰-이코노미-설계-회의">5월 12일 프로젝트 컨셉 및 토큰 이코노미 설계 회의</h4>
<p>문제 리스트 요청, 문제 상세 페이지 요청 API를 이어서 구현해 12일에는 아주 기본적인 틀을 가진 사이트가 만들어졌다. 클라이언트와 함께 연결해 테스트를 해보며 몇몇 버그를 잡고 이후 일정에 대해 회의를 진행했다.
우리 서비스의 토큰이 언제 생성되고 언제 소비되는지를 다시 한 번 정리했고 문제 풀이 사이트이기 때문에 토큰 가치의 변동을 최소화할 수 있는 적절한 토큰 발급과 소모, 소각이 필요할 것이라는 이야기를 나누었다. 다만 이것 역시 우리가 설계하는 것이 쉽지 않았다. 최대한 토큰을 소비할 수 있는 컨텐츠를 많이 준비해야할 것이고 과한 공급이 되지 않도록 적정량을 지급하도록 해야하지만 서비스를 직접 해보지 않아서인지 감이 잘 잡히지 않았다.
그래서 이번에도 역시 기능 구현에 초점을 맞추기로 했다. 하지만 고민은 멈추지 않았다.</p>
<p>콜로세움이라는 컨텐츠가 이미 정해진 상황에서 콜로세움에서 소비된 문제를 어떻게 할 것인가에 대한 논의가 이루어졌다. 소비된 문제는 연습문제로 전환할 수 있도록 하고 전환할 때 NFT화하면서 유저들이 연습문제를 풀이할 때 마다 출제자에게도 보상이 갈 수 있도록 구상을 했다.</p>
<h4 id="5월-13일--5월-27일-코드-콜로세움-구현-및-완성">5월 13일 ~ 5월 27일 코드 콜로세움 구현 및 완성</h4>
<p>콜로세움 문제는 문제에 진입할 때 토큰을 지불할 수 있도록 해야해고, 이를 위한 조금 복잡한 검증 과정 로직이 필요했다.</p>
<ul>
<li>유저가 문제에 접근함</li>
<li>유저가 풀이 중인 문제인지 확인(토큰을 이미 지불했는지, 풀이 중인 유저 목록 확인)</li>
<li>지불하지 않은 유저라면 지불하도록 응답</li>
<li>지불한 유저라면 바로 문제 데이터 전송</li>
<li>이제 막 지불을 하고 들어온 유저라면 풀이 중인 유저 목록에는 없지만 데이터를 보내줘야 함</li>
<li>바로 위 상황을 위해 트랜잭션 검증이 필요함
13일 당시에는 아직 컨트랙트가 준비되지 않았어서 실제 토큰 지불이나 트랜잭션 검증 등은 되고 있다고 가정하고 그 부분은 비워둔 채로 문제 상세 페이지 요청 API를 구현했다. 이어서 풀이 제출 API를 구현했다. 이것 역시 콜로세움 문제, 연습문제에 따라 처리할 로직이 달랐다. 당시에는 하나의 API로 구현했지만 프로젝트 막바지에는 결국 둘로 나누어 따로 구현했다.
이런 구현 과정에서 검증, 중복 방지 등을 위한 토큰 지불 기록이나 문제 풀이 기록 등 다양한 기록이 필요했고 몇차례 디비 스키마에 수정이 필요해 문제 출제, 풀이 제출, 문제 리스트 API 등에 조금씩 변화가 생겼다. 시간 관계상 우리가 처음부터 완벽하게 계획한 것이 아닌 구현과 구체화, 구상을 동시에 진행하다보니 일어날 수 밖에 없는 일이었고 감수하며 진행했다.</li>
</ul>
<p>17일 회의에서는 콜로세움 문제에 재도전은 불가능하도록 하고 제한시간이 지나도 우승자가 아직 나오지 않았다면 풀이는 계속 가능하며, 보상은 없도록 하기로 했다. 18일까지는 계속 위 API를 구현하는데 힘썼다.</p>
<p>19일에는 컨트랙트가 준비되었다 해서 구현된 API들을 전체적으로 살펴보며 수정할 준비를 했다. 여기서 콜로세움과 연습문제를 분리시키는 것이 좋겠다는 생각이 들어 컨트랙트 함수를 집어넣으며 따로 분리시키는 작업을 동시에 진행하였다. 추가적으로 NFT, 연습문제 전환 요청 API와 피드백 API가 필요하다는 얘기가 나왔고 앞선 작업이 완료되는대로 구현하기로 했다. 전환이나 피드백은 너무 간단한 작업이어서 순식간에 완료할 수 있었다. </p>
<p>20일에는 컨트랙트 담당 팀원분이 토큰 지불 시 수수료 대납 함수 구현에 성공했다고 해서 콜로세움 문제 상세 페이지 요청 API 로직을 대폭 수정할 필요가 있었다. 서버에서 수수료 대납을 하겠다는 내용이 담긴 사인 요청을 클라이언트에 보내면 유저가 이에 사인을 해 다시 전송하고, 사인 객체를 받아 이를 사용해 토큰을 전송하면서 수수료를 대납하는 구조였다.</p>
<p>21일에는 콜로세움 풀이 제출 API, NFT 전환 요청 API, 연습 문제 전환 요청 API, 피드백 API가 남아있는 상황이었는데 아직 관련된 컨트랙트 함수가 준비되지 않아 이번에도 있다치고~ 구현을 시작했다. 또 아직 채점 서버 시간 초과 관련 문제를 해결하지 못했기 때문에 이 부분 역시 계속해서 고민하고 있었다.</p>
<p>22일에는 조금 큰 변경사항이 있었다. 연습 문제를 풀이할 때마다 보상으로 토큰이 왔다갔다하는 것이 수수료 부분에서 부담이 커서 DB에만 기록하는 중간 재화를 추가하기로 했다. 때문에 이를 기록하는 로그가 또 필요했고 연습 문제 관련된 디비 스키마와 API에 변화가 많이 생겼다. 또한 이 중간 재화를 토큰으로 환전해주는 API가 필요했기 때문에 이에 대한 구상도 필요해진 상황이었다. 연습 문제 출제자에 대한 보상 역시 같은 방식으로 처리하기로 했다.</p>
<p>하나하나 구현해가는 과정에서 NFT 전환 요청과 연습 문제 전환 요청 API는 하나로 합쳐서 처리하기로 해서 수정이 있었다. 환전 요청도 컨트랙트 함수가 아직이라 있다고 생각하고 구현했다.</p>
<p>24일에는 컨트랙트 함수를 제외한 API 뼈대를 완성하고 컨트랙트 담당 팀원분의 소식을 기다리는 동안 다시 채점 서버의 문제를 해결하기 위해 구글링을 시작했다. 자바스크립트의 label도 사용해보았지만 소득은 없었다. 아무리 찾아봐도 실행되고 있는 함수를 외부에서 죽이는 (작동을 멈추는) 방법을 찾을 수가 없었다. 그러던 와중 문득 학부때 배웠던 싱글, 멀티 스레드, 프로세스 같은 내용들이 떠올랐고 잘은 모르겠지만 이것이 지금 상황을 해결할 실마리가 되지 않을까 싶어 구글링을 시작했다. 생각보다 빨리 너무나 믿음직스러워보이는 Node의 모듈인 Child-Process 라는 것을 발견할 수 있었고 이것을 사용하면 될 것 같다는 강한 확신이 들었다. 하지만 사용법을 알기 위해서는 문서를 읽어볼 필요가 있었고 여기서 꽤 시간이 걸렸다. 이 작업은 다음날 점심즈음까지 이어졌고 마침내 시간 초과 코드까지 걸러낼 수 있는 채점 서버가 만들어졌다. 또한 이것을 활용하면 자바스크립트 뿐만 아니라 다른 언어로도 채점이 가능하도록 확장할 수 있을 것 같았다. 아쉽게도 시간이 없어서 이 부분은 나중에 따로 해볼 계획이다.</p>
<p>26일 회의에서 또 한 번 공정한 경쟁에 대한 이야기가 나오며 콜로세움 시스템에 변화를 주었다. 문제를 출제할 때 문제가 오픈되는 시간을 정할 수 있도록 했고 그 시간이 되었을 때 도전자가 2명 이상이 되지 않는다면 문제를 보류 상태로 바꾸고 참여자에겐 토큰을 환불해주는 형식으로 바꾸었다. 혼자 참여하고 보상을 획득하는 것이 취지에 맞지 않다는 의견과 최소 획득 보상의 확보, 공정성 등을 위한 개편이었다. 여기서 콜로세움 문제 상세 페이지 요청 API를 거의 새로 작성하는 수준의 작업을 수행해야했다. 또한 재출제를 위한 API가 필요해 추가 작업을 해야했다. 놀랍게도 27일 금요일까지 모든 구현과 테스트를 완료할 수 있었다.</p>
<h4 id="5월-28일--5월-29일-배포">5월 28일 ~ 5월 29일 배포</h4>
<p>주말이었지만 아직 배포가 남아있기에 각자 맡은 부분(클라이언트, 채점 서버, 메인 서버)을 배포해보기로 했다. 나는 채점서버를 배포했는데 한 달 동안의 작업 중 가장 힘든 시간이었다. 처음에는 헤로쿠를 통해 배포해보려 했는데 잘 되지 않아 포기하고 유튜브에서 보았던 AWS Elastic beanstalk 를 통해 배포할 수 있었다. 이 과정에서도 많은 시행착오가 있었지만 여러가지 시도 끝에 https로의 배포까지 겨우 성공할 수 있었다. 이 방법은 너무 고생하며 찾아낸 길이라 나중에 또 써먹을 수 있도록 정리해두었고 또 누군가 써먹을 수 있도록 블로깅도 해볼 계획이다. (제대로 한 것인지는 알 수 없지만..) 내가 먼저 배포에 성공해서 팀원분께도 방법을 공유해서 배포를 도왔는데 잘 되지 않아서 결국 메인 서버까지 내가 배포했다.</p>
<h4 id="5월-30일--5월-31일-배포-후-버그-해결-및-발표">5월 30일 ~ 5월 31일 배포 후 버그 해결 및 발표</h4>
<p>분명 배포 직전까지의 테스트에서는 모든게 완벽하다 생각했는데 배포를 하고나니 멀쩡했던 부분들에서 버그가 터져나오기 시작했다. 열심히 버그를 잡으며 발표 준비까지 하느라 정말 바쁜 이틀이었고 그래도 발표 전에는 버그들을 잘 잡아내며 무사히 발표를 마칠 수 있었다.</p>
<h4 id="배포된-주소---코드-콜로세움">배포된 주소 - 코드 콜로세움</h4>
<p><a href="https://codecolosseum.netlify.app/">https://codecolosseum.netlify.app/</a></p>
<h3 id="초기-아이디어와는-달라진-코드-콜로세움">초기 아이디어와는 달라진 코드 콜로세움</h3>
<ul>
<li>콜로세움<ul>
<li>누구나 문제를 출제할 수 있다.</li>
<li>토큰을 지불해 문제를 오픈할 수 있다.</li>
<li>가장 먼저 문제를 해결하면 모인 토큰의 일부를 보상으로 받는다.</li>
<li>문제가 해결되면 출제자에게도 모인 토큰의 일부가 보상으로 간다.</li>
<li>문제는 출제자가 지정한 시간에 오픈된다.</li>
<li>지정된 시간이 되었을 때 2명 이상이 참여하지 않았다면 펜딩 상태가 된다.</li>
<li>펜딩 상태로 바뀔 때 토큰은 환불되고 문제는 재출제 가능한 상태가 된다.</li>
<li>우승자가 나온 문제는 콜로세움에서 사라지고 출제자는 이를 연습 문제로 전환할 수 있다.</li>
</ul>
</li>
<li>연습 문제<ul>
<li>연습 문제는 토큰, 시간 제한 없이 누구나 풀 수 있다.</li>
<li>풀이에 성공하면 토큰으로 교환할 수 있는 포인트를 준다.</li>
<li>문제의 출제자에게도 포인트가 쌓이며 토큰으로 교환할 수 있다.</li>
</ul>
</li>
<li>포인트 → 토큰 환전<ul>
<li>도전자에게는 미네랄이라는 이름의 포인트, 출제자에게는 광산 수입이라는 리워드가 쌓인다.</li>
<li>각각 500점 이상 쌓이면 일정 수수료를 제외하고 환전이 된다.</li>
</ul>
</li>
</ul>
<h3 id="후기">후기</h3>
<h4 id="즐거운-시간이었지만-그럼에도-남는-아쉬움">즐거운 시간이었지만 그럼에도 남는 아쉬움</h4>
<p>한 달 정도의 시간동안 팀원분들과의 마찰도 없었고 꾸준하게 소통하며, 정말 매끄럽게 잘 진행되었다고 생각한다. 우리 서비스에 대한 컨셉이나 토큰 이코노미 등에 대해 회의하는 것도 정말 재미있었고 괜찮은 결과물이 나왔다고 생각한다. 사실 온라인 저지를 구현하는 것에 대해 코드스테이츠 블록체인 과정을 듣기 전, 개발에 대해 아무것도 모를 때에도 한 번 해보고 싶다는 생각을 막연하게만 갖고 있었는데 이를 직접 구현한 것이 정말 기분 좋았다. 그때는 어떻게 만들어야할지 감도 못 잡던 상태였는데 이제는 내가 뭔가 할 수 있다는 생각이 들기도 한다.</p>
<p>아쉬운 점은 구현을 시작하기 전에 컨셉과 데이터 구조들이 좀 더 구체적으로 잡혔으면 좋았을 것 같다는 점이다. 구현 중간중간 새로운 데이터의 추가가 이루어지다보니 많이 지저분해진 느낌도 있고 그런 과정에서 구현이나 수정이 불필요하게 복잡해지는 경우가 생긴 것 같다. 또 함수화, 모듈화가 잘 되지 않은 것 같아 이 부분도 아쉬움이 남는다. 물론 처음 구현하면서부터 그렇게 예쁜 코드를 작성하는 것이 쉽지는 않다는 것은 알고있지만 확실히 버그를 잡거나 하는 과정에서 예쁜 코드의 필요성을 너무나도 절실히 느낄 수 있었다. 함수는 하나의 기능만 하도록 만들자..</p>
<h4 id="이후에는">이후에는..</h4>
<p>남은 일정을 수행하며 마지막 프로젝트를 블록체인 없이 새롭게 구성해서 혼자 구현해볼 계획이다. 콜로세움 컨셉은 제외하고 그룹을 만들거나 하는 등의 기능과 새로운 기술 스택도 공부할 겸, 취준과 함께 말이다. 얼마전까지는 사실 부트캠프가 끝나면 한 두달 정도는 쉬면서 공부하고 할 생각이었는데 막상 이렇게 그 날이 오니 최대한 빠르게 취직해서 일이 하고 싶어졌다. 블록체인 과정을 들었고 여전히 &#39;블록체인이 미래다&#39;라는 생각에는 변함이 없지만 이번 프로젝트를 하며 당장에는 백엔드 포지션이 너무 재미있고 더 잘 맞는다는 느낌이 들어 이 부분에 좀 더 집중해서 공부하고 준비해볼 계획이다.</p>
]]></description>
        </item>
    </channel>
</rss>