11월은 ADHD Ad Hell 백엔드 프로젝트를 기반으로 한 프론트엔드 프로젝트에 올인한 한 달이었다.
그동안 포스트맨으로만 확인하던 API들을 실제 화면 위에 올리고, 로그인부터 알림까지 전체 흐름을 Vue로 구현하는 데 집중했다.
일정은 여전히 빠듯했고, 날씨도 갑자기 추워져서 컨디션 관리가 쉽지 않았다. 그래도 한 달을 돌아보면, 백엔드에서 설계하고 만들어 두었던 기능들을 실제 웹 화면에서 동작하게 만든 시기였고, 서비스의 한 사이클을 처음부터 끝까지 경험 했다는 점에서 의미가 컸다.

알림 기능 전반을 담당했고, 다음과 같은 기능들을 프론트엔드에서 구현했다.
알림 템플릿 목록 조회

알림 템플릿 검색

알림 템플릿 등록

알림 템플릿 수정

알림 템플릿 삭제

알림 발송 목록 조회

발송 알림 검색

즉시 알림 발송

푸시 알림 발송

이벤트 알림 발송

예약 알림 발송

알림함 화면 구현

백엔드에서 구현했던 알림 API들을 실제 화면으로 옮기면서, 단순 기능 구현을 넘어 UX 흐름까지 고려해야 하는 단계로 나아가게 된 한 달이었다.
Vue 3와 Composition API를 기준으로 프로젝트 구조를 잡았다.
pages
components
composables
api
store
API 계층은 도메인 단위로 분리했다.
authApi, userApi, adApi, reportApi, notificationApi 등으로 나누어 관리
Axios 인스턴스를 공통으로 만들고, 인터셉터를 통해 다음을 처리하도록 구성했다.
모든 요청에 인증 토큰 자동 첨부
토큰 만료 시 Refresh Token 기반 재발급 처리
상태 관리는 Pinia를 중심으로 두고, 복잡한 비즈니스 로직은 composable로 따로 뽑는 구조를 시도했다.
알림 목록 로딩, 페이지네이션, 읽음 처리, 뱃지 갱신 같은 반복 로직은 composable로 분리
컴포넌트는 화면 표현에 집중하도록 역할을 나누는 방향으로 정리
관리자 페이지에서 사용할 알림 템플릿 관리 화면을 구현했다.
템플릿 목록 조회, 검색 필터, 상세 보기
템플릿 신규 등록과 수정, 삭제
텍스트 입력과 변수 영역, 템플릿 타입 선택 등 폼 구조 설계
알림 발송 이력을 확인할 수 있는 화면을 만들었다.
발송 목록 페이징, 발송 상태 필터, 키워드 검색
어떤 템플릿이 언제, 누구에게, 어떤 방식으로 발송되었는지 확인
발송 기능은 다음과 같이 나눠서 구현했다.
즉시 알림 발송 화면
푸시 알림 발송
이벤트 알림 발송
예약 알림 발송
발송 요청 시 어떤 필드가 필요한지, 백엔드에서 정의한 DTO를 기준으로 다시 한번 정리하면서 API 연동을 진행했다.
사용자 입장에서 알림을 확인하는 알림함 화면을 구현했다.
읽지 않은 알림 탭과 전체 알림 탭
알림 타입별 아이콘, 요약 메시지, 시간 표시
읽음 처리 버튼 및 전체 읽음 처리
SSE 기반 실시간 알림 시스템과의 연동도 진행했다.
백엔드에서 구현해 둔 SSE 알림 스트림을 Vue에서 EventSource로 구독
새 알림이 오면 목록과 헤더 뱃지가 실시간으로 갱신되도록 처리
증상
로그인 직후 헤더 알림 아이콘의 뱃지 숫자가 0으로 표시되다가, SSE 연결이 완료된 후에서야 실제 안 읽은 알림 개수로 바뀌는 문제가 있었다.
사용자 입장에서는 로그인 직후 알림이 있는데도 없는 것처럼 보이는 어색한 경험이 발생했다.
원인
초기 알림 개수를 SSE 이벤트에만 의존하고 있었다.
로그인 후 SSE 구독이 연결될 때까지 시간이 걸리는 동안, 뱃지는 기본값인 0으로 남아 있었다.
해결
로그인 성공 이후, 즉시 REST API 호출로 현재 읽지 않은 알림 개수를 가져오도록 흐름을 바꿨다.
notifications unread-count 엔드포인트를 호출해 초기 뱃지 상태를 세팅
SSE는 새 알림이 도착하거나 읽음 처리가 발생하는 등 실시간 변동만 반영하도록 역할 분리
개선 효과
로그인 직후 화면에서 바로 정확한 알림 개수를 볼 수 있게 되었고
그 이후에는 SSE를 통해 자연스럽게 실시간으로 숫자가 갱신되면서 UX가 훨씬 부드러워졌다.
실시간 기능을 설계할 때에도 초기 상태 로딩과 실시간 업데이트를 분리해야 한다는 점을 몸으로 느낀 경험이었다.
11월 한 달은 프론트엔드 프로젝트에 집중하면서,
10월까지 백엔드에서 설계하고 테스트하던 기능들을 실제 화면과 연결해 본 시간이었다.
아쉬웠던 점은 크게 두 가지였다.
첫째, 건강과 컨디션 관리
날씨가 갑자기 추워지고 병원에 다녀올 일도 생기면서, 몸 상태가 들쭉날쭉했다.
몸이 피곤하니 집중력이 떨어지고, 같은 실수를 반복하게 되는 일이 잦았다.
다음 프로젝트에서는 일정만이 아니라 체력까지 감안한 계획이 필요하다는 생각이 들었다.
둘째, 항상 부족했던 시간
프론트엔드 경험이 많지 않았던 탓도 있고, 구현해야 할 기능 수가 많아서
최대한 빠르게 돌아가게 만드는 것에 집중하다 보니 코드 구조나 디자인 디테일을 챙기지 못한 부분이 있다.
리팩토링 여지를 남긴 채 기능 위주로 달려야 했던 점이 조금 아쉬웠다.
그럼에도 불구하고, 백엔드 프로젝트 때 포스트맨으로만 확인하던 기능들을
실제 프론트 화면에서 로그인하고, 버튼을 누르고, 알림 목록이 뜨는 과정을 눈으로 보니 큰 성취감이 있었다.
요청부터 응답까지의 흐름이 단순한 이론이 아니라 실제 서비스의 사용자 경험으로 이어진다는 점이 인상 깊었다.
Vue 3와 Composition API 기반의 모듈 구조 설계
pages, components, composables, api, store 구조를 실제 프로젝트 수준에서 구성
API 계층을 도메인 단위로 완전히 분리
authApi, userApi, adApi, reportApi, notificationApi 등으로 나누어 관리하며,
기능이 늘어나도 API 레이어가 뒤엉키지 않도록 정리
Axios 인스턴스와 인터셉터 설정
공통 인스턴스를 두고, 인증 처리와 토큰 재발급을 인터셉터에서 처리하여
개별 API 호출부의 중복 코드 최소화
Pinia와 composables를 활용한 상태 관리
상태 저장과 비즈니스 로직을 분리하여
불필요한 렌더링을 줄이고, 재사용성을 높이는 패턴을 프로젝트 전체에 적용
단일 서비스가 아닌 Core 서비스와 Notification 서비스 분리 구조 경험
프론트 기준에서도 두 서비스가 어떻게 나뉘고 어떤 경로로 통신하는지 체감하며 개발
SSE 기반 실시간 알림 시스템 구현
JWT 인증과 인가, Refresh Token 재발급 플로우와 함께
로그인 이후에도 안정적으로 알림 스트림을 유지하는 구조를 직접 구현하고 테스트
Git 브랜치 전략 운영
dev 브랜치를 기준으로 기능별 feature 브랜치를 분리해 동시에 개발
충돌을 줄이고, 기능 단위로 변경 사항을 관리하는 흐름에 익숙해졌다.
Pull Request 기반 코드 리뷰
기능 개발 후 PR을 올리고, 리뷰 후 머지하는 과정을 반복
다른 사람들이 보게 될 코드를 작성한다는 의식을 조금씩 갖게 되었다.
API 명세에서 구현, 연동까지 End-to-End 경험
URI와 요청, 응답 스펙을 정리하고
백엔드 구현 후 프론트 연동, 그리고 포스트맨과 실제 화면에서의 검증까지
한 줄기의 흐름으로 경험한 것이 큰 자산이 되었다.
데일리 공유와 주간 회고를 통한 일정 관리
매일 진행 상황과 이슈를 공유하고, 남은 기간을 고려해 우선순위를 조정했다.
일정이 촉박해도 어떤 기능을 먼저 끝내야 할지 논의하며 조율할 수 있었다.
역할 분담과 인터페이스 정의를 통한 병렬 개발
도메인별 담당자를 나누고, 화면과 API 인터페이스를 먼저 정의한 뒤
프론트와 백엔드를 병렬로 개발하는 흐름을 익혔다.
Spring Security, JWT, SSE 등 백엔드 핵심 기술을
실제 프론트 화면과 연결된 상태에서 다시 다뤄 보면서 이해가 더 깊어졌다.
로그, 포스트맨, 브라우저 콘솔 디버깅을 종합적으로 사용해
어디에서 문제가 발생하는지 추적하는 능력이 개선되었다.
단순 CRUD를 넘어 인증, 알림, 로그 관리까지 포함된 기능들을
직접 설계하고 구현해 보면서 서비스 전체를 보는 관점이 생겼다.
예외와 에러 상황을 미리 고려해 방어적으로 설계하려는 습관이 조금씩 자리 잡았다.
레이어 분리와 공통 모듈화를 고려하며 코드를 작성하면서
나중에 리팩토링할 때를 염두에 두는 감각을 익혔다.
11월은 ADHD Ad Hell 백엔드 프로젝트 위에 프론트엔드라는 외형을 입힌 한 달이었다.
알림이라는 하나의 도메인을 시작부터 끝까지 가져가 보며,
백엔드 로직과 프론트 화면을 묶는 작업이 얼마나 많은 고민을 요구하는지 체감할 수 있었다.
시간 부족과 건강 관리의 어려움이라는 한계도 분명 있었지만,
실제로 사용 가능한 화면과 기능을 완성해 본 경험은 그만큼 값졌다.
12월에는 DevOps 프로젝트와 최종 프로젝트로 이어지는 만큼
이번에 익힌 Vue 구조와 협업 방식, 그리고 컨디션 관리에 대한 교훈을 잘 살려서
좀 더 안정적이고 완성도 높은 결과물을 만드는 한 달로 이어가고 싶다.