Files
sam-docs/frontend/api-specs/vehicle-api.md
김보곤 0e6d4e6adf docs: [vehicle] 차량 사진 API 문서 추가
- vehicle-api.md에 사진 API 3개 엔드포인트 추가 (섹션 7)
- corporate-vehicles.md에 사진 이관 현황 및 엔드포인트 추가
2026-03-12 22:26:40 +09:00

25 KiB

차량관리 API 명세

작성일: 2026-03-12 상태: API 이관 예정 (MNG에서 운영중, API 엔드포인트 미구현) Base URL: api.codebridge-x.com (운영) / api.dev.codebridge-x.com (개발)


1. 개요

법인/렌트/리스 차량을 등록하고, 운행일지와 정비이력을 관리하는 API이다. 멀티테넌트 구조로 테넌트별 데이터 격리가 적용된다.

1.1 인증

모든 요청에 다음 헤더가 필요하다:

X-API-KEY: {api_key}
Authorization: Bearer {token}

1.2 공통 응답 형식

{
  "success": true,
  "message": "조회 성공",
  "data": { ... }
}

에러 시:

{
  "success": false,
  "message": "에러 메시지"
}

1.3 메뉴 구성

메뉴 설명 섹션
차량목록 법인/렌트/리스 차량 등록 관리 3. 차량목록 API
차량일지 운행기록 관리 및 월별 통계 4. 차량일지 API
정비이력 정비/주유/보험 등 비용 관리 5. 정비이력 API

1.4 엔드포인트 요약

# Method Path 설명
1 GET /api/v1/corporate-vehicles 차량 목록
2 POST /api/v1/corporate-vehicles 차량 등록
3 GET /api/v1/corporate-vehicles/{id} 차량 상세
4 PUT /api/v1/corporate-vehicles/{id} 차량 수정
5 DELETE /api/v1/corporate-vehicles/{id} 차량 삭제
6 GET /api/v1/corporate-vehicles/dropdown 차량 드롭다운 목록
7 GET /api/v1/vehicle-logs 운행기록 목록
8 POST /api/v1/vehicle-logs 운행기록 등록
9 GET /api/v1/vehicle-logs/{id} 운행기록 상세
10 PUT /api/v1/vehicle-logs/{id} 운행기록 수정
11 DELETE /api/v1/vehicle-logs/{id} 운행기록 삭제
12 GET /api/v1/vehicle-logs/summary 월별 용도별 통계
13 GET /api/v1/vehicle-maintenances 정비이력 목록
14 POST /api/v1/vehicle-maintenances 정비이력 등록
15 GET /api/v1/vehicle-maintenances/{id} 정비이력 상세
16 PUT /api/v1/vehicle-maintenances/{id} 정비이력 수정
17 DELETE /api/v1/vehicle-maintenances/{id} 정비이력 삭제
18 GET /api/v1/corporate-vehicles/{id}/photos 차량 사진 목록
19 POST /api/v1/corporate-vehicles/{id}/photos 차량 사진 업로드 (최대 10장)
20 DELETE /api/v1/corporate-vehicles/{id}/photos/{fileId} 차량 사진 삭제

2. 데이터 모델

2.1 CorporateVehicle (차량)

{
  "id": 1,
  "plate_number": "12가 3456",
  "model": "에쿠스",
  "vehicle_type": "승용차",
  "ownership_type": "corporate",
  "year": 2024,
  "driver": "홍길동",
  "status": "active",
  "mileage": 15000,
  "memo": "대표이사 전용",
  "purchase_date": "2024-01-15",
  "purchase_price": 85000000,
  "contract_date": null,
  "rent_company": null,
  "rent_company_tel": null,
  "rent_period": null,
  "agreed_mileage": null,
  "vehicle_price": 0,
  "residual_value": 0,
  "deposit": 0,
  "monthly_rent": 0,
  "monthly_rent_tax": 0,
  "insurance_company": null,
  "insurance_company_tel": null,
  "log_distance": 2350,
  "total_mileage": 17350,
  "created_at": "2026-01-15T09:00:00.000000Z",
  "updated_at": "2026-03-10T14:30:00.000000Z"
}

