Skip to content

온라인 메모장 📝

공동 편집 가능한 경량화 메모장
Backend Repo »
Frontend Repo »


 📖 목차
  1.   🔍 Introduction
  2.   📄 Documents
  3.   📹 Demo
  4.   💡 Tech Stack
  5.   🗂️ Database
  6.   💻 Architecture
  7.   📂 Directory Structure
  8.   👨‍👩‍👧‍👧 Team

🔍 Introduction

배경

기존 메모 서비스들은 다양한 기능을 추가하며, 정작 핵심인 '간편함'을 잃었습니다.
'다기능 = 편리함'이라는 전제 아래 복잡해졌고, 오히려 단순한 메모 작성조차 번거로워졌습니다.
심지어 일부 서비스는 다른 기기에서 열람하려면 소셜 로그인 내 본인인증까지 거쳐야 합니다.

그래서 질문했습니다. "편리함은 꼭 기능의 많음에서 오는 걸까?"
이에 남녀노소 누구나 직관적으로 사용하도록, 본질에 집중한 '경량화 메모장'을 개발했습니다.
어떤 기기에서든 쉽고 빠르게, 가볍지만 공동 편집까지 가능한 '진짜 편리함'을 제공합니다.

특징

  • 빠른 로그인 :  개인정보 없이 ID·PW로만 즉시 가입/로그인, 계정별 메모 관리
  • 친구 초대 :  계정 초대/수락으로 친구를 맺고, 메모에 함께 참여 가능
  • 공동 메모 :  여러 사용자가 함께 메모를 관리, 권한 기반으로 편집 충돌 방지
  • 메모 분류 :  전체/개인/공동/즐겨찾기 메모를 선택해 유형별로 조회 가능
  • 제목 AI 생성 :  작성중인 메모 내용에 어울리는 제목을 AI가 자동으로 추천
  • 직관적 UI/UX :  복잡한 기능 및 절차 최소화, 편안한 색감과 간결한 인터페이스
  • 기기/플랫폼 호환 :  PC·모바일, Android·iOS, 웹·앱 모두 지원

📄 Documents


📹 Demo

Google Play 스토어

플레이스토어 스크린샷 플레이스토어 PC 스크린샷

PC Page

메모 목록 조회 메모 내용 조회 친구 공동메모 초대

Mobile Page

로그인 메모 목록 조회 메모 내용 조회 메모 작성 (+ AI 제목)
프로필 조회 친구 목록 조회 친구요청 수신 목록 조회 친구 공동메모 초대

💡 Tech Stack

Frontend Backend Back Office (ETL) Security Other

[ React Native ]
[ Spring Boot ]



[ Redis ]



[ Spring Security ]
[ JSON Web Token ]
[ Amazon AWS ]
[ Github Actions ]


- Frontend : React, React Native, JavaScript
- Backend : Spring Boot, Java, Spring Security, JWT, OpenAI
- Back Office (ETL) : GA4, BigQuery, Cloud Run
- Database : MySQL, Redis, MongoDB
- Deployment : Amazon AWS, Github Actions
- Tool : Slack, Postman, Swagger

🗂️ Database

 Redis :  서비스 데이터 (임시)  ⇒  편집권한 Lock, 일일 AI 호출 횟수 등
항목 Key-Value TTL 설명
편집권한 Lock {메모정보:lock : 사용자정보}
{memoId:1200:lock : userId:10,userName:현진}
10분 - Redis Lettuce 분산 락
- 편집자 외 수정접근 제한
  (편집 중인 상대방 표시)
일일 AI 호출횟수 {사용자정보:openai_usage : 호출횟수}
{userId:1200:openai_usage : 3}
자정 개인 OpenAI 호출량 검사
(일일 최대 10회 제한)
JVM Heap 위험 쿨타임
(스케줄러 + Slack)
{backoffice:경보종류 : true}
{backoffice:heap_notification : true}
1시간 - 5분마다 Heap 메모리 체크
- 70/80/90% Slack 알림
  (1시간 내 중복알림 방지)
