공사상세페이지 7단계 조건렌더링 재설계
공사상세페이지 7단계 조건렌더링 재설계
섹션 제목: “공사상세페이지 7단계 조건렌더링 재설계”[!note] 수정이력 | 2025-05-04, 분홍 (hermes)
- 상단 7단계 스텝퍼 구현 완료
- 하단을 단계별 조건렌더링으로 재설계 필요 (분홍아빠 요청)
- “다음단계” 버튼은 현재 단계 필수 조건 충족 시만 활성화
1. 현재 상태
섹션 제목: “1. 현재 상태”단계 흐름 (7단계)
섹션 제목: “단계 흐름 (7단계)”접수(발생) → 실사 → 설계 → 검토 → 진행 → 준공 → 완료기존 DB 모델
섹션 제목: “기존 DB 모델”| 테이블 | 용도 | 상태 |
|---|---|---|
projects | 공사 기본정보, current_stage | ✅ 유지 |
project_stage_logs | 단계변경 이력 | ✅ 유지 |
works | 작업관리 (진행단계용) | ✅ 유지 |
documents | 공가신청/해지 | ✅ 유지 |
ocr_uploads | OCR 자료반영 | ✅ 유지 |
material_inputs | 자재투입 | ✅ 유지 |
2. 단계별 데이터 모델 설계 (신규)
섹션 제목: “2. 단계별 데이터 모델 설계 (신규)”2.1 실사단계: inspection_photos 테이블
섹션 제목: “2.1 실사단계: inspection_photos 테이블”CREATE TABLE inspection_photos ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE, photo_type VARCHAR(20) NOT NULL, -- 'before', 'after', 'panorama', 'detail' file_path VARCHAR(500) NOT NULL, file_name VARCHAR(255), description TEXT, taken_at TIMESTAMP, uploaded_by UUID NOT NULL REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW());필수조건: photo_type=‘before’ 최소 1장 + photo_type=‘after’ 최소 1장
2.2 설계단계: design_documents 테이블
섹션 제목: “2.2 설계단계: design_documents 테이블”CREATE TABLE design_documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE, doc_category VARCHAR(30) NOT NULL, -- 'plan', 'drawing', 'calculation', 'approval' file_path VARCHAR(500), file_name VARCHAR(255), description TEXT, created_by UUID NOT NULL REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW());필수조건: doc_category=‘plan’ 최소 1개
2.3 검토단계: project_approvals 테이블
섹션 제목: “2.3 검토단계: project_approvals 테이블”CREATE TABLE project_approvals ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE, approval_date DATE NOT NULL, request_number VARCHAR(50), -- 공사요청번호 construction_number VARCHAR(50), -- 공사번호 approved_by UUID REFERENCES users(id), approval_note TEXT, created_at TIMESTAMP DEFAULT NOW());필수조건: approval_date + (request_number OR construction_number)
2.4 준공단계: completion_reports 테이블
섹션 제목: “2.4 준공단계: completion_reports 테이블”CREATE TABLE completion_reports ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE, report_type VARCHAR(30) NOT NULL, -- 'photo', 'document', 'checklist' file_path VARCHAR(500), file_name VARCHAR(255), description TEXT, created_by UUID NOT NULL REFERENCES users(id), created_at TIMESTAMP DEFAULT NOW());필수조건: 작업관리(works) 상태 ‘완료’ ≥ 1개
3. 단계전이(Transition) 규칙
섹션 제목: “3. 단계전이(Transition) 규칙”| 현재단계 | 다음단계 | 필수 조건 | 실패 시 메시지 |
|---|---|---|---|
| 접수 | 실사 | 공사기본정보 완료 (title, location) | “공사명과 위치를 입력하세요” |
| 실사 | 설계 | 실사사진 ≥ 2장 (before+after) | “실사 사진을 등록하세요 (현장전/후)“ |
| 설계 | 검토 | 설계자료 ≥ 1개 | ”설계 계획서를 등록하세요” |
| 검토 | 진행 | 승인일자 + 공사번호 입력 | ”승인 정보를 입력하세요” |
| 진행 | 준공 | 작업완료 ≥ 1개 | ”완료된 작업이 없습니다” |
| 준공 | 완료 | 준공자료 ≥ 1개 | ”준공 자료를 등록하세요” |
| 완료 | - | (마감) | - |
검토단계 상세
섹션 제목: “검토단계 상세”[검토자료 입력] → [승인] or [반려]→ 승인: 다음단계(진행) 버튼 활성화→ 반려: 설계단계로 롤백 + 반려사유 기록4. 프론트엔드 UI 규칙
섹션 제목: “4. 프론트엔드 UI 규칙”4.1 단계별 렌더링 매트릭스
섹션 제목: “4.1 단계별 렌더링 매트릭스”| 단계 | 공사정보 | 실사자료 | 설계자료 | 검토자료 | 작업관리 | 준공자료 | 자재요약 |
|---|---|---|---|---|---|---|---|
| 접수 | ✅편집 | ❌숨김 | ❌숨김 | ❌숨김 | ❌숨김 | ❌숨김 | ❌숨김 |
| 실사 | 🔒읽기 | ✅편집 | ❌숨김 | ❌숨김 | ❌숨김 | ❌숨김 | ❌숨김 |
| 설계 | 🔒읽기 | 🔒읽기 | ✅편집 | ❌숨김 | ❌숨김 | ❌숨김 | ❌숨김 |
| 검토 | 🔒읽기 | 🔒읽기 | 🔒읽기 | ✅편집 | ❌숨김 | ❌숨김 | ❌숨김 |
| 진행 | 🔒읽기 | 🔒읽기 | 🔒읽기 | 🔒읽기 | ✅편집 | ❌숨김 | ❌숨김 |
| 준공 | 🔒읽기 | 🔒읽기 | 🔒읽기 | 🔒읽기 | 🔒읽기 | ✅편집 | ❌숨김 |
| 완료 | 🔒읽기 | 🔒읽기 | 🔒읽기 | 🔒읽기 | 🔒읽기 | 🔒읽기 | ✅표시 |
4.2 단계별 컴포넌트 구조
섹션 제목: “4.2 단계별 컴포넌트 구조”<template> <div v-if="project"> <!-- 상단: 공사정보 + 스텝퍼 (모든 단계 공통) --> <ProjectHeader :project="project" /> <StageStepper :current="project.current_stage" />
<!-- 현재 단계의 활성 컴포넌트 --> <component :is="currentStageComponent" :project="project" />
<!-- 하단: 다음단계 버튼 --> <StageTransitionButton :current="project.current_stage" :validation="stageValidation" @advance="advanceStage" /> </div></template>4.3 단계별 컴포넌트 목록
섹션 제목: “4.3 단계별 컴포넌트 목록”| 컴포넌트 | 단계 | 설명 |
|---|---|---|
StageInfoEdit | 접수 | 공사정보 편집 (제목, 위치, 기간) |
StageInspection | 실사 | 사진등록 (before/after/panorama) |
StageDesign | 설계 | 설계파일 업로드 + 설계정보 |
StageReview | 검토 | 승인일자/공사번호 + 승인/반려 버튼 |
StageProgress | 진행 | 작업관리 (기존 works 재활용) |
StageCompletion | 준공 | 준공자료 + 작업완료 검토 |
StageDone | 완료 | 전체요약 + 자재요약 + 마감 |
4.4 “다음단계” 버튼 상태
섹션 제목: “4.4 “다음단계” 버튼 상태”const canAdvance = computed(() => { switch (project.current_stage) { case '접수': return !!project.title && !!project.location; case '실사': return inspectionPhotos.value.length >= 2; case '설계': return designDocs.value.length >= 1; case '검토': return !!approval.approval_date && (!!approval.request_number || !!approval.construction_number); case '진행': return completedWorks.value.length >= 1; case '준공': return completionReports.value.length >= 1; case '완료': return false; // 마지막 단계 default: return false; }});4.5 이전단계 데이터 읽기 전용 표시
섹션 제목: “4.5 이전단계 데이터 읽기 전용 표시”<!-- 실사단계일 때 --><StageInfoReadonly :project="project" /> <!-- 접수단계 데이터 읽기 --><StageInspectionEdit :project="project" /> <!-- 현재 활성 -->5. 백엔드 API 설계
섹션 제목: “5. 백엔드 API 설계”5.1 신규 엔드포인트
섹션 제목: “5.1 신규 엔드포인트”# 실사자료GET /api/projects/{id}/inspection-photosPOST /api/projects/{id}/inspection-photosDELETE /api/projects/{id}/inspection-photos/{photo_id}
# 설계자료GET /api/projects/{id}/design-documentsPOST /api/projects/{id}/design-documentsDELETE /api/projects/{id}/design-documents/{doc_id}
# 검토승인GET /api/projects/{id}/approvalsPOST /api/projects/{id}/approvalsPATCH /api/projects/{id}/approvals/{approval_id}
# 준공자료GET /api/projects/{id}/completion-reportsPOST /api/projects/{id}/completion-reportsDELETE /api/projects/{id}/completion-reports/{report_id}
# 단계전이POST /api/projects/{id}/advance-stageBODY: { "target_stage": "설계", "note": "실사 완료" }RESPONSE: { "success": true, "current_stage": "설계", "validation_passed": true }5.2 advance-stage 검증 로직
섹션 제목: “5.2 advance-stage 검증 로직”@router.post("/projects/{id}/advance-stage")async def advance_stage(project_id: UUID, req: AdvanceRequest, db: Session): project = get_project(project_id)
# 1. 현재 단계 확인 current = project.current_stage
# 2. 다음 단계 결정 target = get_next_stage(current) # 단계 흐름 정의
# 3. 필수조건 검증 validator = StageValidator(db, project) result = validator.validate_transition(current, target)
if not result.passed: raise HTTPException(400, detail=result.error_message)
# 4. 단계 전이 실행 project.current_stage = target db.add(ProjectStageLog(...)) db.commit()
return {"success": True, "stage": target}6. 구현 우선순위
섹션 제목: “6. 구현 우선순위”Phase 1: 프론트엔드 UI 구조 (빠른 프로토타입)
섹션 제목: “Phase 1: 프론트엔드 UI 구조 (빠른 프로토타입)”- 단계별 컴포넌트 7개 생성 (StageInfoEdit, StageInspection…)
- 조건렌더링 매트릭스 구현
- “다음단계” 버튼 + 검증 UI (mock 검증)
- 이전단계 읽기전용 표시
Phase 2: 백엔드 API + DB 마이그레이션
섹션 제목: “Phase 2: 백엔드 API + DB 마이그레이션”- Alembic 마이그레이션 (inspection_photos, design_documents, project_approvals, completion_reports)
- CRUD API 구현
- advance-stage API + 검증 로직
Phase 3: API 연동 + 통합테스트
섹션 제목: “Phase 3: API 연동 + 통합테스트”- 프론트엔드 ↔ 백엔드 API 연동
- 단계전이 end-to-end 테스트
- 에러 케이스 테스트 (조건 미충족 시)
Phase 4: 자재요약 + 완료단계
섹션 제목: “Phase 4: 자재요약 + 완료단계”- 자재투입 데이터 집계
- 완료단계 마감 UI
7. 특이사항
섹션 제목: “7. 특이사항”검토단계 복잡도
섹션 제목: “검토단계 복잡도”- 승인 → 진행단계 이동
- 반려 → 설계단계 롤백 + 사유 필수 입력
- 보류 → 현재 단계 유지
파일 저장
섹션 제목: “파일 저장”- NAS WebDAV 경로에 저장 (
/mnt/y/공사{project_id}/) - DB에는 파일 경로만 저장 (file_path)
- 각 단계별 담당팀/역할이 다름 (ProjectTypeStage.assigned_role 참조)
- 현재 단계의 담당자만 편집 가능, 다른 역할은 읽기만