필드 설명 — 공통

필드 타입 필수 설명
plate_number string(20) 차량번호
model string(100) 차량 모델명
vehicle_type string(20) 차종
ownership_type enum 소유형태
year int 연식
driver string(50) 주 운전자
status enum 상태 (기본: active)
mileage int 기준 주행거리 (정비 시 갱신, 기본: 0)
memo text 메모

필드 설명 — 법인 전용 (ownership_type = "corporate")

필드 타입 설명
purchase_date date 취득일자
purchase_price int 취득가액 (원)

필드 설명 — 렌트/리스 전용 (ownership_type = "rent" or "lease")

필드 타입 설명
contract_date date 계약일자
rent_company string(100) 렌트/리스 회사명
rent_company_tel string(20) 회사 연락처
rent_period string(20) 계약기간
agreed_mileage string(20) 약정주행거리
vehicle_price int 차량가액 (원)
residual_value int 잔존가치 (원)
deposit int 보증금 (원)
monthly_rent int 월 렌트료 공급가 (원)
monthly_rent_tax int 월 렌트료 부가세 (원)
insurance_company string(100) 보험사명
insurance_company_tel string(20) 보험사 연락처

계산 필드 (API 응답에만 포함, 저장 안 함)

필드 계산식 설명
log_distance SUM(vehicle_logs.distance_km) 운행일지 거리 합계
total_mileage mileage + log_distance 총 주행거리

Enum 값

ownership_type (소유형태):

라벨 UI 배지 색상
corporate 법인 보라 (purple)
rent 렌트 파랑 (blue)
lease 리스 초록 (green)

vehicle_type (차종):

설명
승용차 일반 승용차
승합차 승합차
화물차 화물차
SUV SUV

status (상태):

라벨 UI 배지 색상
active 운행중 초록 (green)
maintenance 정비중 노랑 (yellow)
disposed 처분 빨강 (red)

2.2 VehicleLog (운행기록)

{
  "id": 1,
  "logDate": "2026-03-12",
  "vehicleId": 1,
  "plateNumber": "12가 3456",
  "model": "에쿠스",
  "department": "영업부",
  "driverName": "홍길동",
  "tripType": "business",
  "departureType": "office",
  "departureName": "본사",
  "departureAddress": "서울시 강남구 테헤란로 123",
  "arrivalType": "client",
  "arrivalName": "거래처A",
  "arrivalAddress": "경기도 성남시 분당구 판교로 456",
  "distanceKm": 45,
  "note": "거래처방문"
}

필드 설명

필드 타입 필수 설명
vehicleId int 차량 ID (FK → corporate_vehicles)
logDate date 운행일
driverName string(50) 운전자명
tripType enum 운행 용도
distanceKm int 운행거리 (km, 0 이상)
department string(50) 부서
departureType enum 출발지 유형
departureName string(100) 출발지명
departureAddress string(200) 출발지 주소
arrivalType enum 도착지 유형
arrivalName string(100) 도착지명
arrivalAddress string(200) 도착지 주소
note string(200) 비고

참고: plateNumber, model은 차량 관계에서 자동 포함된 읽기 전용 필드이다.

Enum 값

tripType (운행 용도):

라벨 UI 배지 색상
commute_to 출근용 초록 (green)
commute_from 퇴근용 파랑 (blue)
business 업무용 보라 (purple)
personal 비업무 회색 (gray)
commute_round 출퇴근 왕복 초록 (green)
business_round 업무용 왕복 보라 (purple)
personal_round 비업무 왕복 회색 (gray)

departureType / arrivalType (위치 유형):

라벨
home 자택
office 회사
client 거래처
other 기타

비고 프리셋 옵션 (버튼으로 빠른 입력):

["거래처방문", "제조시설등", "회의참석", "판촉활동", "교육등"]

2.3 VehicleMaintenance (정비이력)

