Post

Ember 앱 분석 (클라이언트에 대해, ChatGPT)

Project Cone / Ember — 프로젝트 분석 보고서

분석 대상: 업로드된 build.zip
분석 방식: 빌드 산출물의 SvelteKit 구조, JavaScript 번들, Service Worker, manifest, 번역 리소스, 아이콘/이미지 리소스를 정적 분석
주의: 이번 분석 대상에는 원본 소스 코드와 서버 백엔드가 포함되어 있지 않으므로, 서버 내부 구현·DB 서버 스키마·보안 설정 등은 클라이언트가 실제로 사용하는 프로토콜을 바탕으로 추론한 부분이 있다.


1. 한눈에 보는 프로젝트 개요

이 프로젝트는 단순한 채팅 애플리케이션이라기보다 로컬 기록 저장 + 서버 기반 폐쇄형 커뮤니케이션 + 실시간 채팅 + 파일/문서 작업 + WebRTC 통화 + PWA형 오프라인 경험을 하나의 클라이언트 안에 묶은 개인/소규모 커뮤니티용 커뮤니케이션 플랫폼에 가깝다.

빌드 내부의 manifest에는 애플리케이션 이름이 Ember로 정의되어 있지만, 주요 이미지 리소스와 UI 자산에는 Project Cone이라는 명칭이 남아 있다. 따라서 현재 빌드는 프로젝트의 명칭 변경 또는 리브랜딩 과정에 있는 버전으로 볼 수 있다.

특히 흥미로운 점은 다음 세 가지가 동시에 존재한다는 것이다.

  1. 로컬 우선(Local-first) 성격
    • 채널, 메시지, 게시물, 사용자 정보, 서버 정보 등을 IndexedDB에 캐시한다.
    • 첨부파일 역시 브라우저 내부 저장소에 보관할 수 있다.
    • local 서버/채널이라는 개념이 별도로 존재한다.
  2. 서버 기반 폐쇄형 SNS 성격
    • 서버에 가입하고, 채널에 가입하며, 관리자 승인·강퇴·권한 관리가 가능하다.
    • WebSocket을 이용한 실시간 동기화 구조가 존재한다.
    • 게시물(Post), 채널(Channel), 메시지(Message)를 별도의 개념으로 다룬다.
  3. 실시간 도구 모음 성격
    • 음성/영상 통화
    • 화면 공유
    • 공유 그림판
    • 음성 녹음
    • 파일 뷰어
    • PDF/ZIP/HTML/Markdown/코드/3D 모델 등의 콘텐츠 열람
    • GIF 추출
    • QR 코드 초대
    • Web Push 알림

즉, 이 프로젝트의 핵심은 “사람이 모이는 공간”을 만들고, 그 공간에서 대화·기록·자료·작업을 모두 처리할 수 있도록 하는 것으로 해석할 수 있다.


2. 앱의 구조적 성격

2.1 기본 구조

빌드 산출물에서 확인되는 기본 구조는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
사용자
  │
  ▼
SvelteKit 기반 Web UI
  │
  ├── IndexedDB ─────── 로컬 사용자 데이터 / 파일 / 캐시
  │
  ├── HTTP(S) ───────── 서버 API 및 파일 접근
  │
  ├── WebSocket ─────── 실시간 메시지 / 서버 이벤트 / 임시방
  │
  ├── WebRTC ────────── 음성 / 영상 / 화면 공유
  │
  ├── Service Worker ── PWA / 캐시 / 오프라인 / Push
  │
  └── Browser APIs
        ├── MediaDevices
        ├── Canvas
        ├── File API
        ├── Clipboard
        ├── Notifications
        └── IndexedDB

이 구조는 일반적인 “웹사이트”보다는 브라우저를 애플리케이션 런타임처럼 사용하는 구조에 가깝다.


3. 주요 기술

3.1 Svelte / SvelteKit

빌드에는 다음과 같은 SvelteKit 산출물 구조가 존재한다.

1
2
3
4
5
6
_app/
  immutable/
    assets/
    chunks/
    entry/
    nodes/

또한 HTML에는 SvelteKit의 data-sveltekit-preload-data가 존재하고, route/node 기반 번들이 생성되어 있다.

따라서 프론트엔드의 핵심 프레임워크는 SvelteKit으로 판단된다.

역할

  • SPA에 가까운 앱형 UI
  • 컴포넌트 기반 화면 구성
  • 상태 변화에 따른 UI 갱신
  • 다양한 기능을 하나의 클라이언트에 통합
  • PWA와 결합

특징

