버스래핑 광고 시스템
노선 등급, 가격, 승하차 데이터, 차종 규격을 함께 쓰는 버스래핑 상품 운영 문서
1. 개요
하루 16시간 이상 도심을 순환하며 노선에 따라 수만 명에게 반복 노출되는 대형 광고 매체입니다.
- 노선별 등급/가격 확인
- 견적 시뮬레이션
- 견적 요청 문의
- 노선·정류장 데이터 관리
- 가격·할인 규칙 관리
- 차종 규격 및 이미지 관리
2. 전체 구조
상품 소개, 견적 계산기, 노선 탐색, 규격표, FAQ, CTA를 묶은 랜딩 페이지입니다.
핵심 액션은 견적 계산과 문의 전환입니다.
유저용 API는 공개 읽기 전용입니다.
어드민 API는 세션 인증을 거친 CRUD입니다.
manage API는 AI/CLI 자동화에 맞춘 무인증 운영 경로입니다.
메인 DB는 노선, 가격, 할인, 차종 규격을 저장합니다.
common DB는 승하차 로그와 정류장 마스터를 읽기 전용으로 참조합니다.
API 레이어
유저용: /api/bus-wrapping/*
어드민: /api/admin/bus-wrapping/*
관리용: /api/bus-wrapping/manage/*
DB 레이어
dukplace_db: bus_route, bus_route_stop, bus_wrapping_price,
bus_wrapping_discount, bus_vehicle_spec
common_db: bus_ridership_logs, bus_stopGET /routes: 노선 목록GET /prices: 가격표GET /discounts: 할인 규칙GET /vehicle-specs: 차종 규격
route: 노선 CRUDroute/stop: 경유 정류장 CRUDprice: 가격 수정discount: 할인 CRUDvehicle-spec: 차종 규격 수정
route / stop / price / discount / vehicle-specupload: 노선도 이미지 업로드search-stop: 정류장 검색route-stops-suggest: 노선별 정류장 추천
3. 데이터 모델
| 테이블 | DB | 역할 | 비고 |
|---|---|---|---|
bus_route | dukplace_db | 노선 마스터, 등급, 공개 여부 관리 | API 응답 시 stops / avgDailyRiders 병합 |
bus_route_stop | dukplace_db | 노선별 경유 정류장과 순서 관리 | busStopArsId로 common DB 정류장과 연결 |
bus_wrapping_price | dukplace_db | 등급 × 래핑유형별 월 단가 및 1회성 비용 | UNIQUE KEY (grade, wrappingType) |
bus_wrapping_discount | dukplace_db | 기간 할인 / 볼륨 할인 규칙 | priceDiscount / productionFree 지원 |
bus_vehicle_spec | dukplace_db | 차종 × 래핑면별 규격 | 일반/중형/저상 계열 규격 관리 |
bus_ridership_logs | common_db | 노선별, 정류장별 일별 승하차 로그 | 최근 30일 평균 승차 수 계산에 사용 |
bus_stop | common_db | 전국 버스 정류장 마스터 | ARS 번호, 좌표, 유형 코드 보유 |
핵심 컬럼은 노선번호, 등급, 공개 여부(isOpen), 관리자 메모, 생성/수정 시각입니다.
API 응답 시에는 경유 정류장 배열 stops 와 최근 30일 기준 avgDailyRiders 가 자동 병합됩니다.
| 등급 | 의미 | 설명 |
|---|---|---|
SSA | 프리미엄 | 강남, 명동 등 핵심 상권 통과 |
SA | 우수 | 주요 간선도로 중심 |
A | 일반 | 중간 수요 노선 |
B | 기본 | 외곽 및 기본 수요 노선 |
노선과 정류장 관계를 저장하며 busRouteId, stopName, arsId, xCoord, yCoord, stopOrder, busStopArsId 를 사용합니다.
busStopArsId 는 common DB bus_stop.arsId 를 참조해 자동 연결됩니다.
정류장 순서는 공공데이터만으로 완전히 보장되지 않으므로 관리자가 직접 지정합니다.
가격 테이블은 grade, wrappingType, monthlyPrice, productionFee, installationFee 를 중심으로 운영합니다.
등급과 래핑유형 조합은 UNIQUE KEY (grade, wrappingType)로 upsert 관리합니다.
| 구분 | 조건 | 혜택 | 비고 |
|---|---|---|---|
| 기간 할인 | 6개월 이상 | 5% 할인 | 월 비용 할인 |
| 볼륨 할인 | 10대 이상 | 출력비 무상 | 제작비 성격 혜택 |
bus_vehicle_spec 은 차종 × 래핑면별 규격을 저장해 제작 가이드와 UI 표시에 사용합니다.
bus_ridership_logs 는 nodeId, arsNo, rteNo, stationNm, useYmd, gtonCount, gtoffCount 를 포함한 대용량 로그입니다.
bus_stop 은 정류장명, ARS 번호, 좌표, 유형 코드 마스터로 자동완성과 좌표 매칭에 사용됩니다.
주의: 평균 승차 인원 계산에는 반드시 gtonCount 를 사용합니다.
주의: 정류장 유형 코드 6(가상정류장)은 물리 매체 설치 대상에서 제외하는 것이 안전합니다.
4. 화면 및 운영 플로우
- 등급, 래핑 유형, 집행 기간, 대수를 선택해 실시간 견적 계산
- 노선 목록에서 등급 필터와 검색으로 대상 노선을 탐색
- RouteCard에서 경유 정류장과 최근 30일 평균 승차 인원을 확인
- 차종 규격표를 보고 광고 디자인 사이즈를 검토
- CTA 클릭 후 견적 요청 폼을 제출해 상담으로 연결
- 어드민 페이지에서 노선 관리, 가격/할인 관리, 차종 규격 관리 탭 운영
- 노선 CRUD 후 route-stops-suggest와 search-stop으로 정류장 후보를 가져와 순서 지정
- 가격은 등급 × 래핑유형 단위 upsert, 할인은 기간/볼륨 규칙으로 관리
- 노선도 이미지를 업로드하면 S3 key를 mapUrl로 저장하고 프론트에서 base URL과 결합
- QA가 끝난 노선만 isOpen = 1로 공개
| 기능 | 역할 |
|---|---|
| 견적 시뮬레이터 | 등급, 래핑유형, 기간, 대수 기반 실시간 견적 계산 |
| 노선 탐색 | 노선 목록, 경유 정류장 열람, 평균 승차 인원 확인 |
| 차종 규격표 | 차종 × 래핑면별 규격 정보 |
| FAQ | 자주 묻는 질문 |
| 견적 요청 폼 | CTA → 견적 문의 연결 |
5. 구현 구조
app/
api/bus-wrapping/
routes/route.ts
prices/route.ts
discounts/route.ts
vehicle-specs/route.ts
manage/
route/route.ts
stop/route.ts
price/route.ts
discount/route.ts
vehicle-spec/route.ts
upload/route.ts
search-stop/route.ts
route-stops-suggest/route.ts
api/admin/bus-wrapping/
route/route.ts
route/stop/route.ts
price/route.ts
discount/route.ts
vehicle-spec/route.ts6. 주요 기술 포인트
가격표와 할인 규칙만 API로 가져오고, 월 비용·할인·총 비용 계산은 클라이언트에서 즉시 처리합니다.
월 비용 = monthlyPrice × volume 할인 적용 = 기간 할인율 + 볼륨 할인율 최종 월 비용 = 월 비용 × (1 - 할인율) 총 비용 = 최종 월 비용 × duration 1회성 비용 = (productionFee + installationFee) × volume
노선번호를 기준으로 common DB의 최근 30일 로그를 집계해 RouteCard에 평균 일 승차 인원을 보여줍니다.
SELECT rteNo,
ROUND(SUM(gtonCount) / COUNT(DISTINCT useYmd)) AS avgDaily
FROM bus_ridership_logs
WHERE rteNo IN (...)
AND useYmd >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY rteNo공공데이터만으로는 실제 운행 순서를 완전히 복원하기 어려워, 관리자가 stopOrder를 직접 지정하는 구조입니다.
유저용 읽기 API, 세션 기반 어드민 API, AI/CLI용 manage API를 분리해 사용성과 운영 편의성을 함께 확보합니다.
Cafe24 Object Storage에 webp 변환본과 small/base/original 버전을 저장하고, 프론트는 base.dataURL과 key를 조합합니다.
manage API는 자연어 지시를 받은 에이전트가 직접 curl 호출로 노선, 정류장, 가격, 할인, 이미지 데이터를 갱신할 수 있게 설계됩니다.
7. 데이터 입력 순서
- 가격표 등록: 등급(SSA/SA/A/B) × 래핑유형 조합을 먼저 입력
- 할인 규칙 등록: 기간 할인과 볼륨 할인 정책 정의
- 차종 규격 등록: 차종 × 래핑면별 사이즈 입력
- 노선 등록: 노선번호, 등급, 기종점, 운영 메모 등 기본 정보 입력
- 정류장 등록: route-stops-suggest와 search-stop 기반으로 경유 정류장 구성
- 최종 공개: 검수 후 isOpen = 1로 전환