{
  "id": 1,
  "date": "2026-03-10",
  "vehicleId": 1,
  "plateNumber": "12가 3456",
  "model": "에쿠스",
  "category": "주유",
  "description": "LPG 충전",
  "amount": 85000,
  "mileage": 17350,
  "vendor": "SK에너지 강남점",
  "memo": null
}

필드 설명

필드 타입 필수 설명
vehicleId int 차량 ID (FK → corporate_vehicles)
date date 정비일
category string(20) 카테고리
amount int 금액 (원, 0 이상)
description string(200) 설명
mileage int 정비 시 주행거리 (입력 시 차량 mileage 자동 갱신)
vendor string(100) 업체명
memo text 메모

카테고리 목록

카테고리 아이콘 UI 배지 색상
주유 Fuel amber
정비 Wrench blue
보험 Shield emerald
세차 Droplets cyan
주차 ParkingCircle purple
통행료 Route orange
검사 ClipboardCheck indigo
기타 MoreHorizontal gray

3. 차량목록 API

3.1 차량 목록 조회

GET /api/v1/corporate-vehicles

쿼리 파라미터:

파라미터 타입 기본값 설명
ownership_type string all corporate / rent / lease / all
vehicle_type string all 승용차 / 승합차 / 화물차 / SUV / all
status string all active / maintenance / disposed / all
search string 차량번호, 모델, 운전자 검색

응답:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "plate_number": "12가 3456",
      "model": "에쿠스",
      "vehicle_type": "승용차",
      "ownership_type": "corporate",
      "year": 2024,
      "driver": "홍길동",
      "status": "active",
      "mileage": 15000,
      "memo": null,
      "purchase_date": "2024-01-15",
      "purchase_price": 85000000,
      "log_distance": 2350,
      "total_mileage": 17350
    }
  ]
}

3.2 차량 등록

POST /api/v1/corporate-vehicles

요청 Body:

{
  "plate_number": "12가 3456",
  "model": "에쿠스",
  "vehicle_type": "승용차",
  "ownership_type": "corporate",
  "year": 2024,
  "driver": "홍길동",
  "status": "active",
  "mileage": 15000,
  "memo": "대표이사 전용",
  "purchase_date": "2024-01-15",
  "purchase_price": 85000000
}

유효성 검증:

필드 규칙
plate_number required, string, max:20
model required, string, max:100
vehicle_type required, string, max:20
ownership_type required, in:corporate,rent,lease

응답 (201):

{
  "success": true,
  "message": "차량이 등록되었습니다.",
  "data": { ... }
}

3.3 차량 상세

GET /api/v1/corporate-vehicles/{id}

3.4 차량 수정

PUT /api/v1/corporate-vehicles/{id}

요청 Body는 등록과 동일. 유효성 검증도 동일.

3.5 차량 삭제

DELETE /api/v1/corporate-vehicles/{id}

SoftDelete 적용 (복구 가능).

응답:

{
  "success": true,
  "message": "차량이 삭제되었습니다."
}

3.6 차량 드롭다운 목록

GET /api/v1/corporate-vehicles/dropdown

차량일지, 정비이력에서 차량 선택 드롭다운에 사용. 간소화된 필드만 반환.

응답:

{
  "success": true,
  "data": [
    { "id": 1, "plate_number": "12가 3456", "model": "에쿠스" },
    { "id": 2, "plate_number": "56나 7890", "model": "스타리아" }
  ]
}

4. 차량일지 API

4.1 운행기록 목록

GET /api/v1/vehicle-logs

쿼리 파라미터:

파라미터 타입 기본값 설명
vehicle_id int all 차량 ID
year int 현재년 연도
month int 현재월
trip_type string all 운행 용도
search string 운전자, 부서, 출발지, 도착지, 비고 검색

응답:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "logDate": "2026-03-12",
      "vehicleId": 1,
      "plateNumber": "12가 3456",
      "model": "에쿠스",
      "department": "영업부",
      "driverName": "홍길동",
      "tripType": "business",
      "departureType": "office",
      "departureName": "본사",
      "departureAddress": "서울시 강남구 테헤란로 123",
      "arrivalType": "client",
      "arrivalName": "거래처A",
      "arrivalAddress": "경기도 성남시 분당구 판교로 456",
      "distanceKm": 45,
      "note": "거래처방문"
    }
  ]
}

