[{"data":1,"prerenderedAt":3483},["ShallowReactive",2],{"skill-skillList":3,"career-all":47,"projects-hobby":1586,"projects-all":2245},{"id":4,"title":5,"body":6,"description":38,"extension":41,"meta":42,"navigation":12,"path":43,"seo":44,"stem":45,"__hash__":46},"skills\u002Fskills\u002FskillList.md","SkillList",{"type":7,"value":8,"toc":37},"minimark",[9],[10,11,13,18,22,25,28,31,34],"details",{"open":12},true,[14,15,17],"summary",{"style":16},"font-size: 1.5em;","소개",[19,20,21],"p",{},"안녕하세요. 백엔드 개발자 어진석입니다.",[19,23,24],{},"저는 제가 개발한 프로젝트를 소개하고 알고 있는 지식을 사람들과 공유하는 일에서 가장 큰 보람을 느낍니다.",[19,26,27],{},"또한 제가 가진 이 마르지 않고 있는 창작의 샘물이 끊임없는 자기 성장과 미래를 모색할 수 있는 기회가 된다고 생각합니다.",[19,29,30],{},"이제는 경험과 노하우가 쌓이면서 프로그래밍 회로가 점점 더 확장되어가는 것을 느낍니다.",[19,32,33],{},"매 순간의 선택이 최선의 선택이 되도록 노력하고 있습니다.",[19,35,36],{},"제가 만드는 것들이 누군가에게 도움이 주고, 누군가에게 영감을 주고, 누군가에게 희망을 주는 일이 되기를 기원합니다.",{"title":38,"searchDepth":39,"depth":39,"links":40},"",2,[],"md",{},"\u002Fskills\u002Fskilllist",{"description":38},"skills\u002FskillList","Cr7zWXVORKHBHc34FDEvFWiUWdh3XLX8ANbX_2jh5Pg",[48,138,220,305,403,470,583,637,691,759,834,914,1027,1142,1192,1272,1327,1386,1453,1514],{"id":49,"title":50,"body":51,"description":59,"extension":41,"meta":133,"navigation":12,"path":134,"seo":135,"stem":136,"__hash__":137},"career\u002Fcareer\u002F0-dashboard-21-02-08.md","1. NFC 온도 측정 앱 개발",{"type":7,"value":52,"toc":127},[53,57,60,63,68,71,75,97,105,109,112,116],[54,55,50],"h1",{"id":56},"_1-nfc-온도-측정-앱-개발",[19,58,59],{},"패시브 태그 센서의 온도 데이터를 안드로이드 NFC 기능으로 읽고 온도 값과 GPS 정보를 서버로 전송하는 앱을 개발하였습니다. 패시브 태그 센서를 스마트폰에서 NFC 태깅을 통해 읽고 온도를 앱에 출력하게 하는 것이 회사 입사전 주어진 과제였으며 어떻게 해결해야 하는 지는 전혀 제시되지 않았습니다. 하지만 1개월 정도 집요하게 분석한 결과, 데이터 시트를 읽어내 방법을 찾아냈습니다. 결과적으로 패시브 태그 센서의 온도 데이터를 안드로이드 NFC 태깅을 통해서 온도 값을 읽을 수 있었으며, 이를 스프링 부트로 개발한 웹서버로 전송하여 웹사이트로 시각화하여 모바일과 PC에서 로그인하여 볼 수 있게 하였습니다. 안드로이드 앱은 네이티브로 개발하였고, 앱의 UI는 WebView를 사용하여 구현하였습니다. 웹사이트는 AWS EC2에 배포하였으며 도메인은 Let's Encrypt를 사용하여 HTTPS로 인증하였습니다.",[61,62],"hr",{},[64,65,67],"h2",{"id":66},"개발-기간","개발 기간",[19,69,70],{},"2021.02.08 ~ 2021.03.05 (1개월)",[64,72,74],{"id":73},"사용-기술","사용 기술",[76,77,78,82,85,88,91,94],"ul",{},[79,80,81],"li",{},"Spring Boot + MyBatis + Tomcat 9",[79,83,84],{},"Bootstrap 5",[79,86,87],{},"MySQL",[79,89,90],{},"AWS EC2 (Linux Ubuntu Server)",[79,92,93],{},"Let's Encrypt + Certbot",[79,95,96],{},"Android WebView (Android Studio)",[19,98,100],{"align":99},"center",[101,102],"img",{"src":103,"alt":104},"\u002Fimg\u002Fandroid-front.png","android-front",[64,106,108],{"id":107},"프로젝트-기여도","프로젝트 기여도",[19,110,111],{},"100% (앱 + 웹 백엔드 + 웹 프론트 + 안드로이드 네이티브 웹뷰)",[64,113,115],{"id":114},"개발-부분","개발 부분",[76,117,118,121,124],{},[79,119,120],{},"Spring Boot로 개발한 웹 서버로 회원 가입, 로그인, 위도 및 경도, 온도 정보를 특정 위경도 범위 내로 조회하는 서버 구현",[79,122,123],{},"NFC Temperature Sensor를 통해 온도와 위경도 정보를 조회하고 서버로 전송하는 앱 구현",[79,125,126],{},"네이티브 앱으로 기능을 전부 구현하고,자바스크립트 인터페이스를 통해 웹뷰와 앱간 통신으로 데이터를 전달하는 기능 구현",{"title":38,"searchDepth":39,"depth":39,"links":128},[129,130,131,132],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":107,"depth":39,"text":108},{"id":114,"depth":39,"text":115},{},"\u002Fcareer\u002F0-dashboard-21-02-08",{"title":50,"description":59},"career\u002F0-dashboard-21-02-08","Z3lKeRjRqNcs7HP-ooX7gCwVwpsDRZ-_i1dcCBILyds",{"id":139,"title":140,"body":141,"description":148,"extension":41,"meta":215,"navigation":12,"path":216,"seo":217,"stem":218,"__hash__":219},"career\u002Fcareer\u002F1-dashboard-21-05-07.md","2. 데이터 관제 서버 개발",{"type":7,"value":142,"toc":209},[143,146,149,151,153,156,158,180,182,185,189],[54,144,140],{"id":145},"_2-데이터-관제-서버-개발",[19,147,148],{},"패시브 온도 태그 센서를 통해 측정된 온도를 실시간으로 관제하고 시각화하는 웹 서비스를 개발하였습니다.",[61,150],{},[64,152,67],{"id":66},[19,154,155],{},"2021.05 ~ 2021.07 (3개월)",[64,157,74],{"id":73},[76,159,160,163,166,169,172,175,177],{},[79,161,162],{},"Nest.js (Node.js Express)",[79,164,165],{},"SequelizeORM",[79,167,168],{},"Redis",[79,170,171],{},"Socket.io",[79,173,174],{},"Docker",[79,176,90],{},[79,178,179],{},"Vue.js",[64,181,108],{"id":107},[19,183,184],{},"100% (풀스택)",[64,186,188],{"id":187},"담당-업무","담당 업무",[76,190,191,194,197,200,203,206],{},[79,192,193],{},"깃허브 웹훅을 사용하여 웹 서버 자동 빌드 및 무중단 배포 시스템 구현",[79,195,196],{},"배치 스케줄러를 통해 일정 시간마다 사용량을 RDBMS에 갱신하는 기능 구현",[79,198,199],{},"실시간 온도 로그 조회 및 엑셀 다운로드 기능 구현",[79,201,202],{},"구글 차트와 Socket.io를 이용하여 실시간 온도 차트 그래프, 실시간 알림 구현",[79,204,205],{},"원격지에 있는 센서를 실시간으로 재부팅하고 관리할 수 있는 터미널 기능 구현",[79,207,208],{},"동작하지 않는 패시브 태그 센서(온\u002F습도계)를 감지하여 되살리는 기능 구현",{"title":38,"searchDepth":39,"depth":39,"links":210},[211,212,213,214],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F1-dashboard-21-05-07",{"title":140,"description":148},"career\u002F1-dashboard-21-05-07","Y6txW6Y1IyLwEN5Jw1O8biwIIFNz55J2oJ3oBD6-E0U",{"id":221,"title":222,"body":223,"description":230,"extension":41,"meta":300,"navigation":12,"path":301,"seo":302,"stem":303,"__hash__":304},"career\u002Fcareer\u002F10-dashboard-22-12-19.md","11. 통합 온도 관리 시스템 서버 개발",{"type":7,"value":224,"toc":294},[225,228,231,233,236,238,268,272,275,277],[54,226,222],{"id":227},"_11-통합-온도-관리-시스템-서버-개발",[19,229,230],{},"1채널 및 3채널 엑티브 온도 로거를 통해 짧은 시간 안에 들어오는 최소 수천 건 이상의 온도 데이터를 레디스와 Bull을 통해 큐잉하여, 2대 이상의 서버 프로세스에 안정적으로 분산 삽입 처리하는 서버를 개발하였습니다.",[64,232,67],{"id":66},[19,234,235],{},"2022.12.19 ~ 진행중",[64,237,74],{"id":73},[76,239,240,243,246,249,252,255,257,260,262,265],{},[79,241,242],{},"Nest.js (Node.js)",[79,244,245],{},"Typescript",[79,247,248],{},"Linux (Ubuntu)",[79,250,251],{},"MariaDB 10.10.2",[79,253,254],{},"TypeORM",[79,256,168],{},[79,258,259],{},"Bull",[79,261,174],{},[79,263,264],{},"AWS",[79,266,267],{},"Yarn PnP",[64,269,271],{"id":270},"프로젝트-인원-구성-및-기여도","프로젝트 인원 구성 및 기여도",[19,273,274],{},"1명 (100%)",[64,276,188],{"id":187},[76,278,279,282,285,288,291],{},[79,280,281],{},"Bull과 Redis를 이용하여 수천 건의 온도 데이터를 분산 처리하는 큐 시스템 구축",[79,283,284],{},"커버링 인덱스를 이용하여 온도 데이터 조회 성능을 48% 개선",[79,286,287],{},"Yarn PnP를 도입하여 도커 이미지 용량 50% 이상 감소, 배포 속도 2배 이상 개선",[79,289,290],{},"중첩 트리 구조를 사용하여 메뉴를 권한 별로 동적으로 생성할 수 있는 기능 구현",[79,292,293],{},"Server To Server 통신을 위한 API 키 인증 시스템 구축",{"title":38,"searchDepth":39,"depth":39,"links":295},[296,297,298,299],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F10-dashboard-22-12-19",{"title":222,"description":230},"career\u002F10-dashboard-22-12-19","pKZG8Ipf402CVykotZVRzkcxCQ-I-VPXpAFgas-yyqM",{"id":306,"title":307,"body":308,"description":315,"extension":41,"meta":398,"navigation":12,"path":399,"seo":400,"stem":401,"__hash__":402},"career\u002Fcareer\u002F11-dashboard-22-12-27.md","12. 통합 온도 관리 시스템 대시보드 개발",{"type":7,"value":309,"toc":392},[310,313,316,318,320,323,325,367,369,371,373],[54,311,307],{"id":312},"_12-통합-온도-관리-시스템-대시보드-개발",[19,314,315],{},"자사의 1채널 및 3채널 엑티브 온도 로거를 통해 들어오는 데이터를 시각화하여 평균 온도, 최저 온도, 최대 온도 등을 시계열 차트로 보여주고 차량 관리, 장비 관리, 권한 관리, 메뉴 관리 등을 할 수 있는 대시보드와 관리자 메뉴를 개발하였습니다.",[61,317],{},[64,319,67],{"id":66},[19,321,322],{},"2022.12.27 ~ 진행중",[64,324,74],{"id":73},[76,326,327,330,333,336,339,342,345,348,351,354,357,360,362,365],{},[79,328,329],{},"React.js",[79,331,332],{},"mui",[79,334,335],{},"mobx",[79,337,338],{},"react-hook-form",[79,340,341],{},"recoil",[79,343,344],{},"swr",[79,346,347],{},"styled-components",[79,349,350],{},"typescript",[79,352,353],{},"vite",[79,355,356],{},"chart.js",[79,358,359],{},"leaflet and KakaoMap",[79,361,174],{},[79,363,364],{},"tailwindcss",[79,366,267],{},[64,368,271],{"id":270},[19,370,274],{},[64,372,188],{"id":187},[76,374,375,377,380,383,386,389],{},[79,376,287],{},[79,378,379],{},"코드 스플리팅을 이용하여 JS 번들 크기 90% 감소",[79,381,382],{},"NGINX 및 GZIP 압축을 이용하여 웹 페이지 로딩 속도 개선",[79,384,385],{},"느린 네트워크 환경에서 생기는 UI 문제점 개선",[79,387,388],{},"이미지 압축 업로드 처리를 통해 서버 용량 절약",[79,390,391],{},"컴포넌트 팩토리를 이용하여 코드 중복을 최소화하고 재사용성을 높임",{"title":38,"searchDepth":39,"depth":39,"links":393},[394,395,396,397],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F11-dashboard-22-12-27",{"title":307,"description":315},"career\u002F11-dashboard-22-12-27","QZ_V3q5q8yrnnjPPjkDqN8VRMFR61povcd-KiETTlyQ",{"id":404,"title":405,"body":406,"description":413,"extension":41,"meta":465,"navigation":12,"path":466,"seo":467,"stem":468,"__hash__":469},"career\u002Fcareer\u002F12-dashboard-23-04-20.md","13. 홈페이지 마이그레이션",{"type":7,"value":407,"toc":459},[408,411,414,416,418,421,423,442,444,446,448],[54,409,405],{"id":410},"_13-홈페이지-마이그레이션",[19,412,413],{},"기존 홈페이지는 퍼블리셔가 전적으로 작업하였고, 퍼블리셔가 퇴사한 상황에서 빈번하게 많은 수정 요청이 발생하였습니다. 그때마다 HTML 파일과 CSS 파일을 수정하고 어떤 요소에 어떤 CSS가 적용되는지 파악하는데 많은 시간이 소요되었습니다. 컴포넌트 단위로 분리가 되어있지 않았고 CSS도 전역으로 관리되어 있어서 수정이 어려웠습니다 이런 문제를 해결하기 위해 기존의 익숙했던 리액트로 마이그레이션을 하게 된 것입니다. 먼저 제이쿼리를 사용한 부분과 리액트에서 사용이 제한된 기술을 제거하고, 최대한 비슷하게 돌아가도록 호환 작업을 하였습니다. 그리고 기존 HTML 요소를 컴포넌트 단위로 분리하여 수정이 빠르게 이뤄질 수 있게 하였습니다. 미리 준비해둔 덕분에 수정 요청이 발생할 때마다 빠르게 대응할 수 있었습니다. 모든 것을 다시 만드는 것보다, 부품을 갈아 끼우듯 점진적인 변화를 꾀했기 때문에 거대한 CSS 파일은 그대로 사용하였으나, 추후에는 이것마저도 모듈화하여 적재적소에 관리할 수 있게 하는 것이 목표입니다.",[61,415],{},[64,417,67],{"id":66},[19,419,420],{},"2023.04.20 ~ 2023.05.04 (2주)",[64,422,74],{"id":73},[76,424,425,428,431,434,437,440],{},[79,426,427],{},"Next.js",[79,429,430],{},"classNames",[79,432,433],{},"TailwindCSS",[79,435,436],{},"Swiper",[79,438,439],{},"Framer Motion",[79,441,174],{},[64,443,271],{"id":270},[19,445,274],{},[64,447,188],{"id":187},[76,449,450,453,456],{},[79,451,452],{},"기존 바닐라로 개발된 홈페이지를 Next.js로 최대한 가깝게 마이그레이션",[79,454,455],{},"네이버 검색 상위 노출을 위해 SEO 최적화 처리",[79,457,458],{},"메타 태그를 이용한 SNS 공유 최적화 처리",{"title":38,"searchDepth":39,"depth":39,"links":460},[461,462,463,464],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F12-dashboard-23-04-20",{"title":405,"description":413},"career\u002F12-dashboard-23-04-20","9T81OhOyp10-LOUimlRk2GUVtLzu3mdQ2QTcNLyfwsw",{"id":471,"title":472,"body":473,"description":480,"extension":41,"meta":578,"navigation":12,"path":579,"seo":580,"stem":581,"__hash__":582},"career\u002Fcareer\u002F13-dashboard-23-07-24.md","14. 생물학적제제 딜리버리 대시보드 마이그레이션",{"type":7,"value":474,"toc":572},[475,478,481,483,485,488,490,546,548,550,552],[54,476,472],{"id":477},"_14-생물학적제제-딜리버리-대시보드-마이그레이션",[19,479,480],{},"이 대시보드는 자사의 3채널 패시브 온도 태그로 생물학적 제제(의약품)의 온도를 측정하여 2~8℃의 온도가 유지되는지 추적 관리하는데 도움을 줍니다. 차트 형태로 데이터를 시각화하였기 때문에 한 눈에 확인이 가능하며 배송 현황도 추적할 수 있습니다. 또한 웹에서 생물학적제제 출하증명서 발급이 가능합니다. 이 대시보드는 2022년에 개발되었지만 당시 선택한 기술었던 Vue 2가 2023년 12월 31일에 모든 기술적 지원이 종료되는 상황을 앞두고 있었습니다. 따라서 유지 보수를 위해 Nuxt.js 2에서 리액트로 마이그레이션하게 된 것입니다. 기존 대시보드는 퍼블리셔가 HTML과 CSS를 작업하고 프론트엔드 작업은 제가 맡았었습니다. 뷰는 HTML\u002FCSS가 명확하게 분리되어있어서 퍼블리싱 담당이 있었을 땐 선택하기 좋은 기술이었습니다. 몇년 전과 달리, 퍼블리셔가 없는 인원 구성에서는 리액트가 더 적합한 기술이라고 판단하여 리액트로 마이그레이션하였습니다.",[61,482],{},[64,484,67],{"id":66},[19,486,487],{},"2023.07.24 ~ 2023.08.08 (약 2주)",[64,489,74],{"id":73},[76,491,492,494,496,498,500,502,504,507,510,512,515,517,520,523,526,529,532,535,538,541,544],{},[79,493,245],{},[79,495,329],{},[79,497,341],{},[79,499,335],{},[79,501,332],{},[79,503,347],{},[79,505,506],{},"react-error-boundary",[79,508,509],{},"react-calendar",[79,511,344],{},[79,513,514],{},"react-auth-kit",[79,516,338],{},[79,518,519],{},"react-hook-form-mui",[79,521,522],{},"rc-image",[79,524,525],{},"react-infinite-scroll-component",[79,527,528],{},"react-toastify",[79,530,531],{},"sweetalert2",[79,533,534],{},"dayjs",[79,536,537],{},"react-to-print",[79,539,540],{},"jspdf",[79,542,543],{},"html2canvas",[79,545,356],{},[64,547,271],{"id":270},[19,549,274],{},[64,551,188],{"id":187},[76,553,554,557,560,563,566,569],{},[79,555,556],{},"뷰에서 리액트로 마이그레이션",[79,558,559],{},"생물학적 제제 출하증명서 발급을 위한 기능(서명, 직인) 구현",[79,561,562],{},"생물학적 제제 출하증명서 인쇄 및 PDF 다운로드 기능 구현",[79,564,565],{},"차트 라이브러리를 사용하여 데이터 시각화 처리 및 카카오맵과 연동하여 배송 위치 표시",[79,567,568],{},"무한 스크롤을 이용하여 데이터를 효과적으로 불러오는 기능 구현",[79,570,571],{},"SWR을 이용하여 데이터 캐싱 효율 개선",{"title":38,"searchDepth":39,"depth":39,"links":573},[574,575,576,577],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F13-dashboard-23-07-24",{"title":472,"description":480},"career\u002F13-dashboard-23-07-24","Zg9QuJhjzMCs5lzHEgeutgqV7C3Epl91Rhq9-zJCg8c",{"id":584,"title":585,"body":586,"description":38,"extension":41,"meta":632,"navigation":12,"path":633,"seo":634,"stem":635,"__hash__":636},"career\u002Fcareer\u002F14-dashboard-23-12-01.md","15. 통합 온도 관리 시스템 대시보드",{"type":7,"value":587,"toc":626},[588,591,593,595,598,600,603,605,607,609],[54,589,585],{"id":590},"_15-통합-온도-관리-시스템-대시보드",[61,592],{},[64,594,67],{"id":66},[19,596,597],{},"2022.04 ~ 2023.12 (약 1년 8개월)",[64,599,74],{"id":73},[19,601,602],{},"React.js, mui, mobx, react-hook-form, recoil, swr, styled-components, typescript, vite, chart.js, leaflet, KakaoMap, Docker, tailwindcss, Yarn PnP",[64,604,271],{"id":270},[19,606,274],{},[64,608,188],{"id":187},[76,610,611,614,617,620,623],{},[79,612,613],{},"데이터 시각화 처리 및 카카오맵과 연동하여 배송 위치 표시",[79,615,616],{},"JS 번들 크기 90% 감소를 위한 코드 스플리팅",[79,618,619],{},"NGINX 및 GZIP 압축을 이용한 웹 페이지 로딩 속도 개선",[79,621,622],{},"이미지 압축 업로드 처리",[79,624,625],{},"컴포넌트 팩토리 이용한 코드 중복 최소화",{"title":38,"searchDepth":39,"depth":39,"links":627},[628,629,630,631],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F14-dashboard-23-12-01",{"title":585,"description":38},"career\u002F14-dashboard-23-12-01","7tObWaeMXCjooYtQEbYT76qB4W2EK1ChR2YuVvdicd0",{"id":638,"title":639,"body":640,"description":38,"extension":41,"meta":686,"navigation":12,"path":687,"seo":688,"stem":689,"__hash__":690},"career\u002Fcareer\u002F15-dashboard-23-12-01.md","16. 통합 온도 관리 시스템 서버",{"type":7,"value":641,"toc":680},[642,645,647,649,652,654,657,659,661,663],[54,643,639],{"id":644},"_16-통합-온도-관리-시스템-서버",[61,646],{},[64,648,67],{"id":66},[19,650,651],{},"2022.02 ~ 2023.12 (약 1년 10개월)",[64,653,74],{"id":73},[19,655,656],{},"NestJS, Typescript, Linux (Ubuntu), MariaDB, TypeORM, Redis, Bull, Docker, AWS, Yarn PnP",[64,658,271],{"id":270},[19,660,274],{},[64,662,188],{"id":187},[76,664,665,668,671,674,677],{},[79,666,667],{},"Bull과 Redis로 온도 데이터를 분산 처리하는 큐 시스템 구축",[79,669,670],{},"커버링 인덱스를 사용하여 온도 데이터 조회 성능 48% 개선",[79,672,673],{},"YarnPnP 도입 | 도커 이미지 용량 50% 이상 감소 및 배포 속도 2배 이상 개선",[79,675,676],{},"Nested Set을 이용한 메뉴 권한 동적 생성",[79,678,679],{},"API 키 인증 시스템 구축",{"title":38,"searchDepth":39,"depth":39,"links":681},[682,683,684,685],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F15-dashboard-23-12-01",{"title":639,"description":38},"career\u002F15-dashboard-23-12-01","Rl-JbhPUJNB9O5f4xUVyH2QTQjiRqC2CVdw-lrnMX8k",{"id":692,"title":693,"body":694,"description":701,"extension":41,"meta":754,"navigation":12,"path":755,"seo":756,"stem":757,"__hash__":758},"career\u002Fcareer\u002F16-dashboard-24-04-01.md","17. WMS",{"type":7,"value":695,"toc":748},[696,699,702,704,706,709,711,714,716,719,721],[54,697,693],{"id":698},"_17-wms",[19,700,701],{},"웹 기반 창고 관리 시스템입니다. 창고 내 재고의 이동, 보관을 관리하고 배송, 입고, 출고, 피킹과 관련된 데이터를 처리하도록 설계되었습니다.",[61,703],{},[64,705,67],{"id":66},[19,707,708],{},"2023.12 ~ 2024.04 (약 4개월)",[64,710,74],{"id":73},[19,712,713],{},"NestJS, Typescript, Linux (Ubuntu), MariaDB, TypeORM, Redis, Docker, AWS, Yarn PnP, React, Mobx, React Hook Form, Nginx",[64,715,271],{"id":270},[19,717,718],{},"풀스택 1명, 기획자 1명, 디자이너 1명",[64,720,188],{"id":187},[76,722,723,731,734,742,745],{},[79,724,725,726],{},"ExcelJS Shape 묘화 미지원 문제 해결\n",[76,727,728],{},[79,729,730],{},"XLSX 포맷을 분석해보니 ZIP 포맷과 동일하는 것을 확인하였고, 압축을 해제해보니 라이브러리에서는 여러 XML 파일의 값을 작성하여 엑셀 파일을 만드는 것으로 분석하였습니다. 따라서 엑셀 파일을 역공학으로 분석하여 서버에서 Shape에 해당하는 XML 파일을 직접 작성하고, 최종적으로 ZIP 파일로 압축해 문제를 해결했습니다.",[79,732,733],{},"PDF 문서(입고지시서\u002F출고지시서) 자동 발급 기능",[79,735,736,737],{},"권한 별 메뉴 표시 및 IDE와 유사한 탭 메뉴 구현\n",[76,738,739],{},[79,740,741],{},"VSCode나 크롬 탭과 비슷하게 탭 드래깅 기능과 우측 탭 닫기, 다른 탭 닫기 등을 구현하였습니다.",[79,743,744],{},"재고 조회 가상화 처리로 빠른 스크롤링 가능",[79,746,747],{},"입고\u002F출고\u002F재고 등을 처리하는 API 서버 구현",{"title":38,"searchDepth":39,"depth":39,"links":749},[750,751,752,753],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F16-dashboard-24-04-01",{"title":693,"description":701},"career\u002F16-dashboard-24-04-01","9y_-CSxbiu0m6tyQP2l-_XYxc9SxCQSa9D5pJR3L4pI",{"id":760,"title":761,"body":762,"description":769,"extension":41,"meta":829,"navigation":12,"path":830,"seo":831,"stem":832,"__hash__":833},"career\u002Fcareer\u002F17-dashboard-24-06-01.md","18. TMS 앱",{"type":7,"value":763,"toc":823},[764,767,770,772,774,777,779,782,784,786,788],[54,765,761],{"id":766},"_18-tms-앱",[19,768,769],{},"TMS 앱은 생물학적제제 의약품\u002F일반의약품을 약국으로 배송할 때 온도를 측정하고 노선 정보와 길찾기, 출퇴근 등의 기능을 제공하는 앱입니다.",[61,771],{},[64,773,67],{"id":66},[19,775,776],{},"2024.04 ~ 2024.06 (약 2개월)",[64,778,74],{"id":73},[19,780,781],{},"React Native, TanStack Query, Mobx, Zod, React Hook Form, NestJS, Docker Compose, Nginx, TypeORM, Redis, BullMQ",[64,783,271],{"id":270},[19,785,718],{},[64,787,188],{"id":187},[76,789,790,798,801,804,812,815],{},[79,791,792,793],{},"근거리 무선 통신 NFC 기술을 통해 박스 내부 온도 측정\n",[76,794,795],{},[79,796,797],{},"사용한 오픈 소스에 누락된 안드로이드 관련 인터페이스 추가",[79,799,800],{},"OCR을 통한 거래처 및 출하증명서 정보 자동 입력 처리",[79,802,803],{},"Object Detection을 통해 문서가 감지되면 이미지 자동 캡쳐",[79,805,806,807],{},"EAS 도입\n",[76,808,809],{},[79,810,811],{},"EAS를 도입하여 자바스크립트 번들을 실시간으로 교체 가능하여 사용자에게 좋은 경험 선사",[79,813,814],{},"멀티 프로세스 기반 서버에서 웹소켓 세션 프로세스 간 동기화 및 부하 분산 문제 해결",[79,816,817,818,822],{},"웹소켓 세션 동기화 문제로 NGINX에 기존 라운드로빈 기반에서 ",[819,820,821],"code",{},"hash $remote_addr consistent;","를 설정하여 IP 주소를 기반으로 요청을 특정 서버에 분배하도록 하였습니다.",{"title":38,"searchDepth":39,"depth":39,"links":824},[825,826,827,828],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F17-dashboard-24-06-01",{"title":761,"description":769},"career\u002F17-dashboard-24-06-01","de-oIZN8zoPUDO9kLGP2-QSyy_IuK-Mhw4I8sXko_cI",{"id":835,"title":836,"body":837,"description":844,"extension":41,"meta":909,"navigation":12,"path":910,"seo":911,"stem":912,"__hash__":913},"career\u002Fcareer\u002F18-dashboard-24-08-01.md","19. TMS 대시보드",{"type":7,"value":838,"toc":903},[839,842,845,847,849,852,854,857,859,861,863],[54,840,836],{"id":841},"_19-tms-대시보드",[19,843,844],{},"TMS 앱에서 보낸 데이터를 확인하고, 출하증명서 출력, 노선 관리, 도매상, 태그, 사용자 관리 등을 할 수 있는 대시보드입니다.",[61,846],{},[64,848,67],{"id":66},[19,850,851],{},"2024.06 ~ 2024.08 (약 2개월)",[64,853,74],{"id":73},[19,855,856],{},"React, TanStack Query, Mobx, Zod, React Hook Form, Recharts, Docker Compose, Nginx, NestJS, TypeORM, Redis, DayJS, Websocket, BullMQ",[64,858,271],{"id":270},[19,860,718],{},[64,862,188],{"id":187},[76,864,865,884,895],{},[79,866,867,868],{},"권한 관리에 특화된 메뉴 시스템 개발\n",[76,869,870,877],{},[79,871,872,873,876],{},"권한 테이블 - 상속 관계 매핑(",[819,874,875],{},"@TableInheritance",")을 이용하여 공통 권한과 사용자 권한을 분리하였습니다.",[79,878,879,880,883],{},"계층형 카테고리 조회 - ",[819,881,882],{},"@Tree","를 활용하여 트리로 구조화된 형태로 카테고리를 구성하여 계층형 카테고리 조회 쿼리를 단순화하였습니다.",[79,885,886,887],{},"출하증명서 일괄 PDF 출력 기능\n",[76,888,889,892],{},[79,890,891],{},"ChatGPT Vision API와 Tesseract를 통해 이미지에서 텍스트를 자동으로 추출(OCR)하여 PDF로 생성",[79,893,894],{},"PDF 용 공통 디자인 컴포넌트(표, 라벨, 헤더)를 개발하여 이전보다 더 빠르고 효율적인 개발이 가능하게 됨",[79,896,897,898],{},"재사용성과 확장성을 고려한 프론트엔드 설계 강화\n",[76,899,900],{},[79,901,902],{},"공통 모달과 상태에 기반하여 동작해야 하는 특수한 대화상자를 HOC와 Currying 패턴을 통해 스토어와 결합하였습니다. 이에 따라 코드가 단순해지고 가독성과 재사용성이 좋아지는 결과가 있었습니다.",{"title":38,"searchDepth":39,"depth":39,"links":904},[905,906,907,908],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F18-dashboard-24-08-01",{"title":836,"description":844},"career\u002F18-dashboard-24-08-01","pw6cFNUMvGJeT88vgPNb83roFZmla2J1oaeQj2856_U",{"id":915,"title":916,"body":917,"description":924,"extension":41,"meta":1022,"navigation":12,"path":1023,"seo":1024,"stem":1025,"__hash__":1026},"career\u002Fcareer\u002F19-dashboard-24-10-01.md","20. Cleaning Monitoring System",{"type":7,"value":918,"toc":1016},[919,922,925,928,930,932,935,937,977,979,982,984],[54,920,916],{"id":921},"_20-cleaning-monitoring-system",[19,923,924],{},"고온 세척 시설에서 박스의 온도 및 세척 상태를 체크하기 위한 Medium Range RFID Reader Backend 프로그램입니다.",[19,926,927],{},"Windows에서 Medium Range RFID Reader를 C++\u002FC# 언어를 이용하여 기기 정보 및 태그 UID, 내\u002F외부 온도를 측정하여 웹 서버로 전송하는 프로그램을 개발하였습니다.",[61,929],{},[64,931,67],{"id":66},[19,933,934],{},"2024.08 ~ 진행 중 (약 2개월)",[64,936,74],{"id":73},[76,938,939,971,974],{},[79,940,941,942],{},"Low-level Programming \u002F Hardware Integration:\n",[76,943,944,947,950,953,956,959,962,965,968],{},[79,945,946],{},"C++",[79,948,949],{},"C# (.NET Framework)",[79,951,952],{},"libcurl",[79,954,955],{},"nlohmann\u002Fjson",[79,957,958],{},"Windows API",[79,960,961],{},"C++ STL",[79,963,964],{},"vcpkg",[79,966,967],{},"FEIG SDK",[79,969,970],{},"Visual Studio 2022",[79,972,973],{},"Backend: NestJS, Yarn Berry + PnP, TypeORM, WebSocket",[79,975,976],{},"Frontend: React, Recharts, MUI, SWR, Zod, Axios",[64,978,271],{"id":270},[19,980,981],{},"풀스택 1명",[64,983,188],{"id":187},[76,985,986,1005],{},[79,987,988,989],{},"C++ 과 USB 드라이버를 이용하여 기기(하드웨어)와 통신해 온도 데이터 취득\n",[76,990,991,994,997,1002],{},[79,992,993],{},"게임 업데이트 루프 패턴을 도입하여 30프레임(0.5초) 간격으로 NFC 태그 정보 취득",[79,995,996],{},"Inventory 후 ADC 데이터를 주기적으로 읽는 기능 구현",[79,998,999,1001],{},[819,1000,952],{},"를 통해 BFF 서버로 RAW 데이터 전송. DTO 객체에 JSON 직렬화 기능 추가",[79,1003,1004],{},"부모 프로세스에서 프로세스의 생명 주기를 제어하여 항상 프로그램이 실행 상태에 있을 수 있도록 함",[79,1006,1007,1008],{},"BFF 서버 \u002F 웹 클라이언트 화면 구현\n",[76,1009,1010,1013],{},[79,1011,1012],{},"온도 서버에서 온도 변환 데이터 취득 후 웹소켓으로 실시간으로 데이터 전송",[79,1014,1015],{},"웹소켓으로 전달 받은 세척 상태 \u002F 온도 \u002F 시간 정보를 화면에 표시 및 구현",{"title":38,"searchDepth":39,"depth":39,"links":1017},[1018,1019,1020,1021],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":270,"depth":39,"text":271},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F19-dashboard-24-10-01",{"title":916,"description":924},"career\u002F19-dashboard-24-10-01","DuuGzdEfnJ4tarw3Gu5-rCUfAgeXLphgCMzgfRQ10Gk",{"id":1028,"title":1029,"body":1030,"description":1037,"extension":41,"meta":1137,"navigation":12,"path":1138,"seo":1139,"stem":1140,"__hash__":1141},"career\u002Fcareer\u002F2-dashboard-21-08-10.md","3. 딜리버리 프로젝트",{"type":7,"value":1031,"toc":1130},[1032,1035,1038,1040,1042,1045,1047,1069,1071,1073,1075,1086,1088],[54,1033,1029],{"id":1034},"_3-딜리버리-프로젝트",[19,1036,1037],{},"자사 3채널 패시브 태그 센서를 음식 딜리버리에 접목하여 온도를 추적하고 신선도를 알 수 있는 컨셉이었으며 노드를 이용한 MVP 개발하여 최소한의 기능만을 구현하여 빠르게 출시하였습니다. 2차 프로젝트로 자사의 3채널 패시브 태그 센서를 통해 의약품(생물학적제제)의 온도를 추적하고 관리하는 아이디어로 생물학적제제 딜리버리 콜드체인 프로젝트 MVP를 진행하였습니다.",[61,1039],{},[64,1041,67],{"id":66},[19,1043,1044],{},"2021.08 ~ 2021.10 (3개월)",[64,1046,74],{"id":73},[76,1048,1049,1051,1054,1057,1060,1062,1064,1067],{},[79,1050,162],{},[79,1052,1053],{},"SequelizeORM (초기)",[79,1055,1056],{},"TypeORM (추후 마이그레이션)",[79,1058,1059],{},"Nuxt.js (Vue.js)",[79,1061,87],{},[79,1063,90],{},[79,1065,1066],{},"Nginx",[79,1068,174],{},[64,1070,108],{"id":107},[19,1072,184],{},[64,1074,188],{"id":187},[76,1076,1077,1080,1083],{},[79,1078,1079],{},"타입스크립트 기반 Nest.js (Node.js)를 사용하여 웹 백엔드 서버 구현",[79,1081,1082],{},"도커와 NGINX Reverse Proxy 그리고 깃허브 웹훅을 사용하여 웹 서버 자동 빌드 및 배포 시스템 구현",[79,1084,1085],{},"Nuxt.js를 사용하여 SPA 대시보드 사이트 개발",[64,1087,115],{"id":114},[76,1089,1090,1100,1105,1112,1115,1118,1121,1124,1127],{},[79,1091,1092,1093,1096,1097,1099],{},"웹 백엔드 개발(",[819,1094,1095],{},"Nest.js"," + ",[819,1098,165],{},")",[79,1101,1102,1103,1099],{},"CI\u002FCD 서버 자체 구현 (",[819,1104,1095],{},[79,1106,1107,1108,1111],{},"24시간 무중단 서비스 구현(",[819,1109,1110],{},"Docker Compose","를 이용한 다중 서버)",[79,1113,1114],{},"깃 웹훅 서버와 NGINX 블루-그린 배포 전략을 이용한 무중단 배포 시스템 구현",[79,1116,1117],{},"JWT를 이용한 세션리스 서버 구성",[79,1119,1120],{},"카카오맵을 활용한 지도 구현",[79,1122,1123],{},"차트 라이브러리(Chart.js)를 활용하여 시간대별 온도 정보 통계 및 다양한 그래프 제공",[79,1125,1126],{},"스크롤 시 자동 페이지네이션 자체 구현",[79,1128,1129],{},"Vue.mixin을 사용하여 코드 재사용성을 높임",{"title":38,"searchDepth":39,"depth":39,"links":1131},[1132,1133,1134,1135,1136],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{"id":114,"depth":39,"text":115},{},"\u002Fcareer\u002F2-dashboard-21-08-10",{"title":1029,"description":1037},"career\u002F2-dashboard-21-08-10","kkIm9DkwBkdqz3Rnskgy6OIG4ajCL80ylKR_LFU7f1o",{"id":1143,"title":1144,"body":1145,"description":1152,"extension":41,"meta":1187,"navigation":12,"path":1188,"seo":1189,"stem":1190,"__hash__":1191},"career\u002Fcareer\u002F3-dashboard-21-11-11.md","4. 회사 홈페이지 인프라 및 최적화",{"type":7,"value":1146,"toc":1182},[1147,1150,1153,1155,1158,1160,1163,1165],[54,1148,1144],{"id":1149},"_4-회사-홈페이지-인프라-및-최적화",[19,1151,1152],{},"자사의 패시브 온도 태그 등의 제품을 소개하는 콜드체인 관련 전시회에 참가하기 위해 회사 홈페이지 인프라를 빠르게 구축했습니다. 단, 3시간 만에 MVP 개발을 완료하고 서비스를 시작했습니다. 피드백을 받아 무선 데이터 환경에서도 자동으로 저화질로 재생될 수 있도록 FFMPEG와 HLS를 사용하여 스트리밍 재생을 지원하여 전시회에 참여한 사람들이 쾌적하게 동영상을 재생할 수 있게 대응했습니다. 또한 PC 환경에서는 고화질 스트리밍 영상으로 재생될 수 있도록 서버 설정을 변경했습니다.",[64,1154,67],{"id":66},[19,1156,1157],{},"2021.11 ~ 2021.11 (1일)",[64,1159,108],{"id":107},[19,1161,1162],{},"100%",[64,1164,188],{"id":187},[76,1166,1167,1170,1173,1176,1179],{},[79,1168,1169],{},"단 3시간만에 새로운 서버 인프라를 구축하고 완벽히 서비스한 경험 (리눅스 우분투 서버)",[79,1171,1172],{},"iOS에서 동영상이 전체 화면으로 재생되는 문제 해결",[79,1174,1175],{},"무선 데이터 환경에서는 자동으로 저화질로 재생될 수 있도록 스트리밍 재생 지원 (FFMPEG와 HLS 사용)",[79,1177,1178],{},"PC 환경에서는 고화질 스트리밍 영상으로 재생될 수 있도록 서버 설정 변경",[79,1180,1181],{},"SSL\u002FTLS 인증서 문제 해결",{"title":38,"searchDepth":39,"depth":39,"links":1183},[1184,1185,1186],{"id":66,"depth":39,"text":67},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F3-dashboard-21-11-11",{"title":1144,"description":1152},"career\u002F3-dashboard-21-11-11","wbsMWOHiWJH8_-WFnxT8SEKXWDX2Uqhc2OUR-wbfiYU",{"id":1193,"title":1194,"body":1195,"description":1202,"extension":41,"meta":1267,"navigation":12,"path":1268,"seo":1269,"stem":1270,"__hash__":1271},"career\u002Fcareer\u002F4-dashboard-21-12-12.md","5. 의약품 온도 관리 서버",{"type":7,"value":1196,"toc":1260},[1197,1200,1203,1205,1207,1210,1212,1230,1232,1234,1236,1241,1243],[54,1198,1194],{"id":1199},"_5-의약품-온도-관리-서버",[19,1201,1202],{},"딜리버리 MVP 프로젝트에 이어, 의약품(생물학적제제)의 온도를 추적하고 관리하는 생물학적제제 딜리버리 콜드체인 MVP 프로젝트를 진행하였습니다. MVP 개발을 통해 최소한의 기능만을 구현하여 빠르게 출시하여 피드백을 받고, 이를 바탕으로 1년 후인 2022년에 3차 프로젝트를 진행하였습니다.",[61,1204],{},[64,1206,67],{"id":66},[19,1208,1209],{},"2021.12 ~ 2021.12",[64,1211,74],{"id":73},[76,1213,1214,1216,1218,1220,1223,1226,1228],{},[79,1215,162],{},[79,1217,254],{},[79,1219,1059],{},[79,1221,1222],{},"MariaDB",[79,1224,1225],{},"Linux (Ubuntu Server)",[79,1227,1066],{},[79,1229,174],{},[64,1231,108],{"id":107},[19,1233,184],{},[64,1235,188],{"id":187},[76,1237,1238],{},[79,1239,1240],{},"태그 센서를 이용하여 의약품의 온도와 위치를 관리 및 추적할 수 있는 웹 백엔드 서버 및 대시보드 개발",[64,1242,115],{"id":114},[76,1244,1245,1248,1251,1254,1257],{},[79,1246,1247],{},"서버 인프라 구축 (리눅스 우분투 서버)",[79,1249,1250],{},"백엔드 서버 개발 (Nest.js, Docker)",[79,1252,1253],{},"프론트엔드 개발 (Nuxt.js)",[79,1255,1256],{},"도커 게이트웨이를 이용하여 서버 로그를 웹훅 서버로 보내는 기능 구현 (ts-node로 개발)",[79,1258,1259],{},"서버 로그 제거 기능 추가",{"title":38,"searchDepth":39,"depth":39,"links":1261},[1262,1263,1264,1265,1266],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{"id":114,"depth":39,"text":115},{},"\u002Fcareer\u002F4-dashboard-21-12-12",{"title":1194,"description":1202},"career\u002F4-dashboard-21-12-12","LQJyePulDFtzqfR8BOcdnsTJy58kmIe-TBTNu7nvo6Q",{"id":1273,"title":1274,"body":1275,"description":1282,"extension":41,"meta":1322,"navigation":12,"path":1323,"seo":1324,"stem":1325,"__hash__":1326},"career\u002Fcareer\u002F5-dashboard-22-02-03.md","6. 개발 환경 고도화 작업",{"type":7,"value":1276,"toc":1316},[1277,1280,1283,1285,1287,1290,1292,1299,1301,1303,1305],[54,1278,1274],{"id":1279},"_6-개발-환경-고도화-작업",[19,1281,1282],{},"기존에 익숙하게 사용하던 ORM에서 TypeORM을 사용하여 새로 개발하고 전반적인 개발 환경을 고도화하는 작업을 진행했습니다.",[61,1284],{},[64,1286,67],{"id":66},[19,1288,1289],{},"2022.01 ~ 2022.02 (총 2개월)",[64,1291,74],{"id":73},[76,1293,1294,1297],{},[79,1295,1296],{},"Node.js (Typescript)",[79,1298,254],{},[64,1300,108],{"id":107},[19,1302,1162],{},[64,1304,115],{"id":114},[76,1306,1307,1310,1313],{},[79,1308,1309],{},"SequelizeORM에서 TypeORM으로 마이그레이션 경험",[79,1311,1312],{},"설정 파일을 자동으로 설정할 수 있는 스타터 툴 개발 경험",[79,1314,1315],{},"인증서 남은 기간을 계산하여 휴대폰으로 PUSH 알람을 보내는 서비스 개발 경험",{"title":38,"searchDepth":39,"depth":39,"links":1317},[1318,1319,1320,1321],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":107,"depth":39,"text":108},{"id":114,"depth":39,"text":115},{},"\u002Fcareer\u002F5-dashboard-22-02-03",{"title":1274,"description":1282},"career\u002F5-dashboard-22-02-03","puYzQcDbdB8A1XmFWrYJ4k4_czyB-GzBTlplTSYfiqw",{"id":1328,"title":1329,"body":1330,"description":38,"extension":41,"meta":1381,"navigation":12,"path":1382,"seo":1383,"stem":1384,"__hash__":1385},"career\u002Fcareer\u002F6-dashboard-22-01-02.md","7. 아일랜드 백엔드 서버",{"type":7,"value":1331,"toc":1375},[1332,1335,1337,1339,1342,1344,1358,1360,1362,1364],[54,1333,1329],{"id":1334},"_7-아일랜드-백엔드-서버",[61,1336],{},[64,1338,67],{"id":66},[19,1340,1341],{},"2022.02.14 ~ 2022.04.22 (총 3개월)",[64,1343,74],{"id":73},[76,1345,1346,1348,1350,1352,1354,1356],{},[79,1347,162],{},[79,1349,254],{},[79,1351,1222],{},[79,1353,1225],{},[79,1355,1066],{},[79,1357,174],{},[64,1359,108],{"id":107},[19,1361,1162],{},[64,1363,115],{"id":114},[76,1365,1366,1369,1372],{},[79,1367,1368],{},"대규모 Bulk Insert 시, Bull.js와 Redis를 이용하여 성능 5배 이상 향상",[79,1370,1371],{},"로그 데이터 수집 및 개인 정보 암호화 처리 강화",[79,1373,1374],{},"메일 발송 처리 및 인증 체계 개선",{"title":38,"searchDepth":39,"depth":39,"links":1376},[1377,1378,1379,1380],{"id":66,"depth":39,"text":67},{"id":73,"depth":39,"text":74},{"id":107,"depth":39,"text":108},{"id":114,"depth":39,"text":115},{},"\u002Fcareer\u002F6-dashboard-22-01-02",{"title":1329,"description":38},"career\u002F6-dashboard-22-01-02","FO7YzCvfcnCEPOzYTDpHV6b59DYRWcQN2dlN6IgNXpw",{"id":1387,"title":1388,"body":1389,"description":38,"extension":41,"meta":1448,"navigation":12,"path":1449,"seo":1450,"stem":1451,"__hash__":1452},"career\u002Fcareer\u002F7-dashboard-22-04-26.md","8. 아일랜드 프론트엔드 개발",{"type":7,"value":1390,"toc":1441},[1391,1394,1396,1398,1401,1405,1419,1421,1423,1425,1433,1436],[54,1392,1388],{"id":1393},"_8-아일랜드-프론트엔드-개발",[61,1395],{},[64,1397,67],{"id":66},[19,1399,1400],{},"2022.04.26 ~ 2022.06.13",[64,1402,1404],{"id":1403},"사용-라이브러리","사용 라이브러리",[76,1406,1407,1410,1413,1416],{},[79,1408,1409],{},"React",[79,1411,1412],{},"Mobx",[79,1414,1415],{},"Recoil",[79,1417,1418],{},"MUI",[64,1420,108],{"id":107},[19,1422,1162],{},[64,1424,188],{"id":187},[76,1426,1427,1430],{},[79,1428,1429],{},"기존에 익숙하게 사용하던 Nuxt.js(Vue 2)에서 React.js (Typescript)로 라이브러리로 변경",[79,1431,1432],{},"클라이언트 상태 관리와 서버 상태 관리 라이브러리를 구분하여 사용",[64,1434,1435],{"id":1435},"특징",[76,1437,1438],{},[79,1439,1440],{},"리액트, 뷰 같은 V-DOM 기반에서 자바 스프링 템플릿 엔진 사용이 결정되면서 개발이 중단됨.",{"title":38,"searchDepth":39,"depth":39,"links":1442},[1443,1444,1445,1446,1447],{"id":66,"depth":39,"text":67},{"id":1403,"depth":39,"text":1404},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{"id":1435,"depth":39,"text":1435},{},"\u002Fcareer\u002F7-dashboard-22-04-26",{"title":1388,"description":38},"career\u002F7-dashboard-22-04-26","hkKRzyzhI_hBr5ux93h32rwlcxb2fAWX84RHL31el_I",{"id":1454,"title":1455,"body":1456,"description":1463,"extension":41,"meta":1509,"navigation":12,"path":1510,"seo":1511,"stem":1512,"__hash__":1513},"career\u002Fcareer\u002F8-dashboard-22-06-07.md","9. 생물학적제제 딜리버리 콜드체인 프로젝트",{"type":7,"value":1457,"toc":1503},[1458,1461,1464,1466,1468,1471,1473,1483,1485,1487,1489],[54,1459,1455],{"id":1460},"_9-생물학적제제-딜리버리-콜드체인-프로젝트",[19,1462,1463],{},"이 대시보드는 자사의 3채널 패시브 온도 태그로 생물학적 제제(의약품)의 온도를 측정하여 2~8℃의 온도가 유지되는지 추적 관리하는데 도움을 줍니다. 차트 형태로 데이터를 시각화하였기 때문에 한 눈에 확인이 가능하며 배송 현황도 추적할 수 있습니다. 또한 웹에서 생물학적제제 출하증명서 발급이 가능합니다.",[61,1465],{},[64,1467,67],{"id":66},[19,1469,1470],{},"2022.06.07 ~ 2022.07.15 (4주)",[64,1472,1404],{"id":1403},[76,1474,1475,1477,1480],{},[79,1476,242],{},[79,1478,1479],{},"Nuxt.js",[79,1481,1482],{},"TypeScript",[64,1484,108],{"id":107},[19,1486,184],{},[64,1488,188],{"id":187},[76,1490,1491,1494,1497,1500],{},[79,1492,1493],{},"엑셀을 통한 DB 삽입 기능 추가",[79,1495,1496],{},"전자 증명서 발급 기능 추가",[79,1498,1499],{},"바코드(CODE-39, CODE-128)를 기준으로 전면 개편",[79,1501,1502],{},"무중단 배포 기능 추가",{"title":38,"searchDepth":39,"depth":39,"links":1504},[1505,1506,1507,1508],{"id":66,"depth":39,"text":67},{"id":1403,"depth":39,"text":1404},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F8-dashboard-22-06-07",{"title":1455,"description":1463},"career\u002F8-dashboard-22-06-07","F6V-xtNpwRxOTPUnjq32dI2QoTHTG2bJiTq9zj4s-Mg",{"id":1515,"title":1516,"body":1517,"description":1524,"extension":41,"meta":1581,"navigation":12,"path":1582,"seo":1583,"stem":1584,"__hash__":1585},"career\u002Fcareer\u002F9-dashboard-22-07-29.md","10. 생물학적제제 딜리버리 콜드체인 프로젝트 관리자 대시보드",{"type":7,"value":1518,"toc":1575},[1519,1522,1525,1527,1529,1532,1534,1552,1554,1556,1558],[54,1520,1516],{"id":1521},"_10-생물학적제제-딜리버리-콜드체인-프로젝트-관리자-대시보드",[19,1523,1524],{},"3채널 패시브 온도 태그로 생물학적 제제(의약품)의 온도를 측정하여 2~8℃의 온도가 유지되는지 추적 관리하는 역할을 가진 대시보드의 관리자 페이지입니다. 관리자 페이지는 배송 과정에서 누락되는 바코드 상태를 확인할 수 있습니다.",[61,1526],{},[64,1528,67],{"id":66},[19,1530,1531],{},"2022.07.29 ~ 2022.08.12 (2주)",[64,1533,1404],{"id":1403},[76,1535,1536,1539,1541,1543,1546,1549],{},[79,1537,1538],{},"React.js (TypeScript)",[79,1540,1418],{},[79,1542,1412],{},[79,1544,1545],{},"react-spring",[79,1547,1548],{},"카카오맵 API",[79,1550,1551],{},"Chart.js v3.9.1",[64,1553,108],{"id":107},[19,1555,1162],{},[64,1557,188],{"id":187},[76,1559,1560,1563,1566,1569,1572],{},[79,1561,1562],{},"태그 센서 관리 기능 추가",[79,1564,1565],{},"출하증명서 관리 기능 추가",[79,1567,1568],{},"액세스 키를 권한 별로 부여하는 기능 추가",[79,1570,1571],{},"멤버 관리 기능",[79,1573,1574],{},"측정 로그 관리 기능",{"title":38,"searchDepth":39,"depth":39,"links":1576},[1577,1578,1579,1580],{"id":66,"depth":39,"text":67},{"id":1403,"depth":39,"text":1404},{"id":107,"depth":39,"text":108},{"id":187,"depth":39,"text":188},{},"\u002Fcareer\u002F9-dashboard-22-07-29",{"title":1516,"description":1524},"career\u002F9-dashboard-22-07-29","vmMO0Xbeb92HZJJPU9-z9yYGwqzz9PUvsHGKkDr4jF0",{"id":1587,"title":1588,"body":1589,"description":38,"extension":41,"meta":2240,"navigation":12,"path":2241,"seo":2242,"stem":2243,"__hash__":2244},"projects\u002Fprojects\u002Fhobby.md","Hobby",{"type":7,"value":1590,"toc":2238},[1591,1923],[10,1592,1593,1596],{},[14,1594,1595],{},"Ruby Game Scripting System (RGSS)",[76,1597,1598,1601,1604,1607,1610,1613,1616,1619,1622,1625,1628,1631,1634,1637,1640,1643,1646,1649,1652,1655,1658,1661,1664,1667,1670,1673,1676,1679,1682,1685,1688,1691,1694,1697,1700,1703,1706,1709,1712,1715,1718,1721,1724,1727,1730,1733,1736,1739,1742,1745,1748,1751,1754,1761,1764,1769,1775,1778,1784,1787,1790,1793,1796,1799,1802,1805,1808,1811,1814,1817,1823,1826,1829,1832,1835,1838,1841,1844,1847,1853,1856,1859,1862,1865,1868,1871,1874,1877,1880,1883,1886,1889,1892,1895,1898,1901,1904,1907,1910,1915,1920],{},[79,1599,1600],{},"눈보라 효과가 적용된 타이틀 메뉴 - 2014. 6. 27.",[79,1602,1603],{},"그림 애니메이션 - 2014. 6. 27.",[79,1605,1606],{},"윈도우 투명도 조절 스크립트(WinAPI) - 2014. 6. 27.",[79,1608,1609],{},"볼륨 조절 (불안정) - 2014. 6. 27.",[79,1611,1612],{},"자동 저장 - 2014. 6. 27.",[79,1614,1615],{},"원형 타이틀 메뉴 스크립트 - 2014. 6. 30.",[79,1617,1618],{},"슈팅 게임 개발 키트 - 2014. 7. 11.",[79,1620,1621],{},"심플 세이브 파일\u002F로드 스크립트 - 2014. 7. 30.",[79,1623,1624],{},"원형 회전판 메뉴 - 2014. 8. 13.",[79,1626,1627],{},"그래픽 메뉴 - RGSS3 Scripts - 2014. 8. 13.",[79,1629,1630],{},"도둑질 시스템 - 2014. 8. 19.",[79,1632,1633],{},"한글 인코딩 모듈 - 2014. 9. 25.",[79,1635,1636],{},"HUD(HP, MP, EXP, LEVEL) - 2014. 9. 25.",[79,1638,1639],{},"화면 크기 변경하기 - 2014. 9. 25.",[79,1641,1642],{},"엔딩을 마친 후 타이틀 메뉴에 특별 메뉴를 추가하는 스크립트 (데이터 확인) - 2014. 9. 25.",[79,1644,1645],{},"화면 중앙 상단 메시지 - 2014. 10. 10.",[79,1647,1648],{},"미니맵 시스템 - RGSS3 Scripts - 2014. 10. 17.",[79,1650,1651],{},"일정 시간마다 타이틀을 변경하는 스크립트 (타이틀 움짤 만들기) - 2014. 10. 20.",[79,1653,1654],{},"미니맵 시스템 - RGSS1 Scripts - 2014. 10. 21.",[79,1656,1657],{},"BM Font (완성형 한글) - RGSS3 Scripts - 2014. 10. 22.",[79,1659,1660],{},"엔딩을 마친 후 타이틀과 BGM을 변경하는 스크립트 - 2014. 10. 29.",[79,1662,1663],{},"세이브 화면에 얼굴그래픽 설정 - 2014. 10. 30.",[79,1665,1666],{},"캐릭터 컨트롤러 - RGSS3 Scripts - 2014. 10. 30.",[79,1668,1669],{},"레벨 제한 돌파 - 2014. 11. 9.",[79,1671,1672],{},"상점 가격 변동 - 2014. 11. 11.",[79,1674,1675],{},"캐릭터 톤 변경 - 2014. 11. 18.",[79,1677,1678],{},"램덤 스킬 습득 - 2014. 11. 30.",[79,1680,1681],{},"엔딩을 마친 후 타이틀 메뉴에 특별 메뉴를 추가하는 스크립트 (데이터 미확인) - 2014. 12. 6.",[79,1683,1684],{},"캐릭터 점멸 - 2014. 12. 21.",[79,1686,1687],{},"RTP 파일 가져오기 - 2015. 1. 18.",[79,1689,1690],{},"이벤트 생성 스크립트 - RGSS3 Scripts - 2015. 1. 18.",[79,1692,1693],{},"HUD(HP,SP,EXP,LEVEL) - RGSS Scripts - 2015. 1. 22.",[79,1695,1696],{},"런타임 패키지(RTP) 다운로드 - RPG 만들기 RTP - 2015. 1. 25.",[79,1698,1699],{},"INI 모듈 - RGSS3 Scripts - 2015. 1. 30.",[79,1701,1702],{},"Bitmap Extension (Draw Circle) - RGSS3 Scripts - 2015. 2. 23.",[79,1704,1705],{},"이벤트 생성 스크립트 - RGSS2 Scripts - 2015. 2. 25.",[79,1707,1708],{},"데이터베이스 최대치 확장 (RGSS3) - 2015. 2. 27.",[79,1710,1711],{},"RS Input Core : 전체키 확장 및 마우스 지원 + 자동 이동 - 2015. 3. 3.",[79,1713,1714],{},"셀프 변수(Self Variables) - RGSS3 Scripts - 2015. 3. 21.",[79,1716,1717],{},"메소드 동적으로 생성 - 2015. 3. 22.",[79,1719,1720],{},"로고 스크립트(Logo) - RGSS3 Scripts - 2015. 4. 12.",[79,1722,1723],{},"뮤텍스로 다중 인스턴스 방지(WinAPI) - 2015. 5. 7.",[79,1725,1726],{},"메시지 루프 및 핸들러 - 2015. 5. 10.",[79,1728,1729],{},"세이브 파일 간 아이템 주고 받기 - 2015. 5. 27.",[79,1731,1732],{},"작업 관리자 강제 종료 - 2015. 6. 28.",[79,1734,1735],{},"게임 멈춤 방지 - 2015. 6. 29.",[79,1737,1738],{},"조건부 저장 버튼 표시 - 2015. 7. 6.",[79,1740,1741],{},"장비 교체 후 현재 체력 자동 보정 - 2015. 7. 6.",[79,1743,1744],{},"웹페이지 html 소스 가져오기 - RGSS3\u002FRuby Scripts - 2015. 7. 9.",[79,1746,1747],{},"루비 명령 프롬프트(Ruby Command Prompt) - 2015. 7. 14.",[79,1749,1750],{},"한글 이름 입력 처리 | 한국어, 영어, 일본어, 중국어 입력 가능 - 2015. 7. 14.",[79,1752,1753],{},"Game.rgss3a 파일 복호화 과정 - 2015. 7. 20.",[79,1755,1756,1760],{},[1757,1758,1759],"span",{},"Ruby"," re_define, re_call - 2015. 7. 20.",[79,1762,1763],{},"인터넷으로 파일을 다운로드 받는 스크립트 - 2015. 8. 7.",[79,1765,1766,1768],{},[1757,1767,1759],{}," Vector2.rb - 2015. 9. 4.",[79,1770,1771,1774],{},[1757,1772,1773],{},"새로운 소식"," GG Maker, 20일 무료 체험판 공개 - 2015. 9. 5.",[79,1776,1777],{},"상태 이상에 따라 적 배틀러 그래픽을 알맞게 자동 변경하는 스크립트 - 2015. 9. 7.",[79,1779,1780,1783],{},[1757,1781,1782],{},"통합본"," 엔딩 후 타이틀과 BGM 변경 + 엔딩 후 스페셜 메뉴 띄우기 - 2015. 9. 7.",[79,1785,1786],{},"효과음 루프 스크립트 - 2015. 10. 13.",[79,1788,1789],{},"GIF Controller (Bitmap-Ex Add-On) - 2015. 10. 13.",[79,1791,1792],{},"메시지박스 추가 정의 예제 - RGSS3 - 2015. 12. 19.",[79,1794,1795],{},"세이브 화면에 얼굴그래픽 설정 - RPG Maker VX - 2015. 12. 20.",[79,1797,1798],{},"특정 엔딩 클리어 시에만 특별 메뉴 추가 - 2016. 1. 17.",[79,1800,1801],{},"바탕화면에 바로가기 만들기 - 2016. 1. 24.",[79,1803,1804],{},"세이브파일 전부 삭제 - 2016. 2. 25.",[79,1806,1807],{},"플레이어가 파티원을 통과하지 못하게 하기 - 2016. 6. 1.",[79,1809,1810],{},"FPS (DLL) - 2016. 6. 15.",[79,1812,1813],{},"엔딩 후 타이틀 변경하기 - 2016. 7. 27.",[79,1815,1816],{},"전투 중에 이름 입력 처리 - 2017. 8. 10.",[79,1818,1819,1822],{},[1757,1820,1821],{},"VXA\u002FVX"," 그림을 맵 좌표에 고정하기 - RPG Maker - 2018. 2. 23.",[79,1824,1825],{},"한글이 포함된 환경 변수 취득하기 - 2018. 5. 2.",[79,1827,1828],{},"Pause 아이콘의 위치 변경 - 2018. 6. 29.",[79,1830,1831],{},"변수 표시 윈도우 - 2018. 6. 29.",[79,1833,1834],{},"XBOX360 컨트롤러 사용 여부 체크 (게임 패드) - 2018. 7. 12.",[79,1836,1837],{},"콘솔창 띄우기 - 2018. 7. 15.",[79,1839,1840],{},"대화중 캐릭터 이동 - 2018. 7. 15.",[79,1842,1843],{},"아이템 소지 시 패시브 상태 발동 - 2018. 8. 20.",[79,1845,1846],{},"파티원 페이스칩 표시 (텍스트 코드 추가) - 2018. 8. 20.",[79,1848,1849,1852],{},[1757,1850,1851],{},"XP"," 메뉴에 배경 표시 (저장용) - 2018. 12. 3.",[79,1854,1855],{},"HUD for VX - RPG Maker VX - 2019. 1. 28.",[79,1857,1858],{},"커스텀 타이틀 - 2019. 3. 11.",[79,1860,1861],{},"길찾기(path finding) - 2019. 3. 31.",[79,1863,1864],{},"이벤트 이름 표시 - 2019. 5. 3.",[79,1866,1867],{},"모든 아이템 회수 및 복구 - 2019. 5. 3.",[79,1869,1870],{},"길 찾기 - 2019. 5. 3.",[79,1872,1873],{},"한글 비트맵 폰트 - RPG Maker :: All RGSS - 2019. 5. 4.",[79,1875,1876],{},"사용자 컴퓨터의 언어를 체크하는 스크립트 - RGSS3 - 2019. 5. 13.",[79,1878,1879],{},"XML 파일 처리 - 2019. 6. 18.",[79,1881,1882],{},"게임 포커스 유지 스크립트 (버그 수정본) - RPG Maker - 2019. 9. 9.",[79,1884,1885],{},"자세한 오류 표시 - 2019. 12. 21.",[79,1887,1888],{},"스플래시 애니메이션 스크립트 (영상만 있음) - 2020. 1. 4.",[79,1890,1891],{},"마우스 이벤트 스크립트 - 2020. 1. 29.",[79,1893,1894],{},"JSON - 2020. 3. 13.",[79,1896,1897],{},"관리자 권한 획득 - 2020. 3. 19.",[79,1899,1900],{},"게임 화면 녹화 및 영상 리플레이 스크립트 - 2020. 3. 24.",[79,1902,1903],{},"Rust로 ZIP 압축 해제(Decompres) 기능 만들기 - 2020. 4. 10.",[79,1905,1906],{},"텍스트 파일에서 문장을 가져오는 스크립트 - 2020. 4. 21.",[79,1908,1909],{},"Bitmap Digit Number - 2020. 5. 30.",[79,1911,1912,1914],{},[1757,1913,1759],{}," Steam C-API Extractor - 2020. 6. 27.",[79,1916,1917,1919],{},[1757,1918,1759],{}," 한글로 적혀있는 파일 탐색 및 영어로 이름 강제 변경 - 2020. 10. 24.",[79,1921,1922],{},"Splash Screen - 2021. 5. 9.",[10,1924,1925,1928],{},[14,1926,1927],{},"JGSS (Javascript Game Scripting System: MV, MZ)",[76,1929,1930,1933,1936,1939,1942,1945,1948,1951,1954,1957,1960,1963,1966,1972,1975,1980,1983,1986,1989,1992,1995,1998,2001,2004,2007,2010,2013,2016,2019,2022,2025,2028,2031,2034,2037,2040,2043,2046,2049,2052,2055,2058,2061,2064,2067,2070,2073,2076,2079,2082,2085,2091,2097,2100,2103,2106,2109,2112,2115,2118,2121,2124,2127,2130,2133,2136,2139,2142,2145,2148,2151,2154,2157,2160,2163,2166,2169,2172,2175,2178,2181,2184,2187,2190,2193,2196,2199,2202,2205,2208,2211,2214,2217,2225,2232,2235],{},[79,1931,1932],{},"한글 이름 입력의 처리 (IME) - 2015. 10. 19.",[79,1934,1935],{},"대화 시 이벤트 원래 방향 유지 - 2015. 11. 7.",[79,1937,1938],{},"Online Chat (Node.js + Socket.io) - 2015. 11. 8.",[79,1940,1941],{},"타이틀 이미지 특정 시간 마다 변경 - 2015. 11. 9.",[79,1943,1944],{},"이벤트 이름 표시 - 2015. 11. 11.",[79,1946,1947],{},"Login Form - 2015. 11. 25.",[79,1949,1950],{},"OGG 파일 우선 재생 - 2015. 11. 28.",[79,1952,1953],{},"버전 표시 레이어(Version Layer) - 2015. 12. 13.",[79,1955,1956],{},"특정 엔딩을 마친 후 타이틀과 BGM을 변경하는 플러그인 - 2015. 12. 21.",[79,1958,1959],{},"게임 스크린샷 파일을 만드는 플러그인 - 2015. 12. 22.",[79,1961,1962],{},"발소리 재생 플러그인 - 2015. 12. 26.",[79,1964,1965],{},"WAV 파일 재생 - 2015. 12. 26.",[79,1967,1968,1971],{},[1757,1969,1970],{},"Android"," 취소(Back) 버튼 처리하기 - 2015. 12. 26.",[79,1973,1974],{},"세이브 파일 난독화 - 2015. 12. 29.",[79,1976,1977,1979],{},[1757,1978,1970],{}," Toast - 2015. 12. 30.",[79,1981,1982],{},"파일 업데이트 시스템(File Update System) - 2016. 1. 4.",[79,1984,1985],{},"심플 메뉴 정보창 - 2016. 1. 4.",[79,1987,1988],{},"HUD \u002F 게이지바 - 2016. 1. 12.",[79,1990,1991],{},"웨이브 필터(Wave Filter) - 2016. 1. 14.",[79,1993,1994],{},"Minimize to Tray - 2016. 1. 21.",[79,1996,1997],{},"상점 아이템 물가 변동률 설정 - 2016. 1. 21.",[79,1999,2000],{},"아이템 설명창 확장 애드온 (YEP) - 2016. 1. 21.",[79,2002,2003],{},"자동 이동 시스템 끄기 - 2016. 1. 21.",[79,2005,2006],{},"스테이터스 색상값 변경 애드온 (YEP) - 2016. 1. 21.",[79,2008,2009],{},"저장 경로 변경 - 2016. 1. 30.",[79,2011,2012],{},"심플 라이트(Simple Light) - 2016. 2. 13.",[79,2014,2015],{},"이벤트 생성 플러그인 - 2016. 2. 20.",[79,2017,2018],{},"언어 설정 - 2016. 2. 20.",[79,2020,2021],{},"변수 값 제한 - 2016. 2. 23.",[79,2023,2024],{},"타이틀 스킵(Title Skip) - 2016. 3. 3.",[79,2026,2027],{},"세이브 파일간 아이템 전송(Item Stream) - 2016. 3. 7.",[79,2029,2030],{},"선택지 위치 변경 - 2016. 3. 14.",[79,2032,2033],{},"Vector2 클래스 - 2016. 3. 14.",[79,2035,2036],{},"얼굴 그래픽 스크롤 애드온 - 2016. 4. 18.",[79,2038,2039],{},"길찾기 - 2016. 4. 26.",[79,2041,2042],{},"Video Control - 2016. 5. 7.",[79,2044,2045],{},"YouTube Player - 2016. 5. 8.",[79,2047,2048],{},"WebGL 모드 우선 적용 - 2016. 5. 12.",[79,2050,2051],{},"Refresh Manager - 2016. 5. 16.",[79,2053,2054],{},"배틀 허드(Battle HUD) 애드온 - 2016. 5. 21.",[79,2056,2057],{},"파티원 통과 금지 설정 - 2016. 6. 1.",[79,2059,2060],{},"이벤트 터치 트리거 - 2016. 7. 4.",[79,2062,2063],{},"렌더러 옵션 변경 - 2016. 7. 4.",[79,2065,2066],{},"셀프 변수 플러그인 (Self Variables) - 2016. 7. 25.",[79,2068,2069],{},"텍스트 입력창 - 2016. 8. 9.",[79,2071,2072],{},"화면 분할 플러그인(Multiple Viewports) - 2016. 8. 24.",[79,2074,2075],{},"노이즈 필터(Tilemap Noise Filter) - 2016. 9. 4.",[79,2077,2078],{},"화면 해상도 설정 - 2016. 10. 4.",[79,2080,2081],{},"FPS 박스에서 커서 모양 수정하기(Mode Text Curosr Fixes) - 2016. 10. 6.",[79,2083,2084],{},"캔버스 필터(Canvas Filter) - 2016. 10. 6.",[79,2086,2087,2090],{},[1757,2088,2089],{},"Android\u002FiOS"," 화면 꺼짐 방지 - 2016. 11. 19.",[79,2092,2093,2096],{},[1757,2094,2095],{},"실험작"," 커스텀 타이틀 - 2016. 11. 22.",[79,2098,2099],{},"Wav 파일 암호화 도구 - 2016. 11. 30.",[79,2101,2102],{},"거울에 이미지를 표시하는 플러그인(Mirror Area) - 2016. 12. 7.",[79,2104,2105],{},"키보드 이벤트 - 2017. 1. 3.",[79,2107,2108],{},"메시지 코어 텍스트 정렬 애드온 (YEP) - 2017. 1. 25.",[79,2110,2111],{},"화면 방향 전환(Screen Orientation) - 2017. 2. 16.",[79,2113,2114],{},"Cordova Build Package (Intel XDK 3900) - 2017. 3. 28.",[79,2116,2117],{},"한글 메시지 시스템에서 이름 윈도우 스킨 변경 - 2017. 4. 8.",[79,2119,2120],{},"상태 창에 EXP 게이지바 표시 - 2017. 4. 12.",[79,2122,2123],{},"일시 정지(Pause Plugin) - 2017. 5. 7.",[79,2125,2126],{},"심플 그래픽 메뉴(Simple Graphics Menu) - 2017. 7. 11.",[79,2128,2129],{},"주석 찾기 정규식 - 2018. 2. 1.",[79,2131,2132],{},"한글 비트맵 폰트 - 2018. 2. 19.",[79,2134,2135],{},"스페인어 이름 입력의 처리 - 2018. 2. 24.",[79,2137,2138],{},"한글 이름 입력의 처리 (조합) - 2018. 4. 2.",[79,2140,2141],{},"Picture Tool - 2018. 4. 17.",[79,2143,2144],{},"특정 페이지에서 텍스트 추출하기 - 2018. 4. 29.",[79,2146,2147],{},"옵션 창에 메시지 속도 및 글자 크기 변경 기능 추가 - 2018. 7. 15.",[79,2149,2150],{},"9마리 이상의 몬스터 설정 | More Enemies - 2018. 8. 31.",[79,2152,2153],{},"커스텀 숫자 입력 패드 - 2018. 10. 16.",[79,2155,2156],{},"JS 파일 통합 모듈 : 소스 코드를 보호하자 - 2018. 11. 2.",[79,2158,2159],{},"리소스 컨버터 (MV→XP) - 2018. 11. 26.",[79,2161,2162],{},"전투 배경 미 설정 시 VXA와 같은 블러 효과 내기 | Battle Background Radial Blur - 2018. 12. 18.",[79,2164,2165],{},"그림의 가로와 세로 길이 구하는 플러그인 | Picture Variables - 2018. 12. 18.",[79,2167,2168],{},"Ghost Effect - 2019. 1. 11.",[79,2170,2171],{},"투명색 지정 툴 - 2019. 3. 10.",[79,2173,2174],{},"애니메이션 바로 정지 - 2019. 3. 24.",[79,2176,2177],{},"게임 속도 조절 - 2019. 5. 6.",[79,2179,2180],{},"메시지 Pause 표시 이미지 위치 변경 - 2019. 5. 6.",[79,2182,2183],{},"한글 조합 입력기 - 2019. 6. 21.",[79,2185,2186],{},"동영상 볼륨 조절 - 2019. 8. 12.",[79,2188,2189],{},"전투 중에 애니메이션 반복 재생 - 2019. 9. 11.cn",[79,2191,2192],{},"RPG Maker MV 폰트 CSS 파일 생성기 - 2019. 10. 19.",[79,2194,2195],{},"확장 도구 등록 - 2019. 10. 22.",[79,2197,2198],{},"ES5 플레이어 추가 - 2019. 10. 27.",[79,2200,2201],{},"이미지를 해상도에 맞게 강제 리사이징하여 출력 - 2020. 1. 6.",[79,2203,2204],{},"텍스트 효과 플러그인 (개발중) - 2020. 1. 24.",[79,2206,2207],{},"텍스트 입력창 (다중 라인) - 2020. 2. 29.",[79,2209,2210],{},"타이틀 버티칼 이펙트 | RPG Maker MV - 2020. 2. 29.",[79,2212,2213],{},"암호화 프로젝트 복구용 유틸 (소스 코드만 제공) - 2020. 7. 25.",[79,2215,2216],{},"코르도바 광고 삽입 플러그인 - 2016. 8. 4.",[79,2218,2219,2224],{},[2220,2221,2223],"a",{"href":2222},"https:\u002F\u002Fgithub.com\u002Fbiud436\u002Fmv-android-client","애드몹 구현 샘플 코드"," - 2019. 11. 5.",[79,2226,2227,2231],{},[2220,2228,2230],{"href":2229},"https:\u002F\u002Fgithub.com\u002Fbiud436\u002FMV-Android-Updater","안드로이드 게임 실시간 업데이트 샘플 코드"," - 2019. 12. 12",[79,2233,2234],{},"한글 이름 입력 - 2020. 8. 7.",[79,2236,2237],{},"심플 그래픽 메뉴 - 2020. 8. 7.",{"title":38,"searchDepth":39,"depth":39,"links":2239},[],{},"\u002Fprojects\u002Fhobby",{"description":38},"projects\u002Fhobby","eaFYqw6fmJ23nqRFDBu-Roeg7MwlMtdCAzo89xNx4ac",[2246,2303,2381,2438,2879,2942,2999,3058,3134,3377,3436],{"id":2247,"title":2248,"body":2249,"description":38,"extension":41,"meta":2298,"navigation":12,"path":2299,"seo":2300,"stem":2301,"__hash__":2302},"projects\u002Fprojects\u002FandroidAppBuilder.md","AndroidAppBuilder",{"type":7,"value":2250,"toc":2292},[2251,2255,2266,2270,2273,2275,2278,2281,2287,2289],[64,2252,2254],{"id":2253},"사용한-기술","사용한 기술",[76,2256,2257,2260,2263],{},[79,2258,2259],{},"C# Winform",[79,2261,2262],{},"Cordova CLI",[79,2264,2265],{},"Node.js",[64,2267,2269],{"id":2268},"동작-플랫폼","동작 플랫폼",[19,2271,2272],{},"Windows 7 이상",[64,2274,17],{"id":17},[19,2276,2277],{},"HTML5 웹페이지를 안드로이드 웹앱으로 변환할 수 있는 빌드\n프로그램입니다. 실제 컴파일러처럼 앱 빌드에 필요한 파일을 하위\n프로세스로 실행하여 출력 리다이렉션을 통해 현재 빌드 로그로\n표시합니다.",[19,2279,2280],{},"또한 NSIS와 정규표현식을 통한 자동 업데이트 시스템을 구축하여\n업데이트가 있을 시 프로그램이 자동으로 업데이트되는 기능을\n갖추고 있습니다. 하위 프로세스 출력 리다이렉션 기능을 통해\n안드로이드 SDK 목록, 안드로이드 빌드, 리소스 복사 및 중복 제거\n작업 등을 자동으로 수행하며 안드로이드 SDK 레벨 조절 기능과\n화면 방향 조절 그리고 개발에 필요한 플러그인과 키스토어 파일을\n직접 생성할 수 있습니다.",[19,2282,2283],{},[2284,2285,2286],"strong",{},"이 프로그램을 설치하면 안드로이드 스튜디오 없이도 앱을 만들 수 있습니다",[64,2288,67],{"id":66},[19,2290,2291],{},"2019.11 ~ 2020.02 (3개월)",{"title":38,"searchDepth":39,"depth":39,"links":2293},[2294,2295,2296,2297],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Fandroidappbuilder",{"description":38},"projects\u002FandroidAppBuilder","GYuFmE9b026-ZE62w0leV1EOxA17_TXtG5_UGXRQvdo",{"id":2304,"title":2305,"body":2306,"description":38,"extension":41,"meta":2376,"navigation":12,"path":2377,"seo":2378,"stem":2379,"__hash__":2380},"projects\u002Fprojects\u002Fblog.md","Blog",{"type":7,"value":2307,"toc":2370},[2308,2310,2352,2354,2357,2359,2362,2364,2367],[64,2309,2254],{"id":2253},[76,2311,2312,2314,2316,2318,2320,2322,2325,2328,2330,2332,2335,2338,2341,2343,2346,2349],{},[79,2313,1095],{},[79,2315,254],{},[79,2317,1222],{},[79,2319,168],{},[79,2321,427],{},[79,2323,2324],{},"Material-UI",[79,2326,2327],{},"Nestia",[79,2329,1412],{},[79,2331,1415],{},[79,2333,2334],{},"Styled-Components",[79,2336,2337],{},"SWR",[79,2339,2340],{},"React-Hook-Form",[79,2342,174],{},[79,2344,2345],{},"AWS EC2",[79,2347,2348],{},"AWS Code Deploy",[79,2350,2351],{},"AWS S3",[64,2353,2269],{"id":2268},[19,2355,2356],{},"Linux(서버), 웹(프론트)",[64,2358,17],{"id":17},[19,2360,2361],{},"일기를 남기기 위해 만든 블로그입니다.",[64,2363,67],{"id":66},[19,2365,2366],{},"서버: 2022.03.01 ~ 계속 업데이트 중",[19,2368,2369],{},"프론트: 2022.10.10 ~ 2022.11.15 (1개월)",{"title":38,"searchDepth":39,"depth":39,"links":2371},[2372,2373,2374,2375],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Fblog",{"description":38},"projects\u002Fblog","_-P5YVEtkjq5S4xAUhLz9IWqW6lYDFBDnaBRlUiNYp0",{"id":2382,"title":2383,"body":2384,"description":2388,"extension":41,"meta":2433,"navigation":12,"path":2434,"seo":2435,"stem":2436,"__hash__":2437},"projects\u002Fprojects\u002FcustomServer.md","CustomServer",{"type":7,"value":2385,"toc":2428},[2386,2389,2391,2394,2396,2399,2402],[19,2387,2388],{},"직접 바닥부터 설계하여 만든 NestJS Like 서버 프레임워크입니다. 단순 연습용에 그치지 않고, 실제로 사용해도 될 수준이 될때까지 개발을 거듭하면서 내부 원리에 대해 많은 깨달음을 얻었던 프로젝트입니다. 바닥부터 나름의 설계와 해결책을 가지고 풀어내려고 노력했습니다.",[64,2390,2254],{"id":2253},[19,2392,2393],{},"Node.js, fastify, reflect-metadata, class-transformer, class-validator, http-status",[64,2395,67],{"id":66},[19,2397,2398],{},"2023.07.21 ~ 진행중",[64,2400,2401],{"id":2401},"기능",[76,2403,2404,2407,2410,2413,2416,2419,2422,2425],{},[79,2405,2406],{},"자체 개발한 ORM 시스템 탑재",[79,2408,2409],{},"싱글턴 패턴 기반의 DI와 IoC 지원",[79,2411,2412],{},"서버 구성에 유용한 데코레이터 제공",[79,2414,2415],{},"타입스크립트 컴파일러를 통한 파일 자동 생성",[79,2417,2418],{},"예외 처리 기능 제공",[79,2420,2421],{},"트랜잭션 기능 제공",[79,2423,2424],{},"템플릿 엔진 내장",[79,2426,2427],{},"프레임워크 차원에서 세션을 통한 인증\u002F인가 처리 지원",{"title":38,"searchDepth":39,"depth":39,"links":2429},[2430,2431,2432],{"id":2253,"depth":39,"text":2254},{"id":66,"depth":39,"text":67},{"id":2401,"depth":39,"text":2401},{},"\u002Fprojects\u002Fcustomserver",{"description":2388},"projects\u002FcustomServer","XhskNhxWGIDdUb1HS6yshJ-aoKrbHyv9GHQAT-_4_3s",{"id":1587,"title":1588,"body":2439,"description":38,"extension":41,"meta":2877,"navigation":12,"path":2241,"seo":2878,"stem":2243,"__hash__":2244},{"type":7,"value":2440,"toc":2875},[2441,2665],[10,2442,2443,2445],{},[14,2444,1595],{},[76,2446,2447,2449,2451,2453,2455,2457,2459,2461,2463,2465,2467,2469,2471,2473,2475,2477,2479,2481,2483,2485,2487,2489,2491,2493,2495,2497,2499,2501,2503,2505,2507,2509,2511,2513,2515,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543,2545,2547,2549,2551,2555,2557,2561,2565,2567,2571,2573,2575,2577,2579,2581,2583,2585,2587,2589,2591,2593,2597,2599,2601,2603,2605,2607,2609,2611,2613,2617,2619,2621,2623,2625,2627,2629,2631,2633,2635,2637,2639,2641,2643,2645,2647,2649,2651,2653,2655,2659,2663],{},[79,2448,1600],{},[79,2450,1603],{},[79,2452,1606],{},[79,2454,1609],{},[79,2456,1612],{},[79,2458,1615],{},[79,2460,1618],{},[79,2462,1621],{},[79,2464,1624],{},[79,2466,1627],{},[79,2468,1630],{},[79,2470,1633],{},[79,2472,1636],{},[79,2474,1639],{},[79,2476,1642],{},[79,2478,1645],{},[79,2480,1648],{},[79,2482,1651],{},[79,2484,1654],{},[79,2486,1657],{},[79,2488,1660],{},[79,2490,1663],{},[79,2492,1666],{},[79,2494,1669],{},[79,2496,1672],{},[79,2498,1675],{},[79,2500,1678],{},[79,2502,1681],{},[79,2504,1684],{},[79,2506,1687],{},[79,2508,1690],{},[79,2510,1693],{},[79,2512,1696],{},[79,2514,1699],{},[79,2516,1702],{},[79,2518,1705],{},[79,2520,1708],{},[79,2522,1711],{},[79,2524,1714],{},[79,2526,1717],{},[79,2528,1720],{},[79,2530,1723],{},[79,2532,1726],{},[79,2534,1729],{},[79,2536,1732],{},[79,2538,1735],{},[79,2540,1738],{},[79,2542,1741],{},[79,2544,1744],{},[79,2546,1747],{},[79,2548,1750],{},[79,2550,1753],{},[79,2552,2553,1760],{},[1757,2554,1759],{},[79,2556,1763],{},[79,2558,2559,1768],{},[1757,2560,1759],{},[79,2562,2563,1774],{},[1757,2564,1773],{},[79,2566,1777],{},[79,2568,2569,1783],{},[1757,2570,1782],{},[79,2572,1786],{},[79,2574,1789],{},[79,2576,1792],{},[79,2578,1795],{},[79,2580,1798],{},[79,2582,1801],{},[79,2584,1804],{},[79,2586,1807],{},[79,2588,1810],{},[79,2590,1813],{},[79,2592,1816],{},[79,2594,2595,1822],{},[1757,2596,1821],{},[79,2598,1825],{},[79,2600,1828],{},[79,2602,1831],{},[79,2604,1834],{},[79,2606,1837],{},[79,2608,1840],{},[79,2610,1843],{},[79,2612,1846],{},[79,2614,2615,1852],{},[1757,2616,1851],{},[79,2618,1855],{},[79,2620,1858],{},[79,2622,1861],{},[79,2624,1864],{},[79,2626,1867],{},[79,2628,1870],{},[79,2630,1873],{},[79,2632,1876],{},[79,2634,1879],{},[79,2636,1882],{},[79,2638,1885],{},[79,2640,1888],{},[79,2642,1891],{},[79,2644,1894],{},[79,2646,1897],{},[79,2648,1900],{},[79,2650,1903],{},[79,2652,1906],{},[79,2654,1909],{},[79,2656,2657,1914],{},[1757,2658,1759],{},[79,2660,2661,1919],{},[1757,2662,1759],{},[79,2664,1922],{},[10,2666,2667,2669],{},[14,2668,1927],{},[76,2670,2671,2673,2675,2677,2679,2681,2683,2685,2687,2689,2691,2693,2695,2699,2701,2705,2707,2709,2711,2713,2715,2717,2719,2721,2723,2725,2727,2729,2731,2733,2735,2737,2739,2741,2743,2745,2747,2749,2751,2753,2755,2757,2759,2761,2763,2765,2767,2769,2771,2773,2775,2779,2783,2785,2787,2789,2791,2793,2795,2797,2799,2801,2803,2805,2807,2809,2811,2813,2815,2817,2819,2821,2823,2825,2827,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849,2851,2853,2855,2857,2859,2861,2863,2867,2871,2873],{},[79,2672,1932],{},[79,2674,1935],{},[79,2676,1938],{},[79,2678,1941],{},[79,2680,1944],{},[79,2682,1947],{},[79,2684,1950],{},[79,2686,1953],{},[79,2688,1956],{},[79,2690,1959],{},[79,2692,1962],{},[79,2694,1965],{},[79,2696,2697,1971],{},[1757,2698,1970],{},[79,2700,1974],{},[79,2702,2703,1979],{},[1757,2704,1970],{},[79,2706,1982],{},[79,2708,1985],{},[79,2710,1988],{},[79,2712,1991],{},[79,2714,1994],{},[79,2716,1997],{},[79,2718,2000],{},[79,2720,2003],{},[79,2722,2006],{},[79,2724,2009],{},[79,2726,2012],{},[79,2728,2015],{},[79,2730,2018],{},[79,2732,2021],{},[79,2734,2024],{},[79,2736,2027],{},[79,2738,2030],{},[79,2740,2033],{},[79,2742,2036],{},[79,2744,2039],{},[79,2746,2042],{},[79,2748,2045],{},[79,2750,2048],{},[79,2752,2051],{},[79,2754,2054],{},[79,2756,2057],{},[79,2758,2060],{},[79,2760,2063],{},[79,2762,2066],{},[79,2764,2069],{},[79,2766,2072],{},[79,2768,2075],{},[79,2770,2078],{},[79,2772,2081],{},[79,2774,2084],{},[79,2776,2777,2090],{},[1757,2778,2089],{},[79,2780,2781,2096],{},[1757,2782,2095],{},[79,2784,2099],{},[79,2786,2102],{},[79,2788,2105],{},[79,2790,2108],{},[79,2792,2111],{},[79,2794,2114],{},[79,2796,2117],{},[79,2798,2120],{},[79,2800,2123],{},[79,2802,2126],{},[79,2804,2129],{},[79,2806,2132],{},[79,2808,2135],{},[79,2810,2138],{},[79,2812,2141],{},[79,2814,2144],{},[79,2816,2147],{},[79,2818,2150],{},[79,2820,2153],{},[79,2822,2156],{},[79,2824,2159],{},[79,2826,2162],{},[79,2828,2165],{},[79,2830,2168],{},[79,2832,2171],{},[79,2834,2174],{},[79,2836,2177],{},[79,2838,2180],{},[79,2840,2183],{},[79,2842,2186],{},[79,2844,2189],{},[79,2846,2192],{},[79,2848,2195],{},[79,2850,2198],{},[79,2852,2201],{},[79,2854,2204],{},[79,2856,2207],{},[79,2858,2210],{},[79,2860,2213],{},[79,2862,2216],{},[79,2864,2865,2224],{},[2220,2866,2223],{"href":2222},[79,2868,2869,2231],{},[2220,2870,2230],{"href":2229},[79,2872,2234],{},[79,2874,2237],{},{"title":38,"searchDepth":39,"depth":39,"links":2876},[],{},{"description":38},{"id":2880,"title":2881,"body":2882,"description":38,"extension":41,"meta":2937,"navigation":12,"path":2938,"seo":2939,"stem":2940,"__hash__":2941},"projects\u002Fprojects\u002Finitial2D.md","Initial2D",{"type":7,"value":2883,"toc":2932},[2884,2886,2920,2922,2925,2927],[64,2885,2254],{"id":2253},[76,2887,2888,2890,2893,2896,2899,2902,2905,2908,2911,2914,2917],{},[79,2889,946],{},[79,2891,2892],{},"Lua",[79,2894,2895],{},"Zlib",[79,2897,2898],{},"libpng",[79,2900,2901],{},"SDL2",[79,2903,2904],{},"SDL Audio",[79,2906,2907],{},"OpenAL",[79,2909,2910],{},"TinyXML",[79,2912,2913],{},"GDI",[79,2915,2916],{},"JSON",[79,2918,2919],{},"SQLite3",[64,2921,2269],{"id":2268},[19,2923,2924],{},"Windows",[64,2926,17],{"id":17},[19,2928,2929,2931],{},[819,2930,958],{},"를 이용한 C++ 2D 게임 엔진입니다. XML 파일과 JSON 파일을 로드하여 데이터를 읽거나 저장할 수 있습니다. 또한 Finite State Machine(FSM) 패턴과 싱글턴 패턴을 활용하여 스테이지 전이 기능을 갖추고 있습니다. 그래픽 엔진은 Windows GDI를 사용하였고 Sprite는 Vector2D 통해 회전, 이동, 크기 조절이 가능합니다. 이미지는 LibPNG와 Zlib를 통해 직접 PNG 파일을 비트맵 파일을 추출하는 방식을 사용합니다. 또한 폰트 파일에서 윤곽선 정보를 직접 추출하여 부드러운 폰트 묘화 기능도 지원하고 있습니다. 비트맵 폰트를 통해 미리 그려진 비트맵 폰트를 그릴 수도 있습니다. Input과 Audio를 통해 키입력을 받거나 마우스 입력을 할 수 있고 사운드도 재생할 수 있습니다. 쓰레드와 프로세스 실행 기능을 갖추고 있어 내부적으로 프로그램을 실행할 수도 있습니다. 사용자는 루아 스크립트 엔진을 통해 스크립트를 작성하여 소스 코드 컴파일 없이 로직을 구성할 수 있습니다.",{"title":38,"searchDepth":39,"depth":39,"links":2933},[2934,2935,2936],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{},"\u002Fprojects\u002Finitial2d",{"description":38},"projects\u002Finitial2D","Up8yDpYALZFurZAslcn5j-g5XfZZy2VVMtF1FU6X5JE",{"id":2943,"title":2944,"body":2945,"description":38,"extension":41,"meta":2994,"navigation":12,"path":2995,"seo":2996,"stem":2997,"__hash__":2998},"projects\u002Fprojects\u002FinitialEditor.md","InitialEditor",{"type":7,"value":2946,"toc":2988},[2947,2949,2973,2975,2978,2980,2983,2985],[64,2948,2254],{"id":2253},[76,2950,2951,2954,2957,2959,2962,2965,2968,2970],{},[79,2952,2953],{},"Electron",[79,2955,2956],{},"HTML5\u002FCSS3",[79,2958,245],{},[79,2960,2961],{},"webpack",[79,2963,2964],{},"canvas",[79,2966,2967],{},"PIXI.js",[79,2969,2265],{},[79,2971,2972],{},"NextJS",[64,2974,2269],{"id":2268},[19,2976,2977],{},"모든 플랫폼에서 동작(Windows, MacOS, Linux)",[64,2979,17],{"id":17},[19,2981,2982],{},"타입스크립트와 웹팩을 활용하여 만든 웹 기반 타일맵 에디터입니다.\n타일맵 에디터는 MVC 패턴으로구성되었습니다.\n모든 기능은 하나의 컴포넌트 단위로 분리되었고 필요할 때마다 불러서 쓸 수 있습니다.\n각 컴포넌트는 개량된 옵저버 패턴이 구현되었으므로 필요할\n때마다 분리된 상태에서 이벤트를 통해 컴포넌트를 호출할 수 있습니다.\n모든 클래스는 타입스크립트를 통해 모듈화 되어있으며 웹팩으로 번들링됩니다.\n메뉴는 C# Winform과 비슷하게 사전에 JSON 파일에 등록된 이벤트를 실행할 수 있게 되어있습니다.\n타일 채우기는 Flood Fill 알고리즘을 활용하여 빈 셀을 매우 빠르게 찾아 채울 수 있습니다.",[64,2984,67],{"id":66},[19,2986,2987],{},"2020.10.01 ~ 2020.12 (2개월)",{"title":38,"searchDepth":39,"depth":39,"links":2989},[2990,2991,2992,2993],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Finitialeditor",{"description":38},"projects\u002FinitialEditor","m1tcd_hVU_KHWqn1P9C7h64JMATuAJDjlp9wri6X6QA",{"id":3000,"title":3001,"body":3002,"description":38,"extension":41,"meta":3053,"navigation":12,"path":3054,"seo":3055,"stem":3056,"__hash__":3057},"projects\u002Fprojects\u002FrgssCompiler.md","RgssCompiler",{"type":7,"value":3003,"toc":3047},[3004,3006,3017,3019,3022,3024,3039,3042,3044],[64,3005,2254],{"id":2253},[76,3007,3008,3010,3013,3015],{},[79,3009,2265],{},[79,3011,3012],{},"VSCode Extension API",[79,3014,245],{},[79,3016,1759],{},[64,3018,2269],{"id":2268},[19,3020,3021],{},"Visual Studio Code (Windows 및 MacOS only)에서만 동작",[64,3023,17],{"id":17},[19,3025,3026,3027,3030,3031,3034,3035,3038],{},"RPG Maker의 코드를 자동으로 컴파일하는 Visual Studio Code Extension 입니다.\n",[819,3028,3029],{},"Scripts.rxdata","와 ",[819,3032,3033],{},"Scripts.rvdata2"," 파일을 역직렬화(deserialize)하고 ",[819,3036,3037],{},"zlib","로 압축 해제하여 스크립트를 불러올 수 있고,\n또한 단축키 CTRL + s(CMD + s)를 통해 자동으로 루비 직렬화 파일을 만들 수 있습니다.\nF5 버튼(fn + F5)를 통해 스크립트 파일들을 압축하여 게임 플레이를 바로 할 수 있습니다.",[19,3040,3041],{},"이것은 맥에서 스크립트를 편집하고 게임을 플레이 하기 위해 개발되었습니다.",[64,3043,67],{"id":66},[19,3045,3046],{},"2022.03.06 ~ 2022.03.09 (3일)",{"title":38,"searchDepth":39,"depth":39,"links":3048},[3049,3050,3051,3052],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Frgsscompiler",{"description":38},"projects\u002FrgssCompiler","5qcgcLbGvxS3pTYeUhVP4Vnq1_GDHNUaUpjRPXZ05V4",{"id":3059,"title":3060,"body":3061,"description":38,"extension":41,"meta":3129,"navigation":12,"path":3130,"seo":3131,"stem":3132,"__hash__":3133},"projects\u002Fprojects\u002FshoppingMall.md","ShoppingMall",{"type":7,"value":3062,"toc":3123},[3063,3065,3108,3110,3113,3115,3118,3120],[64,3064,2254],{"id":2253},[76,3066,3067,3069,3072,3075,3078,3081,3083,3085,3088,3091,3094,3097,3100,3103,3105],{},[79,3068,2956],{},[79,3070,3071],{},"SCSS",[79,3073,3074],{},"jQuery",[79,3076,3077],{},"JavaScript",[79,3079,3080],{},"JSP",[79,3082,1222],{},[79,3084,2265],{},[79,3086,3087],{},"Selenium(Node.js)",[79,3089,3090],{},"JWT",[79,3092,3093],{},"Java Mail",[79,3095,3096],{},"소셜 로그인(네이버\u002F카카오\u002F페이스북)",[79,3098,3099],{},"소셜 댓글(페이스북)",[79,3101,3102],{},"구매 모듈(카카오페이)Oracle Cloud",[79,3104,2345],{},[79,3106,3107],{},"Let's Encrypt(https)",[64,3109,2269],{"id":2268},[19,3111,3112],{},"웹",[64,3114,17],{"id":17},[19,3116,3117],{},"JSP로 만든 쇼핑몰 팀 프로젝트로 MVC2가 적용된 멀티 페이지 구조의 사이트입니다. 프로젝트 초기부터 깃허브를 통한 형상 관리를 하여 팀원을 이끌었으며 리눅스 우분투 서버에 직접 DB와 톰캣 서버를 구동하여 같은 환경에서 웹페이지를 개발할 수 있도록 하였습니다. 상단 메뉴를 모던 자바스크립트를 이용하여 직접 구성하였고 카드 슬롯을 페이징 처리하여 로딩 속도를 대폭 향상시켰습니다. 또한 결제 기능, 장바구니 기능, 게시판, 소셜 댓글, 이메일로 비밀번호 찾기 등의 기능을 구현하였습니다. 결제나 소셜 로그인에 필수 기능들을 제외한 나머지 기능들은 모던 자바스크립트의 모듈화 기능(ESM)을 통해 구현되어있습니다.",[64,3119,67],{"id":66},[19,3121,3122],{},"2020.10.01 ~ 2021.01.05 (3개월)",{"title":38,"searchDepth":39,"depth":39,"links":3124},[3125,3126,3127,3128],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Fshoppingmall",{"description":38},"projects\u002FshoppingMall","kl5uGXhMZgzCbgshCdS4bvAByg8QFp2wxKQ12dMCYTM",{"id":3135,"title":3136,"body":3137,"description":3371,"extension":41,"meta":3372,"navigation":12,"path":3373,"seo":3374,"stem":3375,"__hash__":3376},"projects\u002Fprojects\u002Fstingerloom-orm.md","Stingerloom Orm",{"type":7,"value":3138,"toc":3366},[3139,3146,3150,3153,3156,3160,3163,3319,3322,3326,3362],[19,3140,3141,3142,3145],{},"PostgreSQL, MySQL, SQLite 를 다룰 수 있는 TypeScript ORM 입니다. 운영 환경에서 그대로 쓸 수 있는 수준을 목표로 잡고 만들었고, npm 에 ",[819,3143,3144],{},"@stingerloom\u002Form"," 으로 배포 중입니다. 현재 v0.20.0 까지 릴리스했습니다.",[64,3147,3149],{"id":3148},"멀티-테넌시","멀티 테넌시",[19,3151,3152],{},"가장 직접 부딪혀 보고 싶었던 주제였습니다. SaaS 환경에서 한 인스턴스가 여러 테넌트의 데이터를 안전하게 다루려면 메타데이터 분리와 런타임 컨텍스트 격리를 함께 해결해야 합니다.",[19,3154,3155],{},"Docker 의 OverlayFS 가 파일 시스템을 레이어로 쌓는 구조에서 아이디어를 가져와, 베이스 메타데이터 위에 테넌트별 메타데이터를 얹는 계층형 모델로 만들었습니다. 컨텍스트는 AsyncLocalStorage 로 격리해서 요청과 요청 사이에 데이터가 새지 않도록 했습니다.",[64,3157,3159],{"id":3158},"타입-안전한-query-dsl","타입 안전한 Query DSL",[19,3161,3162],{},"쿼리 인터페이스는 Proxy 로 구현했습니다. 빌드 단계의 코드 생성 없이도 모든 컬럼에 IDE 자동완성이 동작하고, 집계 \u002F 윈도우 함수 \u002F CASE-WHEN \u002F 서브쿼리 \u002F JSON path 까지 모두 타입 안전한 표현식으로 자유롭게 합성됩니다.",[3164,3165,3169],"pre",{"className":3166,"code":3167,"language":3168,"meta":38,"style":38},"language-ts shiki shiki-themes github-dark-dimmed","const u = qAlias(User, 'u')\nem.repository(User)\n  .createQueryBuilder()\n  .select(u.id, u.email, count(u.id).as('count'))\n  .where(u.email.like('%@example.com'))\n  .groupBy(u.tenantId)\n  .having(count(u.id).gt(10))\n  .getMany()\n","ts",[819,3170,3171,3201,3212,3224,3253,3274,3285,3309],{"__ignoreMap":38},[1757,3172,3175,3179,3183,3186,3190,3194,3198],{"class":3173,"line":3174},"line",1,[1757,3176,3178],{"class":3177},"scLw-","const",[1757,3180,3182],{"class":3181},"sDGpf"," u",[1757,3184,3185],{"class":3177}," =",[1757,3187,3189],{"class":3188},"sLyBy"," qAlias",[1757,3191,3193],{"class":3192},"s1ain","(User, ",[1757,3195,3197],{"class":3196},"sP_-H","'u'",[1757,3199,3200],{"class":3192},")\n",[1757,3202,3203,3206,3209],{"class":3173,"line":39},[1757,3204,3205],{"class":3192},"em.",[1757,3207,3208],{"class":3188},"repository",[1757,3210,3211],{"class":3192},"(User)\n",[1757,3213,3215,3218,3221],{"class":3173,"line":3214},3,[1757,3216,3217],{"class":3192},"  .",[1757,3219,3220],{"class":3188},"createQueryBuilder",[1757,3222,3223],{"class":3192},"()\n",[1757,3225,3227,3229,3232,3235,3238,3241,3244,3247,3250],{"class":3173,"line":3226},4,[1757,3228,3217],{"class":3192},[1757,3230,3231],{"class":3188},"select",[1757,3233,3234],{"class":3192},"(u.id, u.email, ",[1757,3236,3237],{"class":3188},"count",[1757,3239,3240],{"class":3192},"(u.id).",[1757,3242,3243],{"class":3188},"as",[1757,3245,3246],{"class":3192},"(",[1757,3248,3249],{"class":3196},"'count'",[1757,3251,3252],{"class":3192},"))\n",[1757,3254,3256,3258,3261,3264,3267,3269,3272],{"class":3173,"line":3255},5,[1757,3257,3217],{"class":3192},[1757,3259,3260],{"class":3188},"where",[1757,3262,3263],{"class":3192},"(u.email.",[1757,3265,3266],{"class":3188},"like",[1757,3268,3246],{"class":3192},[1757,3270,3271],{"class":3196},"'%@example.com'",[1757,3273,3252],{"class":3192},[1757,3275,3277,3279,3282],{"class":3173,"line":3276},6,[1757,3278,3217],{"class":3192},[1757,3280,3281],{"class":3188},"groupBy",[1757,3283,3284],{"class":3192},"(u.tenantId)\n",[1757,3286,3288,3290,3293,3295,3297,3299,3302,3304,3307],{"class":3173,"line":3287},7,[1757,3289,3217],{"class":3192},[1757,3291,3292],{"class":3188},"having",[1757,3294,3246],{"class":3192},[1757,3296,3237],{"class":3188},[1757,3298,3240],{"class":3192},[1757,3300,3301],{"class":3188},"gt",[1757,3303,3246],{"class":3192},[1757,3305,3306],{"class":3181},"10",[1757,3308,3252],{"class":3192},[1757,3310,3312,3314,3317],{"class":3173,"line":3311},8,[1757,3313,3217],{"class":3192},[1757,3315,3316],{"class":3188},"getMany",[1757,3318,3223],{"class":3192},[19,3320,3321],{},"별도 codegen 단계를 두지 않고도 이 정도 추론을 잡아낼 수 있는지 시연해 보고 싶었습니다.",[64,3323,3325],{"id":3324},"그-외-갖춘-것들","그 외 갖춘 것들",[76,3327,3328,3338,3352],{},[79,3329,3330,3333,3334,3337],{},[2284,3331,3332],{},"Unit of Work"," — Identity Map, dirty checking, cascade, 배치 flush, lazy proxy, 비관적 락. ",[819,3335,3336],{},"em.extend(bufferPlugin())"," 한 줄로 활성화됩니다.",[79,3339,3340,3343,3344,3347,3348,3351],{},[2284,3341,3342],{},"스키마 Diff 마이그레이션"," — 라이브 DB 상태와 엔티티 정의를 비교해 마이그레이션 SQL 을 자동 생성합니다. ",[819,3345,3346],{},"safe",", ",[819,3349,3350],{},"dry-run"," 모드를 별도로 제공합니다.",[79,3353,3354,3357,3358,3361],{},[2284,3355,3356],{},"드라이버 추상화"," — 세 가지 DB 가 동일한 ",[819,3359,3360],{},"EntityManager"," 인터페이스를 공유합니다. 드라이버를 바꿔도 쿼리 코드를 다시 쓰지 않습니다. MariaDB 특화 최적화도 별도로 들어가 있습니다.",[3363,3364,3365],"style",{},"html pre.shiki code .scLw-, html code.shiki .scLw-{--shiki-default:#F47067}html pre.shiki code .sDGpf, html code.shiki .sDGpf{--shiki-default:#6CB6FF}html pre.shiki code .sLyBy, html code.shiki .sLyBy{--shiki-default:#DCBDFB}html pre.shiki code .s1ain, html code.shiki .s1ain{--shiki-default:#ADBAC7}html pre.shiki code .sP_-H, html code.shiki .sP_-H{--shiki-default:#96D0FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":38,"searchDepth":39,"depth":39,"links":3367},[3368,3369,3370],{"id":3148,"depth":39,"text":3149},{"id":3158,"depth":39,"text":3159},{"id":3324,"depth":39,"text":3325},"PostgreSQL, MySQL, SQLite 를 다룰 수 있는 TypeScript ORM 입니다. 운영 환경에서 그대로 쓸 수 있는 수준을 목표로 잡고 만들었고, npm 에 @stingerloom\u002Form 으로 배포 중입니다. 현재 v0.20.0 까지 릴리스했습니다.",{},"\u002Fprojects\u002Fstingerloom-orm",{"description":3371},"projects\u002Fstingerloom-orm","HMP1IWAqdnPIBEkfcueeRutr3Ma71ErueLpC0BJIa1E",{"id":3378,"title":3379,"body":3380,"description":38,"extension":41,"meta":3431,"navigation":12,"path":3432,"seo":3433,"stem":3434,"__hash__":3435},"projects\u002Fprojects\u002Fweather.md","Weather",{"type":7,"value":3381,"toc":3425},[3382,3384,3408,3410,3412,3414,3417,3420,3422],[64,3383,2254],{"id":2253},[76,3385,3386,3389,3392,3394,3397,3400,3402,3405],{},[79,3387,3388],{},"HTML5",[79,3390,3391],{},"CSS3",[79,3393,3074],{},[79,3395,3396],{},"모던 자바스크립트",[79,3398,3399],{},"Webpack",[79,3401,2964],{},[79,3403,3404],{},"Open Weather",[79,3406,3407],{},"Font Awesome",[64,3409,2269],{"id":2268},[19,3411,3112],{},[64,3413,17],{"id":17},[19,3415,3416],{},"Open Weather API를 사용하여 인터렉티브 날씨 웹페이지입니다.",[19,3418,3419],{},"컴포넌트 패턴과 이벤트 큐 패턴을 활용하여 각 오브젝트를 완벽하게 디커플링하였고 레고처럼 조립되듯 실행됩니다.\nES6 클래스와 import\u002Fexport 문을 활용하여 모듈화 하였고 웹팩으로 번들링하여 속도를 향상시켰습니다.\n기온 차트는 선형 보간과 동차 좌표를 활용하여 HTML5 Canvas API로 라이브러리 없이 직접 차트를 그렸습니다.\n또한 패러랠스 스크롤링 로직을 이용하여 라이브러리 없이 차트의 애니메이션 스크롤링을 직접 구현하였습니다.",[64,3421,67],{"id":66},[19,3423,3424],{},"2020년 09월 25일 (1일)",{"title":38,"searchDepth":39,"depth":39,"links":3426},[3427,3428,3429,3430],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Fweather",{"description":38},"projects\u002Fweather","IUCFDiDYwtYQ_GtaaCkd04Qh7fZpQGJbiC5FogUwCnk",{"id":3437,"title":3438,"body":3439,"description":38,"extension":41,"meta":3478,"navigation":12,"path":3479,"seo":3480,"stem":3481,"__hash__":3482},"projects\u002Fprojects\u002FweatherReact.md","WeatherReact",{"type":7,"value":3440,"toc":3472},[3441,3443,3455,3457,3459,3461,3467,3469],[64,3442,2254],{"id":2253},[76,3444,3445,3447,3449,3451,3453],{},[79,3446,329],{},[79,3448,1412],{},[79,3450,174],{},[79,3452,2345],{},[79,3454,2348],{},[64,3456,2269],{"id":2268},[19,3458,3112],{},[64,3460,17],{"id":17},[19,3462,3463,3464,3466],{},"날씨 웹페이지의 리액트 버전으로 ",[819,3465,2348],{},"를 이용하여 자동 배포를 구축하였습니다.\n기존 바닐라 버전은 컴포넌트 패턴과 이벤트 큐 패턴을 활용한 각 오브젝트가 완벽하게 디커플링 되어있었습니다.\n하지만 DOM 조작 부분은 디커플링되어있지 못했고, 리액트로 변환 작업을 하면서 Mobx 클라이언트 스토어를 통해 동기화하는 방식으로 변환을 하였습니다.\n기온 그래프 차트는 선형 보간과 동차 좌표를 활용하여 HTML5 Canvas API로 라이브러리 없이 직접 차트를 그렸고 남극과 적도의 극단적인 환경의 온도도 표현 가능합니다.\n패러랠스 스크롤링 로직을 이용하여 라이브러리 없이 차트의 애니메이션 스크롤링을 직접 구현하였습니다.",[64,3468,67],{"id":66},[19,3470,3471],{},"2022년 05월 21일 ~ 2022년 05월 22일 (1일)",{"title":38,"searchDepth":39,"depth":39,"links":3473},[3474,3475,3476,3477],{"id":2253,"depth":39,"text":2254},{"id":2268,"depth":39,"text":2269},{"id":17,"depth":39,"text":17},{"id":66,"depth":39,"text":67},{},"\u002Fprojects\u002Fweatherreact",{"description":38},"projects\u002FweatherReact","KWkIqJZSDLHp9zH6O1IWbckSkla8fCINLvU0J3MEmI4",1777626137014]