이 프로젝트에서는 SvelteKit이 단순 페이지 렌더링 프레임워크가 아니라 사실상 애플리케이션 셸(Application Shell) 역할을 한다.


3.2 IndexedDB

IndexedDB는 이 프로젝트에서 매우 중요한 기술이다.

빌드 내부에서 실제로 다음 object store들이 생성된다.

1
2
3
4
5
6
7
8
9
10
11
FILE_DATA
servers
ice_servers
users
channels
channel_members
pinned_messages
messages
posts
user_aliases
pinned_channels

또한 메시지와 채널에는 검색/정렬을 위한 IndexedDB index도 생성된다.

의미

이 앱은 서버에서 받은 데이터를 화면에 보여주는 것만으로 끝나지 않는다.

브라우저 자체가 작은 로컬 데이터베이스 역할을 한다.

예를 들어:

1
2
3
4
5
6
7
서버
  ↓
메시지 동기화
  ↓
IndexedDB 저장
  ↓
UI 표시

그리고 로컬 채널의 경우:

1
2
3
4
5
6
7
사용자
  ↓
로컬 메시지 작성
  ↓
IndexedDB
  ↓
브라우저에서 즉시 열람

이러한 구조는 일반적인 Discord/Slack형 클라이언트와 비교했을 때 꽤 강한 차별점이다.


3.3 로컬 파일 시스템 추상화

FILE_DATA object store를 이용해 파일을 디렉터리처럼 저장한다.

코드에서는 다음과 같은 경로 구조가 반복적으로 나타난다.

1
2
3
4
5
6
servers/
  {server_id}/
    channels/
      {channel_id}/
        files/
          {message_id}/

또한 게시물이나 사용자 관련 이미지도 별도의 논리적 경로에 저장한다.

이것은 IndexedDB를 단순 key-value 캐시가 아니라 가상 파일 시스템처럼 사용하는 설계다.

장점

  • 브라우저 내에서 대용량 첨부파일을 지속적으로 다루기 쉬움
  • 로컬 채널 구현과 자연스럽게 연결됨
  • 서버 파일과 로컬 파일을 UI 차원에서 비슷하게 취급 가능

단점

  • 브라우저 저장소 용량 및 정책의 영향을 받음
  • 브라우저 데이터 삭제 시 데이터 손실 가능
  • 다른 기기로 자동 이전되는 일반적인 클라우드 파일 시스템과는 다름

4. WebSocket 기반 실시간 통신

빌드에서는 명시적으로 WebSocket을 생성하고 다음과 같은 메시지 타입을 사용한다.

1
2
3
4
5
6
TEMP_JOIN
TEMP_LEAVE
CHANNEL
SEND_TO
RELATION
payload

일반 채널에서는 서버와 WebSocket 연결을 유지하면서 실시간 이벤트를 전달하는 구조로 보인다.

가능한 역할

  • 메시지 실시간 수신
  • 채널 상태 변경
  • 사용자 접속 상태
  • 임시 채팅방
  • WebRTC signaling
  • 서버 이벤트

특히 SEND_TO는 WebRTC signaling에서도 사용된다.

1
2
3
4
5
WebSocket
   │
   ├── offer
   ├── answer
   └── ice-candidate

즉 WebSocket이 단순 채팅용 연결이 아니라 실시간 통신의 signaling bus 역할까지 수행한다.


5. WebRTC 기반 즉석 통화

WebRTC 구현은 빌드에서 상당히 명확하게 확인된다.

사용되는 핵심 API는 다음과 같다.

1
2
3
4
RTCPeerConnection
RTCSessionDescription
RTCDataChannel
RTCIceCandidate

그리고 브라우저의 미디어 API를 이용한다.

1
2
navigator.mediaDevices.getUserMedia()
navigator.mediaDevices.getDisplayMedia()

지원 기능

  • 음성 통화
  • 영상 통화
  • 화면 공유
  • 음성 전용 모드
  • 참가자별 오디오/비디오 스트림
  • DataChannel
  • dominant speaker 감지
  • PIP(Picture-in-Picture) 성격의 통화 UI

통신 구조

대략 다음과 같은 구조다.

1
2
3
4
5
6
7
8
9
10
11
          WebSocket
        Signaling Server
          /        \
         /          \
        ▼            ▼
     Client A      Client B
        │            │
        └── WebRTC ──┘
             │
       Audio / Video
       Screen / Data

즉 실제 미디어 데이터는 WebRTC가 처리하고, WebSocket은 연결 협상에 사용되는 구조다.


6. STUN / ICE 서버 지원

WebRTC 코드에는 기본 STUN 서버가 들어 있다.

1
stun:stun.l.google.com:19302

