-
[2026 ABC 프로젝트 멘토링 8기] 프로젝트 5주차ABC 프로젝트 2026. 7. 5. 23:16ABC 프로젝트 멘토링 8기
프로젝트 5주 차 — 개발 마감 스퍼트: 중간 점검 회의, 실시간 대시보드, 그리고 QA 준비
00들어가며
5주 차는 개발의 마지막 스퍼트를 올리는 주였다. 4주 차에 흩어져 있던 기능들을 하나로 통합했다면, 이번 주는 그 통합된 서비스가 실제로 돌아가는지를 점검하고, 다음 주 개발 마감과 QA를 앞두고 남은 일을 촘촘히 정리하는 데 집중했다.
이번 주의 큰 줄기는 세 가지였다. 첫째는 지금까지 구현된 것을 함께 점검하고 다음 태스크를 정하는 중간 점검 회의, 둘째는 4주 차에 예고했던 Redis 기반 실시간 대시보드를 실제로 붙이며 겪은 고난, 셋째는 마감 이후 곧바로 이어질 QA와 남은 추가 기능 정리였다.
이번 주 태스크: 중간 점검 회의 → 실시간 대시보드(Redis) 구현 → 다음 태스크 & QA 준비
01중간 점검 회의 — 어디까지 왔고, 무엇이 남았나
개발이 마무리하면서, 각자 작업한 것을 모아 점검하는 회의를 진행했다. 통합한 메인 프로덕트를 두고 기능 추가보다 기능 개선에 중점을 두고 개발을 진행하였다. 기존에 더미데이터로 존재했던 것들을 직접 서버와 연결하여 실제 데이터로 바꾸는 작업을 진행했다.
회의 안건 — ① 대시보드 처리는 어떻게 되었는가(Redis?) · ② 중간 기능 보고 · ③ 다음 Task 선정
첫 안건인 대시보드는 4주 차 마무리에서 ‘Redis를 도입해 실시간으로 올리겠다’고 예고했던 부분이라, 진행 상황을 공유하는 것으로 회의를 열었다(자세한 내용은 아래 02에서 따로 정리했다). 이어서 각자 맡은 파트의 중간 기능 보고를 돌아가며 진행했고, 마지막으로 마감까지 남은 다음 Task를 우선순위대로 정리하며 회의를 마쳤다.

