우아한형제들

10 개의 포스트

techblog.woowahan.com

태그로 필터

woowahan

끊김 없는 사용 경험을 위하여 : 카카오톡 선물함 속 교환권을 배달의민족 주문으로 연결한 여정 (새 탭에서 열림)

배달의민족 선물하기 팀은 사용자가 카카오톡으로 받은 브랜드 교환권을 배달의민족 앱에서 직접 등록하고 주문에 사용할 수 있도록 하는 '외부 교환권 연동 서비스'를 기획하고 구현했습니다. 이 프로젝트는 플랫폼 간의 기술적·비즈니스적 장벽을 허물어 사용자의 파편화된 구매 경험을 하나로 잇고, 외부의 잠재적 주문 수요를 배달의민족 생태계 안으로 흡수하는 것을 핵심 목표로 삼았습니다. 결과적으로 기술적 복잡성과 다자간의 이해관계를 극복하며 '끊김 없는 연결'이라는 사용자 중심의 가치를 실현해냈습니다. **사용자 불편 해소와 비즈니스 성장의 결합** - 카카오톡 선물을 사용하기 위해 브랜드 자사 앱을 새로 설치하거나 매장을 직접 방문해야 했던 고객의 페인포인트(Pain Point)를 해결했습니다. - 외부 플랫폼에 머물던 교환권 수요를 배달의민족 앱 내 주문으로 전환함으로써 신규 고객 유입과 락인(Lock-in) 효과를 도모했습니다. - 단순히 기능을 추가하는 것을 넘어, 플랫폼 경계를 확장하여 배달의민족을 모든 주문 경험의 통합 창구로 만들고자 했습니다. **플랫폼 간 장벽을 넘는 ‘연결’의 본질 정의** - 여러 조직이 참여하는 대규모 프로젝트에서 "플랫폼 간 장벽을 넘어 사용자에게 끊김 없는 연결을 제공한다"는 본질적인 목표를 설정하여 의사결정의 기준으로 삼았습니다. - 기술적 제약이나 비즈니스 수익성 등 이해관계가 충돌할 때마다 프로젝트의 본질을 자문하며 사용자 중심 사고를 유지했습니다. - 고립된 플랫폼 생태계를 연결함으로써 사용자에게 경험의 단절이 없는 새로운 가치를 제공하는 선례를 남겼습니다. **다자간 협업을 위한 맞춤형 소통 기술** - 카카오(플랫폼사), 브랜드사, 쿠폰 연동사 등 서로 다른 KPI를 가진 파트너들과 공통의 목표인 ‘고객 경험 개선’을 공유하며 협력을 이끌어냈습니다. - 백엔드 개발자에게는 API 응답 속도와 에러 핸들링을, 비즈니스 담당자에게는 제휴 조건과 정산 프로세스를 중심으로 설명하는 ‘맞춤형 언어’를 사용했습니다. - ‘등록·사용’(배민)과 ‘조회·승인’(연동사)처럼 서로 다른 도메인 용어와 로직을 꼼꼼히 동기화하여 시스템 간의 간극을 메웠습니다. **주도적인 문제 해결과 기술적 조율** - 단순히 요구사항을 전달하는 가교 역할을 넘어, 양사 기술팀이 합리적인 타협점을 찾을 수 있도록 API 스펙과 에러 대응 정책을 주도적으로 조율했습니다. - 다양한 외부 연동사의 시스템을 수용하면서도 배달의민족 내에서의 사용 경험을 표준화하기 위한 기술적 스펙을 정의했습니다. - 복잡한 의존 관계를 가진 작업들 사이에서 우선순위를 설정하고 일정을 관리하며 프로젝트의 항해사 역할을 수행했습니다. 이 프로젝트는 기술적 구현만큼이나 플랫폼 간의 심리적·비즈니스적 거리를 좁히는 과정이 중요함을 보여줍니다. 복잡한 시스템 연동을 앞두고 있다면, 기술 스펙에 매몰되기보다 '사용자에게 어떤 연결된 가치를 줄 것인가'라는 본질을 먼저 정의하고, 파트너의 언어로 소통하며 주도적으로 표준을 만들어가는 접근 방식이 필요합니다.

woowahan

WOOWACON 2025 미니게임 WOOWA POP! | 우아한형제들 기술블로그 (새 탭에서 열림)

