From efd0427cd6029d67017b62f8f98c36318dfafb73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Thu, 12 Mar 2026 13:31:34 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20[equipment]=20React=20=ED=94=84?= =?UTF-8?q?=EB=A1=A0=ED=8A=B8=EC=97=94=EB=93=9C=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EB=AC=B8=EC=84=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 26개 API 엔드포인트 상세 스펙 (파라미터, 응답 구조) - 8개 화면 구현 가이드 (레이아웃, 컬럼, 드롭다운 옵션) - 점검 그리드 동작 규칙 (셀 토글, 비근무일, 자동 판정) - 비즈니스 규칙 정리 (권한, 사진 제한 등) --- INDEX.md | 3 +- requests/equipment-frontend-request.md | 749 +++++++++++++++++++++++++ 2 files changed, 751 insertions(+), 1 deletion(-) create mode 100644 requests/equipment-frontend-request.md diff --git a/INDEX.md b/INDEX.md index 93629cc..60ada6b 100644 --- a/INDEX.md +++ b/INDEX.md @@ -145,7 +145,7 @@ DB 도메인별: | [hr/](features/hr/) | 인사관리 | | [crm/README.md](features/crm/README.md) | CRM | | [esign/README.md](features/esign/README.md) | 전자서명 | -| [equipment/README.md](features/equipment/README.md) | 설비관리 (MNG R&D 현황 + DB 스키마) | +| [equipment/README.md](features/equipment/README.md) | 설비관리 (API Phase 1 완료 + DB 스키마) | | [boards/README.md](features/boards/README.md) | 게시판 | | [ai/README.md](features/ai/README.md) | AI 분석 | | [card-vehicle/README.md](features/card-vehicle/README.md) | 법인카드·차량 | @@ -223,6 +223,7 @@ DB 도메인별: | [document-api-integration.md](frontend/api-specs/document-api-integration.md) | 문서 API 연동 명세 | | [payroll-api.md](frontend/api-specs/payroll-api.md) | 급여관리 API 전체 명세 (18개 엔드포인트) | | [barobill-api.md](frontend/api-specs/barobill-api.md) | 바로빌 회계 데이터 API 명세 (42개 엔드포인트) | +| [equipment-api.md](requests/equipment-frontend-request.md) | 설비관리 React 프론트엔드 구현 요청 (26개 엔드포인트 + 화면 가이드) | ### frontend/integration/ — 프론트엔드 개발 가이드 diff --git a/requests/equipment-frontend-request.md b/requests/equipment-frontend-request.md new file mode 100644 index 0000000..d763861 --- /dev/null +++ b/requests/equipment-frontend-request.md @@ -0,0 +1,749 @@ +# 설비관리 React 프론트엔드 구현 요청 + +> **작성일**: 2026-03-12 +> **요청자**: R&D실 +> **상태**: API 백엔드 완료, React 프론트엔드 구현 요청 + +--- + +## 1. 개요 + +설비관리(Equipment Management) 기능의 React 프론트엔드를 구현해 주세요. +API 백엔드(26개 엔드포인트)는 개발 완료되어 개발서버에 배포된 상태입니다. + +- **API 문서**: Swagger 미작성 상태이므로 아래 엔드포인트 스펙을 참고 +- **MNG 참고**: `mng/resources/views/equipment/` 에 Blade/HTMX로 구현된 R&D 버전이 있으므로 화면 구성 참고 가능 +- **API Base URL**: `https://api.dev.codebridge-x.com/api/v1` + +--- + +## 2. 구현 화면 목록 + +| # | 화면 | 경로 (제안) | 우선순위 | 비고 | +|---|------|------------|:--------:|------| +| 1 | 설비 목록 | `/equipment` | 1순위 | DataTable + 필터 | +| 2 | 설비 등록 | `/equipment/create` | 1순위 | 폼 | +| 3 | 설비 상세 | `/equipment/:id` | 1순위 | 탭 3개 (기본정보/점검항목/수리이력) | +| 4 | 설비 수정 | `/equipment/:id/edit` | 1순위 | 등록과 동일 폼 + 사진 관리 | +| 5 | 점검 그리드 | `/equipment/inspections` | 2순위 | 동적 그리드, 셀 토글 (가장 복잡) | +| 6 | 수리이력 목록 | `/equipment/repairs` | 2순위 | DataTable + 필터 | +| 7 | 수리이력 등록 | `/equipment/repairs/create` | 2순위 | 폼 | +| 8 | 설비 대시보드 | `/equipment/dashboard` | 3순위 | 통계 카드 + 차트 | + +--- + +## 3. API 엔드포인트 상세 + +### 3.1 설비 CRUD (9개) + +#### `GET /v1/equipment` — 목록 조회 (페이지네이션) + +**Query Parameters:** + +| 파라미터 | 타입 | 필수 | 기본값 | 설명 | +|----------|------|:----:|--------|------| +| `search` | string | — | — | 설비코드, 설비명 LIKE 검색 | +| `status` | string | — | — | `active` / `idle` / `disposed` | +| `production_line` | string | — | — | 생산라인 필터 | +| `equipment_type` | string | — | — | 설비유형 필터 | +| `sort_by` | string | — | `sort_order` | 정렬 컬럼 | +| `sort_direction` | string | — | `asc` | `asc` / `desc` | +| `per_page` | integer | — | `20` | 페이지당 개수 | +| `page` | integer | — | `1` | 페이지 번호 | + +**응답:** + +```json +{ + "success": true, + "message": "...", + "data": { + "current_page": 1, + "data": [ + { + "id": 1, + "equipment_code": "KD-M-001", + "name": "포밍기#1", + "equipment_type": "포밍기", + "specification": "1200x800mm", + "manufacturer": "제조사", + "model_name": "모델A", + "serial_no": "SN-001", + "location": "1공장-1F", + "production_line": "스라트", + "purchase_date": "2020-01-15", + "install_date": "2020-02-01", + "purchase_price": "15000000.00", + "useful_life": 10, + "status": "active", + "disposed_date": null, + "manager_id": 1, + "sub_manager_id": 2, + "photo_path": null, + "memo": "비고", + "options": {}, + "is_active": 1, + "sort_order": 1, + "manager": { "id": 1, "name": "홍길동" }, + "sub_manager": { "id": 2, "name": "김철수" } + } + ], + "total": 12, + "per_page": 20, + "last_page": 1 + } +} +``` + +--- + +#### `GET /v1/equipment/options` — 드롭다운 데이터 + +**응답:** + +```json +{ + "success": true, + "data": { + "equipment_types": ["포밍기", "미싱기", "샤링기", "V컷팅기", "절곡기", "프레스", "드릴", "기타"], + "production_lines": ["스라트", "스크린", "절곡", "기타"], + "statuses": ["active", "idle", "disposed"], + "equipment_list": [ + { "id": 1, "equipment_code": "KD-M-001", "name": "포밍기#1" } + ] + } +} +``` + +> 설비 등록/수정 폼, 필터 드롭다운에 사용 + +--- + +#### `GET /v1/equipment/stats` — 대시보드 통계 + +**응답:** + +```json +{ + "success": true, + "data": { + "total": 12, + "active": 10, + "idle": 2, + "disposed": 0 + } +} +``` + +--- + +#### `POST /v1/equipment` — 설비 등록 + +**Request Body (JSON):** + +| 필드 | 타입 | 필수 | 설명 | +|------|------|:----:|------| +| `equipment_code` | string | ✅ | 설비코드 (tenant 내 unique) | +| `name` | string | ✅ | 설비명 | +| `equipment_type` | string | — | 설비유형 | +| `specification` | string | — | 규격 | +| `manufacturer` | string | — | 제조사 | +| `model_name` | string | — | 모델명 | +| `serial_no` | string | — | 제조번호 | +| `location` | string | — | 위치 | +| `production_line` | string | — | 생산라인 | +| `purchase_date` | date | — | 구입일 (YYYY-MM-DD) | +| `install_date` | date | — | 설치일 (YYYY-MM-DD) | +| `purchase_price` | number | — | 구입가격 | +| `useful_life` | integer | — | 내용연수 | +| `status` | string | — | `active`(기본) / `idle` / `disposed` | +| `disposed_date` | date | — | 폐기일 | +| `manager_id` | integer | — | 담당자 ID (users FK) | +| `sub_manager_id` | integer | — | 부담당자 ID (users FK) | +| `memo` | string | — | 비고 | +| `options` | object | — | 확장 속성 JSON | +| `sort_order` | integer | — | 정렬순서 | + +**응답:** 생성된 설비 객체 (관계 포함) + +--- + +#### `GET /v1/equipment/{id}` — 설비 상세 + +**응답에 포함되는 관계 데이터:** +- `manager` — 담당자 (User) +- `subManager` — 부담당자 (User) +- `inspectionTemplates` — 점검항목 배열 +- `repairs` — 수리이력 배열 +- `processes` — 연결 공정 배열 +- `photos` — 사진 파일 배열 + +--- + +#### `PUT /v1/equipment/{id}` — 설비 수정 + +Body는 등록과 동일 (변경할 필드만 전송 가능) + +--- + +#### `DELETE /v1/equipment/{id}` — 설비 삭제 (Soft Delete) + +--- + +#### `POST /v1/equipment/{id}/restore` — 삭제된 설비 복원 + +--- + +#### `PATCH /v1/equipment/{id}/toggle` — 활성/비활성 토글 + +`is_active` 값이 반전됨 + +--- + +### 3.2 점검 템플릿 (5개) + +#### `GET /v1/equipment/{id}/templates` — 활성 점검 주기 조회 + +**응답:** + +```json +{ + "data": ["daily", "weekly", "monthly"] +} +``` + +> 해당 설비에 점검항목이 등록된 주기 목록 반환 + +--- + +#### `POST /v1/equipment/{id}/templates` — 점검항목 등록 + +**Request Body:** + +| 필드 | 타입 | 필수 | 설명 | +|------|------|:----:|------| +| `inspection_cycle` | string | ✅ | 주기: `daily`/`weekly`/`monthly`/`bimonthly`/`quarterly`/`semiannual` | +| `item_no` | string | ✅ | 항목번호 | +| `check_point` | string | ✅ | 점검개소 (예: 겉모양) | +| `check_item` | string | ✅ | 점검항목 (예: 청결상태) | +| `check_timing` | string | — | 시기: `operating` / `stopped` | +| `check_frequency` | string | — | 주기 (예: 1회/일) | +| `check_method` | string | — | 점검방법 | +| `sort_order` | integer | — | 정렬순서 | + +--- + +#### `PUT /v1/equipment/templates/{templateId}` — 점검항목 수정 + +--- + +#### `DELETE /v1/equipment/templates/{templateId}` — 점검항목 삭제 + +--- + +#### `POST /v1/equipment/{id}/templates/copy` — 점검항목 다른 주기에 복사 + +**Request Body:** + +```json +{ + "source_cycle": "daily", + "target_cycles": ["weekly", "monthly"] +} +``` + +**응답:** + +```json +{ + "data": { + "copied": 5, + "skipped": 2, + "source_count": 7, + "target_cycles": ["weekly", "monthly"] + } +} +``` + +--- + +### 3.3 점검 (5개) — 가장 핵심 기능 + +#### `GET /v1/equipment/inspections` — 점검 그리드 데이터 + +**Query Parameters:** + +| 파라미터 | 타입 | 필수 | 기본값 | 설명 | +|----------|------|:----:|--------|------| +| `cycle` | string | — | `daily` | 점검주기 | +| `period` | string | — | 현재월 | daily: `YYYY-MM`, 그 외: `YYYY` | +| `production_line` | string | — | — | 생산라인 필터 | +| `equipment_id` | integer | — | — | 특정 설비만 | + +**응답 구조 (핵심):** + +```json +{ + "data": [ + { + "equipment": { + "id": 1, + "equipment_code": "KD-M-001", + "name": "포밍기#1" + }, + "templates": [ + { + "id": 10, + "item_no": "1", + "check_point": "겉모양", + "check_item": "청결상태", + "check_timing": "operating", + "check_method": "육안 확인" + } + ], + "inspection": { + "id": 5, + "overall_judgment": "OK", + "inspector_id": 1, + "repair_note": "", + "issue_note": "" + }, + "details": { + "10_2026-03-01": { "result": "good" }, + "10_2026-03-02": { "result": "bad" }, + "10_2026-03-03": { "result": null } + }, + "labels": { + "1": "1", "2": "2", "3": "3", ..., "31": "31" + }, + "can_inspect": true + } + ] +} +``` + +> **details 키 형식**: `{template_item_id}_{check_date}` +> **labels**: 그리드 열 헤더 (주기별로 다름) +> **can_inspect**: 현재 사용자가 이 설비를 점검할 권한이 있는지 + +--- + +#### `PATCH /v1/equipment/inspections/toggle` — 셀 클릭 (결과 순환) + +**Request Body:** + +```json +{ + "equipment_id": 1, + "template_item_id": 10, + "check_date": "2026-03-12", + "cycle": "daily" +} +``` + +**응답:** + +```json +{ + "data": { + "result": "good", + "symbol": "○" + } +} +``` + +**결과 순환 규칙:** + +``` +(빈칸) → good(○) → bad(X) → repaired(△) → (빈칸) → ... +``` + +--- + +#### `PATCH /v1/equipment/inspections/set-result` — 결과 직접 설정 + +toggle과 같은 Body + `result` 필드 추가 (`good` / `bad` / `repaired` / `null`) + +--- + +#### `PATCH /v1/equipment/inspections/notes` — 메모/판정 업데이트 + +**Request Body:** + +```json +{ + "equipment_id": 1, + "year_month": "2026-03", + "cycle": "daily", + "overall_judgment": "OK", + "inspector_id": 1, + "repair_note": "수리 사항...", + "issue_note": "이상 사항..." +} +``` + +--- + +#### `DELETE /v1/equipment/inspections/reset` — 점검 데이터 초기화 + +**Request Body:** + +```json +{ + "equipment_id": 1, + "cycle": "daily", + "period": "2026-03" +} +``` + +--- + +### 3.4 수리이력 (4개) + +#### `GET /v1/equipment/repairs` — 목록 (페이지네이션) + +**Query Parameters:** + +| 파라미터 | 타입 | 설명 | +|----------|------|------| +| `equipment_id` | integer | 설비 필터 | +| `repair_type` | string | `internal`(사내) / `external`(외주) | +| `date_from` | date | 수리일 시작 | +| `date_to` | date | 수리일 종료 | +| `search` | string | 설비명/수리내용 검색 | +| `per_page` | integer | 페이지당 개수 (기본 20) | + +--- + +#### `POST /v1/equipment/repairs` — 수리이력 등록 + +**Request Body:** + +| 필드 | 타입 | 필수 | 설명 | +|------|------|:----:|------| +| `equipment_id` | integer | ✅ | 설비 ID | +| `repair_date` | date | ✅ | 수리일 (YYYY-MM-DD) | +| `repair_type` | string | — | `internal`(사내) / `external`(외주) | +| `repair_hours` | number | — | 수리시간 (0.5 단위) | +| `description` | string | — | 수리내용 | +| `cost` | number | — | 수리비용 (원) | +| `vendor` | string | — | 외주업체 (repair_type=external 시) | +| `repaired_by` | integer | — | 수리자 ID | +| `memo` | string | — | 비고 | + +--- + +#### `PUT /v1/equipment/repairs/{id}` — 수정 + +#### `DELETE /v1/equipment/repairs/{id}` — 삭제 + +--- + +### 3.5 사진 (3개) + +#### `GET /v1/equipment/{id}/photos` — 사진 목록 + +#### `POST /v1/equipment/{id}/photos` — 사진 업로드 + +> 기존 파일 업로드 API(`/v1/file/upload`)를 사용하여 업로드한 후, 이 엔드포인트로 연결하는 방식. 상세 구현은 기존 파일 업로드 모듈 참고. + +#### `DELETE /v1/equipment/{id}/photos/{fileId}` — 사진 삭제 + +--- + +## 4. 화면별 구현 가이드 + +### 4.1 설비 목록 + +``` +┌────────────────────────────────────────────────────┐ +│ 설비 등록대장 [+ 설비 등록] │ +├────────────────────────────────────────────────────┤ +│ 필터: [검색] [상태 ▼] [라인 ▼] [유형 ▼] [검색] │ +├────────────────────────────────────────────────────┤ +│ 설비번호 │ 설비명 │ 유형 │ 라인 │ 상태 │ 담당자 │…│ +│ KD-M-001│ 포밍기 │포밍기│스라트│🟢가동│ 홍길동│…│ +│ KD-M-002│ 미싱기 │미싱기│스크린│🟡유휴│ 김철수│…│ +├────────────────────────────────────────────────────┤ +│ < 1 2 3 > │ +└────────────────────────────────────────────────────┘ +``` + +**테이블 컬럼:** + +| 컬럼 | 필드 | 정렬 | +|------|------|------| +| 설비번호 | `equipment_code` | center | +| 설비명 | `name` | left | +| 유형 | `equipment_type` | center | +| 위치 | `location` | center | +| 생산라인 | `production_line` | center | +| 상태 | `status` | center, Badge | +| 담당자 정 | `manager.name` | center | +| 담당자 부 | `sub_manager.name` | center | +| 구입일 | `purchase_date` | center | +| 액션 | — | 상세보기/수정/삭제 | + +**상태 Badge 색상:** + +| 상태 | 라벨 | 색상 | +|------|------|------| +| `active` | 가동 | 초록 | +| `idle` | 유휴 | 노랑 | +| `disposed` | 폐기 | 회색 | + +--- + +### 4.2 설비 등록/수정 폼 + +**4개 섹션:** + +1. **기본정보**: 설비코드*, 설비명*, 설비유형(select), 규격 +2. **제조사 정보**: 제조사, 모델명, 제조번호 +3. **설치 정보**: 위치, 생산라인(select), 구입일, 설치일, 구입가격, 내용연수 +4. **관리자/비고**: 담당자(select), 부담당자(select), 상태(select), 비고(textarea) + +**드롭다운 고정값:** + +``` +설비유형: 포밍기 / 미싱기 / 샤링기 / V컷팅기 / 절곡기 / 프레스 / 드릴 / 기타 +생산라인: 스라트 / 스크린 / 절곡 / 기타 +상태: 가동(active) / 유휴(idle) / 폐기(disposed) +``` + +> 담당자/부담당자 드롭다운은 사용자 API에서 동적 로드 + +**사진 관리 (수정 화면):** +- 설비 상세/수정 화면에서 사진 업로드/삭제 가능 +- 최대 10장 제한 + +--- + +### 4.3 설비 상세 (탭 3개) + +``` +← 뒤로 KD-M-001 포밍기#1 [🟢가동] [수정] +───────────────────────────────────────────── +[기본정보] [점검항목] [수리이력] +───────────────────────────────────────────── +``` + +**탭 1: 기본정보** +- 설비 상세 정보 (읽기 전용) +- 사진 갤러리 +- 연결된 공정 목록 + +**탭 2: 점검항목** +- 주기별 탭 (daily/weekly/monthly/bimonthly/quarterly/semiannual) +- 각 주기의 점검항목 테이블 (항목번호, 점검개소, 점검항목, 시기, 주기, 점검방법) +- 항목 추가/수정/삭제 기능 +- "다른 주기에 복사" 기능 + +**탭 3: 수리이력** +- 해당 설비의 수리이력 테이블 + +--- + +### 4.4 점검 그리드 (가장 복잡한 화면) + +``` +설비 점검표 +[일일] [주간] [월간] [2개월] [분기] [반기] ← 주기 탭 + +필터: [년월/연도] [라인 ▼] [설비 ▼] [조회] + +┌──────────┬──────────┬───┬───┬───┬───┬──────┐ +│ 설비 │ 점검항목 │ 1 │ 2 │ 3 │...│ 판정 │ +│(고정열) │(고정열) │(토)│(일)│(월)│ │ │ +├──────────┼──────────┼───┼───┼───┼───┼──────┤ +│ KD-M-001 │ 청결상태 │ — │ — │ ○ │ │ 합격 │ +│ 포밍기#1 │ 윤활상태 │ — │ — │ X │ │ │ +│(rowspan) │ 볼트이완 │ — │ — │ △ │ │ │ +├──────────┼──────────┼───┼───┼───┼───┼──────┤ +│ KD-M-002 │ 청결상태 │ — │ — │ ○ │ │ 합격 │ +└──────────┴──────────┴───┴───┴───┴───┴──────┘ +범례: ○ 양호 X 이상 △ 수리완료 ━ 비근무일 +``` + +**핵심 동작:** + +1. **셀 클릭**: `PATCH /inspections/toggle` 호출 → 결과 순환 (빈칸→○→X→△→빈칸) +2. **비근무일**: 주말(토/일) + holidays 테이블 등록 휴일 → 클릭 불가, 음영 처리 (daily만 적용) +3. **고정 열**: 설비/점검항목 열은 가로 스크롤 시 고정 (sticky) +4. **자동 판정**: 비근무일 제외, 모든 점검항목이 good 또는 repaired면 "합격" +5. **rowspan**: 동일 설비의 여러 점검항목은 설비명을 세로 병합 + +**주기별 그리드 열 구성:** + +| 주기 | period 형식 | 열 개수 | 열 라벨 | +|------|------------|---------|---------| +| daily | `YYYY-MM` | 28~31 | 1, 2, 3, ..., 31 (요일 표시) | +| weekly | `YYYY` | 52 | 1주, 2주, ..., 52주 | +| monthly | `YYYY` | 12 | 1월, 2월, ..., 12월 | +| bimonthly | `YYYY` | 6 | 1~2월, 3~4월, ..., 11~12월 | +| quarterly | `YYYY` | 4 | 1분기, 2분기, 3분기, 4분기 | +| semiannual | `YYYY` | 2 | 상반기, 하반기 | + +**점검 결과 심볼/색상:** + +| result | 심볼 | 색상 | +|--------|------|------| +| `good` | ○ | 초록 (`text-green-600`) | +| `bad` | X | 빨강 (`text-red-600`) | +| `repaired` | △ | 노랑 (`text-yellow-600`) | +| `null` | (빈칸) | — | + +--- + +### 4.5 수리이력 + +**목록 필터:** +- 검색 (설비명/수리내용) +- 설비 선택 (드롭다운) +- 보전구분 (`internal` 사내 / `external` 외주) +- 기간 (시작일 ~ 종료일) + +**테이블 컬럼:** + +| 컬럼 | 필드 | 형식 | +|------|------|------| +| 수리일 | `repair_date` | YYYY-MM-DD | +| 설비 | `equipment.name` | 텍스트 | +| 보전구분 | `repair_type` | Badge (사내: 파랑, 외주: 주황) | +| 수리시간 | `repair_hours` | "2h" 또는 "-" | +| 수리내용 | `description` | 텍스트 (40자 제한) | +| 비용 | `cost` | 통화 형식 (1,000,000원) | +| 외주업체 | `vendor` | 텍스트 또는 "-" | +| 액션 | — | 수정/삭제 | + +**등록 폼 특이사항:** +- `repair_type`이 `external`(외주)일 때만 `vendor`(외주업체) 필드 표시 +- `repair_hours`는 0.5 단위 입력 (step=0.5) + +--- + +### 4.6 대시보드 + +``` +┌────────────┬────────────┬────────────┬────────────┐ +│ 총 설비 │ 가동 중 │ 유휴 │ 폐기 │ +│ 12대 │ 10대 │ 2대 │ 0대 │ +└────────────┴────────────┴────────────┴────────────┘ + +┌──────────────────────────┬──────────────────────────┐ +│ 이번달 점검 현황 │ 설비 유형별 현황 │ +│ 점검 대상: 12대 │ 포밍기 ████████ 5 │ +│ 점검 완료: 8대 │ 절곡기 █████ 3 │ +│ 완료율: 66% [████░░] │ 미싱기 ███ 2 │ +│ 이상 발견: 2건 │ 기타 ██ 2 │ +└──────────────────────────┴──────────────────────────┘ + +┌────────────────────────────────────────────────────┐ +│ 최근 수리이력 [전체보기 →] │ +├─────────┬──────────┬──────────┬───────────┬────────┤ +│ 수리일 │ 설비 │ 보전구분 │ 수리내용 │ 비용 │ +│ 03-08 │ KD-M-01 │ 사내 │ 베어링 교체│ 50,000│ +└─────────┴──────────┴──────────┴───────────┴────────┘ +``` + +> `GET /v1/equipment/stats` 로 상단 4개 카드 데이터를 가져옴. +> 점검 현황과 유형별 차트는 stats 응답을 가공하여 표시. + +--- + +## 5. 비즈니스 규칙 + +### 5.1 점검 권한 + +- 관리자(admin): 모든 설비 점검 가능 +- 일반 사용자: 자신이 `manager_id` 또는 `sub_manager_id`인 설비만 점검 가능 +- `can_inspect` 플래그로 API가 알려줌 → false면 셀 클릭 비활성화 + +### 5.2 비근무일 제한 (daily만) + +- **일일 점검에서만** 주말(토/일) 및 등록된 휴일에 점검 기록 불가 +- 해당 셀은 음영 처리 + 클릭 비활성화 +- 그 외 주기(weekly/monthly 등)에는 제한 없음 + +### 5.3 점검 결과 순환 + +셀 클릭 시 결과가 순환: + +``` +(빈칸) → good(○) → bad(X) → repaired(△) → (빈칸) +``` + +### 5.4 자동 판정 + +- 도래한 날짜 중 비근무일 제외 +- 모든 항목-날짜 조합이 `good` 또는 `repaired` → **합격(OK)** +- 하나라도 `bad` 또는 미점검 → **불합격(NG)** + +### 5.5 설비 사진 + +- 최대 10장 +- GCS(Google Cloud Storage)에 저장 +- 기존 파일 업로드 모듈 사용 + +--- + +## 6. 공통 응답 포맷 + +모든 API 응답은 다음 구조를 따릅니다: + +```json +{ + "success": true, + "message": "성공/에러 메시지", + "data": { ... } +} +``` + +에러 시: + +```json +{ + "success": false, + "message": "에러 메시지", + "errors": { + "equipment_code": ["설비코드는 필수입니다."] + } +} +``` + +--- + +## 7. 참고 사항 + +### MNG R&D 화면 확인 + +개발서버 MNG에서 기존 구현을 확인할 수 있습니다: +- **URL**: `https://admin.codebridge-x.com/equipment` +- 대시보드, 등록대장, 점검 그리드, 수리이력 모두 동작하는 상태 + +### 개발서버 API 테스트 + +```bash +# 설비 목록 조회 예시 +curl -H "X-Api-Key: " \ + -H "Authorization: Bearer " \ + "https://api.dev.codebridge-x.com/api/v1/equipment?per_page=5" +``` + +### 구현 순서 제안 + +1. **1단계**: 설비 CRUD (목록 → 등록 → 상세 → 수정) — 기본 DataTable + 폼 +2. **2단계**: 수리이력 (목록 → 등록) — 1단계와 유사한 패턴 +3. **3단계**: 점검 그리드 — 가장 복잡, 동적 그리드 + 셀 토글 +4. **4단계**: 대시보드 — 통계 카드 + 간단한 차트 + +--- + +## 관련 문서 + +- [설비관리 기능 문서](../features/equipment/README.md) +- [서비스 구축 계획](../dev/dev_plans/equipment-service-build-plan.md) + +--- + +**최종 업데이트**: 2026-03-12