참고: 응답 필드명은 camelCase를 사용한다 (MNG 기존 패턴 유지).

4.2 운행기록 등록

POST /api/v1/vehicle-logs

요청 Body:

{
  "vehicle_id": 1,
  "log_date": "2026-03-12",
  "department": "영업부",
  "driver_name": "홍길동",
  "trip_type": "business",
  "departure_type": "office",
  "departure_name": "본사",
  "departure_address": "서울시 강남구 테헤란로 123",
  "arrival_type": "client",
  "arrival_name": "거래처A",
  "arrival_address": "경기도 성남시 분당구 판교로 456",
  "distance_km": 45,
  "note": "거래처방문"
}

유효성 검증:

필드 규칙
vehicle_id required, exists:corporate_vehicles,id
log_date required, date
driver_name required, string, max:50
trip_type required, in:commute_to,commute_from,business,personal,commute_round,business_round,personal_round
distance_km required, integer, min:0

응답 (201):

{
  "success": true,
  "message": "운행기록이 등록되었습니다.",
  "data": { ... }
}

4.3 운행기록 상세

GET /api/v1/vehicle-logs/{id}

4.4 운행기록 수정

PUT /api/v1/vehicle-logs/{id}

요청 Body/유효성 검증은 등록과 동일.

4.5 운행기록 삭제

DELETE /api/v1/vehicle-logs/{id}

4.6 월별 용도별 통계

GET /api/v1/vehicle-logs/summary

쿼리 파라미터:

파라미터 타입 설명
vehicle_id int 차량 ID (생략 시 전체)
year int 연도
month int

응답:

{
  "success": true,
  "data": {
    "byType": {
      "commute_to": { "label": "출근용", "count": 5, "distance": 125 },
      "commute_from": { "label": "퇴근용", "count": 5, "distance": 130 },
      "business": { "label": "업무용", "count": 10, "distance": 280 },
      "personal": { "label": "비업무", "count": 2, "distance": 45 }
    },
    "total": {
      "count": 22,
      "distance": 580
    }
  }
}

5. 정비이력 API

5.1 정비이력 목록

GET /api/v1/vehicle-maintenances

쿼리 파라미터:

파라미터 타입 기본값 설명
vehicle_id int all 차량 ID
category string all 카테고리 (주유, 정비, 보험 등)
start_date date 3개월 전 시작일
end_date date 오늘 종료일
search string 설명, 업체명, 메모 검색

응답:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "date": "2026-03-10",
      "vehicleId": 1,
      "plateNumber": "12가 3456",
      "model": "에쿠스",
      "category": "주유",
      "description": "LPG 충전",
      "amount": 85000,
      "mileage": 17350,
      "vendor": "SK에너지 강남점",
      "memo": null
    }
  ]
}

5.2 정비이력 등록

POST /api/v1/vehicle-maintenances

요청 Body:

{
  "vehicle_id": 1,
  "date": "2026-03-10",
  "category": "주유",
  "description": "LPG 충전",
  "amount": 85000,
  "mileage": 17350,
  "vendor": "SK에너지 강남점",
  "memo": null
}

유효성 검증:

필드 규칙
vehicle_id required, exists:corporate_vehicles,id
date required, date
category required, string, max:20
amount required, numeric, min:0

부수 효과: mileage 값이 있으면 해당 차량의 corporate_vehicles.mileage를 자동 갱신한다.

응답 (201):

{
  "success": true,
  "message": "정비 이력이 등록되었습니다.",
  "data": { ... }
}

5.3 정비이력 상세

GET /api/v1/vehicle-maintenances/{id}

5.4 정비이력 수정

PUT /api/v1/vehicle-maintenances/{id}

요청 Body/유효성 검증은 등록과 동일. mileage 갱신 부수 효과도 동일.