우아콘 2025에서 선보인 '우아팝(WOOWA POP!)'은 단순한 이벤트를 넘어 기술적 무결성을 증명하기 위한 도전의 결과물입니다. 대규모 인원이 참여하는 랭킹 시스템에서 발생할 수 있는 조작 가능성을 차단하기 위해, 단순히 보안 솔루션을 덧붙이는 대신 게임의 동작 원리 자체를 보안 메커니즘으로 활용했습니다. 서버에서 클라이언트의 플레이 과정을 결정론적으로 재현하여 검증함으로써, 기술 콘퍼런스에 걸맞은 투명하고 공정한 게임 환경을 구축했습니다. ### 게임 보안과 수학적 증명 * 폰 노이만의 게임 이론에 따르면 모든 게임은 수학적 구조로 환원될 수 있으며, 해커는 이를 역공학하여 최적해(조작)를 찾아내는 존재입니다. * 기존의 보안 방식이나 CAPTCHA는 게임의 재미를 반감시키거나 AI 기술의 발전으로 인해 점차 무력화되는 한계가 있었습니다. * 수박 게임과 같은 물리 기반 퍼즐 게임은 수학적으로 NP-난해(NP-hard) 문제에 속하며, 답을 찾기는 어렵지만 주어진 답이 맞는지 확인하는 것은 쉽다는 특성을 가집니다. * 이를 이용해 사용자가 보낸 최종 점수를 그대로 믿는 것이 아니라, 점수에 도달하기까지의 '과정'을 증명서처럼 제출받아 서버에서 검증하는 방식을 채택했습니다. ### 결정론적 물리 엔진의 구현 * 서버가 클라이언트의 플레이를 정확히 재현하기 위해서는 동일한 입력에 대해 항상 동일한 결과가 나오는 '결정론(Determinism)'이 보장되어야 합니다. * 웹 환경의 `Math.sin`이나 `Math.cos` 같은 함수는 브라우저나 OS 엔진에 따라 미세한 오차가 발생할 수 있어, 이를 대체할 결정론적 수학 라이브러리를 사용했습니다. * 물리 엔진인 Matter.js를 활용하여 물체의 생성 위치, 시간(프레임), 충돌 계산 등을 정수 기반 혹은 오차 없는 계산 방식으로 통일했습니다. * 클라이언트는 사용자의 조작 로그(아이템 투하 위치, 타이밍 등)를 기록하여 서버로 전송하고, 서버는 Node.js 환경에서 이 로그를 그대로 시뮬레이션하여 최종 점수의 일치 여부를 판단합니다. ### 14,570점의 등장과 검증의 실효성 * 행사 기간 중 약 2,000명의 사용자가 참여했으며, 서버 로그를 통해 모든 플레이 과정이 실시간으로 검증되었습니다. * 운영 도중 물리적으로 도달하기 어려운 14,570점이라는 비정상적인 점수가 전송되었으나, 서버의 재현 시뮬레이션 결과 클라이언트가 보낸 점수와 일치하지 않음을 감지하여 자동으로 랭킹에서 제외했습니다. * 이는 별도의 복잡한 보안 툴 없이도 게임 엔진의 결정론적 특성만으로 완벽한 부정행위 방지가 가능함을 입증한 사례입니다. 단순히 점수 데이터를 주고받는 방식에서 벗어나, 실행 과정을 서버에서 재현할 수 있도록 설계하는 것은 게임뿐만 아니라 높은 신뢰성이 필요한 다양한 웹 시스템에 응용될 수 있습니다. 특히 결정론적 설계를 통해 클라이언트와 서버의 상태를 동기화하는 기법은 복잡한 비즈니스 로직의 무결성을 확보하는 데 매우 강력한 도구가 됩니다.

woowahan

Delivering the Future: 글로벌 해커톤 2025, 준비부터 운영까지 | 우아한형제들 기술블로그 (새 탭에서 열림)

