Information Architecture — HeyMoa
⚠︎ 지난 판 — 2026-08-13. 현재 판은 여기다. 이 문서는 그때의 기록이고 고치지 않는다.
갱신일 2026-08-13 · 기준:
heymoa-web워킹트리 실측 +docs/pm/3-screens/+ 계약 생성물 이 문서가 갖는 것: 사용자가 보는 정보 구조 — 화면 트리, URL, 정보 계층, 권한, 상태가 화면을 가르는 축. 여기 없는 것: 모듈 배치(application-architecture.md) · 런타임 경계(system-architecture.md) · 배포 형상(cloud-architecture.md) · 회의 전·중·후로 자른 흐름(user-flow).
1. 화면 한 장
모두가 페이지는 아니다. 라우트는 9개뿐이고 나머지는 셸 안의 영역·오버레이다. 모양으로 구분한다.
| 표기 | 뜻 |
|---|---|
▱ 평행사변형 · 파랑 | 라우트 — URL 이 바뀐다 |
▭ 둥근 사각 · 초록 | 영역 — 같은 화면 안의 구획 |
⬛ 겹사각 · 보라 | 오버레이 — 라우트를 바꾸지 않고 위에 뜬다 |
| 노랑 | MVP 2 예정 |
설정과 개인 챗봇은 라우트를 바꾸지 않는다. 노트를 보던 중에도 열리고, 닫으면 보던 자리로 돌아온다. 개인 챗봇은 여는 위치가 스코프를 정한다.
면(view)과 탭(tab)은 쿼리스트링이다. 링크를 공유하면 보던 면 그대로 열린다.
근거 칩이 요약과 전사를 잇는 유일한 고리다 — 아직 구현 전이고, 이게 열려 있는 것 ①이다.
1.1 녹음 컨트롤 — 화면이 아니라 상태다
서버가 상태의 권위를 갖는다. 웹은 이 값을 받아 버튼 라벨만 바꾼다 — 전이 규칙의 정본은 server 다.
2. 정보 계층 — 무엇이 무엇 안에 있나
account
└ workspace ─── member (ADMIN · MEMBER) ← 권한 경계
─── integration (Linear · GitHub) ← 토큰 소유 경계
└ project ← 노트를 묶는 축 (URL 없음)
└ note (회의 1건)
├ transcription session (N개)
│ └ transcript segment
├ analysis job
│ └ meeting item (OVERVIEW · ACTION_ITEM · DECISION)
│ └ evidence → transcript segment (최대 3)
└ shared chat (노트당 1개 · 영구)
account
└ personal chat (사용자당 1개 · 스코프별 활성 세션)
Action Item은 note 아래에 저장되지만 project 단위로 다시 모인다 — 그게 S17 "할 일" 탭이다.
3. URL 표
| URL | 화면 | 인증 | 비고 |
|---|---|---|---|
/ | 랜딩 (S1 진입) | ✕ | Google 로그인 단일 진입 |
/privacy · /terms | 약관 | ✕ | |
/auth/callback | OAuth 콜백 | ✕ | 처리 후 셸로 |
/invite | 초대 토큰 랜딩 (S13) | ✕ | 미가입자도 도달. 수락 시 로그인 유도 |
/w/{workspaceId} | 워크스페이스 셸 + 노트 허브 (S2·S3) | ✓ | layout.tsx가 셸을 소유, page.tsx는 null |
/w/{workspaceId}/notes/{noteId} | 노트 상세 (S4·S5) | ✓ | ?view=side|full, ?tab=transcript|summary |
/settings/integrations | 연동 OAuth 복귀 (S10) | ✓ | 설정은 다이얼로그가 본체. 이 경로는 복귀 지점 |
/mock-oauth | MSW 전용 | — | 제품 IA가 아니다 |
project를 URL에 올리지 않았다. 노트는 워크스페이스 안에서 유일하게 식별된다. project는 사이드바·목록의 그룹핑 축으로만 존재한다.
⚠️ S17(할 일 탭)의 선행 조건: 프로젝트 선택이 지금은 셸의 지역 상태다. 프로젝트 횡단 목록을 공유·북마크하려면 search param으로 승격해야 한다. S17보다 먼저 필요하다.
같은 화면 안의 상태(view·tab)는 history.replaceState, 다른 화면 이동만 router.push. page.tsx가 searchParams를 읽으면 Next가 쿼리 변경을 진짜 내비게이션으로 취급해 _rsc= 왕복이 돈다 (실측 102ms → 10ms).
4. 상태가 화면을 가르는 축 4개
| 축 | 값 | 화면에서 무엇이 달라지나 |
|---|---|---|
| 회의 상태 | NOT_STARTED → IN_PROGRESS ⇄ PAUSED → ENDED | ACTIVE 판정이 공유 챗봇 쓰기와 녹음 컨트롤을 연다 |
| 조작권 | 최초 녹음 시작자 1인 | 나머지는 뷰어 — 중지·재개·종료 버튼이 화면에 없다. 403은 최후 방어선이지 UX가 아니다 |
| 역할 | ADMIN · MEMBER | 초대·멤버 관리·도구 연동은 ADMIN만 (MEMBER는 상태 열람만) |
| 분석 결과 | 없음 → 있음 | 종료 뒤 요약이 노트에 붙는다. web은 폴링으로 도착을 안다 (§7 미확인 ②) |
ACTIVE 판정 = IN_PROGRESS && meetingStartedBy != null. READY 구간에는 activeSessionStartedAt = null일 수 있고 이때는 실제 녹음 중이 아니다 — 뷰어 화면은 "회의 상태"와 "지금 녹음 중인가"를 따로 보여야 한다.
녹음 컨트롤 라벨
| 회의 상태 | 시작자에게 | 뷰어에게 |
|---|---|---|
| NOT_STARTED | 회의 시작 (누른 멤버가 시작자가 된다) | 회의 시작 |
| IN_PROGRESS | Dock 중지 · 상단 회의 종료 | 조작 없음 |
| PAUSED | Dock 재개 · 상단 회의 종료 | 조작 없음 |
| ENDED | 요약 보기 | 요약 보기 |
5. 챗봇 2종의 탐색 위치
화면당 "지금 입력 가능한 챗봇"은 항상 하나다.
| 화면 상황 | 주인공 | 보조 |
|---|---|---|
| 노트 full · IN_PROGRESS | 공유 챗봇 (S7) | 개인 챗봇 플로팅 |
| 노트 full · PAUSED | 개인 챗봇 (노트 스코프) | 공유 챗봇 기록 — 읽기 전용 |
| 노트 full · ENDED | 개인 챗봇 (노트 스코프) | 공유 챗봇 아카이브 |
| 워크스페이스 화면 | 개인 챗봇 (워크스페이스 스코프) | — |
| 노트 side | 공유 챗봇 | 개인 챗봇 숨김 |
이 문서는 어느 화면에서 어느 쪽이 주인공인가만 정한다.
공유 챗봇 기록은 회의 기록의 일부다 (제품 원칙 4). 노트를 지우면 함께 지워진다.
6. 권한
| 행위 | ADMIN | MEMBER |
|---|---|---|
| 초대 · 역할 변경 · 추방 | ✅ | ❌ |
| 워크스페이스 나가기 | ✅ (단, 마지막 ADMIN은 불가 — LAST_WORKSPACE_ADMIN 409) | ✅ |
| 도구 연동 연결 · 해제 | ✅ | ❌ (상태 열람만) |
| 회의 시작 · 노트 생성 | ✅ | ✅ |
| 회의 중지 · 재개 · 종료 | 시작자 1인 (+ 시작자 이탈 시 ADMIN 대리 종료) | 시작자일 때만 |
| 챗봇을 통한 연동 도구 사용 | ✅ | ✅ — ADMIN의 연동이 곧 팀 사용 동의 |
| 도구 쓰기 승인 | 해당 메시지 입력자 본인만 | 동일 |
OWNER 역할은 만들지 않았다. 소유권 이전은 "상대를 ADMIN으로 올리고 내가 나간다" 두 호출이다.
외부 도구에 남는 기록의 명의는 연동 계정(ADMIN), 실제 수행자는 채팅 기록으로 추적한다 — 감수한 트레이드오프.
7. 미확인 · 문서와 코드가 갈린 곳
| # | 무엇 | 지금 상태 |
|---|---|---|
| ① | AI 산출물의 원문 근거 연결 — 제품 원칙 2 | server가 세그먼트 ID를 갖고도 AI로 넘길 때 버렸다. 근거·evidence 구조는 설계 완료(APP-391), 구현 전 |
| ② | 분석 완료 push 채널 | 의도는 STOMP 완료 이벤트, 현실은 web 3초 폴링. 화면을 닫은 사용자는 요약 완료를 영영 알 수 없다 |
| ③ | 공유 챗봇의 agent profile | chatKind가 계약에는 있고 server 요청 DTO에는 없다 → ai는 항상 기본값을 받아 meeting 프로필이 도달 불가능. 그래서 이 문서는 "공유 챗이 어느 profile로 간다"를 단정하지 않는다 |
| ④ | 인용 타임스탬프 | evidence[].startedAtMs는 세션별 오프셋, 전사 화면은 세션을 이어 붙인 타임라인. 세션이 둘 이상인 노트에서 같은 04:12가 다른 줄을 가리킨다 (APP-398) |
| ⑤ | 온보딩 · 개인 챗봇 스코프 · 초대 흐름 | 구현은 되어 있는데 어떤 사용자 문제를 푸는지 문서에 없다 |
| ⑤′ | 회의 전 화면이 없다 | 노트 생성 다이얼로그가 전부고 제목·참여자 말고 채울 칸이 없다. 안건·배경을 넣을 자리가 생기면 이 문서의 §1이 바뀐다 — 사용자 흐름 §2 |
| ⑥ | 알림 폴링 주기 | 계약이 정하지 않는다. web이 고르는데 어느 문서에도 규약이 없다 |
| ⑦ | 화면 목록의 기준 | MVP1 IA 문서는 라우트 6개만 적는다. /invite·/settings/integrations는 그 뒤에 생겼다 — 이 문서가 워킹트리 실측 기준이다 |