작업 목록

Company · Production · 2025-2026

Notiiv

4개의 서비스를 하나의 프로젝트로 관리하다

어드민, 오너, 서비스 상태, 고객지원 네 앱과 13개 공통 패키지를 pnpm·Turborepo 모노레포로 운영하며, 반복되는 인증·API·공유 로직과 웹뷰 경계를 공통 구조로 정리했습니다.

Notv

미팅 종료, 그 즉시 시작되는
당신의 스마트 비즈니스
Notv

Google Play에서 다운로드App Store에서 다운로드
9:30
녹음중
김성태님 미팅2026.05.12빅태블릿 본사 · 9층 회의실
00:38
메모 화면 모드
4 Frontend Apps
하나의 제품 모노레포
13 packages
API · Query · Schema · UI 등 공통 기반
90%+ Test Coverage
공통 패키지의 안정성

Problem

Notiiv는 pnpm workspace와 Turborepo 기반 모노레포에서 어드민, 오너 대시보드, 서비스 상태, 고객지원 4개의 앱과 API·Query·Schema·UI 등 13개 공통 패키지를 함께 운영합니다.

제품이 확장되면서 앱마다 QueryClient 설정, BFF proxy, 인증/세션 처리, 공유 경로 같은 기반 로직이 반복되기 시작했습니다. 특히 DS 조합, path validation, auth cookie 주입, SSR/브라우저 환경 차이처럼 작은 경계 조건이 여러 앱에 흩어져 있어 같은 문제를 반복해서 수정할 가능성이 있었습니다.

운영 도구에서는 기술적인 정상 동작만큼 실제 업무 흐름이 중요했습니다. FAQ 작성 화면의 preview와 실제 렌더링이 다르거나, Excel 중심의 고객 등록 흐름 때문에 소수의 고객을 직접 추가하기 번거로운 등 운영자의 작업 흐름과 UI 사이에 마찰이 있었습니다.

공유 페이지와 모바일 웹뷰에서는 또 다른 종류의 예외가 발생했습니다. 카카오톡 인앱 브라우저의 OAuth/deep link 제한, blob download 실패, 일부 브라우저의 API 부재, PDF viewer의 pinch-zoom/swipe 충돌처럼 일반 브라우저에서는 드러나지 않는 경계 조건을 안정적으로 처리해야 했습니다.

Approach

1. Shared Frontend Infrastructure

QueryClient와 BFF proxy처럼 앱마다 반복되던 기반 로직을 공통 패키지로 이동했습니다. createDefaultQueryClient factory를 만들어 앱별 설정을 override할 수 있도록 하고, admin/support에서 중복되던 BFF route는 createSimpleBffProxy로 추출해 path validation, backend URL 조합, auth cookie injection을 공통화했습니다.

WebAuthn API는 raw axios 호출 대신 Zod 기반 response parsing을 적용해 런타임 응답을 검증했습니다. 인증 과정에서 예상되는 4xx는 전역 401 redirect와 분리하고, catch-all path와 trailing slash가 포함된 서버 URL 등 BFF 경계 조건도 함께 방어했습니다.

2. Operational UX

FAQ 작성 화면은 admin preview와 실제 support 렌더링이 동일한 규칙을 사용하도록 정리하고, aria-invalid, aria-required, toolbar role, focus-visible 등 편집기의 접근성을 보강했습니다. useUnsavedChangesWarning을 적용해 작성 중 이탈을 방지하면서 정상 저장 후 redirect에는 경고가 발생하지 않도록 form state와 연결했습니다.

고객 등록은 Excel import만 제공하던 구조에서 직접 카드 입력도 지원하도록 확장했습니다. 빈 row validation, 국내 전화번호 자동 포맷, 명함 이미지 삭제와 optimistic update 등을 적용해 반복적인 운영 작업에 필요한 단계를 줄였습니다.

3. Sharing & WebView Boundaries

Business card와 meeting share path를 공통 entity package에서 관리해 생성/수신 앱이 같은 경로 규칙을 사용하도록 했습니다. 미팅 공유에는 RFC 5545 규칙에 맞춘 .ics 생성을 추가하고 UTC timestamp, TEXT escaping, 75-octet folding과 all-day event를 테스트했습니다.

카카오톡 인앱 브라우저에서는 외부 브라우저 전환을 안내하고, blob download와 crypto.randomUUID처럼 브라우저별 지원 여부가 다른 기능에는 fallback과 오류 안내를 추가했습니다.

4. Interaction Edge Cases

PDF viewer에서는 keyboard/swipe/fullscreen navigation을 제공하면서 visualViewport.scale을 기준으로 pinch zoom 중 page flip을 차단했습니다. 한국어 IME에서 shortcut 입력이 Process로 전달되는 경우에는 KeyboardEvent.code를 기준으로 처리해 입력 방식에 따른 차이를 줄였습니다.

Result

4개의 프론트엔드 앱과 13개의 공통 패키지가 하나의 pnpm·Turborepo 모노레포 안에서 같은 기반 규칙을 공유하도록 정리했습니다. QueryClient, BFF proxy, API response parsing, share path처럼 앱별로 반복되던 로직을 공통화해 동일한 문제를 여러 앱에서 반복해서 수정해야 하는 범위를 줄였습니다.

운영 도구에서는 FAQ 작성·고객 등록·명함 관리 등의 흐름을 실제 업무 방식에 맞게 개선했습니다. Preview와 실제 렌더링의 차이, 저장 전 이탈, 반복적인 입력 단계처럼 기능 오류는 아니지만 운영 과정에서 누적되는 마찰을 줄이는 데 집중했습니다.

공유 페이지와 모바일 환경에서는 카카오톡 인앱 브라우저, blob download 제한, 브라우저 API 부재, SSR URL 조합, pinch zoom과 swipe 충돌 등 실제 환경에서 발생하는 경계 조건을 명시적으로 처리했습니다.

결과적으로 이 프로젝트에서는 새로운 화면을 많이 만드는 것보다 여러 앱이 같은 기반을 공유할 수 있는 구조를 만들고, 운영 환경에서 반복적으로 발생하는 오류와 사용자 마찰을 줄이는 것에 집중했습니다.

04

근거

역할

pnpm·Turborepo 기반 멀티 앱 구조, 공통 프론트엔드 인프라, 운영 도구 UX, 인증·공유·웹뷰 경계 조건 개선

집중한 영역

pnpm monorepo · Turborepo · BFF & WebAuthn · Operational UX

기술

React · Next.js · TypeScript · TanStack Query · Zod · React Hook Form · Vitest · WebAuthn · BFF Proxy · i18n · DeepLink · react-spring · pnpm workspace · Turborepo

공개 범위

공개 제품과 저장소 구조를 기준으로 작성했으며 내부 고객·운영 데이터는 제외했습니다.

다음 작업 Bigtablet Design System