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_to ↔ commute_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) 각 사진에 표시
│ * 드래그앤드롭 또는 파일 선택으로 업로드
│
특수 기능:
- 다중 파일 선택 지원 (
multipleattribute) - 업로드 전 미리보기 (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