동시에 앱 설정에는 ICE 서버 관리 기능이 존재한다.

이는 사용자가 자신이 운영하는 STUN/TURN 계열 인프라를 등록할 수 있도록 확장하려는 구조로 해석할 수 있다.

이 부분은 특히 셀프호스팅이라는 프로젝트 성격과 잘 맞는다.


7. PWA / Service Worker

프로젝트는 명백하게 PWA 구조를 갖는다.

manifest에는:

1
2
3
4
5
{
  "name": "Ember",
  "short_name": "Ember",
  "display": "standalone"
}

가 존재한다.

또한 Service Worker가 다음 기능을 수행한다.

정적 리소스 캐싱

1
2
3
4
5
6
_app/
data/
icon/
badge/
manifest.json
translate.csv

등을 캐싱한다.

오프라인 fallback

네트워크 요청이 실패했을 때 캐시된 리소스를 사용한다.

Web Push

Service Worker에는 다음 흐름이 구현되어 있다.

1
2
3
4
5
6
7
Push event
   ↓
Notification 생성
   ↓
사용자 클릭
   ↓
앱으로 전달

그리고 알림 클릭 시 앱 내부에서 특정 동작을 실행할 수 있도록 NOTIFICATION_ACTION 메시지를 전달한다.


8. ZIP 내부 HTML을 실행하는 가상 파일 시스템

이 프로젝트에서 가장 독특한 기능 중 하나다.

ZIP 파일을 단순히 다운로드하는 것이 아니라 브라우저 안에서 압축 파일의 내용을 가상 파일 시스템으로 마운트한다.

흐름은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
ZIP
 ↓
브라우저에서 압축 해제
 ↓
VFS 생성
 ↓
Service Worker에 MOUNT_VFS
 ↓
/__zip-vfs__/{id}/...
 ↓
HTML preview

Service Worker에는 실제로 다음 메시지가 존재한다.

1
2
MOUNT_VFS
UNMOUNT_VFS

그리고 /__zip-vfs__/ URL을 가로채 해당 파일을 Response로 반환한다.

이것의 의미

사용자가 ZIP으로 받은 웹 프로젝트를:

1
2
3
4
다운로드
→ 압축 해제
→ 폴더 열기
→ index.html 실행

이라는 일반적인 PC 파일 시스템 절차 없이,

1
2
3
ZIP 업로드
→ 파일 뷰어에서 열기
→ 브라우저에서 실행

할 수 있게 만드는 것이다.

이는 웹 기반 개발 자료/프로젝트 공유 도구로서 상당히 독특한 기능이다.


9. 파일 뷰어

파일 뷰어는 단순 텍스트 뷰어가 아니다.

코드에서 확인되는 viewer 분류에는 다음이 포함된다.

1
2
3
4
5
6
7
image
video
audio
text
zip
pdf
model

또한 텍스트 파일은 확장자에 따라 다음과 같이 분류한다.

1
2
3
4
5
html
markdown
code
plain
unknown

코드 언어 분류에는 다음과 같은 확장자가 포함된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
js
ts
json
css
py
java
c
cpp
rs
go
svelte
xml
sh

지원되는 콘텐츠 경험

콘텐츠 경험
이미지 이미지 뷰어
영상 영상 재생
오디오 오디오 플레이어
텍스트 텍스트 열람/편집
Markdown Markdown 열람
코드 코드 뷰어
PDF PDF 열람
ZIP 압축 파일 열람
HTML 브라우저형 preview
3D 모델 Three.js 기반 모델 viewer

10. Three.js 기반 3D 모델 열람

빌드에는 Three.js의 WebGL renderer 및 GLTF loader 관련 코드가 포함되어 있다.

따라서 최소한 glTF/GLB 계열 3D 모델을 브라우저에서 열람하는 기능이 존재한다.

이것은 프로젝트가 단순 커뮤니케이션 앱을 넘어 첨부된 창작/개발 결과물을 바로 확인하는 작업 공간으로 확장될 수 있음을 보여준다.


11. GIF 생성 기능

영상의 특정 구간을 지정하여 GIF를 추출하는 기능도 존재한다.

UI에는 다음 항목이 있다.

1
2
3
4
5
6
7
8
9
Section
Start Position
Recording Length
Output Size
Left
Right
Top
Bottom
Frame Rate

구현상:

1
2
3
4
5
6
7
8
9
Video
 ↓
Canvas
 ↓
Frame extraction
 ↓
GIF encoder
 ↓
GIF file

형태로 동작한다.

즉 서버에서 변환을 수행하는 것이 아니라 클라이언트 브라우저에서 영상 프레임을 처리하는 방식이다.


