|
@@ -0,0 +1,670 @@
|
|
|
|
|
+---
|
|
|
|
|
+description:
|
|
|
|
|
+globs:
|
|
|
|
|
+alwaysApply: true
|
|
|
|
|
+---
|
|
|
|
|
+# Technical Requirements Document (TRD)
|
|
|
|
|
+
|
|
|
|
|
+## 1. Executive Technical Summary
|
|
|
|
|
+- **프로젝트 개요**
|
|
|
|
|
+ 인플루언서와 벤더사 간 수·발주, 배송, 정산, 알림을 웹 기반으로 자동화하는 통합 플랫폼. 오프라인 문서 교환 제거, 실시간 상태 관리, 파트너 매칭 기능 제공.
|
|
|
|
|
+- **핵심 기술 스택**
|
|
|
|
|
+ Frontend: Vue 3 + Nuxt3, Vuetify, TypeScript
|
|
|
|
|
+ Backend: CodeIgniter4 REST API + Node.js BFF
|
|
|
|
|
+ DB: MySQL(RDS), Redis 캐시
|
|
|
|
|
+ 배포: Docker, Kubernetes, GitHub Actions CI/CD
|
|
|
|
|
+ OCR: Google Cloud Vision API
|
|
|
|
|
+ 모니터링: ELK 스택, Grafana
|
|
|
|
|
+- **주요 기술 목표**
|
|
|
|
|
+ 평균 응답시간 300ms 이하, 동시 5,000 사용자 처리, 가용성 99.9%, 서버 오류율 <1%
|
|
|
|
|
+- **주요 가정**
|
|
|
|
|
+ - 초기 규모: 월 거래액 10억, DAU 1,000+
|
|
|
|
|
+ - 클라우드 인프라(AWS/GCP) 사용
|
|
|
|
|
+ - 외부 택배사·ERP API 연동 가능성 상시 고려
|
|
|
|
|
+
|
|
|
|
|
+## 2. Tech Stack
|
|
|
|
|
+
|
|
|
|
|
+| Category | Technology / Library | Reasoning (선택 이유) |
|
|
|
|
|
+| ------------------ | ------------------------------ | ----------------------------------------------------------------- |
|
|
|
|
|
+| Frontend Framework | Vue 3 + Nuxt3 | SSR/SSG 지원으로 초기 로딩 최적화, SEO 강화 |
|
|
|
|
|
+| UI Library | Vuetify | 머티리얼 디자인 기반, 빠른 UI 컴포넌트 구성 |
|
|
|
|
|
+| Language | TypeScript | 정적 타입 검사로 코드 안정성 및 가독성 확보 |
|
|
|
|
|
+| State Management | Pinia | Composition API 친화적, 러닝 커브 완만 |
|
|
|
|
|
+| HTTP Client | Axios | Promise 기반, 요청/응답 인터셉터 활용 용이 |
|
|
|
|
|
+| Backend Framework | CodeIgniter 4 | 경량 PHP 프레임워크, 빠른 개발 및 유지보수 |
|
|
|
|
|
+| API Layer (BFF) | Node.js + Express | 프론트엔드 맞춤형 API 어댑터, 비즈니스 로직 경량 분리 |
|
|
|
|
|
+| Database | MySQL (RDS) | 관계형 데이터 안정성·확장성, RDS 관리 편의성 |
|
|
|
|
|
+| Cache | Redis | 세션 관리, 빈번한 조회 데이터 캐싱으로 응답 속도 개선 |
|
|
|
|
|
+| Containerization | Docker | 환경 일관성 확보, 배포 자동화 |
|
|
|
|
|
+| Orchestration | Kubernetes | 자동 스케일링, 자가 복구, 클러스터 관리 |
|
|
|
|
|
+| CI/CD | GitHub Actions | 코드 푸시 시 빌드·테스트·배포 자동화 |
|
|
|
|
|
+| OCR | Google Cloud Vision API | 높은 정확도, 이미지→텍스트 자동 변환 |
|
|
|
|
|
+| Monitoring | ELK (Elasticsearch, Logstash, Kibana), Grafana | 로그 집계·시각화, 메트릭 모니터링 |
|
|
|
|
|
+| Authentication | JWT, OAuth2 (Google/Kakao/Naver) | 보안성 높은 인증, SNS 간편 로그인 지원 |
|
|
|
|
|
+| Real-time | WebSocket (Socket.IO) | 실시간 알림(주문 상태, 승인 결과) |
|
|
|
|
|
+| Integration | Courier API, ERP REST API | 택배사 송장 조회, 회계 시스템 자동 연동 |
|
|
|
|
|
+
|
|
|
|
|
+## 3. System Architecture Design
|
|
|
|
|
+
|
|
|
|
|
+### Top-Level building blocks
|
|
|
|
|
+- Frontend (Nuxt3): SSR 페이지, 컴포넌트, 인증/알림 UI
|
|
|
|
|
+- BFF (Node.js + Express): Frontend 전용 경량 API 어댑터, 실시간 채널 관리
|
|
|
|
|
+- Backend API (CI4): 핵심 비즈니스 로직, DB CRUD, 권한 관리
|
|
|
|
|
+- Database & Cache: MySQL RDS, Redis 캐시 서버
|
|
|
|
|
+- External Integrations: Google Vision OCR, 택배사 API, ERP API
|
|
|
|
|
+- Monitoring & Logging: ELK 스택, Grafana 알림
|
|
|
|
|
+
|
|
|
|
|
+### Top-Level Component Interaction Diagram
|
|
|
|
|
+```mermaid
|
|
|
|
|
+graph TD
|
|
|
|
|
+ F[Nuxt3 Frontend] --> BFF(BFF: Node.js)
|
|
|
|
|
+ BFF --> API[Backend API: CI4]
|
|
|
|
|
+ API --> DB[MySQL(RDS)]
|
|
|
|
|
+ API --> Cache[Redis]
|
|
|
|
|
+ API --> OCR[Google Vision API]
|
|
|
|
|
+ API --> Courier[택배사 API]
|
|
|
|
|
+ API --> ERP[ERP API]
|
|
|
|
|
+ Monitoring --> API
|
|
|
|
|
+ Monitoring --> BFF
|
|
|
|
|
+```
|
|
|
|
|
+- Nuxt3 프론트엔드가 BFF로 요청 전달
|
|
|
|
|
+- BFF는 세션/인증 관리 후 CI4 API 호출
|
|
|
|
|
+- CI4 API는 MySQL/Redis, 외부 OCR·택배·ERP 연동
|
|
|
|
|
+- ELK·Grafana로 전체 서비스 상태 모니터링
|
|
|
|
|
+
|
|
|
|
|
+### Code Organization & Convention
|
|
|
|
|
+**Domain-Driven Organization Strategy**
|
|
|
|
|
+- **도메인 분리**: 사용자, 주문, 배송, 정산, 매칭 등 비즈니스 도메인별 모듈
|
|
|
|
|
+- **레이어 아키텍처**: Presentation, Application, Domain, Infrastructure
|
|
|
|
|
+- **기능 기반 모듈화**: 각 도메인 기능을 독립 패키지로 관리
|
|
|
|
|
+- **공유 컴포넌트**: Utils, Types, 공통 미들웨어, 인터셉터
|
|
|
|
|
+
|
|
|
|
|
+**Universal File & Folder Structure**
|
|
|
|
|
+```
|
|
|
|
|
+/
|
|
|
|
|
+├── app.vue
|
|
|
|
|
+├── assets
|
|
|
|
|
+│ ├── font
|
|
|
|
|
+│ │ ├── Inter-Medium.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Black.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-Black.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Black.woff2
|
|
|
|
|
+│ │ ├── NotoSansKR-Bold.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-Bold.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Bold.woff2
|
|
|
|
|
+│ │ ├── NotoSansKR-DemiLight.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-DemiLight.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-DemiLight.woff2
|
|
|
|
|
+│ │ ├── NotoSansKR-Light.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-Light.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Light.woff2
|
|
|
|
|
+│ │ ├── NotoSansKR-Medium.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-Medium.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Medium.woff2
|
|
|
|
|
+│ │ ├── NotoSansKR-Regular.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-Regular.woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Regular.woff2
|
|
|
|
|
+│ │ ├── NotoSansKR-Regular(1).woff
|
|
|
|
|
+│ │ ├── NotoSansKR-Thin.otf
|
|
|
|
|
+│ │ ├── NotoSansKR-Thin.woff
|
|
|
|
|
+│ │ └── NotoSansKR-Thin.woff2
|
|
|
|
|
+│ ├── img
|
|
|
|
|
+│ │ ├── bg_login.svg
|
|
|
|
|
+│ │ ├── bg_otp_reg.png
|
|
|
|
|
+│ │ ├── bg_popup.svg
|
|
|
|
|
+│ │ ├── bg_tab_off.svg
|
|
|
|
|
+│ │ ├── bg_tab_on.svg
|
|
|
|
|
+│ │ ├── bg_tooltip.svg
|
|
|
|
|
+│ │ ├── bg_tooltip2.svg
|
|
|
|
|
+│ │ ├── bg_tooltip3.svg
|
|
|
|
|
+│ │ ├── bg_tooltip4.svg
|
|
|
|
|
+│ │ ├── btn_app_store.svg
|
|
|
|
|
+│ │ ├── btn_goolge_play.svg
|
|
|
|
|
+│ │ ├── btn.png
|
|
|
|
|
+│ │ ├── caution_bg.jpg
|
|
|
|
|
+│ │ ├── db_set_list01.svg
|
|
|
|
|
+│ │ ├── db_set_list02.svg
|
|
|
|
|
+│ │ ├── db_set_list03.svg
|
|
|
|
|
+│ │ ├── head_flip_btn.svg
|
|
|
|
|
+│ │ ├── ic_add.svg
|
|
|
|
|
+│ │ ├── ic_allview.svg
|
|
|
|
|
+│ │ ├── ic_arrow_right_chv.svg
|
|
|
|
|
+│ │ ├── ic_avg01.svg
|
|
|
|
|
+│ │ ├── ic_avg02.svg
|
|
|
|
|
+│ │ ├── ic_avg03.svg
|
|
|
|
|
+│ │ ├── ic_avg04.svg
|
|
|
|
|
+│ │ ├── ic_card_nodata.svg
|
|
|
|
|
+│ │ ├── ic_card_off.svg
|
|
|
|
|
+│ │ ├── ic_card_on.svg
|
|
|
|
|
+│ │ ├── ic_chv_arrow.svg
|
|
|
|
|
+│ │ ├── ic_chv.svg
|
|
|
|
|
+│ │ ├── ic_close.svg
|
|
|
|
|
+│ │ ├── ic_drop_down_on.svg
|
|
|
|
|
+│ │ ├── ic_drop_down.svg
|
|
|
|
|
+│ │ ├── ic_ds.svg
|
|
|
|
|
+│ │ ├── ic_end_close_cl.svg
|
|
|
|
|
+│ │ ├── ic_end_close_x.svg
|
|
|
|
|
+│ │ ├── ic_end_close.png
|
|
|
|
|
+│ │ ├── ic_end_close.svg
|
|
|
|
|
+│ │ ├── ic_end_red.svg
|
|
|
|
|
+│ │ ├── ic_equip01.svg
|
|
|
|
|
+│ │ ├── ic_equip02.svg
|
|
|
|
|
+│ │ ├── ic_equip03.svg
|
|
|
|
|
+│ │ ├── ic_equip04.svg
|
|
|
|
|
+│ │ ├── ic_excel_green.svg
|
|
|
|
|
+│ │ ├── ic_excel.svg
|
|
|
|
|
+│ │ ├── ic_gear.svg
|
|
|
|
|
+│ │ ├── ic_google.svg
|
|
|
|
|
+│ │ ├── ic_grid_box.png
|
|
|
|
|
+│ │ ├── ic_home_arrow.svg
|
|
|
|
|
+│ │ ├── ic_info.svg
|
|
|
|
|
+│ │ ├── ic_issue_flag.svg
|
|
|
|
|
+│ │ ├── ic_kakao.svg
|
|
|
|
|
+│ │ ├── ic_list_off.svg
|
|
|
|
|
+│ │ ├── ic_list_on.svg
|
|
|
|
|
+│ │ ├── ic_map_card.svg
|
|
|
|
|
+│ │ ├── ic_map_pin.svg
|
|
|
|
|
+│ │ ├── ic_mapt_chv.svg
|
|
|
|
|
+│ │ ├── ic_more_btn.svg
|
|
|
|
|
+│ │ ├── ic_more_plust_gray.svg
|
|
|
|
|
+│ │ ├── ic_naver.svg
|
|
|
|
|
+│ │ ├── ic_no_img.svg
|
|
|
|
|
+│ │ ├── ic_no_tree.svg
|
|
|
|
|
+│ │ ├── ic_preview_nw.svg
|
|
|
|
|
+│ │ ├── ic_radio_off.svg
|
|
|
|
|
+│ │ ├── ic_radio_on.svg
|
|
|
|
|
+│ │ ├── ic_sch_nw.svg
|
|
|
|
|
+│ │ ├── ic_sts.svg
|
|
|
|
|
+│ │ ├── ic_tab01.svg
|
|
|
|
|
+│ │ ├── ic_tab02.svg
|
|
|
|
|
+│ │ ├── ic_tab03.svg
|
|
|
|
|
+│ │ ├── ic_tab04.svg
|
|
|
|
|
+│ │ ├── ic_tack_off.svg
|
|
|
|
|
+│ │ ├── ic_tack_on.svg
|
|
|
|
|
+│ │ ├── ic_tenant_small_white.svg
|
|
|
|
|
+│ │ ├── ic_tenant_small.svg
|
|
|
|
|
+│ │ ├── ic_tenant01.svg
|
|
|
|
|
+│ │ ├── ic_tenant02.svg
|
|
|
|
|
+│ │ ├── ic_tenant03.svg
|
|
|
|
|
+│ │ ├── ic_tenant04.svg
|
|
|
|
|
+│ │ ├── ic_wifi_dis.svg
|
|
|
|
|
+│ │ ├── ic_wifi.svg
|
|
|
|
|
+│ │ ├── ic_x_btn.svg
|
|
|
|
|
+│ │ ├── ic_x_btn2.svg
|
|
|
|
|
+│ │ ├── ic_xcircle.svg
|
|
|
|
|
+│ │ ├── ico_alarm_blue.svg
|
|
|
|
|
+│ │ ├── ico_alarm_gray.svg
|
|
|
|
|
+│ │ ├── ico_alarm_green.svg
|
|
|
|
|
+│ │ ├── ico_alarm_red.svg
|
|
|
|
|
+│ │ ├── ico_alarm1.svg
|
|
|
|
|
+│ │ ├── ico_alarm2.svg
|
|
|
|
|
+│ │ ├── ico_alarm3.svg
|
|
|
|
|
+│ │ ├── ico_alarm4.svg
|
|
|
|
|
+│ │ ├── ico_all_pop.svg
|
|
|
|
|
+│ │ ├── ico_arrow_next.svg
|
|
|
|
|
+│ │ ├── ico_arrow_prev.svg
|
|
|
|
|
+│ │ ├── ico_backup1.svg
|
|
|
|
|
+│ │ ├── ico_backup2.svg
|
|
|
|
|
+│ │ ├── ico_backup3.svg
|
|
|
|
|
+│ │ ├── ico_backup4.svg
|
|
|
|
|
+│ │ ├── ico_ban.svg
|
|
|
|
|
+│ │ ├── ico_bar.svg
|
|
|
|
|
+│ │ ├── ico_black_pin.svg
|
|
|
|
|
+│ │ ├── ico_blue_pin.svg
|
|
|
|
|
+│ │ ├── ico_btn1.svg
|
|
|
|
|
+│ │ ├── ico_btn2.svg
|
|
|
|
|
+│ │ ├── ico_btn3.svg
|
|
|
|
|
+│ │ ├── ico_cal_dis.svg
|
|
|
|
|
+│ │ ├── ico_cal.svg
|
|
|
|
|
+│ │ ├── ico_calendar.svg
|
|
|
|
|
+│ │ ├── ico_cancel_disabled.svg
|
|
|
|
|
+│ │ ├── ico_cancel.svg
|
|
|
|
|
+│ │ ├── ico_cate.svg
|
|
|
|
|
+│ │ ├── ico_certify_n.svg
|
|
|
|
|
+│ │ ├── ico_certify_y.svg
|
|
|
|
|
+│ │ ├── ico_certify_y2.svg
|
|
|
|
|
+│ │ ├── ico_certify_y3.svg
|
|
|
|
|
+│ │ ├── ico_check_indeterminate.svg
|
|
|
|
|
+│ │ ├── ico_chk_circle_disabled.svg
|
|
|
|
|
+│ │ ├── ico_chk_circle.svg
|
|
|
|
|
+│ │ ├── ico_chk_off.svg
|
|
|
|
|
+│ │ ├── ico_chk_off2.svg
|
|
|
|
|
+│ │ ├── ico_chk_on.svg
|
|
|
|
|
+│ │ ├── ico_chk.svg
|
|
|
|
|
+│ │ ├── ico_close_gray.svg
|
|
|
|
|
+│ │ ├── ico_close.svg
|
|
|
|
|
+│ │ ├── ico_core_alarm1.svg
|
|
|
|
|
+│ │ ├── ico_core_alarm2.svg
|
|
|
|
|
+│ │ ├── ico_date_pic.svg
|
|
|
|
|
+│ │ ├── ico_del_disabled.svg
|
|
|
|
|
+│ │ ├── ico_del_disabled2.svg
|
|
|
|
|
+│ │ ├── ico_del.svg
|
|
|
|
|
+│ │ ├── ico_del2.svg
|
|
|
|
|
+│ │ ├── ico_download.svg
|
|
|
|
|
+│ │ ├── ico_end.svg
|
|
|
|
|
+│ │ ├── ico_equip.svg
|
|
|
|
|
+│ │ ├── ico_eraser.svg
|
|
|
|
|
+│ │ ├── ico_eraser2.svg
|
|
|
|
|
+│ │ ├── ico_error.svg
|
|
|
|
|
+│ │ ├── ico_event_pop.svg
|
|
|
|
|
+│ │ ├── ico_event_view_black.png
|
|
|
|
|
+│ │ ├── ico_event_view_black.svg
|
|
|
|
|
+│ │ ├── ico_event_view_down.svg
|
|
|
|
|
+│ │ ├── ico_event_view.svg
|
|
|
|
|
+│ │ ├── ico_excel_d.svg
|
|
|
|
|
+│ │ ├── ico_excel.svg
|
|
|
|
|
+│ │ ├── ico_excel2.svg
|
|
|
|
|
+│ │ ├── ico_eye.svg
|
|
|
|
|
+│ │ ├── ico_eye2.svg
|
|
|
|
|
+│ │ ├── ico_gray_pin.svg
|
|
|
|
|
+│ │ ├── ico_grid_sort.svg
|
|
|
|
|
+│ │ ├── ico_grid_sort2.svg
|
|
|
|
|
+│ │ ├── ico_id_off.svg
|
|
|
|
|
+│ │ ├── ico_id_on.svg
|
|
|
|
|
+│ │ ├── ico_info.svg
|
|
|
|
|
+│ │ ├── ico_lang_english.svg
|
|
|
|
|
+│ │ ├── ico_lang_korea.svg
|
|
|
|
|
+│ │ ├── ico_lang_korea2.svg
|
|
|
|
|
+│ │ ├── ico_link.svg
|
|
|
|
|
+│ │ ├── ico_list_white.svg
|
|
|
|
|
+│ │ ├── ico_list.svg
|
|
|
|
|
+│ │ ├── ico_location_arr.svg
|
|
|
|
|
+│ │ ├── ico_location_home.svg
|
|
|
|
|
+│ │ ├── ico_logo.svg
|
|
|
|
|
+│ │ ├── ico_logout.svg
|
|
|
|
|
+│ │ ├── ico_map.svg
|
|
|
|
|
+│ │ ├── ico_menu_arr.svg
|
|
|
|
|
+│ │ ├── ico_menu_arr2.svg
|
|
|
|
|
+│ │ ├── ico_menu_minus.svg
|
|
|
|
|
+│ │ ├── ico_menu_nodata.svg
|
|
|
|
|
+│ │ ├── ico_menu_plus.svg
|
|
|
|
|
+│ │ ├── ico_menu.svg
|
|
|
|
|
+│ │ ├── ico_minus.svg
|
|
|
|
|
+│ │ ├── ico_mod_disabled.svg
|
|
|
|
|
+│ │ ├── ico_mod.svg
|
|
|
|
|
+│ │ ├── ico_mod2.svg
|
|
|
|
|
+│ │ ├── ico_mode_dark.svg
|
|
|
|
|
+│ │ ├── ico_mode_white.svg
|
|
|
|
|
+│ │ ├── ico_mode_white2.svg
|
|
|
|
|
+│ │ ├── ico_ne_add.svg
|
|
|
|
|
+│ │ ├── ico_ne_del_d.svg
|
|
|
|
|
+│ │ ├── ico_ne_del.svg
|
|
|
|
|
+│ │ ├── ico_no_data_nw.svg
|
|
|
|
|
+│ │ ├── ico_no_data.svg
|
|
|
|
|
+│ │ ├── ico_no_data2.svg
|
|
|
|
|
+│ │ ├── ico_no_table_dt.svg
|
|
|
|
|
+│ │ ├── ico_not_excel.svg
|
|
|
|
|
+│ │ ├── ico_otp_step1.svg
|
|
|
|
|
+│ │ ├── ico_otp_step2.svg
|
|
|
|
|
+│ │ ├── ico_otp_step3.svg
|
|
|
|
|
+│ │ ├── ico_otp_step4.svg
|
|
|
|
|
+│ │ ├── ico_otp_step5.svg
|
|
|
|
|
+│ │ ├── ico_paging_more.svg
|
|
|
|
|
+│ │ ├── ico_paging_next.svg
|
|
|
|
|
+│ │ ├── ico_paging_next1.svg
|
|
|
|
|
+│ │ ├── ico_paging_next2.svg
|
|
|
|
|
+│ │ ├── ico_paging_prev.svg
|
|
|
|
|
+│ │ ├── ico_paging_prev1.svg
|
|
|
|
|
+│ │ ├── ico_paging_prev2.svg
|
|
|
|
|
+│ │ ├── ico_performance1.svg
|
|
|
|
|
+│ │ ├── ico_performance2.svg
|
|
|
|
|
+│ │ ├── ico_pin_off.svg
|
|
|
|
|
+│ │ ├── ico_pin_on.svg
|
|
|
|
|
+│ │ ├── ico_pip.svg
|
|
|
|
|
+│ │ ├── ico_pip2.svg
|
|
|
|
|
+│ │ ├── ico_plus.svg
|
|
|
|
|
+│ │ ├── ico_pop_close.svg
|
|
|
|
|
+│ │ ├── ico_pos.svg
|
|
|
|
|
+│ │ ├── ico_ran_arrow_gray.svg
|
|
|
|
|
+│ │ ├── ico_ran_arrow_white.svg
|
|
|
|
|
+│ │ ├── ico_red_pin.svg
|
|
|
|
|
+│ │ ├── ico_refresh_dis.svg
|
|
|
|
|
+│ │ ├── ico_refresh.svg
|
|
|
|
|
+│ │ ├── ico_reg_disabled.svg
|
|
|
|
|
+│ │ ├── ico_reg.svg
|
|
|
|
|
+│ │ ├── ico_save_disabled.svg
|
|
|
|
|
+│ │ ├── ico_save.svg
|
|
|
|
|
+│ │ ├── ico_search.svg
|
|
|
|
|
+│ │ ├── ico_set_blue.svg
|
|
|
|
|
+│ │ ├── ico_set.svg
|
|
|
|
|
+│ │ ├── ico_setting.svg
|
|
|
|
|
+│ │ ├── ico_slt.svg
|
|
|
|
|
+│ │ ├── ico_slt2.svg
|
|
|
|
|
+│ │ ├── ico_sort.svg
|
|
|
|
|
+│ │ ├── ico_square.svg
|
|
|
|
|
+│ │ ├── ico_state1.svg
|
|
|
|
|
+│ │ ├── ico_state2.svg
|
|
|
|
|
+│ │ ├── ico_state3.svg
|
|
|
|
|
+│ │ ├── ico_status1.svg
|
|
|
|
|
+│ │ ├── ico_status2.svg
|
|
|
|
|
+│ │ ├── ico_status3.svg
|
|
|
|
|
+│ │ ├── ico_step_arr.svg
|
|
|
|
|
+│ │ ├── ico_step_arr2.svg
|
|
|
|
|
+│ │ ├── ico_tenant1.svg
|
|
|
|
|
+│ │ ├── ico_tenant2.svg
|
|
|
|
|
+│ │ ├── ico_tenant3.svg
|
|
|
|
|
+│ │ ├── ico_tenant4.svg
|
|
|
|
|
+│ │ ├── ico_time_disabled.svg
|
|
|
|
|
+│ │ ├── ico_time.svg
|
|
|
|
|
+│ │ ├── ico_tit_arr.svg
|
|
|
|
|
+│ │ ├── ico_tool.svg
|
|
|
|
|
+│ │ ├── ico_trash_nw.svg
|
|
|
|
|
+│ │ ├── ico_tree_add.svg
|
|
|
|
|
+│ │ ├── ico_tree_arr.svg
|
|
|
|
|
+│ │ ├── ico_tree_save.svg
|
|
|
|
|
+│ │ ├── ico_tree1.svg
|
|
|
|
|
+│ │ ├── ico_tree2.svg
|
|
|
|
|
+│ │ ├── ico_tree3_core.svg
|
|
|
|
|
+│ │ ├── ico_tree3_ran.svg
|
|
|
|
|
+│ │ ├── ico_tree3.svg
|
|
|
|
|
+│ │ ├── ico_trend.svg
|
|
|
|
|
+│ │ ├── ico_view_del.svg
|
|
|
|
|
+│ │ ├── ico_view_list.svg
|
|
|
|
|
+│ │ ├── ico_view_list2.svg
|
|
|
|
|
+│ │ ├── ico_wifi.svg
|
|
|
|
|
+│ │ ├── ico-arrow-right.svg
|
|
|
|
|
+│ │ ├── ico-check-on.svg
|
|
|
|
|
+│ │ ├── img_mode_dark.svg
|
|
|
|
|
+│ │ ├── img_mode_white.svg
|
|
|
|
|
+│ │ ├── img_popup.svg
|
|
|
|
|
+│ │ ├── img_qr.svg
|
|
|
|
|
+│ │ ├── img_system.svg
|
|
|
|
|
+│ │ ├── inf_bg.png
|
|
|
|
|
+│ │ ├── is_disconnect.svg
|
|
|
|
|
+│ │ ├── logo_foot.svg
|
|
|
|
|
+│ │ ├── logo_foot2.svg
|
|
|
|
|
+│ │ ├── logo_login.svg
|
|
|
|
|
+│ │ ├── logo_new.svg
|
|
|
|
|
+│ │ ├── logo_sams_sds.svg
|
|
|
|
|
+│ │ ├── logo_sams.svg
|
|
|
|
|
+│ │ ├── mail_logo1.png
|
|
|
|
|
+│ │ ├── mail_logo2.png
|
|
|
|
|
+│ │ ├── map_kangwon.svg
|
|
|
|
|
+│ │ ├── pf_sample.svg
|
|
|
|
|
+│ │ ├── pin.png
|
|
|
|
|
+│ │ ├── rlt_bg.png
|
|
|
|
|
+│ │ ├── round.png
|
|
|
|
|
+│ │ └── ven_bg.png
|
|
|
|
|
+│ └── scss
|
|
|
|
|
+│ ├── default.scss
|
|
|
|
|
+│ ├── main.scss
|
|
|
|
|
+│ ├── mode-w-m.scss
|
|
|
|
|
+│ ├── roulette.scss
|
|
|
|
|
+│ ├── sample.scss
|
|
|
|
|
+│ └── style.scss
|
|
|
|
|
+├── components
|
|
|
|
|
+│ ├── cellRenderer
|
|
|
|
|
+│ │ ├── customActionTypeTextColor.vue
|
|
|
|
|
+│ │ ├── customBackUpBtn.vue
|
|
|
|
|
+│ │ ├── customBackUpBtnR.vue
|
|
|
|
|
+│ │ ├── customButtonSms.vue
|
|
|
|
|
+│ │ ├── customHeaderText.vue
|
|
|
|
|
+│ │ ├── customInhibitSelect.vue
|
|
|
|
|
+│ │ ├── customIpConnTextColor.vue
|
|
|
|
|
+│ │ ├── customIpNotConnTextColor.vue
|
|
|
|
|
+│ │ ├── customLicenseBtn.vue
|
|
|
|
|
+│ │ ├── customLogLevelSelect.vue
|
|
|
|
|
+│ │ ├── customNullValue.vue
|
|
|
|
|
+│ │ ├── customRadio.vue
|
|
|
|
|
+│ │ ├── customResultTextDivBg.vue
|
|
|
|
|
+│ │ ├── customSessionSetTextField.vue
|
|
|
|
|
+│ │ ├── customStatusBox.vue
|
|
|
|
|
+│ │ ├── customTextColor.vue
|
|
|
|
|
+│ │ ├── customTextDivSession.vue
|
|
|
|
|
+│ │ └── customUseYNTextColor.vue
|
|
|
|
|
+│ ├── common
|
|
|
|
|
+│ │ ├── confirmDialog.vue
|
|
|
|
|
+│ │ ├── customLoading.vue
|
|
|
|
|
+│ │ ├── excelUpload.vue
|
|
|
|
|
+│ │ ├── footer
|
|
|
|
|
+│ │ │ └── eventDetailView.vue
|
|
|
|
|
+│ │ ├── footer.vue
|
|
|
|
|
+│ │ ├── header
|
|
|
|
|
+│ │ │ └── modal
|
|
|
|
|
+│ │ │ ├── myInfoUpdate.vue
|
|
|
|
|
+│ │ │ ├── passwordCheck.vue
|
|
|
|
|
+│ │ │ └── privacyPop.vue
|
|
|
|
|
+│ │ ├── header.vue
|
|
|
|
|
+│ │ ├── leftMenu.vue
|
|
|
|
|
+│ │ ├── location.vue
|
|
|
|
|
+│ │ ├── pagination.vue
|
|
|
|
|
+│ │ ├── topologyPop.vue
|
|
|
|
|
+│ │ └── topologyPopMgmt.vue
|
|
|
|
|
+│ ├── home
|
|
|
|
|
+│ │ ├── dashboard
|
|
|
|
|
+│ │ │ ├── common
|
|
|
|
|
+│ │ │ │ ├── coreDetailModal.vue
|
|
|
|
|
+│ │ │ │ ├── map
|
|
|
|
|
+│ │ │ │ │ ├── mapBusan.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapChungbuk.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapChungnam.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapDaegu.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapDaejeon.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapGwangju.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapGyeongbuk.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapGyeonggido.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapGyeongnam.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapIncheon.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapJeju.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapJeonbuk.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapJeonnam.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapKangwon.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapSejong.vue
|
|
|
|
|
+│ │ │ │ │ ├── mapSeoul.vue
|
|
|
|
|
+│ │ │ │ │ └── mapUlsan.vue
|
|
|
|
|
+│ │ │ │ ├── pagination.vue
|
|
|
|
|
+│ │ │ │ ├── ranCardGroupDetailModal.vue
|
|
|
|
|
+│ │ │ │ ├── ranMapGroupDetailModal.vue
|
|
|
|
|
+│ │ │ │ └── ranMapNeDetailModal.vue
|
|
|
|
|
+│ │ │ ├── layout01
|
|
|
|
|
+│ │ │ │ ├── core
|
|
|
|
|
+│ │ │ │ │ ├── layout01Core.vue
|
|
|
|
|
+│ │ │ │ │ ├── layout01CoreWidgetM.vue
|
|
|
|
|
+│ │ │ │ │ └── layout01CoreWidgetS.vue
|
|
|
|
|
+│ │ │ │ ├── layout01.vue
|
|
|
|
|
+│ │ │ │ ├── ran
|
|
|
|
|
+│ │ │ │ │ └── layout01Ran.vue
|
|
|
|
|
+│ │ │ │ └── user
|
|
|
|
|
+│ │ │ │ ├── layout01User.vue
|
|
|
|
|
+│ │ │ │ ├── layout01UserWidgetM.vue
|
|
|
|
|
+│ │ │ │ ├── layout01UserWidgetS.vue
|
|
|
|
|
+│ │ │ │ └── layout01UserWidgetT.vue
|
|
|
|
|
+│ │ │ ├── layout02
|
|
|
|
|
+│ │ │ │ ├── core
|
|
|
|
|
+│ │ │ │ │ ├── layout02Core.vue
|
|
|
|
|
+│ │ │ │ │ ├── layout02CoreWidgetM.vue
|
|
|
|
|
+│ │ │ │ │ └── layout02CoreWidgetS.vue
|
|
|
|
|
+│ │ │ │ ├── layout02.vue
|
|
|
|
|
+│ │ │ │ ├── ran
|
|
|
|
|
+│ │ │ │ │ └── layout02Ran.vue
|
|
|
|
|
+│ │ │ │ └── user
|
|
|
|
|
+│ │ │ │ ├── layout02User.vue
|
|
|
|
|
+│ │ │ │ ├── layout02UserWidgetM.vue
|
|
|
|
|
+│ │ │ │ ├── layout02UserWidgetS.vue
|
|
|
|
|
+│ │ │ │ └── layout02UserWidgetT.vue
|
|
|
|
|
+│ │ │ ├── layout03
|
|
|
|
|
+│ │ │ │ ├── core
|
|
|
|
|
+│ │ │ │ │ ├── layout03Core.vue
|
|
|
|
|
+│ │ │ │ │ ├── layout03CoreWidgetM.vue
|
|
|
|
|
+│ │ │ │ │ └── layout03CoreWidgetS.vue
|
|
|
|
|
+│ │ │ │ ├── layout03.vue
|
|
|
|
|
+│ │ │ │ ├── ran
|
|
|
|
|
+│ │ │ │ │ ├── layout03Ran.vue
|
|
|
|
|
+│ │ │ │ │ └── ranMapComponent.vue
|
|
|
|
|
+│ │ │ │ └── user
|
|
|
|
|
+│ │ │ │ ├── layout03User.vue
|
|
|
|
|
+│ │ │ │ ├── layout03UserWidgetM.vue
|
|
|
|
|
+│ │ │ │ └── layout03UserWidgetS.vue
|
|
|
|
|
+│ │ │ ├── settingModal.vue
|
|
|
|
|
+│ │ │ └── test.json
|
|
|
|
|
+│ │ ├── jobNoti
|
|
|
|
|
+│ │ │ └── jobNotiModal.vue
|
|
|
|
|
+│ │ ├── tenant
|
|
|
|
|
+│ │ │ ├── chart
|
|
|
|
|
+│ │ │ │ ├── doughnut.vue
|
|
|
|
|
+│ │ │ │ ├── trendBar.vue
|
|
|
|
|
+│ │ │ │ └── userDoughnut.vue
|
|
|
|
|
+│ │ │ ├── common
|
|
|
|
|
+│ │ │ │ └── ranGroupDetailModal.vue
|
|
|
|
|
+│ │ │ ├── tenantRan.vue
|
|
|
|
|
+│ │ │ ├── tenantTrend.vue
|
|
|
|
|
+│ │ │ └── tenantUser.vue
|
|
|
|
|
+│ │ └── trend
|
|
|
|
|
+│ │ └── headerChart.vue
|
|
|
|
|
+│ ├── login
|
|
|
|
|
+│ │ └── privacyPop.vue
|
|
|
|
|
+│ ├── search
|
|
|
|
|
+│ │ └── searchModules.vue
|
|
|
|
|
+│ └── sunEdt.vue
|
|
|
|
|
+├── composables
|
|
|
|
|
+│ ├── useApi.js
|
|
|
|
|
+│ ├── useAxios.js
|
|
|
|
|
+│ ├── useChart.js
|
|
|
|
|
+│ ├── useEnumCode.js
|
|
|
|
|
+│ ├── useEnumCodeEn.js
|
|
|
|
|
+│ ├── useEnumCodeKr.js
|
|
|
|
|
+│ ├── useErrorHandler.js
|
|
|
|
|
+│ ├── useHangul.js
|
|
|
|
|
+│ ├── useMenuConstants.js
|
|
|
|
|
+│ ├── useSunEditor.js
|
|
|
|
|
+│ ├── useToastEditor.ts
|
|
|
|
|
+│ ├── useUrlHandler.js
|
|
|
|
|
+│ ├── useUtil.js
|
|
|
|
|
+│ ├── useValid.js
|
|
|
|
|
+│ └── useWatchFocusValidate.js
|
|
|
|
|
+├── error.vue
|
|
|
|
|
+├── lang
|
|
|
|
|
+│ ├── en.js
|
|
|
|
|
+│ └── kr.js
|
|
|
|
|
+├── layouts
|
|
|
|
|
+│ ├── default.vue
|
|
|
|
|
+│ ├── designdefault.vue
|
|
|
|
|
+│ ├── designloginlayout.vue
|
|
|
|
|
+│ ├── loginlayout.vue
|
|
|
|
|
+│ ├── roulette.vue
|
|
|
|
|
+│ └── samplelayout.vue
|
|
|
|
|
+├── middleware
|
|
|
|
|
+│ └── auth.global.js
|
|
|
|
|
+├── nuxt.config.ts
|
|
|
|
|
+├── package-lock.json
|
|
|
|
|
+├── package.json
|
|
|
|
|
+├── pages
|
|
|
|
|
+│ ├── auth
|
|
|
|
|
+│ │ ├── join.vue
|
|
|
|
|
+│ │ └── popupClose.vue
|
|
|
|
|
+│ ├── index.vue
|
|
|
|
|
+│ └── view
|
|
|
|
|
+│ ├── cs
|
|
|
|
|
+│ │ ├── financial.vue
|
|
|
|
|
+│ │ └── index.vue
|
|
|
|
|
+│ ├── deli
|
|
|
|
|
+│ │ ├── index.vue
|
|
|
|
|
+│ │ ├── mngAdd.vue
|
|
|
|
|
+│ │ └── mngListDeleted.vue
|
|
|
|
|
+│ ├── item
|
|
|
|
|
+│ │ ├── add.vue
|
|
|
|
|
+│ │ ├── evtListClosed.vue
|
|
|
|
|
+│ │ ├── evtListOngoing.vue
|
|
|
|
|
+│ │ ├── evtListPending.vue
|
|
|
|
|
+│ │ └── index.vue
|
|
|
|
|
+│ ├── log
|
|
|
|
|
+│ │ └── logList.vue
|
|
|
|
|
+│ ├── order
|
|
|
|
|
+│ │ └── index.vue
|
|
|
|
|
+│ ├── settle
|
|
|
|
|
+│ │ ├── curationAdd.vue
|
|
|
|
|
+│ │ ├── curationList.vue
|
|
|
|
|
+│ │ ├── index.vue
|
|
|
|
|
+│ │ ├── irAdd.vue
|
|
|
|
|
+│ │ ├── mediaAdd.vue
|
|
|
|
|
+│ │ ├── mediaList.vue
|
|
|
|
|
+│ │ ├── newsAdd.vue
|
|
|
|
|
+│ │ └── newsList.vue
|
|
|
|
|
+│ └── vendor
|
|
|
|
|
+│ ├── dashboard
|
|
|
|
|
+│ │ └── index.vue
|
|
|
|
|
+│ └── index.vue
|
|
|
|
|
+├── plugins
|
|
|
|
|
+│ ├── fontawesome.js
|
|
|
|
|
+│ ├── i18n.js
|
|
|
|
|
+│ ├── log.js
|
|
|
|
|
+│ ├── mitt.js
|
|
|
|
|
+│ ├── toast.js
|
|
|
|
|
+│ ├── userAgent.js
|
|
|
|
|
+│ ├── vue-cool-lightbox.js
|
|
|
|
|
+│ ├── vue3-editor.js
|
|
|
|
|
+│ └── vuetify.js
|
|
|
|
|
+├── public
|
|
|
|
|
+│ ├── favicon.ico
|
|
|
|
|
+│ ├── ft_logo.png
|
|
|
|
|
+│ ├── js
|
|
|
|
|
+│ │ └── jquery-3.7.1.min.js
|
|
|
|
|
+│ └── logo.png
|
|
|
|
|
+├── README.md
|
|
|
|
|
+├── server
|
|
|
|
|
+│ └── tsconfig.json
|
|
|
|
|
+├── stores
|
|
|
|
|
+│ ├── auth.js
|
|
|
|
|
+│ ├── detail.js
|
|
|
|
|
+│ ├── lang.js
|
|
|
|
|
+│ ├── loading.js
|
|
|
|
|
+│ └── tenantMgmt.js
|
|
|
|
|
+├── toast-editor.d.ts
|
|
|
|
|
+├── tsconfig.json
|
|
|
|
|
+└── vite-plugin-sri.d.ts
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Data Flow & Communication Patterns
|
|
|
|
|
+- **Client-Server 통신**: RESTful API, JWT 인증 헤더, Axios 인터셉터
|
|
|
|
|
+- **Database 상호작용**: CI4 Query Builder/Model, 트랜잭션 관리, Redis 캐시 사용
|
|
|
|
|
+- **외부 서비스 연동**: 비동기 메시지 큐 없이 HTTP 호출, 에러 리트라이 로직
|
|
|
|
|
+- **실시간 통신**: Socket.IO 기반 WebSocket 연결, 주문·승인 알림
|
|
|
|
|
+- **데이터 동기화**: 캐시 무효화 패턴, 이벤트 기반 상태 업데이트
|
|
|
|
|
+
|
|
|
|
|
+## 4. Performance & Optimization Strategy
|
|
|
|
|
+- HTTP 응답 캐싱: Redis로 빈번 조회 데이터 캐싱
|
|
|
|
|
+- DB 인덱싱 및 쿼리 튜닝: 주요 조회 쿼리 Explain 분석
|
|
|
|
|
+- 코드 스플리팅·지연 로딩: Nuxt3 동적 import 활용
|
|
|
|
|
+- 로드 밸런싱: Kubernetes HPA 기반 자동 스케일링
|
|
|
|
|
+
|
|
|
|
|
+## 5. Implementation Roadmap & Milestones
|
|
|
|
|
+
|
|
|
|
|
+### Phase 1: Foundation (MVP Implementation)
|
|
|
|
|
+- Core Infrastructure: Docker/K8s 환경, CI/CD 파이프라인
|
|
|
|
|
+- Essential Features: 로그인·회원가입, 상품 조회·발주, 주문 승인, 송장 엑셀 업로드
|
|
|
|
|
+- Basic Security: JWT 인증, HTTPS, OAuth2 SNS 로그인
|
|
|
|
|
+- Development Setup: 로컬 개발 환경, 코드 린팅·테스트 프레임워크
|
|
|
|
|
+- Timeline: M+2
|
|
|
|
|
+
|
|
|
|
|
+### Phase 2: Feature Enhancement
|
|
|
|
|
+- Advanced Features: 정산 모듈, 파트너 매칭 시스템, 알림 센터
|
|
|
|
|
+- Performance Optimization: 캐시 전략, DB 튜닝
|
|
|
|
|
+- Enhanced Security: 권한 관리 강화, OWASP 점검
|
|
|
|
|
+- Monitoring Implementation: ELK 대시보드, Grafana 알림
|
|
|
|
|
+- Timeline: M+4
|
|
|
|
|
+
|
|
|
|
|
+### Phase 3: Scaling & Optimization
|
|
|
|
|
+- Scalability Implementation: HPA/Cluster Autoscaler, DB 리드 리플리카
|
|
|
|
|
+- Advanced Integrations: ERP 연동, 다중 택배사 API 연결
|
|
|
|
|
+- Enterprise Features: 서브계정 관리, 대시보드
|
|
|
|
|
+- Compliance & Auditing: GDPR, 데이터 암호화 심화
|
|
|
|
|
+- Timeline: M+6
|
|
|
|
|
+
|
|
|
|
|
+## 6. Risk Assessment & Mitigation Strategies
|
|
|
|
|
+
|
|
|
|
|
+### Technical Risk Analysis
|
|
|
|
|
+- **기술 리스크**: OCR 인식률 저하 → 수동 검증 UI 제공
|
|
|
|
|
+- **성능 리스크**: 동시 사용자 증가 시 DB 병목 → 읽기/쓰기 분리, 캐시 활용
|
|
|
|
|
+- **보안 리스크**: 토큰 탈취 → 짧은 만료, 리프레시 토큰 설계
|
|
|
|
|
+- **통합 리스크**: 외부 API 변경 → 버전 관리, 어댑터 패턴 적용
|
|
|
|
|
+- **Mitigation**: 대체 흐름, 로깅·모니터링 알림, 자동 테스트
|
|
|
|
|
+
|
|
|
|
|
+### Project Delivery Risks
|
|
|
|
|
+- **일정 리스크**: 기능 지연 → MVP 단계별 우선순위 조정
|
|
|
|
|
+- **자원 리스크**: 전문 인력 부족 → 외부 컨설팅·아웃소싱 검토
|
|
|
|
|
+- **품질 리스크**: 테스트 커버리지 부족 → CI/CD 자동화 테스트 강화
|
|
|
|
|
+- **배포 리스크**: 프로덕션 오류 → 블루/그린 배포 전략 채택
|
|
|
|
|
+- **Contingency**: 페이즈별 핵심 기능 최소화, 백업 환경 준비
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+*본 문서는 PRD 기반 최소 기능 중심으로 설계되었으며, 차후 요구사항 변화에 따라 단계별 확장이 가능합니다.*
|