검증완료율 표시 기능 구현 및 데이터 구조 개선

## 변경사항

### 1. 10-회의록상세조회.html
- 기본 노출 탭 주석 명확화
  - 유저스토리 UFR-MEET-047 요구사항 참조 주석 추가
  - 대시보드 탭이 기본 노출임을 명시

### 2. 12-회의록목록조회.html
- 검증완료율 표시 기능 구현
  - calculateCompletionRate() 함수를 사용한 실시간 계산
  - 작성중 상태 회의록에만 표시 (✓ XX% 검증완료)
  - 확정완료 상태는 검증완료율 미표시
- CSS 스타일 추가
  - .completion-rate 클래스: 녹색 배경 배지 스타일
  - 시각적으로 눈에 띄는 디자인 적용

### 3. common.js
- SAMPLE_MINUTES 데이터 구조 개선 (23개 회의록)
  - completionRate 필드 제거 (하드코딩된 값 삭제)
  - sections 필드를 숫자에서 객체 배열로 변경
    - 각 섹션: { id, title, verified } 구조
    - 다양한 검증 상태 시나리오 반영
- 검증완료율 계산 공통 함수 추가
  - calculateCompletionRate(minute) 함수 생성
  - 섹션별 검증 상태 기반 실시간 계산
  - JSDoc 주석 및 예제 포함
  - 안전한 에러 처리 (null 체크, 배열 검증)

## 산출 공식
검증완료율(%) = (검증완료된 섹션 수 / 전체 섹션 수) × 100

## 관련 이슈
- 요구사항설계검토-report-V1.1.md 이슈 #2 해결
- 유저스토리 UFR-MEET-046: 회의록목록조회 요구사항 반영

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yabo0812 2025-10-24 01:26:58 +09:00
parent af80fe8f52
commit 752d1c14cf
3 changed files with 177 additions and 36 deletions

View File

@ -948,7 +948,7 @@
</div>
</div>
<!-- 대시보드 탭 -->
<!-- 대시보드 탭 (기본 노출 탭 - 유저스토리 UFR-MEET-047 요구사항) -->
<div id="dashboard-content" class="tab-content active">
<!-- 핵심내용 -->
<div class="section dashboard-section">

View File