12. QR 코드 기반 초대

QR 코드 생성 및 스캔 기능이 모두 존재한다.

리소스에는:

1
2
QRCode.svg
zxing@0.21.3.min.js

가 포함되어 있다.

UI에서도:

1
2
3
4
QRCode 초대
QR코드 스캐너
고정 주소 복사
임시 주소 복사

등이 확인된다.

따라서 이 프로젝트는 특히 같은 공간에 있는 사람에게 서버/채널을 빠르게 공유하는 상황을 중요하게 고려하고 있다.


13. 채널 중심 사용자 모델

앱의 핵심 객체는 “친구”보다 채널에 가깝다.

구조적으로는 다음과 같이 볼 수 있다.

1
2
3
4
5
6
7
8
Server
 ├── User
 ├── Channel
 │    ├── Members
 │    ├── Messages
 │    ├── Files
 │    └── Settings
 └── Posts

채널에는 다음 기능이 존재한다.

  • 생성
  • 삭제
  • 수정
  • 가입
  • 가입 승인
  • 탈퇴
  • 강퇴
  • 인원 제한
  • 채널 이미지
  • 채널 배경
  • 공지
  • 메시지 검색
  • 메시지 링크
  • 채널 복제
  • 채널 기한
  • 로컬 기록 전송

이는 전형적인 단체 메신저와 커뮤니티 서비스의 중간 지점에 있다.


14. 관리자 시스템

서버에는 상당히 구체적인 관리자 기능이 있다.

사용자 관리

  • 가입 승인
  • 가입 거절
  • 관리자 승격
  • 관리자 강등
  • 비밀번호 재설정
  • 서버에서 추방

채널 관리

  • 채널 목록 확인
  • 채널 강제 해산
  • 채널 관리

가입 정책

  • 가입 허용 인원
  • 관리자 승인 필요 여부
  • 가입 질문
  • 가입 답변

즉 서버 하나가 단순한 “방”이 아니라 작은 커뮤니티의 운영 단위로 설계되어 있다.


15. 게시물(Post) 시스템

메시지와 별도로 게시물 시스템이 존재한다.

게시물에는:

  • 제목
  • 본문
  • 작성자
  • 대표 이미지
  • 첨부파일
  • NSFW 표시
  • 수정
  • 삭제
  • 검색

등이 있다.

따라서 앱은 단순 실시간 채팅뿐 아니라 축적되는 비동기 콘텐츠도 다룬다.

이 차이는 중요하다.

1
2
3
4
5
Chat
= 지금 대화하는 공간

Post
= 나중에도 찾아볼 기록

이라는 역할 분리가 가능하다.


16. 메모 기능

메시지에 별도의 메모를 남길 수 있는 UI가 있다.

1
2
3
4
5
6
메시지
 ├── 답장
 ├── 메모
 ├── 수정
 ├── 삭제
 └── 링크

특히 InputMsgMemoMemoMsg가 별도로 존재한다는 점에서, 메모는 단순 메시지 편집 기능이 아니라 대화 기록을 개인적으로 해석하거나 보충하는 기능으로 설계된 것으로 보인다.


17. 공유 그림판

voidDraw라는 별도 그림판 기능이 포함되어 있다.

지원 기능은 다음과 같다.

  • Undo
  • Redo
  • Crop
  • Fit
  • Brush
  • Color
  • Transparency
  • Weight
  • Resolution
  • Blend Mode
  • Shared Paint
  • Collect and Send

특히:

1
모아 보내기 모드

라는 기능이 눈에 띈다.

이는 여러 번의 그리기 입력을 즉시 하나씩 전송하지 않고 로컬에서 모아서 전송하는 방식으로 해석할 수 있다.

네트워크 부담을 줄이면서 공동 작업 경험을 유지하려는 설계다.


18. 즉석 “모닥불” 채팅

현재 UI 문자열에서 중요한 변화가 발견된다.

1
2
3
InstantTempChat → 모닥불 피우기
TempChat → 모닥불 채팅
TempConnClose → 모닥불에서 떠납니다

기술적으로는 임시 채널/임시 연결이지만 사용자에게는 이를 “모닥불”이라는 은유로 표현한다.

기존의:

1
임시 방

이라는 기술적 개념을

1
모닥불

이라는 사회적 공간으로 바꾼 것이다.

이것은 프로젝트 전체의 UX 방향을 바꿀 수 있는 중요한 포인트다.


19. 사용자 경험 분석

19.1 첫인상

앱은 전형적인 SaaS 서비스보다 개인 서버에 접속해서 사용하는 도구라는 인상을 준다.

