Skip to content

Retrospective Week3

이현민 edited this page Jun 15, 2026 · 1 revision

회고 · Week 3

기간: 2026-06-09 ~ 2026-06-15

Week 3는 “기능을 더 많이 만드는 주”라기보다, 실제 배포된 서비스를 사람에게 써 보게 하고 그 결과로 워크플로우를 완성하는 주였다. 실제 운동 후 부원들이 뮤런에 기록을 남겼고, 그 과정에서 로컬 개발 때는 보이지 않던 운영/UX 문제가 드러났다.


1. 무엇을 완성했나

영역 결과
배포 main push → GHCR image → N100 prod 자동 배포
도메인 murun.duckdns.org + Caddy HTTPS
인증 Google OAuth + @snu.ac.kr + 관리자 승인 운영
핵심 흐름 세션 생성 → 사진 업로드 → 참여자 본인 기록 입력 → 아카이브
통계 /me, /runners/[id] 누적 거리/참여 수/평균 페이스/최근 페이스 차트
검색 /sessions 장소/멤버/월/참여 인원 필터
품질 Vitest/RTL/Playwright 테스트 안전망
워크플로우 08-Agent-Workflow-Report로 최종 정리

2. Dogfooding 결과

실제로 운동 후 부원들이 각자 기록을 입력했다. 이게 가장 중요했다. 혼자 happy path를 클릭하는 것과, 실제 사람들이 단톡방 링크를 열고 자기 기록을 적는 것은 전혀 달랐다.

확인된 점:

  • “그날 운동 주최자가 세션 페이지를 만들고, 참여자가 각자 자기 행을 채운다”는 모델은 자연스럽게 동작했다.
  • 숫자 ID(/sessions/1, /sessions/2)는 내부 동아리 서비스에서 공유하기 쉬웠다.
  • 사진 원본 보존 정책은 맞았다. 서버에서 임의 resize/crop을 하지 않는 쪽이 서비스 의도와 맞는다.
  • 관리자 승인 흐름은 처음엔 번거롭지만, 동아리 내부 서비스라서 납득 가능한 마찰이었다.

부족했던 점:

  • 호스트가 장소/시간/메모 오타를 고치는 세션 수정 UI가 없었다.
  • 큰 사진, OAuth 오류, 관리자 페이지 권한처럼 prod에서만 드러나는 문제가 있었다.
  • 테스트가 없던 시절엔 “내가 방금 고친 게 다른 입력 경계를 깨지 않았나?”를 확신하기 어려웠다.

3. Prod에서 발견한 문제들

3.1 Caddy / DuckDNS / 인증서

Caddy 자체 설정 문제라기보다 DuckDNS 전파와 외부 검증 타이밍 문제가 있었다. 로그를 보며 DNS, 80/443 포트포워딩, Caddy challenge를 분리해서 봐야 했다.

배운 점: 자체 서버에서는 “앱 코드가 맞다”와 “외부에서 접속 가능하다”가 별개의 문제다.

3.2 /admin/members 404

middleware에서 role을 보려던 접근이 문제였다. Edge-safe auth config는 DB fresh role을 보장하지 못한다. 최종 권한 판단은 page/action의 requireAdmin()에서 해야 한다.

결론: middleware는 로그인 여부 정도만 다루고, DB 기반 권한은 서버 진입점에서 판단한다.

3.3 큰 이미지 업로드 413

앱에서는 15MB 제한을 걸었지만, Next Server Action 기본 body limit 1MB에 먼저 걸려 generic error가 났다.

결론: 파일 업로드는 framework limit → client preflight → server validation 세 층을 모두 봐야 한다.

3.4 Auth.js error page

Google OAuth fetch timeout이나 설정 오류가 /api/auth/error?... 기본 페이지로 가면 사용자가 아무것도 할 수 없다. /login으로 error page를 라우팅하고 한국어 메시지를 보여주도록 바꿨다.


4. 마지막에 테스트를 붙인 이유