맛있는 쿠키를 먹으며 회의를 진행했다ㅎㅎ
02지금까지 구현된 것 — 중간 기능 점검
중간 기능 보고를 통해, 현재까지 서비스가 어느 정도 형태를 갖췄는지 확인했다. 핵심 골격은 대부분 올라와 있었고, 세부에서 다듬을 지점들이 드러났다.
권한 체계 — super-admin / admin / user
서비스는 super-admin → admin → user 순으로 권한이 나뉘는 구조로 구현돼 있었다. 특히 백오피스(BO), 프로젝트 관리(PMS), 그리고 실제 사용자용 웹이 하나의 시스템 안에서 권한으로 구분되도록 통합돼 있는 점이 중요한 부분이었다. 하나의 코드베이스로 세 종류의 사용자 경험을 권한에 따라 갈라 보여주는 방식이다.
다만 점검 중 두 가지 문제가 확인됐다. 하나는 계정 인증번호 전송이 되지 않아 로그인 확인 자체가 막혀 있다는 점이었다. 이건 담당 팀원이 계정 정보를 따로 전달해 우회 확인하기로 했다. 다른 하나는 백오피스 기능이 아직 부실하다는 점으로, 마감 전에 다시 한번 집중적으로 살펴보기로 미뤄 두었다.
CI/CD, User 기능, 그리고 보고서 양식
배포 파이프라인은 Jenkins와 Argo CD로 구성돼 있었다. 빌드는 Jenkins가, 쿠버네티스 환경으로의 배포는 Argo CD가 맡는 익숙한 조합이다. 사용자용 기능(User 기능)도 기본 흐름은 올라와 있어, 이제는 세부 완성도를 높이는 단계로 넘어가는 참이었다.
보고서 기능과 관련해서는 실무 관점의 의견이 나왔다. 실제 현장에서 쓰는 보고서는 대개 정해진 한글(HWP) 양식이 있을 텐데, 그 양식을 그대로 받아 와서 내용을 채우고 수정할 수 있게 하면 실사용성이 크게 올라간다는 것이다. 우리 서비스가 만들어 주는 보고서가 그럴듯한 문서를 넘어 바로 제출 가능한 문서가 되려면 필요한 방향이라, 다음 단계 과제로 함께 메모해 두었다.
점검 요약 — 골격은 대부분 완성. 남은 건 백오피스 보강, 계정 인증 흐름 정상화, 그리고 한글 양식 기반 보고서 등 ‘완성도’의 영역.
03이번 주 가장 어려웠던 것 — 실시간 대시보드 붙이기
이번 주 내가 가장 오래 붙잡은 건 회의 1번 안건이기도 했던 실시간 대시보드였다. 4주 차 말미에 ‘Redis로 실시간 처리를 올리겠다’고 적어 뒀는데, 막상 구현에 들어가니 개념으로 이해한 것과 실제로 동작시키는 것 사이에는 꽤 큰 간극이 있었다.
!여러 워커로 띄우자 실시간 이벤트가 일부 사용자에게만 도착하는 문제어떤 문제였나
대시보드는 서버에서 일어나는 이벤트(라벨링 처리 현황, 에러 알람 등)를 WebSocket으로 클라이언트에 실시간으로 밀어준다. 로컬에서 단일 프로세스로 돌릴 때는 잘 됐다. 그런데 서버를 안정적으로 굴리려고 워커(프로세스)를 여러 개로 띄우자, 어떤 사용자에게는 이벤트가 오고 어떤 사용자에게는 오지 않는 현상이 나타났다. 원인은 명확했다. 각 워커가 자기 메모리 안에만 WebSocket 연결 목록을 들고 있어서, A 워커에서 발생한 이벤트가 B 워커에 붙어 있는 사용자에게는 전달되지 못한 것이다. 프로세스가 재시작되면 그 연결들이 통째로 날아가는 문제도 겹쳤다.
어떻게 풀까 — 두 가지 선택지
A안 · Sticky Session으로 워커 고정한 사용자를 항상 같은 워커에 붙여, 메모리 내 연결만으로 처리. 당장은 되지만 워커가 죽거나 늘면 다시 깨진다.
B안 · Redis Pub/Sub로 이벤트 브로드캐스트 채택이벤트를 Redis 채널에 발행하고 모든 워커가 그 채널을 구독. 어느 워커에서 난 이벤트든 전 사용자에게 도달.
왜 B안인가A안(Sticky Session)은 연결을 한 워커에 묶어 된다는 발상인데, 근본을 피해 가는 임시방편에 가까웠다. 워커가 재시작되거나 수가 바뀌면 묶여 있던 연결이 흩어져 같은 문제가 또 터진다. 반면 우리가 진짜 원하는 건 어느 워커에서 이벤트가 나든 모든 사용자에게 똑같이 전달되는 것이었고, 그 요구에 정확히 맞는 도구가 Pub/Sub이었다. 마침 4주 차에 개념으로 정리해 둔 방향이기도 했다. 그래서 이벤트를 특정 채널에 '발행'하면 그 채널을 ‘구독’하는 모든 워커가 동시에 받아 각자 붙은 클라이언트에게 전달하도록, 그 허브로 Redis를 도입했다.
여담이지만 Pub/Sub이 MQTT에서 많이 사용해 본 개념이었기에 더 빠르게 이해되고, 효율이 좋다고 느껴졌다.
backend/dashboard/realtime.py — 핵심 구조# 문제: 각 워커가 자기 메모리에만 연결을 들고 있어 이벤트가 일부에게만 도착 # 해결: Redis Pub/Sub로 모든 워커가 같은 채널을 구독 → 어디서 난 이벤트든 전체 브로드캐스트 import redis.asyncio as redis r = redis.from_url("redis://redis:6379") CHANNEL = "dashboard:events" async def publish_event(event: dict): # 어떤 워커에서 처리하든, 이벤트는 공용 채널로 발행 await r.publish(CHANNEL, json.dumps(event)) async def dashboard_ws(ws: WebSocket): await ws.accept() pubsub = r.pubsub() await pubsub.subscribe(CHANNEL) # 모든 워커가 같은 채널 구독 async for msg in pubsub.listen(): if msg["type"] == "message": await ws.send_text(msg["data"].decode()) # 내게 붙은 클라이언트로 전달해결 — 결과Redis Pub/Sub를 붙인 뒤로는 워커를 몇 개로 띄우든 모든 사용자가 같은 이벤트를 실시간으로 동일하게 받게 됐다. 워커가 재시작돼도 연결 상태를 각 프로세스 메모리에만 의존하지 않으니 동기화가 깨지지 않았다. 더불어 Redis를 캐시·세션 저장소로도 함께 쓸 수 있어, 앞으로 확장할 여지까지 확보했다. 개념으로만 알던 Pub/Sub를 실제 코드로 옮겨 ‘분산 환경에서의 실시간 전달’ 문제를 직접 풀어 본 게, 이번 주 가장 값진 경험이었다.
04다음 Task & 추가 기능 정리
회의 마지막에는 마감까지 남은 일을 우선순위대로 정리했다. 큰 기능을 새로 얹기보다, 완성도와 안정성을 끌어올리는 항목이 대부분이었다.
프런트엔드 품질 — 언어 마이그레이션
현재 프론트엔드의 완성도를 한 단계 더 끌어올리기 위해, React나 Next.js로의 마이그레이션을 검토하기로 했다. 지금 구조로도 동작은 하지만, 유지보수성과 화면 품질을 생각하면 프레임워크를 갖춰 정리하는 작업이 필요하다는 데 의견이 모였다.
QA — YOLO fallback 로직
QA 관점에서 나온 중요한 지적은 YOLO fallback 로직이었다. 이미지 인식(YOLO)이 실패하거나 결과가 부실할 때를 대비한 대체 경로가 아직 없다는 점이다. 실사용에서는 인식이 안 되는 이미지가 반드시 나오므로, 실패 시 다른 방식으로 처리하거나 사용자에게 적절히 안내하는 fallback을 마련하는 것을 QA 항목으로 넣었다.
API 교체 & 배포(CD) 구축
검증용으로 쓰던 AI API를 정식 키로 교체하는 작업도 남아 있다. 이와 함께 CD(지속적 배포) 구축이 병행돼야, 키 교체나 코드 변경이 안정적으로 서버에 반영된다. 서버 쪽 컨테이너 오케스트레이션은 Docker든 k3s든 상황에 맞게 붙이기로 유연하게 열어 두었다.
사용자 데이터 & 페이지네이션
사용자 로그인 정보를 확인할 수 있는 DB를 추가하기로 했다. 다만 목록성 데이터를 한 번에 다 불러오면 DB 부하가 커지므로, 리스트로 받아오는 값들은 페이지 단위(pagination)로 분리해 필요한 만큼만 가져오도록 하는 작업을 함께 진행하기로 했다. 부하를 줄이면서 응답 속도도 챙기는 방향이다.
문서 정리
그동안 빠르게 진행되느라 부족했던 Notion 문서 정리도 과제로 올렸다. 커피챗에서 배운 ‘Ground Truth 문서’ 원칙대로, 요구사항과 진행 상황을 기준 문서로 다시 정돈해 두면 마감과 QA, 그리고 인수인계까지 한결 수월해진다.
남은 Task 한눈에 보기
항목 내용 프론트 마이그레이션 React / Next.js로 전환해 화면 품질·유지보수성 향상 QA · YOLO fallback 이미지 인식 실패 시 대체 경로/안내 로직 추가 API 교체 · CD 정식 API 키 전환 + 지속적 배포 파이프라인 구축 사용자 DB · 페이지네이션 로그인 정보 DB 추가, 목록은 page 단위로 분리해 부하 절감 서버 오케스트레이션 Docker 또는 k3s로 서버 구성(유연 선택) 문서 정리 Notion 문서를 Ground Truth 기준으로 재정돈 05일정 — 개발 마감, QA, 그리고 영상
마지막으로 앞으로의 일정을 맞췄다. 큰 방향은 명확하다. 다음 주까지 개발을 마감하고 곧바로 QA로 넘어간다.
- 다음 주 개발 마감 → QA 착수 남은 태스크를 마무리하고, 통합 서비스 전반을 QA로 점검. 완성도·안정성을 끌어올리는 단계.
- 임베디드 경진대회 변수 2학년 팀원들이 다음 주 청주에서 열리는 임베디드 경진대회에 참가한다. 일정이 겹치는 만큼 작업 분배를 미리 조율.
- 시연 영상 촬영 완성된 서비스를 보여줄 시연 영상 촬영이 필요. 마감·QA와 함께 준비.
요약 — 다음 주 개발 마감 후 QA 전환. 대회 일정과 겹치는 점을 고려해 분배하고, 시연 영상까지 준비한다.
06번외 — 5주 동안 자란 우리 하네스를 해부해 보다
이번 주 개발과는 별개로 Claude를 이용한 바이브코딩을 위해서 여러가지 .md파일을 구성했다. MCP, Skills, ignore, settings, hooks 등 많은 파일을 만들어서 Claude의 가이드라인을 정확히 제시하는 엔지니어링에 대해 실습했다. 성능 향상 결과는 생각보다 놀라웠다. 처음엔 설정 파일 몇 개로 시작했던 하네스가, 어느새 29개 파일, 7개 범주로 이루어진 팀용 하네스가 되어 있었다. 이렇게 많은 파일로 Claude는 중간에 Context를 잃지 않고, 프로젝트를 파악하며 개발을 진행할 수 있었다.