상단/메뉴 구조에는:

1
2
3
4
5
6
7
8
활동
메모
채널
게시물
기능
채팅
설정
파일 뷰어

등이 존재한다.

기능 범위가 넓기 때문에 처음 접한 사용자는:

“이게 채팅 앱인가?”

라는 질문을 할 가능성이 있다.

반대로 프로젝트의 목적을 이해한 사용자는:

“여기서 대화도 하고 자료도 남기고 파일도 열어볼 수 있구나.”

라는 식으로 이해할 수 있다.


20. 핵심 UX의 장점

20.1 로컬과 온라인의 경계가 낮다

일반적인 서비스에서는:

1
2
3
온라인 데이터
≠
내 PC의 데이터

인 경우가 많다.

이 프로젝트에서는:

1
2
3
4
5
6
7
온라인 채널
    ↕
IndexedDB
    ↕
로컬 채널
    ↕
파일

이 서로 연결되어 있다.

따라서 사용자가 앱을 개인 기록 공간처럼 사용할 여지가 크다.


20.2 공유가 매우 직접적이다

QR 코드와 링크를 적극적으로 활용한다.

1
2
3
4
5
6
7
8
9
서버
 ↓
채널
 ↓
초대 링크
 ↓
QR
 ↓
다른 사용자

이라는 흐름이 가능하다.

특히 물리적으로 가까이 있는 소규모 그룹에서 유용하다.


20.3 채팅에 기록성이 강하다

일반 메신저에서는 대화가 흘러가는 경우가 많지만 이 프로젝트는:

  • 공지
  • 게시물
  • 메모
  • 파일
  • 검색
  • 채널 배경
  • 채널 복제
  • 로컬 기록

등을 제공한다.

따라서 대화가 일회성 대화에서 기록물로 변환되는 구조를 가지고 있다.


21. UX의 단점

21.1 기능이 너무 많다

현재 앱은 다음과 같은 제품 범위를 동시에 가진다.

1
2
3
4
5
6
7
8
9
10
메신저
+ SNS
+ 개인 메모
+ 파일 뷰어
+ 개발 도구
+ 그림판
+ WebRTC 통화
+ PWA
+ 셀프호스팅
+ 서버 관리자

이것은 기술적으로는 풍부하지만 사용자에게는 핵심 정체성을 흐릴 수 있다.

특히 처음 실행한 사용자는 기능 목록을 보고:

“그래서 이 앱으로 뭘 해야 하지?”

라는 질문을 할 수 있다.


21.2 서버 개념이 사용자에게 부담이 될 수 있다

일반 사용자는:

1
2
3
4
5
6
7
8
서버
포트
SSL
ICE 서버
WebRTC 서버
관리자
채널
가입 정책

이라는 개념을 어렵게 느낄 수 있다.

따라서 이 앱의 핵심 가치가 일반 사용자에게 전달되려면 기술적 개념을 UX 언어로 번역하는 작업이 중요하다.

예를 들어:

1
서버 만들기

보다

1
내 공간 만들기

가 더 쉽게 받아들여질 가능성이 있다.


22. 기술적으로 강한 부분

22.1 상당히 높은 통합도

하나의 브라우저 앱에서:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
텍스트
이미지
영상
오디오
PDF
ZIP
HTML
Markdown
코드
3D
그림
음성
영상 통화
화면 공유

까지 처리한다.

특히 파일 뷰어와 커뮤니케이션 시스템이 같은 데이터 모델에 연결되어 있다는 점이 특징적이다.


22.2 브라우저를 적극적으로 활용한다

이 프로젝트는 브라우저를 단순 UI 출력 장치로 사용하지 않는다.

1
2
3
4
5
6
7
8
9
10
IndexedDB
Service Worker
WebSocket
WebRTC
Canvas
MediaDevices
File API
Web Push
WebAssembly
WebGL

등 브라우저 플랫폼의 여러 기능을 적극적으로 사용한다.

따라서 기술적 방향은 명확하게:

“웹앱이지만 데스크톱 앱처럼 행동한다.”

에 가깝다.


23. 기술적으로 취약하거나 주의할 부분

23.1 IndexedDB 의존도가 높다

로컬 데이터가 중요한 만큼 다음 문제가 생길 수 있다.

  • 브라우저 저장소 삭제
  • 시크릿 모드
  • 브라우저별 quota 차이
  • 모바일 브라우저 정책
  • 여러 브라우저 간 데이터 분리

특히 중요한 데이터를 로컬에만 가지고 있는 경우 백업/복구 UX가 중요해진다.