5.5 정비이력 삭제

DELETE /api/v1/vehicle-maintenances/{id}

6. UI 구현 가이드

6.1 차량목록 화면

┌─ 페이지 헤더 ──────────────────────
│  제목: "차량목록"
│  검색 | Excel 다운로드 | 차량 등록 버튼
│
├─ 요약 카드 (4열) ──────────────────
│  총 차량 | 법인 취득가 | 월 렌트/리스비 | 총 주행거리
│
├─ 필터 바 ──────────────────────────
│  소유형태: 전체 | 법인 | 렌트 | 리스
│  상태: 전체 | 운행중 | 정비중 | 처분
│
├─ 차량 목록 테이블 ─────────────────
│  차량번호 | 차종/모델 | 소유형태 | 운전자 | 주행거리 | 상태
│
├─ 등록/수정 모달 ───────────────────
│  차량번호, 모델명, 차종, 소유형태
│  연식, 주 운전자, 상태, 메모
│  ─────────────────────────
│  [법인] 취득일자, 취득가액
│  [렌트/리스] 계약일, 렌트사, 계약기간,
│    약정주행, 차량가액, 잔존가치, 보증금,
│    월렌트료, 부가세, 보험사
│  ─────────────────────────
│  [삭제] [취소] [등록/저장]
└────────────────────────────────────

요약 카드 계산:

카드 계산식
총 차량 전체 차량 수
법인 취득가 ownership_type = 'corporate'인 차량의 purchase_price 합계
월 렌트/리스비 ownership_type in ('rent','lease')인 차량의 monthly_rent + monthly_rent_tax 합계
총 주행거리 전체 차량의 total_mileage 합계

조건부 폼 필드:

  • ownership_type = "corporate" → 법인 전용 필드 표시
  • ownership_type = "rent" or "lease" → 렌트/리스 전용 필드 표시

6.2 차량일지 화면

┌─ 페이지 헤더 ──────────────────────
│  차량 선택 드롭다운 (현재 주행거리 표시)
│  연/월 선택 | CSV 다운로드 | 기록 추가 버튼
│
├─ 용도별 통계 카드 ─────────────────
│  출근 | 퇴근 | 업무 | 비업무
│  건수 + 총 거리(km)
│
├─ 운행기록 테이블 ──────────────────
│  날짜 | 차량 | 부서/이름 | 용도 | 출발지 | 도착지 | 거리 | 비고
│
├─ 등록/수정 모달 ───────────────────
│  차량 선택, 날짜, 부서, 운전자, 용도
│  출발지: 유형 + 이름 + 주소
│  도착지: 유형 + 이름 + 주소
│  운행거리(km)
│  비고: 프리셋 버튼 + 자유 입력
│  [삭제] [취소] [등록/저장]
└────────────────────────────────────

특수 기능 (프론트엔드에서 처리):

기능 설명
기록 복사 기존 기록을 복제하여 새 날짜로 등록 (API는 일반 POST)
출발↔도착 교환 출발지/도착지 swap + tripType 자동 전환 (commute_tocommute_from)
비고 프리셋 5개 버튼 클릭 시 비고 필드에 텍스트 입력

6.3 정비이력 화면

┌─ 페이지 헤더 ──────────────────────
│  제목: "정비이력"
│  새로고침 | CSV 다운로드 | 정비 등록 버튼
│
├─ 요약 카드 (4열) ──────────────────
│  총 정비비용 | 주유비 | 정비비 | 기타비용
│
├─ 필터 영역 ────────────────────────
│  기간: 시작일 ~ 종료일 (기본: 최근 3개월)
│  카테고리: 전체 | 주유 | 정비 | 보험 | 세차 | 주차 | 통행료 | 검사 | 기타
│  차량: 드롭다운 선택
│  검색: 설명, 업체명 검색
│
├─ 정비이력 테이블 ──────────────────
│  날짜 | 차량 | 카테고리 | 설명 | 금액 | 주행거리 | 작업
│
├─ 등록/수정 모달 ───────────────────
│  차량 선택, 날짜, 카테고리
│  설명, 금액, 주행거리, 업체명, 메모
│  [삭제] [취소] [등록/저장]
└────────────────────────────────────

