Showing Posts From
Figma
- 09 Dec, 2025
Figma 화면 정의, 개발자가 이해할 수 있게
Figma 화면 정의, 개발자가 이해할 수 있게 디자이너가 준 파일 어제 디자이너한테 화면 받았다. Figma 열었다. 예쁘다. 인터랙션도 화려하다. 프로토타입 클릭하니까 움직인다. 근데 개발자한테 공유했더니 슬랙이 왔다. "K님, 이 버튼 눌렀을 때 정확히 어떤 조건에서 어떻게 되는 거예요?" "로딩은 어느 타이밍에 보여주나요?" "에러 케이스는요?" 디자이너는 열심히 했다. 나도 확인했다. 근데 개발자 입장에선 부족하다. 항상 이렇다. 예쁜 화면과 개발 가능한 스펙은 다르다는 걸 또 배웠다.프로토타입의 함정 디자이너들은 프로토타입 툴을 잘 쓴다. Figma에서 클릭하면 화면이 넘어간다. 애니메이션도 들어간다. 멋있다. 근데 이게 함정이다. 프로토타입은 해피 케이스만 보여준다. 버튼 누르면 다음 화면. 스크롤하면 콘텐츠 나옴. 이게 전부다. 실제 개발은 다르다.로딩 중엔 뭘 보여줄까 API 실패하면 어떻게 할까 데이터가 없으면 어떤 화면 인터넷이 끊기면 동시에 두 번 클릭하면이런 거 프로토타입엔 없다. 디자이너도 모른다. 기획자가 정해야 한다. 작년에 있었던 일이다. 찜하기 버튼 기능. 디자이너는 하트 아이콘 누르면 빨갛게 채워지는 애니메이션 만들었다. 예뻤다. 개발자가 물었다. "연타하면요? API 응답 오기 전에 또 누르면요?" 그때 정의 안 했다. 나중에 QA에서 터졌다. 연타하니까 찜 목록이 꼬였다. 핫픽스 나갔다. 새벽에. 프로토타입 보고 다 됐다고 착각하면 안 된다.개발자가 원하는 건 따로 있다 개발자랑 협업 6년째다. 그들이 뭘 원하는지 알게 됐다. 예쁜 화면 아니다. 명확한 스펙이다. 명확한 스펙이란:이 데이터는 어디서 오나 (API 명세) 언제 호출하나 (타이밍) 실패하면 어떻게 하나 (에러 핸들링) 조건은 뭐냐 (if문에 들어갈 것들) 우선순위는 (뭘 먼저 만들까)디자인 파일에 이런 거 없다. 당연하다. 디자이너 일이 아니니까. 기획자가 해야 한다. 우리 팀 개발자 말이 있다. "디자인은 참고만 합니다. 스펙 보고 개발합니다." 처음 들었을 땐 서운했다. 디자이너랑 열심히 만들었는데. 근데 맞는 말이다. 개발자는 코드로 구현한다. 코드는 명확해야 한다. "대충 이런 느낌"은 코드가 안 된다. 그래서 나는 Figma 파일에 스펙을 박는다. 컴포넌트마다 코멘트로.내가 하는 방법 1. 컴포넌트별 코멘트 Figma에서 컴포넌트 선택하고 우클릭. 코멘트 단다. 예시: [로그인 버튼] - 상태: 활성/비활성 - 활성 조건: 이메일 형식 valid + 비밀번호 6자 이상 - 비활성 시: opacity 40%, 클릭 불가 - 클릭 시: 로딩 스피너 표시 (버튼 내부) - API: POST /auth/login - 성공: 홈 화면 이동 - 실패: 토스트 메시지 "로그인에 실패했습니다" (3초)처음엔 귀찮았다. 근데 이거 안 하면 슬랙 폭탄 맞는다. 미리 쓰는 게 낫다. 2. 플로우 차트 따로 프로토타입은 해피 케이스. 나는 FigJam으로 플로우 차트 그린다. 모든 분기 다 그린다.성공 케이스 실패 케이스 로딩 케이스 엣지 케이스개발자들이 이걸 더 좋아한다. 한눈에 보인다. 지난주 결제 기능 기획했다. 프로토타입은 단순했다. 버튼 누르면 완료 화면. 플로우 차트엔 14개 분기가 있었다.결제 수단 선택 전 잔액 부족 네트워크 에러 서버 에러 결제 취소 중복 결제 방지 ...이거 다 정의했다. 개발자가 고맙다고 했다. "이러면 개발 시작할 수 있어요." 3. 스펙 문서 별도 Figma는 디자인 툴이다. 스펙 문서는 아니다. 나는 Notion에 스펙 문서 따로 쓴다. 구조: # 화면명## 개요 - 목적 - 유저 플로우상 위치## 화면 구성 - 상단: 헤더 (뒤로가기, 타이틀) - 중단: 입력 폼 - 하단: 버튼## 상태 정의 ### State 1: 초기 - 데이터: 없음 - 버튼: 비활성### State 2: 입력 중 - 데이터: 부분 입력 - 버튼: 조건부 활성## API 정의 ### 요청 - Method: POST - Endpoint: /api/user/profile - Body: { name, email, phone }### 응답 - 200: 성공 - 400: 유효성 검사 실패 - 500: 서버 에러## 에러 처리 - 네트워크 에러: "인터넷 연결을 확인해주세요" - 서버 에러: "잠시 후 다시 시도해주세요" - 유효성 에러: 필드별 메시지 표시## 애널리틱스 - 화면 진입: screen_view_profile_edit - 버튼 클릭: click_save_profile - 성공: success_save_profile - 실패: fail_save_profile이거 쓰는 데 2시간 걸린다. 근데 안 쓰면 개발하면서 질문 100개 온다. 2시간이 싸다. 개발자와 리뷰 스펙 다 정의했다고 끝 아니다. 개발자랑 리뷰한다. 우리 팀은 '스펙 리뷰 미팅'을 한다. 30분. 개발 시작 전에. 내가 준비한 것:Figma 링크 플로우 차트 스펙 문서미팅에서 하는 것:화면 하나씩 설명 개발자 질문 받음 애매한 거 즉석 정리 예상 공수 확인이 미팅에서 항상 나온다. "이거 이렇게 하면 안 되나요?" "이 API는 없는데요." "이거 기술적으로 어려운데요." 좋다. 개발 시작 전에 알았다. 여기서 틀어지면 기획 수정한다. 개발 중에 틀어지는 것보다 100배 낫다. 지난달에 있었던 일. 실시간 알림 기능 기획했다. 웹소켓 써야 한다고 생각했다. 스펙 리뷰 미팅에서 백엔드 개발자가 말했다. "웹소켓 인프라 없어요. 구축하려면 2주 걸려요." 그 자리에서 폴링 방식으로 바꿨다. 30초마다 API 호출. 완벽하진 않지만 동작한다. 일정 맞췄다. 미팅 안 했으면 개발 중에 알았을 것이다. 일정 다 틀어졌을 것이다. 인터랙션 명세 디자이너가 만든 인터랙션 예쁘다. 근데 개발자는 숫자로 말해야 한다. "부드럽게 나타나요" → 개발자: "몇 초요?" "자연스럽게 사라져요" → 개발자: "어떤 easing이요?" 나는 인터랙션 명세를 쓴다. 예시: [모달 등장] - Duration: 0.3s - Easing: ease-out - Transform: translateY(100%) → translateY(0) - Opacity: 0 → 1 - Backdrop: opacity 0 → 0.6 (0.2s)[버튼 눌림] - Scale: 1 → 0.95 - Duration: 0.1s - Feedback: haptic (iOS만)[리스트 로딩] - Skeleton: 3개 표시 - Duration: 최소 0.5s (너무 빠른 깜빡임 방지) - 실패 시: 3초 후 재시도 버튼 표시디자이너한테 물어본다. "이 애니메이션 몇 초로 할까요?" 대부분 모른다. 함께 정한다. 0.3초, 0.5초 차이 크다. 개발자한테 준다. 질문 안 온다. 에러 케이스가 반이다 디자이너는 성공 케이스 그린다. 당연하다. 그게 메인이니까. 근데 실제 서비스에선 에러가 반이다. 내가 정의하는 에러:네트워크 에러 (연결 끊김) 서버 에러 (500, 502, 503) 인증 에러 (401, 403) 유효성 에러 (400) 타임아웃 (느린 네트워크) 데이터 없음 (empty state) 권한 없음 중복 요청 방지각각 어떻게 처리할지 정한다. 토스트? 모달? 인라인 메시지? 페이지 전환? 예시: [네트워크 에러] - 표시: 토스트 "인터넷 연결을 확인해주세요" - 위치: 하단 중앙 - 지속: 3초 - 액션: 재시도 버튼 (선택)[서버 에러] - 표시: 풀스크린 에러 페이지 - 메시지: "일시적인 오류가 발생했습니다" - 액션: "다시 시도" 버튼 → 이전 액션 재시도[데이터 없음] - 표시: Empty state 일러스트 - 메시지: "아직 내역이 없어요" - 액션: "추가하기" 버튼 → 생성 플로우로 이동이거 안 정하면 개발자가 알아서 한다. 그럼 일관성 없다. 어떤 에러는 토스트, 어떤 에러는 모달. 유저 혼란스럽다. 데이터 상태별 화면 API 호출하면 3가지 상태다.로딩 중 성공 실패각 상태마다 화면 다르다. 다 정의해야 한다. 예시: 피드 목록 화면 로딩 중Skeleton UI 3개 표시 상단 새로고침 인디케이터 스크롤 비활성성공 (데이터 있음)리스트 표시 Pull to refresh 활성 무한 스크롤성공 (데이터 없음)Empty state "아직 피드가 없어요" CTA 버튼실패에러 메시지 재시도 버튼 이전 캐시 데이터 표시 (선택)디자이너는 보통 "성공 (데이터 있음)" 화면만 그린다. 나머지는 내가 추가한다. Figma에 페이지 4개 만든다. 로딩/성공/Empty/에러. 개발자가 다 볼 수 있게. 우선순위 표시 기능 많으면 다 못 만든다. 시간 부족하다. 우선순위 정해야 한다. 나는 MoSCoW 방식 쓴다.Must: 필수. 이거 없으면 릴리즈 못함 Should: 중요. 있어야 하는데 밀리면 다음 스프린트 Could: 있으면 좋음. 여유되면 Won't: 안 함. 나중에 재논의Figma 코멘트에 표시한다. [M] 로그인 버튼 - 핵심 기능 [S] 자동 로그인 체크박스 - 유저 편의 [C] 생체 인증 로그인 - Nice to have [W] 소셜 로그인 - 다음 스프린트개발자들이 뭐부터 만들지 안다. 일정 타이트하면 M만 만든다. 릴리즈 한다. 나머지는 다음에. 이거 안 하면 개발자가 순서대로 만든다. Figma에 위에서부터. 그럼 Won't 먼저 만들고 Must 못 만드는 경우 생긴다. 우선순위는 기획자가 정해야 한다. 실제 데이터로 테스트 디자인 파일엔 예쁜 더미 데이터 들어있다.이름: "홍길동" 이메일: "hong@example.com" 한 줄 소개: "안녕하세요"실제는 다르다.이름: "Alexander Maximilian Constantine III" 이메일: "verylongemailaddress123456789@subdomain.domain.co.kr" 한 줄 소개: "안녕하세요반갑습니다저는서울에사는개발자입니다코딩을좋아하고커피를사랑합니다취미는등산이고..."텍스트 길면 레이아웃 깨진다. 항상. 나는 엣지 케이스 데이터 준비한다.최대 길이 텍스트 특수문자 (emoji 포함) 줄바꿈 여러 개 숫자 0, 음수, 아주 큰 수 빈 값Figma에 "엣지 케이스 테스트" 페이지 만든다. 이 데이터로 화면 그린다. 깨지는 거 미리 확인한다. 개발자랑 공유한다. "이 경우엔 말줄임(...)으로 처리해주세요" 같은 가이드 준다. 반응형 고려 모바일 앱 기획해도 디바이스 여러 개다.iPhone SE: 작음 iPhone Pro: 표준 iPhone Pro Max: 큼 iPad: 더 큼똑같은 화면이 다 다르게 보인다. 나는 최소 2가지 사이즈 정의한다.Small (iPhone SE 기준) Large (iPhone Pro Max 기준)Figma에서 프레임 2개 만든다. 같은 화면, 다른 사이즈. 버튼 크기, 텍스트 줄 수, 이미지 비율, 다 달라진다. 개발자한테 말한다. "이 컴포넌트는 flexible하게, 이건 fixed로." 안 그러면 개발자가 하나 사이즈로 만든다. Pro에선 예쁘다. SE에선 깨진다. QA에서 터진다. 개발 중 커뮤니케이션 스펙 다 정의했다. 개발 시작했다. 끝난 거 아니다. 개발 중에 계속 질문 온다. 당연하다. 스펙이 완벽할 순 없다. 나는 슬랙 채널 만든다. "#프로젝트명-개발" 규칙:질문은 여기서만 답변은 12시간 내 결정사항은 Notion 스펙 문서에 바로 반영개발자가 묻는다. "이 경우엔 어떻게 해요?" 나는 답한다. 바로. 애매하면 "30분 후에 답변드릴게요" 하고 정리한다. 절대 안 하는 것: "음... 좀 더 생각해볼게요" 하고 며칠 방치. 개발자는 기다린다. 내가 답 안 하면 일 못 한다. 블로킹 된다. 일정 밀린다. 빠른 의사결정이 좋은 기획이다. 완벽한 기획보다. 개발 완료 후 QA 준비 개발 끝났다. QA 넘긴다. 나는 QA 시나리오 미리 쓴다. 구조: # TC-001 로그인 성공 1. 로그인 화면 진입 2. 유효한 이메일 입력 3. 유효한 비밀번호 입력 4. 로그인 버튼 클릭 예상 결과: 홈 화면 이동# TC-002 로그인 실패 (잘못된 비밀번호) 1. 로그인 화면 진입 2. 유효한 이메일 입력 3. 잘못된 비밀번호 입력 4. 로그인 버튼 클릭 예상 결과: "비밀번호가 일치하지 않습니다" 토스트 표시# TC-003 네트워크 에러 1. 로그인 화면 진입 2. 비행기 모드 켜기 3. 로그인 버튼 클릭 예상 결과: "인터넷 연결을 확인해주세요" 토스트 표시이거 있으면 QA가 체계적으로 된다. 빠진 케이스 없다. QA에서 버그 나온다. 당연하다. 근데 "스펙과 다르다"와 "스펙이 없었다"는 다르다. 스펙 있으면: 개발자가 고친다. 명확하다. 스펙 없으면: "이거 기획 실수 아닌가요?" 논쟁 시작. 시간 낭비. 스펙을 명확히 하는 게 QA를 빠르게 한다. 회고 이번 스프린트 끝났다. 릴리즈 했다. 회고 미팅 한다. 나는 항상 묻는다. "스펙 정의가 명확했나요?" 개발자들이 답한다. 솔직하게. "이 부분은 애매했어요." "이건 나중에 알려주셔서 일정이 밀렸어요." "이 부분은 정말 명확해서 좋았어요." 피드백 받는다. 다음 스프린트에 반영한다. 6년 전엔 스펙을 대충 썼다. "디자인 보고 만들어주세요." 그랬다. 지금은 다르다. 개발자가 질문 없이 만들 수 있게 쓴다. 여전히 부족하다. 계속 배운다. 기획자는 디자이너도 아니고 개발자도 아니다. 둘을 연결하는 사람이다. 디자이너의 예쁜 화면을 개발자의 코드로 만들려면 번역이 필요하다. 그게 스펙 정의다. Figma 파일이 예쁜 게 중요한 게 아니다. 개발자가 이해할 수 있게 정리하는 게 중요하다.스펙 명확하면 개발 빠르다. 질문 줄어든다. 결과물 예측 가능하다. 그게 좋은 기획이다.