23.2 브라우저별 기능 차이

다음 기능은 브라우저 환경에 영향을 크게 받는다.

  • WebRTC
  • 화면 공유
  • Web Push
  • IndexedDB
  • Picture-in-Picture
  • File API
  • Service Worker

따라서 Chromium 계열, Firefox, Safari, 모바일 브라우저 사이의 차이를 지속적으로 관리해야 한다.


23.3 WebRTC는 사용자 수가 증가하면 구조적 부담이 생긴다

현재 WebRTC 서비스 구현은 각 연결을 RTCPeerConnection 단위로 관리한다.

즉 다수 사용자에게 직접 연결하는 구조에서는 대략:

1
2
3
4
5
        A
      / | \
     B  C  D
     |  |  |
     ...

처럼 연결 수가 증가할 수 있다.

소규모 모임에는 적합하지만 대규모 방을 목표로 한다면 SFU 같은 별도 미디어 서버 구조를 고려해야 한다.


23.4 ZIP HTML 실행은 보안 경계가 중요하다

ZIP 내부 HTML을 브라우저에서 실행할 수 있다는 것은 강력한 기능이지만 동시에 가장 주의해야 할 기능 중 하나다.

특히:

1
2
3
4
5
외부에서 받은 ZIP
        ↓
HTML / JS 실행
        ↓
브라우저 환경 접근

이라는 경로가 있기 때문이다.

현재 구현은 Service Worker를 이용해 VFS를 제공하고, 내부 child Service Worker를 비활성화하는 처리도 포함한다. 하지만 실제 배포 환경에서는 sandboxing, origin 분리, CSP, 외부 요청 제한 등을 별도로 검토할 가치가 크다.


24. 보안 관점에서 확인이 필요한 부분

이번 분석은 프론트엔드 build만을 대상으로 했기 때문에 다음 항목은 확인할 수 없다.

확인이 필요한 서버 측 영역

  • 비밀번호 해시 방식
  • 세션/토큰 만료 정책
  • CSRF 방어
  • WebSocket 인증
  • 파일 업로드 검증
  • 파일 크기 제한
  • MIME spoofing 방어
  • 서버 권한 검증
  • 관리자 API 권한 검증
  • SQL injection 방어
  • Rate limit 구현
  • TURN 서버 인증
  • HTTPS 강제 여부
  • 서버 간 데이터 격리

따라서 이 보고서에서 “보안상 안전하다”는 결론을 내릴 수는 없다.

반대로 클라이언트 코드에는:

1
2
3
4
5
6
로그인
세션 만료
관리자 권한
가입 승인
비밀번호 재설정
Rate limit 관련 오류 메시지

등의 개념이 존재하므로, 적어도 서버 인증/권한 모델을 전제로 설계된 것은 확인된다.


25. 목적 분석

현재 빌드의 기능을 종합하면 프로젝트의 목적은 단순히:

“사람끼리 채팅한다.”

보다 넓다.

더 정확하게 표현하면:

개인 또는 소규모 그룹이 자신들의 공간을 만들고, 그 공간에서 대화하고, 자료를 공유하고, 기록을 축적하고, 필요하면 실시간 작업까지 할 수 있게 하는 것

에 가깝다.

이를 구조적으로 표현하면:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        사람
         │
         ▼
       공간
         │
 ┌───────┼────────┐
 ▼       ▼        ▼
대화     기록      자료
 │       │        │
 ▼       ▼        ▼
채팅    게시물    파일
메시지  메모      문서
                 그림
                 3D
         │
         ▼
      실시간 작업
         │
   ┌─────┼─────┐
   ▼     ▼     ▼
 음성   영상   화면

이 구조가 현재 프로젝트의 본질에 가장 가깝다.


26. 이 프로젝트의 가장 독특한 점

기술 하나만 놓고 보면:

  • Svelte
  • WebRTC
  • IndexedDB
  • PWA
  • WebSocket
  • Three.js

모두 이미 존재하는 기술이다.

하지만 이 프로젝트의 독특함은 이 기술들을 결합한 방식에 있다.

특히:

1
2
3
4
5
6
7
8
9
10
11
12
13
Self-hosted
+
Local-first
+
Closed community
+
Realtime communication
+
Persistent records
+
Rich file viewer
+
Temporary rooms

가 한 제품 안에 들어가 있다.

즉 기술적인 차별점보다는 제품 구조의 차별점이 더 크다.


27. 장점 요약