파일 구조는 다음과 같다
- 설정(settings) — 모델 고정과 함께, 권한을 allow / ask / deny 3단계로 나눠 놓았다. 일상 개발 명령(uv, pytest, ruff, git 읽기류)은 자동 허용, git commit·push나 rm·docker는 매번 확인,
.env·사용자 DB 읽기는 완전 차단. “Claude가 임의로 커밋하지 않는다”는 팀의 깃 정책이 말이 아니라 권한 레벨로 구현돼 있었다. - 훅(hooks) 3개 — 위험한 명령(rm -rf, git push --force, .env 외부 전송 등)을 실행 전에 잡아내는 block-secrets, 파일을 고칠 때마다 ruff 포맷을 자동 적용하는 format-on-save, 세션이 열릴 때 브랜치·미커밋 변경·프로토타입 목록을 브리핑해 주는 session_start.
- 서브에이전트(agents) 6개 — VLM 조사, RAG 설계, 프로토타입 빌드, 공공데이터 탐색, 기획 문서, 코드 리뷰까지 역할별 전문 에이전트. 특히 code-reviewer에는 Edit/Write 도구가 아예 없어서 물리적으로 수정이 불가능하다. ‘리뷰어는 리뷰만 한다’를 도구 제한으로 강제한 셈이다.
- 규칙(rules) 4개 — LLM 호출은 반드시 어댑터 레이어를 거칠 것, 라즈베리파이(8GB, GPU 없음)에서 못 도는 의존성 금지, 키가 없어도 폴백으로 항상 동작할 것 같은 조항들이 파일 종류별로 자동 적용된다. RAG 규칙에는 “청크 400자, overlap 60”처럼 우리가 실험으로 찾아낸 값이 상수로 박제돼 있었다.
- 스킬 4개 + 커맨드 3개 — 기획 보고서 생성, 프로토타입 스캐폴드, 공공데이터 RAG 절차(Decoded 키, 일 1,000회 한도 같은 실무 함정 체크리스트 포함), 팀 워크스페이스 초기화. 커맨드로는 서버 띄우기, 4대 데모 시나리오 점검, 이슈 수정 절차가 준비돼 있다.
- 자동화·기억 — 하루 작업을 요약해 작업노트를 만들어 주는 daily-sync 워크플로우, 그리고 의존성 0으로 SQLite에 세션 간 기억을 저장하는 자체 제작 memory MCP. 4주 차 커피챗에서 들었던 Memory Palace 개념이, 사실 우리 하네스 안에 이미 작게 구현돼 있었던 것이다.
해부하며 얻은 것
가장 크게 와닿은 건 다층 방어라는 개념이었다. 예를 들어 ‘시크릿 유출’ 하나만 봐도, 설정의 deny(Claude가 .env를 못 읽음) → block-secrets 훅(명령 실행 전 차단) → code-reviewer(하드코딩 지적) → 각 스킬의 키는 환경변수만으로 관리하는 조항까지 무려 4겹으로 막혀 있다. 한 층이 뚫려도 다음 층이 잡는 구조라, 사람이 실수하든 AI가 실수하든 같은 안전망 위에서 작업하게 된다. 하네스 엔지니어링이란 결국 팀의 제약과 약속을 말이 아니라 환경 자체에 파일로 구조화 하는 일이라는 걸, 2주 차에 멘토님이 왜 하네스부터 잡으라고 하셨는지를 5주가 지나서야 이해했다.
그리고 웃긴 발견도 하나 있었다. 프론트엔드 규칙 파일에는 “React 등 프레임워크 신규 도입 금지”가 박혀 있는데, 정작 우리는 이번 주에 React 마이그레이션을 결정했다. 하네스를 해부하지 않았다면 몰랐을 어긋남이다. 규칙 문서도 코드처럼 낡는다는 것, 그래서 커피챗에서 배운 Ground Truth 원칙(구현 중 계속 업데이트한다)이 코드뿐 아니라 규칙 파일에도 그대로 적용된다는 걸 체감했다. 규칙 파일 갱신도 조용히 다음 Task에 얹어 두었다.
5주 차를 마치며이번 주는 프로덕트 동작을 확인하고, 마지막 완성도를 향해 방향을 다시 맞춘 한 주였다. 골격은 대부분 올라왔고, 남은 건 백오피스 보강·페이지네이션·QA처럼 프로젝트의 완성도를 높이는 일이라는 게 분명해졌다.
무엇보다 4주 차에 개념으로만 적어 뒀던 Redis 실시간 대시보드를, 이번 주에 직접 문제에 부딪히며 코드로 완성한 게 크게 남는다. 분산 환경에서 이벤트를 어떻게 일관되게 전달할지 고민하고 Pub/Sub로 풀어 본 경험은, 앞으로 어떤 실시간 기능을 만나도 든든한 밑천이 될 것 같다.
다음 주에는 남은 태스크를 마무리해 개발을 마감하고, 곧바로 QA와 시연 영상 준비에 들어간다. 이제 정말 마지막 언덕이다.
'ABC 프로젝트' 카테고리의 다른 글
[2026 ABC 프로젝트 멘토링 8기] 프로젝트 7주차 (0) 2026.07.19 [2026 ABC 프로젝트 멘토링 8기] 프로젝트 6주차 (1) 2026.07.12 [2026 ABC 프로젝트 멘토링 8기] 프로젝트 4주차 (1) 2026.06.27 [2026 ABC 프로젝트 멘토링 8기] 프로젝트 3주차 (0) 2026.06.20 [2026 ABC 프로젝트 멘토링 8기] 프로젝트 2주차 (0) 2026.06.14