[PonsLink] 연결은 붙었지만 신뢰는 아직 만들어지지 않았다
영상이 켜지는 순간을 성공으로 보면 PonsLink는 너무 일찍 끝난다. 실제 상담이나 협업에서는 방에 들어온 사람이 누구인지, 어떤 권한을 받았는지, 끊겼다가 돌아왔을 때 무엇을 이어받는지가 더 오래 남는다. 이 판단은 ponslink-room-frontend/src/pages/Lobby.tsx와 ponslink-room-frontend/src/pages/Room.tsx를 함께 볼 때 더 분명해진다. 화면에서 보이는 기능은 결과이고, 실제 제품성은 그 기능이 열리는 조건과 실패했을 때 돌아갈 길에 있다.

연결은 붙었지만 신뢰가 없는 지점
깨진 지점은 연결 품질이 아니라 책임의 위치였다. WebRTC 연결이 성공해도 세션 토큰이 어떤 기능을 허용하는지, TURN fallback이 필요한 환경인지, 게스트가 나간 뒤 기록을 어디까지 남길지 결정하지 않으면 방은 안심할 수 없는 임시 화면이 된다. 이 부분은 실제로 실패와 trade-off가 함께 있는 지점이었다. 기능을 열어 두면 데모는 풍성해지지만, 사용자에게 필요한 설명은 줄어들지 않는다.
반대로 권한을 좁게 잡으면 초반 경험은 답답해질 수 있지만 운영자는 사고 범위를 예측할 수 있다. 호스트 입장에서는 링크 공유가 쉬울수록 운영 책임이 커진다. 잘못 보낸 링크, 지난 세션의 재사용, 권한이 끝난 게스트의 재입장 같은 사례를 생각하면 단순 URL만으로는 부족하다. 그래서 session token과 request action이 화면 밖에서 방을 붙잡아야 했다. 운영 관점에서는 ponslink-api-infra/README.md가 글의 방어선이다.
사용자는 방을 하나의 경험으로 보지만 시스템은 요청, 세션, 미디어, 파일, 결제, 기록처럼 여러 책임으로 나뉜다. 이 책임을 나눠 적으면 글은 조금 덜 매끈해지지만, 실패했을 때 어디서 멈춰야 하는지 설명할 수 있다. 이번 배치에서 모든 글에 실패나 한계를 넣은 것도 이 때문이다. 결국 beyond calls라는 말은 통화 이상의 기능을 많이 넣었다는 뜻이 아니다.
통화가 된 뒤에도 남는 신뢰, 권한, 기록, 실패 안내를 제품이 떠안기 시작했다는 뜻이다. 이 기준이 있어야 다음 글의 기능 확장도 방향을 잃지 않는다.

