[{"content":"","date":null,"permalink":"/","section":"Inlee's Blog","summary":"","title":"Inlee's Blog"},{"content":"","date":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts"},{"content":"","date":null,"permalink":"/tags/realgroove/","section":"태그","summary":"","title":"Realgroove"},{"content":"","date":null,"permalink":"/tags/renewal/","section":"태그","summary":"","title":"Renewal"},{"content":"작년부터 개발·운영 중인 록 음악 커뮤니티 리얼그루브를 개편하고, 9월 1일에 적용했다. 1년여간 쌓인 데이터와 운영 추이를 바탕으로 필요한 기능을 추가하거나 보완하고, 불필요한 기능은 정리했다.\n개요 #리얼그루브를 1년여간 운영하며 약 3,500건의 글을 작성하고 공유했다. 감사하게도 사이트에 가입해 주신 분들도 있었다. 글은 직접 작성하면서, AI를 활용해 카드뉴스와 주간소식 제작 과정을 자동화했다.\n하지만 사이트는 회원들의 참여보다 내가 콘텐츠를 발행하는 일이 중심이 되었고, 회원들의 참여도 늘지 않았다.\n당초 생각했던 운영 기간인 1년이 지나 현업에 복귀할 시기도 다가왔다. 복귀 후에는 기존 구조를 유지하면서 장애가 발생할 때마다 즉시 대응하기 어려울 것으로 판단했다.\n회원들의 참여가 활발했다면 기존 구조를 유지했겠지만, 콘텐츠 발행이 중심인 상황에서는 이를 그대로 유지할 필요가 크지 않았다. 그래서 운영 부담을 줄이고 콘텐츠 발행에 집중할 수 있도록, 사이트 구조를 간소화하고 정적 사이트로 전환하기로 했다.\n전환 과정에서는 코드 구현과 데이터 마이그레이션에 AI를 적극적으로 활용해 작업 시간을 줄일 수 있었다.\n개편 기간 및 범위 #회원 안내는 7월 31일에 시작했고, 사이트 구현과 전환 준비는 8월 1일부터 31일까지 진행했다. 사이트 구현 자체는 2주가 채 걸리지 않았으며, 9월 1일 공개 이후에는 운영 상태를 확인하고 외부 서비스를 정리했다. 소스 코드와 데이터 관리, 회원 기능, AI 자동화 등 리얼그루브의 개발·운영 전반을 개편 대상으로 삼았다. 주요 변경 사항은 아래와 같다.\n항목 변경 사항 세부 내용 웹 애플리케이션(Laravel + Vue, Docker 환경) 정적 사이트로 전환 기존 애플리케이션을 정적 사이트로 재구현하고 Cloudflare Pages에서 운영 데이터베이스(PostgreSQL) 사용 종료 저장된 게시글을 마크다운(.md) 파일로 변환 회원 회원 기능 제거 및 전체 회원 탈퇴 처리 탈퇴 처리 한 달 전 기존 회원들에게 이메일로 사전 안내 소셜 로그인 기능 제거 유일하게 지원하던 구글 로그인과 관련 인증 API 제거 댓글 외부 댓글 서비스로 대체 기존 댓글 기능을 GitHub Discussions 기반의 댓글 서비스로 대체 검색 정적 사이트용 검색 도입 기존 검색 기능을 정적 사이트용 오픈 소스 검색 도구인 Pagefind로 대체 이메일 발송 서비스 사용 종료 Amazon SES를 통한 이메일 발송 중단 미디어 제공 서비스(Cloudflare Images Stream Bundle Basic) 사용 종료 미디어 파일을 정적 사이트에 포함해 Cloudflare Pages에서 제공 Google Workspace 해지 기존 이메일 주소는 Cloudflare의 이메일 라우팅 기능으로 유지 카드뉴스·주간소식 제작 변경된 데이터 구조에 맞춰 수정 AI가 변환된 마크다운 파일을 활용하도록 제작 과정 수정 Hugo를 선택한 이유 #사이트 구조를 단순화하고 콘텐츠 발행 중심으로 운영하기 위해 정적 사이트 생성 도구인 Hugo를 선택했다. 선택한 이유는 다음과 같다.\n개발자 블로그를 비롯한 여러 사이트에서 활용하고 있어 참고할 수 있는 사례가 많았다. 마크다운 파일로 콘텐츠를 관리할 수 있어, 데이터베이스의 게시글을 .md 파일로 옮기려는 방향에 적합했다. React나 Vue 같은 프런트엔드 프레임워크 없이 HTML 중심으로 사이트를 구성할 수 있어 구조를 단순하게 유지하기 좋았다. Cloudflare Pages에서 빌드와 배포 과정을 간단하게 구성할 수 있었다. 개편 진행 #7월에 개편 계획을 세우고, 9월 1일 공개를 목표로 8월 한 달간 작업했다. 먼저 기존 회원들에게 회원제 종료와 탈퇴 처리 일정을 안내한 뒤, 사이트 구현과 약관 변경을 순서대로 진행했다.\n개편한 사이트를 공개한 뒤에는 안정적으로 운영되는지 확인하고, 더 이상 사용하지 않는 외부 서비스를 정리했다. 카드뉴스와 주간소식 제작 자동화도 변경된 사이트 구조에 맞춰 수정했다.\n회원 탈퇴 안내 #회원 기능을 제거하기로 결정하면서, 기존 회원들이 종료 일정과 자료 요청 방법을 미리 확인할 수 있도록 안내했다. 7월 31일에 회원제 종료 및 신규 회원가입 중단 공지를 게시하고, 회원들에게 이메일로도 같은 내용을 알렸다.\n주요 내용은 아래와 같다.\n사이트 구조를 단순화하기 위해 회원제를 종료하며, 신규 회원가입은 7월 31일부터 중단한다. 기존 회원은 8월 31일까지 로그인과 글쓰기를 이용할 수 있으며, 9월 1일에 계정과 개인정보를 삭제할 예정이다. 본인이 작성한 글과 댓글을 전달받고 싶은 회원은 8월 30일까지 안내 이메일에 기재된 주소로 요청할 수 있다. 구현 #Laravel + Vue로 만든 사이트를 Hugo로 옮기는 작업이라 구현이 까다로울 것으로 예상했지만, 생각보다 수월했다. 기존 디자인을 유지한 덕분에 렌더링된 HTML을 재사용할 수 있었고, 구현 과정에서는 바이브 코딩을 적극적으로 활용했다.\n기존 화면을 옮기는 과정에서 검색 기능의 이용 대상을 넓히고, 태그를 탐색할 수 있는 기능도 추가했다.\n검색: 기존에는 로그인한 회원만 검색할 수 있었지만, 개편 후에는 모든 방문자가 이용할 수 있도록 했다. 검색 기능은 Pagefind로 구현했다. 태그: 게시글에 사용한 태그를 모아 볼 수 있는 목록 페이지를 만들고, 사이트 오른쪽에 ‘랜덤 태그’와 ‘최근 본 태그’ 영역을 추가했다. 회원 기능을 제거하면서 기존 댓글 시스템도 대체해야 했다. 여러 외부 댓글 서비스를 비교한 끝에, giscus를 도입해 댓글을 GitHub Discussions에 저장하고 관리하도록 했다. 서비스를 선택할 때는 광고 유무와 비용, 별도로 관리해야 할 요소가 있는지를 고려했다.\nDisqus: 처음에는 도입을 고려했지만, 광고로 인해 이용 경험이 저하될 수 있다는 점이 리얼그루브의 운영 방향과 맞지 않는다고 판단했다. Cusdis: 클라우드 서비스가 불안정했고, 직접 설치해 운영하려면 별도의 관리가 필요해 부담이 있었다. LiveRe: 국내 서비스라는 점에서 검토했지만, 당시 무료로 제공되는 요금제가 없어 선택하지 않았다. 이런 조건을 종합했을 때 giscus가 가장 적합하다고 판단했다. GitHub이 일반 사용자에게는 익숙하지 않을 수 있지만, 댓글 화면이 깔끔하고 무료로 안정적으로 운영할 수 있다는 점이 선택 이유였다.\n자체 회원 기능 없이 이용할 수 있는 익명 댓글 시스템을 직접 구현하는 방안도 고려했다. 다만 스팸 관리에 드는 부담이 커질 것으로 판단해 도입하지 않았다.\n사이트 구현에 걸린 시간은 2주가 채 되지 않았다.\n게시글 마이그레이션 #데이터베이스에 저장된 약 3,500건의 게시글은 마크다운(.md) 파일로 변환했다. AI를 활용해 변환 작업을 수행하는 스킬을 만들었고, 이를 이용해 큰 어려움 없이 마이그레이션을 진행했다.\n먼저 제목, 본문, 생성일, 참조 링크, 태그, 분류 등을 담은 마크다운 템플릿을 준비하고, 이 형식에 맞춰 게시글을 변환하도록 스킬을 구성했다. 이후 게시글을 1,000개 단위로 JSON 파일로 내보낸 뒤, 스킬을 실행해 변환했다. 변환 규칙은 다음과 같다.\n파일명은 {게시글ID}-{UUID}.md 형식으로 지정하고, YYYY/MM/DD 형식의 폴더에 저장했다. YouTube와 Instagram 임베드는 Hugo에서 제공하는 쇼트코드(shortcode)로 변환했다. 게시글의 댓글 설정값(true/false)에 따라 giscus 댓글 창을 활성화할 수 있도록 했다. 파일 저장 구조는 바뀌었지만, 기존 게시글 주소는 그대로 유지해 이전에 공유한 링크로도 접근할 수 있도록 했다. 본문에 사용한 이미지는 대부분 커버 이미지였는데, 저작권 문제가 있을 수 있다고 판단해 이번 마이그레이션에서는 제외했다. 기존 회원이 작성한 글과 댓글은 없어 별도로 옮길 데이터는 없었다.\n이번 개편에서는 코드 구현보다 게시글 마이그레이션에서 AI의 도움을 더 크게 체감했다. 예전 같았으면 변환 코드를 작성하는 데만도 상당한 시간이 들었을 텐데, AI가 스킬을 만드는 과정에서 변환 스크립트까지 작성해 활용했다. 스크립트를 실행해 전체 게시글을 변환하는 데는 5분이 채 걸리지 않았고, 스킬 작성과 결과 검수도 1시간 안에 마쳤다.\n약관 변경 #회원제 폐지와 외부 댓글 서비스 도입 등 개편 내용을 반영해 이용약관과 개인정보처리방침을 수정했다. 개편한 사이트를 공개하기 일주일 전에 변경된 문서를 게시하고, 공지를 통해 주요 변경 사항을 안내했다.\n주요 변경 사항은 다음과 같다.\n회원제 폐지와 외부 댓글 서비스 도입에 따른 관련 내용 수정 웹사이트 이용 통계 관련 내용 수정 웹사이트 운영에 사용하는 외부 서비스 관련 내용 수정 사이트 공개 #Hugo로 구현한 리얼그루브는 예정대로 9월 1일에 공개했다. Cloudflare Pages에 사이트를 배포한 뒤, 메인 도메인을 연결해 개편을 마무리했다.\n기존에는 컨테이너를 빌드하고 배포하는 데 오랜 시간이 걸렸다. 개편 후에는 main 브랜치에 변경 사항을 푸시하면 Cloudflare Pages에서 자동으로 빌드와 배포가 진행되도록 구성해, 배포 관리도 한결 편해졌다.\n다만 Pagefind 검색 인덱스 등을 포함한 빌드 결과물의 파일 수가 20,000개를 넘어, 배포 당시 무료 요금제의 파일 수 제한을 초과했다. 이 때문에 25달러인 Pro 요금제를 사용했다.\n공개 후 운영 #공개 후 약 10일간 운영 상태를 확인했으며, 사이트는 별다른 문제 없이 동작했다.\n가장 눈에 띈 변화는 응답 시간이었다. 리얼그루브 상태 페이지에 표시되는 응답 시간(Response Time)을 기준으로, 기존에는 평균 1,000ms 이상 걸렸지만 개편 후에는 약 100~200ms로 줄었다.\n기존에 사용하던 Fly.io 인스턴스의 성능과 데이터베이스 입출력이 응답 시간에 영향을 주었던 것으로 보인다. 이전에도 웹과 데이터베이스 성능을 높인 뒤 속도가 개선된 경험이 있었다. 이번에는 미리 생성한 정적 페이지를 제공하면서 요청마다 데이터베이스에 접근할 필요가 없어졌고, 이 점이 응답 시간 단축에 기여한 것으로 보인다.\n사이트가 안정적으로 운영되는 것을 확인한 뒤에는 더 이상 사용하지 않는 외부 서비스를 정리하고, 필요한 서비스는 대체하는 작업을 진행했다.\n외부 서비스 해지 및 대체 #개편 후 필요 없어진 서비스는 순차적으로 사용을 종료했다. 이미지 제공과 이메일 수신은 기존 서비스를 해지하고 Cloudflare로 옮겼다.\n항목 기존 서비스 사용 용도 조치 및 대체 방식 이메일 발송 Amazon SES 회원가입 안내 등 이메일 발송 회원 기능 제거에 따라 사용 종료 서버 Fly.io 컨테이너 기반 웹 애플리케이션 운영 Cloudflare Pages로 사이트를 이전한 뒤 사용 종료 이미지 제공 Cloudflare Images Stream Bundle Basic 썸네일 등 이미지 저장 및 제공 기존 서비스를 해지하고 이미지를 Cloudflare Pages에서 제공 업무용 이메일 Google Workspace 이메일 수신 및 업무용으로 사용 기존 서비스를 해지하고, 이메일 수신은 Cloudflare의 이메일 라우팅 기능으로 대체 카드뉴스·주간소식 제작 수정 #사이트 구조가 바뀌면서 일일 카드뉴스와 주간소식 제작 과정도 수정했다. 기존 제작 방식은 유지하되, 프로젝트 구성과 소식 데이터를 가져오는 방법을 변경했다.\n별도로 관리하던 일일 카드뉴스와 주간소식 제작 프로젝트를 게시글의 마크다운(.md) 파일이 있는 사이트 프로젝트로 통합했다. MCP를 통해 소식을 불러오던 방식을 마크다운 파일을 직접 읽고 분석하는 방식으로 바꿨다. 개편 후 더 이상 사용할 수 없게 된 기존 MCP는 제거했다. 구체적인 변경 내용은 별도의 글에서 자세히 다루겠다.\n개편 후 글 발행 과정 #개편 후에는 새로운소식, 주간소식, 공지사항, 자유게시판에 사용할 마크다운(.md) 템플릿을 마련했다. AI를 활용해 게시판별 템플릿에 맞는 빈 글을 생성하는 스킬을 만들었고, 글 생성부터 작성·검수까지 다음 순서로 진행했다.\n글 파일 생성: 파일명은 {id}-{uuid}.md 형식으로 지정했다. id는 마지막으로 생성한 글의 값에 1을 더하고, uuid는 파일을 만들 때 새로 생성했다. 본문 작성: 글은 직접 작성했다. 다만 단순한 소식 전달은 YouTube 동영상 URL을 입력하면 동영상과 본문을 분석해 내용을 채워 주는 스킬을 만들어 활용했고, 최종 검수는 직접 진행했다. 교정 및 표기 확인: 작성 후에는 오탈자와 문법, 고유명사 표기를 검사하고 수정하는 스킬을 사용했다. 처음 사용하는 고유명사는 별도의 마크다운 파일에 기록해, 이후에도 같은 표기를 사용할 수 있도록 했다. 검수를 마친 글은 main 브랜치에 반영해 Cloudflare Pages의 자동 빌드·배포 과정을 거쳐 발행했다.\n구체적인 내용은 별도의 글에서 자세히 다루겠다.\n비용 #개편 전 월 운영 비용은 Fly.io의 웹·데이터베이스 운영에 58.77달러, Google Workspace에 8.32달러, Cloudflare에 5달러로, 총 72.09달러였다. Amazon SES는 이메일 발송량이 적어 비용이 발생하지 않았다. 개편 후에는 Cloudflare Pro 요금제 비용인 월 25달러로 줄어, 매월 47.09달러, 기존 대비 약 65.3%를 절감했다.\n9월 18일 기준으로 적용한 환율인 1달러당 1,382.20원으로 환산하면, 약 99,643원에서 34,555원으로 줄어든 셈이다.\n마치며 #이번 개편은 1년여간의 운영 경험을 바탕으로 리얼그루브의 실제 이용 방식에 맞춰 사이트 구조를 정리하는 작업이었다. 회원 참여보다는 콘텐츠 발행이 중심이 된 상황에서, 현업에 복귀한 뒤에도 꾸준히 운영할 수 있는 구조가 필요했다.\n정적 사이트로 전환하면서 직접 관리해야 할 서버와 데이터베이스, 외부 서비스를 줄였다. 응답 시간이 짧아지고 월 운영 비용도 약 65.3% 줄어들었다. AI는 구현과 데이터 마이그레이션에 드는 시간을 줄이는 데 도움이 됐고, 특히 게시글 변환 과정에서 그 효과를 크게 체감했다.\nGitHub 기반 댓글처럼 일반 방문자에게 낯설 수 있는 부분은 남아 있다. 앞으로도 실제 이용 상황을 살피며 필요한 부분을 보완하고, 단순해진 운영 구조를 바탕으로 록 음악 소식을 꾸준히 발행하는 데 집중하려고 한다.\n","date":"2026-09-18","permalink":"/posts/2026/09/realgroove-renewal-1/","section":"Posts","summary":"\u003cp\u003e작년부터 개발·운영 중인 록 음악 커뮤니티 \u003ca href=\"https://realgroove.net\" target=\"_blank\" rel=\"noreferrer\"\u003e리얼그루브\u003c/a\u003e를 개편하고, 9월 1일에 적용했다. 1년여간 쌓인 데이터와 운영 추이를 바탕으로 필요한 기능을 추가하거나 보완하고, 불필요한 기능은 정리했다.\u003c/p\u003e","title":"리얼그루브 리뉴얼(1) - 커뮤니티에서 콘텐츠 중심 사이트로 변경 후 운영 비용 65% 줄이기"},{"content":"이 블로그에서 사용하는 태그를 모아볼 수 있습니다.\n","date":null,"permalink":"/tags/","section":"태그","summary":"\u003cp\u003e이 블로그에서 사용하는 태그를 모아볼 수 있습니다.\u003c/p\u003e","title":"태그"},{"content":"","date":null,"permalink":"/tags/ai/","section":"태그","summary":"","title":"AI"},{"content":"","date":null,"permalink":"/tags/claude/","section":"태그","summary":"","title":"Claude"},{"content":"","date":null,"permalink":"/tags/mcp/","section":"태그","summary":"","title":"MCP"},{"content":"","date":null,"permalink":"/tags/weekly/","section":"태그","summary":"","title":"Weekly"},{"content":"작년부터 개발·운영 중인 록 음악 커뮤니티 리얼그루브에서는 새로운소식 데이터를 활용해 AI 기반의 일일 카드뉴스 제작과 주간소식 작성에 AI를 활용하고 있다.\n기존에는 리얼그루브 MCP와 주간소식 스킬(Skill)을 이용해 주간소식을 작성한 뒤 내용을 직접 검수하고 최종 게시했다. 이번에는 여기에 인스타그램용 콘텐츠 제작 과정까지 확장했다. 주간소식을 카테작고리별로 자동 요약하도록 스킬을 개선하고, 게시물에 사용할 커버 이미지까지 함께 생성하도록 기능을 추가했다.\n이번 글에서는 기존 주간소식 제작 스킬을 어떤 방식으로 개선했고, 인스타그램용 콘텐츠 제작까지 지원하도록 어떻게 확장했는지 소개해보고자 한다.\n인스타그램용 주간소식 요약 #주간소식은 한 주 동안 등록된 소식을 각각 2~3줄로 요약해 하나의 글로 제작한다. 하지만 이를 그대로 인스타그램 카드뉴스에 담기에는 분량이 너무 많다.\n그래서 AI가 각 카테고리의 핵심 내용만 추려 요약하도록 스킬 내용을 추가했으며, AI가 아래와 같이 반영했다.\n🇰🇷 국내소식 (N건): 주요 아티스트/소식 나열 🎵 신보 및 비디오 (N건): 주요 내용 나열 🔥 아티스트 (N건): 주요 내용 나열 🤐 인터뷰 (N건 + AI M건): 주요 내용 나열 🎸 악기 및 장비 (N건): 주요 내용 나열 🎤 음악산업 (N건): 주요 내용 나열 ⚖️ 법적문제 (N건): 주요 내용 나열 ✨ 기타 (N건): 주요 내용 나열 추가로, 분류 내용이 없을 경우 내용을 만들지 않도록 했으며, 게시글에 분류가 지정되어 있지 않거나 AI 관련 내용은 아래와 같이 분류하도록 했다.\n해당 분류에 소식이 없어 빈 섹션으로 처리된 경우 괄호 안에 건수 대신 처리 사유를 간략히 기재한다 (예: 빈 섹션 처리 (이승환은 국내소식으로 분류)). AI 관련 인터뷰가 있을 경우 인터뷰 건수를 (N건 + AI M건) 형식으로 표기한다. 인스타그램 카드 커버 이미지 제작 #주간소식과 함께 인스타그램에 게시할 커버 이미지는 일일 카드뉴스 제작에서 사용한 방식을 그대로 활용했다.\n커버에는 해당 주간소식의 대상 기간이 표시되도록 구성했다. 또한 주간소식을 생성할 때 Playwright를 이용해 커버 이미지도 함께 생성하도록 스킬에 제작 과정을 추가했다.\n마치며 #기존 주간소식 제작 스킬을 개선해 블로그 게시물과 함께 인스타그램용 카테고리 요약과 커버 이미지도 생성할 수 있도록 했다.\n주간소식의 모든 내용을 인스타그램에 담기는 어렵기 때문에 각 카테고리의 핵심 내용을 별도로 요약했고, Playwright를 이용해 해당 기간이 표시된 커버 이미지도 함께 제작하도록 구성했다. 이를 통해 주간소식을 작성한 뒤 인스타그램용 콘텐츠를 다시 정리하고 이미지를 별도로 만드는 반복 작업을 줄일 수 있었다.\n생성된 결과는 그대로 게시하지 않고 내용과 이미지의 최종 상태를 직접 검수했다. 완전 자동화보다는 반복적인 제작 과정은 AI에 맡기고, 정확성과 품질에 대한 판단은 사람이 담당하는 현재 방식 그대로 진행했다.\n결과를 인스타그램에 게시한 결과는 아래와 같다.\nView this post on Instagram ","date":"2026-07-27","permalink":"/posts/2026/07/cardnews-weekly-instagram/","section":"Posts","summary":"\u003cp\u003e작년부터 개발·운영 중인 록 음악 커뮤니티 리얼그루브에서는 새로운소식 데이터를 활용해 AI 기반의 \n      \n    \u003ca href=\"/posts/2026/06/07/realgroove-ai-daily-cardnews/\"\u003e일일 카드뉴스 제작\u003c/a\u003e과 \n      \n    \u003ca href=\"/posts/2026/05/realgroove-ai-weekly-reporter/\"\u003e주간소식 작성\u003c/a\u003e에 AI를 활용하고 있다.\u003c/p\u003e","title":"주간소식 스킬에 인스타그램 게시글 제작 과정 추가"},{"content":"작년부터 개발·운영 중인 록 음악 커뮤니티 리얼그루브의 새로운소식 글을 이용해 일일 카드뉴스 제작과 주간소식 작성에 AI를 활용하고 있다.\n그동안은 새로운소식 데이터를 직접 DB에서 추출한 뒤 AI에 입력하는 방식으로 작업을 진행했다. 하지만 매번 DB에 접속해 데이터를 조회·가공하고 다시 입력하는 과정을 반복해야 했고, 이 과정에서 불필요한 시간이 소모되었다. 또한 잘못된 쿼리나 실수가 발생할 경우 운영 중인 시스템 전체에 영향을 줄 가능성도 있었다.\n그래서 데이터 추출과 AI 입력 과정을 보다 안전하고 효율적으로 처리하기 위해 MCP(Model Context Protocol)로 게시글을 조회하도록 하여 자동화 환경을 구현하게 되었다.\n이 글에서 MCP를 어떻게 구현하고 적용했는지 작성해보려고 한다.\nMCP(Model Context Protocol) #MCP(Model Context Protocol)는 2024년 11월 25일 앤트로픽(Anthropic)이 제안한 공개 표준 프로토콜로, AI가 외부 데이터 소스와 도구, 다양한 시스템에 표준화된 방식으로 연결될 수 있도록 설계되었다. 프로토콜은 JSON-RPC 기반으로 구현되어 있으며, 특정 AI 서비스에 종속되지 않는 개방형 구조를 지향한다.\n아키텍처 측면에서 MCP는 호스트(Host), 클라이언트(Client), 서버(Server)로 구성된다. 또한 MCP 서버가 AI에 기능을 제공하는 방식은 리소스(Resources), 도구(Tools), 프롬프트(Prompts)라는 세 가지 개념으로 나뉜다.1\n쉽게 말해 AI 호스트2에 MCP 서버를 연결해두면, AI는 MCP 서버를 통해 필요한 데이터를 조회하거나 특정 기능을 실행할 수 있다. 이후 AI는 반환된 결과를 분석·가공해 사용자에게 자연어 형태로 전달한다. 이 과정에서 데이터 조회나 기능 실행은 도구(Tools) 또는 프롬프트(Prompts)34를 통해 이루어진다.\nMCP 서버는 개발자의 PC와 같은 로컬 환경에 직접 구현할 수도 있고, 별도의 원격 서버에 구축한 뒤 AI 호스트와 연결하여 사용할 수도 있다.\n현재 MCP는 앤트로픽 뿐만 아니라 OpenAI를 비롯한 다양한 AI 서비스에서도 지원하고 있으며, 관련 생태계도 빠르게 성장하고 있다. 이미 공개된 MCP를 손쉽게 설치하고 활용할 수 있도록 Smithery, PlayMCP와 같은 MCP 레지스트리 서비스도 제공되고 있다.\n구현 #최근 리얼그루브를 Laravel 12에서 13으로 업데이트했다. Laravel 13에는 AI Agent와 MCP가 공식 패키지⁠￼로 추가되었고, 이를 이용해 원격 MCP 서버를 구현했다.\n이 MCP는 일반 사용자에게 공개하는 용도가 아니라 카드뉴스와 주간소식 제작용으로 사용한다. 비록 나 혼자 사용하는 서비스지만 운영 서버에 구축되어 외부에서 접근하므로 사용자 인증은 필수였고, API Key 기반 인증을 적용했다.\nTool 설계 #일일 카드뉴스와 주간소식은 모두 새로운소식 게시글을 기반으로 제작된다. 두 작업의 차이는 조회하는 날짜 범위뿐이며, 사용하는 데이터는 동일하다. 따라서 날짜 범위에 맞는 새로운소식을 조회하는 Tool 하나를 구현해 공통으로 사용하도록 설계했다5.\nLaravel MCP는 AI 클라이언트가 전달할 수 있는 입력값을 Schema로 정의⁠￼할 수 있다. 이를 함께 작성하면 AI가 어떤 매개변수를 사용할 수 있는지 이해하고 적절한 값을 전달할 수 있다.\nTool 구현 #Laravel MCP의 Tool 구현은 일반적인 Controller를 작성하는 방식과 비슷해 생각보다 간단했다. 오히려 Tool을 구현하는 것보다 Laravel MCP의 동작 방식과 사용법을 이해하는 데 더 많은 시간을 사용했다.\n또한 AI의 반복 호출이나 오작동으로 서버에 과도한 부하가 발생하는 상황을 방지하기 위해 Rate Limit을 적용하여 분당 최대 60회까지만 호출할 수 있도록 제한했다.\n인증 #MCP 서버는 운영 서버에 구축되어 있으며 외부에서 접근 가능하다. 비공개 서비스라고 하더라도 인증 없이 공개하는 것은 보안상 바람직하지 않다고 판단했다.\n그래서 AI 클라이언트가 MCP를 사용할 때 API Key를 함께 전달하도록 구현했으며, 서버에서는 이를 검증한 뒤에만 Tool을 실행하도록 구성했다.\nMCP 기능 추가 #MCP를 구현하며 이 MCP를 카드뉴스, 주간소식 제작 뿐만 아니라 클로드 코드 등에서 궁금한 소식들을 직접 검색하여 사용할 수 있도록 검색어를 추가했다.\n검색 기능 추가 후 테스트를 해보니, AI가 자체적으로 판단해 한글 검색어뿐만 아니라 영문으로도 검색을 시도하는 경우가 있었다. 예를 들어 메탈리카와 Metallica를 함께 검색하는 식이다.\n이를 지원하기 위해 검색어를 쉼표(,)로 구분하면 OR 조건으로 여러 검색어를 동시에 조회할 수 있도록 검색 기능을 수정했다. 또한 검색어 Schema에도 해당 형식을 정의해 AI가 이를 활용할 수 있도록 했다.\n결과 #구현을 완료한 뒤 운영 서버에 배포하고, Claude Code에서 사용할 수 있도록 MCP 서버 주소와 API Key를 전역 설정에 등록했다.\n설정을 마친 후 테스트한 결과, Claude Code가 원격 MCP 서버에 정상적으로 연결되었으며 새로운소식 데이터를 문제없이 조회할 수 있었다. 기존처럼 데이터를 직접 추출해 입력하지 않아도 AI가 필요한 시점에 MCP를 호출해 데이터를 가져오는 것을 확인할 수 있었다.\n카드뉴스, 주간소식 스킬 수정 #현재 일일 카드뉴스와 주간소식은 각각 Claude Code의 스킬(Skill)을 통해 생성하고 있다. 기존 스킬은 DB에서 직접 추출한 JSON 데이터를 입력받는 방식으로 작성되어 있었기 때문에, MCP를 이용하도록 내용을 수정했다.\n이제는 다음과 같이 간단한 프롬프트만 입력하면 스킬이 자동으로 MCP를 호출해 필요한 데이터를 조회한 후 콘텐츠를 생성한다.\n리얼그루브 오늘 소식 카드뉴스 만들어줘 리얼그루브 이번 주 주간소식 만들어줘 이제는 데이터를 직접 추출하거나 붙여넣을 필요 없이, AI가 필요한 데이터를 MCP를 통해 조회한 뒤 카드뉴스와 주간소식을 자동으로 작성할 수 있게 되었다.\n마치며 #실제 운영 중인 사이트에 MCP를 적용하면서 반복적으로 수행하던 작업을 자동화할 수 있었다.\nMCP라는 개념은 문서와 예제를 통해 알고 있었지만, 직접 구현하고 운영 환경에 적용해보니 데이터가 AI까지 전달되는 과정과 동작 원리를 훨씬 명확하게 이해할 수 있었다. 역시 직접 만들어보고 사용해보는 경험이 가장 좋은 학습 방법이라는 것을 다시 한번 느꼈다.\n실제로 카드뉴스와 주간소식을 제작해보니, 기존처럼 JSON을 직접 추출해 AI에 붙여넣는 방식보다 MCP를 통해 필요한 데이터를 조회하는 방식이 훨씬 편리했다. 반복적인 데이터 추출 과정이 사라지면서 작업 시간도 줄었고, 실수할 가능성도 함께 낮출 수 있었다.\n현재 이 MCP는 개인적으로 사용하는 서비스이기 때문에 새로운소식 조회를 위한 Tool 하나만 구현했다. 하지만 외부에 공개하는 서비스로 확장한다면 기능별로 Tool을 세분화하고, 별도의 MCP 서버를 구축하는 방향이 적합할 것으로 생각한다. 그 과정에서 기능이 커진다면, 별도의 프로젝트로 구현 / 별도 서버에 배포하는 것이 구현과 유지보수가 훨씬 수월할 것이다. 이 때 현재 상황 등을 고려해 MCP Python SDK 등을 활용할 수도 있을 것이다.\n이번 구현에서 특히 흥미로웠던 점은 AI가 MCP를 통해 조회한 데이터를 단순히 출력하는 것이 아니라 의미를 이해하고 가공해 결과를 만들어낸다는 점이었다. 이를 보면서 카드뉴스 제작뿐 아니라 리얼그루브의 검색 기능에도 AI를 접목할 수 있겠다는 가능성을 발견했다.\n앞으로는 AI Agent를 리얼그루브에 적용해 사용자의 질문을 이해하고 관련 뉴스와 정보를 종합해 답변하는 검색 기능도 실험해보고자 한다. 물론 이를 위해서는 AI API 비용 문제를 해결하는 것이 먼저일 것이다.\nMCP(Model Context Protocol) 란? (2025 4). MCP란 무엇인가: LLM Agent 동작 흐름으로 이해하는 MCP - 한컴테크. https://tech.hancom.com/mcp-llm-agent\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nClaude Code, Claude Desktop과 같은 AI를 담고 있는 프로그램\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n도구(Tool)은 AI가 프롬프트를 분석해 사용자에게 확인(혹은 자동) 으로 호출하지만, 프롬프트(Prompt)는 사용자가 AI 호스트에서 명시적으로 호출해야 함\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n리소스(Resource)는 사용자가 아닌 AI가 참조하는 요소로, AI 모델이 컨텍스트(맥락)를 파악하기 위해 읽을 수 있는 데이터 및 정보(파일, 데이터베이스, API 응답 등)를 정의하는 요소 (개발자가 정의해야 함)\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n프롬프트(Prompt)로 구현하지 않는 이유는 프롬프트는 AI 호스트에 사용자가 직접 명시적으로 호출해야 하기 때문이다. 스킬에 넣어 사용하는 방법도 고려했으나, 프롬프트의 목적(원래 사용자가 AI 호스트에서 직접 선택·호출하는 설계)에 맞지 않기 때문에 제외였음\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-06-22","permalink":"/posts/2026/06/realgroove-mcp-weekly-daily/","section":"Posts","summary":"\u003cp\u003e작년부터 개발·운영 중인 록 음악 커뮤니티 리얼그루브의 새로운소식 글을 이용해 \n      \n    \u003ca href=\"/posts/2026/06/07/realgroove-ai-daily-cardnews/\"\u003e일일 카드뉴스 제작\u003c/a\u003e과 \n      \n    \u003ca href=\"/posts/2026/05/realgroove-ai-weekly-reporter/\"\u003e주간소식 작성\u003c/a\u003e에 AI를 활용하고 있다.\u003c/p\u003e","title":"MCP를 이용한 카드뉴스 및 주간소식 제작 개선"},{"content":"작년부터 개발·운영 중인 록 음악 커뮤니티 리얼그루브는 매일 새로운소식에 업로드한 글들을 X(옛 트위터)에도 요약해 올리고 있다1.\n추가로 인스타그램￼에도 콘텐츠를 업로드해보려 했지만, 카드뉴스에 사용할 이미지 제작과 편집에 생각보다 많은 시간이 필요했다. 이미 글 작성, 개발, 유지보수를 혼자 진행하고 있는 상황이라 지속적으로 운영하기에는 부담이 컸고, 결국 사실상 방치 상태가 되었다.\n그러던 중 클로드(Claude)를 이용해 인스타그램 카드뉴스를 만드는 영상을 보게 되었고, “매일 올리는 새로운소식을 카드뉴스 형태로 자동 제작하면 어떨까?”라는 생각이 들었고, 이후 실제로 구현과 운영까지 진행하게 되었다.\n이 글에서는 인스타그램 카드뉴스 템플릿 선택부터 구현, 그리고 실제 카드뉴스 제작 과정까지 정리해보려 한다.\n구현 결과 #설명하기 앞서 구현 결과는 아래와 같다. (6월 5일자 카드뉴스) 제작 순서 #앞서 언급한 영상을 참고해 카드뉴스를 아래와 같은 순서로 제작했다.\n카드뉴스 내용을 담을 HTML 템플릿 제작 새로운소식 게시글을 클로드로 정리해 Markdown(.md) 생성 Markdown 내용을 기반으로 카드뉴스 HTML 생성 playwright를 이용해 HTML 페이지를 이미지로 캡처 생성된 결과 검수 후 인스타그램 업로드 템플릿 완성 후에는 2~5번 과정 반복 카드뉴스 제작에 사용할 글은 DB에서 직접 추출(Export)2했다.\n카드뉴스 템플릿 제작 #가장 먼저 클로드를 이용해 생성한 카드뉴스 내용을 담을 HTML 템플릿을 제작했다. 영상에서도 언급하듯이 HTML은 이미지보다 내용 입력과 수정이 쉽고, 세밀한 제어와 템플릿화에도 유리하다.\n템플릿은 Canva에서 제공하는 무료 카드뉴스 템플릿 중 단순한 디자인을 참고해 아래와 같이 구성했다.\n인스타그램 카드뉴스에서 많이 사용하는 1080x1350 비율 적용 제목, 본문, 해시태그, 로고 영역 구성 리얼그루브 웹사이트에서 사용하는 색상과 폰트 적용 기본적인 Cover, Cardnews, CTA 외에도 List 형태 템플릿을 추가로 제작했다. 금~토요일에는 국내외를 가리지 않고 앨범 발매나 공연 발표 등으로 업로드되는 소식 수가 많아지는데, 이 경우 모든 내용을 상세 카드로 만들기보다 제목 위주로 빠르게 정리하는 것이 최대한 많은 소식을 실을 수 있었기 때문이다.\n마지막으로, 아래 이미지처럼 제작된 카드뉴스 전체를 한 화면에서 확인할 수 있는 검수 페이지( 구현결과 영역의 이미지)도 함께 구현했다.\nAI를 이용한 카드뉴스 내용 제작 #카드뉴스 내용은 매일 새로운소식 게시판 글을 클로드를 이용해 Markdown(.md) 파일 형태로 정리하도록 구성했으며,진행 과정은 아래와 같다.\n새로운소식 제목, 본문, 해시태그, 작성일 목록 추출2 추출한 데이터를 클로드에 입력 클로드가 내용을 읽고 카드뉴스용 Markdown 생성 카드뉴스 제작은 제작 지시사항을 정리한 Skill 형태로 구성했으며, 주요 규칙은 아래와 같다.\n문체: 토스 스타일의 해요체 사용 (~합니다, ~했습니다 와 같은 합쇼체 금지) HTML Entity 디코딩: \u0026amp;nbsp;, \u0026amp;lt;, \u0026amp;gt; 등을 실제 문자로 변환 Cover: 제목 및 헤드라인 5개 생성 Cardnews: 제목 요약, 300자 이내 본문 요약, 해시태그 생성 List: 명시적으로 요청한 경우에만 생성 추가로 인스타그램 업로드 시 사용할 게시글 캡션도 함께 생성하도록 구성했고, 생성된 내용은 Markdown 파일 마지막에 포함했다.\n카드뉴스 HTML 생성 #앞서 생성한 카드뉴스 내용이 저장된 마크다운 파일 내용을 기반으로 각각의 카드뉴스 HTML 파일을 생성했다. 이 과정 역시 앞서 미리 만들어둔 템플릿 HTML에 내용을 채워 넣는 방식으로 동작하도록 스킬로 만들어 사용하였다.\n또한 검수 편의를 위해 카드뉴스 전체를 한 화면에서 확인할 수 있는 페이지도 함께 구성했다. 이 화면을 통해 들여쓰기, 줄바꿈, 문장 길이, 내용 추가·삭제 등을 최종 확인하고 수정했다.\n생성한 HTML을 이미지로 캡처 #완성된 카드뉴스 HTML은 인스타그램 업로드를 위해 이미지로 변환해야 했고, 이를 위해 playwright를 사용했다.\nplaywright는 Microsoft에서 개발한 브라우저 자동화 및 E2E 테스트 도구로, UI 없이 백그라운드에서 Chromium 실행 가능 각 카드뉴스 화면은 Chromium 브라우저의 Viewport 크기를 카드뉴스 크기와 동일한 1080x1350으로 설정한 뒤, screenshot 기능을 이용해 이미지로 캡처했다.\n인스타그램 게시 #최종 검수를 마친 카드뉴스 이미지를 인스타그램에 업로드하고, 함께 생성한 게시글 캡션을 추가하면 하루 카드뉴스 제작 과정이 완료된다.\n추가 적용 #카드뉴스 제작 자동화를 구성한 뒤 약 한 달 정도 운영하면서 몇 가지를 추가로 개선했다.\n스킬 업데이트: 제목 길이를 줄이기 위해 밴드명의 영문 표기를 제거 카드뉴스에 맞게 문장 길이 및 표현 수정 치환: 뮤직비디오 → MV, N번째 스튜디오 앨범 → 정규 N집 등으로 변경 비속어 제외: F**k, Shit, Damn 등의 표현은 생략하거나 순화 Claude에 /harness 플러그인을 설치한 뒤, 카드뉴스 생성부터 이미지 제작, GitHub Push까지 단독으로 수행할 수 있는 스킬과 QA 에이전트 추가 QA 에이전트는 생성된 HTML 카드뉴스가 앞서 정의한 규칙대로 작성되었는지 검증하고, 결과를 보고한 뒤 필요한 수정 작업까지 진행 영어 한글 표현 맞는지 검사 체크. 한글(English) 같은 형식일 경우 체크, 만타스(Mantas) 일 경우 통과, 만티스로 입력될 경우 사용자에게 알리고 진행하도록 추가 마치며 #AI를 이용한 카드뉴스 제작 자동화 프로세스를 구현한 뒤 약 한 달 정도 운영해본 결과, 크게 수정이 필요한 부분은 없었다. 생각보다 AI가 핵심 내용을 잘 파악해 요약해주는 경우가 많아 그대로 사용하기도 했다.\n물론 주제와 어긋나거나 문맥의 의미가 미묘하게 달라지는 경우도 있었는데, 이런 경우에는 직접 내용을 수정하거나 추가 지시를 통해 다시 생성하도록 했다.\n이번 작업에서는 “사람이 하지 않아도 되는 작업은 최대한 줄이자”는 방향으로 접근했다. 완전 자동화도 가능했지만, 내용과 카드뉴스 레이아웃에 대한 최종 검수는 직접 진행했다. 그 결과 사람이 직접 카드뉴스 내용 제작, 이미지 편집 등 최소 1~2시간 정도 예상되는 작업을 약 30분 이내로 줄일 수 있었다.\n또한 이미지 편집 툴 대신 HTML 기반으로 카드뉴스를 제작하면서 템플릿 재사용과 유지보수도 훨씬 수월해졌다. 개발자가 익숙한 방식으로 콘텐츠 제작 파이프라인을 구성할 수 있다는 점도 만족스러웠다.\n현재는 새로운소식 글을 DB에서 JSON 형태로 직접 추출2해 입력 데이터로 사용하고 있다. 앞으로는 이 과정 역시 개선해, 별도의 데이터 추출 없이 프롬프트만으로 카드뉴스를 생성할 수 있는 형태도 시도해볼 생각이다. 그렇게 된다면 전체 제작 과정은 지금보다 훨씬 단순해질 것으로 예상된다.\n스레드(Threads)도 운영했지만, X(옛 트위터)와 달리 반복 업로드로 메타 정책 위반에 걸려 운영 종료.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n새로운소식 글 내용 추출 기능을 구현하기 전까지 직접 추출하여 사용.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-06-11","permalink":"/posts/2026/06/07/realgroove-ai-daily-cardnews/","section":"Posts","summary":"\u003cp\u003e작년부터 개발·운영 중인 록 음악 커뮤니티 \u003ca href=\"https://realgroove.net\" target=\"_blank\" rel=\"noreferrer\"\u003e리얼그루브\u003c/a\u003e는 매일 \u003ca href=\"https://realgroove.net/space/news/post\" target=\"_blank\" rel=\"noreferrer\"\u003e새로운소식\u003c/a\u003e에 업로드한 글들을 X\u003ca href=\"https://x.com/realgroove_net\" target=\"_blank\" rel=\"noreferrer\"\u003e(옛 트위터)\u003c/a\u003e에도 요약해 올리고 있다\u003csup id=\"fnref:1\"\u003e\u003ca href=\"#fn:1\" class=\"footnote-ref\" role=\"doc-noteref\"\u003e1\u003c/a\u003e\u003c/sup\u003e.\u003c/p\u003e","title":"AI를 이용한 일일 인스타그램 카드뉴스 요약 및 생성 자동화"},{"content":"작년부터 개발하고 운영 중인 록 음악 커뮤니티 리얼그루브￼에는 주간소식 메뉴가 있다. 매주 평균 60개 이상의 새로운소식 글을 직접 정리해, 매주 월요일에 업로드하고 있다.\n주간소식을 약 35건 정도 작성하다 보니 점점 패턴이 보이기 시작했다. 글의 구조는 점점 비슷해졌고, 분류·요약·정리 과정에서 반복적으로 수행하는 작업이 많아졌다. 특히 이 과정에 평균 2시간 이상이 소요되면서 점점 부담되기 시작했다.\n이 작업은 더 이상 ‘창작’이라기보다 정형화된 작업에 가깝다는 생각이 들었고, “일부는 자동화할 수 있지 않을까?” 라는 생각이 들었다.\n그래서 Claude Code를 이용해 주간소식에 들어갈 콘텐츠를 분류하고 요약하는 스킬(Skill)을 구현했고, 실제 발행 과정에도 적용해보기 시작했다.\n이 글에서는 해당 스킬을 어떻게 설계하고 적용했는지, 그리고 실제 운영에 어떤 변화가 있었는지 정리해보려고 한다.\n배경 #주간소식은 매주 일요일부터 토요일까지 업로드된 새로운소식 글을 정리해, 월요일 새벽에 발행하는 방식으로 운영하고 있다.\n사이트 오픈 초기에는 ChatGPT를 이용해 프롬프트로 단순 \u0026ldquo;이 내용을 요약해줘\u0026quot;와 같은 방식으로 요약을 진행하였다. 그러나 문맥이 부자연스러워 결과가 기대만큼 만족스럽지 않았다.\n이후 AI를 사용하지 않고 직접 내용을 확인 후 요약했고, 게시글을 7개의 카테고리(신보 및 비디오, 아티스트, 인터뷰, 악기 및 장비, 음악산업, 법적문제, 기타)로 나누고, 각 분류별로 내용을 정리하는 방식으로 구조를 잡았다. 또한 국내 소식의 비중을 점차 늘려가며, 해당 카테고리 내에서 국내 소식만 따로 추려 정리하는 방식도 추가했다.\n하지만 여전히 매주 60개 이상의 글을 정리하는 데에는 상당한 시간(평균 2시간 이상)이 필요했고, 개인적으로도 지속하기에는 부담이 되는 작업이었다. 그리고 주간소식의 구조가 점점 고정되면서, 이 작업은 자동화할 수 있겠다는 생각이 들어 Claude Code를 활용해 주간소식 정리를 자동화하는 스킬을 구현하게 되었다.\n주간소식 형식 #현재 주간소식은 아래의 순서대로 작성하고 있다.\n상단 대표 이미지 추가 인사말 작성 아래 분류별로 소식 정리 국내소식, 신보 및 비디오 아티스트, 인터뷰, 악기 및 장비, 음악산업, 법적문제, 기타 국내 소식은 기존 분류 상관없이 국내소식 분류에 정리 마지막 인사말 작성 한 주간 소식 제목 및 원문 링크 목록을 Ordered List로 추가 일부 분류는 아래의 추가 규칙을 갖는다.\n신보 및 비디오: 내용 작성 후 마지막에 게시글 제목만 Unordered List로 별도 정리 인터뷰: AI 내용이 포함될 경우 별도로 해당 내용을 Unordered List로 정리 분류가 없는 글일 경우 기타 분류에 포함 Skill 구현 #앞서 정의한 주간소식 형식을 기반으로, 입력 데이터를 이용해 주간소식을 마크다운(.md) 파일로 생성하는 Claude Code 스킬(Skill)을 구현했다.\n스킬은 Claude Code에 요구사항을 프롬프트 형태로 전달하여 생성하는 방식으로 구현했으며, 원하는 결과를 얻기 위해 입력 데이터 구조, 날짜, URL, 파일명, 글자 수 등 최대한 명확하게 정의해주었다.\n입력 데이터 #주간소식 생성에 사용되는 입력 데이터는 관리자가 DB에서 직접 추출한 JSON 배열 형태이며, 각 항목은 아래와 같은 구조를 가진다.\n항목 설명 비고 id 게시글 ID category_name 게시글 분류 이름으로 {국내소식, 신보 및 비디오 아티스트, 인터뷰, 악기 및 장비, 음악산업, 법적문제, 기타} 중 하나 created_at 게시글 작성일 ISO 8601 형식 subject 제목 stripped_content stripg tag된 게시글 본문 날짜 처리 (시작일 / 종료일) #주간소식의 기간은 입력 데이터의 첫 번째와 마지막 항목의 created_at 값을 기준으로 계산한다.\n시작일: 첫 번째 데이터의 날짜 종료일: 마지막 데이터의 날짜 출력 형식: M/D (예: 4/1 ~ 4/7) 해당 기간 정보는 주간소식 제목 및 본문, 파일명에 사용된다.\n원문 링크 #각 게시글의 원문 링크는 아래 규칙을 따른다.\nhttps://realgroove.net/space/news/post/:id :id 항목은 입력 데이터의 id 값을 이용해 자동 생성한다.\n저장 파일명 #생성된 주간소식은 아래 경로와 파일명 규칙에 따라 저장한다.\n/weekly/[Weekly#{순서}] 주간소식 {시작일} - {종료일}.md {순서}: 주간소식 번호 (36부터 시작 - 35까지 직접 작성) {시작일}, {종료일}: M/D 형식 글자 수 #내용이 길어지는 것을 방지하기 위해 최대 300자 이내로 요약하도록 정의하도록 지정했다.\n작성 예시 #Claude가 문체, 구성 방식 요약 스타일을 확인 후 학습할 수 있도록 최근 작성된 주간소식 4건의 URL을 예시로 함께 제공했다.\n적용 #위에서 정의한 구조를 기반으로 스킬을 구현한 후, 36번째 주간소식(Weekly #36)에 사용할 데이터를 입력해 실제로 생성해보았다.\n결과는 기대 이상이었다. 데이터를 입력하자 거의 즉시 주간소식이 생성되었고, 기존에 작성하던 형식과 거의 동일한 구조로 결과가 나왔다. 내용 역시 대부분 그대로 사용할 수 있을 정도로 완성도가 높았다.\n매주 일요일에서 월요일로 넘어가는 새벽마다 2시간 이상을 들여 작성하던 작업이었기 때문에, “왜 더 빨리 적용하지 않았을까”라는 생각이 들 정도였다.\n실제 작업 시간도 크게 줄었다. 기존에는 주간소식 작성에 2시간 이상이 소요되었지만, 스킬 적용 이후에는 검수 및 수정, 링크 정리까지 포함해 약 30분 내외로 마무리할 수 있게 되었다.\n오히려 현재는 내용 자체를 작성하는 것보다, 리얼그루브 에디터에 맞게 형식을 정리하는 작업이 더 많은 시간을 차지하고 있다.\n앞으로는 생성된 결과를 기반으로 부족한 부분을 보완하고, 그 기준을 다시 스킬에 반영하는 방식으로 개선을 반복한다면, 주간소식의 기본적인 내용 생성은 AI가 충분히 담당할 수 있는 영역이라고 될 수 있을 것 같다.\n한계와 보완 #하지만 AI가 생성한 주간소식 내용을 그대로 사용할 수 있는 것은 아니다.\nAI가 판단하기 어려운 영역 #AI가 생성한 결과는 기본적인 구조나 요약 측면에서는 충분히 활용 가능하지만, 내용의 정확성이나 문맥의 자연스러움에 대해서는 반드시 한 번 더 검증하는 과정이 필요하다.\n또한 아티스트의 중요도나 소식의 우선순위 판단은 현재 기준에서는 AI가 완전히 대체하기 어려운 영역이라고 생각한다.\n예를 들어 ‘신보 및 비디오’ 카테고리의 경우, 주요 아티스트의 소식은 본문으로 정리하고 나머지는 제목 리스트로 구성하는 방식으로 작성하고 있는데, 어떤 아티스트를 ‘주요’로 볼 것인지에 대한 기준은 단순한 데이터만으로 판단하기 어렵다.\n이 부분은 밴드의 인지도, 최근 활동, 현재 이슈 등 다양한 요소를 종합적으로 고려해야 하기 때문에, 이 부분은 여전히 사람이 직접 판단하고 수정하는 과정이 필요하다.\n해당 부분은 주간소식 작성하면서 기존과 같이 직접 판단한 후 작성할 예정이며, AI가 판단할 수 있는 방법이 있는지는 지속적으로 확인해 나갈 것이다.\n자동화 확장 #현재는 주간소식 생성을 위해 필요한 JSON 데이터를 직접 추출한 후, 프롬프트에 입력하여 결과를 생성하는 방식으로 운영하고 있다.\n하지만 이 과정을 조금 더 확장하면, 아래와 같이 하나의 자동화된 업무 프로세스로 구성할 수 있다.\n주간소식 데이터를 API로 자동 수집 Claude Code 또는 Claude 기반 워크플로우를 이용해 정해진 시간에 자동 실행 생성 결과를 알림으로 전달 (예: PlayMCP의 카카오톡 나챗방등 활용) 필요 시 관리자 페이지에서 검수 후 발행 리얼그루브 관리자가 만들어진다면(현재는 사용자 규모가 많지 않아 수동운영), Crontab을 이용해 일정 시간에 자동 실행한 뒤 주간소식 내용을 pending 상태로 저장하고, 검수 후 발행하는 방식으로도 확장해 나가려고 한다.\n마치며 #이번 구현을 통해 AI를 활용한 주간소식 요약 자동화를 진행했고, 기대 이상으로 만족스러운 결과를 얻을 수 있었다.\n처음에는 단순히 “AI로 요약을 해보자”는 생각으로 시작했지만, 실제로는 내가 작업하던 방식과 예외 사항을 그대로 정의해 스킬로 구성한 뒤 적용해보니, 사람이 직접 작성한 것과 유사한 결과가 만들어졌다. 이 과정에서 AI를 어떻게 활용해야 하는지에 대해서도 알 수 있었다.\n물론 모든 과정을 AI에 맡길 수 있는 것은 아니다. 중요한 판단이나 최종 검수는 여전히 사람이 직접 수행해야 하는 영역이다. 하지만 반복적이고 시간이 많이 소요되던 작업을 크게 줄일 수 있었다는 점에서, 충분히 의미 있는 변화라고 생각한다.\n스킬은 결국 내가 수행하던 업무의 일부를 AI에게 위임하는 과정이다. 업무 방식이 계속 변화하는 만큼, 스킬 또한 그에 맞게 지속적으로 개선되어야 한다. 앞으로도 주간소식을 작성하면서, 부족한 부분을 보완하고 그 기준을 스킬에 반영해 나갈 예정이다.\n예전부터 느껴왔지만, 이번 경험을 통해 더욱 확신하게 된 점은 앞으로는 AI를 단순히 사용하는 사람이 아니라, 제대로 활용할 수 있는 사람이 높은 생산성을 만들어낼 것이라는 것이다.\n그렇다면 AI가 만들어낸 결과를 검수하고, 판단하고, 최종적으로 책임질 수 있는 사람은 어떻게 만들어질까? 결국 답은 단순하다고 생각한다. 직접 고민하고, 만들어보고, 경험해보고, 결론을 내 본 사람일 것이다. 기초를 바탕으로 스스로 문제를 해결해본 경험이 있는 사람만이, AI를 단순한 도구가 아니라 생산성을 극대화하는 수단으로 활용할 수 있을 것이다.\n","date":"2026-05-06","permalink":"/posts/2026/05/realgroove-ai-weekly-reporter/","section":"Posts","summary":"\u003cp\u003e작년부터 개발하고 운영 중인 록 음악 커뮤니티 \u003ca href=\"https://realgroove.net\" target=\"_blank\" rel=\"noreferrer\"\u003e리얼그루브\u003c/a\u003e￼에는 \u003ca href=\"https://realgroove.net/space/weekly/post\" target=\"_blank\" rel=\"noreferrer\"\u003e주간소식\u003c/a\u003e 메뉴가 있다. 매주 평균 60개 이상의 \u003ca href=\"https://realgroove.net/space/news/post\" target=\"_blank\" rel=\"noreferrer\"\u003e새로운소식\u003c/a\u003e 글을 직접 정리해, 매주 월요일에 업로드하고 있다.\u003c/p\u003e","title":"Claude Code를 이용한 주간소식 요약 및 자동화"},{"content":"전 회사 메인 서비스는 20년 이상 운영된 레거시 환경 아래 구성되어 있었다. 그동안 수많은 기능이 추가되었지만, 적절한 시점에 리팩토링이 이루어지지 않은 채 확장만 반복되면서 코드 구조는 점점 복잡해졌고, 이른바 ‘스파게티 코드’ 상태가 되어 기존 코드를 분석하고 새로운 기능을 적용하는 과정 자체가 쉽지 않은 상태였다.\n이러한 상황에서 PC 메인 서비스의 GNB(Global Navigation Bar)와 Footer를 전면 개편해야 했고, 기존 구조를 유지한 채 부분 수정으로 대응하기에는 한계가 분명했다.\n단순한 UI 개선이 아니라, 일부 페이지는 Vue 기반으로 일부 페이지가 이미 동작하고 있었고, 향후 확장과 유지보수를 고려한 구조 개선이 필요하다고 판단해 GNB와 Footer를 Vue 기반으로 새롭게 만들기로 결정했다. 이 글에서는 이러한 환경에서 GNB를 어떻게 설계하고 적용했는지, 그리고 어떤 방식으로 문제를 해결했는지 정리해보려고 한다.\n기존 구조 #기존 GNB / Footer는 PHP 기반으로 구현되어 있었으며, 메뉴 변경이 필요할 때마다 업무 협조 요청을 통해 개발자가 직접 수정하는 방식이었다.\n메뉴 변경이 드물다면 큰 문제가 되지 않았겠지만, 실제로는 변경 요청이 빈번했음 업무 담당자는 즉각적인 수정이 불가능해 답답함을 느꼈고, 개발자는 과거 구현 방식을 다시 파악한 후 작업을 진행해야 하는 부담이 생김 실제 변경 작업 중 오류가 종종 발생했으며, 이러한 경험이 반복되면서 이 업무를 업무 담당자 / 개발자 모두 부담스럽게 느끼게 되어버림 심지어 관리자 페이지에서 메뉴를 직접 수정할 수 있는 기능과 미리보기 기능이 존재하긴 했지만, 해당 기능에 대한 인수인계가 제대로 이루어지지 않았고, 사용 중 오류도 발생하면서 실질적으로 활용되지 못해 대부분의 메뉴 변경은 하드코딩 방식으로 처리하고 있었다.\n또한 메뉴이용 사용자 통계 기능도 제공되지 않아, 업무 담당자가 사용자 흐름을 파악하는 데에도 어려움이 있었다.\n이러한 구조는 단순한 불편함을 넘어, 지속적인 운영과 확장에 있어 명확한 한계로 작용하고 있었다.\n리뉴얼 #이러한 상황에서 담당 부서로부터 PC 페이지 GNB와 Footer에 대한 전면적인 개선 요청이 들어왔고, 기존 단점을 보완할 수 있도록 다음과 같은 기능들이 요구되었다.\n담당자가 직접 메뉴 이름 변경, 메뉴 추가 / 삭제를 할 수 있어야 함 적용 전 미리 확인할 수 있는 Preview 기능 필요 메뉴 클릭에 대한 통계 기능 필요 광고 배너 교체 및 클릭 통계 기능 필요 리비전: 최근 n개의 GNB 정보를 저장해 필요 시 rollback 할 수 있는 기능 필요 이는 단순한 UI 변경이 아니라, 개발자 의존 구조를 운영 중심 구조로의 전환이었다.\n구현 #결론부터 말하면, 이번 GNB / Footer 리뉴얼은 Vite(Vue) 기반으로 구현한 후 라이브러리 형태로 빌드하여 기존 레거시 시스템에 적용하는 방식으로 구현했다.\n과거 일부 컴포넌트를 빌드하여 웹 페이지에 적용한 경험이 있었고, 레거시 서비스 내 일부 페이지에서도 Vite(Vue) 기반 MPA 방식이 이미 운영 중이였기 때문에, 이를 바탕으로 레거시 환경에서도 Vue 기반 구조를 적용하는 것이 가능하다고 판단했다.\n그리고 이번 GNB / Footer 개편을 계기로, 기존 레거시 페이지들도 이번 리뉴얼하는 GNB / Footer를 포함해 Vue 기반으로 전환하여 점진적으로 대체하는 방향을 고려해 단계별로 현대화 하는 기반을 마련하고자 했다 (해당 내용은 업무 담당자들과도 공유함).\n또한 기존의 PHP 중심 레거시 방식을 유지하는 것은 장기적인 유지보수성과 확장성 측면에서 한계가 있다고 판단했다. 이에 따라, 향후 구조 개선과 개발 생산성을 고려하여 Vue 기반 구조를 도입하는 것이 더 적절하다고 판단했다.\n개발에는 다음과 같은 기술을 사용했다.\nVite (Vue), 라이브러리 빌드 Tailwindcss, DaisyUI Typescript Prettier, ESLint, Commitlint 적용 Node / Docker 기반 개발환경 구성 사용자 페이지 #전 회사에서는 디자인팀에서 Vue 기반으로 퍼블리싱 해주어 디자인 측면에서는 큰 수정 없이 적용이 가능했고, 필요한 경우에는 협의를 통해 일부 수정만 진행했다.\n다만 테스트 및 적용 과정에서 몇 가지 현실적인 이슈가 있었다.\n테스트 환경의 부재 #레거시 서비스에는 운영 환경과 동일한 조건의 개발 서버가 사실상 존재하지 않았다. (개발 서버와 운영 서버의 버전 차이로 인해 테스트 결과의 신뢰도가 낮았음)\n이로 인해 운영 서버에 직접 적용하되, 특정 로그인 사용자에게만 새로운 GNB / Footer가 노출되도록 분기 처리하여 테스트를 진행했다.\n페이지별 CSS 충돌 #레거시 서비스는 페이지마다 서로 다른 스타일이 적용되어 있었기 때문에, GNB / Footer의 스타일이 페이지별로 다르게 깨지는 문제가 발생했다.\n이를 해결하기 위해\n전체 페이지를 담당 부서와 함께 점검하며 스타일을 일괄 수정 신규 GNB / Footer 기준으로 기존 스타일을 정리하고, 필요한 경우 컴포넌트 스타일도 함께 수정 사용되지 않는 레거시 페이지는 이 과정에서 함께 정리 하는 작업을 병행했다.\nVue 컴포넌트에 scoped 스타일을 적용했지만, 기존 레거시의 전역 스타일과 태그 기반 CSS가 우선 적용되면서 의도한 스타일이 유지되지 않는 문제가 있었다.\n결과적으로 일부 영역에서는 스타일 충돌을 제어하기 위해 !important를 사용할 수밖에 없었으며, 이는 레거시 환경에서 안정적으로 동작시키기 위한 현실적인 선택이었다.\n메뉴 데이터 #GNB 메뉴 데이터는 페이지 로드 시마다 DB에서 조회하는 것은 비효율적이라고 판단하여, 메뉴 정보를 JSON 형태로 CDN에 저장한 후 이를 가져와 사용하는 구조로 변경했다.\n일반적으로는 Redis와 같은 캐시를 사용하는 것이 적절하지만, 레거시 서비스의 배포 구조로 인해 이를 적용하기 어려운 상황이었다.\n레거시 서비스는 FTP 기반으로 배포되고 있었으며,\nPR 이후 담당자가 직접 FTP 접속하여 배포 캐시 파일이 저장된 디렉토리가 그대로 노출됨 배포 과정에서 캐시가 변경되거나 삭제될 경우 서비스 전체에 영향 발생 과 같은 구조적 문제가 존재했다.\n이러한 환경에서 기존 방식으로 캐시를 운영하는 것은 위험하다고 판단하여, 메뉴 데이터를 특정 담당자만 접근 가능한 CDN에 JSON 형태로 저장해 이를 사용하는 방식으로 변경해 DB 의존을 제거하고, 공통 데이터를 보다 안정적으로 제공할 수 있도록 했다.\n관리자 페이지 #관리자 페이지는 별도의 팀원이 담당하여 개발을 진행했으며, 나는 전체 구조 방향 설정과 주요 기능 설계, 그리고 사용자 페이지 적용에 집중했다.\n관리자 페이지에서는 다음과 같은 기능을 중심으로 구현되었다.\n메뉴 변경 이력 저장 (사용자 정보 포함) 메뉴 구조 미리보기 기능 CDN 기반 JSON 캐시 생성 및 배포 로그 #담당자가 메뉴 정보 편집 후 저장 버튼을 누를 때 전체 메뉴 정보를 JSON 형태로 사용자 정보와 날짜와 함께 DB에 저장하였고 이를 관리자 페이지에서 볼 수 있도록 구현했다.\n미리보기 #이번 구현의 요구사항 중 하나인 미리보기 기능은 사용자 페이지에서 사용하는 Vue 컴포넌트를 그대로 재사용하여 구현했다.\nDB에 저장된 메뉴 데이터를 불러온 후, 컴포넌트에 props 형태로 전달하여 실제 적용 모습과 동일하게 렌더링되도록 구성했다.\n캐시 #레거시 서비스는 콘텐츠, 쇼핑몰 등 여러 서비스가 동일한 DB를 사용하고 있었기 때문에\nDB 부하가 빈번하게 발생하는 구조였다.\n이러한 환경에서 GNB 메뉴까지 매번 DB에서 조회하는 것은 비효율적이라고 판단했다.\n따라서 메뉴 데이터를 CDN에 JSON 형태로 저장하고, 사용자 페이지에서는 이를 직접 조회하도록 구성했다.\n다만 CDN은 캐싱된 콘텐츠를 제공하는 특성상, 동일한 파일을 업로드해도 즉시 반영되지 않는 문제가 있었다.\n이를 해결하기 위해 CDN의 무효화(Invalidation) 기능을 활용하여 메뉴 변경 시 캐시를 즉시 무효화하고 최신 데이터가 반영되도록 처리했다.\n해당 기능은 관리자 페이지 구현을 담당한 팀원이 개발을 진행했으며, 나는 CDN Invalidation 방식과 적용 방향을 정의하고 관련 자료를 공유하여 구현이 가능하도록 지원했다.\n적용 #구현 완료한 후 업무 담당자들과 최종 테스트 및 레거시 전 페이지 대상으로 이상 없는지 확인 후 적용했다.\n전체 업무 기간은 약 3개월 가량 소요되었고 적용 이후 별다른 이슈 없이 안정적으로 운영되었으며, 메뉴 변경 및 관리 측면에서도 소모시간과 커뮤니케이 비용 또한 감소되었다.\n결론 #이번 GNB / Footer 리뉴얼은 단순한 UI 개편이 아니라, 레거시 시스템을 점진적으로 현대화하기 위한 구조적 개선 작업이었다.\n기존에는 메뉴 관리가 개발자에게 의존하고 있었지만, 이번 개편을 통해 담당자가 직접 관리할 수 있는 구조로 전환되었다. 또한 Vue 기반 구조를 도입함으로써, 기존 레거시 페이지를 유지한 채 점진적으로 개편해 나갈 수 있는 기반을 마련할 수 있었다.\n이 과정에서 이상적인 구조를 적용하기보다는, 현재 시스템 환경에 맞게 현실적인 타협을 하며 안정적으로 적용했다.\n적용 이후에는 담당 부서에서도 레거시 시스템이 점진적으로 개선되는 과정을 체감할 수 있었고, 다른 서비스(쇼핑몰)에도 동일한 방식으로 적용하고 싶다는 의견이 나오기도 했다.\n결과적으로, 이 업무는 개발과 운영 모두에서 만족할 수 있는 결과를 만들어낸 사례였다고 생각한다.\n회고 #시간이 흐른 뒤 이 글을 정리하면서, 이번 업무를 진행하며 몇 가지를 다시 돌아보게 되었다.\n팀원에게 기회를 #이번 업무에서는 CSS 레이아웃 수정과 같은 단순 대응보다는, 개발 비중이 높은 관리자 페이지 기능을 팀원에게 맡기기로 했다 (당시 나의 일정도 영향을 주었지만, 의도적인 선택이기도 했다).\n이 팀원은 3년차 개발자로, 레거시 유지보수 외에도 신규 프로젝트를 몇 차례 경험한 상태였다. 이번 기회를 통해 단순 구현을 넘어,\n사용자 관점에서의 입력(Form Validation) 처리 CDN 기반 캐싱 구조 이해 및 Invalidation 적용 관리자 UI 구현 과 같은, 이전과는 다른 개발 경험을 할 수 있도록 하고자 했다.\n개발은 단순히 기능을 구현하는 것보다,\n새로운 문제를 해결하고 그 과정에서 성장하는 경험이 중요하다고 생각한다.\n이번 업무를 통해 이 팀원이 새로운 영역을 경험하고, 개발에 대한 흥미와 함께 한 단계 성장했다는 느낌을 받을 수 있기를 바랐다.\n기술 부채 #앞서 언급한 것처럼, 20년 이상의 기술 부채를 가지고 있던 레거시 서비스에 Vue 컴포넌트 기반의 GNB / Footer를 적용했고, 향후 레거시 페이지를 점진적으로 교체할 수 있는 기반을 마련했다.\n다만 시간이 지나고 돌아보니, 이 구조가 조직 전체를 고려했을 때도 적절한 선택이었는지에 대해 생각을 하게 되었다.\n다른 팀원들 또한 Vue를 다룰 수 있었기 때문에 기술적으로는 충분히 이어서 개발이 가능한 상태였지만, 테스트 및 배포 프로세스가 충분히 정립되어 있지 않은 상황이었다.\n결과적으로, 레거시 환경에서의 기술 도입이 또 다른 형태의 기술 부채로 이어질 가능성도 있었던 것은 아닌지 고민하게 되었다.\n개인적으로는 20년 넘는 레거시는 반드시 개선이 필요했기 때문에 이와 같이 진행은 했겠지만, 부족했던 테스트 및 배포, 기타 환경 구성의 필요한 시스템도 같이 진행 했을 것 같다.\n문화 부채 #오랜 기간 누적된 문제는 코드에만 남는 것이 아니라, 업무 방식과 의사결정 구조에도 함께 쌓이게 된다.\n그동안 충분히 정리되지 않은 코드 위에 기능이 계속 추가되었고, 문제가 발생하면 이를 수정하는 방식이 반복되었다. 이러한 구조 속에서 후임 개발자들은 기존 코드를 이해하고 수정하는 데 많은 시간을 소모해야 했다.\n개발 인력은 부족했고, 근본적인 개선을 진행할 수 있는 시간도 충분히 주어지지 않았다. 결과적으로 단기적인 대응이 우선되는 구조가 반복되었고, 업무 부서의 개발 요청은 점점 증가하게 되었다.\n이 과정에서 개발팀에 대한 기대보다는 “요청하면 늦어지고 문제가 발생할 수 있다”는 인식이 점차 형성되었던 것 같다.\n이후 팀장이 된 뒤, 실장님과 함께 구조적인 개선을 시도하기 시작했다. 신규 서비스들 또한 안정적으로 개발 및 론칭을 진행했고, 이 과정에서 개발팀은 “우리는 할 수 있다” 라는 인식이 형성되었고, 이번 GNB 개편 역시 문제 없이 적용되는 모습을 보고 운영 부서에서도 점차 신뢰를 갖고 맡길 수 있게 되었다.\n물론 제한된 인력과 시간으로 인해 모든 요구사항을 즉시 반영할 수는 없었지만, 이전과 달리 개발팀이 신뢰를 바탕으로 협업할 수 있는 상태로 변화했다는 점에서 의미가 있었다고 생각한다.\n","date":"2026-04-20","permalink":"/posts/2026/04/renewal-gnb-vue/","section":"Posts","summary":"\u003cp\u003e전 회사 메인 서비스는 20년 이상 운영된 레거시 환경 아래 구성되어 있었다. 그동안 수많은 기능이 추가되었지만, 적절한 시점에 리팩토링이 이루어지지 않은 채 확장만 반복되면서 코드 구조는 점점 복잡해졌고, 이른바 ‘스파게티 코드’ 상태가 되어 기존 코드를 분석하고 새로운 기능을 적용하는 과정 자체가 쉽지 않은 상태였다.\u003c/p\u003e","title":"20년 넘은 레거시 사이트에 Vue 기반 GNB / Footer 적용"},{"content":"","date":null,"permalink":"/tags/gnb/","section":"태그","summary":"","title":"GNB"},{"content":"","date":null,"permalink":"/tags/legacy/","section":"태그","summary":"","title":"Legacy"},{"content":"","date":null,"permalink":"/tags/computer-graphics/","section":"태그","summary":"","title":"Computer Graphics"},{"content":"","date":null,"permalink":"/tags/software-renderer/","section":"태그","summary":"","title":"Software Renderer"},{"content":"웹 개발을 하다 보면 이미지를 다루어야 하는 경우가 생기고, 그 과정에서 Canvas를 사용하는 상황을 한 번쯤은 마주하게 된다.\n단순한 도형이나 이미지를 그리는 것을 넘어서, 조금 더 나아가면 3D 모델을 화면에 표현해야 하는 경우도 생긴다. 보통은 WebGL이나 라이브러리를 사용해 이를 해결하지만, 그 내부에서 어떤 과정이 일어나는지, 이미지가 실제로 어떻게 그려지는지, 그리고 3D 모델이 2D 이미지로 변환되는 과정이 어떻게 이루어지는지까지 깊이 고민하는 경우는 많지 않다.\n그래서 이 과정을 하드웨어(GPU) 도움 없이, 렌더링 과정(Rendering Pipeline)을 코드로 직접 구현하는 소프트웨어 렌더러(Software Renderer)를 웹 기반으로 만들어보았으며, 그 과정을 간략하게 정리해보고자 한다.\nRendering Pipeline #렌더링(Rendering)은 컴퓨터 화면에 우리가 보는 UI나 웹 페이지 등을 출력하는 과정으로, 쉽게 말해 화면에 그림을 그리는 것을 의미한다.\n3차원 모델을 2차원 화면에 출력하기 위해서는 차원 1개를 줄여 3D 좌표를 2D 좌표로 변환해야 한다. 이 과정은 수학적으로 정의되어 있으며, 정해진 절차에 따라 계산된 결과가 픽셀 단위의 이미지로 변환되어 화면에 출력된다.\n이 일련의 과정을 렌더링 파이프라인(Rendering Pipeline) 이라고 한다. 이 과정은 오래전부터 하드웨어(GPU)로 구현되어 왔으며, 개발자는 일반적으로 OpenGL이나 DirectX와 같은 그래픽 API를 통해 이를 활용한다.\n렌더링 파이프라인은 일반적으로 다음과 같은 단계로 구성되며, 이번 구현한 소프트웨어 렌더러는 아래 과정을 구현하였다 (모든 과정은 오른손 좌표계(Right-hand Coordinates) 기준으로 함).\nflowchart LR; A(ModelView)--\u003eB(Backspace\nCulling); B--\u003eC(Projection) C--\u003eD(Lighting) D--\u003eE(Clipping) E--\u003eF(Viewport) F--\u003eG(Rasterization) Transformation #변환(Transformation)은 3차원 공간에 존재하는 정점(Vertex)을 화면에 출력하기 위한 좌표로 변환하는 과정이다.\n각 정점은 모델 변환(Model Transform), 뷰 변환(View Transform), 투영 변환(Projection Transform)을 거치며, 이후 Perspective Divide를 통해 3차원 좌표계에서 [-1, 1] 범위를 가지는 NDC(Normalized Device Coordinates)로 변환된다.\n이후 NDC 범위를 벗어난 정점이나 도형은 클리핑(Clipping) 과정을 통해 제거되거나 잘려나가며, Rasterization 단계에서 실제 화면에 출력될 픽셀로 변환된다.\n또한, 삼각형이나 폴리곤 수가 많을 경우 렌더링 비용이 증가하기 때문에 보이지 않는 면을 제거하는 Back-face Culling을 뷰 변환 이후 단계에서 수행하였다.\n폴리곤 법선 벡터와 카메라 방향 벡터의 내적을 통해, 카메라를 향하지 않는 면을 제거하는 방식으로 구현 내적 값이 0보다 크면 카메라를 향하는 면(Front-face), 0보다 작으면 카메라를 등지고 있는 면(Back-face)으로 판단 Lighting \u0026amp; Shading #Lighting과 Shading 단계에서는 물체가 빛을 어떻게 반사하고 표현되는지를 계산한다.\nLighting은 광원과 물체의 관계를 기반으로 밝기를 계산하는 과정이며, Ambient, Diffuse, Specular, Emission 요소의 조합을 통해 물체의 입체감과 재질감을 표현한다.\nAmbient (주변광): 방향성과 관계없이 물체 전체에 균일하게 적용되는 기본 조명 Diffuse (난반사광): 빛이 물체 표면에 닿아 여러 방향으로 퍼지며, 표면 각도에 따라 밝기가 달라짐 Specular (정반사광): 특정 각도에서 반사되어 하이라이트를 생성하는 빛 Emission (방출광): 외부 광원과 관계없이 물체 자체가 발광하는 효과 Shading은 계산된 조명 정보를 실제 픽셀에 적용하는 과정으로, Flat Shading, Smooth Shading (Gouraud, Phong) 방식이 있으며 각 방식에 따라 표면의 부드러움과 디테일이 달라진다.\n이번 구현에서는 세 가지 Shading 방식을 모두 구현하여, 사용자가 화면에서 직접 선택하고 비교할 수 있도록 하였다.\nFlat Shading: 폴리곤 단위로 하나의 법선을 사용하여 색상을 계산 Gouraud Shading: 각 정점 색상을 계산한 후, 보간(Interpolation)으로 폴리곤 내부 색상을 결정 Phong Shading: 정점 법선 보간 후, 픽셀 단위로 Lighting을 계산하여 자연스러운 결과를 생성 Texture Mapping #Texture Mapping은 물체 표면에 이미지를 입혀 실제와 같은 재질감과 디테일을 표현하는 방법이다.\n각 정점에는 UV 좌표가 정의되어 있으며, 이를 기반으로 텍스처 이미지의 특정 위치를 참조하여 최종 픽셀 색상을 결정한다.\n이번 구현에서는 별도의 이미지 처리 모듈을 사용하지 않고, Canvas를 통해 이미지를 로드한 뒤 픽셀 데이터를 배열로 변환하여 사용하였다.\n텍스처 매핑 과정에서는 인접한 픽셀 값을 사용하는 Nearest Neighbor Sampling 방식을 적용하였으며, 소수점 단위 보간 없이 정수 좌표 기반으로 샘플링을 수행하였다.\nRasterization #Rasterization 단계에서는 출력할 화면 크기(Viewport)에 맞는 이미지 버퍼를 생성하고, 3D 공간에서 정의된 도형을 픽셀 단위로 변환하여 화면에 그린다.\n이 단계에서는 삼각형 단위로 스캔라인 렌더링(Scanline Rendering)을 수행하였으며, 텍스처 매핑과 조명 계산 결과를 최종 픽셀 색상에 반영하였다. 픽셀 단위 색상 계산 과정에서 무게 중심 좌표계 (barycentric)를 활용하여 보간을 수행하였다.\n또한, Depth Buffer(Z-buffer)를 활용하여 겹쳐지는 물체의 앞뒤 관계를 처리하였고, 부드러운 경계를 표현하기 위해 2x2 MSAA(Multi-Sample Anti-Aliasing)를 적용하였다.\n최종적으로 생성된 이미지 버퍼를 Canvas에 전달하여 브라우저에 결과를 출력하였다.\nImplementation #본 프로젝트는 Vite와 TypeScript를 기반으로 구현하였다.\n일반적으로 사용하는 프론트엔드 프레임워크인 React나 Vue를 사용하지 않고, HTML과 JavaScript만으로 동작하도록 구성하였다. 단, 이벤트 처리를 위해 Alpine.js를 사용했고, Viewport 크기를 고정했기 때문에 (1024x768) 반응형이 아닌 고정형 페이지로 구현했다.\n별도의 렌더 루프를 사용하지 않고 Canvas에 렌더링된 이미지 버퍼를 전달하여 출력하는 형태로 구현했고, 이벤트(숫자 변경, frame/depth buffer 변경 시)에만 업데이트 후 다시 렌더링 하는 방식으로 동작하도록 했다.\nModels #구현 시 아래 5개 모델을 이용하였다.\nTexture 있는 모델: Tiger, Bunny, Buddha, Zebra: Texturemontage Textured Models Texture 없는 모델: Teapot: Utah University Graphics Lab 각 모델의 정점, 폴리곤 개수는 아래와 같다.\nModel # of Vertices # of Polygons 비고 Tiger 6,089 10,788 Bunny 16,323 30,338 Buddha 29,609 51,414 Zebra 21,305 40,310 Teapot 17,456 33,462 텍스쳐 없음 Performance #모델 렌더링 후 이벤트가 발생했을 시에만 업데이트하도록 하여 단순한 뷰어 용으로 볼땐 약간의 딜레이가 있지만 감안한다면 문제 없이 사용 가능했다.\n그러나 일반적인 그래픽스 프로그램 처럼 렌더 루프(Render Loop)를 이용해 매번 업데이트 해야 하는 경우 M4Pro@24GB, 크롬 브라우저 결과 평균 10fps 정도를 보여주어 실시간 렌더링에는 부적합했다.\n구현 결과는 아래와 같다. Demo: https://inium.github.io/web-canvas-software-renderer/dist/ Repository: https://github.com/inium/web-canvas-software-renderer Conclusion #약 15년 전, C++로 소프트웨어 렌더러를 구현해본 적이 있었다. 그때의 기억과 경험을 바탕으로, 이번에는 웹 환경에서 동작하는 소프트웨어 렌더러를 다시 구현해보았다. 그 과정을 통해 렌더링 파이프라인 전반을 다시 정리하고, 그동안 익숙하게 사용해왔던 그래픽 처리 과정을 한 단계 더 깊이 이해할 수 있는 계기가 되었다.\n컴퓨터 그래픽스(Computer Graphics)는 보통 전문 분야로 여겨지며, OpenGL이나 DirectX와 같은 그래픽 API, 혹은 Unreal, Unity3D, Godot과 같은 엔진을 기반으로 데스크탑이나 모바일 환경에서 구현되는 경우가 많다.\n그에 비해 웹 환경에서의 3D 렌더링은 상대적으로 익숙하지 않은 영역일 수 있다. 하지만 실제로는 교육, 산업, 시각화 등 다양한 분야에서 웹 기반 3D 렌더링이 활용되고 있다. 예를 들어, 교육용 서비스에서는 3D 모델을 웹에서 확인하고 수정해야 할 수 있으며, 산업 현장에서는 스캔된 데이터를 웹에서 검토한 뒤 다음 프로세스로 전달하는 과정이 필요할 수도 있다.\n이번 구현을 통해 느낀 점은, 기술을 사용하는 것과 그 원리를 이해하는 것은 전혀 다른 경험이라는 것이었다.\n소프트웨어 렌더러를 직접 구현해보면 3D 모델이 화면에 그려지기까지의 모든 과정을 한 번에 연결해서 이해할 수 있고, 각 단계가 왜 필요한지 자연스럽게 체감할 수 있다.\n개인적으로 그래픽스에 대한 이해를 깊게 가져가고 싶다면, 소프트웨어 렌더러를 한 번쯤 직접 구현해보는 것을 추천한다.\n","date":"2026-04-02","permalink":"/posts/2026/04/implement-web-software-renderer/","section":"Posts","summary":"\u003cp\u003e웹 개발을 하다 보면 이미지를 다루어야 하는 경우가 생기고, 그 과정에서 Canvas를 사용하는 상황을 한 번쯤은 마주하게 된다.\u003c/p\u003e","title":"웹으로 구현해본 3D 소프트웨어 렌더러"},{"content":" 이인 (In Lee) ☕️ 커피와 🤘락 음악을 좋아하는 소프트웨어 개발자 입니다. 안녕하세요. 풀스택 소프트웨어 개발자 이인입니다. Computer Graphics (Real-Time Rendering)를 전공했고 관련 업무를 했으며, 현재 풀스택 웹 개발자로 업무를 하고 있습니다.️\n지금까지 언어 / 플랫폼 가리지 않고 커뮤니티, 교육, 커머스, 콘텐츠 플랫폼 등 다양한 도메인을 설계하고 구현·운영·개선을 해왔고 기능 개발뿐 아니라 성능 개선·자동화·기술 부채 해소·아키텍처 개선·코드 품질 향상과 같은 “보이지 않는 영역”에 꾸준히 힘을 쏟아왔습니다.\n빠른 개발보다 지속 가능한 개발, 한 번의 성과보다 지속적인 개선을 선호합니다 또한 닭 잡는데 소를 잡는 칼(牛刀割鷄, 우도할계)을 사용하지 않으려고 항상 생각합니다.\n☕️ 커피와 🤘락 음악을 좋아합니다.\n현재 록 음악 커뮤니티 리얼그루브 https://realgroove.net 개발과 운영을 진행하고 있습니다.\n주요 개인 프로젝트 # 웹 기반 3D 소프트웨어 렌더러: Demo / Repository Laravel 게시판 패키지 laraboard: Repository / Composer Package Laravel Repository - Service 패키지: Repository / Composer Package ","date":null,"permalink":"/about/","section":"Inlee's Blog","summary":"\u003csection\n  class=\"not-prose \n    items-center\n   mb-3 flex flex-col\"\n\u003e\n  \n  \n  \n    \n    \n      \n      \n      \n\n\n\n\n\n\n\n\n  \n    \u003cpicture\n      class=\"mb-2 h-auto w-36 rounded-full\"\n      \n    \u003e\n      \n      \n      \n      \n        \u003csource\n          \n            \n              srcset=\"/profile/inlee_hu_63835206095527d4.webp\"\n            \n          \n          sizes=\"100vw\"\n          type=\"image/webp\"\n        /\u003e\n      \n      \u003cimg\n        width=\"460\"\n        height=\"460\"\n        class=\"mb-2 h-auto w-36 rounded-full\"\n        alt=\"이인 (In Lee)\"\n        loading=\"lazy\" decoding=\"async\"\n        \n          src=\"/profile/inlee.jpeg\"\n        \n      /\u003e\n    \u003c/picture\u003e\n  \n\n\n    \n  \n  \u003ch1 class=\"text-4xl font-extrabold\"\u003e\n    이인 (In Lee)\n  \u003c/h1\u003e\n  \n    \u003ch2 class=\"text-xl text-neutral-500 dark:text-neutral-400\"\u003e\n      ☕️ 커피와 🤘락 음악을 좋아하는 소프트웨어 개발자 입니다.\n    \u003c/h2\u003e\n  \n  \u003cdiv class=\"mt-1 text-2xl\"\u003e\n    \n  \u003cdiv class=\"flex flex-wrap text-neutral-400 dark:text-neutral-500\"\u003e\n    \n      \n        \u003ca\n          class=\"px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400\"\n          style=\"will-change:transform;\"\n          href=\"mailto:jamesinlee@gmail.com\"\n          target=\"_blank\"\n          aria-label=\"Email\"\n          rel=\"me noopener noreferrer\"\n          \u003e\u003cspan class=\"icon relative inline-block px-1 align-text-bottom\"\u003e\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"\u003e\u003cpath fill=\"currentColor\" d=\"M207.8 20.73c-93.45 18.32-168.7 93.66-187 187.1c-27.64 140.9 68.65 266.2 199.1 285.1c19.01 2.888 36.17-12.26 36.17-31.49l.0001-.6631c0-15.74-11.44-28.88-26.84-31.24c-84.35-12.98-149.2-86.13-149.2-174.2c0-102.9 88.61-185.5 193.4-175.4c91.54 8.869 158.6 91.25 158.6 183.2l0 16.16c0 22.09-17.94 40.05-40 40.05s-40.01-17.96-40.01-40.05v-120.1c0-8.847-7.161-16.02-16.01-16.02l-31.98 .0036c-7.299 0-13.2 4.992-15.12 11.68c-24.85-12.15-54.24-16.38-86.06-5.106c-38.75 13.73-68.12 48.91-73.72 89.64c-9.483 69.01 43.81 128 110.9 128c26.44 0 50.43-9.544 69.59-24.88c24 31.3 65.23 48.69 109.4 37.49C465.2 369.3 496 324.1 495.1 277.2V256.3C495.1 107.1 361.2-9.332 207.8 20.73zM239.1 304.3c-26.47 0-48-21.56-48-48.05s21.53-48.05 48-48.05s48 21.56 48 48.05S266.5 304.3 239.1 304.3z\"/\u003e\u003c/svg\u003e\n\u003c/span\u003e\u003c/a\n        \u003e\n      \n    \n      \n        \u003ca\n          class=\"px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400\"\n          style=\"will-change:transform;\"\n          href=\"https://linkedin.com/in/jamesinlee\"\n          target=\"_blank\"\n          aria-label=\"Linkedin\"\n          rel=\"me noopener noreferrer\"\n          \u003e\u003cspan class=\"icon relative inline-block px-1 align-text-bottom\"\u003e\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\"\u003e\u003cpath fill=\"currentColor\" d=\"M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z\"/\u003e\u003c/svg\u003e\n\u003c/span\u003e\u003c/a\n        \u003e\n      \n    \n      \n        \u003ca\n          class=\"px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400\"\n          style=\"will-change:transform;\"\n          href=\"https://github.com/inium\"\n          target=\"_blank\"\n          aria-label=\"Github\"\n          rel=\"me noopener noreferrer\"\n          \u003e\u003cspan class=\"icon relative inline-block px-1 align-text-bottom\"\u003e\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 496 512\"\u003e\u003cpath fill=\"currentColor\" d=\"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"/\u003e\u003c/svg\u003e\n\u003c/span\u003e\u003c/a\n        \u003e\n      \n    \n  \u003c/div\u003e\n\n\n  \u003c/div\u003e\n\u003c/section\u003e\n\n\n\u003cbr /\u003e\n안녕하세요. 풀스택 소프트웨어 개발자 이인입니다.\n\u003cp\u003eComputer Graphics (Real-Time Rendering)를 전공했고 관련 업무를 했으며, 현재 풀스택 웹 개발자로 업무를 하고 있습니다.️\u003c/p\u003e","title":"About Me"},{"content":"","date":null,"permalink":"/tags/%EC%84%9C%EB%B9%84%EC%8A%A4/","section":"태그","summary":"","title":"서비스"},{"content":"","date":null,"permalink":"/tags/%ED%87%B4%EC%82%AC/","section":"태그","summary":"","title":"퇴사"},{"content":" 이전 글에서와 같이 작년 4월까지 회사를 다녔다. 이직을 준비하던 중, 오래전부터 해보고 싶었던 일이 다시 떠올랐다. 막연히 언젠가 하겠다고 미뤄왔지만, 지금이 아니면 어렵겠다는 생각이 들었다.\n퇴사 후 한 달간의 휴식을 거쳐 5월부터 지금까지, 그 생각을 실제로 옮겨보는 시간을 보냈다. 이 글에서는 내가 오래전부터 하고 싶었던 일이 무엇이었는지, 그리고 그것을 어떤 방식으로 시도해왔는지를 정리해보려 한다.\n하고 싶었던 일 #고등학교 시절부터 록(Rock) 음악을 좋아했다. 당시는 온라인 커뮤니티가 하나둘 생겨나던 시기였고, 비록 제한적이었지만 록 음악과 관련된 소식들을 인터넷을 통해 접할 수 있었다.\n그 무렵 기타에도 관심을 갖게 되면서 자연스럽게 뮬(Mule)이라는 사이트를 알게 됐다. 악기 정보는 물론 록 음악 이야기를 나누는 공간이었고, 그곳에서 많은 정보를 얻으며 시간을 보냈다 (악기에 대해 많은 정보를 얻을 수 있었지만 록 음악에 대해서는 많이 접할 수는 없었다). 그러다 어느 순간, 언젠가는 나도 이런 커뮤니티를 만들어보고 싶다는 막연한 생각이 마음에 남게 됐다.\n그렇게 시간이 흘러, 금수강산이 두 번 바뀔 만큼의 세월이 지났다. 하지만 지금 다시 돌아보면 그때와 크게 달라진 점은 많지 않아 보였다. 뮬은 2000년대 초 다크한 디자인에서 현재의 모습으로 한 차례 개편된 이후, 구조나 방향성은 크게 달라지지 않았다. 이 곳에서 록 음악 관련 소식은 예전처럼 충분히 접하기 어려웠다.\n스트리밍 서비스가 대중화되며 음악은 ‘소장’이 아닌 ‘소비’의 영역이 되었다. 록 음악 소식은 유튜브, 인스타그램 같은 플랫폼을 통해 훨씬 빠르게 접할 수 있게 되었지만, 새로운 소식을 지속적으로 정리하고 전달하는 독립적인 커뮤니티는 좀처럼 찾아보기 어려웠다.\n디씨인사이드의 록 음악 관련 갤러리(일렉트릭기타 갤러리, 락 갤러리, 포스트락 갤러리 등)나 아카라이브의 메탈 채널처럼 게시판 형태의 공간은 존재했고, 메탈킹덤이나 뮬처럼 독립적인 커뮤니티도 여전히 운영되고 있었다. 다만 이들 대부분은 사용자 참여 중심의 구조였고, 새로운 소식을 전담해 꾸준히 다루는 곳은 아니었다.\n돌이켜보면 예전에도 그런 공간은 거의 없었고, 지금도 상황은 크게 다르지 않았다. 그래서 오래전부터 마음에 남아 있던 생각을 이번 기회에 직접 해보기로 했다. 대신 록 음악 소식과 악기 이야기를 함께 다루는 공간을 만들어보자는 생각이었다.\n요구사항 #록 음악을 주제로 한 커뮤니티이지만, 구조 자체는 일반적인 커뮤니티 사이트와 크게 다르지 않다. 초기 단계에서는 새로운 기능보다는 기본적인 사용 경험을 최소화 하면서 안정적으로 제공하는 것을 우선 목표로 삼았다.\n반응형 디자인 회원: 이메일 회원가입, 이메일 인증, 정보 수정, 회원 탈퇴 / 각 단계별 이메일 알림발송 게시판: 게시글, 2-Depth 댓글, 게시글 태그, 게시글 분류, 검색(제목, 내용, 댓글, 태그) / 일부 게시판은 권한이 있는 회원만 작성가능, 구글 로그인 추가 포인트: 게시판별 게시글, 댓글 점수 차등 적용 / 포인트 충족 시 특정 게시판 작성 권한 부여 기타: Dark Mode / Light Mode 지원 개발 #그동안 풀스택으로 개발해 온 경험이 있어 프론트엔드와 백엔드 모두 혼자서 진행했다. 시간적인 여유도 있었고, 별도의 팀 없이 혼자 어디까지 만들 수 있는지 시험해보고 싶었다.\n1인 개발인 만큼, 가장 중요하게 둔 기준은 복잡도를 낮추는 것이었다. 확장성보다는 지금의 나에게 관리 가능한 구조를 우선했다.\n아키텍처 #가장 익숙한 Laravel과 Vue로 개발하기로 결정했다.\nLaravel12 + Inertia.js(Vue) SPA에 가까운 사용자 경험 + 프론트엔드와 백엔드 분리 최소화 Vue + TypeScript / Tailwind CSS / DaisyUI 디자인 리소스를 최소화하면서도 빠르게 UI를 구성할 수 있는 조합 선택 코드 품질 #개발 과정에서 실수를 줄이고 일관된 코드를 유지하기 위해 정적 분석과 규칙 검증 도구를 적극적으로 적용했다.\n아래 항목들은 Commit 시 자동 검사되도록 설정했고, Github Actions를 통해 배포 과정에서도 동일한 검증이 이루어지도록 구성했다.\nESLint PHPStan Stylelint Commitlint 그리고 Laravel은 코드 테스트 프레임워크인 Pest 를 적용하여 Github Action 에 php test 코드를 실행하도록 구성했다.\n개발 · 운영 환경 #개발과 운영 환경의 차이로 발생하는 문제를 줄이기 위해 초기부터 docker(Container)로 구성했다.\n서버 #운영 환경 역시 Container 기반 배포가 가능한 구조를 기준으로 선택했다.\n여러 옵션을 검토한 끝에 설정과 운영이 비교적 단순하고 비용 부담이 적은 Fly.io를 사용했다. 이 과정에서 Fly.io에서 제공하는 데이터베이스를 활용하기 위해 기존 MySQL 대신 PostgreSQL로 변경했다.\nDNS: Cloudflare Image Storage: Cloudflare Images Email 발송: AWS SES Server: Fly.io (Container - AWS ECS와 같이 Container기반으로 쉽게 배포할 수 있는 환경) Database: PostgreSQL (Fly.io) 오픈 #약 3개월간의 개발을 마치고 2025년 8월 24일 서비스를 오픈했다.\n하지만 오픈은 끝이 아니라, 그때부터가 진짜 시작이었다.\n운영 #서비스를 오픈한 이후에는 신규 기능 개발뿐만 아니라 오류 수정과 개선, 콘텐츠 작성, SNS 관리까지 모든 일을 직접 맡아야 했다.\n특히 콘텐츠를 작성하고 팩트체크를 하다 보면 생각보다 많은 시간이 소요됐다. 그 과정에서 개발에 집중할 수 있는 시간은 자연스럽게 줄어들었고, 운영 또한 많은 에너지를 요구한다는 사실을 체감하게 됐다.\n서비스를 만든다는 것은 개발만으로 끝나는 일이 아니라는 걸 실감했다.\n페이지 수정 #오픈 이후 큰 장애나 치명적인 문제는 없었지만, 사용하면서 눈에 띄는 자잘한 레이아웃 수정과 반드시 필요하다고 느낀 기능들을 중심으로 개선을 이어갔다.\n대표적으로 구글 로그인 기능을 추가했고, 내 정보 페이지에서는 내가 작성한 글과 댓글, 공감한 글과 댓글 확인할 수 있는 기능을 추가했다. 또한 링크 길이에 따라 레이아웃이 깨지는 문제 등, 반응형 환경에서 발생하는 UI 문제들을 중심으로 수정해 나갔다.\n특히 콘텐츠가 없는 초기 상태에서 메인 페이지를 어떻게 보여줄 것인가는 예상보다 큰 고민거리는데, 이는 콘텐츠가 누적되며 몇 번의 변경을 거친 후 현재의 형태에 도달하게 되었다.\n콘텐츠 #운영을 이어가면서 무엇보다 중요했던 것은 지속적으로 작성해야 하는 콘텐츠인 매일 업로드하는 새로운 소식과, 일주일에 한 번 정리하는 주간 소식였다.\n특히 가장 많은 시간을 차지한 것은 록 음악 관련 소식을 매일 정리하는 일이었다. 대부분의 자료가 영문이였고, 하루에 최소 30개 이상의 콘텐츠를 읽고 10개 가량의 글들을 추려낸 후 정리해야 했다. 물론 모든 내용을 직접 번역하고 요약하기에는 시간적인 한계가 있었기 때문에, AI를 활용해 번역과 요약을 한 후 확인한다.\n업로드할 글들을 선정한 후 처음에는 AI가 생성한 내용을 거의 그대로 사용했는데, 팩트가 정확하지 않거나 맥락이 어긋나는 경우가 적지 않았다. 이후부터는 반드시 원문을 다시 확인하고, 직접 내용을 수정·정리한 뒤 업로드하는 방식으로 바꾸었다.\n록 음악 소식은 단순한 뉴스가 아니라 과거의 역사, 이전 사건과의 연결 관계를 함께 이해해야 하는 경우가 많았다. 악기 관련 소식 역시 재질이나 소재 같은 세부 정보까지 확인해야 했기 때문에, 이 과정을 거치는 데 예상보다 많은 시간이 소요됐다.\n주 1회, 매주 월요일에는 주간 소식 글을 작성해 업로드하고 있다. 한 주 동안 작성한 약 60~70개의 새로운 소식을 한 글로 정리하는 일은 생각보다 쉽지 않았다.\n초기에는 일주일치 글을 모두 AI에 입력해 주간 소식을 작성해보기도 했지만, 문장이 어색하거나 팩트 체크가 되지 않은 내용, 심지어 존재하지 않는 내용을 만들어내는 경우도 있어 해당 방식은 포기했다. 이 또한 결국 직접 글을 분류하고 정리하는 방향으로 변경했고, 이 작업을 조금이라도 수월하게 하기 위해 새로운 소식 게시글에 분류 항목을 추가하는 방식으로 구조를 개선했다.\n홍보 #지금도 마찬가지지만, 홍보는 여전히 답을 찾지 못해 무엇을 어떻게 해야 하는지 막막함이 든다.\n우선 기본적인 노출을 위해 구글과 네이버 검색에 사이트를 등록했다. 이후에는 X(구 트위터)와 스레드(Threads)를 중심으로, 작성한 콘텐츠를 간략히 정리해 업로드하고 있다(인스타그램의 경우 이미지·영상 콘텐츠 중심의 플랫폼 특성과 저작권 문제를 고려해 별도로 운영하지 않고 있다).\n스레드는 초기에 한 번에 많은 글을 업로드하면서 계정이 몇 차례 차단되는 경험도 했다. 이후 확인해보니 메타(Meta) 정책상 짧은 시간 다량 반복 게시가 스팸 행위로 간주되었기 때문이였고, 전화번호 인증과 얼굴 인증을 거쳐 계정을 복구한 뒤로는 하루 최대 10~12개 내외, 업로드 간격은 15 ~ 20분을 가급적으로 지키며 업로드하고 있다.\n유사한 음악 커뮤니티에 홍보 글을 올리면 보다 빠르게 알릴 수 있을 것이라 생각한 적도 있었다. 하지만 개인적으로는 그것이 일종의 도덕선을 넘는 행위처럼 느껴져 현재까지는 시도하지 않고 있다.\n한편, 해외 소식보다는 국내 록 음악 관련 콘텐츠에서 일시적으로 트래픽이 크게 증가한 경험도 있어 이를 계기로 최근에는 국내 소식의 비중을 조금씩 늘려가고 있다.\n홍보의 방향을 찾고는 있지만, 어쩌면 아직 크게 조급하지 않아서, 혹은 그렇게까지 뻔뻔해지지 못해서, 간절하게 보이지 않아서, 막다른 골목에 다다르지 못해서 일지도 모르겠다. 어쨌든 홍보에 공을 좀 더 들일 것이고, 시험해보고 실패하다보면 결과가 나올 것이라 생각한다.\n그나마 긍정적인 것은 X, 스레드에서 좋아요를 눌러주는 분들이 몇 분이 있어 완전 수요가 없는 것은 아니라는 것을 알게 되었다.\n통계 #초기에는 구글 애널리틱스(GA)만 사용했지만, 데이터를 교차 검증하기 위해 네이버 애널리틱스를 추가로 도입했다. 두 도구의 수치를 비교해보니 방문자 수나 흐름은 큰 차이 없이 비슷하게 나타났고, 각각의 도구에서만 확인할 수 있는 지표들도 존재했다. 마케팅 담당자들이 여러 개의 통계 도구를 함께 사용하는 이유를 조금이나마 이해하게 되었다.\n콘텐츠를 정리하는 과정에서 알게 된 경량 웹 분석 도구인 GoatCounter도 추가로 도입해볼까 고민 중이다.\n또한 구글 서치 콘솔을 함께 사용하며 페이지 색인 문제나 로딩 속도 관련 경고를 확인하고 있다. 실제로 몇 가지 항목은 코드 수정으로 개선했고, 앞으로도 주기적으로 점검하며 보완해 나갈 예정이다.\n성과 #2025년 8월 24일 서비스를 오픈한 이후, 글 작성 기준인 2026년 1월 26일까지 약 5개월간의 성과를 정리해보면 다음과 같다.\n누적 작성 글 수: 1,174개 방문당 PV (PV/UV): 약 1.09 (PV: 낮음) / 일부 콘텐츠는 예상보다 큰 반응을 얻은 경우도 있었음 일 평균 콘텐츠 업로드 수: 약 10개 내외 오픈 후 배포: 124(현재 컨테이너 버전 v124) 아직 눈에 띄는 수치라고 말하기는 어렵지만, 혼자 운영하며 매일 콘텐츠를 쌓아왔다는 점에서는 조금씩 성장을 하는 중이라고 생각한다.\n마치며 #지금까지 하고 싶었던 일에 대한 내용과 진행상황이였다. 거창한 목표에서 시작한 프로젝트는 아니였고 오래전부터 마음속에 남아 있는 생각을 더 늦기전에 한 번은 직접 해보고 싶다는 마음에서 출발했다.\n막연했던 아이디어는 개발이라는 형태를 거쳐 서비스가 되었고, 오픈 이후에는 운영과 콘텐츠, 홍보와 통계까지 모두 현실적인 문제로 다가왔다. 개발보다 운영이 더 많은 에너지를 요구한다는 사실도, 콘텐츠를 ‘지속적으로 만든다’는 것이 얼마나 어려운 일인지도 이 과정을 통해 실감했다.\n수치만 놓고 보면 작은 서비스다. 눈에 띄는 성과를 이야기하기에는 부족하고, 앞으로 어떻게 성장시켜야 할지도 여전히 고민 중이다. 그럼에도 불구하고, 하루도 빠짐없이 콘텐츠를 쌓고 서비스를 운영해온 지난 3개월 + 5개월은 내게 꽤 의미 있는 시간이었고 앞으로도 그럴 것이다.\n누군가의 지시나 일정이 아닌, 오롯이 스스로의 기준과 책임으로 하나의 서비스를 만들어보고 운영해본 경험은 이전에는 알지 못했던 많은 것들을 알려주었다. 이 서비스가 앞으로 어떤 모습으로 남게 될지는 아직 알 수 없다. 계속 이어질 수도 있고, 어느 시점에서는 멈추게 될 수도 있다.\n이 경험 자체는 이후 어떤 선택을 하더라도 내 안에 오래 남을 것이라 생각들며, 조직 생활에서 기획, 디자인, 개발자 등과의 커뮤니케이션에도 큰 도움이 될 것이라 생각한다.\n","date":"2026-01-26","permalink":"/posts/2026/01/after-resign-todo/","section":"Posts","summary":"\u003cp\u003e\n      \n    \u003ca href=\"/posts/2025/12/resign-lookback/\"\u003e이전 글에서와 같이\u003c/a\u003e 작년 4월까지 회사를 다녔다. 이직을 준비하던 중, 오래전부터 해보고 싶었던 일이 다시 떠올랐다. 막연히 언젠가 하겠다고 미뤄왔지만, 지금이 아니면 어렵겠다는 생각이 들었다.\u003c/p\u003e","title":"퇴사 후 - 지금 아니면 평생 후회할 것 같아 시작한 서비스를 만들고 운영한 경험 (그리고 진행중)"},{"content":"","date":null,"permalink":"/tags/%EA%B0%9C%EB%B0%9C/","section":"태그","summary":"","title":"개발"},{"content":"전 회사에서 개발팀 팀장으로 근무했었다. 20년 넘는 오래된 레거시 시스템을 유지보수하면서 동시에 신규 프로젝트를 진행해야 하는 팀을 맡는다는 건, 시작부터 쉽지 않은 과제였다.\n안정성을 해치지 않으면서 변화를 만들어야 했고, 변화가 필요하다는 사실을 팀 모두가 뿐만 아니라 관련 부서들도 납득해야 했다.\n이 글은 그런 상황에서 개발팀 팀장으로서 무엇을 우선순위로 두었고, 어떤 판단과 선택을 했는지에 대한 기록이다.\n팀 파악 #이미 팀원으로 근무했던 팀이었기 때문에 팀 파악 자체에는 큰 어려움이 없었다. 당시 팀의 상황을 정리해보면 아래와 같았다.\n20개 이상의 레거시 서비스 유지보수 중심 모든 서비스가 상시 이슈를 일으키는 것은 아니었지만, 오래된 문제일수록 원인 파악과 해결에 많은 시간이 소요됨 단기 해결에 익숙해지며 이른바 ‘땜빵식 처리’가 반복되었고, 그 결과 코드 품질 저하와 동일 이슈의 재발이 계속됨 신규 서비스조차 레거시화 Laravel, Vue 기반의 신규 서비스가 존재했으나 구조와 구현 방식이 레거시와 크게 다르지 않아 사실상 유지보수가 불가능한 상태 개발 프로세스 부재 공통된 개발 규칙, 리뷰 문화, 배포 기준 등이 정리되어 있지 않음 인력 유지의 악순환 새로 합류한 개발자들이 팀의 기술적 상태와 업무 방식을 보고 의욕을 잃고 퇴사하는 일이 발생 이 모든 문제의 근본에는 레거시에 익숙해진 문화가 자리 잡고 있다고 판단했다.\n다만 매출과 직결된 레거시 업무를 무시할 수는 없었기 때문에, 레거시와 신규 개발을 분리된 축으로 바라보고 단계적으로 개선해 나가는 방향을 선택했다.\n레거시 유지보수 및 개선 #매출과 직결된 레거시 시스템의 유지보수 및 개선 방향은, 큰 틀에서는 기존 방식을 유지했다. 대신 동일한 이슈 재발 등을 방지하기 위한 코드 품질 개선에 집중했다.\n구체적으로는 코드 리뷰를 도입했고, 담당자 단독 배포가 아니라 리뷰 후 승인된 변경만 운영 서버에 반영하도록 프로세스를 변경했다.\n물론 근본적인 문제는 따로 있었다. 레거시 시스템은 여전히 FTP를 통해 담당자가 직접 운영 서버에 배포하고 있었고, 이는 명백히 위험한 구조였다. 반드시 개선해야 할 지점이었지만, 당시 상황에서는 즉시 손대기 어려운 영역이기도 했다.\n레거시 전체 코드베이스에는 각종 리소스까지 포함되어 있었고, 규모가 지나치게 컸음 필요한 코드만 Git으로 관리하고 git pull 기반 배포로 전환은 단기간 시도하기에는 리스크가 매우 큼 결국 이 시점에서는 완전한 구조 개선보다는, 현실적으로 사고 가능성을 줄이는 방향의 점진적 개선을 선택할 수밖에 없었다.\n신규 프로젝트 #팀은 레거시 유지보수 뿐만 아니라 신규 프로젝트도 진행해야 했다. 다만 팀 내 신규 프로젝트에 대한 경험이 많지 않았기에, 프로젝트 시작할 때 마다 기술스택을 직접 선정하고 적용하는 역할이 필요했다.\n신규 프로젝트는 성격에 따라 두 가지 유형으로 나누어 진행했다.\n기존 레거시 시스템 내부에서 동작하는 신규 기능 개발 기존 시스템과 분리된 완전히 새로운 서비스 개발 각 유형의 특성과 리스크를 고려해 접근 방식과 기술 스택을 달리 선택했다.\n레거시 내부에서 동작하는 신규 기능 개발 #기존에도 레거시 시스템 내부에서 신규 기능 개발이 이루어지고 있었지만, 대부분은 기존 레거시 코드 스타일을 그대로 따르는 방식이었다. 그 결과 신규 기능임에도 불구하고 코드 품질은 레거시와 크게 다르지 않았고, 구조적인 개선 효과를 기대하기 어려운 상태였다.\n이러한 방식이 반복된다면 장기적으로 확장성과 유지보수성을 확보할 수 없다고 판단했다. 이에 따라 신규 기능을 레거시와 동일한 방식으로 개발하는 접근을 중단하고, 코드 구조와 개발 방식을 근본적으로 변경했다. 레거시 환경 안에서 동작하더라도, 신규 기능만큼은 명확한 구조와 기준을 갖춘 형태로 개발하는 것을 원칙으로 삼았다.\nFrontend는 Vue를 기반으로 개발을 진행했으며, TypeScript를 기본으로 사용했다. Backend는 Laravel을 활용해 API를 구현해 연동하거나, 레거시 시스템에서 데이터를 정리한 뒤 Vue 컴포넌트에 파라미터 형태로 전달하는 방식으로 구성했다. 레거시와의 공존을 고려해, 다음과 같은 방식으로 점진적인 적용을 시도했다.\n레거시 내 신규 페이지 개발 Frontend: Vite의 MPA 구성을 활용해 페이지 단위로 개발한 후 레거시 시스템에 적용 Backend: Laravel로 API를 구현해 연동 레거시 일부 영역 교체 (GNB, Footer 등) Frontend: Vite Module 방식을 이용해 특정 영역만 분리 개발 후 레거시 시스템에 적용 Backend: 빌드 결과를 레거시 시스템에 반영한 뒤, 컴포넌트에 가공된 데이터를 직접 파라미터로 전달하거나 Laravel로 구현한 API를 활용 이 과정에서 이후에 서술할 코드 표준, 정적 분석 도구, 포매팅 규칙, Docker 기반 개발 환경 등을 함께 도입했다. 이를 통해 팀 내부에서 반드시 지켜야 할 개발 기준을 명확히 했고, 시간이 지날수록 레거시 코드 내부에서도 점진적인 개선 효과가 나타나기 시작했다.\n이러한 변화는 타 부서에도 긍정적으로 인식되었으며, 다른 서비스에서도 동일한 방식으로 개발해달라는 요청이 이어졌다. 더 나아가, 이 접근 방식은 향후 다른 레거시 시스템에도 적용할 수 있도록 사업 계획에 반영되기도 했었다.\n완전 새로운 서비스 개발 #완전히 새로운 서비스 개발의 경우 기술 스택과 개발 방식은 비교적 자유롭게 선택할 수 있었다. 다만 팀 전체의 업무량이 많은 상황이었기 때문에, 업무 전환(Context Switching)에 드는 비용을 최소화하는 것이 가장 중요한 기준이었다.\n예를 들어 PHP 환경에서 Java나 Node.js와 같은 다른 언어로 전환하는 것과, PHP 기반에서 동일한 언어와 생태계를 유지하며 개발하는 것은 전환 속도와 안정성 측면에서 큰 차이가 있었다. 이러한 이유로, 팀이 이미 경험했던 Laravel을 신규 서비스의 기반 기술로 사용했다.\n신규 서비스 개발 시에는 다음과 같은 기준으로 진행했다.\nAPI 설계 Laravel 기반 API 개발 Route 규칙 내 버전 관리(V1, V2) 적용 API Key 필수 적용 신규 서비스 모놀리식(Monolithic) 구조로 개발 Laravel에 Inertia.js 기반 Vue (Typescript) 적용 - Frontend와 Backend를 하나의 프로젝트로 구성 특히 서비스 전체를 개발·운영하는 과정에서 관리 복잡도를 줄이기 위해, Frontend와 Backend를 물리적으로 분리하지 않고 하나의 프로젝트 내에서 동작할 수 있도록 하였다. 서비스 규모가 커지는 경우에는 Controller에 로직을 집중시키지 않고, Repository–Service–DTO 계층으로 분리해 개발함으로써 재사용성과 유지보수성을 확보했다.\n또한 팀 내부에서 반드시 지켜야 할 개발 기준을 명확히 하기 위해, 이후에 서술할 코드 표준, 정적 분석 도구, 포매팅 규칙, Docker 기반 개발 환경을 함께 도입했다. 이를 통해 신규 서비스 개발에는 표준을 지켜 개발할 수 있었다.\n개발 규칙 #팀에는 명확한 개발 규칙이 존재하지 않았다. Git을 사용하고는 있었지만 도입된 지 오래되지 않았고, 사실상 파일 백업 용도에 가까운 수준으로만 활용되고 있었다. 이 상태에서는 코드 품질 관리나 협업, 이력 추적이 어렵다고 판단했고, 개발 규칙을 정립하는 것을 가장 우선 과제로 설정했다.\n이에 따라 다음과 같은 기준과 도구를 단계적으로 도입했다.\n버전 관리 도구(Git) 운영 규칙 정립\nPull Request 및 코드 리뷰 프로세스 도입 Issue 및 Pull Request 템플릿(Markdown) 적용 Pull Request 승인(Merge Complete) 후 배포 진행 브랜치 생성 자동화 사내 관리자 \u0026gt; 업무 협조 프로세스에서 담당자가 요청 접수 시 Git 브랜치가 자동으로 생성되도록 기능 추가 브랜치 네이밍 규칙을 고정해 개발자가 브랜치 생성 시 고민하지 않도록 개선 신규 프로젝트 기준 코드 규칙 적용\nConventional Commit 규칙 적용 \u0026amp; 커밋 시 커밋 메시지 검사하는 Commitlint 도입\n커밋 시 정적 코드 검사 도입\n커밋 대상 소스코드 검사 실패 시 커밋이 되지 않도록 설정 Frontend(Vue): ESLint / Backend(Laravel): PHPStan 적용 / SCSS: Stylelint 도입 개발 환경 표준화\nDocker 기반 개발 환경 도입 Windows 환경은 WSL2 기반, macOS 환경은 colima 사용 에디터 설정 통일\n.editorconfig 적용 개발 도구와 상관없이 동일한 코드 포맷을 유지하도록 설정 이러한 규칙을 통해 개인별 개발 스타일 차이로 발생하던 문제를 줄이고, 팀 전체가 공통된 기준 위에서 개발할 수 있는 환경을 마련했다. 결과적으로 코드 품질과 협업 효율이 함께 개선되었고, 이는 신규 인원이 합류하더라도 빠르게 팀의 개발 방식에 적응할 수 있는 기반이 되었다.\n커뮤니케이션 #커뮤니케이션은 단순한 대화 수단이 아니라, 팀이 현재 무엇을 하고 있는지 서로 인지하고 있는 상태를 만드는 것이라고 생각했다. 이를 위해 팀 내에서 누가 어떤 업무를 하고 있으며, 작업이 어떻게 진행되고 있는지를 자연스럽게 공유할 수 있도록 커뮤니케이션 방식을 개선했다.\n사내 정책상 Slack과 같은 메신저를 사용할 수 없는 환경이었기 때문에, 개발팀 내부 커뮤니케이션 도구로 Google Chat을 사용했다. 제한된 환경 안에서도 최대한 실시간성과 가시성을 확보하는 것을 목표로 했다.\n기존 메신저 대신 Google Chat을 개발팀 메인 커뮤니케이션 채널로 사용 Google Chat 내 개발 이벤트 자동 공유 GitLab Hook을 Google Chat에 연동, Merge Request 생성, 코드 리뷰 댓글 등 주요 이벤트를 Google Chat으로 자동 전송 업무 인지 개선 Google Apps Script + Naver API를 활용해 업계 뉴스 및 참고 자료를 매일 아침 Google Chat으로 공유 추가로, 서비스 운영 안정성을 높이기 위해 사이트 오류 발생 시 즉시 팀에 공유되도록 했다. 레거시와 신규 서비스 구분 없이 오류가 발생하면 Google Chat으로 알림이 전송되도록 구성했으며, 이를 통해 팀원들이 빠르게 상황을 인지하고 원인을 파악해 조치할 수 있도록 했다.\n이러한 커뮤니케이션 개선을 통해 팀 내 정보 비대칭을 줄이고, 문제 발생 시 대응 속도를 눈에 띄게 개선할 수 있었다.\n업무 분배 #팀은 7~9명 규모로 구성되어 있었지만, 각 팀원의 강점과 성향은 모두 달랐다. 레거시 시스템에 강점이 있는 팀원, 신규 개발에 잠재력이 있는 팀원, 그리고 하나의 도메인에 집중할 때 가장 좋은 성과를 내는 팀원 등 다양한 특성이 존재했다.\n레거시 유지보수와 신규 개발을 동시에 수행해야 하는 팀 특성상, 기본적으로는 각자의 강점에 맞는 업무를 우선 배정했다. 다만 특정 업무에만 고착되는 것을 방지하기 위해, 역할을 유연하게 조정했다.\n레거시 유지보수를 주로 담당하는 팀원에게도 신규 개발에 참여할 기회를 제공해 업무 편중에 따른 불만을 최소화하려고 노력 신규 개발을 중심으로 일하는 팀원에게는, 신규 기능 개발을 위해 반드시 필요한 도메인 이해를 위해 레거시 개발을 병행하도록 구성 이를 통해 특정 인력이 레거시 또는 신규 개발에만 고정되지 않도록 하고, 팀원 모두가 레거시와 신규 개발을 모두 경험할 수 있는 구조를 지향했다. 이러한 업무 분배 방식은 개인의 성장과 팀 전체의 리스크 분산을 동시에 고려한 선택이었다.\n마치며 #돌이켜보면 2년이 조금 넘는 기간 동안 팀장으로서 레거시 위주의 팀에 변화를 시도해 온 시간이었다. 누군가는 이를 “달리는 기차의 바퀴를 갈아끼우는 일”에 비유했는데, 실제로도 그에 가까운 작업이었다. 운영을 멈출 수 없는 상황 속에서 레거시의 기술 부채를 하나씩 정리해 나갔고, 그 과정에서 레거시 환경에서도 충분히 개선이 가능하다는 자신감을 팀과 함께 만들어갈 수 있었다.\n물론 아쉬운 점도 몇 가지 있었다.\n배포 과정 자동화를 충분히 완성하지 못한 점 Jenkins를 활용해 Git Pull 기반의 배포 환경을 구성했지만, 일부 플러그인의 보안 취약성 문제로 사용 빈도를 낮출 수밖에 없었음 개인적인 업무 상황으로 인해 더 깊이 파고들지 못한 부분도 있어, 지금 돌아보면 가장 아쉬움 클라우드 플랫폼을 사용할 수 없어 도움받아 제대로 만들 수 있는 것도 만들지 못한 점 사용했다면 이미지와 동영상 처리 영역에서 더 나은 구조를 만들 수 있었을 것 같음 이미지: AWS S3, Lambda, CloudFront를 이용해 On-Demand Image Resizing을 활용한 포맷 및 사이즈 동적 처리 동영상: AWS S3, Lambda, Cloudfront, MediaConvert를 이용해 MP4를 스트리밍(HLS) 형태 변환 후 활용 컨테이너(Container) 기반 개발/운영 환경 구축: AWS ECS(Elastic Container Service) 사용 무엇보다 이 모든 변화는 내 윗분이자 실장님의 지속적인 지원과 이해가 있었기에 가능했다. 기술적인 시도와 방향성에 대해 믿고 맡겨주지 않았다면, 레거시 환경에서 이 정도의 변화조차 시도하기 어려웠을 것이다.\n마지막으로, 위에서 서술한 변화와 개선의 내용들은 이미 많은 회사에서 보편적으로 수행하고 있는 것들이기도 하다. 그렇기 때문에 이 글을 읽는 분들 중에는 “특별할 것 없는 이야기”라고 느끼실 수도 있을 것이다.\n다만 나에게 이 경험은, 레거시 위주로 운영되며 익숙해진 틀을 깨고 새로운 방식을 시도해 본 과정 그 자체에 의미가 있었다. 당연하게 여겨지던 관성과 한계를 넘어서기 위해 고민하고, 작은 것부터 순차적으로 도입해 나갔던 이 시간들은 앞으로 내가 더 나은 선택을 하고, 더 단단한 판단을 내릴 수 있게 해주는 중요한 밑바탕이 될 것이라 믿는다.\n이 경험은 분명 미래의 나를 성장시키는 데 있어 매우 값진 자산이 될 것이다.\n","date":"2025-12-14","permalink":"/posts/2025/12/team-leader-lookback/","section":"Posts","summary":"\u003cp\u003e전 회사에서 개발팀 팀장으로 근무했었다. 20년 넘는 오래된 레거시 시스템을 유지보수하면서 동시에 신규 프로젝트를 진행해야 하는 팀을 맡는다는 건, 시작부터 쉽지 않은 과제였다.\u003c/p\u003e","title":"전 회사 개발팀 팀장으로서의 역할 회고 - 나는 무엇을 했고 개선하려 노력했는가"},{"content":"","date":null,"permalink":"/tags/%ED%8C%80%EC%9E%A5/","section":"태그","summary":"","title":"팀장"},{"content":"","date":null,"permalink":"/tags/%ED%9A%8C%EA%B3%A0/","section":"태그","summary":"","title":"회고"},{"content":"전 회사에서 개발팀 팀장으로써 20년 넘게 축적된 레거시 청산과 교체 그리고 기술 개선을 해 왔다. 신규 사이트 및 API 개발은 현재 팀 그리고 회사에서 사용중인 기술개발스택을 고려해 결정 후 진행했다.\n레거시 위주의 업무와 신규 개발을 병행할 수 있도록 체질 개선을 했고, 코드 품질이 과거에 비해 많이 좋아졌다1. 또한 타 부서의 요구사항 또는 개발 도중 프로세스에 문제가 생겼을 시 적극적으로 피드백 및 개선을 하는 커뮤니케이션을 진행했고, 해당 부서도 만족할 수 있는 결과를 내려고 노력을 했고 과거에 비해 신뢰도가 높아졌었다.\n하지만, 새로온 기술 리더(임원)의 출근 2일차 발언이 모든 흐름을 한순간에 뒤집었다.\n“지금까지 해왔던 건 전부 무시하겠다. 내가 들은 걸로 판단하고, 내가 원하는 방식으로 바꾸겠다.”\n그 외 여러 변화가 있었고, 최종적으로 나는 퇴사를 결정했다.\n이 글은 퇴사이유 그리고 미래의 내가 타산지석으로 삼아야 할 것들에 대한 내용을 작성한 글이다.\n그리고 이 글은 특정 사람을 비난하려는 목적이 아니라, 기술 조직이 왜 붕괴하는지, 무엇이 조직을 흔드는지 공유하기 위한 기록이다.\n내용 #조직의 역사와 현 상황을 고려하지 않을 수 없음 #어느 조직이던지 합류하게 되면 업무를 어떻게 하는지, 어떻게 해야 하는지를 파악하는 온 보딩(On Boarding)을 거친다. 임원도 마찬가지이다. 온 보딩 이후 본격적으로 업무를 진행하며, 개선을 해 나가면서 조직이 발전하고 개인 또한 발전하게 된다 (물론 이를 받아들일 수 있는 조직이 발전하고 개인의 성취감이 높아진다).\n새로운 기술 리더는 오자마자 기존 기술 스택과 운영 구조 전부를 무시했다. 사실 기술개발 스택을 바꾼다는 건 문제가 되지 않는다. 문제는 오자마자 기술, 사람, 업무 방식을 이해하려는 노력 없이 기존을 전면 부정했다는 점이다.\n20년 넘는 서비스 운영 히스토리 도메인 지식 누적된 기술부채 개선 중이던 구조 레거시 처리 경험 이 모든 걸 \u0026ldquo;없던 것처럼\u0026rdquo; 할 수는 없다.\n기술 스택 전환 과정은 선언이 아니라 과정 #팀장으로 재직 시 PHP 레거시 외 신규 프로젝트는 Laravel + Vue (Inertia.js) + Docker 를 이용해 개발을 진행하고 있었고 이를 이용해 만든 서비스가 운영되고 있었다. Laravel을 사용한 이유는 기존 개발자들이 가장 빠르게 습득할 수 있는 프레임워크가 Laravel이였기 때문이였다.\n새로운 기술 리더는 오자마자 Laravel + Vue 기반에서 운영 중이던 서비스에 대해, Java로 전면 전환하겠다고 밝혔다.\n하지만 전환에는 최소 다음이 필요하다.\n도메인 분석 레거시 이해 단계적 마이그레이션 병행 운영 기간 성능/보안 문제 조직 교육과 문서화 그 어떤 단계도 준비되지 않은 상태에서 \u0026ldquo;전면 전환\u0026quot;은 기술 리스크가 아니라 사업 리스크이다.\n리더십의 첫 발언이 조직 분위기 결정 #\u0026ldquo;기존 다 무시하겠다\u0026rdquo;, \u0026ldquo;인턴도 파트장 할 수 있다\u0026rdquo;, \u0026ldquo;평가는 내가 새로 한다\u0026quot;와 같은 \u0026ldquo;무시\u0026quot;와 \u0026ldquo;불신\u0026rdquo; 발언은 개발자들에게 불안감을 가져오고 방어 모드로 들어갈 수 밖에 없을 것이다.\n역으로 생각하면 새로운 기술 리더는 기존 개발자들을 포함한 다른 부서 직원들에게도 업무 및 소프트 파워 능력을 인정을 받아야 한다. 이는 시간을 필요로 하는데, 그 시간없이 오자마자 저런 발언으로 볼 때 기존 직원들이 인정하고 따를 사람들이 누가 있겠는가.\n기술 판단보다 구조 개편 집중 #새로운 기술 리더는 오자마자 \u0026ldquo;파트장(실장급)도 내릴 수 있다\u0026rdquo;, \u0026ldquo;인턴도 파트장 할 수 있다\u0026rdquo;, \u0026ldquo;내가 판단해서 직책 정하겠다\u0026rdquo;, \u0026ldquo;내가 만든 양식에 일일 업무일지 작성\u0026rdquo; 와 같은 통제 방식을 내세웠다. 기술 방향에 대한 합리적 논의보다는 오자마자 구조 및 권한 개편이 중심이 된 것처럼 느껴졌다.\n개발자 동요 #결과적으로 위와 같은 일들 때문에 개발자들이 동요하기 시작했고, 이를 어떻게 할 수 없었다. 결과적으로 다른 두 분과 나는 퇴사를 하게 되었다.\n퇴사 #새로운 기술 리더가 온지 몇 주 만에 퇴사 절차가 이루어졌다. 새로운 기술 리더의 윗분인 대표이사(회장 바로 아래) 와의 퇴사면담에서 대표이사는 외주 개발 및 재입사 등을 제안했지만, 전부 거절했다. 대표이사는 연락하고 한달에 한번 만나서 저녁밥 먹자고 했지만, 진짜였다면 본인이 먼저 나섰을 것이다.\n마치며 #결과적으로 \u0026ldquo;더 이상 일할 수 없는 환경\u0026quot;이 만들어졌기 때문에 퇴사를 하게 되었다.\n위에서 서술했듯이 기술은 더 나은 방향으로 변경할 수 있고, 변경해야만 한다. 하지만 사람과 조직에 대한 존중이 없었으며 업무 이력과 프로세스를 무시하고 업무 히스토리를 무시한다면 어떤 기술도 조직을 발전시킬 수 없다. 결국 조직은 나아가고자 하는 방향으로 움직이지 못할 것이다.\n이것은 내 입장과 경험일 뿐 물론 그분에게도 나름의 판단과 이유가 있었을 것이다.\n내가 경험한 이 과정은 현재의 나보다 더 나은 리더가 되기 위해 반드시 거쳐가는 과정이라 생각한다. 언젠가는 이 경험이 나에게 크나큰 경험이 될 것이며, 매우 소중하게 쓰여질 것이다.\n정적코드분석(PHPStan, ESLint), 코드 포매터(Pretter), Git 커밋 메시지 포맷(Conventional Commmit) 도입, 코드 리뷰 진행\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-12-09","permalink":"/posts/2025/12/resign-lookback/","section":"Posts","summary":"\u003cp\u003e전 회사에서 개발팀 팀장으로써 20년 넘게 축적된 레거시 청산과 교체 그리고 기술 개선을 해 왔다. 신규 사이트 및 API 개발은 현재 팀 그리고 회사에서 사용중인 기술개발스택을 고려해 결정 후 진행했다.\u003c/p\u003e","title":"퇴사 - 나의 여정에서의 밑거름, 새로운 챕터를 열 기회를 맞이했다"},{"content":"","date":null,"permalink":"/tags/%EC%8B%A0%EC%9E%85/","section":"태그","summary":"","title":"신입"},{"content":"최근 몇년 동안 신입사원 교육을 진행했고 이를 위한 커리큘럼을 준비했다. 짧은 교육 기간이지만 도움이 되고자 매년 다르게 준비했는데, 올해 커리큘럼에는 AI 에 대한 기초 지식을 추가하였다.\n올해 준비한 내용 중 AI 내용은 아래와 같다.\n1. 개요 #AI(Artificial Intelligence, 인공지능)은 인간의 지능을 모방하거나 대체할 수 있도록 컴퓨터 시스템을 개발하는 기술이며, 기계가 학습(머신러닝), 논리적 추론, 문제 해결, 자연어 이해, 시각 인식 등의 기능을 수행할 수 있도록 하는 기술을 포함.\n2. 주요분야 # 분야 내용 머신러닝 (ML, Machine Learning) 데이터를 학습하여 패턴 인식하고 예측하는 기술. ex) 스팸 메일 필터링, 추천 시스템(넷플릭스, 유튜브) 딥러닝 (Deep Learning) 인공신경망(Artificial Neural Network, ANN)을 이용한 학습 방법. ex) 음성 인식(시리, 구글 어시스턴트), 이미지 인식(자율주행, 안면 인식) 자연어 처리 (NLP, Natural Language Processing) 인간의 언어를 이해하고 생성하는 기술. ex) 챗봇, 번역기(구글 번역, 파파고) 컴퓨터 비전 (Computer Vision) 이미지와 영상을 분석하고 이해하는 기술. ex) 얼굴 인식, 자율 주행 자동차 생성형 AI (Generative AI) 새로운 텍스트, 이미지, 음악 등을 생성하는 기술. ex) ChatGPT, 미드저니, 스테이블 디퓨전 3. 튜링테스트 (Turing Test) #1950년 엘런 튜닝이 기계가 인간과 얼마나 비슷하게 대화할 수 있는지를 기준으로 기계에 지능이 있는지를 판별하고자 하는 시험을 제안.\n질의자 하나와 응답자 둘을 준비, 응답자 중 하나는 컴퓨터, 나머지는 인간. 질의자는 어느 쪽이 컴퓨터인지는 모름 응답은 키보드로만 이루어지고 이 테스트에서 질의자가 어느 쪽이 컴퓨터인지 판별할 수 없다면 컴퓨터는 시험을 통과 즉, 컴퓨터가 인간처럼 대화할 수 있다면 그 컴퓨터는 인간처럼 사고를 할 수 있다고 보는 것 영화 “엑스 마키나 (Ex Machina)”가 이를 주제로 함.\n4. 인공신경망 (ANN; Artificial Neural Network) #인간의 시각/청각을 본떠 만든 알고리즘으로 인간의 뉴런 구조를 소프트웨어로 구현한 알고리즘. 이 뉴런의 이용해 심층학습(Deep Learning)이 이루어지며 출력이 다시 입력이 되어 시간에 따라 연속성 (사람으로 치면 기억력)을 가진 순환신경망 (RNN; Recurrent Neural Network) 이 제시됨.\n5. Attention Is All You Need #2017년 구글 브레인(Google Brain) 에서 Attention Is All You Need 라는 논문 (68481회 인용됨) 에서 순환신경망(RNN)의 느린 연산속도를 해결할 수 있는 트랜스포머(Transformer) 모델 소개.\nSelf-Attention(문장 내 단어들이 서로 어떤 관계가 있는지를 학습) 기반, 병렬화 가능 모델 Attention: 입력된 데이터 사이의 비슷함을 따져 정보를 모으고 이를 반복해 의미 있는 정보를 모으는 기술 Attention Is All You Need는 자연어 처리(NLP) 분야에서 혁신적인 전환점을 만들었고 이는 현재 인공지능 분야에서 대세로 자리잡아 사용되고 있음. 현재 ChatGPT와 같은 AI 모델의 핵심 기술로 사용.\n6. GPT #Generative Pre-trained Transformer 의 약자로 생성형 AI 모델. 트랜스포머(Transformer) 아키텍처를 기반으로, 자연어를 이해하고 생성하는 능력을 가지고 있음.\n6-1. 핵심개념 # 항목 내용 Generative (생성형) 단순히 입력을 이해하는 것이 아니라 새로운 텍스트 생성. ex) 질문에 답하기, 글쓰기, 코드 생성 Pre-trained (사전 학습) 인터넷에서 방대한 양의 텍스트 데이터를 학습한 후, 특정 작업에 맞게 추가 학습(미세 조정, Fine-tuning) ex) 기본 GPT 모델 → 법률 문서 요약, 의료 상담 등으로 추가 훈련 가능 Transformer (트랜스포머) “Attention Is All You Need” 논문에서 소개된 트랜스포머 구조를 사용. RNN/LSTM보다 빠르고, 긴 문맥을 잘 이해함. 핵심 기술: Self-Attention, Multi-Head Attention 6-2. 학습과정 # 항목 내용 사전 학습 (Pre-training) 인터넷의 방대한 데이터(책, 논문, 웹사이트 등)를 사용해 학습 단어 간 관계를 이해하고 문맥을 파악하는 능력 습득 미세 조정(Fine-tuning, 선택적 과정) 특정 목적(예: 고객 지원, 의료 상담)에 맞게 추가 학습. RLHF(인간 피드백 기반 강화 학습) 기법 사용 6-3. 주요특징 # 자연어 이해(NLU) + 생성(NLG) 가능 맥락(Context) 유지 능력 → 대화형 AI 가능! 추론 및 창의적 작업 수행 가능 → 글쓰기, 번역, 요약, 코딩 등 6-4. GPT 발전과정 # 버전 내용 GPT-1 (2018) 1.17 억개 파라미터 / 대규모 코퍼스를 활용한 사전 학습을 통해 언어 모델의 성능 향상 가능성을 제시 / 자연어 추론, 번역 등 다양한 작업에서 우수한 성능을 보임 GPT-2 (2019) 15억개 파라미터 / 이전 모델보다 10배 이상 큰 규모로, 텍스트 생성 능력이 크게 향상 문장 완성, 번역, 요약 등 다양한 작업에서 인간과 유사한 텍스트 생성 가능 GPT-3 (2020) 1750억개 파라미터, 대화형 AI 발전 / 매우 큰 규모의 모델로, 소수의 예시만으로도 특정 작업을 수행하는 능력 보임 코딩, 글쓰기, 질의응답 등 다양한 분야에서 활용 GPT-3.5 (2022) GPT-3의 개선 버전으로, 대화형 AI인 ChatGPT에 활용 / 더 자연스러운 대화와 향상된 이해력을 제공 GPT-4 (2023) 멀티모달 능력을 갖추어 텍스트뿐만 아니라 이미지 입력도 처리할 수 있음 / 이전 모델보다 향상된 추론 능력과 창의성을 보임 GPT-4.5 (2025) 2025년 2월 말에 발표된 최신 모델 / 이전 버전보다 환각(hallucination) 현상이 줄어들고 감성 지능이 향상 더 자연스러운 대화와 확장된 지식 베이스를 갖추었으며, 창의적인 통찰력을 생성하는 능력이 향상 / 수학적 문제 해결이나 코딩 능력에서는 일부 한계가 지적됨 7. 주요 용어 #7-1. 멀티모달 (Multimodal) #멀티모달(Multimodal)은 여러 유형의 데이터를 동시에 처리할 수 있는 AI. 즉, 단순히 텍스트만 이해하는 것이 아닌 이미지, 음성, 영상 등 다양한 입력을 함께 분석할 수 있는 기술\n텍스트 + 이미지 + 음성 등 다양한 데이터 동시 활용하여 더 풍부한 문맥(Context) 이해 가능, 사람처럼 다양한 감각을 조합해 더 똑똑한 AI 구현 가능\n모달 (Modal)\n모달(Modal)은 정보의 형태(모드, Mode)를 의미. ex) 사람이 정보를 받아들이는 방식 - 시각(이미지, 영상), 청각(음성, 소리), 언어(텍스트, 말) 하나의 모달만 처리하면 단일 모달(Unimodal) 여러 개를 동시에 처리하면 멀티모달(Multimodal) 사용예시\n사진을 업로드하면 그 안에 있는 사물 설명 그래프를 보여주면 데이터 분석 텍스트 설명을 입력하면 해당 설명에 맞는 이미지를 생성 음성을 텍스트로 변환, 텍스트를 음성으로 변환 활용분야\n의료 분야: X-ray 이미지를 분석하고, 환자의 진료 기록(텍스트)과 함께 종합적으로 진단 자율주행: 카메라(이미지) + 라이다(센서) + 지도(텍스트) 정보를 함께 분석 번역 및 접근성: 수화(영상) → 텍스트 변환, 시각 장애인을 위한 이미지 설명 AI 크리에이티브 AI: 텍스트 → 이미지/영상 생성 (예: DALL·E, Runway) 7-2. RAG (Retrieval-Augmented Generation) #정보 검색(Retrieval)과 생성(Generation)을 결합한 AI 모델. 외부 지식베이스에서 정보를 검색하여, 이를 활용해 더 정확한 응답을 생성하는 기술\n등장배경\nGPT 같은 대규모 언어 모델(LLM)은 훈련 데이터에 의존해 답변을 생성하나 단점 존재 최신 정보 부족: GPT-4 같은 모델은 사전 학습된 데이터까지만 알고 있음 / 최신 뉴스나 실시간 정보를 제공할 수 없음 환각(Hallucination): 존재하지 않는 정보를 만들어내는 경우 / 사실 검증 없이 “그럴듯한” 답변을 내놓는 경우가 많음 동작원리\nRAG는 “검색(Retrieval) + 생성(Generation)” 두 가지 과정을 결합 검색 단계 (Retrieval)\n- 질문을 받으면, 외부 데이터베이스(예: 위키백과, 논문, 문서 등)에서 관련 정보를 찾음\n- 예를 들어, “최신 GPT 버전이 뭐야?“라고 물으면, 인터넷에서 최신 정보를 검색하는 과정이 포함됨 생성 단계 (Generation)\n- 검색된 정보를 바탕으로 LLM이 응답을 생성\n- 기존 모델보다 더 정확하고 신뢰할 수 있는 답변을 제공할 수 있음 장점\n최신 정보 제공 가능: 검색을 통해 실시간 데이터 활용 더 신뢰할 수 있는 답변 생성: 환각 문제 줄이기 도메인 특화 가능: 특정 분야(법률, 의료 등)의 데이터베이스와 연결 가능 활용사례\nChatGPT + 웹 검색: ChatGPT가 웹 검색을 활용해 최신 정보를 반영하는 방식도 RAG의 원리와 비슷 기업 내 문서 검색 AI: 사내 문서, 매뉴얼에서 검색한 후 답변 생성 (예: Notion AI, Microsoft Copilot) 의료, 법률 분야 AI: 신뢰할 수 있는 논문이나 법률 문서를 검색하여 정확한 답변 제공 결론\n검색과 생성의 결합으로 더 정확하고 최신 정보를 제공 가능 7-3. 환각 (Halluciation) #AI가 사실이 아닌 정보를 생성하는 현상. 즉, 잘못된 정보, 존재하지 않는 사실, 그럴듯하지만 틀린 내용을 생성하는 문제\n특징\n그럴듯해 보이지만 틀린 정보 생성 사실 검증 없이 추론하여 답변 생성 특히 숫자, 고유명사, 코드 생성에서 오류 발생 가능 발생원인\nLLM(대규모 언어 모델)의 본질적인 한계\n- GPT 같은 모델은 통계적으로 가장 적절한 다음 단어를 예측하는 방식\n- 하지만 단어 예측은 정확한 지식을 보장하는 게 아님\n- 즉, 학습 데이터에 없는 내용이라도 “가장 가능성 높은 답변”을 만들어내려는 경향이 있음 최신 정보 부족\n- 모델이 사전 학습된 데이터까지만 알고 있기 때문에, 최신 뉴스나 업데이트된 정보를 반영하지 못하고, 그럴듯한 답변을 생성할 수 있음\n- 예: “GPT-5는 2024년 7월 15일 출시되었습니다.” (사실이 아닐 수도 있음) 제한된 문맥 길이(Context Length)\n- AI는 긴 문서를 처리할 때, 일부 내용을 잊어버릴 수 있음\n- 그러면 문맥을 잃어버리고, 틀린 답변을 생성할 가능성이 커짐 예시\n사실과 다른 정보를 생성 - “네덜란드의 수도는 베를린입니다.” (정답: 암스테르담) 존재하지 않는 책이나 논문 인용 - “이 논문은 2022년 John Doe가 ‘AI 미래’에서 발표한 내용입니다.” (존재하지 않는 논문일 가능성이 큼) 잘못된 코드 생성 - I가 엉뚱한 코드나 실행되지 않는 코드를 만들어낼 수 있음 환각 줄이는 방법\nRAG (Retrieval-Augmented Generation) 활용 - 외부 지식 검색을 추가하여 사실 기반 응답 생성 (예: ChatGPT 웹 검색 기능) 인간 검토(Human-in-the-loop) - AI가 생성한 답변을 사람이 검토하여 오류를 걸러내는 방식 신뢰할 수 있는 데이터로 학습(Fine-tuning) - 특정 도메인(의료, 법률 등)에서는 정확한 데이터를 추가 학습하여 오류를 줄일 수 있음 결론\n환각은 AI 모델이 “그럴듯한” 답변을 만들어내면서 발생하는 문제\n- 검색 기반 AI(RAG) 및 인간 검토를 통해 줄일 수 있음\n- AI의 답변을 맹신하지 않고, 항상 검증하는 것이 중요! 8. 주요 서비스 # 업무: 문서 작성, 이메일 초안, 데이터 분석 (ChatGPT, Notion AI, Grammarly) 콘텐츠 제작: 이미지·동영상·음성 생성 (DALL·E, Runway, ElevenLabs) 코딩: 코드 자동 완성, 버그 수정 (GitHub Copilot, Codeium) 검색 \u0026amp; 정보: AI 기반 최신 정보 검색 (Perplexity AI, You.com) 번역 \u0026amp; 다국어 지원: 자연어 번역 (DeepL, Papago) ","date":"2025-03-03","permalink":"/posts/2025/03/rookie-training-ai-basic/","section":"Posts","summary":"\u003cp\u003e최근 몇년 동안 신입사원 교육을 진행했고 이를 위한 커리큘럼을 준비했다. 짧은 교육 기간이지만 도움이 되고자 매년 다르게 준비했는데, 올해 커리큘럼에는 AI 에 대한 기초 지식을 추가하였다.\u003c/p\u003e","title":"신입사원 교육 - 인공지능 (AI) 기초지식 요약 정리"},{"content":"약 3년전쯤 Laravel에서 사용할 게시판을 패키지로 구현한 후 바쁘다는 핑계로 방치해두고 로직 구현만 참조하고 있었다. 그런데, 올해 중순 경 어느 개발자 한 분이 패키지가 오래되어 설치가 되지 않아 정상동작하는 버전이 있는지 문의를 했었고 없던 관계로 나도 겸사겸사 사용할 목적으로 새로 구현한 후 회신하였다.\n그래서 지난번과 달라진 점 / 어떤 부분들을 수정했는지 간단히 정리 후 복기(復棋)1 해보고자 한다.\n주요 변경사항 #1. 스캐폴딩(Scaffolding) 형태로 변환 #기존 게시판은 게시판 로직 자체가 패키지 내부에 정의되어 있어 소스코드를 개발자가 직접 수정하여 사용할 수 없었다2. 생각해보면 그 당시 게시판을 만들 때 각 사이트별로 요구하는 바가 달라 커스터마이징이 가능해야 하는 점을 생각하지 못했었다. 또한 Laravel용 패키지를 만드는 공부를 겸했기 때문에 어떻게 해결해야 할지도 몰랐던 것 같다.\n그래서 이번 구현에서는 스캐폴딩(Scaffolding)3 형태로 제작하여 명령어를 통해 게시판 CRUD4 샘플 코드를 개발자 프로젝트에 Publish 해주는 역할만 하도록 하였다.\n2. API 형태로 구현 #기존 게시판은 view 구현을 포함하였으나 참조했던 적이 없어 이번에는 API 형태로 구현하였다.\n2-1. Authentication #게시판을 API형태로 구현함에 따라 사용자 인증을 Stateless5 형태로 변경하였다.\n스캐폴딩으로 코드를 생성(샘플코드)해주는 점을 생각해 별다른 구현 없이 사용 가능하고(Laravel에서 기본제공) 가장 간단한 email:password 형태를 base64 인코딩하여 사용하는 Basic Authentication을 적용하였다.\n회원 정보: Laravel 제공해주는 기본 테이블 사용 POST, PUT, DELETE method 에 대해서만 Basic Authentication 적용 2-2. Role #간단한 형태로 구현하고자 게시판 사용자 역할은 별도로 두지 않았다6.\n2-2. Versioning #API 구현으로 변경하며 URL에 Version을 삽입하였다 (ex. /api/v1/board/free의 v1)7.\nCommand #패키지 설치 후 게시판 스캐폴딩 코드를 Publish 해주는 명령어를 추가하였다. 자세한 내용은 inium/laraboard의 README.md \u0026gt; 2. Publish files \u0026amp; Append routes에 기록하였다.\n문서화 #패키지 개발완료 후 사용방법 등을 기록한 내용을 inium/laraboard의 README.md에 기록하였다. 또한 구현한 API에 대한 문서를 REST Client 를 이용해 REST API 형식으로 기록하였다.\n결과 #약 2주간 구현 및 수정을 완료했고 Github, Packagist에서 참조할 수 있도록 하였다.\n마치며 #작년 여름, 어느 개발자의 요청으로 게시판 패키지를 단순화 및 개선을 하였고 그 결과를 해가 바뀌고 돌아보았다.\n처음 구현은 게시판에 필요한 많은 것을 구현하려고 했는데 개선하면서 복기를 해 보니 부끄러울 정도로 구조 및 구현이 마음에 들지 않았다. 그래서 이번에는 게시판에 필요한 최소 기능만 구현한 후 개발자가 원하는 대로 필요한 코드를 스캐폴딩해주는 식으로 변경하였다.\n돌아보면 지난번에 비해 많이 나아진 것 같으나, 시간이 지나면 이 또한 부끄러움이 될 것 같다. 생각해보면 이 과정을 통해 발전을 하는게 아닌가 싶다.\n요청주신 어느 개발자분 덕분에 나 또한 돌아보고 개선 항목들을 추릴 수 있었으며 그것들을 이번 구현에 반영할 수 있어 감사하다는 말을 하고 싶다. 현재 약 6개월 정도 지난 시점에서 수정해야 할 부분들이 많이 보이는데, 향후 이를 포함해 코드 리펙토링, 테스트 코드를 구현하여 추가해보고자 한다.\n바둑 대국이 끝난 뒤, 해당 대국의 내용을 검토하기 위하여 두었던 순서대로 다시 두어보는 일\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n패키지 자체를 수정하면 사용 가능하긴 함\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n초기 프로젝트의 뼈대를 만들어주는 행위를 뜻한다. 명령어를 입력하면 어플리케이션 내 코드 생성을 해준다. 건축에서 가져온 비계(飛階)라는 단어 (작업자들이 임시로 외벽을 지나다닐 수 있도록 만든 임시 구조물) 에서 유래했다.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nCreate, Read, Update, Delete\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n사용자 인증 상태를 서버에서 유지하지 않고 요청(request)시 유효한 사용자인지 여부를 판단하는 방법. Request header에 주로 Authentication 항목에 token을 입력하여 사용하며 OAuth2, JWT, Basic 등의 방법이 있다.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n추후 게시판 역할 추가 시 Laravel에서 제공하는 Gate or Policy, 혹은 spatie/laravel-permission와 같은 패키지를 사용하는 것을 고려해 볼 수 있을 것 같다.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n버전을 명시하는 방법에는 여러가지 방법 중 Request Body 내 버전을 명시하는 방법도 고려해 보았으나 URL에 버전을 명시하는 것이 더 간편하다고 판단하였다.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2023-01-08","permalink":"/posts/2023/modify-laravel-board-package/","section":"Posts","summary":"\u003cp\u003e약 3년전쯤 Laravel에서 사용할 게시판을 패키지로 구현한 후 바쁘다는 핑계로 방치해두고 로직 구현만 참조하고 있었다. 그런데, 올해 중순 경 어느 개발자 한 분이 패키지가 오래되어 설치가 되지 않아 정상동작하는 버전이 있는지 문의를 했었고 없던 관계로 나도 겸사겸사 사용할 목적으로 새로 구현한 후 회신하였다.\u003c/p\u003e","title":"회고 - Laravel 게시판 패키지 수정"},{"content":"2022년이 얼마 남지 않아 올해 있던 일 중 몇 가지를 되돌아보고 정리해보고자 한다.\n비온 뒤 땅은 굳는다 #전 회사가 신규 사업을 진행했으나 신사업 담당 인원들 전부 권고사직을 했다는 이야기를 들었다.\nCTO를 뽑고 그 분이 개발자를 데리고와 3개월만에 론칭 후 5개월가량 잘 운영하는 것처럼 보였으나, 결국 8개월만에 좋지 않은 결말이 되었다.\n나도 매우 초반에 참여했던지라 이 소식을 듣고 충격을 받았는데 3년 가까운 시간동안 재직하신 분이 대표들의 지시로 신사업으로 이동한지 한달만에 권고사직을 당해 충격이 더 컸다. 그리고 CTO가 데리고온 개발자들의 원성이 심했다는 이야기를 들었다.\n3개월만에 기본인 것들을 포함해 많은 부분이 구현되지 않고 론칭했다는 걸 볼 때 대표들이 후속 투자를 염두하고 무리하게 진행하지 않았나 싶다 (결국 후속투자가 실패했다는 이야기를 들었다).\n슬프지만 시간은 냉정히 지나갈 것이고 비온 뒤에 땅은 굳을 것이지만 권고사직 통보를 몇 단어로 끝냈다고 한 점에서 사람을 대하는 태도에 실망과 아쉬움이 남았다 (비록 직접 겪은 것은 아니지만). 그리고 항상 그렇듯이 일은 사람이 하기 때문에 사람, 동료가 중요하다는 것을 다시 한번 생각하게 되었다.\n누군가에게 도움이 되었다 #올해는 전혀 모르는 분들과 연이 닿았다. 모르는 곳에서도 겸손하게 행동해야 한다는 생각은 항상 들었지만 올해는 더욱 그러함을 느꼈고 내년에는 무겁게 받아들여야 하지 않을까 싶다.\nEp 1. 코드 도와달라고 한 분이 계셨다 #몇년 전, Laravel용 게시판을 패키지로 만든 후 (귀찮다는 핑계로) 업데이트를 하지 않고 필요할 때마다 참고용으로 사용하고 있었다.\n그런데 올해 중순 경, 어느 한 개발자께서 내 Github을 보고 이 코드가 예전 버전 기반으로 만들어져 동작이 하지 않아 동작하는 소스코드가 있는지 문의하는 메일을 받았다. 동작하는 코드는 없어 최신 버전(Laravel 9.x) 으로 업데이트 해주겠다는 답신을 보냈고, 회사업무 / 개인 일정 포함 약 2주간 전부 새로 개발하여 회신하였다. 이후 정상 동작하며 감사하다는 답신을 받았다.\n개인적으로 참고하려고 만든 코드라 크게 신경쓰지 않고 있었는데 누군가에게 도움이 되어 신기하고 한편으로 뿌듯했다. 그리고 업데이트 하며 예전에 짜놓은 코드를 보니 나의 흑역사를 보는 것 같아 부끄러웠지만 이 과정에서 내가 발전했는지 그리고 그 당시 무슨 생각을 했는지 복기를 할 수 있어 나 역시 많은 도움이 되었다 (+ 덕분에 게시판 코드 버전도 메이저 버전으로 업데이트 할 수 있었다).\nEp 2. 면접때 나하고 일하고 싶다는 분이 계셨다 #나하고 같이 일을 하고 싶다고 말한 지원자가 있었다는 이야기를 면접을 진행했던 분들을 통해 들었다. 전혀 알지 못하는 분이여서 무슨 일인가 싶어 좀 더 이야기를 들어보니 내 블로그와 Github을 보고 같이 일하고 싶다고 했다. 이 또한 신기했고 한편으로는 감사했다.\n결국 이 분은 채용이 되지 않았지만 같이 일을 했었다면 어떠했을까 싶다.\n개인의 발전 #개인의 발전은 회사 업부보단 개인 프로젝트와 구인/구직을 진행하는 분들과의 대화를 통해 발전을 했던 것 같다.\n회사 업무 #회사 업무에서 발전은 레거시가 대부분인지라 개발 측면에서는 기대할 수는 없었던 것 같다. 대신 개발 관련된 아이디어, 노하우와 비즈니스 측면에서 어떤 면을 고려해야 하는지(특히 돈을 벌어야 하는 부분) 에 대해 생각할 수 있는 계기들이 있어 이에 대한 도움이 되었던 것 같다.\n개인 프로젝트 #Layered Architecture -Repository, Service, DTO- 를 Laravel에 구현하고 적용하며 Java(Struts, Spring Boot), Node(Nestjs)에 적용된 BO, DAO, VO, DTO, Bean, Entity 개념을 많이 참조하였다. 이 과정에서 지속성있는 코드를 위해 이런 컨셉들이 나왔고 사용되었는지 다시 한번 생각해 볼 수 있었다.\n그리고 이와 같은 구조가 필요에 따라 필요한지 / 하지 않는지 결정할 수 있는 눈을 키우는 것이 중요하다는 생각이 들었다. 규모가 크다면 이와 같은 구조를 고려해야겠지만 크지 않으면 구지 사용할 필요는 없을 것이다. 닭잡는 데 소잡는 칼을 사용할 이유가 없는 것과 같다.\n이 과정에서 구현한 결과물을 패키지화 해볼까 한다.\n마치며 #언제나 그랬듯 많은 일들이 있었고 아쉬운 한 해였다. 누군가에게 도움이 되었던 경험이 개인적으로 인상적이였기 때문에 내년에도 누군가에게 도움이 될 수 있었으면 좋겠으며 꾸준한 학습을 놓지 않고 기록을 하며 공유를 하는 것을 목표로 하고자 한다. 또한 올해는 누군가에 의해 끌려가는 시간이 많았던 것 같았는데 내년에는 내 위주의 시간을 보낼 수 있도록 실행해야 겠다.\n","date":"2022-12-24","permalink":"/posts/2022/12/lookback/","section":"Posts","summary":"\u003cp\u003e2022년이 얼마 남지 않아 올해 있던 일 중 몇 가지를 되돌아보고 정리해보고자 한다.\u003c/p\u003e","title":"2022년을 마무리하며 (회고)"},{"content":"회사를 떠나고 다른 곳으로 가기 위해 면접과 채팅을 나눠보았다. 좋은 경험도 있었지만, 그렇지 못한 경험도 있었으며 어떠했는지 간략하게 개인적인 느낌을 적어보려고 한다.\n개발스택 #Backend 개발로 인터뷰를 진행했으며, 개발 스택은 크게 Docker, PHP (Laravel - Repository, Service), Node (Express, Nest), MySQL, Vue, Git 그리고 AWS 였다.\n인터뷰, 플랫폼에서의 제안에서 PHP 보단 Node를 요구하는 곳이 많았으며, AWS는 어떤걸 사용해 보았는지 물어보는 수준이였다. PHP는 현실적으로 안좋은 인식과 Laravel 개발자 Pool이 적은 점, Node는 많은 곳에서 사용하는 점, 클라우드는 회사가 시간 / 비용 등을 고려해 선택하기 나름이라고 판단했다.\nJob Interviews #4 곳의 회사와 이야기를 나누었다.\n1. 대기업 자회사 #지인 추천으로 대기업 자회사에 면접을 보게 되었다. 회사 환경은 괜찮았다. 면접은 괜찮게 진행되었으나, 팀, 협업 경험, 개발 스택에 대한 질문이 이루어졌다. Node 개발이였다.\n질문과 다른 방향의 답변으로 할 때 비꼬는 말투로 답을 하는 면접관이 있었다. 생각해보니 기분 나쁘게 면접자에게 답변하는 것은 개인적인 경험으로는 면접관의 잘못이라고 생각한다. 면접자가 긴장 할 수 있는 상황인데, 면접관이라면 긴장을 완화시켜주어야 한고 생각한다. 아래 서술할 분과 비교가 되었다.\n면접에서 느낀 점은 무언가 공무원 조직과 비슷하다는 느낌이였다. 공무원 조직에 몸을 담았던 적이 있어 느낌이 비슷하다는 생각이 들었다. 기획자로써의 역할도 했나는 답변을 받았을 때 철저히 분업화를 하는 듯한 느낌이 들었다. 개발할 때 기획에서 무언가 잘못하면 피드백을 주어 의견을 물을 수 있고 의견을 낼 수 있다고 생각하는데, 이것에 대해 부정적으로 보는 듯했다. 즉 개발자는 군말없이 개발만 해야 한다는 느낌을 받았다. 지인도 비슷한 이야기를 했다.\n확실한 숫자는 기억나지 않지만, Frontend 4명, Backend 4명, 본부장 1명 그리고 인프라(AWS) 담당 1명으로 구성되어 있다는 이야기를 들었다. 개발 인원 구성으로만 볼 때 조금 규모 있는 스타트업 정도로 보였다.\n결국 이 곳에서 합/불에 대한 답을 듣진 못했다.\n2. 2번째 면접을 본 한국에서 큰 규모의 커머스 중 한 곳 #링크드인을 통해 인사담당께서 면접 제안을 해서 고민을 하다 보게 되었다. 사실 몇년전 이곳에서 기술 면접을 통과하고 다른 곳에 가게 되어 2차 면접을 안보았다는 이야기를 인사담당께 이야기를 했으나, 이전 면접 결과도 좋고 다시 면접 보아도 불이익은 없다는 답변을 받아 보게 되었다. PHP 개발이였다.\n1차로 예전에 없던 코딩테스트를 보았다. 2시간동안 5문제 푸는 문제였고 긴장을 했던 탓인지 2문제는 주석으로 썼고 3문제는 풀었다. 이후 기술 면접을 보았는데, 몇년전 면접을 보신 분을 다시 뵙게 되었으며, 이 분께서는 긴장을 많이 풀어주시려 했고 답변을 잘못 했을 경우 좋은 말로 방향을 바꿔서 다시 질문해주셨다. 이 점은 굉장히 본받고 싶은 부분이였다. 위에서 언급한 면접관의 모습과는 정 반대였다.\nLaravel Service Provider, Service Container 에 대한 질문, 대규모 트래픽에 대한 대응, CTO가 되었을 때 어떻게 할 것인가 등등을 물어보았는데 긴장을 많이 해서 제대로된 답변은 하지 못한 것 같다.\n면접 이후, 퇴근 시간이 지났음에도 그날 인사팀에서 전화로 합격했다는 말을 했는데, 면접때 제대로 말을 하지 못해서 사실 아직까지도 왜 합격을 했는지 궁금하긴 하다. 개인적으로는 PHP Laravel 개발자 Pool이 적어서 그러지 않을까 싶다.\n질문으로 왜 아직도 PHP를 사용하냐고 물어보았는데, 답변으로 PHP, Java가 같이 사용되어 동작할 수 있다는 암묵적인 합의가 존재한다는 답변을 받았으며 이 점이 굉장히 인상깊었다. 말 그대로 언어는 도구일 뿐이라는 것이다. 개인적으로 언어는 도구일 뿐이라고 생각하지만, 현실은 그렇지 않기에 이 말이 더 와닿았다.\n최종적으로, 이 곳 2차 컬쳐 면접 일정을 잡았지만 다른 곳으로 가게 되어 또 거절하게 되었다. 인사팀 담당자께 전화로 죄송하다는 말씀을 드렸고, 그분도 아쉽다는 (아마도 형식적이였겠지만) 답변을 받았다. 면접 경험은 좋았지만, 이곳보다 더 많은 것을 내 주도로 할 수 있는 곳으로 가는 것으로 결정하였다.\n3. 문자로 대화를 나눈 모 스타트업 #리멤버를 통해 제안해온 스타트업이였다. 공유오피스에 입주하고 있으며, 문자로 내가 만든 코드가 구조가 매우 잘 잡혀 있다는 칭찬을 해 주셨다. Github 코드를 보고 말씀해주셨는데, 내가 만든 코드를 외부분께 평가받았고 구현하는 방향은 맞는 것 같아 기분이 좋았지만 한편으로는 Github 업데이트를 너무 안해 부끄러웠다.\n이미 다른 곳으로 가게 되었기 때문에, 이후 면접은 진행되지 않았다.\n4. 화상인터뷰한 모 스타트업 #이미 다른 곳으로 가게 된 상태에서 로켓펀치를 통해 연락을 해 온 스타트업이였다. 이곳 프로필 업데이트를 오랫동안 안해 구인 하는 회사 입장에선 메리트가 없는 기술개발 스택이였다. 그래서 사실대로 개발자가 구하기 힘들어 연락 한 것 같다고 물어보았는데, 답변으로는 PHP 개발자를 찾고 있고 Node로 전환할 계획이라고 받았으며, 적합한 것 같아 이야기를 나눠보고 싶다고 하셨다 (로켓펀치엔 Node를 작성하진 않았다).\n게더타운을 통해 인터뷰를 진행했고, 20분정도 간단한 인터뷰 겸 대화를 나눴다. 로켓펀치에 이력서 업데이트가 오랫동안 이루어지지 않았고, 최근엔 Laravel과 Node로 개발을 진행했다는 이야기를 했을 때 기술이 너무 딱 맞고 아쉽다는 듯한 말씀을 해 주셨다. Laravel에서 Node로 전환하는 이유를 물어볼 때, Laravel 오래된 버전을 사용하고 있고 (5.x) 개발자 Pool이 적다는 말씀을 해 주셨다.\n현재 나의 상황에 대해 솔직하게 말을 했다. 이미 다른 곳으로 가게 되어, 이 곳에 대한 이야기도 나누었다. 나중에 연락 주신다고 하셔서 혹시 몰라 로켓펀치 채팅으로 연락처를 드렸다.\n이곳의 첫 느낌은 젊고 좋은 회사라고 느꼈으며, 앞으로도 발전을 할 수 있을 것 같다는 생각이 들었다.\n결론 #이상 개인적인 인터뷰 후기였다. 면접관이 된다면, 면접자의 긴장을 풀어주는 것과 답변 방향이 잘못되었을 때 올바른 방향으로 부드럽게 넘어갈 수 있는 소프트 스킬이 필요하다는 생각이 들었다.\n나에게 온 제안과 면접 과정에서 느낀 건, 언어는 언어일 뿐이지만, 현실적으로 PHP는 현실적으로 좋지 않은 인식이 존재하고 Laravel 개발자는 구하기 힘든 점, Node 개발자 수요는 많았다. 제안이 온 기술스택 대부분이 Node 였다. 이제서야 현실을 인식하게 된 것 같다.\n2번 면접을 보고 1차 모두 합격시켜준 회사에게는 죄송하다는 생각이 들었다. 매우 좋은 회사이고 커리어를 쌓아갈 수 있지만, 최종적으로는 더 많은 부분에서 적극적으로, 주도적으로 참여하고 리빌딩을 할 수 있는 곳으로 가는 것을 선택했다. 아직까지는 회사의 규모보단 내가 더 많은 역할을 할 수 있는 곳이 더 좋아 선택하였다. 커리어를 망칠지도 모르지만 그건 그때 생각하려고 한다.\n","date":"2022-05-01","permalink":"/posts/2022/05/job-interview-lookback/","section":"Posts","summary":"\u003cp\u003e회사를 떠나고 다른 곳으로 가기 위해 면접과 채팅을 나눠보았다. 좋은 경험도 있었지만, 그렇지 못한 경험도 있었으며 어떠했는지 간략하게 개인적인 느낌을 적어보려고 한다.\u003c/p\u003e","title":"Job Interview 후기"},{"content":"","date":null,"permalink":"/tags/%EC%9D%B8%ED%84%B0%EB%B7%B0/","section":"태그","summary":"","title":"인터뷰"},{"content":"","date":null,"permalink":"/tags/%ED%9B%84%EA%B8%B0/","section":"태그","summary":"","title":"후기"},{"content":"","date":null,"permalink":"/tags/%EA%B3%A0%EB%8F%84%EB%AA%B0/","section":"태그","summary":"","title":"고도몰"},{"content":"고도몰5 Pro 기반으로 제작된 자사몰(이하 고도몰)을 빠져나오는 것을 목표로 했지만 현실적으로 고도몰 기능추가 / 유지보수를 담당하게 되었다. 이 글은 지난 1년간 담당했던 고도몰의 기능개발 / 유지보수를 하며 개발자 관점에서 느낀 점이다.\n고도몰은 무엇인가 #고도몰은 국내 인터넷 쇼핑몰 호스팅 업체로 결제 후 몇 가지 설정을 통해 쇼핑몰을 바로 구축할 수 있도록 제공하는 솔루션이다. 경쟁업체로 카페24, 메이크샵, 글로벌 업체인 쇼피파이가 있다.\n장점 / 단점 #고도몰을 이용하면 손쉽고 빠르게 쇼핑몰을 구축할 수 있고 매출을 빠르게 만들 수 있다. 문자, 마케팅, 앱 등 부가서비스 등이 무료 혹은 유료로 제공되며 손쉽게 사용할 수 있다. frontend / backend 모두 직접 개발할 수 있도록 제공해주며, 호스팅 서비스이기 때문에 서버 관리도 담당해준다.\n하지만 고도몰 소스코드의 품질은 좋지 않아 유지보수가 힘들며 개발 가이드 문서 또한 부실하다. 예상치 못한 고도몰의 코드 및 서버의 잦은 이슈(Issue)로 인해 매출에 손해가 발생하는 경우가 다반사다. 이를 문의해도 수정할 것이란 답변이 있을 뿐 실제 수정되지 않은 경우가 많다.\n개발하며 느낀 점들 #고도몰이 비즈니스 입장에서는 손쉽고 빠르게 쇼핑몰을 구축할 수 있어 매출을 낼 수 있다는 큰 장점이 있지만, 매출을 내기 위한 기능 추가 / 유지보수는 힘들다. 고도몰을 개발하며 개인적으로 느낀 점들을 정리하면 아래와 같다.\n1. 개발 환경 #고도몰5 Pro의 frontend, backend는 아래와 같이 개발한다. 사실 frontend / backend 가 명확히 구분되지 않는 구조이나, 편의상 분리하였다.\nfrontend(스킨): 워드프레스 스킨과 유사하게 개발. 관리자 페이지에서 개발 or 로컬에서 개발 후 ftp 업로드, 테스트, 배포. 렌더링 엔진은 템플릿언더바(template_) 기반. 고도몰에서 Widget 이라고 부르는 컴포넌트 같은 기능 제공. backend: PHP 7 기반(고도몰5) 으로 구현된 자체 프레임워크. 필요한 기능은 상속받아 구현, 상속받지 않으면 자체 프레임워크 Core 코드 동작. 로컬개발 불가. ftp 업로드 후 테스트, 배포. composer를 이용한 패키지 직접설치 불가. 정리하자면, 사실상 서버에서만 개발 / 테스트를 할 수 있도록 되어 있다. 개인적인 경험으로는 개발 시간과 유지보수를 위한 디버깅을 하는데 로컬 개발, 배포에 비해 시간이 늘어났으며 늘어날 수 밖에 없다는 생각이 들었다.\n2. 코드 품질과 부실한 개발문서 # 훌륭한 소프트웨어의 기능은 복잡한 것을 간단하게 보이게하는 것입니다. - 그래디 부치\n고도몰5 Pro 기준으로, 소스코드를 분석하고 구현하면 위의 인용구가 생각난다. 고도몰에서는 고도몰5 개발 가이드 라는 문서를 공개하고 있으나 큰 도움이 되지 않았다.\n3. Side Effect #고도몰의 장점 중 하나는 기능 오류나 수정이 필요한 패치를 제공해준다는 점이다. frontend는 스킨 패치 라는 것으로 제공하고, backend 코드는 고도몰이 직접 본인들의 core 코드를 수정한 후 적용한다.\n문제는 이 패치 과정, 고도몰에서 수정해서 배포하는 frontend / backend 패치 이후 예상치 못한 Side Effect(부작용, 또다른 오류) 발생이 있는 편이다. 자사몰에 특화된 기능들이 이로인해 오류가 발생하는 경우가 발생하기도 하며, 고도몰 기본 기능 또한 오류가 발생하기도 한다.\n이러한 리스크가 발생할 가능성을 항상 인지하고 있어야 했으며, 수정이 필요한 경우 최대한 빠르게 수정을 진행해야 했다.\n4. 버전관리 #ftp를 이용해 배포하기 때문에, 사실상 개인이 소스코드를 별도로 관리하는 수 밖에 없다. 그래서 ftp에 올라온 파일 버전과 버전관리로 관리되는 파일 버전이 다른 경우가 종종 발생하였고 발생할 수 밖에 없었다.\n이러한 불편을 해결하고자 배포 프로세스를 구축하려 했으나, 결정적으로 배포 과정 구축 시 기존 운영 코드를 잘못 건드릴 경우 서비스에 매우 큰 문제를 (중단, 복구 오랜 시간 소요 등) 야기할 수 있다고 판단되어 적용 하지 않았다.\n최종적으로, 개발 결과물을 Git을 이용해 버전관리를 하기도 했지만 이와 별개로 주기적으로 frontend / backend 코드를 백업받아 적용하였다.\n5. 확장성 #확장은 가능하지만 번거롭다. 패키지 매니저 사용이 불가능하기 때문에 필요한 패키지가 있으면 직접 ftp를 이용해 업로드한 후 사용하는 수밖에 없었다.\n이 확장 과정을 고도몰에서는 이를 \u0026ldquo;튜닝\u0026rdquo; 이라는 단어로 부르며 이들을 전문적으로 해주는 업체들이 존재한다. 개인적인 경험으로 어떤 업체가 튜닝한 코드를 보았는데, 코드 품질이 기본도 되어 있지 않아 이를 수정하여 사용하는데 어려움이 있었다. 튜닝 업체를 사용할 경우 어느정도 리스크가 발생할 수도 있을 것 같다는 생각이 들었다.\n추가로, 고도에서 제공하는 코드가 아닌 React / Vue를 고도몰 페이지 일부 영역에 적용할 계획이라면 신중히 생각해야 한다. 이 곳에서 오류가 발생할 경우 찾고 수정하여 번들링하고 스크립트 업데이트 하고 확인하는 과정이 기존 고도몰 코드보다 훨씬 복잡하다.\n그리고 \u0026hellip; #개발과 연관은 있지만, 고도몰이 가지는 문제로 인해 개발에 애로사항이 생겼던 점을 정리하면 아래와 같다.\n1. 주체 #쇼핑몰 호스팅이라 당연한 이야기겠지만, Core 소스코드와 서버를 제어하는 주체는 회사가 아닌 고도몰이다. 그래서 서버 설정 변경, Core 코드 이슈 문의 및 수정은 별도로 요청해야 한다.\n반대로 말하면, 고도몰 Core 코드와 서버에 이슈가 발생하면 내부에서 할 수 있는 것은 손 놓고 기다리거나 고객센터에 전화걸어 해결방법을 찾아볼 수 밖에 없다. 원인을 알더라도 신속히 대응하기가 힘들다.\n가장 큰 문제는 이러한 이슈가 자주 발생하는 편이다. Core에 오류가 있으면 상속받아 수정하기도 했다.\n2. 도메인 설정 직접 불가 #이해가 되지 않는 부분이지만, 도메인이 고도몰에 등록되어 있을 경우 DNS 설정을 직접 할 수 없다. 고도몰에서 설정 메뉴를 제공하고 있지 않으며, 1:1 문의 게판을 통해서만 가능하다. 설정 완료되었다는 답변이 언제 올지 예상할 수 없다. 그래서 도메인 A 레코드 하나 추가하는데 오랜 시간이 걸린다. DNS 갱신시간 포함하면 일정을 미리 잡아야 한다.\n그래서 고도몰에 입점한 업체 중 일부분은 AWS 와 같은 외부 DNS를 사용하기도 했으며 고도몰에선 세팅이 변경될 경우 외부 DNS 를 사용하는 업체들에게 주의 및 확인하라고 공지사항을 통해 알려주기도 한다.\n3. 잦은 이슈 #이슈가 자주 발생하는 편이다. 이슈 발생 시 구현한 소스코드에서 대응이 가능하면 다행이지만 고도몰 코어(Core) 코드나 서버 설정 등의 오류는 무작정 기다릴 수 밖에 없다.\n솔루션 자체 오류 때문에 1:1 문의를 남겨보았지만, 해결되지 않고 추후 수정할 예정이라는 답변이 온 것들이 몇 건이 있었으며 수정되지 않은 것들도 있었다.\n4. 개발자가 필요한 CS 대응 불가 #CS 대응은 (매뉴얼대로 진행해주지만) 친절하다. 그러나 개발자와 직접 통화해서 해결해야 하는 이슈들이 종종 있는데, 개발자와 직접 통화가 불가능하며 관련 내용을 전달하겠다는 답변만 받았다. 그 전달한 내용에 대한을 답변을 받으려면 1:1 문의 게시판을 통해 다시 남겼어야 했다.\n결론 #개인적으로는 고도몰 유지보수를 통해 발전을 기대할 수 없었다. 하지만 고도몰과 같은 서비스는 빠르게 쇼핑몰 구축이 필요한 곳이라면 필요하다고 생각하고 필요로 하는 곳이 반드시 존재한다. 비즈니스를 하는 입장에선 환영을 할 수 있으나 개발자 입장에서는 양날의 검과 같다고 생각한다.\n","date":"2022-04-24","permalink":"/posts/2022/04/godomall-lookback/","section":"Posts","summary":"\u003cp\u003e고도몰5 Pro 기반으로 제작된 자사몰(이하 고도몰)을 빠져나오는 것을 목표로 했지만 현실적으로 고도몰 기능추가 / 유지보수를 담당하게 되었다. 이 글은 지난 1년간 담당했던 고도몰의 기능개발 / 유지보수를 하며 개발자 관점에서 느낀 점이다.\u003c/p\u003e","title":"고도몰5 Pro 기반 자사몰 기능개발 / 유지보수 하며 느낀점들"},{"content":"","date":null,"permalink":"/tags/%EB%A0%88%EA%B1%B0%EC%8B%9C/","section":"태그","summary":"","title":"레거시"},{"content":"","date":null,"permalink":"/tags/%EC%9C%A0%EC%A7%80%EB%B3%B4%EC%88%98/","section":"태그","summary":"","title":"유지보수"},{"content":"","date":null,"permalink":"/tags/wework/","section":"태그","summary":"","title":"WeWork"},{"content":"","date":null,"permalink":"/tags/%EA%B3%B5%EC%9C%A0%EC%98%A4%ED%94%BC%EC%8A%A4/","section":"태그","summary":"","title":"공유오피스"},{"content":"이 글은 지난 1년여간 공유오피스인 위워크(wework)에 입주한 회사에서 일을 하며 느낀 점에 대한 내용이다. 위워크는 여러 지점이 있지만, 작성한 내용은 모든 지점에 대해 공통으로 적용될 것 같다.\nTL;DR # 장점: 비용만 지불하면 공간 + 필요한 서비스 사용 가능. 세련된 인테리어. 접근성 좋음. 커피 / 맥주 무제한(코로나19 로 인해 맥주는 미제공). 친절한 직원분들. 필요시 다른 국내 / 해외 위워크 지점에서 일을 할 수 있음(크레딧 소진).\n단점: 비싼 비용. 책상 가로(120cm), 세로가 좁다. 책상 서랍장이 작다. 27인치 모니터의 경우 한 눈에 들어오지 않는다. 공기 순환과 온도 조절이 안된다. 방음이 거의 되지 않는다. 크레딧 초과비용, 카드분실 비용이 비싸다.\n위워크(Wework)는 #위워크(wework)는 전 세계에 지점을 둔 공유오피스이다. 소프트뱅크의 손정의(Masayoshi Son)가 투자를 했으며 기업 공개 준비를 하며 파산할 뻔했었다. 이 과정이 애플TV 드라마인 우린폭망했다(wecrashed)로 나오기도 했다. 이후 소프트뱅크가 추가 투자를 함으로써 위워크는 현재까지 문제없이 운영되고 있다.\n분위기 #대부분의 공유오피스들과 같이 깔끔하고 세련되었으며 젊은 느낌이다. 스타트업들이 많이 입주해있지만, 어느정도 연혁있고 규모있는 기업들도 입주해있다 (입주한 지점은 아니지만 심지어 아마존도 입주해있다). 그래서 그런지 근무하는 분들의 연령대는 다양했다.\n위워크 직원 분들은 매우 친절했으며, 구석구석까진 힘들었지만 사무실 청소도 깔끔하게 해주신 편이였다. 직원분들도 자유로운 분위기에서 일을 하셨으며, 입주회사를 최대한 배려해주셨다.\n글로벌 기업이기 때문에 직원분들께서 외국분들께 영어로 응대를 하는 모습도 볼 수 있었다.\n장점 #비용을 지불하면 공간과 업무 외 신경써야할 부분(인터넷, 프린트, 화장실, 청소, 커피, 전화부스, 싱크대, 사무용품 등) 제공해준다. 거꾸로 말하면 일반적인 사무실 마련 시엔 이와 같은 것을 전부 신경써야 하는데 위워크에 입주하면 한번에 손쉽게 해결할 수 있다. 단기간 계약도 가능하다. 사실 이는 모든 공유오피스의 장점일 것이다.\n다른 국내 공유오피스와 차별화 되는 점은 위워크는 글로벌 기업이기 때문에 크레딧만 지불하면 전국 혹은 전세계 어느 지점이든 가서 일을 할 수 있다. 컴퓨터 1대만 있으면 디지털 노마드(Digital Nomad)를 실현 할 수 있다.\n단점 #지불해야할 비용이 비싸다. 자세한 기억은 나지 않지만 위워크에 입주한 사무실 가격이 12인실 기준 꽤 비쌌으며 크레딧 초과 비용도 비싸다(초과시 1크레딧당 \\20,000).\n그리고 큰 단점은 공간일듯 싶다. 장점에 언급한 공간 이라는 항목과 모순되는 것 같은데, 공간을 대여해주지만 공간을 구성하는 세부적인 항목들이 단점이 된다. 이 공간에 대해 개인적으로 느낀 점은 아래와 같다.\n환기: 입주한 지점은 환기가 되지 않았다. 천장에 에어컨 / 히터가 있었으나 위워크에서 제어하는 방식이기 때문에 개별 제어는 불가능했다(리모컨 없음). 그래서 에어서큘레이터를 두고 사용했었다.\n책상: 책상이 무지 좁다. 가로 120cm이며 세로도 매우 좁다. iMac 5K 27인치를 사용했는데, 한 눈에 화면이 들어오지 않았다. 그래서 눈이 좀 아프기도 했다. 듀얼모니터를 사용한다면 키보드 마우스 빼곤 책상 위에 놓을 공간이 거의 없을 정도이다. 모니터암 설치가 가능하다는 답변을 받았으나, 책상에 흠집이 나면 변상해야 한다는 답변을 들었다. 그리고 책상이 작아 모니터암 + 모니터를 설치할 시 책상이 앞으로 고꾸라질 것 같았다. 하여, 다른 오피스의 경우 본인들이 구매한 책상과 파티션을 가지고 와 사용하기도 했다. 아래 사람간의 간격 또한 생각하면 업무에 집중이 잘 되지 않았다.\n사람간의 간격: 책상이 좁기 때문에 사람간 간격도 좁을 수 밖에 없다. 시야에 옆 사람이 들어오는 경우가 있어 신경 쓰이기도 한다.\n좁은 서랍장: 책상이 좁기 때문에 서랍장 또한 좁다. 서랍장 사이즈는 책상 가로 120cm 기준 의자 1개가 들어가고 남은 공간을 최대한 살리는 사이즈인 것 같다. 비밀번호 세팅해서 사용 가능하다.\n소음 (방음): 오피스 공간이 유리벽으로 구분되어 있다. 그래서 옆 오피스에서 말하는 내용이 들리기도 한다. 심지어 옆옆옆 오피스에서 싸우는 소리가 들리기도 했다.\n채광: 유리창이기 때문에 햇빛이 강하게 들어온다. 하여 1년 365일 블라인드를 치고 근무했다. 이마저도 햇빛이 들어온다는 민원이 있어 블라인드를 전부 교체해주기도 했다.\n회의실: 회의실을 예약해서 사용해야 하는데, 대부분 꽉 차 있어 예약하기 힘들었다. 그래서 공용 공간에서 간단한 회의를 하기도 했다.\n엘레베이터: 여러 층에서 같이 사용하기 때문에 이용이 힘든 시간대가 존재한다.\n기타 # 현재 코로나19 상황으로 인해 맥주제공은 되지 않는다. 대신 음료수(사이다), 무알콜 맥주를 제공하기도 했었다.\n창고가 필요한 경우, 확인해봐야 할 것 같다. 참고로 예전 같이 일하는 회사가 패스트파이브에 입주했을 시 그곳에서는 창고를 제공하지 않아 추가 공간을 임대한 후 사용했었다.\n코워킹: 코로나19 상황 때문인지 이루어 진 것을 볼 수 없었다.\n택배가 밤 늦게 배달이 오면 받을 곳이 없다. 가끔 위워크 입구에 놓여 있는 것을 볼 수 있었다.\n몇 층에서 코로나19 확진자가 나왔고 소독을 실시한다는 공지를 메일(한글 / 영어)로 알려준다.\n결론 #이상 공유오피스 위워크에서 1년여간 근무해본 경험이였다. 비용만 지불하면 오피스에서 필요한 대부분을 곧바로 사용할 수 있는 장점을 가지고 있지만, 개인적인 경험으로 근무 환경을 생각해 볼 때 불편할 점이 다수 존재한다. trade-off 가 있지만 지불하는 비용을 생각한다면 개선이 필요할 만한 부분은 존재하는 것 같다.\n한 가지 확실한 것은 공유오피스 홍보물을 절대적으로 믿지 말라고 말하고 싶다. 직접 방문하고 책상에 앉아보고 이동동선 등 한번 경험해보고 fit이 맞는지 아닌지 확인해보는 것을 추천한다.\n뱀다리 #예전에 같이 일했던 회사가 위워크는 아니지만 공유오피스(패스트파이브, 드림플러스)에 입주해있었다. 그들하고 이야기한 내용을 정리하면, \u0026lsquo;겉모습은 좋아 보이지만 실제 근무 환경은 좋지 못하다\u0026rsquo; 였고 그 예로 책상과 사무공간을 직접 보여주었었다. 그 당시 \u0026lsquo;좁구나\u0026rsquo; 라는걸 느끼긴 했는데(드림플러스가 조금 넓었음) 실제로 근무하진 않아서 크게 와 닿지 않았다.\n사실 그것이 얼마나 불편하지는 잘 몰랐다. 그리고 지난 1년여간 공유오피스인 위워크에서 일을 했는데, 그것이 무엇을 뜻하는지 알게 되었다. 그리고 공유오피스들은 대부분 비슷비슷하게 구성되어 있구나 하는 것을 느꼈다.\n친구가 패스트파이브에 근무한 경험이 있었는데, 그곳은 140cm 책상 옵션이 있다는 것이였다. 그 책상을 사용했었는데, 괜찮았다는 답변과 함께 120cm 썼으면 힘들었을거라고 말을 해 주었다. 확실히 120cm는 좁긴 한 것 같다.\n","date":"2022-04-20","permalink":"/posts/2022/04/wework-lookback/","section":"Posts","summary":"\u003cp\u003e이 글은 지난 1년여간 공유오피스인 위워크(wework)에 입주한 회사에서 일을 하며 느낀 점에 대한 내용이다. 위워크는 여러 지점이 있지만, 작성한 내용은 모든 지점에 대해 공통으로 적용될 것 같다.\u003c/p\u003e","title":"공유오피스 위워크(wework) 1년여간 경험 - 장점과 단점"},{"content":"2020년은 코로나19로 인해 많은 것들이 변했지만 나에게도 많은 변화가 있었다. 기존 것을 과감히 버리려고 했고 새로운 것을 얻으려 했지만 생각만큼 만족한 결과를 얻진 못했다. 개발자로의 삶을 영위하기 위해 꼭 필요하지만 갖지 못했던 것을 가질 수 있었지만 개발자로써의 학습은 많이 하지 못한것 같다. 2021년에는 조금 더 발전하는 개발자가 되고자 2020년을 정리해 보고자 한다.\n퇴사 #잦은 야근으로 인해 피로가 쌓이고 몸 상태는 나빠졌으며 업무가 많았다. 정신적으로 힘들어 쉬어야 한다는 생각이 들어 회사를 나오게 되었다. 마지막 프로젝트는 처음부터의 변경이 4~5번 정도 이루어졌으며 설날에도 일을 할 수 밖에 없었다.\n개발 스택을 꾸준히 변경해왔지만 대부분 혼자서 frontend / backend (Monolithic) 개발을 했고 SI만 해 비전이 없었다. 현재 반복적으로 하는 업무 중 불편한 것들을 개선하고 기능을 추가해 서비스 형태로 만들자고 꾸준히 제안했지만 회사는 알았다고만 할 뿐이였다. 이후 충분히 쉬었고 결과론적으론 나오길 잘 했지만 진작 왜 나오지 못했나 하는 생각이 들었다.\n세상은 넓고 기회는 많다고 하는데 너무 우물 안 개구리로 살았던 것 같다.\n운동 #평소에도 자세가 좋지 않았기 때문에 퇴사 후 곧바로 정형외과로 가 도수치료를 처음 받았다 (12회). 도수치료를 받은 후엔 몸이 좋아졌지만 오래 가지는 못했던 것 같다. 그래서 몸, 자세 유지 및 건강을 위해 운동을 해야 한다는 생각이 들었다. 헬스장에 등록하려 했으나 코로나19로 인해 포기했다.\n푸시업 (Push up) #그래서 집에서 간단히 할 수 있는 푸시업(Push up)을 하기로 했고 맨손으로 무작정 하는 대신 Power Press 푸시업 보드를 사서 했다. Power Press 푸시업 보드는 푸시업 + 맨몸운동 10주 프로그램을 Youtube 동영상과 같이 제공한다.\n결과부터 말하면 3월 중순부터 Power Press 푸시업 보드를 이용해 제공하는 프로그램대로 운동을 시작했으며 10주를 넘긴 시점에서는 푸시업 정자세로 한번에 5개씩 할 수 있게 되었다. 처음엔 1~2개도 하기 힘들었고 몸이 욱신거려 힘들었지만 무릎대고 푸시업을 8주까지 한번에 최대 10번까지 늘렸고 이후 정자세로 변경했더니 그냥 되었다. 말 그대로 그냥 되었다.\n10주 프로그램에서 푸시업 뿐만 아니라 스쿼트, 크런치, 러시안 트위스트, 플랭크, 버피 등 맨몸 운동도 같이 제공해 그대로 따라했고 어려운 운동은 쉬운 버전으로 바꾸어 했다(버피는 층간소음 때문에 슬로우버피로 바꾸어 했다). 그리고 식단에 샐러드를 추가했다. 나의 경우 10주 중 8주 후에 살이 빠지고 푸시업이 정자세로 되는 변화가 보이기 시작했다.\n지금은 1회에 25 ~ 30개를 할 수 있게 되었다.\n풀업 (Pull up) #푸시업이 익숙해진 후 8월 중순부터 풀업(Pull Up)을 시작했다. 앉은 자세에서 등에 통증이 있던 관계로 등 운동으로 하면 나아질 것이라는 생각에서 하기 시작했다. 생전 해보지 않아 두려웠는데 풀업은 맨몸 운동의 끝판왕이고 본인 체중 100%를 (푸시업은 60%)을 들어올려야 하는 매우 어려운 운동이라는 말에 걱정이 되었다.\n풀업 처음 할 때 악력이 없어 매달리기 10초도 힘들었고 1개 올라가기도 힘들었지만 Youtube 동영상들에서 소개하는 매달리기, 인버티드 로우, 점프 풀업, 풀업밴드 이용한 풀업 등을 꾸준히 하다보니 어느순간 1개가 되기 시작했으며 2개 이후부터 개수가 늘기 시작했다.\n풀업을 꾸준히 하니 어깨가 펴지게 되어 올바른 자세가 되어 등 통증이 많이 사라졌다. 장시간 컴퓨터를 사용하는 직업 때문에 어깨가 굽어있었던 것이 교정된 것 같다.\n지금은 1회에 7 ~ 10개를 할 수 있게 되었지만, 자세 교정은 항상 필요하다.\n결론 #지금은 1주일에 4일, 푸시업 / 스쿼트 / 무릎운동 각 100개, 풀업 50개를 한다. 풀업은 미 해병대 풀업 루틴을 참고하며 하고 있다. 스트레칭 -\u0026gt; 풀업 -\u0026gt; (푸시업 / 스쿼트 / 무릎) -\u0026gt; 풀업 형태로 하고 있는데 이 루틴대로라면 50분 정도 소요된다. 이제는 푸시업 / 풀업을 하지 않으면 안되는 강박관념 같은 것이 생겼고 몸을 풀어주어야 하루를 마무리 한 것 같다.\n생각해보면 운동의 \u0026lsquo;ㅇ\u0026rsquo;도 몰랐는데 입문하고 꾸준히 한 결과 운동이 된 것이 신기하다. 난 운동과는 거리가 먼 사람이라고 항상 생각했었는데 운동을 하고 나서부터 20대때 운동을 하지 않은 것이 뼈아프게 후회되었다.\n그리고 푸시업, 풀업 과정에서 체지방이 최대 10% 정도 빠졌다 (물론 지금도 수치상으론 비만). 30% 대에서 20% 대로 감소했다. 체지방이 감소하니 몸이 가벼워졌고 이 느낌이 굉장히 좋다.\n무엇보다 잡생각이 많이 사라졌다. 운동을 하면 힘들어 잡다한 생각을 잊을 수 있었고 이는 정신건강에 매우 큰 도움이 되었다. 어찌보면 몸이 건강해지는건 주가 아닌 부가적인 옵션이였을 정도다.\n마지막으로 인터넷에 많은 글 중 30대에 운동을 해야 한다는 글들이 많았는데 이 말을 실감하게 되었다. 내년에 코로나19가 어느정도 해결되면 반드시, 반드시 헬스장을 등록해서 정식으로 운동을 배워서 할 생각이다.\n이직 #6개월 간 충분한 생각을 통한 개인 공부와 휴식을 좀 길게 가지고 이직을 했다. 이직 과정에서 나의 경력을 하찮게 보는 회사도 있었지만(그럴거면 왜 코딩테스트와 면접을 봤는지 모르겠다), 좋은 인상을 주는 회사도 있었다. 이직 과정에서 느낀 것은 지금까지 개발 스택 선정과 변경, 그리고 방향이 맞았다는 것을 느꼈으며 공부가 더 필요한 부분이 어떤 부분인지도 알 수 있었다. 몇 번의 면접 끝에 이직을 했고 대규모 데이터를 다룰 수 있는 회사에 재직중이다.\n그리고 #현재 회사의 소스코드는 소스코드의 구조 변경이 전혀 이루어지지 않았다. Modern PHP는 꿈같은 이야기이고 codeigniter 또한 기대할 수 없다. 형상관리 또한 기대할 수 없고 FTP를 통해 배포된다. 일부는 운영 서버에서 직접 구현 후 테스트를 해야 하기 때문에 항상 불안하다.\n이 과정을 개선하고자 git의 적극적인 사용, git-flow, docker 도입, 배포 시스템 등을 시도하고 있지만 잘 되고 있지 않다. 간단히 framework 형태로 사용하고자 코드를 구현 했지만 오래된 서버 설정으로 인해 사용할 수 없다. 최근 들어 이 과정에 계속 노출이 되면 어느순간 이게 당연하다는 듯이 적응할 것 같고 그렇게 되고 있다는 것을 느껴 불안하다는 생각이 든다. 개인 공부를 통해 부족한 부분과 발전 욕구를 충족시키려 하지만, 욕심이 많은 탓인지 쉽게 채워지지 않는다. 클리앙의 어느 글의 글쓴이와 같은 고민이 된다.\n마치며 #2020년은 많은 일들이 일어났지만 그 많은 일들은 순식간에 사라졌고 이제 남은 시간이 얼마 남지 않았다. 올해의 가장 큰 성과는 운동에 습관을 들인 것이다. 물론 개발자로서의 발전도 있었지만, 개발자로써의 발전보다 휴식과 운동 비중이 큰 한 해였다. 내년에는 쉬어간 올해 못한 것들을 포함해 개발자로써의 발전을 이루고자 한다.\n또 한가지, 운동을 꾸준히 하고자 하는 목표를 미리 세웠다. 코로나19가 어느정도 진정이 되면 헬스장에 등록해 본격적으로 운동을 배우고자 한다.\n","date":"2020-12-23","permalink":"/posts/2020/12/lookback/","section":"Posts","summary":"\u003cp\u003e2020년은 코로나19로 인해 많은 것들이 변했지만 나에게도 많은 변화가 있었다. 기존 것을 과감히 버리려고 했고 새로운 것을 얻으려 했지만 생각만큼 만족한 결과를 얻진 못했다. 개발자로의 삶을 영위하기 위해 꼭 필요하지만 갖지 못했던 것을 가질 수 있었지만 개발자로써의 학습은 많이 하지 못한것 같다. 2021년에는 조금 더 발전하는 개발자가 되고자 2020년을 정리해 보고자 한다.\u003c/p\u003e","title":"2020년을 마무리하며 (회고)"},{"content":"주제별로 글을 분류해 정리합니다.\n","date":null,"permalink":"/categories/","section":"카테고리","summary":"\u003cp\u003e주제별로 글을 분류해 정리합니다.\u003c/p\u003e","title":"카테고리"}]