@ -368,6 +368,19 @@
color: var(--gray-500);
}
/* 검증완료율 표시 */
.completion-rate {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
background: rgba(77, 213, 167, 0.1);
color: var(--primary);
border-radius: 12px;
font-size: var(--font-small);
font-weight: var(--font-weight-medium);
}
/* 빈 상태 */
.empty-state {
text-align: center;
@ -592,7 +605,11 @@
'<span class="badge badge-complete">확정완료</span>' :
'<span class="badge badge-draft">작성중</span>';
const crownEmoji = isCreator ? '<span style="font-size: 16px; flex-shrink: 0;" title="생성자">👑</span>' : '';
const completionRate = minute.status === 'draft' ? `<span>${minute.completionRate}% 완료</span>` : '';
// 검증완료율 실시간 계산 (작성중 상태일 때만 표시)
const completionRate = minute.status === 'draft'
? `<span class="completion-rate">✓ ${calculateCompletionRate(minute)}% 검증완료</span>`
: '';
return `
<div class="meeting-item" data-status="${minute.status}" data-type="${participationType}" data-date="${minute.date}" onclick="navigateTo('10-회의록상세조회.html')">

View File

@ -140,8 +140,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 4,
lastUpdated: '2025-10-23',
completionRate: 75,
sections: 3,
sections: [
{ id: 'section-1', title: '신제품 기획 방향', verified: true },
{ id: 'section-2', title: '개발 일정 및 리소스', verified: true },
{ id: 'section-3', title: '마케팅 전략', verified: false }
],
todos: 5
},
{
@ -158,8 +161,10 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-21',
completionRate: 60,
sections: 2,
sections: [
{ id: 'section-1', title: '지난주 진행 사항', verified: true },
{ id: 'section-2', title: '이번주 계획', verified: false }
],
todos: 8
},
{
@ -175,7 +180,12 @@ const SAMPLE_MINUTES = [
],
participantCount: 2,
lastUpdated: '2025-10-23',
sections: 4,
sections: [
{ id: 'section-1', title: '현재 AI 모델 성능 분석', verified: true },
{ id: 'section-2', title: '개선 방향 논의', verified: true },
{ id: 'section-3', title: '기술 스택 검토', verified: true },
{ id: 'section-4', title: '일정 계획', verified: true }
],
todos: 3
},
{
@ -194,8 +204,13 @@ const SAMPLE_MINUTES = [
],
participantCount: 5,
lastUpdated: '2025-10-22',
completionRate: 50,
sections: 5,
sections: [
{ id: 'section-1', title: '현재 리소스 현황', verified: true },
{ id: 'section-2', title: '프로젝트 우선순위', verified: true },
{ id: 'section-3', title: '인력 배분 계획', verified: false },
{ id: 'section-4', title: '채용 계획', verified: true },
{ id: 'section-5', title: '일정 조정', verified: false }
],
todos: 7
},
{
@ -212,7 +227,13 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-18',
sections: 5,
sections: [
{ id: 'section-1', title: '현재 영업 현황', verified: true },
{ id: 'section-2', title: '타겟 고객 분석', verified: true },
{ id: 'section-3', title: '영업 전략 수립', verified: true },
{ id: 'section-4', title: '목표 설정', verified: true },
{ id: 'section-5', title: '실행 계획', verified: true }
],
todos: 6
},
{
@ -229,7 +250,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-20',
sections: 3,
sections: [
{ id: 'section-1', title: 'Keep (유지할 것)', verified: true },
{ id: 'section-2', title: 'Problem (문제점)', verified: true },
{ id: 'section-3', title: 'Try (시도할 것)', verified: true }
],
todos: 4
},
{
@ -247,8 +272,12 @@ const SAMPLE_MINUTES = [
],
participantCount: 4,
lastUpdated: '2025-10-19',
completionRate: 40,
sections: 4,
sections: [
{ id: 'section-1', title: '디자인 시스템 검토', verified: true },
{ id: 'section-2', title: '사용자 플로우 검증', verified: true },
{ id: 'section-3', title: '접근성 개선', verified: false },
{ id: 'section-4', title: '다음 스프린트 계획', verified: false }
],
todos: 5
},
{
@ -265,7 +294,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-20',
sections: 3,
sections: [
{ id: 'section-1', title: '경쟁사 A 분석', verified: true },
{ id: 'section-2', title: '경쟁사 B 분석', verified: true },
{ id: 'section-3', title: '차별화 전략', verified: true }
],
todos: 2
},
{
@ -281,8 +314,10 @@ const SAMPLE_MINUTES = [
],
participantCount: 2,
lastUpdated: '2025-10-18',
completionRate: 75,
sections: 2,
sections: [
{ id: 'section-1', title: '인터뷰 결과 요약', verified: true },
{ id: 'section-2', title: '다음 액션 아이템', verified: false }
],
todos: 4
},
{
@ -299,7 +334,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-17',
sections: 3,
sections: [
{ id: 'section-1', title: '보안 취약점 분석', verified: true },
{ id: 'section-2', title: '대응 방안', verified: true },
{ id: 'section-3', title: '후속 조치', verified: true }
],
todos: 5
},
{
@ -317,7 +356,12 @@ const SAMPLE_MINUTES = [
],
participantCount: 4,
lastUpdated: '2025-10-16',
sections: 4,
sections: [
{ id: 'section-1', title: '시장 분석', verified: true },
{ id: 'section-2', title: '타겟 고객층', verified: true },
{ id: 'section-3', title: '마케팅 채널 선정', verified: true },
{ id: 'section-4', title: '예산 계획', verified: true }
],
todos: 6
},
{
@ -337,8 +381,10 @@ const SAMPLE_MINUTES = [
],
participantCount: 6,
lastUpdated: '2025-10-15',
completionRate: 20,
sections: 2,
sections: [
{ id: 'section-1', title: '분기 성과 분석', verified: true },
{ id: 'section-2', title: '개선 계획', verified: false }
],
todos: 3
},
{
@ -357,7 +403,12 @@ const SAMPLE_MINUTES = [
],
participantCount: 5,
lastUpdated: '2025-10-14',
sections: 4,
sections: [
{ id: 'section-1', title: '프로젝트 목표', verified: true },
{ id: 'section-2', title: '역할 분담', verified: true },
{ id: 'section-3', title: '일정 계획', verified: true },
{ id: 'section-4', title: '리스크 관리', verified: true }
],
todos: 7
},
{
@ -374,7 +425,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-13',
sections: 3,
sections: [
{ id: 'section-1', title: '고객 피드백 분석', verified: true },
{ id: 'section-2', title: '개선 우선순위', verified: true },
{ id: 'section-3', title: '실행 계획', verified: true }
],
todos: 4
},
{
@ -392,8 +447,10 @@ const SAMPLE_MINUTES = [
],
participantCount: 4,
lastUpdated: '2025-10-12',
completionRate: 30,
sections: 2,
sections: [
{ id: 'section-1', title: '현재 기술 스택 검토', verified: true },
{ id: 'section-2', title: '새로운 기술 도입 검토', verified: false }
],
todos: 5
},
{
@ -414,7 +471,13 @@ const SAMPLE_MINUTES = [
],
participantCount: 7,
lastUpdated: '2025-10-11',
sections: 5,
sections: [
{ id: 'section-1', title: '이번 달 실적 요약', verified: true },
{ id: 'section-2', title: '주요 이슈 및 대응', verified: true },
{ id: 'section-3', title: '개선 사항', verified: true },
{ id: 'section-4', title: 'KPI 분석', verified: true },
{ id: 'section-5', title: '다음 달 계획', verified: true }
],
todos: 8
},
{
@ -431,7 +494,10 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-10',
sections: 2,
sections: [
{ id: 'section-1', title: '후보자 평가', verified: true },
{ id: 'section-2', title: '채용 결정', verified: true }
],
todos: 3
},
{
@ -450,8 +516,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 5,
lastUpdated: '2025-10-09',
completionRate: 50,
sections: 3,
sections: [
{ id: 'section-1', title: '협업 방안 논의', verified: true },
{ id: 'section-2', title: '계약 조건 검토', verified: false },
{ id: 'section-3', title: '일정 및 로드맵', verified: true }
],
todos: 6
},
{
@ -469,7 +538,12 @@ const SAMPLE_MINUTES = [
],
participantCount: 4,
lastUpdated: '2025-10-08',
sections: 4,
sections: [
{ id: 'section-1', title: '데이터 수집 현황', verified: true },
{ id: 'section-2', title: '분석 결과', verified: true },
{ id: 'section-3', title: '인사이트 도출', verified: true },
{ id: 'section-4', title: '액션 플랜', verified: true }
],
todos: 5
},
{
@ -489,7 +563,12 @@ const SAMPLE_MINUTES = [
],
participantCount: 6,
lastUpdated: '2025-10-07',
sections: 4,
sections: [
{ id: 'section-1', title: '현재 서비스 분석', verified: true },
{ id: 'section-2', title: '개선 아이디어 도출', verified: true },
{ id: 'section-3', title: '우선순위 결정', verified: true },
{ id: 'section-4', title: '실행 계획', verified: true }
],
todos: 7
},
{
@ -506,8 +585,10 @@ const SAMPLE_MINUTES = [
],
participantCount: 3,
lastUpdated: '2025-10-06',
completionRate: 65,
sections: 2,
sections: [
{ id: 'section-1', title: 'VOC 데이터 분석', verified: true },
{ id: 'section-2', title: '개선 방향', verified: false }
],
todos: 4
},
{
@ -529,7 +610,14 @@ const SAMPLE_MINUTES = [
],
participantCount: 8,
lastUpdated: '2025-10-05',
sections: 6,
sections: [
{ id: 'section-1', title: '연말 목표 설정', verified: true },
{ id: 'section-2', title: '예산 계획', verified: true },
{ id: 'section-3', title: '인력 계획', verified: true },
{ id: 'section-4', title: '프로젝트 우선순위', verified: true },
{ id: 'section-5', title: '리스크 관리', verified: true },
{ id: 'section-6', title: '실행 로드맵', verified: true }
],
todos: 10
},
{
@ -549,8 +637,11 @@ const SAMPLE_MINUTES = [
],
participantCount: 6,
lastUpdated: '2025-10-04',
completionRate: 45,
sections: 3,
sections: [
{ id: 'section-1', title: '현재 브랜드 분석', verified: true },
{ id: 'section-2', title: '리뉴얼 방향 논의', verified: false },
{ id: 'section-3', title: '타임라인 및 예산', verified: true }
],
todos: 5
},
{
@ -779,7 +870,40 @@ const SAMPLE_TODOS = [
];
// ========================================
// 2. DOM Utilities
// 2. Data Utilities
// ========================================
/**
* 회의록 검증완료율 계산
* @param {Object} minute - 회의록 객체 (sections 배열 포함)
* @returns {number} 검증완료율 (0-100)
*
* @example
* const minute = {
* sections: [
* { id: 'section-1', verified: true },
* { id: 'section-2', verified: false },
* { id: 'section-3', verified: true }
* ]
* };
* calculateCompletionRate(minute); // 67 (2/3 * 100)
*/
function calculateCompletionRate(minute) {
if (!minute || !minute.sections || !Array.isArray(minute.sections)) {
return 0;
}
const totalSections = minute.sections.length;
if (totalSections === 0) {
return 0;
}
const verifiedSections = minute.sections.filter(section => section.verified === true).length;
return Math.round((verifiedSections / totalSections) * 100);
}
// ========================================
// 3. DOM Utilities
// ========================================
/**