딜리버리히어로 산하 전 세계 7개 엔티티의 기술직군 구성원들이 참여한 ‘글로벌 해커톤 2025’는 글로벌 기술 인재들을 하나로 연결하고 미래의 고객 경험을 혁신하기 위해 개최되었습니다. 우아한형제들 DR팀은 이번 행사의 오거나이저로서 한국에서의 커뮤니티 운영 노하우를 발휘해 서로 다른 시차와 환경을 가진 팀들이 기술적으로 협업할 수 있는 온·오프라인 하이브리드 환경을 구축했습니다. 이를 통해 전 세계 270여 명의 참가자는 구글 클라우드 등 최신 기술 스택을 활용하여 비즈니스 아이디어를 실현하며 글로벌 기술 시너지를 확인했습니다. **글로벌 협업을 위한 행사 기획과 소통 구조** * 전 세계 70여 개국에 퍼져 있는 구성원들의 참여를 독려하기 위해 각국의 공휴일과 휴가 시즌을 면밀히 분석하여 가장 참여도가 높을 것으로 예상되는 일정을 확정했습니다. * 물리적 거리의 한계를 극복하고자 각 엔티티 오피스를 '베이스캠프'로 지정해 오프라인의 몰입감을 유지하는 동시에, 라이브 중계와 온라인 채널을 연계해 전 세계를 실시간으로 연결했습니다. * 시간대 차이로 발생하는 소통의 병목 현상을 해결하기 위해 정기 회의 대신 엔티티별 개별 미팅을 진행하고, 표준화된 가이드 문서와 체크리스트를 배포하여 운영 효율성을 높였습니다. **규제와 실험의 자유를 고려한 기술 환경 구축** * 참가자들이 GCP, AWS, ML 모델 등 각자 익숙한 기술 스택을 자유롭게 활용하면서도, GDPR(EU 일반 개인정보 보호 규정)과 같은 엄격한 글로벌 보안 및 컴플라이언스 규정을 준수하도록 인프라를 설계했습니다. * 딜리버리히어로 중앙 조직이 직접 조율한 공통 기술 가이드를 마련하여 리소스 제공 범위와 데이터 접근 절차를 명확히 규정함으로써 기술적 파편화를 방지했습니다. * 구글 클라우드와의 파트너십을 통해 Google AI 기반 환경을 폭넓게 제공하여, 참가자들이 실제 현업 환경과 유사한 조건에서 고도화된 기술적 실험을 수행할 수 있도록 지원했습니다. **현지 운영과 글로벌 네트워크의 확장** * 근무 형태가 서로 다른 엔티티들이 같은 도시 내 오피스를 개방하고 공유하도록 독려하여, 소속에 관계없이 글로벌 구성원들이 자연스럽게 섞여 협업할 수 있는 분위기를 조성했습니다. * 각 엔티티의 CTO와 CPO가 예선 심사에 직접 참여하고, 딜리버리히어로 글로벌 CTO 및 구글 클라우드 디렉터가 최종 심사를 맡아 프로젝트의 비즈니스 가치와 기술적 완성도를 다각도로 검증했습니다. * 수상 팀에게는 상금과 함께 미국에서 열리는 'Google Cloud Next 2026' 참가 기회를 제공하여 해커톤 이후에도 기술적 성장이 이어질 수 있는 동기를 부여했습니다. 이번 글로벌 해커톤은 거대한 조직 규모와 지리적 제약 속에서도 공통의 기술 가이드와 명확한 운영 원칙이 있다면 전 세계 엔지니어들이 하나의 팀처럼 혁신을 만들어낼 수 있음을 보여주었습니다. 서로 다른 배경을 가진 개발자들이 기술로 소통하며 시너지를 내는 과정은 글로벌 기술 기업으로서의 결속력을 다지는 중요한 발판이 됩니다.

woowahan

배달의민족 주문접수 채널에 Flutter를 도입하며 고민한 것 | 우아한형제들 기술블로그 (새 탭에서 열림)

배달의민족 주문접수 채널은 다양한 디바이스 환경에 대응하고 개발 생산성을 극대화하기 위해 Flutter와 클린 아키텍처를 도입했습니다. 단일 코드베이스를 통해 Android, macOS 등 멀티 플랫폼 지원을 효율화하는 한편, 플랫폼별 차이는 추상화 계층으로 격리하여 유지보수성을 확보했습니다. 나아가 비즈니스 로직의 빠른 변화에 대응하기 위해 Flutter 기반 앱 셸(App Shell)에 웹뷰를 결합한 하이브리드 구조로 진화하며 일관된 사용자 경험을 제공하고 있습니다. ### 멀티 플랫폼 대응을 위한 Flutter 도입과 전략 * Windows, Android, iOS를 넘어 macOS 및 POS 환경까지 확장되는 파트너 요구사항에 대응하기 위해 단일 코드베이스인 Flutter를 선택했습니다. * "Write Once, Run Everywhere"의 이상보다는 플랫폼별 차이(업데이트 방식, 권한 관리 등)를 인정하고 공통 인터페이스로 대응하는 "Write Once, Adapt Everywhere" 접근법을 취했습니다. * 플랫폼별 구현이 다르거나 외부 라이브러리 의존성이 높은 경우, 혹은 테스트를 위해 Mock이 필요한 지점에만 선택적으로 추상화를 적용하여 불필요한 코드 복잡도를 제어했습니다. * 최근 실시간 통신 방식을 MQTT에서 SSE(Server-Sent Events)로 변경할 때, 인터페이스 기반 설계 덕분에 비즈니스 로직 수정 없이 구현체만 교체하여 작업을 완료할 수 있었습니다. ### 클린 아키텍처와 BLoC을 활용한 안정적인 상태 관리 * 계층 간 관심사를 명확히 분리하기 위해 데이터(Data), 도메인(Domain), 프레젠테이션(Presentation), 인프라(Infrastructure) 계층으로 구성된 클린 아키텍처를 적용했습니다. * 상태 관리 도구로는 BLoC(Business Logic Component) 패턴을 채택하여, 이벤트와 상태 변화를 명시적으로 로깅하고 추적함으로써 복잡한 주문 흐름의 디버깅 효율을 높였습니다. * 기능(Feature) 단위로 모듈을 분리하여 각 기능이 독립적으로 동작하고 확장될 수 있는 구조를 마련했습니다. ### 웹뷰 기반 앱 셸(App Shell)로의 전환과 유연성 확보 * 잦은 비즈니스 요구사항 변경에 실시간으로 대응하기 위해, 핵심 로직은 웹(WebView)으로 구현하고 기기 제어 기능은 Flutter(Native)가 담당하는 하이브리드 구조를 도입 중입니다. * Flutter는 프린터 제어, 오디오 출력, 푸시 알림, 로컬 DB 관리 등 하드웨어 및 OS 밀착형 기능을 '앱 셸'로서 제공합니다. * 웹과 Flutter 간의 통신은 JavaScript Bridge를 통해 이루어지며, 이를 통해 앱 스토어 심사 없이도 웹 업데이트만으로 새로운 비즈니스 기능을 즉시 반영할 수 있는 체계를 구축했습니다. 성공적인 멀티 플랫폼 서비스를 위해서는 단일 프레임워크 도입에 그치지 않고, 플랫폼별 차이를 수용할 수 있는 인터페이스 설계와 비즈니스 변화 속도에 맞춘 아키텍처(하이브리드 구조 등)를 전략적으로 선택하는 것이 중요합니다. 특히 클린 아키텍처를 통한 계층 분리는 기술적 부채를 최소화하면서도 급변하는 요구사항에 유연하게 대응할 수 있는 기반이 됩니다.

