Skip to main content
← 블로그

회고 표시 바 하나 넣으려다 — 노랑 팔레트 교체부터 API 버그까지

VauDium ·

태스크 리스트에 '이 태스크는 회고가 작성됐다'는 작은 표시 하나 넣으려다 SECONDARY 팔레트를 갈아엎고 API 버그까지 고친 이야기.

회고 표시 바 하나 넣으려다

사소한 아이디어

“태스크 리스트에서 회고가 작성된 건지 한눈에 보이면 좋겠어.”

태스크를 완료하면 만족도(satisfaction)를 찍고 회고(retrospect)를 쓸 수 있습니다. 근데 리스트로 돌아오면 어떤 게 회고까지 끝났는지, 어떤 건 아직인지 알 수 없었습니다. 모든 완료된 태스크가 똑같이 보이니까요.

표시 하나만 붙이면 될 것 같았습니다.

어디에, 어떻게 표시할까

첫 시도는 State 아이콘 옆에 작은 점. SectionToggleBar에서 이미 쓰던 패턴이었습니다.

“노란색이면 회고답겠지” → SECONDARY500으로 점을 찍어봤습니다.

“탁하고 눈에 안 띈다.” → WARNING500(오렌지)로 바꿔봤습니다.

“이건 REVIEW 느낌이 아니야.” 정확한 지적이었습니다. 경고 아이콘 같은 오렌지는 “잘 해냈다”는 긍정적 회고의 느낌과 어긋납니다.

”명시적으로 REVIEWED라고 쓰자”

그래서 프로젝트 약어 옆에 REVIEWED 배지를 붙여봤습니다.

“저기는 별로인 것 같아.”

그럼 작은 R 한 글자로 State 아이콘 아래에? 문제는 아이템이 세로로 길어진다는 것이었습니다. absolute 포지셔닝으로 해결했더니, 이번엔 특정 State에서만 R이 보이는 현상이 나타났습니다.

진짜 문제는 서버에 있었다

“satisfaction을 수정했는데 R이 안 보여.”

테스트 중 발견한 현상이었습니다. 원인을 로그로 찾아봤더니 — 클라이언트가 아니라 서버 버그였습니다.

Fecit의 태스크 엔드포인트는 대부분 수정 시 revision, revised_at, revised_by를 함께 bump합니다. 증분 sync의 커서로 사용되는 필드들입니다. 그런데 satisfaction/set 엔드포인트만 이걸 누락하고 있었습니다.

# retrospect/set — 제대로 되어 있음
'$set': {
    'retrospect': ticket.retrospect,
    'revised_at': datetime.now(timezone.utc),
    'revised_by': achiever.id,
    'revision': new_revision,
}

# satisfaction/set — 누락
'$set': {
    'satisfaction': ticket.satisfaction,
}

같은 패턴이 task/template의 satisfaction 엔드포인트에도 있었습니다. 두 군데 다 수정. 이제 만족도를 바꿔도 sync가 다른 기기로 제대로 전파됩니다.

바로 돌아가자

R 표시는 레이아웃에 계속 영향을 줬습니다. 결국 오른쪽 바로 돌아갔습니다. STARTED 상태일 때 왼쪽에 나타나는 펄스 바와 같은 형태를, 반대쪽에, 다른 색으로.

{hasReviewContent && (
    <View style={{
        position: "absolute", inset: 0,
        borderRadius: 8,
        borderRightWidth: 3,
        borderRightColor: palette.SECONDARY500,
    }} />
)}

레이아웃을 건드리지 않고, STARTED 바와 대칭을 이루면서, 색으로 도메인을 구분합니다.

”근데 노랑이 녹색 섞여 있지 않아?”

여기서 유저(=저)가 팔레트를 의심합니다.

SECONDARY500의 원본 값: #E0D147 = rgb(224, 209, 71). G 채널이 R에 너무 근접합니다. 순수 노랑이라면 R ≫ G ≈ 준중간, B ≈ 0이어야 하는데, 이 값은 올리브/연두 기운이 강하게 섞여 있었습니다.

Tailwind의 yellow 팔레트로 갈아엎었습니다:

SECONDARY50  = "#FEFCE8"
SECONDARY100 = "#FEF9C3"
SECONDARY200 = "#FEF08A"
SECONDARY300 = "#FDE047"
SECONDARY400 = "#FACC15"
SECONDARY500 = "#EAB308"
SECONDARY600 = "#CA8A04"
SECONDARY700 = "#A16207"
SECONDARY800 = "#854D0E"
SECONDARY900 = "#713F12"

다크 모드는 PRIMARY처럼 스케일을 반전했습니다. 50이 어두운 갈색, 900이 연한 크림색. 어두운 배경에서도 충분히 눈에 띄면서 밝은 모드와 동일한 의미를 유지합니다.

노랑을 짙게 하면 주황이 될까?

작업 중에 나온 질문입니다.

답은 — 정확히는 아닙니다. 노랑의 hue를 유지한 채 명도(L)를 낮추면 RGB가 #EAB308 → #A16207 → #713F12처럼 올리브나 브라운 계열로 수렴합니다. 물리적으로 “짙은 노랑”에 가장 가까운 색이 사실상 갈색이기 때문입니다.

오렌지는 노랑보다 hue 자체가 빨강 쪽에 가까운 별개의 색상입니다. 노랑을 어둡게 한다고 오렌지가 되지 않습니다. 오렌지빛 갈색을 만들려면 R 채널을 의도적으로 더 남기면서 어둡게 해야 합니다.

교훈

  1. 작은 UI 하나가 팔레트 전체를 뒤흔들 수 있다. 리뷰 바가 WARNING과 구분 안 되는 걸 보고서야 SECONDARY의 올리브 기운을 발견했습니다.

  2. 추측 말고 찍어보자. “왜 R이 COMPLETED에서만 보이지?”를 레이아웃 문제로 의심하다가, 실제로는 데이터(satisfaction revision)가 원인이었습니다. 증상 재현해보고 로그 찍는 게 먼저였습니다.

  3. 대칭을 쓰자. STARTED 왼쪽 바와 똑같은 패턴을 오른쪽에 뒤집어 놓는 것만으로, 사용자는 “의미가 있구나”를 직관적으로 느낍니다. 별도 설명 없이도.

  4. 색 상수는 이름으로 의미를 주지만, 값이 의미를 배신할 수 있다. SECONDARY라는 이름 뒤에 올리브색이 숨어 있었듯이, 상수 이름만 믿지 말고 실제 픽셀을 가끔 들여다봐야 합니다.

표시 바 하나 붙이려다 서버 코드 두 군데, 팔레트 40줄, 클라이언트 여러 파일을 건드렸습니다. 결과는 3px짜리 노란 선 하나. 그 선 하나가 “이 태스크는 내가 회고까지 마쳤다”를 조용히 말해줍니다.