commit fed454b8c918a0b1f7ff766e5e4cc3931e895424 Author: caadiq Date: Tue Mar 24 13:17:16 2026 +0900 docs: Traeon 프로젝트 구현 계획서 추가 Co-Authored-By: Claude Opus 4.6 (1M context) diff --git a/docs/plan.md b/docs/plan.md new file mode 100644 index 0000000..510d09d --- /dev/null +++ b/docs/plan.md @@ -0,0 +1,203 @@ +# Traeon (트래온) - 택배 배송조회 웹 구현 계획서 + +## 개요 + +개인용 택배 배송조회 웹 애플리케이션. 운송장 번호를 등록하면 배송 상태를 조회하고, 백그라운드에서 자동 갱신하며, 상태 변경 시 알림을 보내는 서비스다. 기존 Docker 인프라와 fromis_9 프로젝트의 기술 스택/패턴을 따른다. + +## 기술 스택 + +| 영역 | 기술 | +|------|------| +| Frontend | React 18, Vite, Tailwind CSS, Zustand, React Query | +| Backend | Fastify 5, MySQL2, node-cron | +| 배송조회 | delivery-tracker 셀프호스팅 (GraphQL API) | +| DB | MariaDB (기존 인프라) | +| 인프라 | Docker Compose, Caddy 리버스 프록시 | + +## 프로젝트 구조 + +``` +/docker/traeon/ +├── docker-compose.yml +├── .env +├── docs/ +│ └── plan.md # 이 문서 +├── frontend/ +│ ├── Dockerfile +│ ├── package.json +│ ├── vite.config.js +│ ├── tailwind.config.js +│ ├── postcss.config.js +│ └── src/ +│ ├── main.jsx +│ ├── App.jsx +│ ├── index.css +│ ├── api/ +│ │ └── parcels.js # API 클라이언트 함수 +│ ├── components/ +│ │ ├── ParcelForm.jsx # 운송장 등록 폼 +│ │ ├── ParcelList.jsx # 택배 목록 +│ │ ├── ParcelCard.jsx # 개별 택배 카드 +│ │ ├── TrackingTimeline.jsx # 배송 추적 타임라인 +│ │ └── CarrierSelect.jsx # 택배사 선택 드롭다운 +│ └── stores/ +│ └── useParcelStore.js # Zustand 상태관리 +│ +└── backend/ + ├── Dockerfile + ├── package.json + └── src/ + ├── server.js # 진입점 + ├── app.js # Fastify 앱 빌드 + ├── config/ + │ └── index.js # 환경변수 설정 + ├── plugins/ + │ ├── db.js # MySQL2 연결 + │ └── tracker.js # delivery-tracker GraphQL 클라이언트 + ├── routes/ + │ ├── index.js # 라우트 통합 + │ ├── parcels.js # CRUD + 조회 라우트 + │ └── carriers.js # 택배사 목록 라우트 + ├── services/ + │ ├── parcel.js # 택배 비즈니스 로직 + │ ├── tracker.js # delivery-tracker API 호출 + │ ├── cron.js # 자동갱신 스케줄러 + │ └── notification.js # 알림 서비스 (Discord/Telegram webhook) + └── utils/ + └── error.js # 에러 처리 +``` + +## 데이터베이스 스키마 + +```sql +CREATE TABLE parcels ( + id INT AUTO_INCREMENT PRIMARY KEY, + carrier_id VARCHAR(50) NOT NULL, -- 택배사 코드 + carrier_name VARCHAR(100) NOT NULL, -- 택배사 이름 + tracking_number VARCHAR(100) NOT NULL, -- 운송장 번호 + label VARCHAR(200), -- 사용자 별칭 + status VARCHAR(50) DEFAULT 'pending', -- 배송 상태 + last_detail TEXT, -- 최근 배송 상세 (JSON) + last_checked_at DATETIME, -- 마지막 조회 시각 + delivered_at DATETIME, -- 배송 완료 시각 + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY uq_carrier_tracking (carrier_id, tracking_number) +); + +CREATE TABLE tracking_events ( + id INT AUTO_INCREMENT PRIMARY KEY, + parcel_id INT NOT NULL, + status VARCHAR(50), + description TEXT, + location VARCHAR(200), + event_time DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (parcel_id) REFERENCES parcels(id) ON DELETE CASCADE +); +``` + +## API 설계 + +| Method | Path | 설명 | +|--------|------|------| +| `GET` | `/api/parcels` | 전체 택배 목록 (상태별 필터) | +| `POST` | `/api/parcels` | 운송장 등록 | +| `GET` | `/api/parcels/:id` | 개별 택배 상세 + 추적 이벤트 | +| `PUT` | `/api/parcels/:id` | 별칭 수정 | +| `DELETE` | `/api/parcels/:id` | 운송장 삭제 | +| `POST` | `/api/parcels/:id/refresh` | 수동 새로고침 | +| `GET` | `/api/carriers` | 지원 택배사 목록 | + +## 구현 단계 + +### 1단계: 프로젝트 초기 세팅 + +- [ ] `docker-compose.yml` 작성 + - `traeon-frontend`: node:20-alpine, 포트 80, 네트워크 `app` + - `traeon-backend`: node:20-alpine, 포트 80, 네트워크 `app` + `db` + - `delivery-tracker`: 셀프호스팅 컨테이너, 네트워크 `app` + - Watchtower 제외 레이블 +- [ ] `.env` 파일 작성 (DB 접속정보 등) +- [ ] Caddy에 `traeon.caadiq.co.kr` 도메인 추가 + +### 2단계: Backend 구현 + +- [ ] Fastify 앱 세팅 (app.js, server.js) — fromis_9 패턴 +- [ ] DB 플러그인 + 테이블 자동 생성 +- [ ] delivery-tracker GraphQL 클라이언트 플러그인 +- [ ] API 라우트 구현 (위 API 설계 참고) +- [ ] 자동갱신 cron 서비스 (node-cron) + - 배송 중인 택배: 30분 간격 자동 조회 + - 배송 완료된 택배: 조회 중단 + - 상태 변경 감지 시 알림 트리거 +- [ ] 알림 서비스 + - Discord Webhook 또는 Telegram Bot API + - 설정 가능한 Webhook URL (.env) + +### 3단계: Frontend 구현 + +- [ ] Vite + React + Tailwind 초기 세팅 +- [ ] Vite 프록시 설정 (`/api/` → backend) +- [ ] 메인 페이지 + - 운송장 등록 폼 (택배사 선택 + 운송장 번호 + 별칭) + - 택배 목록 (카드형, 상태별 그룹핑: 배송중 / 배송완료) + - 각 카드에 현재 상태, 마지막 위치, 경과 시간 표시 +- [ ] 상세 페이지 + - 배송 추적 타임라인 (세로 타임라인 UI) + - 수동 새로고침 버튼 + - 삭제/수정 기능 +- [ ] React Query로 데이터 페칭 + 자동 리페칭 +- [ ] Zustand로 UI 상태 관리 (필터, 정렬) + +### 4단계: Docker 배포 + +- [ ] Frontend Dockerfile (node:20-alpine, 개발모드) +- [ ] Backend Dockerfile (node:20-alpine, 개발모드) +- [ ] `docker compose up -d --build` 로 실행 확인 +- [ ] Caddy 리버스 프록시 설정 확인 + +## delivery-tracker 셀프호스팅 연동 + +delivery-tracker는 GraphQL API를 제공한다. Backend에서 GraphQL 쿼리로 배송 정보를 조회: + +```graphql +query Track($carrierId: ID!, $trackingNumber: String!) { + track(carrierId: $carrierId, trackingNumber: $trackingNumber) { + lastEvent { + time { datetime } + status { code name } + description + } + events { + edges { + node { + time { datetime } + status { code name } + description + } + } + } + } +} +``` + +## 참조할 기존 파일 + +| 파일 | 용도 | +|------|------| +| `/docker/fromis_9/docker-compose.yml` | Docker 서비스 구성 패턴 | +| `/docker/fromis_9/frontend/vite.config.js` | Vite 프록시 설정 | +| `/docker/fromis_9/backend/src/app.js` | Fastify 플러그인 로드 패턴 | +| `/docker/fromis_9/backend/src/plugins/db.js` | MySQL2 연결 패턴 | +| `/docker/fromis_9/backend/src/routes/index.js` | 라우트 통합 패턴 | +| `/docker/fromis_9/backend/src/server.js` | 서버 진입점 패턴 | +| `/docker/caddy/Caddyfile` | Caddy 도메인 추가 위치 | + +## 검증 방법 + +1. `docker compose up -d --build` 로 전체 서비스 기동 +2. `docker compose logs -f` 로 에러 확인 +3. 브라우저에서 `traeon.caadiq.co.kr` 접속, 운송장 등록/조회 테스트 +4. cron 자동갱신 로그 확인 +5. 알림 Webhook 수신 테스트