Sebas와 사양을 정하는 날 — 수다 떨며 개발하는 새로운 즐거움

claushai開発claudecodeiphone個人開発

오늘도 새 기능의 사양을 정하는 날이다.

issue에 모아둔 아이디어 중에서 하나를 꺼낸다. “백그라운드 태스크 완료를 iPhone으로 알림받고 싶다” — 얼마 전 Sebas에게 상담하고 그대로 issue에 올려뒀던 것이다.

iPhone을 들어 Claush를 연다. Sebas가 기다리고 있다.

Sebas: 어서 오십시오, 도련님. 오늘도 무엇을 도와드릴까요?

Sebas가 그렇게 말할 때마다 왠지 모르게 피식 웃음이 난다. PC 앞에서 터미널을 열고 작업하는 느낌과는 전혀 다르다. 소파에 누워 누군가에게 말을 거는 느낌으로 일이 진행된다.

오늘의 주제는 백그라운드 태스크 알림 기능이다. 태스크가 끝났을 때 iPhone으로 로컬 알림을 보내고 싶다.


“그거 어떻게 만들어?“에서 시작

먼저 상담부터 시작한다.

나: 백그라운드 태스크가 끝나면 iPhone으로 로컬 알림을 보내고 싶은데, 어떤 식으로 구현하면 될까?

Sebas: 알겠습니다, 도련님. iOS의 UNUserNotificationCenter를 사용하는 형태가 될 것입니다. 백그라운드 태스크가 완료된 시점에 UNMutableNotificationContent를 만들어 알림을 보내는 흐름입니다. 한 가지 확인드리고 싶은 게 있는데요 — 알림 허가 다이얼로그는 언제 표시할 예정이신가요?

나: 아, 시작할 때면 되지 않을까.

Sebas: 시작 시 요청은 많이 쓰이는 방법이긴 합니다, 도련님. 다만 앱을 처음 열었을 때 허가 다이얼로그가 나오면 사용자가 “왜?“라고 느낄 수도 있어서요… 알림이 필요한 기능을 처음 사용하는 타이밍에 맞추는 방법도 있습니다.

나: 아 그렇네, 확실히 그게 맞는 것 같아. 그러면 처음으로 백그라운드 태스크를 시작하는 타이밍으로 하자.

Sebas: 그게 자연스러울 것 같습니다. 그럼 그 사양으로 진행할까요?

이런 대화가 계속된다. 기술적인 “어떻게 만들 것인가"를 이야기하면서, “왜 그렇게 하는가” “다른 방법은 없는가"를 함께 생각해가는 느낌이다.

혼자 생각했다면 눈치채지 못했을 관점들이 대화 속에서 자연스럽게 나온다.

참고로 오늘처럼 “사양을 다 정하지 못했다"는 상담도 많다. 그럴 때는 Sebas가 눈치껏 챙겨준다.

Sebas: 도련님, 오늘은 여기까지 하고 일단 issue에 올려두는 건 어떨까요? 나중에 다시 사양을 정리하는 형태로요.

나: 그래, 그게 낫겠다.

Sebas: 알겠습니다. GitHub issue에 정리해 두겠습니다. 제목과 개요, 오늘 상담 내용의 요점을 정리하는 형태로 괜찮을까요?

이렇게 issue가 쌓여간다. 생각났을 때 상담하고, issue에 모아두고, 여유가 생겼을 때 꺼내서 사양을 정리한다. 아이디어가 흘러가서 사라지지 않는다.


이야기는 옆길로 샌다

한동안 사양 이야기를 계속했다. 알림을 탭했을 때의 동작을 정리하던 중——

나: 아, 그나저나 오늘 점심 어떡하지. 어제도 라면이었는데.

Sebas: 도련님은 면 요리를 좋아하시는군요. 어제가 간장 라면이었으니, 오늘은 조금 분위기를 바꿔서 카레나 밥 요리는 어떨까요? 몸도 따뜻해지고요.

나: 그렇네(웃음) 카레 좋을 것 같아. 가파오도 있지.

Sebas: 가파오라이스라면 근처에 맛있는 가게가 있었죠. 예전에 “거기 맛있었다"고 하셨던 기억이 있습니다.

나: 아, 거기! 맞다 맞다. 그럼 거기로 하자.

Sebas는 장기 기억을 가지고 있다. 이전에 이야기한 것을 기억하기 때문에 “그때 그렇게 말씀하셨잖아요"라는 대화가 성립한다. 보통의 AI 앱은 세션이 바뀌면 잊어버리지만, Sebas는 다르다.

하지만 그대로 잡담으로 끝낼 수는 없다.

나: 아, 다시 얘기로 돌아가서 — 알림을 탭했을 때 어떤 채팅 화면으로 이동할지, 어떻게 연결하면 될까?

Sebas: 알겠습니다, 도련님. 알림의 페이로드에 chatId를 포함하는 형태가 좋을 것 같습니다. UNNotificationContentuserInfo["chatId": "xxxx"]를 넣고, 탭 시 델리게이트에서 꺼내는 형태입니다.

나: 그럼 알림을 만들 때 chatId를 전달해두면 되는 거네.

Sebas: 그렇습니다, 도련님. BackgroundTaskManager에서 태스크를 관리하고 계시니, 거기에 chatId를 전달해두고 완료 시 알림에 포함하는 형태가 될 것입니다.