처음에는 연결만 맺으면 될 줄 알았다
*브라우저가 방을 열기 전에 BFF가 origin, quota, feature policy를 확인하는 흐름. 운영 흐름으로 보면 사용자는 링크를 열고 Lobby에서 장치를 확인한 뒤 Room에 들어간다. 그 사이 API는 origin, quota, feature policy, TURN credential, session token을 확인한다. 사용자가 보는 건 방이지만 운영자가 관리하는 건 방을 열 수 있는 조건이다. 사용자는 이 복잡도를 몰라도 된다. 대신 제품은 사용자가 보지 않는 곳에서 무엇을 허용하고 무엇을 미룰지 결정해야 한다.
그 결정을 숨기면 당장은 매끄러워 보여도 장애나 결제 지연, 네트워크 실패가 왔을 때 설명할 말이 없어진다. 이어 읽으면 좋은 글은 [과 [이다. 앞 글은 왜 이 문제가 생겼는지 보여 주고, 다음 글은 같은 기준이 다른 기능이나 운영 경계로 어떻게 넘어갔는지 보여 준다. Room.tsx는 영상, 채팅, 파일, 화이트보드를 한데 모으는 쪽으로 자연스럽게 커진다.
하지만 모든 패널이 같은 무게로 열리면 게스트는 제품이 무엇을 보장하는지 알기 어렵다. 채팅을 보낼 수 있다는 사실과 그 채팅이 세션 기록으로 남는다는 사실은 다르다. 파일을 올릴 수 있다는 사실과 그 파일이 언제 사라지는지도 다르다. 방 안에서 보이는 버튼마다 책임의 수명이 달랐고, 그 차이를 설명하지 않으면 연결은 되어도 신뢰는 생기지 않았다.
이 글의 이미지는 그 경계를 보여 주기 위해 넣었다. 첫 그림은 사용자가 보는 링크와 방 사이의 숨은 책임을, 두 번째 그림은 BFF가 기능을 열기 전 확인하는 조건을, 세 번째 이미지는 실제 room proof를 보여 준다. 장식 이미지를 넣지 않은 이유도 여기에 있다.

신뢰 부족이 선명해진 순간
연결은 붙었지만 신뢰는 아직 만들어지지 않았다에서 먼저 확인한 파일은 ponslink-room-frontend/src/pages/Lobby.tsx이다. 이 근거는 글의 출발점이 추상적인 제품 감상이 아니라 실제 화면과 상태를 가진 코드였음을 보여 준다. 화면 컴포넌트가 어떤 이름으로 나뉘어 있는지 따라가면 사용자가 보는 흐름과 운영자가 책임지는 흐름이 어디서 갈라지는지 보인다. 그 갈라짐을 문장으로 남기지 않으면 글은 다시 기능 소개로 돌아간다.
마지막으로 ponslink-api-infra/src/http/routes.ts를 함께 읽으면 다음 작업의 기준이 보인다. PonsLink의 각 글은 독립된 기능 홍보가 아니라 앞뒤 글과 이어지는 판단 기록이어야 한다. 그래서 내부 링크를 두 개씩 남겼고, 이미지도 cover가 아니라 본문 근거로 다시 만들었다. 글 하나를 읽고 끝나는 것이 아니라 독자가 다음 방, 다음 권한, 다음 운영 문제로 넘어갈 수 있게 하는 것이 이번 확장의 목적이다.
Lobby.tsx를 볼 때 가장 먼저 보이는 것은 장치 선택이나 이름 입력이다. 예전에는 그 화면을 입장 전 준비 단계로만 봤다. 다시 읽어 보니 그곳은 게스트가 방을 믿어도 되는지 판단하는 첫 표면이었다. 장치가 준비됐는지보다 더 중요한 것은 사용자가 지금 어떤 세션에 들어가는지, 호스트가 누구인지, 이 방에서 어떤 기능이 열릴지 감을 잡는 일이다.
그래서 통화 연결보다 신뢰의 순서를 앞에 두었다. *로컬 PonsLink room frontend의 room proof 이미지를 본문 자료로 재가공했다. routes.ts의 API 경계를 다시 보면 프론트엔드가 직접 판단하지 않아야 할 것들이 보인다. 계정, 세션, request action, reservation access 같은 이름은 UI에서 길게 설명되지 않지만 실제 운영 사고를 막는 단위다. 이 경계를 서버에 남겨 둔 덕분에 브라우저는 provider secret이나 관리자 권한을 알 필요가 없다.
사용자는 링크 하나로 들어오지만, 제품은 그 링크 뒤에서 훨씬 좁은 grant만 건네야 했다. 이 글을 다음 글과 이어 보면 기능 추가의 기준도 달라진다. 신뢰 경계가 없는 상태에서 채팅이나 파일을 붙이면 편의 기능처럼 보이지만, 경계가 잡힌 뒤에는 각 기능이 어떤 권한과 기록 정책을 따라야 하는지 먼저 묻게 된다. 그래서 PonsLink의 다음 고민은 기능 수가 아니라 기능이 들어올 자리를 정하는 일이었다.
신뢰 경계 나누기
지금 보면 이 전환이 PonsLink를 통화 데모에서 제품 쪽으로 옮긴 첫 번째 선이었다. 다만 화면에 많은 기능을 동시에 보여 주면 신뢰가 생기는 게 아니라 책임이 흐려진다. 그래서 이후 글에서는 기능을 붙이는 속도보다 방의 경계를 좁히는 판단을 먼저 봐야 한다. 다음에 같은 문제를 다시 푼다면 먼저 기능 목록을 쓰지 않고, 방의 목적과 닫혀야 하는 실패 경로를 표로 만들 것이다.
기능은 그 뒤에 붙여도 늦지 않다. *연결 성공 이후에도 세션, 권한, 기록 책임이 남는 구조를 정리한 다이어그램. 그래서 처음 선택한 구조는 방 화면을 최대한 단순하게 두는 방식이었다. Lobby.tsx에서 이름과 장치만 정리하고 Room.tsx에서 영상, 채팅, 화이트보드, 파일 패널을 한 화면에 놓으면 충분하다고 봤다. 이 선택은 빠르게 확인하기 좋았다. 사용자는 들어오고, 장치는 켜지고, 메시지는 오간다.
하지만 빠른 확인이 곧 운영 가능한 구조라는 뜻은 아니었다. 권한이 화면 안에 섞이면 나중에 기능을 줄이기도 어렵고, 문제가 생겼을 때 어디를 막아야 하는지도 흐려진다. 다시 잡은 설계는 BFF가 권한과 세션을 먼저 정하고, 프론트엔드는 그 결과를 받아 방 UI를 여는 구조였다. API README의 request flow처럼 브라우저는 제한된 grant만 받고, provider secret이나 운영 권한은 서버 밖으로 나오지 않는다.
이때부터 PonsLink의 중심은 단순한 room component가 아니라 상태와 권한의 연결이 되었다. ponslink-api-infra/README.md와 ponslink-api-infra/src/http/routes.ts를 보면 이 판단이 프론트엔드 취향이 아니라 API/BFF 경계와 맞물린 결정이라는 점이 보인다.
책임 흐름이 바뀐 지점
게스트 입장에서는 가입하지 않는 편리함과 아무 계정도 없다는 불안이 동시에 온다. 이 불안을 줄이는 방법은 더 많은 설명 문구가 아니라 방이 알아서 좁은 권한만 열어 주는 것이다. 브라우저가 제한된 grant만 받으면 사용자는 복잡한 보안 용어를 몰라도 안전한 범위 안에서 움직인다. 이 설계의 trade-off는 속도였다. 모든 것을 방 화면에서 결정하면 개발은 빠르고 데모도 간단하다.
반대로 BFF가 권한을 먼저 정하게 하면 입장 전 단계가 늘고 실패 메시지도 더 많이 필요하다. 그래도 상담이나 협업 제품에서는 이 느린 쪽이 맞았다. 방이 한 번 잘못 열리면 사용자는 기술 문제가 아니라 신뢰 문제로 받아들이기 때문이다. 초기에는 통화 버튼을 누르고 상대 화면이 보이면 제품이 된 줄 알았다. 하지만 방에 늦게 들어온 사람은 맥락을 잃었고, 호스트는 누가 어떤 자료를 봤는지 다시 설명해야 했으며, 게스트는 링크 하나만 받은 상태에서 어디까지 신뢰해도 되는지 알기 어려웠다.
그래서 기능 소개가 아니라 그때 내가 어떤 기준을 세우지 못했고, 어떤 실패를 보고 나서 경계를 다시 잡았는지를 따라간다. PonsLink는 회의 앱을 흉내 낸 프로젝트가 아니라 요청에서 방, 방에서 기록으로 이어지는 흐름을 제품으로 만들려는 시도였다. 신뢰를 기능으로 착각하면 방은 쉽게 장식된다. 카메라가 켜지고 마이크가 잡히는 일은 눈에 보이지만, 세션이 누구에게 열렸고 언제 닫히는지는 보이지 않는다.
그래서 제품 설명에서도 WebRTC 성공보다 세션 grant와 입장 조건을 먼저 적어야 했다. 깨진 지점은 연결 품질이 아니라 책임의 위치였다. WebRTC 연결이 성공해도 세션 토큰이 어떤 기능을 허용하는지, TURN fallback이 필요한 환경인지, 게스트가 나간 뒤 기록을 어디까지 남길지 결정하지 않으면 방은 안심할 수 없는 임시 화면이 된다. 이 부분은 실제로 실패와 trade-off가 함께 있는 지점이었다.
기능을 열어 두면 데모는 풍성해지지만, 사용자에게 필요한 설명은 줄어들지 않는다. 반대로 권한을 좁게 잡으면 초반 경험은 답답해질 수 있지만 운영자는 사고 범위를 예측할 수 있다. '[PonsLink 연결은 붙었지만 신뢰는 아직 만들어지지 않았다'을 관통하는 질문은 이 섹션에서도 같았고, 답만 더 구체적이 됐다.
마치며
이 글에서 확인한 경계는 다음 변경의 기준으로 남겼다.