woowahan

“함께 구매하면 좋은 상품” 추천 모델 고도화 | 우아한형제들 기술블로그 (새 탭에서 열림)

배달의민족은 장보기·쇼핑 서비스에서 고객의 구매 의도를 더욱 정확하게 파악하기 위해 기존의 단순 임베딩 유사도 기반 추천에서 벗어나 구매 맥락을 반영한 2단계 추천 모델로 고도화했습니다. 기존 모델의 한계였던 대체재 편향 문제와 시퀀스 정보의 부재를 해결하기 위해 그래프 기반 임베딩과 트랜스포머(Transformer) 아키텍처를 결합한 것이 핵심입니다. 이를 통해 고객이 장바구니에 담은 상품들의 순서와 관계를 학습하여, 단순 유사 상품이 아닌 실제 함께 구매할 가능성이 높은 보완재 중심의 추천 성과를 거두었습니다. ### 기존 Item2Vec 모델의 한계와 문제점 * **대체재 편향 발생**: 기존 모델은 주문 내 동시 출현 빈도를 기반으로 임베딩을 생성하여, 비슷한 구매 패턴을 가진 상품들이 가깝게 배치되었습니다. 이로 인해 우유를 담았을 때 시리얼 같은 보완재 대신 다른 브랜드의 우유가 추천되는 등 추천의 다양성이 떨어졌습니다. * **시퀀스 맥락 소실**: 상품을 장바구니에 담는 순서에는 고객의 의도가 담겨 있지만, 기존 방식은 단순히 '함께 있었다'는 정보만 활용했습니다. 예를 들어 '라면을 담고 고기를 추가한 경우'와 '고기를 담고 라면을 추가한 경우'의 차이를 구분하지 못해 정교한 추천이 어려웠습니다. * **크로스 셀링의 어려움**: 임베딩 유사도에만 의존하다 보니 동일 카테고리 내의 상품 추천에 치중하게 되었고, 장바구니 추천의 핵심 목표인 '다른 카테고리 상품 제안(Cross-selling)'을 달성하기에 한계가 있었습니다. ### Stage 1: 그래프 기반 상품 및 카테고리 임베딩 * **Node2Vec 도입**: 주문 빈도가 낮은 롱테일 상품의 데이터 희소성 문제를 해결하기 위해 Node2Vec을 활용했습니다. 이는 그래프 구조에서 Random Walk를 통해 상품 간의 구조적 관계를 효과적으로 학습하게 해줍니다. * **그래프 구조 설계**: 상품 노드와 카테고리 노드를 함께 구성했습니다. 특히 상품 간 연결(Edge)에는 단순 빈도가 아닌 '연관 규칙(Association Rule)' 기반의 가중치를 부여하여, 인기 상품에만 편중되지 않고 실제 연관성이 높은 상품들이 강하게 연결되도록 했습니다. * **콜드 스타트 방안**: 신규 상품이나 주문 이력이 적은 상품은 카테고리 노드와의 연결을 통해 초기 임베딩을 확보할 수 있도록 설계하여 시스템의 견고함을 높였습니다. ### Stage 2: Transformer 기반 시퀀스 추천 * **맥락 이해**: Stage 1에서 생성된 고품질의 임베딩을 입력값으로 사용하여, 트랜스포머 모델이 장바구니에 담긴 상품들의 순서(Sequence)를 분석합니다. * **다음 상품 예측(Next Item Prediction)**: 고객이 현재 장바구니에 담은 일련의 상품 리스트를 바탕으로, 다음에 담을 가능성이 가장 높은 상품을 예측하는 방식으로 학습을 진행했습니다. * **동적 추천 성능**: 이 과정을 통해 고객이 요리를 위해 재료를 담는 과정인지, 혹은 간식거리를 쇼핑하는 중인지 등의 실시간 맥락을 반영한 개인화된 추천이 가능해졌습니다. 단순히 "어떤 상품과 어떤 상품이 자주 팔리는가"를 넘어 "어떤 순서로 구매 결정이 이루어지는가"를 모델링하는 것이 추천 시스템 고도화의 핵심입니다. 그래프 임베딩을 통해 상품 간의 관계를 정의하고, 트랜스포머를 통해 고객의 시퀀스 맥락을 읽어내는 2단계 구조는 데이터 희소성 극복과 추천의 정확도라는 두 마리 토끼를 잡을 수 있는 실용적인 접근법이 될 수 있습니다.