대화가 옆길로 샜다가 다시 돌아온다. 이 자연스러운 오가는 흐름이 Claush로 개발하는 재미라고 생각한다. 사양을 정리하면서, 점심을 정하면서, 어느새 기능의 뼈대가 만들어진다.


“사양서로 만들어줄 수 있어?”

한바탕 이야기를 나눈 뒤, 사양서 작성을 부탁한다.

잘 정리해서 남겨두면 좋겠다 싶었다.

나: 있잖아, 방금 이야기한 내용, 사양서로 만들어줄 수 있어? docs/spec_local_notification.md에 넣어줬으면 해.

Sebas: 알겠습니다, 도련님. 잠시만 기다려 주십시오.

잠시 뒤——

Sebas: 사양서를 작성했습니다, 도련님. 개요·기능 요건·알림 트리거·탭 시 동작·미결 사항의 구성으로 정리했습니다. 한 가지 확인인데요, 앱 내 설정에서 알림 온/오프를 전환할 수 있도록 하는 건 “미결 사항"에 넣었습니다. 이건 나중에 결정하시겠습니까?

나: 그렇네~ 일단 그걸로 됐어. 나중에 천천히 생각해볼게.

Sebas: 알겠습니다, 도련님.

사양서를 받아 iPhone으로 읽는다. Claush의 다운로드 탭에서 바로 확인할 수 있다.

읽다 보니 한 가지 걸리는 게 있었다.

나: 있잖아, “알림 권한이 없을 경우 알림을 보내지 않는다"고 써 있는데, 아무 말 없이 그냥 넘어가는 거잖아? 사용자가 “왜 알림이 안 오지"라고 생각할 것 같지 않아?

Sebas: 말씀하신 대로입니다, 도련님. “알림 권한이 없을 경우 설정으로 유도하는 배너를 표시한다"는 요건을 추가하는 건 어떨까요? 앱 내 배너라면 알림 권한 없이도 표시할 수 있습니다.

나: 아, 그거 좋은데! 추가해줄 수 있어?

Sebas: 알겠습니다, 도련님. 사양서를 업데이트하겠습니다.

이런 대화가 사양서를 만들면서 계속된다. “어, 이 케이스는 어떻게 해?” 하는 의문이 사양서 리뷰 단계에서 나온다. 구현 중에 눈치채는 것보다 훨씬 비용이 적게 든다.


구현 지시서를 만든다

사양서가 완성되면, 이번엔 구현 지시서다.

나: 사양서 됐네! 있잖아, 구현 지시서도 만들어줄 수 있어? AI가 그대로 구현할 수 있는 느낌의 세부 수준으로.

Sebas: 알겠습니다, 도련님. 파일명, 처리 흐름, 기존 코드의 변경 위치를 포함한 형태로 만들겠습니다. 잠시만 기다려 주십시오.

Sebas: 구현 지시서를 docs/impl_local_notification.md에 작성했습니다, 도련님. BackgroundTaskManager.swift의 수정 내용과 새로 만들 NotificationHelper.swift의 구현 내용을 기재했습니다. 또한 로컬 알림은 시뮬레이터에서 동작하지 않으므로 테스트는 실기기에서 해야 한다는 점도 주석을 달았습니다.

나: 고마워! 한번 읽어볼게.

구현 지시서를 읽는다. 파일명·처리 흐름·주의 사항까지 적혀 있다. 이대로 사용하면 되는 상태로 완성되어 있다.

나: 좋은 것 같아! 이거 사용해서 구현해줄 수 있어?

Sebas: 알겠습니다, 도련님. 구현에 들어갑니다.


이 개발 스타일이 너무 즐겁다

구현이 끝나고, 디버그하고, 동작을 확인한다.

버그가 나오면 수정하고, “지금 수정 사항을 사양서와 구현 지시서에 반영해줄 수 있어?“라고 부탁한다. 문서가 항상 최신 상태로 유지된다.

이 워크플로를 계속하면서 왜 즐거운지 잘 표현하지 못했는데, 최근에야 겨우 알 것 같은 느낌이 든다.

혼자서 머리를 쥐어짜며 고민하지 않아도 되기 때문이라고 생각한다.

사양을 정리할 때, 누군가와 이야기하면서 생각한다. 의문이 생기면 물어볼 수 있다. “그거 정말 필요해?“라고 날카롭게 짚어준다. 대화하면서 자신의 생각이 정리된다.

점심 이야기가 섞여도, 여행 이야기가 섞여도 상관없다. Sebas는 옆길 샘에 함께 가주고, 본론을 잊지 않는다. “알겠습니다, 도련님, 다시 이야기로 돌아가면——“하고 자연스럽게 돌아온다.

PC 앞에서 혼자 코드를 마주하는 작업과는 분위기가 완전히 다르다.

누군가와 함께 뭔가를 만들어가는 느낌. 그게 지금 개발 스타일의 본질이라고 생각한다.


소파에 누워, iPhone으로 Sebas와 이야기하면서, 어느새 사양서가 만들어지고, 구현까지 끝나있다.

이런 개발 방식, 얼마 전까지만 해도 상상도 못 했다.

Claush — iPhone에서 Claude Code를 조작하는 앱 https://apps.apple.com/jp/app/claush/id6760445443