EC2 RAM 위험 쿨타임
(스케줄러 + Slack)
{backoffice:경보종류 : true}
{backoffice:ram_notification : true}
1시간 - 5분마다 RAM 메모리 체크
- 90/95% Slack 알림
  (1시간 내 중복알림 방지)
 MySQL :  서비스 데이터 (영구)  ⇒  사용자, 메모, 친구 관계 등
mysql DB ERD
 MongoDB :  트래픽 데이터  ⇒  GA4 페이지뷰, 접속자 기기, 국가 등
구분 항목 컬럼명 설명
이벤트 정보 이벤트 시간 event_datetime 이벤트 발생 시각
활성 사용자 ID user_pseudo_id 익명 사용자 식별 ID
로그인 사용자 ID login_user_id 로그인한 사용자 ID
페이지 정보 페이지명 page_title 브라우저 탭/문서 제목
유입 경로 URL page_referrer 이전 페이지 URL
현재 경로 URL page_location 전체 현재 페이지 URL
현재 경로 Path page_path 도메인 제외한 경로
기기 정보 기기 카테고리 device_category 모바일/데스크톱 등
기기 브랜드명 device_brand 기기 제조사
웹 브라우저 device_browser 사용 브라우저 이름
접속 정보 국가 geo_country 접속 국가
지역 geo_region 접속 지역(주/도 단위)
도시 geo_city 접속 도시

💻 Architecture

System

onlinememo_architecture drawio network_architecture drawio

- Frontend Deployment : AWS Amplify
- Backend Deployment : AWS Elastic Beanstalk, Github Actions
- Database : AWS RDS, Upstash Redis
- DNS : AWS Route53
- Traffic : AWS Application Load Balancer, Auto Scaling (CPU 70% Out, 30% In)
- Monitoring : AWS CloudWatch, Slack, Spring Logback, ExceptionHandler
- Version control : AWS S3, Github

Back Office (ETL)

backoffice_architecture drawio backoffice_statistics drawio

GA4 (React : 실사용자 지표 수집)
→ BigQuery (SQL : 수집 데이터 검증)
→ Cloud Run (Serverless API : 데이터 필터링 및 제공)
→ MongoDB (Spring : 정제된 지표 저장 및 백오피스 운용)

Monitoring

테스터 트래픽
Web & App 테스터를 모집해,
특정 시간대 10분 동안의
트래픽 변화를 측정.
테스터 30명의 동시접속 결과, CPU 사용률이 0.7% → 6% 상승함을 확인.
초기 운영에는 충분하나, 예기치 않은 트래픽 증가 시 Burst 기능을 안정적으로 운용하고자
인스턴스를 t3.nano(CPU 크레딧 6)t3.micro(CPU 크레딧 12)로 Scale Up 조치.
Slack 경보 CloudWatch 로깅
1.  Spring ExceptionHandler : Error Handling
2.  Spring Logback : Logging
3.  Local  File Storage : Save to file
4-1.  Prod  AWS CloudWatch : Monitoring
4-2.  Prod  Slack Webhook : Notification

📂 Directory Structure

 Backend :  Open!