woowahan

우리는 코드처럼 문화도 리팩토링한다 (새 탭에서 열림)

배달의민족 커머스웹프론트개발팀은 조직 규모 확대에 따른 복잡도와 비효율을 해결하기 위해 문화를 코드처럼 리팩토링하며 '경계 없는 파트' 구조를 도입했습니다. 특정 도메인이나 서비스에 갇히지 않고 책임을 확장하는 R&E(Responsibility & Expandability) 원칙을 통해 기술적 통합과 조직의 유연성을 동시에 확보했습니다. 이러한 시도는 서비스 간 장벽을 허물고 구성원들이 커머스 전반을 조망하는 엔지니어로 성장하며, 비즈니스 요구에 기민하게 대응하는 결과로 이어졌습니다. ### 경계 없는 파트와 R&E 중심의 조직 구성 * **전통적 분할 방식의 탈피**: 프로젝트, 페이지, 서비스(B마트/배민스토어) 단위로 조직을 나눌 경우 발생하는 리소스 불균형과 도메인 파편화 문제를 해결하기 위해 고정된 경계를 제거했습니다. * **R&E(Responsibility & Expandability) 도입**: 단순히 주어진 역할만 수행하는 R&R을 넘어, 문제 해결을 위해 업무 영역을 스스로 확장하고 동료를 돕는 'Own It' 정신을 조직 구조에 이식했습니다. * **유연한 리소스 배분**: 약 20명의 프론트엔드 개발자를 3개 파트로 나누되, 특정 도메인에 종속시키지 않고 팀 상황에 따라 업무를 배분하여 병목 현상을 최소화했습니다. ### 기술적 통합을 통한 도메인 확장성 확보 * **통합 아키텍처 구축**: B마트와 배민스토어의 상품 카드 및 상세 화면 등 유사한 UI/UX를 공통 모듈로 추상화하고 API 구조를 맞춤으로써 코드 베이스의 일관성을 확보했습니다. * **엔지니어링 역량 강화**: 개발자들이 고객 서비스의 UX부터 어드민의 데이터 흐름까지 전방위적인 도메인을 학습하게 하여, 특정 기능 담당자가 아닌 커머스 전체를 이해하는 전문가로 성장하도록 유도했습니다. * **리스크 관리(Bus Factor 개선)**: 특정 인원이 부재하더라도 다른 팀원이 맥락을 즉시 이어받을 수 있는 구조를 만들어 프로젝트 중단 위험인 '버스 팩터'를 획기적으로 낮췄습니다. ### 지속적인 개선을 위한 소통과 기록의 리팩토링 * **의사결정 자산화(ADR)**: 단순한 기획 공유인 1Pager 방식에서 나아가, 기술적 결정의 배경과 맥락을 기록하는 ADR(Architecture Decision Record)을 도입해 팀의 지식을 체계적으로 관리합니다. * **루틴의 재설계와 자동화**: 반복적인 업무나 귀찮은 과정을 레거시로 남기지 않고, 자동화와 프로세스 개선을 통해 개발 효율성을 지속적으로 높입니다. * **심리적 안전감 기반의 협업**: '불판'과 같은 자유로운 논의 문화를 통해 실패를 과정으로 수용하고, 질문이 스터디로 이어지는 선순환 구조를 구축했습니다. 성장하는 조직에서 발생하는 비효율을 방치하지 않고, 코드 리팩토링과 같은 관점에서 구조와 문화를 끊임없이 개선하는 태도가 중요합니다. 특히 도메인 간 경계를 허무는 시도는 대규모 서비스 통합이라는 복잡한 비즈니스 과제를 해결하는 데 매우 강력한 전략이 될 수 있습니다.

