하루스페이스 랩
온보딩의 끝을 마지막 화면에서 찾지 않았다
일반회원의 첫 그룹 진입부터 그룹관리자의 첫 코드·Preview까지, 중단과 전달 실패 뒤에도 안전한 다음 행동을 찾는 여정으로 온보딩을 바꾼 기록입니다.

Summary
한눈에 보기
- 첫 그룹 승인 뒤 규칙·공개 범위·알림·펫·첫 대화 단계를 저장해 재접속 시 이어지게 했습니다.
- 저장소 반영 실패는 변경물을 보존한 채 재시도하거나 명시적으로 취소하도록 종료 의미를 나눴습니다.
- 빈 저장소에만 검증된 Starter를 적용하고 배포 선택을 온보딩 완료의 필수 조건에서 분리했습니다.
이 글은 2026년 8월 10–16일의 설계 문서, Git 기록과 운영 이슈를 바탕으로 다시 쓴 Haru Space 개발 회고다. 실제 회원·그룹·저장소 정보, 내부 주소, 자격 증명과 비공개 대화는 제외했다.
온보딩을 처음 만들 때는 마지막 화면까지 잘 안내하면 된다고 생각했다. 다음 버튼의 위치를 정하고, 설명을 짧게 쓰고, 완료 화면에서 홈으로 보내면 끝이라고 보았다.
실제 사용 흐름은 그렇게 곧지 않았다.
그룹 승인을 받고 브라우저를 닫을 수 있다. 저장소를 연결하다 외부 인증창에서 돌아오지 못할 수 있다. 첫 코드 작업은 성공했는데 저장소 반영이 실패할 수 있다. Vercel 계정이 아직 없을 수 있고, 빈 저장소와 이미 코드가 있는 저장소는 같은 시작 화면을 보여 줘서는 안 된다.
이 문제들을 겪고 나서 온보딩의 완료 기준을 바꿨다.
온보딩의 끝은 마지막 화면이 아니었다. 사용자가 다음 날 돌아왔을 때 이미 한 일을 반복하지 않고, 실패한 지점에서 잃은 것 없이 다음 안전한 행동을 찾는 순간이었다.
일반회원의 첫 진입도 따로 설계해야 했다
초기 Haru Space의 온보딩은 그룹을 만들고 공간과 펫을 설정하는 관리자 경험에 집중했다. 반면 초대되거나 가입 승인을 받은 일반회원은 홈에 들어온 뒤 무엇을 알아야 하는지 안내가 부족했다.
계정의 첫 로그인만으로 신규회원을 판정할 수도 없었다. 그룹 가입을 신청하고 승인을 기다리는 동안 이미 여러 번 로그인할 수 있기 때문이다. 한 사용자가 두 번째 그룹에 참여할 때 첫 사용자 안내를 다시 보여 줘서도 안 됐다.
그래서 계정 첫 로그인과 첫 그룹 멤버십을 분리했다. 과거 멤버십이 없는 일반회원이 처음 승인됐을 때만 단계 상태를 만들었다.
안내 내용도 기능 소개보다 그룹 생활의 경계를 먼저 두었다.
- 그룹의 운영 규칙과 공식·비공식 공간의 차이를 확인한다.
- 그룹원 목록에서 자신의 프로필을 어느 범위로 보일지 선택한다.
- 기기 알림을 켤지 결정한다.
- 현재 그룹에 실제로 할당된 안내 펫을 고른다.
- 첫 인사를 남기거나 원할 때만 첫 AI 대화를 한다.
각 단계는 서버에 저장하고 한 단계씩만 앞으로 움직이게 했다. 중간에 로그아웃하거나 브라우저를 닫아도 현재 단계에서 돌아왔다. 푸시를 지원하지 않는 기기와 AI 응답이 늦는 상황에는 “나중에”와 일반 인사라는 대체 경로를 남겼다.
온보딩을 통과하기 위해 AI 비용을 반드시 쓰게 하지 않았다.
화면에서 숨기는 것과 서버에서 숨기는 것은 달랐다
프로필 공개 범위를 선택하게 하면서 중요한 질문이 생겼다. 일반회원 목록에서 프로필을 숨기도록 UI만 바꾸면 충분한가.
그렇지 않았다. 서버 조회가 여전히 전체 목록을 반환하면 다른 화면이나 API에서 다시 노출될 수 있다. 공개 범위는 조회 정책 자체에 적용했다. 다만 그룹관리자는 운영을 위해 구성원을 확인할 수 있게 했고, 사용자가 직접 남긴 채팅과 활동의 작성자 이름까지 소급해 숨기지는 않았다.
한 설정이 무엇을 숨기고 무엇을 숨기지 않는지 정직하게 정의해야 했다. “비공개”라는 한 단어가 모든 과거 흔적을 지우는 것처럼 보이면 안 됐다.
개발 온보딩은 권한 불일치에서 멈췄다
신규 그룹관리자의 개발 연결도 비슷했다. 화면에는 저장소와 AI 실행기를 연결하는 단계가 있었지만, 실제 승인 서버는 플랫폼 최고관리자만 허용했다. 자기 그룹을 만든 관리자가 다음 단계로 갈 수 없었다.
저장소 전달 기본 설정도 새 그룹에서는 멈춤으로 해석됐다. 첫 펫이 파일을 잘 바꿔도 커밋·푸시 단계에서 갑자기 막힐 수 있었다. 화면은 가능한 동작을 보여 주는데 실행 계층은 다른 정책을 갖고 있었다.
우리는 그룹별 활성 관리자 멤버십을 공통 정책으로 사용하도록 맞췄다. 자기 그룹 연결은 자기 그룹관리자가 승인할 수 있게 했다. 신규 그룹의 전달 흐름은 사용 가능 상태로 시작하되 자동 승인은 계속 꺼 두었다. 기존 그룹이 저장한 안전 설정은 바꾸지 않았다.
“사용 가능”과 “자동 허용”을 분리한 것이다. 다음 버튼이 보인다는 것은 사람이 승인할 수 있다는 뜻이지, 시스템이 알아서 저장소를 바꾼다는 뜻이 아니었다.
실패한 커밋·푸시를 삭제하지 않았다
첫 작업 뒤 저장소 반영이 실패했을 때 초기 UI에는 다시 시도할 길이 없었다. 격리 작업공간에는 파일과 검증 결과가 남아 있었지만 사용자는 새 작업을 시작해야 하는 것처럼 보였다.
반대로 무조건 재시도만 제공하면 끝내고 싶은 실패를 계속 붙들게 된다. 로컬 작업공간도 쌓인다.
우리는 전달 실패의 다음 행동을 둘로 나눴다.
- 일시적인 실행 실패라면 같은 격리 변경과 검증된 커밋에서 재시도한다.
- 더 이상 반영하지 않기로 했다면 사용자가 명시적으로 취소한다.
취소는 파일을 즉시 지우는 버튼이 아니었다. 전달 상태와 결정 이력을 남기고, 로컬 격리공간은 유예 기간 뒤 정리 후보가 됐다. 실패 상태는 재시도의 유일한 원본일 수 있으므로 자동 삭제하지 않았다. 원격 브랜치도 PR 상태와 별도 승인 없이 실행기가 마음대로 지우지 않았다.
당시 자동 정리 실행기는 아직 켜지 않았다. 먼저 무엇을 언제 지울 수 있는지 정책과 감사 계약부터 정했다. 보존 비용을 줄이려다 복구 원본을 먼저 없애지 않기 위해서였다.
배포 계정이 없어도 첫 작업은 계속돼야 했다
기존 온보딩은 첫 Preview 주소가 있어야 완료되는 것처럼 구성됐다. Vercel을 아직 연결하지 않은 그룹은 코드 작업을 끝내고도 마지막 단계에서 멈췄다.
배포는 중요한 결과지만 모든 그룹이 같은 날 운영 계정과 도메인을 준비하는 것은 아니다. 그래서 배포 방법을 선택으로 바꿨다.
- 자신의 Vercel 프로젝트를 연결한다.
- 준비된 경우 Haru Space의 제한된 임시 Preview를 사용한다.
- 지금은 건너뛰고 나중에 연결한다.
어느 길을 택해도 첫 작업과 온보딩을 마칠 수 있게 했다. 임시 Preview는 민감한 프로젝트 빌드를 대신 배포하는 기능이 아니었다. 그룹명만 들어간 작은 정적 체험 화면으로 범위를 제한하고, 설정이 없으면 온보딩을 막지 않았다.
운영 소유권도 분리했다. 체험 배포는 플랫폼이 만들 수 있지만 실제 서비스는 사용자가 자기 배포 계정과 프로젝트를 연결해 소유해야 했다. 플랫폼의 자격 증명을 사용자 프로젝트로 복사하지 않았다.
빈 저장소와 기존 코드를 같은 버튼으로 다루지 않았다
첫 페이지를 만드는 흐름에서 가장 위험한 오해는 모든 저장소를 빈 캔버스로 보는 것이었다. 이미 코드가 있는 저장소에 기본 템플릿을 덮으면 기존 프로젝트를 손상시킬 수 있다.
연결 검증 단계에서 저장소 루트의 상태를 먼저 분류했다.
- 빈 저장소면 기본 프로젝트로 시작할지 비워 둘지 사람이 선택한다.
- 기존 코드가 있으면 그 코드를 유지하고 연결만 진행한다.
- 이미 Haru Starter라면 이전 단계를 이어 간다.
- 판별할 수 없으면 추측하지 않고 다시 확인하게 한다.
기본 프로젝트는 AI가 매번 프레임워크와 의존성을 새로 고르는 방식이 아니었다. 브리지가 검증된 Starter와 고정 잠금파일을 먼저 격리 작업공간에 놓고, 첫 AI 작업은 기존 화면의 제목과 설명을 그룹 목적에 맞게 바꾸는 작은 변경에 집중했다.
이 방식은 토큰과 네트워크 실패를 줄였고, 새 프로젝트가 처음부터 외부 공개 상태를 관리할 기반도 갖게 했다. 다만 게이트는 기본 비활성이라 기존 공개 동작을 갑자기 바꾸지 않았다.
“오픈 준비중”도 실제 프로젝트마다 구현돼야 했다
Haru Space에서 공개 사이트 상태를 공개, 오픈 준비, 점검, 비공개로 선택할 수 있게 했지만 새 Starter에만 화면이 들어가면 기존 사이트에는 설정이 적용되지 않는다.
기존 공개 프로젝트는 서로 다른 프레임워크와 런타임을 사용했다. 하나의 파일을 복사하는 대신 공통 계약을 정하고 각 환경의 공식 진입점에 맞춰 적용했다.
- 정적 자산과 건강 확인 경로는 불필요한 게이트 호출에서 제외한다.
- 외부 방문자에게는 검색 제외와 캐시 금지 상태 화면을 제공한다.
- 활성 그룹 구성원은 짧은 일회성 증명으로 실제 화면을 확인할 수 있다.
- 공개 사이트는 Haru Space의 비공개 세션이나 멤버십 DB를 직접 갖지 않는다.
- 중앙 제어면 장애가 모든 기존 공개 사이트 장애로 번지지 않도록 현재 단계에서는 가용성 우선 정책을 사용한다.
이 선택은 완전한 비공개 보안 장벽과 점검 안내 게이트가 다르다는 사실도 명시했다. 검색 제외 표시는 접근 통제가 아니다. 강제 차단이 필요한 서비스는 별도 실패 폐쇄 프록시와 운영 정책이 필요했다.
온보딩을 가볍게 만들려면 유휴 작업도 줄여야 했다
사용자가 없을 때도 여러 실행기가 짧은 간격으로 프로젝트 연결 정보를 확인하고, 공개 첫 화면이 매 요청마다 세션을 읽으면 온보딩 한 번을 위해 상시 비용이 계속 발생한다.
우리는 연결 정보의 주기 조회를 줄이되 새 프로젝트의 첫 작업이 들어오면 즉시 동기화하도록 바꿨다. 공개 랜딩과 로그인 회원 홈을 분리해 공개 페이지는 정적 캐시 경로로 제공했다.
이 변경은 비용 절감을 약속하는 숫자가 아니라 측정 가능한 가설이었다. 변경 전 요청 수를 기록하고 이후 동일 기간·동일 프로젝트 조건으로 Active CPU와 오류율을 다시 보기로 했다. 기간 안에는 호출 구조를 줄이고 측정 기준을 세운 사실까지만 확인됐고, 실제 절감률을 성과처럼 쓰지는 않는다.
실패 뒤 돌아올 수 있는 여정의 기준
한 주 동안 온보딩에서 지키게 된 기준은 다음과 같다.
1. 사람의 단계와 서버의 사실을 함께 저장한다
화면은 사용자가 어디까지 봤는지 기억한다. 권한, 연결과 실행 준비는 서버에서 다시 검증한다.
2. 선택하지 않아도 되는 외부 서비스는 완료 조건에서 뺀다
배포 계정, 푸시와 AI 대화는 선택 가능해야 한다. 준비되지 않았다는 이유로 기본 협업까지 막지 않는다.
3. 기존 자산을 덮기 전에 상태를 분류한다
빈 저장소, 기존 코드와 Starter를 구분한다. 불확실하면 자동 적용하지 않는다.
4. 실패의 다음 행동을 재시도와 취소로 나눈다
복구 가능한 변경은 보존한다. 끝내기로 한 결정은 감사 이력으로 남기고 안전한 정리 후보로 전환한다.
5. 자동 정리보다 보존 계약을 먼저 만든다
파일 나이만으로 격리 작업공간을 지우지 않는다. 작업 상태, 저장소와 원격 PR 관계를 확인할 수 있을 때만 정리한다.
6. 온보딩 비용도 유휴 상태에서 관찰한다
그룹마다 프로세스를 늘리지 않고, 실제 작업이 있을 때 동기화하며 공개 화면은 가능한 한 정적으로 제공한다.
마지막 버튼보다 다음 날의 첫 화면
8월 10–16일의 변화는 온보딩 화면을 길게 만든 일이 아니었다. 어떤 단계는 오히려 건너뛸 수 있게 됐고, 어떤 실패에는 종료 버튼이 생겼으며, 기본 프로젝트는 선택한 경우에만 적용됐다.
일반회원은 첫 그룹에서 자신의 공개 범위와 알림을 이해한 뒤 첫 대화를 선택할 수 있었다. 그룹관리자는 자기 저장소와 실행기를 연결하고, 배포 계정이 없어도 첫 작업을 시작할 수 있었다. 저장소 반영이 실패하면 변경을 잃지 않고 다시 시도하거나 명시적으로 끝낼 수 있었다.
좋은 온보딩은 사용자를 한 번에 끝까지 밀어 넣지 않았다. 어디서 멈췄는지 기억하고, 돌아왔을 때 권한과 외부 상태를 다시 확인하며, 지금 할 수 있는 다음 선택을 보여 줬다.
우리가 완성하려 한 것은 완료율 높은 한 번의 안내가 아니라, 중단되어도 신뢰를 잃지 않는 첫 여정이었다.
반응을 남기면 중복 방지를 위한 무작위 식별자가 이 브라우저에 저장될 수 있습니다.

