-
Notifications
You must be signed in to change notification settings - Fork 3
29일차 회의록 (11월 25일)
- 카카오 로그인을 누르면 카카오 로그인 페이지로 이동한다.
- 사용자가 로그인에 성공을 하면, Callback URL에 accessToken과 refreshToken이 담기고 리다이렉트 된다.
- accessToken은 zustand에 보관을 한다. refreshToken은 쿠키에 저장한다.
- 로그인 (팝오버) → 문서화? → 워크스페이스 목록
- 충돌 → 워크스페이스 (소켓, 라우터) /
- WorkspaceNav를 클릭을 하면, accessToken을 서버로 보내 토큰 유효성 검사한 후 유효하다면, 그 URL로 리다이렉트한다. 유효하지 않으면
→ guest / owner → Guest이면 Guest라고 띄워준다..
useUser() → 본인의 이메일.. (guest, owner)
- 로그인 → (서버) → 카카오, 네이버 로그인 페이지로 이동
- 토큰 보관
- 토큰을 실어서 request를 보내기 (페이지 이동 GET /{workspace-id})
- 본인 유저 정보 zustand에 저장
- Workspace Navigation
- URL.. (Tanstack Router) - Protected Route → 찾아봐야 할 것 같고..
https://velog.io/@pjh1011409/React-Query- → query key [”user”]
- 미리보기 → 서버에서..
- 그룹화.. → 서버 추가 작업..
- 연결된 문서 목록 확인.. 서버에서 getPage() 실어서..
- 목차
- 패널 사이즈 조절..
- 다크 모드..
focus().. React Flow… id.. DOM query → id → .focus()
- 노션을 참고해보자면
Notion에는 아래와 같은 권한 수준이 있어요.
-
모두 허용
: 페이지에 대해 모두 허용 권한을 가진 사람은 모든 콘텐츠를 편집할 수 있고, 다른 사람에게 페이지를 공유할 수도 있습니다. (OWNER) -
편집 허용
: 페이지에 대해 편집 허용 권한을 가진 사람은 콘텐츠를 편집할 수는 있지만 다른 사람에게 페이지를 공유할 수는 없습니다. (GUEST) -
~~내용 편집 허용
: 이 권한 수준은 데이터베이스 페이지에만 나타납니다. 내용 편집 허용 권한을 가진 사람은 데이터베이스 내에서 페이지를 생성하거나 편집하고, 해당 페이지의 속성을 변경할 수 있습니다. 하지만 데이터베이스 자체의 구조나 속성, 보기, 정렬, 필터를 변경할 수는 없습니다. [데이터베이스에 대해 여기에서 자세히 알아보세요 →](https://www.notion.so/help/category/databases)~~ -
~~댓글 허용
: 댓글 허용 권한을 가진 사람은 페이지에 댓글을 달 수는 있지만 콘텐츠를 편집하거나 공유할 수는 없습니다.~~ -
~~읽기 허용
: 읽기 허용 권한을 가진 사람은 페이지 콘텐츠를 읽을 수는 있지만, 댓글을 달거나 편집하거나 공유할 수는 없습니다.~~
또한 워크스페이스에서 가진 역할에 따라 수행할 수 있는 작업도 달라집니다. 자세히 알아보려면 [이 문서를 읽어보세요 →](https://www.notion.so/help/add-members-admins-guests-and-groups#who%E2%80%99s-who-in-a-workspace)
→ 일단은 위의 권한 두개만 구현하기로!!!
- DB 전략
- 사용자 테이블
- 워크스페이스 테이블
- 두개를 매핑하는 권한(permission) 테이블
- (권한 id)
- 사용자 id
- 워크스페이스 id (사용자 - 워크스페이스는 unique)
- 권한 : owner / guest /→ 둘 다 아니면 접근조차 불가능
- 기본 생성: 비공개 →
- 워크 스페이스 테이블: (private /) 부분 공개 / public
- 부분 공개 → 다른 테이블 참조 (해당 사용자가 owner / guest인지)
- publiv / private으로 나뉘고….
- 생성 시점에 public vs. private → 초대는 private에서만 가능하게? → 알림도 있어야 할 거 같은데…?? → 남는 gmail SMTP
- 구글 드라이브
- → 링크를 가진 사람은 전부 편집 가능 vs. 초대
- 공개 (owner만 본인이 owner인지 알수있어야) ⇒
*비공개 (owner 빼고는 아무도)(안 구현해도 되지 않나?)* ⇒ 부분공개 (owner && guest): 이 순서대로 구현 - OWNER만 GUEST를 지정할 수 있고, GUEST는 편집이 가능하다?
workspace 타입
- public : 로그인, 비로그인 상관 없이 모두가 접근할 수 있다.
- ↔ 링크를 가진 사용자는 전부 편집 가능?
- Socket Room → new Y.doc()
- Owner → 최소한의 권한, validation ()
- Workspace table - Owner
- Workspace <→ node들, page들
- 그래서 .. 권한 체크는 어떻게 하는가.. JWT …
- 카카오 로그인 /api/signin → Redirect ? , 로그인 성공 → Redirect ?
- 로그인 버튼 → /api/auth/provider/
- /api/auth/{provider: naver, kakao}/callback → 요 라우트만 구현하시면?
- 응답으로 access, refresh 토큰이 오는데, 로컬 스토리지에 넣고 이전 경로로 보내주시면 될 듯 합니다
- 모든 api 요청에 자동으로 access token 실어서 보내는 로직
- access token 만료시 refresh 토큰으로 다시 발급받는 로직도 ( POST /api/auth/refresh)
- delete (Owner만 가능)
(화)
Socket, Y.doc() 저장 ← 서버 → 초기 데이터
(수, 목)
웹소켓 자체는 하나만 연결하고
ㄴ 룸1 : 룸ID = 워크스페이스ID
ㄴ 룸2
“f” , “workspaceId-pageid” …
/pages {…} → 로직이 존재 @달면 끝
/auth {…} → 홈페이지 리다이렉트
처음 접속하면 빈 캔버스 → private (다른 사람이 링크 긁어와도 아무것도 못하는 / 볼 수 도 없는)
공유 버튼을 눌렀을 때 → 링크를 가지고 있기만 하면 다 할수 있다: public
/?roomId={} 말이 정리가 잘 안되네요 ㅜㅜ
💡확정 사항 비 로그인 사용자: 공용 워크스페이스 (현재) 첫화면 ⇒ 체험할 수 있는 첫 화면 (DB에도 저장)
- 공용 워크스페이스 == 데모용 랜딩 페이지 !=
비로그인 사용자만 접근? - 처음 로그인(회원가입)하면?? 어디로 가야하는가 →
공용워크스페이스로- 바로 새로운 워크스페이스 자동 생성(private)
- 회원 가입 시 트랜잭션으로 (유저 정보 생성 + private 워크스페이스 생성 + 랜딩 페이지 하나?)
- 워크스페이스 리스트를 열면 ( 공용 - private - 유저가 생성한 순서… )
- 공용 워크스페이스는 그대신 리스트에서 중요성이 덜 강조되어야하지 않나?
- 바로 새로운 워크스페이스 자동 생성(private)
로그인 사용자:
- 마지막으로 참여한 워크스페이스 띄우기 ⇒ 어떻게?? 로컬스토리지 (V)
- excaildraw처럼 링크 기반 공유
- (비공개) → URL → (로그인) → (입장하겠습니까? → 수락 →) 권한 부여.
- URL 공유 (자동으로 24시간 만료, 어려운 URL) ⇒ 곧 수락버튼??
- (참여도) 로그인되어 있어야 가능?
- 권한 부여 URL을 눌렀다.
- (비 로그인) ⇒ 그냥 홈 or 로그인 으로 리다이렉트 (추가 작업 X)
- (로그인) ⇒ 권한 부여 후 안내 메시지 & 홈으로 리다이렉트 (워크스페이스 목록에 추가해줌)
- 권한 부여 URL 따로 있고
- 해당 url로 워크스페이스 + 사용자 → 서버에 들어와야 DB에 업데이트
- → 티켓 테이블 {uuid: (어떤 워크스페이스를 공유 받았다. 언제까지 된다…)}
- 이제 해당 사용자는 워크스페이스에 권한이 있으니까 해당 링크로 들어올 수 있다
- 로그인시 워크스페이스 목록으로 확인
- 워크스페이스 목록을 보낼때 권한 있는건 다 보낸다
- → 권한 부여는 어떻게 하나요???? A가 B의 페이지로 접속하려고 한다면 B가 A를 허락해줘야 하는데…
- 그 링크에 들어가려면 권한이 있으면 자동으로 들어가고
- 만약 권한이 없으면???? —> ????
- 계속해서 바뀌는 권한 부여 링크가
- FE: 권한 부여 창 새로 만들어야 하고
- BE: 해당 사용자가 존재하는지 계속 요청 응답 해봐야하고
-
private : 로그인을 했고 workspace에 대한 권한을 가진 사람만 접근할 수 있다.
-
초대가 들어간다
- 알림
- 초대 로직
- email(계정) validation
- email 발송
- 수락했을 때 권한 부여
-
페이지 리스트?
지금 Rest → socket
user와 workspace 테이블을 N:M으로 매핑
- 워크스페이스 설계 + 유저 통합
- 공유링크 & 권한 등
- 권한 종류?
- OWNER / EDITOR / READER / x : 아예 워크스페이스, 다큐멘트에 접근이 안됨
- OWNER: 워크스페이스 소유자 → 다른 사람 권한 조정
- EDITOR: 수정 / READER: 읽기만
- READER를 어떻게 구현하죠?? → 드래그(캔버스 상)는 되어야 하고 엣지 연결이나 새 페이지 생성 / 내용 추가 이런거만 막혀야하는데
- 소켓 최적화 로직? + 캐시
- 아키텍처 개선도 필요해보이고
- YDoc observe 할 때 forEach 말고 다른 방법이 있는지도 고민해보면 좋을 듯 하네요
- → 아직 자세히는 모르겠지만, 서비스-레포지토리 에서 find-update 를 계속 반복하는 것도 쿼리 과다의 원인이지 않나 싶어요
- 완전 배포
- postgres 연결
- main 기준 public WAS와 private DB에 완전히 연결되도록
- (아키텍처 개선으로 추가되는 서비스 구성)
- 도메인 연결 및 https 구성 (wss도 되어야 할 것 같네요. nginx 말고 방법이 안떠오름...)
- 워크 스페이스 ⇒
- 메모리 기반 캐시 (현재)
- 간단한 스케줄러, Queue 직접 구현
-
캐시 없이 WAS의 임시메모리에 쌓아뒀다가, 일정량 모이면 처리하게
- 1초에 한 번? → lodash.debounce
- node가 변경 →
- title만 변할때도, x,y만 변할때도, content만 변할때도
- 전체를 쌓아둔다 vs. 부분적으로 쌓아둔다
- 전체를 쌓아두는게 라이브러리 사용 + 구현이 더 편할 것
- node가 변경 →
- 1초에 한 번? → lodash.debounce
- Redis 기반 캐시
- Message Queue (Kafka?)
→ 지금은 nodeMap, edgeMap을 observe하는데 “변경되었다는 사실”만 알 수 있어서 forEach로 쿼리를 돌아서 부하가 있음
→ forEach 제거부터 해야한다
→ 변경사항만 감지….
(1) FE에서 변경사항만 감지 → BE로 전달
(2) BE에서 변경사항 알아서 감지
결론 ⇒ 일단 소켓에서 forEach 부분을 전부 없애보고 변경사항만 감지하도록 한 후 테스트 + WAS 메모리로 캐싱 및 bulk save 방식 도입해보기
→ 이래도 느리면 Redis나 MQ 도입 고려
- https → wss nginx + let’s encrypt? → 도커 도입?
- docker-compose 하나?
- → 도커 이미지 pull?
- git pull → pkg로 바이너리 파일
docker-compose로 로컬에서 DB 연결까지 시도해보고 환경에 따라 나누어 작성
compose.local
compose.prod
- postgres 연결
- main 기준 public WAS와 private DB에 완전히 연결되도록
- (아키텍처 개선으로 추가되는 서비스 구성)
- 도메인 연결 및 https 구성 (wss도 되어야 할 것 같네요. nginx 말고 방법이 안떠오름...)
- 환경에 따른 docker-compose 작성
- 프론트는 어캐하죠…? nginx 컨테이너가 빌드해서 가리키게 하기
- local: nginx + nest + postgres
- prod: nginx + nest (+ postgres = private subnet)
- 도메인 연결 + HTTPS + WSS
- let’s encrypt로 인증서 발급
- secure 적용 및 도메인 구입 후 연결 (도메인은 n빵합시다)
- CD?
- 도커 이미지 빌드 후 도커허브 업로드
- 배포 환경에서는 이벤트 감지해서 도커 허브에서 pull 후 재시작
- 캐시 부하 개선
- 워크 스페이스 구현 + 권한 관리
- 워크스페이스 구현 및 권한 관리 + 캐시 개선 + 배포
- 성민: 캐시 개선
- 서진: 워크스페이스 구현 및 권한 관리
- 현준: 배포 및 https / wss + CD
- 각자 분야를 책임지고 맡고, 빨리 끝내신 분들은 도와주세요~
⚓️ 사용자 피드백과 버그 기록
👷🏻 기술적 도전
📖 위키와 학습정리
✏️ 에디터
Novel이란?
Novel 스타일링 문제
에디터 저장 및 고려 사항들
📠 실시간 협업, 통신
Yorkie와 Novel editor 연동
YJS, Websocket, React-Flow
YJS, Socket.io
WebSocket과 Socket.io에 대해 간단히 알아보기
YJS 가이드 근데 이제 Socket.io를 곁들인
🏗️ 인프라와 CI/CD
NCloud CI CD 구축
BE 개발 스택과 기술적 고민
private key로 원격 서버 접근
nCloud 서버, VPC 만들고 설정
monorepo로 변경
⌛ 캐시, 최적화
rabbit mq 사용법
🔑 인증, 인가, 보안
passport로 oAuth 로그인 회원가입 구현
FE 로그인 기능 구현
JWT로 인증 인가 구현
JWT 쿠키로 사용하기
refresh token 보완하기
🧸 팀원 소개
⛺️ 그라운드 룰
🍞 커밋 컨벤션
🧈 이슈, PR 컨벤션
🥞 브랜치 전략
🌤️ 데일리 스크럼
📑 회의록
1️⃣ 1주차
킥오프(10/25)
2일차(10/29)
3일차(10/30)
4일차(10/31)
2️⃣ 2주차
8일차(11/04)
9일차(11/05)
11일차(11/07)
13일차(11/09)
3️⃣ 3주차
3주차 주간계획(11/11)
16일차(11/12)
18일차(11/14)
4️⃣ 4주차
4주차 주간계획(11/18)
23일차(11/19)
24일차(11/20)
25일차(11/21)
5️⃣ 5주차
5주차 주간계획(11/25)
29일차(11/25)
32일차(11/28)
34일차(11/30)
6️⃣ 6주차
6주차 주간계획(12/2)
37일차(12/3)