영역 장점
아키텍처 웹 기반이면서 앱에 가까운 구조
데이터 IndexedDB 기반 로컬 캐시/기록
커뮤니케이션 WebSocket + WebRTC
통화 음성/영상/화면 공유
커뮤니티 서버/채널/가입 승인/관리자
기록 게시물/메모/핀/공지
파일 다양한 포맷을 브라우저에서 직접 열람
개발자 경험 코드/HTML/ZIP/3D 모델까지 다룸
공유 QR/링크 중심
배포 PWA
오프라인 Service Worker 캐시
커스터마이징 언어팩 및 서버/ICE 설정
확장성 로컬과 온라인 데이터를 하나의 UI로 통합

28. 단점 요약

영역 단점 / 위험
제품 정체성 기능 범위가 너무 넓어 핵심 가치가 흐려질 수 있음
진입장벽 서버/채널/ICE 등의 개념이 일반 사용자에게 어려움
로컬 데이터 IndexedDB 삭제/브라우저 정책의 영향을 받음
브라우저 의존성 WebRTC/PWA/Push 등의 호환성 문제
실시간 통화 P2P 연결 수 증가 시 확장성 문제
파일 뷰어 다양한 포맷을 지원할수록 보안/호환성 부담 증가
ZIP 실행 신뢰할 수 없는 HTML/JS 실행에 대한 보안 검토 필요
운영 서버 관리 기능이 많아질수록 관리자 UX 복잡도 증가
모바일 데스크톱에 비해 파일/화면공유/WebRTC 경험이 제한될 가능성
데이터 백업 로컬 데이터의 명확한 export/import 전략이 중요

29. 사용자 경험 관점에서의 핵심 개선 방향

기술을 더 추가하기보다는 이미 있는 기능을 하나의 이야기로 묶는 것이 중요하다.

현재 기능을 보면 다음과 같은 세 가지 층으로 정리할 수 있다.

Layer 1 — 모인다

1
2
3
4
5
서버
채널
초대
QR
모닥불

Layer 2 — 이야기한다

1
2
3
4
5
채팅
음성
영상
화면 공유
그림판

Layer 3 — 남긴다

1
2
3
4
5
6
7
게시물
메모
파일
문서
이미지
3D
로컬 기록

이렇게 정리하면 앱의 기능이 훨씬 자연스럽게 설명된다.


30. 특히 좋은 제품 방향

현재 코드에 이미 존재하는 “모닥불”이라는 사용자 언어는 기술 구조와 상당히 잘 맞는다.

기술적으로는:

1
temporary channel

이지만 사용자에게는:

1
모닥불

이다.

이 차이는 단순한 번역이 아니다.

1
방을 만든다

1
모닥불을 피운다

는 사용자가 상상하는 행동 자체가 다르다.

전자는 기능이고 후자는 경험이다.

따라서 향후 UX에서 다음과 같은 방향을 일관되게 가져갈 수 있다.

1
2
3
4
5
6
서버 → 공간
채널 → 자리 / 모닥불
임시 채널 → 모닥불
초대 → 불을 나눠주기
참여 → 모닥불에 앉기
퇴장 → 모닥불에서 떠나기

단, 이 은유가 모든 화면의 기술적 용어를 대체해야 한다는 의미는 아니다. 설정/관리자 화면에서는 기존 용어가 오히려 정확하다.


31. 프로젝트의 포지셔닝을 한 문장으로 정리한다면

현재 빌드만 놓고 가장 자연스러운 설명은 다음과 같다.

자신만의 공간을 만들고, 그 안에서 사람들과 이야기하고 자료와 기록을 함께 쌓아가는 셀프호스팅 커뮤니케이션 앱.

조금 더 경험 중심으로 표현하면:

사람들이 잠시 모여 이야기하고, 필요하면 그 이야기를 기록으로 남길 수 있는 디지털 공간.

그리고 현재 UI의 “모닥불” 개념까지 포함하면:

필요할 때 모닥불을 피우고, 그곳에서 사람과 이야기와 기록을 함께 나누는 디지털 캠프파이어.


32. 종합 평가

이 프로젝트는 기능적으로 상당히 많은 것을 하나의 클라이언트에 통합하고 있다.

특히 기술적으로는:

1
2
3
4
5
6
7
8
9
10
11
SvelteKit
IndexedDB
WebSocket
WebRTC
Service Worker
Web Push
Canvas
WebGL / Three.js
WebAssembly
File API
QR

를 활용하면서 브라우저 자체를 하나의 애플리케이션 플랫폼으로 취급하는 방향이 일관되게 나타난다.

가장 큰 강점은 “기능이 많다”는 사실 자체가 아니다.

핵심은:

온라인 공간과 개인의 로컬 기록을 하나의 경험으로 연결한다는 점