woowahan

잃어버린 접근성을 찾아서 | 우아한형제들 기술블로그 (새 탭에서 열림)

웹 접근성은 단순히 점수를 높이는 기술적 과제가 아니라, 모든 사용자가 소외 없이 서비스를 이용할 수 있도록 보장하는 보편성의 가치를 실현하는 작업입니다. 우아한형제들 기술 블로그에서는 스크린 리더 사용자가 겪는 실질적인 불편함을 해결하기 위해 탐색 단위 구조화, 텍스트 통합, 상호작용 요소의 역할 구체화를 진행했습니다. 이를 통해 사용자 탐색 피로도를 획기적으로 낮추고 서비스의 본질적인 사용성을 회복하는 성과를 거두었습니다. ### 랜드마크와 머리말을 활용한 탐색 구조화 * **단위 탐색 기능 활성화**: 스크린 리더의 '로터(iOS)'나 '단위 탐색(Android)' 기능을 활용할 수 있도록 페이지를 의미 있는 섹션으로 나누고 적절한 머리말(Heading)을 배치했습니다. * **섹션 컴포넌트화**: `section` 태그와 `h1-h6` 태그, 그리고 이를 연결하는 `aria-labelledby` 속성을 조합한 재사용 가능 컴포넌트를 만들어 페이지 전체에 일관된 랜드마크 구조를 적용했습니다. * **목록 역할 명시**: CSS에서 `list-style: none`을 적용할 경우 VoiceOver가 목록으로 인식하지 못하는 문제를 해결하기 위해 `role="list"`를 명시적으로 선언했습니다. ### 파편화된 텍스트 통합과 발화 최적화 * **불필요한 스와이프 제거**: 스타일링을 위해 "990"과 "원"처럼 분리되어 있던 텍스트를 템플릿 리터럴을 통해 하나의 문자열로 결합하여 스크린 리더가 한 번에 읽도록 개선했습니다. * **스크린 리더 전용 레이어 활용**: 디자인 제약으로 태그를 분리해야만 하는 경우, 시각적 요소에는 `aria-hidden="true"`를 설정하고 보이지 않는 별도 요소에 통합된 텍스트를 담아 제공했습니다. * **크로스 플랫폼 대응**: `span`이나 `div` 같은 일반 컨테이너에 `aria-label`을 쓰면 iOS VoiceOver가 이를 무시하는 특성을 고려하여, 다양한 OS 환경에서 일관되게 읽히는 방식을 채택했습니다. ### 상호작용 요소의 목적과 맥락 명확화 * **모호한 버튼 레이블 개선**: "전체 보기", "자세히"와 같이 목적이 불분명한 버튼에 `aria-label`을 추가하여 "배달팁 자세히 보기"처럼 구체적인 동작 맥락을 제공했습니다. * **사용자 흐름 단축**: 300번 이상의 스와이프가 필요했던 비효율적인 탐색 구조를 개선하여, 사용자가 원하는 정보를 빠르게 찾고 구매하기 버튼까지 도달하는 시간을 대폭 단축했습니다. 진정한 의미의 접근성 개선은 Lighthouse 점수 100점에 안주하는 것이 아니라, 개발자가 직접 스크린 리더를 켜고 사용자의 시점에서 서비스를 탐색해 보는 것에서 시작됩니다. 자동화 도구가 잡아내지 못하는 '맥락의 단절'을 찾아내고, 의미 있는 구조(Semantic)와 구체적인 설명(Labeling)을 더할 때 비로소 모두를 위한 서비스를 완성할 수 있습니다.

woowahan

기획부터 개발까지 전부 직접 했습니다 – 우테코 7기 크루 서비스 론칭! | 우아한형제들 기술블로그 (새 탭에서 열림)