Week 3 요구사항에 “테스트 코드 포함”이 있었기 때문만은 아니다. 실제로 필요한 순간이 왔다.

  • 참여 기록 입력은 빈 값/음수/초 60 이상 같은 negative case가 중요했다.
  • 세션 필터는 URL 파라미터를 대충 parseInt하면 3abc 같은 값을 부분 parse할 수 있다.
  • 업로드 제한은 15MB와 MIME이 client/server에서 어긋나면 다시 같은 사고가 난다.
  • 세션 수정/삭제는 실제 데이터 변경이라 E2E smoke가 필요했다.

그래서 순수 함수는 Vitest, UI 조각은 RTL, 핵심 사용자 흐름은 Playwright로 나눴다.


5. 이번 주의 의도적 보류 결정

5.1 ADMIN의 다른 사람 참여 기록 수정 — 보류

권한 매트릭스상 ADMIN이 다른 사람 기록을 고칠 수 있으면 운영상 편할 수 있다. 하지만 dogfooding 결과, 현재는 각자가 자기 기록을 직접 입력하는 모델이 더 중요하다.

보류 이유:

  • 잘못 만들면 “관리자가 기록을 대신 고치는 서비스”가 되어 책임 경계가 흐려진다.
  • UI도 단순하지 않다. 행별 편집, 감사 로그, 실수 방지가 필요하다.
  • 현재 MVP에서는 본인 수정 + 세션 호스트 수정만으로 충분하다.

결론: 운영 중 실제 요청이 나오면 별도 이슈로 다룬다.

5.2 HEIC 변환 — 보류

iPhone HEIC 업로드는 허용하지만, 브라우저별 표시 호환성은 완벽하지 않다. 다만 지금 바로 서버에서 JPEG 파생본을 만드는 것은 보류한다.

보류 이유:

  • 원본 보존 정책이 중요하다.
  • 변환을 넣으면 원본/표시용 파일 2개를 관리해야 하고 orphan cleanup/백업 범위도 커진다.
  • 현재 dogfooding에서는 jpg 업로드로 충분했다.

결론: “원본 보존 + 표시용 JPEG 파생본” 설계를 따로 잡은 뒤 진행한다.

5.3 백업 자동화 — 보류

SQLite 파일 + uploads 백업은 운영상 중요하지만, 이번 주에는 자동화까지 넣지 않았다.

보류 이유:

  • 백업은 스크립트만 만드는 것보다 복구 리허설이 더 중요하다.
  • N100을 이 프로젝트 외 다른 용도로도 쓸 예정이라, 전체 서버 백업 정책과 같이 잡는 편이 낫다.
  • 급한 위험은 Docker volume 위치를 알고 수동 복사할 수 있는 상태로 낮췄다.

결론: murun-prod_data, murun-prod_uploads 수동 백업 절차를 유지하고, 자동 백업+복구 리허설은 후속 TODO로 둔다.


6. 내가 바꾼 Agent 사용 습관

  1. 버그는 바로 수정시키지 않고, 먼저 로그와 원인 후보를 분리한다.
  2. Agent가 “검증했다”고 해도 내가 실행한 명령/화면만 믿는다.
  3. 새 폼이 생기면 happy path보다 negative case를 먼저 묻는다.
  4. 배포 관련 작업은 로컬 build가 아니라 Docker/N100/prod smoke까지 본다.
  5. 문서와 .gjc/skills를 실제 다음 PR에 영향을 주는 규칙으로 유지한다.

7. 남은 일

  • 사진 업로드/교체/삭제까지 포함한 E2E 확장
  • /admin/members 승인/거절 E2E
  • 자동 백업 + 복구 리허설
  • HEIC 표시용 파생본 설계
  • 관리자 타인 기록 수정 여부 재검토
  • 실제 모바일 기기에서 장기 사용성 확인

3주차의 결론은, 뮤런이 “완성된 앱”이라기보다 실제 동아리 기록을 쌓기 시작한 운영 가능한 소프트웨어가 됐다는 점이다. 그리고 Agent 워크플로우도 문서가 아니라 PR과 테스트, 배포 과정 안에 들어가기 시작했다.

Clone this wiki locally