Todo 및 회의록 관련 요구사항 재정의 (v2.0.5 / v1.4.7)

[유저스토리 v2.0.5]
- UFR-TODO-040 (09-Todo관리): "Todo수정" → "Todo관리" 기능 확장
  - 통계 블록 재정의: 전체(미완료), 마감임박(3일 이내), 지연(기한 경과)
  - 필터링: 전체, 지연, 마감임박, 완료 (각 필터에 개수 표시)
  - 체크박스 확인 모달: 완료/미완료 전환 시 확인
  - 권한: 담당자 본인 OR 회의록 작성자만 편집 가능

- UFR-MEET-047 (10-회의록상세조회): 탭 순서 및 기본 노출 변경
  - 탭 구성: 대시보드 / 회의록
  - 기본 노출: 대시보드 탭 우선 노출

- UFR-MEET-055 (11-회의록수정): 진입 경로 및 권한 제어 명확화
  - 진입 경로: 10-회의록상세조회 → "수정" 버튼 클릭
  - 권한 제어: 검증완료 전(모든 참석자), 검증완료 후(회의 생성자만)
  - 회의 일시/장소: 읽기 전용 표시 명시

[화면설계서 v1.4.7]
- 09-Todo관리: 통계, 필터, 모달 UI/UX 재정의
- 10-회의록상세조회: 탭 순서 변경, 대시보드 탭 기본 활성
- 11-회의록수정: 진입 경로, 권한 제어, UI 구성 명확화

[프로토타입]
- 09-Todo관리.html: 통계 블록, 필터 개수, 체크박스 확인 모달 구현
- 10-회의록상세조회.html: 탭 순서 및 active 클래스 변경
- 11-회의록수정.html: 권한 코멘트, 읽기 전용 표시 추가

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yabo0812 2025-10-23 17:20:19 +09:00
parent 40f02d6d8e
commit bd6f2d5c45
6 changed files with 397 additions and 273 deletions

View File

@ -1,9 +0,0 @@
{
"permissions": {
"allow": [
"Bash(git commit:*)"
],
"deny": [],
"ask": []
}
}

View File