우아한테크코스 7기 크루들이 기획부터 디자인, 개발 및 운영까지 전 과정을 직접 수행하며 실제 사용자를 위한 서비스를 성공적으로 론칭했습니다. 이번 프로젝트는 단순한 기술 습득을 넘어 개발자가 왜 기획과 디자인에 참여해야 하는지, 그리고 사용자 피드백이 아키텍처와 도메인 설계에 어떤 영향을 미치는지 몸소 체험하는 과정이었습니다. 결과적으로 크루들은 2주 단위의 스프린트와 실시간 모니터링, 배포 환경 구축 등 실무에 근접한 경험을 통해 현장 중심의 문제 해결 역량을 갖춘 개발자로 성장했습니다. **개발자 중심의 기획과 협업 문화의 정착** - 우아한테크코스는 레벨 3, 4 과정을 통해 개발자가 직접 기획과 디자인을 포함한 서비스의 전주기를 책임지는 팀 프로젝트를 진행합니다. - 기술적인 구현뿐만 아니라 말하기, 글쓰기 교육을 병행하여 팀원 간의 의견 조율 및 설득 등 소프트 스킬의 중요성을 강조합니다. - 아키텍처 설계와 같은 기술적 결정이 팀의 목표와 사용자의 가치에 어떻게 부합해야 하는지 고민하며 개발자의 역할을 확장했습니다. **픽잇(Pickeat): 취향과 제약을 반영한 협업형 식사 선택 서비스** - "아무거나"라는 답변 뒤에 숨겨진 기피 음식과 다이어트 등의 제약 사항을 실시간 투표로 해결하여 최적의 식당을 추천합니다. - 위치 정보 기반의 식당 자동 조회 및 템플릿 기능을 도입하여 반복되는 회식이나 미팅 시 의사결정 속도를 높였습니다. - 데모데이와 홍보를 통해 받은 피드백을 바탕으로 UI와 백엔드 도메인 구조를 유연하게 재설계하며 사용자 중심의 반복적인 개선 과정을 거쳤습니다. **보따리(Bottari): 실시간 동기화 기반의 상황별 체크리스트** - 출근, 여행, 이사 등 다양한 상황에 맞춘 템플릿 기반 리스트 생성과 팀 단위의 실시간 협업 체크 기능을 제공합니다. - 단순한 기능 구현을 넘어 사용자가 물건을 잊지 않게 돕는 알림 타이밍과 체크 상태 동기화 등 사용자 경험(UX)의 세부 요소를 정밀하게 다듬었습니다. - '기술은 문제를 해결하는 도구'라는 철학 아래 사용자가 안심하고 기억을 맡길 수 있는 흐름을 구현하는 데 집중했습니다. **커피빵(Coffee Bread): 웹소켓 기반의 실시간 내기 미니게임** - 가위바위보보다 더 큰 재미와 긴장감을 주기 위해 실시간 미니게임과 가중치 적용 룰렛 시스템을 도입한 서비스입니다. - 웹소켓(WebSocket) 기술과 분산 환경이라는 기술적 난제를 극복하며 실시간 상호작용이 끊김 없이 이루어지도록 개발했습니다. - 게임의 공정성과 재미를 위해 룰렛 알고리즘을 수차례 수정하고, 실제 사용자들의 피드백을 반영해 밸런스를 최적화했습니다. 이 서비스들은 단순한 교육용 프로젝트를 넘어 실제 배포와 운영을 거치며 기술적 완성도를 높였습니다. 개발자가 기획 단계부터 깊이 관여할 때 사용자에게 더욱 가치 있는 프로덕트가 탄생한다는 점을 시사하며, 실무적인 문제 해결 역량을 키우고 싶은 주니어 개발자들에게 좋은 협업의 귀감이 됩니다.

woowahan

AI와 함께하는 테스트 자동화: 플러그인 개발기 | 우아한형제들 기술블로그 (새 탭에서 열림)

낮은 테스트 커버리지 문제를 해결하기 위해 AI를 활용한 테스트 자동화 도구를 개발하고 적용한 과정을 담고 있습니다. 처음에는 AI에게 모든 것을 맡기는 완전 자동화를 시도했으나 높은 컴파일 오류율로 인해 실패했고, 대신 플러그인이 구조적 템플릿을 생성하고 AI가 로직을 채우는 협업 모델을 통해 30분 만에 100개의 테스트 코드를 성공적으로 생성했습니다. 결과적으로 AI의 할루시네이션(환각) 문제를 개발 도구의 맥락 파악 능력으로 보완하여 운영 안정성을 확보할 수 있었습니다. **AI 에이전트 도입과 초기 한계** * 팀의 생산성을 위해 IntelliJ와 통합이 원활하고 프로젝트 전체 컨텍스트 이해도가 높은 Amazon Q를 도입했습니다. * 단순 AI 사용 시 매번 팀 컨벤션을 설명해야 하는 번거로움과 클래스당 약 10분의 소요 시간, 그리고 15% 정도의 빌드 오류가 발생하는 한계가 있었습니다. * 반복적인 프롬프트 작성과 의존성 수집 작업을 자동화하기 위해 IntelliJ 플러그인 개발을 결정했습니다. **플러그인 첫 버전의 실패와 문제 패턴** * 플러그인이 클래스 코드를 수집해 AI API로 직접 전체 테스트 코드를 생성하는 방식을 시도했으나, 컴파일 성공률이 10%에 불과했습니다. * 주요 실패 원인은 존재하지 않는 클래스를 참조하는 할루시네이션, Import 오류, 기존 테스트 코드를 덮어씌워 삭제하는 문제 등이었습니다. * 특히 실제 운영 환경의 멀티모듈 구조에서는 동일한 이름의 클래스가 여러 패키지에 존재하여 AI가 정확한 의존성을 판단하지 못하는 복잡성이 장애물이 되었습니다. **'컴파일 보장 템플릿'을 통한 해결** * AI에게 모든 생성을 맡기는 대신, 플러그인이 PSI(Program Structure Interface) 분석을 통해 정확한 의존성과 메서드 구조가 포함된 템플릿을 먼저 생성하도록 전략을 수정했습니다. * 플러그인은 팀의 테스트 컨벤션(Kotest, MockK 등)을 반영한 골격과 정확한 Import 문을 작성하여 컴파일 오류 가능성을 원천 차단합니다. * 이렇게 생성된 안전한 기반 위에서 Amazon Q가 구체적인 테스트 로직만 채워 넣게 함으로써 생성 정확도를 획기적으로 높였습니다. AI는 복잡한 프로젝트의 구조와 의존성을 파악하는 데 한계가 있으므로, 이를 플러그인과 같은 도구로 보완하는 '하이브리드 접근법'이 실질적인 생산성 향상의 핵심입니다. 단순히 AI에게 모든 것을 요청하기보다, AI가 가장 잘할 수 있는 '로직 구현'에 집중할 수 있도록 개발자가 정확한 맥락과 구조를 먼저 설계해 주는 도구를 구축하는 것이 권장됩니다.