이다.

반면 가장 큰 약점도 기능의 숫자에서 발생한다.

현재 상태 그대로 기능을 계속 추가하면:

1
2
3
4
5
6
7
채팅 앱
+ 메모 앱
+ SNS
+ 파일 뷰어
+ 그림판
+ 화상회의
+ 서버 관리 도구

라는 인상이 강해질 수 있다.

따라서 다음 단계에서 중요한 것은 새로운 기능을 추가하는 것보다 이미 존재하는 기능들이 왜 하나의 앱에 함께 존재하는지를 사용자에게 설명하는 것이다.

현재 코드와 UI에서 발견되는 “모닥불”이라는 표현은 이 문제를 해결할 수 있는 좋은 UX 축이다.


33. 분석 결과를 아키텍처 관점에서 압축하면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
                    ┌─────────────────────┐
                    │       사용자        │
                    └──────────┬──────────┘
                               │
                         SvelteKit UI
                               │
        ┌──────────────────────┼──────────────────────┐
        │                      │                      │
        ▼                      ▼                      ▼
   Local-first             Online                  Realtime
        │                      │                      │
   IndexedDB                HTTP(S)              WebSocket
        │                      │                      │
   ┌────┴────┐           ┌─────┴─────┐          ┌────┴────┐
   │         │           │           │          │         │
  Data     Files       Server      Posts      Chat     Signaling
   │         │           │           │          │         │
   └─────────┴───────────┴───────────┴──────────┴─────────┘
                               │
                         Communication
                               │
                    ┌──────────┼──────────┐
                    ▼          ▼          ▼
                  Audio      Video      Screen
                    └──────────┼──────────┘
                               │
                            WebRTC

                    Content / Creation
                               │
        ┌──────────┬──────────┼──────────┬──────────┐
        ▼          ▼          ▼          ▼          ▼
      Image      Video      PDF        ZIP       3D
        │          │          │          │          │
        └──────────┴──────────┴──────────┴──────────┘
                               │
                         File Viewer

34. 최종 결론

이 빌드는 단순한 “채팅 프로그램”으로 보기에는 기능과 구조가 훨씬 넓다.

기술적으로는

웹 브라우저를 로컬 데이터베이스 + 파일 시스템 + 실시간 통신 클라이언트 + 미디어 런타임으로 활용하는 앱이다.

제품적으로는

서버와 채널을 중심으로 소규모 사람들이 모이고, 대화하고, 자료를 공유하며, 기록을 남기는 공간이다.

UX적으로는

기능의 풍부함보다 “왜 이 기능들이 한 공간에 존재하는가”를 설명하는 것이 앞으로의 핵심 과제다.

가장 중요한 제품 자산은

이미 구현된 기능의 개수가 아니라, local ↔ server, chat ↔ record, temporary ↔ persistent, technical room ↔ bonfire를 하나의 경험으로 연결할 수 있는 구조다.

현재 빌드에서 발견되는 모닥불, 모닥불 채팅, 모닥불에서 떠납니다라는 표현은 이 구조를 사용자 경험으로 번역하기 시작했다는 명확한 흔적이다.

따라서 이 프로젝트는 기능을 더 많이 가진 메신저로 설명하기보다는, 사람과 기록이 함께 머무는 개인 소유의 디지털 공간이라는 방향으로 설명할 때 현재 구현된 여러 기능이 하나의 제품 안에서 자연스럽게 연결된다.


분석 범위 및 신뢰도

직접 확인한 항목

  • SvelteKit 빌드 구조
  • IndexedDB object store 및 index
  • Service Worker
  • PWA manifest
  • WebSocket 사용
  • WebRTC API 사용
  • STUN/ICE 설정
  • Web Push 처리
  • QR 생성/스캔 리소스
  • 파일 뷰어 분류
  • ZIP VFS
  • Three.js/WebGL 관련 코드
  • GIF 생성 로직
  • 채널/게시물/메시지/관리자 UI
  • 번역 리소스에 기록된 실제 기능명

추론이 필요한 항목

  • 실제 서버 백엔드 구현
  • 실제 DB 서버 종류 및 스키마
  • 인증 토큰의 상세 구조
  • 서버 측 권한 검증
  • 파일 저장 방식
  • 실제 운영 인프라
  • 실제 TURN 서버 구성
  • 서버의 확장성
  • 프로덕션 보안 수준

따라서 이 문서는 업로드된 클라이언트 build를 기반으로 한 제품/기술 구조 분석이며, 서버 코드까지 포함한 전체 시스템 감사(audit)는 아니다.

This post is licensed under CC BY 4.0 by the author.