@ -88,27 +88,57 @@
margin-bottom: var(--space-md); margin-bottom: var(--space-md);
} }
/* 통계 카드 - 모바일에서 컴팩트하게 */ /* 통계 카드 - 정보 표시용 (인터랙션 없음) */
.stat-box { .stat-box {
min-height: 80px; min-height: 80px;
padding: var(--space-sm); padding: var(--space-sm);
background: var(--gray-100); /* 플랫한 배경 */
border: 1px solid var(--gray-200); /* 얇은 경계선 */
border-radius: var(--radius-md); /* 부드러운 모서리 */
box-shadow: none; /* 그림자 제거 */
transition: none; /* 호버 효과 제거 */
} }
.stat-box.highlight { /* 상태별 컬러 코딩 */
background: var(--primary-light); .stat-box.stat-incomplete {
border: 2px solid var(--primary); background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%); /* 차분한 블루 그라데이션 */
border-color: #90CAF9;
}
.stat-box.stat-urgent {
background: linear-gradient(135deg, #FFF3E0 0%, #FFE0B2 100%); /* 주의 오렌지 그라데이션 */
border-color: #FFB74D;
}
.stat-box.stat-overdue {
background: linear-gradient(135deg, #FFEBEE 0%, #FFCDD2 100%); /* 긴급 레드 그라데이션 */
border-color: #EF5350;
} }
.stat-number { .stat-number {
font-size: var(--font-h2); font-size: var(--font-h1); /* 더 크게 강조 */
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
color: var(--primary); line-height: 1.2;
margin-bottom: 2px; margin-bottom: 4px;
}
.stat-box.stat-incomplete .stat-number {
color: #1976D2; /* 진한 블루 */
}
.stat-box.stat-urgent .stat-number {
color: #F57C00; /* 진한 오렌지 */
}
.stat-box.stat-overdue .stat-number {
color: #D32F2F; /* 진한 레드 */
} }
.stat-text { .stat-text {
font-size: var(--font-caption); font-size: var(--font-caption);
color: var(--gray-700); color: var(--gray-600); /* 더 연하게 */
font-weight: var(--font-weight-regular); /* 보통 굵기 */
opacity: 0.85;
} }
/* 원형 진행 바 - 모바일에서 축소 */ /* 원형 진행 바 - 모바일에서 축소 */
@ -131,17 +161,17 @@
/* 데스크톱에서 통계 카드 크기 복원 */ /* 데스크톱에서 통계 카드 크기 복원 */
@media (min-width: 768px) { @media (min-width: 768px) {
.stat-box { .stat-box {
min-height: 100px; min-height: 110px;
padding: var(--space-md); padding: var(--space-lg);
} }
.stat-number { .stat-number {
font-size: var(--font-h1); font-size: 2.5rem; /* 더 큰 숫자 */
margin-bottom: var(--space-xs); margin-bottom: var(--space-xs);
} }
.stat-text { .stat-text {
font-size: var(--font-small); font-size: var(--font-body);
} }
.circular-progress { .circular-progress {
@ -227,23 +257,26 @@
border-color: var(--primary); border-color: var(--primary);
} }
/* Todo 카드 */ /* Todo 카드 - 컴팩트 디자인 */
.todo-card { .todo-card {
position: relative; position: relative;
background: var(--white); background: var(--white);
padding: var(--space-md); padding: var(--space-md);
border-radius: var(--radius-lg); border-radius: var(--radius-lg);
box-shadow: var(--shadow-md); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
margin-bottom: var(--space-md); margin-bottom: var(--space-sm);
transition: all var(--transition-normal); transition: all var(--transition-normal);
border: 1px solid var(--gray-200);
} }
.todo-card:hover { .todo-card:hover {
box-shadow: var(--shadow-lg); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
border-color: var(--primary);
} }
.todo-card.completed { .todo-card.completed {
opacity: 0.6; opacity: 0.5;
background: var(--gray-50);
} }
.todo-card.completed .todo-title { .todo-card.completed .todo-title {
@ -251,20 +284,22 @@
color: var(--gray-500); color: var(--gray-500);
} }
/* 레이아웃: 체크박스 + 콘텐츠 */
.todo-top { .todo-top {
display: flex; display: flex;
gap: var(--space-md); gap: var(--space-md);
margin-bottom: var(--space-md); align-items: flex-start;
} }
.todo-checkbox-wrapper { .todo-checkbox-wrapper {
flex-shrink: 0; flex-shrink: 0;
padding-top: 2px;
} }
.todo-checkbox { .todo-checkbox {
width: 24px; width: 24px;
height: 24px; height: 24px;
border: 2px solid var(--gray-300); border: 2px solid var(--gray-400);
border-radius: 6px; border-radius: 6px;
cursor: pointer; cursor: pointer;
transition: all var(--transition-fast); transition: all var(--transition-fast);
@ -277,41 +312,41 @@
.todo-content-wrapper { .todo-content-wrapper {
flex: 1; flex: 1;
min-width: 0; /* 텍스트 오버플로우 방지 */
} }
.todo-title { /* 배지 영역 */
font-size: var(--font-body);
font-weight: var(--font-weight-medium);
color: var(--gray-900);
margin-bottom: var(--space-sm);
}
.todo-badges { .todo-badges {
display: flex; display: flex;
gap: var(--space-sm); gap: var(--space-xs);
flex-wrap: wrap; flex-wrap: wrap;
margin-bottom: var(--space-sm); margin-bottom: var(--space-xs);
} }
/* Todo 제목 */
.todo-title {
font-size: var(--font-body);
font-weight: var(--font-weight-regular);
color: var(--gray-900);
margin-bottom: var(--space-xs);
line-height: 1.5;
}
/* 하단 메타 정보 */
.todo-meta-row { .todo-meta-row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--space-md); gap: var(--space-sm);
font-size: var(--font-small); font-size: var(--font-small);
color: var(--gray-500); color: var(--gray-500);
} flex-wrap: wrap;
.todo-assignee {
display: flex;
align-items: center;
gap: var(--space-sm);
} }
.todo-meeting-link { .todo-meeting-link {
display: flex; display: inline-flex;
align-items: center; align-items: center;
gap: var(--space-xs); gap: 4px;
color: var(--primary); color: #4CAF50; /* 연한 초록색 */
text-decoration: none; text-decoration: none;
font-size: var(--font-small); font-size: var(--font-small);
cursor: pointer; cursor: pointer;
@ -319,19 +354,47 @@
} }
.todo-meeting-link:hover { .todo-meeting-link:hover {
color: var(--primary-dark); color: #388E3C;
text-decoration: underline;
} }
.todo-progress-section { /* 담당자 정보 숨김 (간결한 디자인) */
margin-top: var(--space-md); .todo-assignee {
padding-top: var(--space-md); display: none;
border-top: 1px solid var(--gray-300);
} }
.todo-progress-label { /* 액션 버튼 영역 */
font-size: var(--font-small); .todo-actions {
color: var(--gray-700); margin-top: var(--space-xs);
margin-bottom: var(--space-sm); }
/* 아이콘 버튼 */
.icon-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
background: none;
border: none;
border-radius: var(--radius-md);
color: var(--gray-600);
cursor: pointer;
transition: all var(--transition-fast);
}
.icon-btn:hover {
background: var(--gray-100);
color: var(--primary);
}
.icon-btn:active {
background: var(--gray-200);
}
.icon-btn .material-icons {
font-size: 20px;
} }
/* 빈 상태 */ /* 빈 상태 */
@ -463,44 +526,33 @@
<main class="main-content"> <main class="main-content">
<!-- 통계 개요 --> <!-- 통계 개요 -->
<div class="stats-overview"> <div class="stats-overview">
<div class="stat-box"> <div class="stat-box stat-incomplete">
<div class="stat-number" id="totalTodos">0</div> <div class="stat-number" id="totalTodos">0</div>
<div class="stat-text">전체</div> <div class="stat-text">미완료</div>
</div> </div>
<div class="stat-box highlight"> <div class="stat-box stat-urgent">
<div class="circular-progress"> <div class="stat-number" id="urgentTodos">0</div>
<svg viewBox="0 0 80 80">
<circle class="bg-circle" cx="40" cy="40" r="36"></circle>
<circle class="progress-circle" cx="40" cy="40" r="36"
stroke-dasharray="226" stroke-dashoffset="226" id="progressCircle"></circle>
</svg>
<div class="circular-progress-text" id="completionRate">0%</div>
</div>
<div class="stat-text">완료율</div>
</div>
<div class="stat-box">
<div class="stat-number" id="inProgressTodos">0</div>
<div class="stat-text">진행 중</div>
</div>
<div class="stat-box">
<div class="stat-number text-error" id="urgentTodos">0</div>
<div class="stat-text">마감 임박</div> <div class="stat-text">마감 임박</div>
</div> </div>
<div class="stat-box stat-overdue">
<div class="stat-number" id="overdueTodos">0</div>
<div class="stat-text">지연</div>
</div>
</div> </div>
<!-- 필터 탭 --> <!-- 필터 탭 -->
<div class="filter-tabs"> <div class="filter-tabs">
<button class="filter-tab active" data-filter="all" onclick="filterTodos('all')"> <button class="filter-tab active" data-filter="all" onclick="filterTodos('all')">
전체 전체 (<span id="filterAllCount">0</span>)
</button> </button>
<button class="filter-tab" data-filter="in_progress" onclick="filterTodos('in_progress')"> <button class="filter-tab" data-filter="overdue" onclick="filterTodos('overdue')">
진행 중 지연 (<span id="filterOverdueCount">0</span>)
</button>
<button class="filter-tab" data-filter="completed" onclick="filterTodos('completed')">
완료
</button> </button>
<button class="filter-tab" data-filter="urgent" onclick="filterTodos('urgent')"> <button class="filter-tab" data-filter="urgent" onclick="filterTodos('urgent')">
마감 임박 마감 임박 (<span id="filterUrgentCount">0</span>)
</button>
<button class="filter-tab" data-filter="completed" onclick="filterTodos('completed')">
완료 (<span id="filterCompletedCount">0</span>)
</button> </button>
</div> </div>
@ -623,28 +675,27 @@
// 통계 업데이트 // 통계 업데이트
function updateStats() { function updateStats() {
const total = allTodos.length; const total = allTodos.filter(t => t.status !== 'completed').length; // 미완료 전체
const completed = allTodos.filter(t => t.status === 'completed').length; const completed = allTodos.filter(t => t.status === 'completed').length;
const inProgress = allTodos.filter(t => t.status === 'in_progress').length;
const urgent = allTodos.filter(t => { const urgent = allTodos.filter(t => {
const dday = calculateDday(t.dueDate); const dday = calculateDday(t.dueDate);
return dday >= 0 && dday <= 3 && t.status !== 'completed'; return dday >= 0 && dday <= 3 && t.status !== 'completed';
}).length; }).length;
const overdue = allTodos.filter(t => {
const dday = calculateDday(t.dueDate);
return dday < 0 && t.status !== 'completed';
}).length;
// 카운터 애니메이션 // 상단 통계 블록 카운터 애니메이션
animateCounter('totalTodos', total); animateCounter('totalTodos', total);
animateCounter('inProgressTodos', inProgress);
animateCounter('urgentTodos', urgent); animateCounter('urgentTodos', urgent);
animateCounter('overdueTodos', overdue);
// 완료율 원형 진행 바 // 필터 탭 개수 업데이트
const completionRate = total > 0 ? Math.round((completed / total) * 100) : 0; $('#filterAllCount').textContent = allTodos.length;
const circumference = 226; $('#filterOverdueCount').textContent = overdue;
const offset = circumference - (completionRate / 100 * circumference); $('#filterUrgentCount').textContent = urgent;
$('#filterCompletedCount').textContent = completed;
setTimeout(() => {
$('#progressCircle').style.strokeDashoffset = offset;
$('#completionRate').textContent = `${completionRate}%`;
}, 100);
} }
// Todo 리스트 렌더링 // Todo 리스트 렌더링
@ -655,8 +706,11 @@
// 필터 적용 // 필터 적용
if (currentFilter === 'completed') { if (currentFilter === 'completed') {
filteredTodos = allTodos.filter(t => t.status === 'completed'); filteredTodos = allTodos.filter(t => t.status === 'completed');
} else if (currentFilter === 'in_progress') { } else if (currentFilter === 'overdue') {
filteredTodos = allTodos.filter(t => t.status === 'in_progress'); filteredTodos = allTodos.filter(t => {
const dday = calculateDday(t.dueDate);
return dday < 0 && t.status !== 'completed';
});
} else if (currentFilter === 'urgent') { } else if (currentFilter === 'urgent') {
filteredTodos = allTodos.filter(t => { filteredTodos = allTodos.filter(t => {
const dday = calculateDday(t.dueDate); const dday = calculateDday(t.dueDate);
@ -702,7 +756,6 @@
onchange="toggleTodoComplete('${todo.id}', this.checked)"> onchange="toggleTodoComplete('${todo.id}', this.checked)">
</div> </div>
<div class="todo-content-wrapper"> <div class="todo-content-wrapper">
<div class="todo-title">${todo.title}</div>
<div class="todo-badges"> <div class="todo-badges">
${createBadge(statusInfo.badgeText, statusInfo.badgeType)} ${createBadge(statusInfo.badgeText, statusInfo.badgeType)}
${createBadge( ${createBadge(
@ -711,28 +764,17 @@
todo.priority todo.priority
)} )}
</div> </div>
<div class="todo-title">${todo.title}</div>
<div class="todo-meta-row"> <div class="todo-meta-row">
<div class="todo-assignee"> <a class="todo-meeting-link" onclick="goToMeeting('${todo.meetingId}')">
${createAvatar(todo.assignee, 'sm')} 🔗 ${todo.meetingTitle}
<span>${todo.assignee.name}</span> </a>
</div>
<span></span>
<span>${formatDate(todo.dueDate)}</span> <span>${formatDate(todo.dueDate)}</span>
</div> </div>
<a class="todo-meeting-link" onclick="goToMeeting('${todo.meetingId}')">
🔗 ${todo.meetingTitle}
</a>
${!isCompleted && todo.progress > 0 ? `
<div class="todo-progress-section">
<div class="todo-progress-label">진행률: ${todo.progress}%</div>
${createProgressBar(todo.progress)}
</div>
` : ''}
${!isCompleted ? ` ${!isCompleted ? `
<div class="todo-actions"> <div class="todo-actions">
<button class="btn btn-ghost btn-sm" onclick="editTodo('${todo.id}')"> <button class="icon-btn" onclick="editTodo('${todo.id}')" title="편집">
<span class="material-icons" style="font-size: 16px;">edit</span> <span class="material-icons">edit</span>
편집
</button> </button>
</div> </div>
` : ''} ` : ''}
@ -760,11 +802,11 @@
// Todo 완료 토글 // Todo 완료 토글
function toggleTodoComplete(todoId, isChecked) { function toggleTodoComplete(todoId, isChecked) {
if (isChecked) { if (isChecked) {
if (confirm('이 Todo를 완료 처리하시겠습니까?')) { // 완료 처리
if (confirm('완료 처리하시겠습니까?')) {
const todo = allTodos.find(t => t.id === todoId); const todo = allTodos.find(t => t.id === todoId);
if (todo) { if (todo) {
todo.status = 'completed'; todo.status = 'completed';
todo.progress = 100;
showToast('Todo가 완료되었습니다', 'success'); showToast('Todo가 완료되었습니다', 'success');
updateStats(); updateStats();
renderTodoList(); renderTodoList();
@ -773,11 +815,17 @@
event.target.checked = false; event.target.checked = false;
} }
} else { } else {
const todo = allTodos.find(t => t.id === todoId); // 미완료로 되돌리기
if (todo) { if (confirm('미완료로 변경하시겠습니까?')) {
todo.status = 'in_progress'; const todo = allTodos.find(t => t.id === todoId);
updateStats(); if (todo) {
renderTodoList(); todo.status = 'incomplete';
showToast('미완료로 변경되었습니다', 'info');
updateStats();
renderTodoList();
}
} else {
event.target.checked = true;
} }
} }
} }

View File

@ -591,8 +591,8 @@
<!-- 탭 네비게이션 --> <!-- 탭 네비게이션 -->
<nav class="tab-nav"> <nav class="tab-nav">
<div class="tabs"> <div class="tabs">
<div class="tab active" data-tab="minutes">회의록</div> <div class="tab active" data-tab="dashboard">대시보드</div>
<div class="tab" data-tab="dashboard">대시보드</div> <div class="tab" data-tab="minutes">회의록</div>
</div> </div>
</nav> </nav>
@ -642,7 +642,7 @@
</div> </div>
<!-- 회의록 탭 --> <!-- 회의록 탭 -->
<div id="minutes-content" class="tab-content active"> <div id="minutes-content" class="tab-content">
<!-- 안건 1 --> <!-- 안건 1 -->
<div class="section"> <div class="section">
<div class="section-header"> <div class="section-header">
@ -826,7 +826,7 @@
</div> </div>
<!-- 대시보드 탭 --> <!-- 대시보드 탭 -->
<div id="dashboard-content" class="tab-content"> <div id="dashboard-content" class="tab-content active">
<!-- 핵심내용 --> <!-- 핵심내용 -->
<div class="section dashboard-section"> <div class="section dashboard-section">
<div class="section-header"> <div class="section-header">

View File

@ -249,6 +249,17 @@
</style> </style>
</head> </head>
<body> <body>
<!--
[진입 경로]
10-회의록상세조회.html → 하단 액션 바 "수정" 버튼 클릭
[권한 제어]
- 검증완료 전 (작성중/초안 상태): 모든 참석자가 수정 가능
- 검증완료 후: 회의 생성자만 수정 가능 (참석자는 "수정" 버튼 비활성화)
- 참석자 관리: 회의 생성자만 추가/삭제 가능
- 회의 일시/장소: 읽기 전용 (회의 예약 화면에서만 변경 가능)
-->
<!-- 헤더 --> <!-- 헤더 -->
<header class="header"> <header class="header">
<div class="header-left"> <div class="header-left">
@ -267,6 +278,7 @@
<main class="main-content"> <main class="main-content">
<!-- 기본 정보 --> <!-- 기본 정보 -->
<div class="info-card"> <div class="info-card">
<!-- 회의 제목 (편집 가능) -->
<input <input
type="text" type="text"
class="meeting-title-input" class="meeting-title-input"
@ -274,13 +286,17 @@
placeholder="회의 제목을 입력하세요" placeholder="회의 제목을 입력하세요"
oninput="markAsUnsaved()" oninput="markAsUnsaved()"
> >
<!-- 회의 일시 (읽기 전용 - 회의 예약 화면에서만 변경 가능) -->
<div class="info-row"> <div class="info-row">
<span class="info-icon">📅</span> <span class="info-icon">📅</span>
<span>2025년 10월 25일 14:00 (90분)</span> <span>2025년 10월 25일 14:00 (90분)</span>
<span class="text-caption text-muted" style="margin-left: 8px;">(읽기 전용)</span>
</div> </div>
<!-- 회의 장소 (읽기 전용 - 회의 예약 화면에서만 변경 가능) -->
<div class="info-row"> <div class="info-row">
<span class="info-icon">📍</span> <span class="info-icon">📍</span>
<span>본사 2층 대회의실</span> <span>본사 2층 대회의실</span>
<span class="text-caption text-muted" style="margin-left: 8px;">(읽기 전용)</span>
</div> </div>
<div class="info-row"> <div class="info-row">
<span class="info-icon"></span> <span class="info-icon"></span>

View File

@ -4,7 +4,7 @@
- **작성일**: 2025-10-21 - **작성일**: 2025-10-21
- **최종 수정일**: 2025-10-23 - **최종 수정일**: 2025-10-23
- **작성자**: 이미준 (서비스 기획자) - **작성자**: 이미준 (서비스 기획자)
- **버전**: 1.4.4 - **버전**: 1.4.7
- **설계 철학**: Mobile First Design - **설계 철학**: Mobile First Design
--- ---
@ -1099,106 +1099,116 @@ graph TD
### 09-Todo관리 ### 09-Todo관리
#### 개요 #### 개요
- **목적**: 할당된 Todo 목록 조회 및 진행 상황 관리 - **목적**: 나의 Todo(내가 담당자인 Todo) 조회 및 관리
- **관련 유저스토리**: UFR-TODO-010, UFR-TODO-030, **UFR-TODO-040 (Todo 수정)** - **관련 유저스토리**: UFR-TODO-040 (Todo 관리)
- **비즈니스 중요도**: 높음 - **비즈니스 중요도**: 높음
- **접근 경로**: 대시보드 → 하단 네비게이션 "Todo" 또는 대시보드 "내 Todo" 카드 → "전체 보기" - **접근 경로**: 대시보드 → 하단 네비게이션 "Todo" 또는 대시보드 "내 Todo" 카드 → "전체 보기"
- **대전제**:
- Todo의 상태는 완료/미완료만 존재
- 09-Todo관리 화면에서는 나의 Todo(내가 담당자인 Todo)만 표시
#### 주요 기능 #### 주요 기능
1. Todo 목록 표시 (상태별 필터링) 1. 나의 Todo 목록 표시 (필터링)
2. **Todo 수정 (UFR-TODO-040)** - 신규 추가 2. Todo 완료/미완료 상태 변경
3. Todo 완료 처리 3. Todo 편집 (모달)
4. 회의록 원문으로 이동 (양방향 연결) 4. 회의록 상세로 이동 (양방향 연결)
5. Todo 진행 상황 통계 5. Todo 통계 (전체, 마감임박, 지연)
6. 마감 임박 Todo 알림
#### UI 구성요소 #### UI 구성요소
**Mobile (320px~768px)** **Mobile (320px~768px)**
- **헤더** - **헤더**
- "Todo" 타이틀 - "Todo 관리" 타이틀
- 필터 버튼 (상태별) - 프로필 아이콘 (모바일)
- **통계 카드** - **상단 통계 블록** (4개 블록)
- 전체 Todo 개수 - **전체**: 미완료 전체 개수
- 완료율 (원형 진행 바) - **마감임박**: 기한 3일 이내 미완료 개수 (강조 스타일)
- 마감 임박 Todo 개수 (배지) - **지연**: 기한이 지난 미완료 개수
- **필터 탭** - **필터 탭**
- 전체, 진행 중, 완료, 마감 임박 - **전체 (개수)**: 완료/미완료 전체
- **지연 (개수)**: 기한이 지난 미완료
- **마감임박 (개수)**: 기한 3일 이내 미완료
- **완료 (개수)**: 완료된 Todo
- **Todo 리스트** - **Todo 리스트 블록**
- 각 Todo 카드: - **정렬**: 미완료 → 완료 순서, 기한일 오래된 순 (복합 정렬)
- 체크박스 (완료 처리) - **각 Todo 카드** (블록 형태):
- Todo 내용 - **체크박스** (완료/미완료 토글, 액션 가능 표시)
- 마감일 (색상 코딩: 초록-여유, 노랑-임박, 빨강-지연) - **Todo 제목**
- 우선순위 배지 (높음/보통/낮음) - **상태 뱃지**: D+n(지연) / D-day / D-n / 완료
- 관련 회의록 링크 아이콘 - **우선순위 뱃지**: 높음(빨강) / 보통(노랑) / 낮음(회색)
- **"편집" 버튼** (본인 담당 Todo만 표시) - 신규 - **기한**
- 스와이프 액션: 수정, 삭제 - **회의록 제목 + 링크** (클릭 시 10-회의록상세조회 대시보드 탭으로 이동)
- **편집 버튼** (권한 있는 경우에만 노출, 액션 가능 표시)
- **FAB** (Floating Action Button) - **페이징**: 최초 10건 노출, 10건 이상일 경우 하단에 "10개 더보기" 버튼
- "Todo 추가" (수동 추가)
**Tablet/Desktop (768px+)** **Tablet/Desktop (768px+)**
- 좌측: Todo 리스트 - 좌측 사이드바 + 메인 콘텐츠 영역
- 우측: 선택된 Todo 상세 정보 - 통계 블록 4개 가로 배치
- Todo 내용 - Todo 리스트 그리드 레이아웃 (2열)
- 담당자
- 마감일
- 우선순위
- 관련 회의록 섹션 (임베디드 뷰)
- 진행 메모 (추가 가능)
#### 인터랙션 #### 인터랙션
1. **Todo 수정 (UFR-TODO-040)** - 신규 추가 1. **Todo 완료/미완료 상태 변경**
- **편집 버튼 클릭**: - **체크박스 클릭**:
- 인라인 편집 모드로 전환 또는 수정 모달 표시 - 완료 처리 시: "완료 처리하시겠습니까?" 확인 모달
- **수정 가능 항목** (담당자 권한): - 미완료로 되돌릴 때: "미완료로 변경하시겠습니까?" 확인 모달
- ✏️ Todo 제목 (문구) - 확인 시: 상태 업데이트, 통계 갱신, 리스트 재정렬
- 📅 마감일 (날짜 선택기) - 취소 시: 이전 상태 유지
- 🎯 우선순위 (high/medium/low 드롭다운)
- ❌ 담당자 변경 불가 (본인 담당 Todo) 2. **Todo 편집 (UFR-TODO-040)**
- **저장 버튼**: 수정 완료 - **편집 버튼 클릭** (권한: 담당자 본인 OR 회의 생성자):
- **취소 버튼**: 편집 모드 취소 - 편집 모달 표시
- **수정 완료 시**: - **모바일**: 바텀시트 형식
- **데스크톱**: 중앙 모달
- **수정 가능 항목**:
- ✏️ Todo 제목 (input, 필수)
- 👤 담당자 (select, 회의록 참석자 중 선택) - **회의 생성자만 변경 가능**
- 📅 마감일 (날짜 선택기, 필수)
- 🎯 우선순위 (높음/보통/낮음 select, 필수)
- **권한 표시**:
- 담당자 본인: "본인에게 할당된 Todo만 수정할 수 있습니다. 담당자는 변경할 수 없습니다."
- 회의 생성자: "회의 생성자로서 모든 항목을 수정할 수 있습니다. 담당자 변경 시 알림이 전송됩니다."
- **저장 버튼 클릭**:
- 유효성 검사 (제목, 마감일 필수)
- "Todo가 수정되었습니다" 토스트 메시지 - "Todo가 수정되었습니다" 토스트 메시지
- 회의록에 수정 내용 실시간 반영 - 회의록에 수정 내용 실시간 반영
- 마감일 변경 시 캘린더 자동 업데이트 - 담당자 변경 시: 이전/새 담당자에게 알림 발송
- **권한 제어**: - 마감일 변경 시: 캘린더 자동 업데이트
- 본인에게 할당된 Todo만 편집 버튼 표시 - **취소 버튼**: 모달 닫기, 변경 사항 취소
- 다른 사람의 Todo는 조회만 가능 (편집 버튼 숨김)
2. **Todo 완료 처리** 3. **회의록 링크 클릭**
- 체크박스 클릭: - 10-회의록상세조회 화면으로 이동
- 확인 다이얼로그 ("완료 처리하시겠습니까?") - **대시보드 탭이 우선 노출**
- 완료 시: 체크 애니메이션, 회의록에 실시간 반영
- 완료 Todo는 리스트 하단으로 이동 (취소선)
3. **회의록 연결** 4. **필터 탭 클릭**
- 회의록 링크 아이콘 클릭: - 선택한 필터 기준으로 Todo 목록 갱신
- 회의록상세조회 화면으로 이동 - 활성 탭 강조 표시
- 해당 Todo가 언급된 섹션으로 자동 스크롤
- 하이라이트 효과
4. **필터링** 5. **10개 더보기 버튼**
- 필터 탭 클릭: 해당 상태의 Todo만 표시 - 클릭 시 하단에 10건씩 추가 로드
- 마감 임박: 3일 이내 마감 Todo - 페이지 새로고침 없이 무한 스크롤 방식
5. **수동 추가** #### 디자인 요구사항
- FAB 클릭: Todo 추가 모달 - **액션 블록 vs 정보 블록 차별화**:
- 내용, 마감일, 우선순위 입력 - 액션 가능 (체크박스, 편집 버튼): 호버 시 배경색 변경, 그림자 효과
- 정보 표시 (상태 뱃지, 우선순위, 기한): 정적 표시, 호버 효과 없음
- **모바일 최적화**:
- 바텀시트 편집 모달 (전체 화면 X)
- 터치 영역 최소 44px × 44px
#### 데이터 요구사항 #### 데이터 요구사항
- **입력**: 사용자 ID - **입력**: 사용자 ID (내가 담당자인 Todo만 조회)
- **출력**: - **출력**:
- Todo 목록 (상태, 내용, 담당자, 마감일, 우선순위, 회의록 링크) - Todo 목록 (제목, 상태, 담당자, 마감일, 우선순위, 회의록 제목, 회의록 ID)
- Todo 통계 (전체, 완료, 진행 중) - Todo 통계 (전체, 마감임박, 지연, 완료)
- **연동**: Todo 서비스, Meeting 서비스 - **연동**: Meeting 서비스 (Todo 관리 통합)
#### 에러 처리 #### 에러 처리
- **Todo 로딩 실패**: "Todo 목록을 불러올 수 없습니다" + 재시도 버튼 - **Todo 로딩 실패**: "Todo 목록을 불러올 수 없습니다" + 재시도 버튼
- **완료 처리 실패**: "완료 처리에 실패했습니다. 다시 시도해주세요" - **상태 변경 실패**: "상태 변경에 실패했습니다. 다시 시도해주세요"
- **편집 저장 실패**: "저장에 실패했습니다. 다시 시도해주세요"
- **빈 상태**: "할당된 Todo가 없습니다. 새 회의를 시작해보세요!" - **빈 상태**: "할당된 Todo가 없습니다. 새 회의를 시작해보세요!"
--- ---
@ -1236,8 +1246,8 @@ graph TD
- 작성자 및 최종 수정 시간 - 작성자 및 최종 수정 시간
- **탭 네비게이션** (상단, Fixed) - **탭 네비게이션** (상단, Fixed)
- "회의록" 탭 (기본 활성) - "대시보드" 탭 (기본 활성)
- "대시보드" 탭 - "회의록" 탭
- **회의록 탭 콘텐츠** (섹션별 구조) - **회의록 탭 콘텐츠** (섹션별 구조)
- 각 섹션: - 각 섹션:
@ -1300,8 +1310,8 @@ graph TD
**Tablet/Desktop (768px+)** **Tablet/Desktop (768px+)**
- **상단**: 탭 네비게이션 - **상단**: 탭 네비게이션
- 회의록 (기본) - 대시보드 (기본 활성)
- 대시보드 - 회의록
- **메인 영역**: - **메인 영역**:
- 회의록 탭: 전체 회의록 내용 (섹션별 구조) - 회의록 탭: 전체 회의록 내용 (섹션별 구조)
- 대시보드 탭: 핵심내용, 결정사항, Todo 진행상황, 참고자료 (11-회의록대시보드.html 구조 참조) - 대시보드 탭: 핵심내용, 결정사항, Todo 진행상황, 참고자료 (11-회의록대시보드.html 구조 참조)
@ -1389,42 +1399,45 @@ graph TD
- **목적**: 지난 회의록 조회 및 수정 - **목적**: 지난 회의록 조회 및 수정
- **관련 유저스토리**: UFR-MEET-055, UFR-AI-040, **UFR-TODO-040 (Todo 수정)** - **관련 유저스토리**: UFR-MEET-055, UFR-AI-040, **UFR-TODO-040 (Todo 수정)**
- **비즈니스 중요도**: 중간 - **비즈니스 중요도**: 중간
- **접근 경로**: 대시보드 → "내 회의록" → 회의록상세조회 → "수정" - **접근 경로**: 10-회의록상세조회 → 하단 액션 바 "수정" 버튼 클릭
- **권한 제어**:
- **검증완료 전**: 모든 참석자가 수정 가능
- **검증완료 후**: 회의 생성자만 수정 가능 (참석자는 "수정" 버튼 비활성화)
#### 주요 기능 #### 주요 기능
1. 회의록 목록 조회 (필터링, 정렬, 검색) 1. 회의 기본 정보 표시 및 수정
- 회의 제목: 수정 가능
- 회의 일시/장소: 읽기 전용 (회의 예약 화면에서만 변경 가능)
- 참석자 관리: 회의 생성자만 추가/삭제 가능
2. 회의록 내용 수정 (섹션별) 2. 회의록 내용 수정 (섹션별)
3. **AI 요약 수정** (섹션별) 3. **AI 요약 수정** (섹션별)
4. **참고자료 편집** (추가/제거) 4. **참고자료 편집** (추가/제거)
5. **Todo 수정 (UFR-TODO-040)** - 신규 추가 (회의 생성자만) 5. **Todo 수정 (UFR-TODO-040)** - 신규 추가 (회의 생성자만)
6. 자동 저장 (30초 간격) 6. 자동 저장 (30초 간격)
7. 수정 이력 관리 7. 수정 이력 관리
8. 상태 변경 (확정완료 → 작성중) 8. 상태 변경 (검증완료 → 작성중으로 자동 변경)
#### UI 구성요소 #### UI 구성요소
**Mobile (320px~768px)** **Mobile (320px~768px)**
- **헤더** - **헤더**
- 뒤로가기 버튼 - 뒤로가기 버튼 (10-회의록상세조회로 이동)
- "회의록 수정" 타이틀 - "회의록 수정" 타이틀
- "저장" 버튼 (Primary) - "저장" 버튼 (Primary)
- 자동 저장 인디케이터 - 자동 저장 인디케이터 ("저장됨", "저장 중...")
- **필터 및 검색** (상단) - **회의 기본 정보 영역**
- 상태 필터: 전체 / 작성중 / 확정완료 - 회의 제목: 편집 가능 (텍스트 필드)
- 정렬: 최신순 / 회의일시순 / 제목순 - 회의 일시: 읽기 전용 (📅 아이콘 + 날짜/시간 표시)
- 검색창: 제목, 참석자, 키워드 - 회의 장소: 읽기 전용 (📍 아이콘 + 장소명)
- 참석자 목록:
- 회의 생성자: 추가/삭제 가능 (05-회의진행 화면과 동일한 UI)
- 참석자: 읽기 전용 표시
- 각 참석자: 아바타 + 이름, 삭제(×) 버튼 (생성자는 삭제 불가)
- "참석자 추가" 버튼 (이메일 입력 + 초대)
- 회의록 상태 배지 (자동 관리)
- **회의록 리스트** (목록 모드) - **편집 화면**
- 각 회의록 카드:
- 회의 제목
- 회의 일시
- 상태 배지
- 마지막 수정 시간
- 검증 완료율 (작성중인 경우)
- 스와이프 액션: 수정, 삭제
- **수정 모드** (편집 화면)
- 섹션별 편집 영역 - 섹션별 편집 영역
- 각 섹션: - 각 섹션:
- 섹션 제목 - 섹션 제목
@ -1452,14 +1465,19 @@ graph TD
- 자동 저장 상태 표시 ("저장됨", "저장 중...") - 자동 저장 상태 표시 ("저장됨", "저장 중...")
**Tablet/Desktop (768px+)** **Tablet/Desktop (768px+)**
- 좌측: 회의록 리스트 - **헤더**: Mobile과 동일 (뒤로가기, 타이틀, 저장 버튼, 자동 저장 인디케이터)
- 중앙: 선택된 회의록 편집 영역 - **메인 영역**:
- 우측: 수정 이력 패널 - 회의 기본 정보 영역 (Mobile과 동일)
- 편집 화면 (섹션별 편집, AI 요약, 참고자료, Todo)
- **우측 패널** (선택사항):
- 수정 이력 (v2.0 고도화 예정)
- 미리보기
#### 인터랙션 #### 인터랙션
1. **회의록 선택** 1. **화면 진입**
- 리스트에서 회의록 클릭: 편집 모드로 전환 - 10-회의록상세조회 → "수정" 버튼 클릭
- 편집 모드에서 다른 회의록 선택: 저장 확인 다이얼로그 - 권한 확인: 검증완료 후에는 회의 생성자만 접근 가능
- 바로 편집 모드로 시작
2. **내용 수정** 2. **내용 수정**
- 텍스트 영역 클릭: 포커스 및 편집 가능 - 텍스트 영역 클릭: 포커스 및 편집 가능
@ -2015,6 +2033,7 @@ graph TD
| 1.4.4 | 2025-10-23 | 강지수 | Mobile 하단 네비게이션 프로토타입 구현 기준 반영<br>- **Mobile 하단 네비게이션**: 4개 메뉴 → 3개 메뉴로 수정 (홈/회의록/Todo)<br> - 프로필 메뉴 제거 (Desktop 사이드바의 사용자 정보 영역으로 통합)<br> - 프로토타입 실제 구현 상태 반영 (02-대시보드.html, 09-Todo관리.html, 12-회의록목록조회.html)<br> - 사용 화면 번호 업데이트: 08→09, 11→12<br>- **참고 사항**: 프로필 메뉴가 필요한 경우 프로토타입에 추가 구현 필요<br>- **설계서-프로토타입 일관성**: 네비게이션 구조 완전 통일 달성 | | 1.4.4 | 2025-10-23 | 강지수 | Mobile 하단 네비게이션 프로토타입 구현 기준 반영<br>- **Mobile 하단 네비게이션**: 4개 메뉴 → 3개 메뉴로 수정 (홈/회의록/Todo)<br> - 프로필 메뉴 제거 (Desktop 사이드바의 사용자 정보 영역으로 통합)<br> - 프로토타입 실제 구현 상태 반영 (02-대시보드.html, 09-Todo관리.html, 12-회의록목록조회.html)<br> - 사용 화면 번호 업데이트: 08→09, 11→12<br>- **참고 사항**: 프로필 메뉴가 필요한 경우 프로토타입에 추가 구현 필요<br>- **설계서-프로토타입 일관성**: 네비게이션 구조 완전 통일 달성 |
| 1.4.5 | 2025-10-23 | 강지수 | 로그아웃 기능 추가 (Desktop 사이드바 + Mobile 헤더)<br>- **Desktop 좌측 사이드바**: 하단에 사용자 정보 영역 추가<br> - 사용자 정보 (아바타 + 이름 + 이메일)<br> - 로그아웃 버튼 (btn-ghost btn-sm)<br>- **Mobile 상단 헤더**: 우측에 프로필 아이콘 버튼 추가 (👤)<br> - 클릭 시 드롭다운 메뉴 표시 (사용자 정보 + 로그아웃 버튼)<br> - 드롭다운 위치: 우측 상단 기준 아래로 펼침<br> - 오버레이 배경으로 UX 개선<br>- **프로토타입 파일**: 02-대시보드.html, 09-Todo관리.html, 12-회의록목록조회.html<br>- **JavaScript 함수**: toggleProfileMenu(), logout() 추가<br>- **반응형 처리**: Desktop에서는 드롭다운 숨김, Mobile에서는 사이드바 사용자 영역 숨김<br>- **설계서-프로토타입 일관성**: 로그아웃 기능 완전 통일 | | 1.4.5 | 2025-10-23 | 강지수 | 로그아웃 기능 추가 (Desktop 사이드바 + Mobile 헤더)<br>- **Desktop 좌측 사이드바**: 하단에 사용자 정보 영역 추가<br> - 사용자 정보 (아바타 + 이름 + 이메일)<br> - 로그아웃 버튼 (btn-ghost btn-sm)<br>- **Mobile 상단 헤더**: 우측에 프로필 아이콘 버튼 추가 (👤)<br> - 클릭 시 드롭다운 메뉴 표시 (사용자 정보 + 로그아웃 버튼)<br> - 드롭다운 위치: 우측 상단 기준 아래로 펼침<br> - 오버레이 배경으로 UX 개선<br>- **프로토타입 파일**: 02-대시보드.html, 09-Todo관리.html, 12-회의록목록조회.html<br>- **JavaScript 함수**: toggleProfileMenu(), logout() 추가<br>- **반응형 처리**: Desktop에서는 드롭다운 숨김, Mobile에서는 사이드바 사용자 영역 숨김<br>- **설계서-프로토타입 일관성**: 로그아웃 기능 완전 통일 |
| 1.4.6 | 2025-10-23 | 강지수 | 검증완료 섹션 잠금해제 정책 단순화<br>- **정책 변경**: 검증완료 섹션은 회의 생성자만 잠금 해제 후 수정 가능 (참석자는 수정 불가)<br>- **제거**: 참석자용 잠금해제 요청 기능 완전 제거 (공수 절감)<br>- **11-회의록수정**: 검증완료 섹션에 "🔒 읽기 전용" 배지 표시 (참석자 화면)<br> - 잠금해제요청 버튼 제거<br> - unlockSection() 함수 제거<br> - 읽기 전용 안내 텍스트 추가: "(잠금됨 · 회의 생성자만 수정 가능)"<br>- **06-검증완료**: 회의 생성자용 잠금해제 버튼 유지 (변경 없음)<br>- **인터랙션**: "3. 섹션 잠금 해제" → "3. 검증완료 섹션 (권한별 차등 표시)"로 수정<br>- **유저스토리**: UFR-MEET-055, UFR-COLLAB-030 권한 제어 명확화 | | 1.4.6 | 2025-10-23 | 강지수 | 검증완료 섹션 잠금해제 정책 단순화<br>- **정책 변경**: 검증완료 섹션은 회의 생성자만 잠금 해제 후 수정 가능 (참석자는 수정 불가)<br>- **제거**: 참석자용 잠금해제 요청 기능 완전 제거 (공수 절감)<br>- **11-회의록수정**: 검증완료 섹션에 "🔒 읽기 전용" 배지 표시 (참석자 화면)<br> - 잠금해제요청 버튼 제거<br> - unlockSection() 함수 제거<br> - 읽기 전용 안내 텍스트 추가: "(잠금됨 · 회의 생성자만 수정 가능)"<br>- **06-검증완료**: 회의 생성자용 잠금해제 버튼 유지 (변경 없음)<br>- **인터랙션**: "3. 섹션 잠금 해제" → "3. 검증완료 섹션 (권한별 차등 표시)"로 수정<br>- **유저스토리**: UFR-MEET-055, UFR-COLLAB-030 권한 제어 명확화 |
| 1.4.7 | 2025-10-23 | 강지수, 도그냥 | Todo 및 회의록 관련 UI/UX 재정의<br>- **09-Todo관리**: "Todo수정" → "Todo관리" 기능 확장<br> - 통계 블록: 전체(미완료), 마감임박(3일 이내), 지연(기한 경과)<br> - 필터 탭 개수 표시: 전체(개수), 지연(개수), 마감임박(개수), 완료(개수)<br> - 편집 모달: 제목, 담당자, 마감일, 우선순위 수정<br> - 체크박스 확인 모달: 완료/미완료 전환 시 확인<br> - 프로토타입: 09-Todo관리.html (통계, 필터, 모달 구현)<br>- **10-회의록상세조회**: 탭 순서 및 기본 노출 변경<br> - 탭 순서: 대시보드 → 회의록 (기존: 회의록 → 대시보드)<br> - 기본 활성 탭: 대시보드 (Desktop/Mobile 공통)<br> - 프로토타입: 10-회의록상세조회.html (탭 순서 변경, active 클래스 이동)<br>- **11-회의록수정**: 진입 경로 및 권한 제어 명확화<br> - 진입 경로: 10-회의록상세조회 → "수정" 버튼 클릭<br> - 권한 제어: 검증완료 전(모든 참석자), 검증완료 후(회의 생성자만)<br> - 회의 일시/장소: 읽기 전용 표시 추가 "(읽기 전용)"<br> - UI 구성: 회의록 리스트 제거, 직접 편집 화면으로 시작<br> - 프로토타입: 11-회의록수정.html (권한 코멘트 추가, readonly 표시) |
--- ---

View File

@ -1,6 +1,6 @@
# AI기반 회의록 작성 및 이력 관리 개선 서비스 - 유저스토리 (v2.0.3) # AI기반 회의록 작성 및 이력 관리 개선 서비스 - 유저스토리 (v2.0.5)
- [AI기반 회의록 작성 및 이력 관리 개선 서비스 - 유저스토리 (v2.0.3)](#ai기반-회의록-작성-및-이력-관리-개선-서비스---유저스토리-v203) - [AI기반 회의록 작성 및 이력 관리 개선 서비스 - 유저스토리 (v2.0.5)](#ai기반-회의록-작성-및-이력-관리-개선-서비스---유저스토리-v205)
- [차별화 전략](#차별화-전략) - [차별화 전략](#차별화-전략)
- [1. 기본 기능 (Hygiene Factors)](#1-기본-기능-hygiene-factors) - [1. 기본 기능 (Hygiene Factors)](#1-기본-기능-hygiene-factors)
- [2. 핵심 차별화 포인트 (Differentiators)](#2-핵심-차별화-포인트-differentiators) - [2. 핵심 차별화 포인트 (Differentiators)](#2-핵심-차별화-포인트-differentiators)
@ -316,9 +316,22 @@ UFR-MEET-047: [회의록상세조회] 회의록 작성자로서 | 나는, 지난
- 각 회의록별 정보: 제목, 날짜, 관련도 %, 요약 내용 - 각 회의록별 정보: 제목, 날짜, 관련도 %, 요약 내용
- 클릭 시 해당 회의록으로 이동 - 클릭 시 해당 회의록으로 이동
[탭 네비게이션]
- **탭 구성**: 대시보드 / 회의록 (2개 탭)
- **기본 노출**: 대시보드 탭 우선 노출
- **탭 전환**: 클릭 시 콘텐츠 전환, URL 변경 없음
- **대시보드 탭 내용**:
- 핵심내용 (주요 포인트 요약)
- 결정사항
- Todo 진행상황
- 관련회의록
- **회의록 탭 내용**:
- 섹션별 상세 내용
- AI 요약
- 관련회의록
[부가 기능] [부가 기능]
- 회의록 수정 버튼 (수정 권한이 있는 경우만 활성화) - 회의록 수정 버튼 (수정 권한이 있는 경우만 활성화)
- 탭 네비게이션 (회의록/대시보드)
- 뒤로가기 버튼 (회의록 목록으로 복귀) - 뒤로가기 버튼 (회의록 목록으로 복귀)
- 더보기 메뉴 (다운로드, 삭제 등) - 더보기 메뉴 (다운로드, 삭제 등)
@ -336,10 +349,15 @@ UFR-MEET-047: [회의록상세조회] 회의록 작성자로서 | 나는, 지난
--- ---
UFR-MEET-055: [회의록수정] 회의록 작성자로서 | 나는, 검증이 완료되지 않았거나 수정이 필요한 | 지난 회의록을 수정하고 싶다. UFR-MEET-055: [회의록수정] 회의 참석자로서 | 나는, 검증이 완료되지 않았거나 수정이 필요한 | 지난 회의록을 수정하고 싶다.
- **화면번호**: 11-회의록수정
- 시나리오: 지난 회의록 수정 - 시나리오: 지난 회의록 수정
회의록 상세 화면에서 수정 버튼을 클릭하면 | 회의록 수정 화면으로 이동하고 | 내용을 수정할 수 있다. 회의록 상세 화면에서 수정 버튼을 클릭하면 | 회의록 수정 화면으로 이동하고 | 내용을 수정할 수 있다.
[진입 경로]
- 10-회의록상세조회 화면 → 하단 액션 바 "수정" 버튼 클릭
- 권한이 있는 경우에만 "수정" 버튼 활성화
[수정 가능 항목] [수정 가능 항목]
- ✅ **회의 제목**: 수정 가능 - ✅ **회의 제목**: 수정 가능
- ❌ **회의 일시**: 수정 불가 (readonly, 회의 예약 화면에서만 변경 가능) - ❌ **회의 일시**: 수정 불가 (readonly, 회의 예약 화면에서만 변경 가능)
@ -366,10 +384,16 @@ UFR-MEET-055: [회의록수정] 회의록 작성자로서 | 나는, 검증이
- 취소 시 이전 상태로 복원 - 취소 시 이전 상태로 복원
[권한 제어] [권한 제어]
- 본인이 작성한 회의록만 수정 가능 (회의 생성자) **검증완료 전 (작성중/초안 상태)**
- 모든 참석자가 회의록 수정 가능
- 모든 섹션 편집 가능 (검증완료 섹션 없음)
- 참석자 관리: 회의 생성자만 가능
**검증완료 후**
- 회의 생성자만 회의록 수정 가능
- 참석자는 "수정" 버튼 비활성화 (조회만 가능)
- 검증완료 섹션: 회의 생성자만 잠금 해제 후 수정 가능 - 검증완료 섹션: 회의 생성자만 잠금 해제 후 수정 가능
- 참석자: 검증완료 섹션은 읽기 전용으로 표시 - 수정 시 회의록 상태는 '작성중'으로 자동 변경 (재검증 필요)
- 조회 전용 권한인 경우 수정 버튼 비활성화
- M/13 - M/13
@ -891,62 +915,87 @@ UFR-TODO-030: [Todo완료처리] Todo 담당자로서 | 나는, 완료된 Todo
--- ---
UFR-TODO-040: [Todo수정] Todo 담당자 또는 회의 생성자로서 | 나는, Todo 내용을 변경하기 위해 | 회의록 확정 전후에 Todo를 수정하고 싶다. UFR-TODO-040: [Todo관리] Todo 담당자로서 | 나는, 나의 Todo를 효율적으로 관리하기 위해 | Todo 목록을 조회하고 상태를 변경하고 편집하고 싶다.
- 시나리오: Todo 수정 - 시나리오: Todo 관리 화면 조회 및 관리
Todo 목록에서 수정이 필요한 상황에서 | 담당자 또는 회의 생성자가 Todo 수정 버튼을 클릭하면 | Todo 내용, 담당자, 마감일, 우선순위를 변경할 수 있다. 09-Todo관리 화면에 접근하면 | 나의 Todo(내가 담당자인 Todo) 목록이 표시되고 | 필터링, 상태 변경, 편집이 가능하다.
[화면 정보] [화면 정보]
- 화면번호: 09-Todo관리 - 화면번호: 09-Todo관리
- 프로토타입: design/uiux/prototype/09-Todo관리.html - 프로토타입: design/uiux/prototype/09-Todo관리.html
[수정 가능 항목] [대전제]
- Todo 제목 (문구) - Todo의 상태는 완료/미완료만 존재
- 담당자 (드롭다운 선택) - 09-Todo관리 화면에서는 나의 Todo(내가 담당자인 Todo)만 표시
- 마감일 (날짜 선택기)
- 우선순위 (high/medium/low)
[수정 시점] [화면 구성]
- **회의록 확정 전**: 회의 진행 중(05-회의진행) 또는 회의 종료 전(07-회의종료)에서 수정 가능 **1. 상단 통계 블록**
- **회의록 확정 후**: Todo 관리 화면(09-Todo관리) 또는 회의록 수정 화면(11-회의록수정)에서 수정 가능 - 전체: 미완료 전체 개수
- 마감임박: 기한 3일 이내 미완료 개수
- 지연: 기한이 지난 미완료 개수
**2. 필터링 기준**
- 전체(개수): 완료/미완료 전체
- 지연(개수): 기한이 지난 미완료
- 마감임박(개수): 기한 3일 이내 미완료
- 완료(개수): 완료된 Todo
**3. Todo 리스트 블록**
- 정렬: 미완료 → 완료 순서, 기한일 오래된 순 (복합 정렬)
- 표시 항목:
- 체크박스 (완료/미완료 토글)
- Todo 제목
- 상태 뱃지: D+n(지연) / D-day / D-n / 완료
- 우선순위 뱃지: 높음 / 보통 / 낮음
- 기한
- 회의록 제목 + 링크 (해당 Todo가 속한 회의록 상세로 이동)
- 편집 버튼 (권한 있는 경우에만 노출)
- 페이징: 최초 10건 노출, 10건 이상일 경우 하단에 "10개 더보기" 버튼 표시
**4. 편집 모달**
- 제목 (input)
- 담당자 (해당 회의록 참석자 중 select) - 회의 생성자만 변경 가능
- 마감일 (달력)
- 우선순위 (높음/보통/낮음 select)
[UI/UX 요구사항]
- **디자인 차별화**: 액션 가능한 블록(체크박스, 편집 버튼)과 정보 표시 블록은 시각적으로 구분
- **체크박스 동작**:
- 체크박스 클릭 시 "완료 처리하시겠습니까?" 확인 모달 표시
- 확인 시 완료 처리, 취소 시 이전 상태 유지
- 미완료로 되돌릴 때도 "미완료로 변경하시겠습니까?" 확인 모달 표시
- **편집 버튼**: 담당자 본인 OR 회의 생성자인 경우에만 노출
- **편집 모달**: 모바일에서는 바텀시트 형식으로 표시
- **회의록 링크**: 클릭 시 10-회의록상세조회 화면으로 이동 (대시보드 탭 우선 노출)
[권한 제어] [권한 제어]
- **Todo 담당자**: 본인에게 할당된 Todo만 수정 가능 (09-Todo관리) - **Todo 담당자**: 본인에게 할당된 Todo만 편집 가능
- 수정 가능 항목: 제목, 마감일, 우선순위 - 수정 가능 항목: 제목, 마감일, 우선순위
- 담당자 변경 불가 (본인 담당 Todo) - 담당자 변경 불가
- **회의 생성자**: 해당 회의의 모든 Todo 수정 가능 (11-회의록수정) - **회의 생성자**: 해당 회의의 모든 Todo 편집 가능 (11-회의록수정 화면에서)
- 수정 가능 항목: 제목, 담당자, 마감일, 우선순위 - 수정 가능 항목: 제목, 담당자, 마감일, 우선순위
- 담당자 변경 가능 - 담당자 변경 가능
[수정 인터페이스]
- 09-Todo관리: 각 Todo 항목에 "편집" 버튼 표시
- 클릭 시 인라인 편집 모드 또는 수정 모달 표시
- 수정 완료 후 "저장" 버튼 클릭
- 11-회의록수정: "액션 아이템(Todo)" 섹션에서 수정
- 회의록 수정 시 Todo 섹션도 편집 가능
- Todo 추가/삭제/수정 모두 가능
[처리 결과] [처리 결과]
- Todo 정보 업데이트 - Todo 상태 변경 시:
- 수정 시간 기록 - 완료/미완료 상태 즉시 업데이트
- 수정자 정보 저장 - 통계 블록 갱신
- 회의록에 수정 내용 실시간 반영 - 리스트 재정렬
- 담당자 변경 시 이전 담당자와 새 담당자에게 알림 발송 - Todo 편집 저장 시:
- 마감일 변경 시 캘린더 자동 업데이트 - Todo 정보 업데이트
- 수정 시간 기록
[알림 발송] - 회의록에 수정 내용 실시간 반영
- 담당자 변경 시: 이전 담당자 및 새 담당자에게 알림 - 담당자 변경 시 이전/새 담당자에게 알림 발송
- 마감일 변경 시: 담당자에게 알림 (캘린더 업데이트) - 마감일 변경 시 캘린더 자동 업데이트
- 제목/우선순위 변경 시: 담당자에게 알림 (변경 사항 안내)
[Policy/Rule] [Policy/Rule]
- 담당자는 본인 Todo만 수정 가능 (담당자 변경 불가) - 필터별 개수 표시로 사용자가 전체 보기 여부 판단 가능
- 회의 생성자는 모든 Todo 수정 가능 (담당자 변경 가능) - 체크박스 토글 시 확인 액션 필수 (실수 방지)
- 확정 전/후 모두 수정 가능 - 편집 권한 없는 Todo는 편집 버튼 미노출
- 수정 시 회의록에 즉시 반영
[비고] [비고]
- 회의록 확정 후에도 유연한 Todo 관리 가능 - 진행률 표시 제거 (상태는 완료/미완료만)
- 인사 이동, 우선순위 변경, 일정 조정 등 실무 요구사항 반영 - 날짜별 그룹핑은 v2.0 고도화 시 고려
- Todo 하이라이트 기능은 v2.0 고도화 시 고려
- M/13 - M/13
@ -1046,5 +1095,6 @@ UFR-TODO-040: [Todo수정] Todo 담당자 또는 회의 생성자로서 | 나는
| 2.0.2 | 2025-10-23 | 강지수, 도그냥 | Todo 수정 기능 추가 (UFR-TODO-040)<br>- 회의록 확정 전/후 Todo 수정 기능 추가<br>- 권한별 수정 범위: 담당자(본인 Todo만), 회의 생성자(모든 Todo)<br>- 수정 항목: 제목, 담당자, 마감일, 우선순위<br>- 09-Todo관리, 11-회의록수정 화면에서 수정 가능 | | 2.0.2 | 2025-10-23 | 강지수, 도그냥 | Todo 수정 기능 추가 (UFR-TODO-040)<br>- 회의록 확정 전/후 Todo 수정 기능 추가<br>- 권한별 수정 범위: 담당자(본인 Todo만), 회의 생성자(모든 Todo)<br>- 수정 항목: 제목, 담당자, 마감일, 우선순위<br>- 09-Todo관리, 11-회의록수정 화면에서 수정 가능 |
| 2.0.3 | 2025-10-23 | 강지수 (Product Designer) | 회의록 수정 항목 정책 명확화 (UFR-MEET-055)<br>- 회의 일시/장소: readonly 처리 (회의 예약 화면에서만 변경 가능)<br>- 참석자 관리: 회의 생성자만 추가/삭제 가능 (11-회의록수정 화면에서 직접 관리)<br>- 참석자 UI: 05-회의진행 화면과 동일한 방식으로 구현<br>- 프로토타입: 11-회의록수정.html에 참석자 관리 섹션 추가 | | 2.0.3 | 2025-10-23 | 강지수 (Product Designer) | 회의록 수정 항목 정책 명확화 (UFR-MEET-055)<br>- 회의 일시/장소: readonly 처리 (회의 예약 화면에서만 변경 가능)<br>- 참석자 관리: 회의 생성자만 추가/삭제 가능 (11-회의록수정 화면에서 직접 관리)<br>- 참석자 UI: 05-회의진행 화면과 동일한 방식으로 구현<br>- 프로토타입: 11-회의록수정.html에 참석자 관리 섹션 추가 |
| 2.0.4 | 2025-10-23 | 강지수 (Product Designer) | 검증완료 섹션 잠금해제 정책 단순화<br>- **정책 변경**: 검증완료 섹션은 회의 생성자만 잠금 해제 후 수정 가능 (참석자는 수정 불가)<br>- **제거**: 참석자용 잠금해제 요청 기능 완전 제거 (공수 절감)<br>- UFR-MEET-055: 권한 제어 명확화 (생성자만 잠금 해제 가능)<br>- UFR-COLLAB-030: 섹션 잠금 기능 설명 업데이트<br>- 프로토타입 11-회의록수정.html: 잠금해제요청 버튼 제거, 검증완료 섹션 읽기 전용 표시 | | 2.0.4 | 2025-10-23 | 강지수 (Product Designer) | 검증완료 섹션 잠금해제 정책 단순화<br>- **정책 변경**: 검증완료 섹션은 회의 생성자만 잠금 해제 후 수정 가능 (참석자는 수정 불가)<br>- **제거**: 참석자용 잠금해제 요청 기능 완전 제거 (공수 절감)<br>- UFR-MEET-055: 권한 제어 명확화 (생성자만 잠금 해제 가능)<br>- UFR-COLLAB-030: 섹션 잠금 기능 설명 업데이트<br>- 프로토타입 11-회의록수정.html: 잠금해제요청 버튼 제거, 검증완료 섹션 읽기 전용 표시 |
| 2.0.5 | 2025-10-23 | 강지수 (Product Designer), 도그냥 (Service Planner) | Todo 및 회의록 관련 요구사항 재정의<br>- **UFR-TODO-040 (09-Todo관리)**: "Todo수정" → "Todo관리" 기능 확장<br> - 통계 블록 재정의: 전체(미완료), 마감임박(3일 이내), 지연(기한 경과)<br> - 필터링: 전체, 지연, 마감임박, 완료 (각 필터에 개수 표시)<br> - 체크박스 확인 모달: 완료/미완료 전환 시 확인<br> - 권한: 담당자 본인 OR 회의록 작성자만 편집 가능<br>- **UFR-MEET-047 (10-회의록상세조회)**: 탭 순서 및 기본 노출 변경<br> - 탭 구성: 대시보드 / 회의록<br> - 기본 노출: 대시보드 탭 우선 노출 (기존: 회의록 우선)<br>- **UFR-MEET-055 (11-회의록수정)**: 진입 경로 및 권한 제어 명확화<br> - 진입 경로: 10-회의록상세조회 → "수정" 버튼 클릭<br> - 권한 제어: 검증완료 전(모든 참석자), 검증완료 후(회의 생성자만)<br> - 회의 일시/장소: 읽기 전용 표시 명시 |
--- ---