woowahan

우아한형제들이 장애를 놓치지 않고 탐지하는 방법 | 우아한형제들 기술블로그 (새 탭에서 열림)

우아한형제들은 시스템 장애로 인한 고객 불편을 최소화하기 위해 서비스 지표 중심의 '서비스 이상 탐지 시스템'을 구축했습니다. 전통적인 인프라 모니터링의 사각지대를 보완하고자 실시간 데이터 예측과 임계치 관리 메커니즘을 도입했으며, 이를 통해 장애 탐지 속도와 대응 효율성을 동시에 확보했습니다. **서비스 지표 중심의 이상 탐지 필요성** * CPU, 메모리 사용률 등 전통적인 시스템 지표 모니터링만으로는 모든 장애 구간을 완벽하게 커버하기 어렵고 사각지대가 발생할 수밖에 없습니다. * 반면 주문 수, 결제 성공률 등 서비스 지표는 사용자 경험을 직접적으로 반영하며, 지표의 종류가 한정적이라 최소한의 관리로도 높은 탐지 효율을 낼 수 있습니다. * 서비스 이상 탐지 시스템은 장애가 발생했을 때 사용자 영향이 지표 변화로 나타나는 즉시 이를 포착하는 것을 목표로 합니다. **중앙값(Median) 기반의 탐지 기법 설계** * 배달 서비스 특성상 점심과 저녁 시간에 주문이 집중되는 선명한 패턴이 존재하므로, 과거 데이터를 통해 정상 범위를 비교적 쉽게 예측할 수 있습니다. * 분석의 용이성과 이상치(Outlier)에 대한 강건함을 확보하기 위해 IQR이나 2-sigma 대신 직관적인 중앙값(Median) 방식을 채택했습니다. * 복잡한 AI 모델을 사용하기보다 빠르게 구현하고 개선할 수 있는 구조를 선택하여 원인 분석과 시스템 업데이트의 속도를 높였습니다. **정확도 향상을 위한 임계 도달 횟수 관리** * 실시간으로 수집되는 실제값(Actual)이 예측된 임계값(Warning, Critical)에 도달할 때 장애를 판단합니다. * 일시적인 지표 튀기 현상으로 인한 오탐(False Positive)을 방지하기 위해, 임계값에 특정 횟수 이상 연속으로 도달했을 때만 경보를 발생시키는 '임계 도달 횟수'를 관리합니다. * 탐지 속도(낮은 횟수 설정)와 정확도(높은 횟수 설정) 사이의 트레이드오프를 고려하여 각 지표의 성격에 맞는 최적의 안정화 기간을 거칩니다. **신속한 대응을 위한 경보 및 프로세스 연계** * 장애 탐지 시 슬랙(Slack) 채널로 지표 현황, 긴급도, 그래프가 포함된 경보를 즉시 발송하여 상황 파악을 돕습니다. * 단순히 알림을 보내는 데 그치지 않고, 장애 숙련도와 관계없이 누구나 표준화된 절차에 따라 대응할 수 있도록 후속 프로세스 가이드를 함께 제공합니다. 장애는 완벽히 막을 수 없지만 탐지 시간은 단축할 수 있습니다. 복잡한 알고리즘에 매몰되기보다 서비스의 비즈니스 패턴을 명확히 분석하고, 가장 직관적인 지표와 통계 모델을 적용하는 것이 실무적인 관점에서는 훨씬 강력한 장애 대응 체계를 만드는 방법입니다.