
미리보기
- 직업
- 논리와 근거를 바탕으로 문제를 해결합니다
- 이름
- 유동선
- 간단소개
- 논리와 근거를 바탕으로 문제를 해결하고 이를 통한 성장을 추구합니다. 실패를 두려워하지 않고 경험으로 승화시키며, 긍정적인 태도로 팀과 함께 공동의 목표를 달성하고자 노력합니다.
기술 스택
- 기술 스택
- TypeScript
- Node.js
- NestJS
- PostgreSQL
- Redis
- AWS
- ec2
- s3
- Prisma
- express.js
프로젝트
- 프로젝트명
- 에코닷
- 소속/기관명
- 개인(프리랜서)
- 프로젝트 기간
- 2024.03. - 2024.06.
- (4개월)
- 프로젝트 설명
서비스 기획을 받아 서버 구축부터 ERD 설계, API 설계, 배포까지 개인이 진행
프로그램의 총 관리자가 학습 컨텐츠와 커리큘럼을 만들고, 선생님은 생성된 커리큘럼과 학습 컨텐츠들을 자신의 반에 자유롭게 구성
학생은 랜딩 web에서 관리자가 등록한 수업을 들을 수 있으며, 선생님은 학생들의 진행상황을 관찰하고 반을 관리
강의 영상, 퀴즈, 블록 코딩, AR학습 등의 학습 컨텐츠를 제공하여 다양한 교육을 지원,
선생님은 학생들의 학습 진도율을 확인할 수 있음.
관리자, 선생님, 학생으로, 총 3가지로 권한이 나누어져 권한에 따른 api 분기처리 세밀화
복잡한 데이터 모델링 설계
ex1) 선생은 여러 개의 반을 관리할 수 있음, 반은 한명의 선생만 가질수 있음. 선생은 반을 가지지 않을 수도 있지만, 반은 선생을 가지고 있어야 함.
ex2) 학습 컨텐츠의 종류는 각기 다른 4가지로 이루어져 있음. 커리큘럼은 여러 개의 학습 콘텐츠를 가질 수 있음, 하지만 하나의 학습 컨텐츠는 여러 커리큘럼을 가질 수 없음
진도율 중복 체크 방지와, 선생님, 또는 관리자가 어떤 학생이 접속해있는지 확인하기 위해 중복 로그인을 방지해야함.
처음에는 단순히 비디오를 통째로 서버에 업로드하고 그대로 영상을 내려주려고 했으나, Postman이 비정상 종료되고 브라우저에서 파일을 받지 못하는 현상이 발생하였습니다.
원인 분석 결과, 큰 용량의 파일을 한번에 업로드 또는 다운로드 하는방식이, 네트워크와 브라우저에서 용량문제가 발생할수 있다는 것을 인지하였습니다.
이를 해결하기 위해 HLS(HTTP Live Streaming)방식을 도입하였습니다, 어플리케이션 서버에서 ffmpeg라이브러리를 이용해 영상을 트랜스코딩하여 작은 청크파일들로 나누어 보관하고, 클라이언트에서 HLS요청을 받아 해당하는 청크파일들을 스트리밍하였습니다.
이를통해 네트워크와 브라우저의 성능 이슈를 해결하고, 스트리밍을 통해 불필요한 네트워크 리소스를 줄였습니다.
express-validator를 이용하여 선언형으로 validation을 구현하였습니다.
이를 이용해 여러 API 엔드포인트마다 재사용 가능하고, 유연한 validation처리가 이루어졌습니다.
각각의 관심사를 가지는 Router, Service 레이어를 두었습니다.
Router: Authentication, Validation 등 Http요청을 받아 전처리 담당
Service: 비즈니스 로직, 데이터 엑세스
위처럼 관심사 별로 레이어를 구성하여, 레이어간의 응집도를 높이고, 추가적으로 TypeDI로 의존성 주입을 이용하여 레이어간 결합도를 낮추었습니다.
이를 통해 각 계층은 외부 의존성에 대해 신경쓰지 않고, 자신의 관심사에만 집중하게 되었습니다.
앞서 중점사항에서 말한 중복 로그인으로 인한 학습 진도율 중복 체크를 방지하기 위해 세션기반의 로그인 방식을 채택하였습니다.
로그인 시 해당하는 사용자의 JWT를 생성한 후, Key에 유저의 인덱스를 넣고, Value에 JWT를 넣어 중복 로그인을 방지할 수 있었습니다.
[Redis를 선택한 이유는?]
key-value를 저장할 공간이 필요함 && 해당 세션에 대한 TTL도 필요함 && 모든 API call 전에 잦은 조회가 수행됨 -> 인메모리 기반의 데이터베이스인 Redis를 선정하였습니다.
클라이언트 요구사항에서, 로그인 후(서버에 세션이 생성된 후) 5분간 활동이 없으면(어떤 API도 호출하지 않았다면) 강제 로그아웃되는 기능이 있었습니다.
로그인 시, Redis에 저장한 세션 정보에 TTL을 5분으로 설정한 후.
권한을 체크하는 미들웨어에서 redis.expire메소드를 통해 TTL을 갱신하였습니다.이를 통해 "로그인 5분 제한" 이라는 문제를 해결하였습니다.
정규화
4가지로 이루어진 학습 컨텐츠 들의 공통된 속성들을 묶어 부모 테이블을 만들고(학습 콘텐츠 테이블), 하위에 학습콘텐츠 종류별 테이블을 만들어 각각의 테이블 역할을 분리하였습니다.
여러 개의 반과, 여러 개의 학습콘텐츠들을 가진 커리큘럼의 N:M관계를 효율적으로 관리하기 위해 중간테이블(curriculum_content, class_curriculum)을 두어 유연하게 관계를 정립하고 중복되는 컬럼들을 최소화하였습니다.
강의 영상 시청 시, 강의 진도율 기록이 완전한 실시간일 필요가 없다고 판단해, Polling방식을 이용하여 강의 영상의 진도율을 계산하였습니다. 강의 재생을 하고 있는 중에 30초마다 강의 진행 API를 호출하여 (API가 들어온 회수 / 전체 영상 길이)로 강의 영상의 진도율을 체크하였습니다.
커리큘럼의 구성과 학습 컨텐츠의 구성이 변경될수도 있기 때문에 진도율을 단순히 DB에 Integer로 저장하면 안된다고 판단해, 학생이 각 학습 컨텐츠들을 완료했을 때 완료여부를 (content_complete)테이블에 저장한 후, 학생이 총 진도율을 체크하는 API를 호출할 시, 서버에서 실시간으로 계산하여(학생이 가지고 있는 학습 컨텐츠 개수 / 완료한 학습 컨텐츠 개수) 내려주었습니다.
이처럼 진도율을 동적으로 산출하여 정확하고 유연한 학습 진도율 관리가 이루어지도록 하였습니다.
개발 기간 도중 프론트엔드 개발자와 기획자 분이 실시간으로 API에 대한 피드백과 질문을 받을수 있게 Notion을 이용하여, API명세서를 작성하였습니다.
기술 스택: Tyepscript, Express, PostgreSQL, Prisma, Redis, AWS S3, AWS EC2
[요약]
환경 분야 교육 플랫폼
[개발 중점 사항]
[고민한 내용들]
강의 영상 스트리밍 [https://inko51366.tistory.com/48]
Reuqest Validation [https://inko51366.tistory.com/54]
레이어드 아키텍쳐 적용 [https://inko51366.tistory.com/53]
사용자 인증 및 인가
중복 로그인을 어떻게 막을것인가?
인가 처리를 어떻게 할것인가?
데이터베이스 설계
학습 진도율 계산
[커뮤니케이션]
- 프로젝트명
- dudu
- 소속/기관명
- 개인(프리랜서)
- 프로젝트 기간
- - 진행 중
- 프로젝트 설명
스케쥴링을 통해 일정 주기마다 .xlsx파일로 문서화 (추후 예정)
출결 관리 시스템 개발 프로젝트
기술 스택: NestJS, Prisma, TypeScript, PostgreSQL, Jest, Docker
프로젝트 배경:
현재 근무 중인 학원에서는 학생들의 출결 관리를 엑셀과 문서로 수동 처리하고 있습니다. 이로 인한 데이터 불일치, 업무 효율성 저하, 학생 외출 관리의 불편함 등의 문제가 발생하고 있습니다. 원장님의 요청으로, 문제를 해결하기 위해 데이터의 정확성과 학생관리의 편의성을 극대화하는 출결 관리 시스템을 개발하였습니다.
개발 중점 사항:
학원의 특성상 프로그램 도입에 대해 보수적인 입장이 있어, 빠르고 다양한 기능 구현보다는 due date를 길게 잡아 안정적이고 탄탄한 설계와 철저한 테스트를 통해 프로그램의 무결성과 일관성을 보장하는 것을 최우선으로 염두에 두고 개발하였습니다. 이를 위해 객체지향 설계와 단위/통합 테스트 코드 작성에 중점을 두고 개발 중입니다.
- 객체지향 설계(OOP): 설계된 데이터베이스 모델을 바탕으로 도메인 객체를 구성하고, 각 객체 간의 책임과 역할을 명확히 정의하며 개발을 진행하고 있습니다. 이로써 코드의 재사용성과 유지보수성을 높이고, 변화에 유연하게 대응할 수 있는 시스템을 구축하였습니다. 또한 외부 의존성과의 분리를 중요시 하고 이에따른 데이터 일관성의 문제를 최대한 고려하여 설계하였습니다.
- 테스트 코드 작성: 서비스의 안정성과 품질을 확보하기 위해 모든 주요 기능에 대해 철저한 테스트 코드를 작성하고 있습니다. 특히, Prisma를 사용한 데이터베이스 연동 부분에서 통합 테스트를 통해 데이터의 정확성을 보장하고 있습니다. 이를 통해 코드 변경 시 발생할 수 있는 문제를 사전에 방지하며, 안정적인 시스템을 유지하고자 노력하고 있습니다.
핵심 기능:
- 학생 정보 등록: 학생들의 정보를 체계적으로 등록 및 관리할 수 있습니다.
- 학생 등원 및 하원 기록: 학생들의 등원 및 하원 시간을 정확하게 기록하여 출결 상황을 관리합니다.
- 학생 결제 내역 기록: 학생들의 결제 내역을 관리하고 기록합니다.
- 외부 학원 스케줄 관리: 외부 학원의 스케줄을 기록하여 일정 관리의 효율성을 높입니다.
- 외출 스케줄 기록: 학생들의 외출 스케줄을 기록하여 복귀하지 않은 학생들을 손쉽게 확인할수 있습니다
- 선생님들 간 인수인계사항 공유: 선생님들 간 인수인계 사항을 실시간으로 공유할 수 있는 기능. (Websocket)
- 등원 및 하원 시 부모님에게 메시지 전송(추후 예정): 학생의 등원 및 하원 시 부모님에게 SMS를 통해
- 미등원 알림 (추후 예정): 미등원 시 학원 측(Server Sent Event), 학부모 측(Naver Cloud Flatform을 이용한 SMS)에 알림을 제공하는 기능
포트폴리오
- 타입
- URL
교육
- 소속/기관
- 스테이지어스
- 종류 | 전공명/전공계열
- 사설 교육 | 웹 백엔드
- 재학 기간 (재학 상태)
- 2023.04. - 2023.11. (졸업)
자기소개
- 자기소개
개발 분야는 좋은 개발자가 되기 위한 방대한 양의 지식들이 존재하고, 저는 매일 꾸준히 개발 공부를 하고, 매 순간 만나게 되는 문제에 대해 깊게 고민합니다.
작은 문제를 해결하며 결국에는 큰 문제를 해결하듯이(분할정복) 매일 매일 꾸준하게 작은 문제들을 해결한다면 어느 순간 큰 문제를 해결하고 있는 자신을 마주합니다.
단순한 개발 능력을 넘어, 문제를 마주했을 때 포기하지 않고 끝까지 해결책을 찾는 끈기를 가지고있습니다
단순히 보면 개발자는 프로그래밍을 통해 요구사항을 구현하는 직업입니다. 이러한 과정에서 기능을 구현하는 것을 넘어, 효율적이고 확장 가능한 솔루션을 만드는 것을 중요한 가치로 여기고 있습니다.
A => B가 만족하고, B => C가 만족한다면 논리적으로 A => C가 만족하듯이. 항상 문제를 논리적으로 접근합니다.
항상 스스로에게 질문을 던집니다.
"이 문제의 근본적인 원인은 무엇인가?"
"내가 지금 당장 해결할 수 있는 문제가 무엇인가?"
이러한 질문을 통해 새로운 기술이나 패턴을 적용하며 배우고, 단기적인 해결책이 아닌 장기적으로 유지보수 가능한 구조를 설계 하려 노력합니다.
정답이 없는 문제에 대해서 이야기하는것을 좋아합니다.
팀원들과 끊임없이 토론하고 대화, 수많은 선택지를 염두에 두고, 상황에 맞는 최선의 선택을 합니다.
진정한 소통이란 서로 다른 관점을 이야기하고, 이를 잘 조합하여 복잡한 문제를 해결하는 것임을 알고있습니다.
단순히 의견을 제시하는 것을 넘어, 상대방의 입장에서 생각하고 바라보는 것을 중요시합니다. 이러한 커뮤니케이션은 협업의 질을 높이고 공동의 목표를 향해 나아갈 수 있는 빠른 지름길을 열 수 있습니다.