----------------------------------------------------------------------------------------------
[ Backend ]
----------------------------------------------------------------------------------------------
:                                                 :
├── client                                        ├── repository
│   ├── Ga4Client.java                            │   ├── UserRepository.java
│   └── OpenAIClient.java                         │   ├── MemoRepository.java
├── config                                        │   ├── MemoBatchRepository.java
│   ├── FeignConfig.java                          │   ├── UserMemoRepository.java
│   ├── SecurityConfig.java                       │   ├── UserMemoBatchRepository.java
│   ├── SwaggerConfig.java                        │   ├── FriendshipRepository.java
│   ├── RedisConfig.java                          │   ├── FriendshipBatchRepository.java
│   └── OpenAIConfig.java                         │   ├── Ga4FilteredRepository.java
├── controller                                    │   ├── Ga4FilteredBatchRepository.java
│   ├── AuthController.java                       │   └── RedisRepository.java
│   ├── UserController.java                       ├── response
│   ├── MemoController.java                       │   ├── ResponseCode.java
│   ├── FriendshipController.java                 │   ├── ResponseData.java
│   ├── BackOfficeController.java                 │   ├── GlobalExceptionHandler.java
│   └── TestController.java                       │   ├── exception
├── domain                                        │   │   ├── CustomException.java
│   ├── User.java                                 │   │   ├── Exception400.java
│   ├── Memo.java                                 │   │   ├── Exception404.java
│   ├── Friendship.java                           │   │   ├── Exception409.java
│   ├── mapping                                   │   │   ├── Exception423.java
│   │   └── UserMemo.java                         │   │   ├── Exception429.java
│   ├── backoffice                                │   │   └── Exception500.java
│   │   └── Ga4Filtered.java                      │   └── item
│   ├── common                                    │       ├── MessageItem.java
│   │   ├── BaseCreatedEntity.java                │       └── StatusItem.java
│   │   └── BaseModifiedEntity.java               ├── service
│   └── enums                                     │   ├── AuthService.java
│       ├── Authority.java                        │   ├── UserService.java
│       └── FriendshipState.java                  │   ├── MemoService.java
├── dto                                           │   ├── MemoFacade.java
│   ├── AuthDto.java                              │   ├── UserMemoService.java
│   ├── UserDto.java                              │   ├── FriendshipService.java
│   ├── MemoDto.java                              │   ├── Ga4FilteredService.java
│   ├── FriendshipDto.java                        │   ├── BackOfficeScheduler.java
│   └── Ga4FilteredDto.java                       │   └── impl
└── jwt                                           │       ├── AuthServiceImpl.java
    ├── JwtFilter.java                            │       ├── UserServiceImpl.java
    ├── TokenProvider.java                        │       ├── MemoServiceImpl.java
    ├── CustomUserDetailsService.java             │       ├── MemoFacadeImpl.java
    └── handler                                   │       ├── UserMemoServiceImpl.java
        ├── JwtExceptionFilter.java               │       ├── FriendshipServiceImpl.java
        ├── JwtAccessDeniedHandler.java           │       └── Ga4FilteredServiceImpl.java
        └── JwtAuthenticationEntryPoint.java      └── util
                                                      ├── SecurityUtil.java
                                                      └── TimeConverter.java


----------------------------------------------------------------------------------------------
[ DevOps - backend ]                              [ DevOps - submodule ]
----------------------------------------------------------------------------------------------
:                                                 :
├── .github/workflows                             ├── .github/workflows
│   └── deploy.yml                                │   └── deploy.env
├── resources                                     └── resources
│   └── application-local.properties                  └── application-prod.properties
├── .ebextensions
│   ├── 00-set-timezone.config
│   ├── 01-set-swapmemory.config
│   └── 02-set-heapdump.config
├── .platform
│   ├── hooks/predeploy
│   │   ├── 00_kill_prev_spring.sh
│   │   └── 99_cleanup_nginx.sh
│   └── nginx/conf.d
│       ├── http_bodysize.conf
│       └── elasticbeanstalk
│           ├── server_gzip.conf
│           ├── server_nolog.conf
│           └── server_nocrawl.conf
└── Procfile
 Frontend_Web :  Open!