요약 카드 계산 (조회된 목록 데이터 기준):

카드 계산식
총 정비비용 전체 amount 합계
주유비 category = '주유'amount 합계
정비비 category = '정비'amount 합계
기타비용 총 정비비용 - 주유비 - 정비비

7. 차량 사진 API

7.1 사진 목록 조회

GET /api/v1/corporate-vehicles/{id}/photos

응답 예시:

{
  "success": true,
  "message": "조회 성공",
  "data": [
    {
      "id": 42,
      "file_name": "차량_전면.jpg",
      "file_path": "1/corporate-vehicles/2026/03/a1b2c3d4e5f6.jpg",
      "file_url": "/api/v1/files/42/download",
      "file_size": 2048576,
      "mime_type": "image/jpeg",
      "created_at": "2026-03-12 15:30:00"
    }
  ]
}

7.2 사진 업로드

POST /api/v1/corporate-vehicles/{id}/photos
Content-Type: multipart/form-data
파라미터 타입 필수 설명
files[] file[] 이미지 파일 (다중 업로드)

제약조건:

항목
최대 보유 수량 10장 / 차량
허용 확장자 jpg, jpeg, png, gif, bmp, webp
파일 크기 제한 10MB / 파일
동적 max 계산 max = 10 - 현재 사진 수

응답 예시 (업로드된 파일 목록 반환):

{
  "success": true,
  "message": "등록 성공",
  "data": [
    {
      "id": 43,
      "file_name": "차량_후면.jpg",
      "file_path": "1/corporate-vehicles/2026/03/f6e5d4c3b2a1.jpg",
      "file_url": "/api/v1/files/43/download",
      "file_size": 1536000,
      "mime_type": "image/jpeg",
      "created_at": "2026-03-12 16:00:00"
    }
  ]
}

에러 응답 (10장 초과 시):

{
  "success": false,
  "message": "사진은 최대 10장까지 등록할 수 있습니다."
}

7.3 사진 삭제

DELETE /api/v1/corporate-vehicles/{id}/photos/{fileId}

응답 예시:

{
  "success": true,
  "message": "삭제 성공",
  "data": {
    "file_id": 42,
    "deleted": true
  }
}

7.4 UI 구현 가이드 — 사진

┌─ 차량 상세/수정 페이지 ───────────────
│
├─ 사진 영역 ──────────────────────────
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│  │ 📷   │ │ 📷   │ │ 📷   │ │  +   │
│  │ 사진1 │ │ 사진2 │ │ 사진3 │ │ 추가 │
│  └──────┘ └──────┘ └──────┘ └──────┘
│  * 최대 10장 (n/10 표시)
│  * 사진 클릭 → 확대 보기
│  * 삭제 버튼 (X) 각 사진에 표시
│  * 드래그앤드롭 또는 파일 선택으로 업로드
│

특수 기능:

  • 다중 파일 선택 지원 (multiple attribute)
  • 업로드 전 미리보기 (FileReader API)
  • 남은 업로드 가능 수량 = 10 - 현재 사진 수
  • 업로드 가능 수량 초과 시 파일 선택 차단

8. 데이터 관계도

corporate_vehicles (차량 마스터)
    │
    ├── vehicle_logs (1:N)
    │   운행기록 → distance_km 합산하여 차량 total_mileage 계산
    │
    ├── vehicle_maintenances (1:N)
    │   정비기록 → mileage 입력 시 차량 mileage 기준값 갱신
    │
    └── files (1:N, polymorphic)
        사진 → document_type='corporate_vehicle', document_id=vehicle.id
        최대 10장, R2 스토리지 저장, Soft Delete
총 주행거리 계산:
  total_mileage = corporate_vehicles.mileage (정비 시 갱신되는 기준값)
                + SUM(vehicle_logs.distance_km) (운행일지 거리 합계)

관련 문서


최종 업데이트: 2026-03-12