:
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── linkthumbnail.png
│   ├── manifest.json
│   ├── memoicon128.png
│   ├── memoicon192.png
│   ├── memoicon512.png
│   └── global
│       ├── globalStyle.css
│       └── fontawesome.css
└── src
    ├── assets
    │   ├── css
    │   │   ├── confirmAlert.css
    │   │   └── mobileToast.css
    │   ├── fonts
    │   │   ├── BMJUA.woff2
    │   │   ├── LINESeedKR-Bd.woff2
    │   │   ├── KOTRAHOPE_subset.woff2
    │   │   ├── Kalam-Regular_subset.woff2
    │   │   └── fontawesome-webfont.woff2
    │   └── images
    │       └── user.png
    ├── apis
    │   └── Api.jsx
    ├── components
    │   ├── Core
    │   │   ├── Header.jsx
    │   │   ├── Footer.jsx
    │   │   ├── Toast.jsx
    │   │   └── GA4Tracker.jsx
    │   ├── List
    │   │   ├── FriendList.jsx
    │   │   ├── InviteFriendList.jsx
    │   │   ├── MemoList.jsx
    │   │   ├── MemoListItem.jsx
    │   │   ├── SelectFriendList.jsx
    │   │   └── SenderList.jsx
    │   ├── Modal
    │   │   ├── ConfirmModal.jsx
    │   │   ├── FriendGroupModal.jsx
    │   │   ├── GlobalModal.jsx
    │   │   ├── NoticeModal.jsx
    │   │   └── SendFriendshipModal.jsx
    │   ├── Navigation
    │   │   ├── LoadingNav.jsx
    │   │   ├── NewMemoNav.jsx
    │   │   ├── ReadAndEditMemoNav.jsx
    │   │   ├── NoLoginNav.jsx
    │   │   └── YesLoginNav.jsx
    │   ├── Styled
    │   │   ├── BasicWrapper.jsx
    │   │   ├── HelloWrapper.jsx
    │   │   ├── NavWrapper.jsx
    │   │   └── OneMemoWrapper.jsx
    │   └── UI
    │       ├── Checkbox.jsx
    │       ├── DropdownCenter.jsx
    │       ├── DropdownLeft.jsx
    │       ├── DropdownRight.jsx
    │       ├── FriendOptionDropdownCenter.jsx
    │       ├── IsStarButton.jsx
    │       ├── MemoOptionButton.jsx
    │       ├── MemoOptionDropdownRight.jsx
    │       ├── NewMemoOptionDropdownRight.jsx
    │       ├── SearchMemo.jsx
    │       └── SortMemo.jsx
    ├── pages
    │   ├── BackOffice
    │   │   └── StatisticPage.jsx
    │   ├── User
    │   │   ├── LoginPage.jsx
    │   │   ├── SignupPage.jsx
    │   │   ├── ChangePwPage.jsx
    │   │   └── ProfilePage.jsx
    │   ├── Memo
    │   │   ├── MemoListPage.jsx
    │   │   ├── NewMemoPage.jsx
    │   │   └── ReadAndEditMemoPage.jsx
    │   ├── Friend
    │   │   ├── FriendListPage.jsx
    │   │   └── SenderListPage.jsx
    │   └── Etc
    │       ├── DownloadPage.jsx
    │       ├── NoticePage.jsx
    │       └── InformationPage.jsx
    ├── hooks
    │   └── useDetectDropdown.jsx
    └── utils
        ├── lazyUtil.js
        ├── AlertUtil.js
        ├── MetaUtil.js
        ├── TimeUtil.js
        ├── ToastUtil.js
        └── TokenUtil.js
 Frontend_App :  Open!
:
├── App.js
├── app.json
├── assets
│   ├── adaptive-icon.png
│   ├── favicon.png
│   ├── icon.png
│   └── splash.png
├── babel.config.js
├── eas.json
├── package-lock.json
└── package.json

👨‍👩‍👧‍👧 Team (Full Stack)

사현진
Backend & Frontend Developer

Popular repositories Loading

  1. .github .github Public

    OnlineMemo - readmeFile / md

  2. backend backend Public

    OnlineMemo - backend / Spring

    Java

  3. frontend-app frontend-app Public

    OnlineMemo - frontend_app / React Native

    JavaScript

  4. frontend-web frontend-web Public

    OnlineMemo - frontend_web / React

    JavaScript

Repositories

Showing 4 of 4 repositories

Top languages

Loading…

Most used topics

Loading…