mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 13:46:24 +00:00
Merge branch 'main' of https://github.com/hwanny1128/HGZero into feat/notification-noti_request
This commit is contained in:
commit
55de4b9411
@ -150,6 +150,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 회의 카드 */
|
/* 회의 카드 */
|
||||||
|
/* 최근 회의는 최대 3개만 표시하므로 3열로 제한 */
|
||||||
.meeting-grid {
|
.meeting-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--space-md);
|
gap: var(--space-md);
|
||||||
@ -168,12 +169,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1440px) {
|
|
||||||
.meeting-grid {
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.meeting-card {
|
.meeting-card {
|
||||||
background: var(--white);
|
background: var(--white);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
@ -689,8 +684,17 @@
|
|||||||
const statusInfo = getMeetingStatusInfo(meeting);
|
const statusInfo = getMeetingStatusInfo(meeting);
|
||||||
const isCreator = meeting.participants.some(p => p.id === currentUser.id && p.role === 'creator');
|
const isCreator = meeting.participants.some(p => p.id === currentUser.id && p.role === 'creator');
|
||||||
|
|
||||||
|
// 버튼 표시 규칙
|
||||||
|
// - ongoing: 참여하기 버튼 표시
|
||||||
|
// - scheduled: 버튼 없음 (카드 클릭으로 수정 화면 이동)
|
||||||
|
// - draft/complete: 버튼 없음 (카드 클릭으로 상세조회 이동)
|
||||||
|
let actionButton = '';
|
||||||
|
if (meeting.status === 'ongoing') {
|
||||||
|
actionButton = `<button class="btn btn-primary btn-sm" onclick="navigateTo('05-회의진행.html'); event.stopPropagation();">참여하기</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="meeting-card ${meeting.status === 'ongoing' ? 'ongoing' : ''}" data-id="${meeting.id}">
|
<div class="meeting-card ${meeting.status === 'ongoing' ? 'ongoing' : ''}" data-id="${meeting.id}" data-status="${meeting.status}">
|
||||||
<div class="meeting-card-header">
|
<div class="meeting-card-header">
|
||||||
${createBadge(statusInfo.badgeText, statusInfo.badgeType)}
|
${createBadge(statusInfo.badgeText, statusInfo.badgeType)}
|
||||||
<h3 class="meeting-card-title">${meeting.title}${isCreator ? ' <span style="font-size: 16px;" title="생성자">👑</span>' : ''}</h3>
|
<h3 class="meeting-card-title">${meeting.title}${isCreator ? ' <span style="font-size: 16px;" title="생성자">👑</span>' : ''}</h3>
|
||||||
@ -699,14 +703,7 @@
|
|||||||
<div class="meeting-card-meta-item">📅 ${formatDate(meeting.date)} ${formatTime(meeting.time)} 👥 ${meeting.participants.length}명</div>
|
<div class="meeting-card-meta-item">📅 ${formatDate(meeting.date)} ${formatTime(meeting.time)} 👥 ${meeting.participants.length}명</div>
|
||||||
<div class="meeting-card-meta-item">📍 ${meeting.location}</div>
|
<div class="meeting-card-meta-item">📍 ${meeting.location}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="meeting-card-actions">
|
${actionButton ? `<div class="meeting-card-actions">${actionButton}</div>` : ''}
|
||||||
${meeting.status === 'ongoing'
|
|
||||||
? `<button class="btn btn-primary btn-sm" onclick="navigateTo('05-회의진행.html'); event.stopPropagation();">참여하기</button>`
|
|
||||||
: meeting.status === 'scheduled' && isCreator
|
|
||||||
? `<button class="btn btn-secondary btn-sm" onclick="navigateTo('03-회의예약.html'); event.stopPropagation();">수정</button>`
|
|
||||||
: `<button class="btn btn-ghost btn-sm" onclick="navigateTo('10-회의록상세조회.html'); event.stopPropagation();">보기</button>`
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}).join('');
|
}).join('');
|
||||||
@ -716,12 +713,14 @@
|
|||||||
card.addEventListener('click', (e) => {
|
card.addEventListener('click', (e) => {
|
||||||
if (e.target.tagName !== 'BUTTON') {
|
if (e.target.tagName !== 'BUTTON') {
|
||||||
const meetingId = card.dataset.id;
|
const meetingId = card.dataset.id;
|
||||||
const meeting = SAMPLE_MEETINGS.find(m => m.id === meetingId);
|
const meetingStatus = card.dataset.status;
|
||||||
if (meeting.status === 'ongoing') {
|
|
||||||
|
// 상태에 따른 이동 처리
|
||||||
|
if (meetingStatus === 'ongoing') {
|
||||||
navigateTo('05-회의진행.html');
|
navigateTo('05-회의진행.html');
|
||||||
} else if (meeting.status === 'completed') {
|
} else if (meetingStatus === 'draft' || meetingStatus === 'complete' || meetingStatus === 'completed') {
|
||||||
navigateTo('10-회의록상세조회.html');
|
navigateTo('10-회의록상세조회.html');
|
||||||
} else {
|
} else if (meetingStatus === 'scheduled') {
|
||||||
navigateTo('03-회의예약.html');
|
navigateTo('03-회의예약.html');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1129,7 +1129,10 @@
|
|||||||
|
|
||||||
<!-- Todo 단순 조회 (MVP 스코프 축소 v1.5.1) -->
|
<!-- Todo 단순 조회 (MVP 스코프 축소 v1.5.1) -->
|
||||||
<div class="card mb-lg">
|
<div class="card mb-lg">
|
||||||
|
<div class="section-header">
|
||||||
<h3 class="card-title">📋 Todo 리스트</h3>
|
<h3 class="card-title">📋 Todo 리스트</h3>
|
||||||
|
<button class="btn btn-primary btn-sm" onclick="openModal('addTodoModal')">추가</button>
|
||||||
|
</div>
|
||||||
<p style="font-size: var(--font-small); color: var(--gray-600); margin-bottom: var(--space-md);">
|
<p style="font-size: var(--font-small); color: var(--gray-600); margin-bottom: var(--space-md);">
|
||||||
Todo 항목은 조회만 가능합니다. 제목, 담당자, 마감일 정보만 표시됩니다.
|
Todo 항목은 조회만 가능합니다. 제목, 담당자, 마감일 정보만 표시됩니다.
|
||||||
</p>
|
</p>
|
||||||
@ -1139,7 +1142,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">데이터베이스 스키마 설계</div>
|
<div class="simple-todo-title">데이터베이스 스키마 설계</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(1)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(1)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 이준호</span>
|
<span>👤 이준호</span>
|
||||||
@ -1150,7 +1153,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">API 명세서 작성</div>
|
<div class="simple-todo-title">API 명세서 작성</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(2)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(2)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 이준호</span>
|
<span>👤 이준호</span>
|
||||||
@ -1161,7 +1164,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">예산 편성안 검토</div>
|
<div class="simple-todo-title">예산 편성안 검토</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(3)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(3)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 김민준</span>
|
<span>👤 김민준</span>
|
||||||
@ -1172,7 +1175,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">UI 프로토타입 디자인</div>
|
<div class="simple-todo-title">UI 프로토타입 디자인</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(4)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(4)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 최유진</span>
|
<span>👤 최유진</span>
|
||||||
@ -1183,7 +1186,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">사용자 피드백 분석</div>
|
<div class="simple-todo-title">사용자 피드백 분석</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(5)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(5)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 김민준</span>
|
<span>👤 김민준</span>
|
||||||
@ -1247,17 +1250,27 @@
|
|||||||
<div class="modal">
|
<div class="modal">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 class="modal-title">Todo 추가</h3>
|
<h3 class="modal-title">Todo 추가</h3>
|
||||||
<button class="modal-close">×</button>
|
<button class="modal-close" onclick="closeModal('addTodoModal')">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Todo 내용</label>
|
<label class="form-label">Todo 내용 <span class="text-error">*</span></label>
|
||||||
<input type="text" class="form-control" placeholder="할 일을 입력하세요">
|
<input type="text" id="addTodoTitle" class="form-control" placeholder="할 일을 입력하세요">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">마감일</label>
|
<label class="form-label">담당자 <span class="text-error">*</span></label>
|
||||||
|
<select id="addTodoAssignee" class="form-control">
|
||||||
|
<option value="">담당자를 선택하세요</option>
|
||||||
|
<option value="김민준">김민준</option>
|
||||||
|
<option value="이준호">이준호</option>
|
||||||
|
<option value="박서연">박서연</option>
|
||||||
|
<option value="최유진">최유진</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">마감일 <span class="text-error">*</span></label>
|
||||||
<div class="date-input-wrapper">
|
<div class="date-input-wrapper">
|
||||||
<input type="date" class="form-control">
|
<input type="date" id="addTodoDueDate" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1290,22 +1303,12 @@
|
|||||||
<option value="박서연">박서연</option>
|
<option value="박서연">박서연</option>
|
||||||
<option value="최유진">최유진</option>
|
<option value="최유진">최유진</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="form-hint">👤 담당자 변경 시 이전/새 담당자에게 알림이 전송됩니다</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">마감일 <span class="text-error">*</span></label>
|
<label class="form-label">마감일 <span class="text-error">*</span></label>
|
||||||
<div class="date-input-wrapper">
|
<div class="date-input-wrapper">
|
||||||
<input type="date" id="editTodoDueDate" class="form-control">
|
<input type="date" id="editTodoDueDate" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<p class="form-hint">📅 마감일 변경 시 캘린더가 자동 업데이트됩니다</p>
|
|
||||||
</div>
|
|
||||||
<!-- 권한 안내 (동적 메시지) -->
|
|
||||||
<div class="alert alert-info" id="editTodoPermissionInfo">
|
|
||||||
<span class="material-icons" style="font-size: 20px;">info</span>
|
|
||||||
<div>
|
|
||||||
<strong>권한 안내</strong>
|
|
||||||
<p style="margin: 4px 0 0 0; font-size: 14px;" id="editTodoPermissionText">회의 생성자로서 모든 항목을 수정할 수 있습니다.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@ -1347,95 +1350,39 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo 편집 모달 - 모바일 전체화면 */
|
/* Todo 추가/편집 모달 - 바텀시트 스타일 */
|
||||||
|
#addTodoModal .modal,
|
||||||
#editTodoModal .modal {
|
#editTodoModal .modal {
|
||||||
position: fixed;
|
max-height: 90vh;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
max-width: none;
|
|
||||||
max-height: none;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-header {
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: var(--space-lg) var(--space-md);
|
|
||||||
border-bottom: 1px solid var(--gray-200);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-title {
|
|
||||||
font-size: var(--font-h3);
|
|
||||||
font-weight: var(--font-weight-bold);
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-close {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 28px;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--gray-600);
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
transition: all var(--transition-fast);
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-close:hover {
|
|
||||||
background: var(--gray-100);
|
|
||||||
color: var(--gray-900);
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-body {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: var(--space-lg) var(--space-md);
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#addTodoModal .modal-footer,
|
||||||
#editTodoModal .modal-footer {
|
#editTodoModal .modal-footer {
|
||||||
flex-shrink: 0;
|
|
||||||
padding: var(--space-md);
|
|
||||||
border-top: 1px solid var(--gray-200);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-sm);
|
gap: var(--space-sm);
|
||||||
background: var(--white);
|
justify-content: flex-end;
|
||||||
|
margin-top: var(--space-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#addTodoModal .modal-footer .btn,
|
||||||
#editTodoModal .modal-footer .btn {
|
#editTodoModal .modal-footer .btn {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 데스크톱에서는 중앙 모달로 복원 */
|
/* 데스크톱에서는 중앙 모달 */
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
|
#addTodoModal .modal,
|
||||||
#editTodoModal .modal {
|
#editTodoModal .modal {
|
||||||
position: relative;
|
|
||||||
top: auto;
|
|
||||||
left: auto;
|
|
||||||
right: auto;
|
|
||||||
bottom: auto;
|
|
||||||
width: 90%;
|
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
height: auto;
|
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
margin: 0 auto;
|
|
||||||
border-radius: var(--radius-lg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 회의 생성자 전용 요소 숨김 */
|
||||||
|
.creator-only.hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="common.js"></script>
|
<script src="common.js"></script>
|
||||||
@ -1766,18 +1713,12 @@
|
|||||||
const currentUser = '김민준'; // 현재 로그인 사용자
|
const currentUser = '김민준'; // 현재 로그인 사용자
|
||||||
const isCreator = checkIfUserIsCreator(CURRENT_MEETING_ID, currentUser);
|
const isCreator = checkIfUserIsCreator(CURRENT_MEETING_ID, currentUser);
|
||||||
|
|
||||||
// 담당자 필드 표시 여부 결정
|
// 담당자 필드 표시 여부 결정 (회의 생성자만 표시)
|
||||||
const assigneeGroup = document.getElementById('editTodoAssigneeGroup');
|
const assigneeGroup = document.getElementById('editTodoAssigneeGroup');
|
||||||
const permissionText = document.getElementById('editTodoPermissionText');
|
|
||||||
|
|
||||||
if (isCreator) {
|
if (isCreator) {
|
||||||
// 회의 생성자: 담당자 변경 가능
|
|
||||||
assigneeGroup.style.display = 'block';
|
assigneeGroup.style.display = 'block';
|
||||||
permissionText.textContent = '회의 생성자로서 모든 항목을 수정할 수 있습니다.';
|
|
||||||
} else {
|
} else {
|
||||||
// 일반 담당자: 담당자 변경 불가
|
|
||||||
assigneeGroup.style.display = 'none';
|
assigneeGroup.style.display = 'none';
|
||||||
permissionText.textContent = '본인에게 할당된 Todo만 수정할 수 있습니다. 담당자는 변경할 수 없습니다.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 모달 열기
|
// 모달 열기
|
||||||
@ -1852,6 +1793,67 @@
|
|||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Todo 추가 함수
|
||||||
|
*/
|
||||||
|
function addTodo() {
|
||||||
|
const title = document.getElementById('addTodoTitle').value.trim();
|
||||||
|
const assignee = document.getElementById('addTodoAssignee').value.trim();
|
||||||
|
const dueDate = document.getElementById('addTodoDueDate').value;
|
||||||
|
|
||||||
|
// 유효성 검사
|
||||||
|
if (!title) {
|
||||||
|
showToast('Todo 내용을 입력해주세요', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assignee) {
|
||||||
|
showToast('담당자를 선택해주세요', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dueDate) {
|
||||||
|
showToast('마감일을 선택해주세요', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 새 Todo 추가 (실제로는 API 호출)
|
||||||
|
const newTodo = {
|
||||||
|
id: 'todo-' + Date.now(),
|
||||||
|
meetingId: CURRENT_MEETING_ID,
|
||||||
|
title: title,
|
||||||
|
assignee: assignee,
|
||||||
|
dueDate: dueDate,
|
||||||
|
status: 'pending'
|
||||||
|
};
|
||||||
|
|
||||||
|
meetingTodos.push(newTodo);
|
||||||
|
|
||||||
|
showToast('Todo가 추가되었습니다', 'success');
|
||||||
|
|
||||||
|
// 담당자에게 알림 전송
|
||||||
|
setTimeout(() => {
|
||||||
|
showToast(`${assignee}에게 알림이 전송되었습니다`, 'info');
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
// 캘린더 업데이트 알림
|
||||||
|
setTimeout(() => {
|
||||||
|
showToast('캘린더가 업데이트되었습니다', 'info');
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
closeModal('addTodoModal');
|
||||||
|
|
||||||
|
// 입력 필드 초기화
|
||||||
|
document.getElementById('addTodoTitle').value = '';
|
||||||
|
document.getElementById('addTodoAssignee').value = '';
|
||||||
|
document.getElementById('addTodoDueDate').value = '';
|
||||||
|
|
||||||
|
// 페이지 새로고침 (실제로는 Todo 리스트만 업데이트)
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
|
}, 2500);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 페이지 초기화
|
* 페이지 초기화
|
||||||
*/
|
*/
|
||||||
@ -1868,6 +1870,12 @@
|
|||||||
crownIcon.title = '회의 생성자';
|
crownIcon.title = '회의 생성자';
|
||||||
// 배지 영역에 크라운 추가
|
// 배지 영역에 크라운 추가
|
||||||
badgesContainer.appendChild(crownIcon);
|
badgesContainer.appendChild(crownIcon);
|
||||||
|
} else {
|
||||||
|
// 회의 생성자가 아닐 경우 creator-only 요소 숨김
|
||||||
|
const creatorOnlyElements = document.querySelectorAll('.creator-only');
|
||||||
|
creatorOnlyElements.forEach(element => {
|
||||||
|
element.classList.add('hidden');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTodoProgress();
|
updateTodoProgress();
|
||||||
|
|||||||
@ -453,10 +453,6 @@
|
|||||||
<span class="sidebar-nav-icon"><img src="img/edit.png" width="32"></span>
|
<span class="sidebar-nav-icon"><img src="img/edit.png" width="32"></span>
|
||||||
<span>회의록</span>
|
<span>회의록</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="09-Todo관리.html" class="sidebar-nav-item">
|
|
||||||
<span class="sidebar-nav-icon"><img src="img/list.png" width="32"></span>
|
|
||||||
<span>Todo 관리</span>
|
|
||||||
</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 사용자 정보 영역 (Desktop) -->
|
<!-- 사용자 정보 영역 (Desktop) -->
|
||||||
@ -581,9 +577,6 @@
|
|||||||
<a href="12-회의록목록조회.html" class="nav-item active">
|
<a href="12-회의록목록조회.html" class="nav-item active">
|
||||||
<img src="img/edit.png" alt="회의록" style="width: 45px;">
|
<img src="img/edit.png" alt="회의록" style="width: 45px;">
|
||||||
</a>
|
</a>
|
||||||
<a href="09-Todo관리.html" class="nav-item">
|
|
||||||
<img src="img/list.png" alt="Todo" style="width: 45px;">
|
|
||||||
</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<script src="common.js"></script>
|
<script src="common.js"></script>
|
||||||
|
|||||||
11
design/uiux/prototype/common.js
vendored
11
design/uiux/prototype/common.js
vendored
@ -31,7 +31,7 @@ const SAMPLE_MEETINGS = [
|
|||||||
time: '14:00',
|
time: '14:00',
|
||||||
duration: 90,
|
duration: 90,
|
||||||
location: '본사 2층 대회의실',
|
location: '본사 2층 대회의실',
|
||||||
status: 'scheduled', // ongoing, scheduled, completed
|
status: 'draft', // ongoing, scheduled, completed, draft(작성중), complete(확정완료)
|
||||||
participants: [
|
participants: [
|
||||||
{ id: 'user-001', name: '김민준', avatar: '김', avatarColor: 'green' },
|
{ id: 'user-001', name: '김민준', avatar: '김', avatarColor: 'green' },
|
||||||
{ id: 'user-002', name: '박서연', avatar: '박', avatarColor: 'blue' },
|
{ id: 'user-002', name: '박서연', avatar: '박', avatarColor: 'blue' },
|
||||||
@ -39,7 +39,8 @@ const SAMPLE_MEETINGS = [
|
|||||||
{ id: 'user-004', name: '최유진', avatar: '최', avatarColor: 'pink' }
|
{ id: 'user-004', name: '최유진', avatar: '최', avatarColor: 'pink' }
|
||||||
],
|
],
|
||||||
sections: 3,
|
sections: 3,
|
||||||
todos: 5
|
todos: 5,
|
||||||
|
minutesId: 'minutes-001' // 회의록 ID 연결
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'meeting-002',
|
id: 'meeting-002',
|
||||||
@ -1083,6 +1084,12 @@ function getMeetingStatusInfo(meeting) {
|
|||||||
if (meeting.status === 'ongoing') {
|
if (meeting.status === 'ongoing') {
|
||||||
return { badgeType: 'ongoing', badgeText: '진행중' };
|
return { badgeType: 'ongoing', badgeText: '진행중' };
|
||||||
}
|
}
|
||||||
|
if (meeting.status === 'draft') {
|
||||||
|
return { badgeType: 'draft', badgeText: '작성중' };
|
||||||
|
}
|
||||||
|
if (meeting.status === 'complete') {
|
||||||
|
return { badgeType: 'complete', badgeText: '확정완료' };
|
||||||
|
}
|
||||||
if (meeting.status === 'completed') {
|
if (meeting.status === 'completed') {
|
||||||
return { badgeType: 'complete', badgeText: '확정완료' };
|
return { badgeType: 'complete', badgeText: '확정완료' };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,23 +4,58 @@
|
|||||||
- **작성일**: 2025-10-21
|
- **작성일**: 2025-10-21
|
||||||
- **최종 수정일**: 2025-10-27
|
- **최종 수정일**: 2025-10-27
|
||||||
- **작성자**: 이미준 (서비스 기획자)
|
- **작성자**: 이미준 (서비스 기획자)
|
||||||
- **버전**: 1.5.2
|
- **버전**: 1.5.3
|
||||||
- **설계 철학**: Mobile First Design
|
- **설계 철학**: Mobile First Design
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 목차
|
## 목차
|
||||||
1. [설계 개요](#설계-개요)
|
1. [설계 개요](#설계-개요)
|
||||||
|
- [설계 목표](#설계-목표)
|
||||||
|
- [설계 원칙](#설계-원칙)
|
||||||
|
- [유저스토리 매핑](#유저스토리-매핑)
|
||||||
|
- [주요 추가 기능 (v1.1)](#주요-추가-기능-v11)
|
||||||
2. [프로토타입 화면 목록](#프로토타입-화면-목록)
|
2. [프로토타입 화면 목록](#프로토타입-화면-목록)
|
||||||
3. [화면 간 사용자 플로우](#화면-간-사용자-플로우)
|
3. [화면 간 사용자 플로우](#화면-간-사용자-플로우)
|
||||||
|
- [주요 사용자 시나리오별 플로우](#주요-사용자-시나리오별-플로우)
|
||||||
|
- [플로우 다이어그램](#플로우-다이어그램)
|
||||||
4. [화면별 상세 설계](#화면별-상세-설계)
|
4. [화면별 상세 설계](#화면별-상세-설계)
|
||||||
|
- [01-로그인](#01-로그인)
|
||||||
|
- [02-대시보드](#02-대시보드)
|
||||||
|
- [03-회의예약](#03-회의예약)
|
||||||
|
- [04-템플릿선택](#04-템플릿선택)
|
||||||
|
- [05-회의진행](#05-회의진행)
|
||||||
|
- [07-회의종료](#07-회의종료)
|
||||||
|
- [09-Todo관리](#09-todo관리)
|
||||||
|
- [10-회의록상세조회](#10-회의록상세조회)
|
||||||
|
- [11-회의록수정](#11-회의록수정)
|
||||||
|
- [12-회의록목록조회](#12-회의록목록조회)
|
||||||
5. [공통 UI 컴포넌트](#공통-ui-컴포넌트)
|
5. [공통 UI 컴포넌트](#공통-ui-컴포넌트)
|
||||||
6. [공통 에러 메시지 표준](#공통-에러-메시지-표준)
|
6. [공통 에러 메시지 표준](#공통-에러-메시지-표준)
|
||||||
|
- [네트워크 오류](#네트워크-오류)
|
||||||
|
- [데이터 로딩 실패](#데이터-로딩-실패)
|
||||||
|
- [권한 오류](#권한-오류)
|
||||||
|
- [인증 오류](#인증-오류)
|
||||||
|
- [입력 검증 오류](#입력-검증-오류)
|
||||||
|
- [서버 오류](#서버-오류)
|
||||||
7. [화면 간 전환 및 네비게이션](#화면-간-전환-및-네비게이션)
|
7. [화면 간 전환 및 네비게이션](#화면-간-전환-및-네비게이션)
|
||||||
8. [반응형 설계 전략](#반응형-설계-전략)
|
8. [반응형 설계 전략](#반응형-설계-전략)
|
||||||
|
- [브레이크포인트](#브레이크포인트)
|
||||||
|
- [레이아웃 전략](#레이아웃-전략)
|
||||||
|
- [컴포넌트별 반응형 전략](#컴포넌트별-반응형-전략)
|
||||||
|
- [이미지 및 미디어](#이미지-및-미디어)
|
||||||
9. [접근성 보장 방안](#접근성-보장-방안)
|
9. [접근성 보장 방안](#접근성-보장-방안)
|
||||||
10. [성능 최적화 방안](#성능-최적화-방안)
|
10. [성능 최적화 방안](#성능-최적화-방안)
|
||||||
|
- [1. 로딩 성능](#1-로딩-성능)
|
||||||
|
- [2. 렌더링 성능](#2-렌더링-성능)
|
||||||
|
- [3. 네트워크 최적화](#3-네트워크-최적화)
|
||||||
|
- [4. 실시간 동기화 최적화](#4-실시간-동기화-최적화)
|
||||||
|
- [5. 성능 모니터링](#5-성능-모니터링)
|
||||||
|
- [성능 목표](#성능-목표)
|
||||||
11. [변경 이력](#변경-이력)
|
11. [변경 이력](#변경-이력)
|
||||||
|
12. [부록](#부록)
|
||||||
|
- [참고 자료](#참고-자료)
|
||||||
|
- [디자인 시스템 (추후 작성)](#디자인-시스템-추후-작성)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -72,14 +107,16 @@
|
|||||||
- 관련도 표시 (퍼센트 또는 별점)
|
- 관련도 표시 (퍼센트 또는 별점)
|
||||||
- 최대 3개 자동 표시, 더보기로 전체 목록 확인 가능
|
- 최대 3개 자동 표시, 더보기로 전체 목록 확인 가능
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 프로토타입 화면 목록
|
## 프로토타입 화면 목록
|
||||||
|
|
||||||
| 번호 | 화면명 | 관련 유저스토리 | 비즈니스 중요도 | 사이드바 유무 | 이전화면 이동버튼 유무 | 비고 |
|
| 번호 | 화면명 | 관련 유저스토리 | 비즈니스 중요도 | 설명 | 사이드바 유무 | 이전화면 이동버튼 유무 | 비고 |
|
||||||
|------|--------|----------------|-------------------|-----------|------------------------|-------|
|
|------|--------|----------------|-------------------|------------------------|------------|------------------------|-------|
|
||||||
| 01 | 로그인 | UFR-USER-010 | 필수 | 사용자 인증 | X | X | |
|
| 01 | 로그인 | UFR-USER-010 | 필수 | 사용자 인증 | X | X | |
|
||||||
| 02 | 대시보드 | - | 필수 | 메인 랜딩 페이지 | O | X | |
|
| 02 | 대시보드 | UFR-USER-020 | 필수 | 메인 랜딩 페이지 | O | X | |
|
||||||
| 03 | 회의예약 | UFR-MEET-010 | 높음 | 회의 생성 | X | O | |
|
| 03 | 회의예약 | UFR-MEET-010 | 높음 | 회의 생성 | X | O | |
|
||||||
| 04 | 템플릿선택 | UFR-MEET-020 | 중간 | 회의록 템플릿 선택 | X | O | |
|
| 04 | 템플릿선택 | UFR-MEET-020 | 중간 | 회의록 템플릿 선택 | X | O | |
|
||||||
| 05 | 회의진행 | UFR-MEET-030, UFR-STT-010/020, UFR-AI-010, UFR-COLLAB-010 | 높음 | 실시간 회의 진행 및 회의록 작성 | X | X | |
|
| 05 | 회의진행 | UFR-MEET-030, UFR-STT-010/020, UFR-AI-010, UFR-COLLAB-010 | 높음 | 실시간 회의 진행 및 회의록 작성 | X | X | |
|
||||||
@ -89,6 +126,8 @@
|
|||||||
| 11 | 회의록수정 | UFR-MEET-055 | 중간 | 지난 회의록 수정 | X | O | |
|
| 11 | 회의록수정 | UFR-MEET-055 | 중간 | 지난 회의록 수정 | X | O | |
|
||||||
| 12 | 회의록목록조회 | UFR-MEET-046 | 높음 | 회의록 목록 필터링/정렬/검색 | O | X | |
|
| 12 | 회의록목록조회 | UFR-MEET-046 | 높음 | 회의록 목록 필터링/정렬/검색 | O | X | |
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 화면 간 사용자 플로우
|
## 화면 간 사용자 플로우
|
||||||
@ -143,6 +182,8 @@ graph TD
|
|||||||
E -.실시간 연동.-> L
|
E -.실시간 연동.-> L
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 화면별 상세 설계
|
## 화면별 상세 설계
|
||||||
@ -1824,6 +1865,8 @@ graph TD
|
|||||||
- 필터링 결과 없음: "조건에 맞는 회의록이 없습니다"
|
- 필터링 결과 없음: "조건에 맞는 회의록이 없습니다"
|
||||||
- 전체 회의록 없음: "회의록이 없습니다. 첫 회의를 시작해보세요!" + 회의 시작 버튼
|
- 전체 회의록 없음: "회의록이 없습니다. 첫 회의를 시작해보세요!" + 회의 시작 버튼
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 공통 UI 컴포넌트
|
## 공통 UI 컴포넌트
|
||||||
@ -1882,6 +1925,8 @@ graph TD
|
|||||||
- **Desktop (768px+)**:
|
- **Desktop (768px+)**:
|
||||||
- 프로필 아이콘 숨김 (사이드바 하단 영역 사용)
|
- 프로필 아이콘 숨김 (사이드바 하단 영역 사용)
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 공통 에러 메시지 표준
|
## 공통 에러 메시지 표준
|
||||||
@ -1921,6 +1966,8 @@ graph TD
|
|||||||
- **로깅**: 오류 상세 정보를 서버로 전송 (Sentry)
|
- **로깅**: 오류 상세 정보를 서버로 전송 (Sentry)
|
||||||
- **적용 화면**: 전체
|
- **적용 화면**: 전체
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 화면 간 전환 및 네비게이션
|
## 화면 간 전환 및 네비게이션
|
||||||
@ -1952,6 +1999,8 @@ graph TD
|
|||||||
- 특정 Todo 직접 접근: `/todo/{todoId}`
|
- 특정 Todo 직접 접근: `/todo/{todoId}`
|
||||||
- 회의록 공유 링크: `/share/{shareToken}`
|
- 회의록 공유 링크: `/share/{shareToken}`
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 반응형 설계 전략
|
## 반응형 설계 전략
|
||||||
@ -2003,6 +2052,8 @@ graph TD
|
|||||||
- Lazy Loading: 뷰포트 진입 시 로딩
|
- Lazy Loading: 뷰포트 진입 시 로딩
|
||||||
- 최적화: WebP 포맷, 적절한 압축
|
- 최적화: WebP 포맷, 적절한 압축
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 접근성 보장 방안
|
## 접근성 보장 방안
|
||||||
@ -2040,6 +2091,8 @@ graph TD
|
|||||||
- 자동 테스트: Lighthouse, axe DevTools
|
- 자동 테스트: Lighthouse, axe DevTools
|
||||||
- 수동 테스트: 키보드 네비게이션, 스크린 리더 (NVDA, JAWS, VoiceOver)
|
- 수동 테스트: 키보드 네비게이션, 스크린 리더 (NVDA, JAWS, VoiceOver)
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 성능 최적화 방안
|
## 성능 최적화 방안
|
||||||
@ -2091,6 +2144,8 @@ graph TD
|
|||||||
- **STT 지연 시간**: < 1s
|
- **STT 지연 시간**: < 1s
|
||||||
- **실시간 동기화 지연**: < 500ms
|
- **실시간 동기화 지연**: < 500ms
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 변경 이력
|
## 변경 이력
|
||||||
@ -2132,7 +2187,10 @@ graph TD
|
|||||||
| 1.4.19 | 2025-10-24 | 강지수 | 05-회의진행 화면 설계서 프로토타입 기준 전면 수정<br>- **레이아웃 구조 변경**: "2열 구조" 표현 제거, "메인 콘텐츠 영역: 정보 패널 (탭 구조)"로 단순화<br> - 텍스트 편집 영역 관련 내용 모두 제거 (왼쪽 영역, 에디터 툴바, contentEditable 등)<br> - 현재 프로토타입은 헤더 + 탭 콘텐츠 구조만 보유<br>- **반응형 디자인 명확화**: Mobile/Desktop 모두 동일한 구조에 너비만 반응형<br> - "2열 구조를 1열로 전환", "바텀시트" 표현 제거<br> - Mobile: 전체 너비 사용, Desktop: 최대 너비 제한 없이 반응형<br>- **AI 제안 탭 기능 명확화**: 논의항목/결정사항 구분 제거<br> - "논의항목/결정사항 등의 구분 없이 중요 내용을 주요 메모로 제안" 명시<br> - AI는 단순히 중요한 내용을 주요 메모 항목으로 제안하는 역할만 수행<br>- **용어 사전 검색 기능 추가**: 검색 입력창 + 검색 버튼<br> - Enter 키 지원, 용어명과 정의 모두 검색<br> - 검색 동작 상세 설명: 일치하는 용어만 표시, 하이라이트 효과, 결과 없으면 전체 목록 표시<br>- **인터랙션 섹션 정리**: 텍스트 편집, 툴바 사용, 충돌 감지 등 편집 관련 내용 모두 제거<br> - 탭 전환, 회의 종료, 실시간 업데이트만 유지<br> - 실시간 업데이트 항목을 현재 화면에 맞게 수정 (AI 제안, 용어 사전, 관련 회의록)<br>- **데이터 요구사항 업데이트**: 사용자 편집 내용 제거, 참석자 초대 이메일 추가<br> - AI 제안을 "주요 메모 항목 제안"으로 명확히 표현<br>- **에러 처리 업데이트**: 편집 충돌 에러 제거, 용어 사전 로드 실패/참석자 초대 실패 추가<br>- **주요 기능 목록 정리**: 실시간 협업/수동 편집 제거, AI 주요 메모 제안/참석자 관리 추가<br>- **권한 항목 수정**: "회의록 편집: 모든 참석자" → "참석자 초대: 모든 참석자"<br>- **프로토타입 기준 반영**: 05-회의진행.html 실제 구현 상태 100% 반영 |
|
| 1.4.19 | 2025-10-24 | 강지수 | 05-회의진행 화면 설계서 프로토타입 기준 전면 수정<br>- **레이아웃 구조 변경**: "2열 구조" 표현 제거, "메인 콘텐츠 영역: 정보 패널 (탭 구조)"로 단순화<br> - 텍스트 편집 영역 관련 내용 모두 제거 (왼쪽 영역, 에디터 툴바, contentEditable 등)<br> - 현재 프로토타입은 헤더 + 탭 콘텐츠 구조만 보유<br>- **반응형 디자인 명확화**: Mobile/Desktop 모두 동일한 구조에 너비만 반응형<br> - "2열 구조를 1열로 전환", "바텀시트" 표현 제거<br> - Mobile: 전체 너비 사용, Desktop: 최대 너비 제한 없이 반응형<br>- **AI 제안 탭 기능 명확화**: 논의항목/결정사항 구분 제거<br> - "논의항목/결정사항 등의 구분 없이 중요 내용을 주요 메모로 제안" 명시<br> - AI는 단순히 중요한 내용을 주요 메모 항목으로 제안하는 역할만 수행<br>- **용어 사전 검색 기능 추가**: 검색 입력창 + 검색 버튼<br> - Enter 키 지원, 용어명과 정의 모두 검색<br> - 검색 동작 상세 설명: 일치하는 용어만 표시, 하이라이트 효과, 결과 없으면 전체 목록 표시<br>- **인터랙션 섹션 정리**: 텍스트 편집, 툴바 사용, 충돌 감지 등 편집 관련 내용 모두 제거<br> - 탭 전환, 회의 종료, 실시간 업데이트만 유지<br> - 실시간 업데이트 항목을 현재 화면에 맞게 수정 (AI 제안, 용어 사전, 관련 회의록)<br>- **데이터 요구사항 업데이트**: 사용자 편집 내용 제거, 참석자 초대 이메일 추가<br> - AI 제안을 "주요 메모 항목 제안"으로 명확히 표현<br>- **에러 처리 업데이트**: 편집 충돌 에러 제거, 용어 사전 로드 실패/참석자 초대 실패 추가<br>- **주요 기능 목록 정리**: 실시간 협업/수동 편집 제거, AI 주요 메모 제안/참석자 관리 추가<br>- **권한 항목 수정**: "회의록 편집: 모든 참석자" → "참석자 초대: 모든 참석자"<br>- **프로토타입 기준 반영**: 05-회의진행.html 실제 구현 상태 100% 반영 |
|
||||||
| 1.4.20 | 2025-10-25 | 이미준, 강지수 | 유저스토리 v2.3.0 반영<br>- 회의 종료 화면 정책 명확화 (확인 전용, 바로 최종 확정 옵션 상세화)<br>- UFR-MEET-050: 최종 확정 2가지 시나리오 설명 추가<br>- UFR-COLLAB-020: 안건 기반 충돌 해결 메커니즘 상세 추가<br>- 실시간 협업 충돌 방지 정책 강화 |
|
| 1.4.20 | 2025-10-25 | 이미준, 강지수 | 유저스토리 v2.3.0 반영<br>- 회의 종료 화면 정책 명확화 (확인 전용, 바로 최종 확정 옵션 상세화)<br>- UFR-MEET-050: 최종 확정 2가지 시나리오 설명 추가<br>- UFR-COLLAB-020: 안건 기반 충돌 해결 메커니즘 상세 추가<br>- 실시간 협업 충돌 방지 정책 강화 |
|
||||||
| 1.5.1 | 2025-10-27 | 강지수 | MVP 스코프 축소 v2.4.0 반영 (4개 화면 수정)<br>- **02-대시보드**: Todo 위젯 및 통계 제거 (UFR-USER-020 반영)<br> - Todo 위젯 전체 제거 (나의 Todo 섹션 삭제)<br> - 통계 카드: "나의 Todo" 제거, "작성중 회의록" 유지 (2개 항목)<br> - 네비게이션: 하단 네비게이션 및 사이드바에서 Todo 관리 메뉴 제거<br> - Desktop 통계 그리드: 2개 항목만 표시<br>- **05-회의진행**: "AI 제안" 탭 → "AI 기반 메모" 탭 기능 변경<br> - 메모 입력창 + 저장 버튼 추가<br> - AI가 감지한 주요 내용 리스트 표시 (시간 + 내용)<br> - 각 참석자별 개별 저장, 다른 참석자 메모 볼 수 없음<br> - 메모는 회의 종료 전까지만 표시/편집 가능<br> - 에러 처리: AI 주요 내용 감지 실패, 메모 저장 실패 추가<br>- **10-회의록상세조회**: Todo 단순 조회 기능으로 변경<br> - Todo는 제목 + 담당자 + 마감일만 표시<br> - D-day 라벨, 우선순위 배지, 진행률 바, 상태별 필터 제거<br> - Todo 관리 화면 연동 링크 제거 (화면 자체가 제거됨)<br> - "수정" 버튼을 헤더로 이동<br>- **11-회의록수정**: 실시간 협업 기능 제거, 안건 기반 충돌 방지 강화<br> - "편집 중" 표시 제거 (실시간 협업 기능 제거)<br> - Todo 편집/추가/삭제 기능 전체 제거 (단순 조회만 가능)<br> - AI 한줄 요약 재생성 불가 (회의 종료 시 1회만 생성)<br> - 검증률 표시 및 최종 확정 버튼 제거<br> - 저장 로직 추가: 검증완료 안건 저장 스킵, 저장 결과 알림<br> - 안건별 검증 완료 체크박스로 충돌 방지 (Last Write Wins 적용)<br> - 에러 처리: 충돌 경고 모달 제거 (LWW로 인해) |
|
| 1.5.1 | 2025-10-27 | 강지수 | MVP 스코프 축소 v2.4.0 반영 (4개 화면 수정)<br>- **02-대시보드**: Todo 위젯 및 통계 제거 (UFR-USER-020 반영)<br> - Todo 위젯 전체 제거 (나의 Todo 섹션 삭제)<br> - 통계 카드: "나의 Todo" 제거, "작성중 회의록" 유지 (2개 항목)<br> - 네비게이션: 하단 네비게이션 및 사이드바에서 Todo 관리 메뉴 제거<br> - Desktop 통계 그리드: 2개 항목만 표시<br>- **05-회의진행**: "AI 제안" 탭 → "AI 기반 메모" 탭 기능 변경<br> - 메모 입력창 + 저장 버튼 추가<br> - AI가 감지한 주요 내용 리스트 표시 (시간 + 내용)<br> - 각 참석자별 개별 저장, 다른 참석자 메모 볼 수 없음<br> - 메모는 회의 종료 전까지만 표시/편집 가능<br> - 에러 처리: AI 주요 내용 감지 실패, 메모 저장 실패 추가<br>- **10-회의록상세조회**: Todo 단순 조회 기능으로 변경<br> - Todo는 제목 + 담당자 + 마감일만 표시<br> - D-day 라벨, 우선순위 배지, 진행률 바, 상태별 필터 제거<br> - Todo 관리 화면 연동 링크 제거 (화면 자체가 제거됨)<br> - "수정" 버튼을 헤더로 이동<br>- **11-회의록수정**: 실시간 협업 기능 제거, 안건 기반 충돌 방지 강화<br> - "편집 중" 표시 제거 (실시간 협업 기능 제거)<br> - Todo 편집/추가/삭제 기능 전체 제거 (단순 조회만 가능)<br> - AI 한줄 요약 재생성 불가 (회의 종료 시 1회만 생성)<br> - 검증률 표시 및 최종 확정 버튼 제거<br> - 저장 로직 추가: 검증완료 안건 저장 스킵, 저장 결과 알림<br> - 안건별 검증 완료 체크박스로 충돌 방지 (Last Write Wins 적용)<br> - 에러 처리: 충돌 경고 모달 제거 (LWW로 인해) |
|
||||||
| 1.5.2 | 2025-10-27 | 강지수 | AI 요약 기능 통합 및 단순화 (유저스토리 v2.4.1 반영)<br>- **11-회의록수정**: AI 요약 기능 통합<br> - 명칭 변경: "AI 상세 요약" → "AI 요약"<br> - AI 요약 영역: AI 한줄 요약만 표시 (30자 이내, 읽기 전용)<br> - 텍스트 편집 영역: 안건 내용 자유 작성 (논의 주제, 발언자별 의견, 결정 사항 등)<br> - "AI 재생성" 버튼: 텍스트 편집 영역 내용 기반으로 AI 요약의 한줄 요약 재생성 (2-5초 처리)<br> - 재생성된 한줄 요약은 회의록 상세조회 화면의 대시보드 및 회의록 탭에 즉시 반영<br> - AI 상세 요약 및 한줄 요약 분리 표시 제거<br>- **프로토타입 UI 개선**:<br> - AI 재생성 버튼 스타일 통일: btn-secondary → btn-primary (다른 화면과 일관성)<br> - 안건별 검증완료 UI 단순화: 참석자는 체크박스만, 회의 생성자는 검증완료 시 잠금해제 버튼 표시<br> - .creator-only CSS 클래스 추가: data-is-creator 속성 기반 표시 제어<br>- **관련 유저스토리**: UFR-AI-036 (AI 한줄요약 확인 및 재생성), UFR-MEET-055 (안건별 검증), UFR-COLLAB-030 (충돌 방지) |
|
| 1.5.2 | 2025-10-27 | 강지수 | AI 요약 기능 통합 및 단순화 (유저스토리 v2.4.0 반영)<br>- **11-회의록수정**: AI 요약 기능 통합<br> - 명칭 변경: "AI 상세 요약" → "AI 요약"<br> - AI 요약 영역: AI 한줄 요약만 표시 (30자 이내, 읽기 전용)<br> - 텍스트 편집 영역: 안건 내용 자유 작성 (논의 주제, 발언자별 의견, 결정 사항 등)<br> - "AI 재생성" 버튼: 텍스트 편집 영역 내용 기반으로 AI 요약의 한줄 요약 재생성 (2-5초 처리)<br> - 재생성된 한줄 요약은 회의록 상세조회 화면의 대시보드 및 회의록 탭에 즉시 반영<br> - AI 상세 요약 및 한줄 요약 분리 표시 제거<br>- **프로토타입 UI 개선**:<br> - AI 재생성 버튼 스타일 통일: btn-secondary → btn-primary (다른 화면과 일관성)<br> - 안건별 검증완료 UI 단순화: 참석자는 체크박스만, 회의 생성자는 검증완료 시 잠금해제 버튼 표시<br> - .creator-only CSS 클래스 추가: data-is-creator 속성 기반 표시 제어<br>- **관련 유저스토리**: UFR-AI-036 (AI 한줄요약 확인 및 재생성), UFR-MEET-055 (안건별 검증), UFR-COLLAB-030 (충돌 방지) |
|
||||||
|
| 1.5.3 | 2025-10-27 | 강지수 | Todo 추가/편집 권한 정책 명확화 (유저스토리 v2.4.1 반영)<br>- **10-회의록상세조회**: Todo 추가/편집 권한 정책 추가 (대시보드 탭)<br> - "추가" 버튼: 모든 회의 참석자에게 노출 (Todo 리스트 우측 상단)<br> - "편집(✏️)" 버튼: 회의 생성자에게만 노출 (각 Todo 항목 우측)<br> - Todo 추가 모달: 제목, 담당자, 마감일 입력 (모든 참석자)<br> - Todo 편집 모달: 제목, 담당자, 마감일 수정 (회의 생성자만)<br> - 담당자 필드: 추가 시 또는 생성자의 편집 시만 표시<br>- **프로토타입 UI 개선**: 10-회의록상세조회.html<br> - Todo 추가/편집 모달 바텀시트 스타일 통일 (모바일: 하단 슬라이드 업, 데스크톱: 중앙 모달)<br> - .creator-only 클래스 적용하여 편집 버튼 권한별 표시/숨김 처리<br> - JavaScript initPage() 함수에서 회의 생성자 여부 확인 후 creator-only 요소 제어<br> - Todo 추가 성공: "담당자에게 알림이 전송되었습니다" → "캘린더가 업데이트되었습니다" 순차 토스트<br> - Todo 편집 성공: 담당자 변경 시 알림, 마감일 변경 시 캘린더 업데이트 토스트<br>- **관련 유저스토리**: UFR-MEET-047 (회의록상세조회), Todo 권한 정책 신규 추가 |
|
||||||
|
|
||||||
|
[↑ 목차로 돌아가기](#목차)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
203
design/userstory-list.md
Normal file
203
design/userstory-list.md
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
# 유저스토리 목록 (v2.4.1)
|
||||||
|
|
||||||
|
최종 수정일: 2025-10-27
|
||||||
|
|
||||||
|
## 📋 전체 유저스토리 목록
|
||||||
|
|
||||||
|
| ID | 서비스 | 역할 | 제목 | As a | I want to | So that | 상태 |
|
||||||
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| UFR-USER-010 | User | 사용자 | 로그인 | 사용자로서 | 사번과 비밀번호로 로그인 | 시스템에 접근하기 위해 | ✅ |
|
||||||
|
| UFR-USER-020 | User | 사용자 | 대시보드 | 사용자로서 | 대시보드를 조회 | 나의 회의 현황을 파악하기 위해 | ✅ |
|
||||||
|
| UFR-MEET-010 | Meeting | 회의 생성자 | 회의예약 | 회의 생성자로서 | 회의를 예약하고 참석자를 초대 | 회의를 효율적으로 준비하기 위해 | ✅ |
|
||||||
|
| UFR-MEET-015 | Meeting | 회의 참석자 | 회의진행 중 참석자 초대 | 회의 참석자로서 | 실시간으로 참석자를 초대 | 회의 중 추가 참석자가 필요할 때 | ✅ |
|
||||||
|
| UFR-MEET-020 | Meeting | 회의 생성자 | 템플릿선택 | 회의 생성자로서 | 회의 유형에 맞는 템플릿을 선택 | 회의록을 효율적으로 작성하기 위해 | ✅ |
|
||||||
|
| UFR-MEET-030 | Meeting | 회의 생성자 | 회의시작 | 회의 생성자로서 | 회의를 시작하고 음성 녹음을 준비 | 회의를 시작하고 회의록을 작성하기 위해 | ✅ v2.4.1 개선 |
|
||||||
|
| UFR-MEET-040 | Meeting | 회의 생성자 | 회의종료 | 회의 생성자로서 | 회의를 종료하고 요약 내용을 확인한 후 다음 단계를 선택 | 회의를 종료하고 회의록을 정리하기 위해 | ✅ v2.4.1 수정 |
|
||||||
|
| UFR-MEET-050 | Meeting | 회의 생성자 | 최종확정 | 회의 생성자로서 | 모든 안건을 검증하고 최종 회의록을 확정 | 회의록을 완성하기 위해 | ✅ |
|
||||||
|
| UFR-MEET-046 | Meeting | 회의 참석자 | 회의록목록조회 | 회의 참석자로서 | 회의록 목록을 조회하고 필터링 | 참여한 회의록들을 효율적으로 관리하기 위해 | ✅ |
|
||||||
|
| UFR-MEET-047 | Meeting | 회의 참석자 | 회의록상세조회 | 회의 참석자로서 | 지난 회의록의 상세 정보와 전체 내용을 한눈에 확인 | 회의록을 효율적으로 검토하기 위해 | ✅ |
|
||||||
|
| UFR-MEET-055 | Meeting | 회의 참석자 | 회의록수정 | 회의 참석자로서 | 검증이 완료되지 않은 안건을 수정하고 검증완료 체크 | 회의록의 정확성을 보장하기 위해 | ✅ |
|
||||||
|
| UFR-AI-010 | AI | 회의 참석자 | 회의록자동작성 | 회의 참석자로서 | AI가 발언 내용을 실시간으로 정리하고 회의 종료 시 전체 안건을 요약 | 회의록 작성 부담을 줄이기 위해 | ✅ |
|
||||||
|
| UFR-AI-020 | AI | 회의 참석자 | Todo자동추출 | 회의 참석자로서 | AI가 안건별 내용에서 Todo 항목을 자동으로 추출하고 기본값을 설정 | 회의 후 실행 사항을 명확히 하기 위해 | ✅ |
|
||||||
|
| UFR-AI-030 | AI | 회의 참석자 | 실시간AI제안 | 회의 참석자로서 | AI가 실시간으로 주요 내용을 분석하여 제안 | 회의 중 놓치는 내용을 최소화하기 위해 | ✅ |
|
||||||
|
| UFR-AI-036 | AI | 회의 참석자 | AI한줄요약 | 회의 참석자로서 | AI가 생성한 한줄 요약을 확인하고 필요 시 재생성 | 각 안건의 핵심을 빠르게 파악하기 위해 | ✅ |
|
||||||
|
| UFR-AI-040 | AI | 회의 참석자 | 관련회의록연결 | 회의 참석자로서 | AI가 같은 폴더 내 관련 있는 과거 회의록을 자동으로 찾아 연결하고 유사 내용을 요약 | 이전 회의 내용을 쉽게 참조하기 위해 | ✅ v2.4.1 개선 |
|
||||||
|
| UFR-STT-010 | STT | 회의 참석자 | 음성녹음인식 | 회의 참석자로서 | 음성이 실시간으로 녹음되고 인식 | 발언 내용이 자동으로 기록되기 위해 | ✅ |
|
||||||
|
| UFR-STT-020 | STT | 시스템 | 텍스트변환 | 회의록 시스템으로서 | 음성을 텍스트로 변환 | 인식된 발언을 회의록에 기록하기 위해 | ✅ |
|
||||||
|
| UFR-RAG-010 | AI (RAG) | 회의 참석자 | 전문용어감지 | 회의 참석자로서 | 전문용어가 자동으로 감지되고 맥락에 맞는 설명을 제공 | 업무 지식이 없어도 회의록을 정확히 작성하기 위해 | ✅ |
|
||||||
|
| UFR-RAG-020 | AI (RAG) | 회의 참석자 | 맥락기반용어설명 | 회의 참석자로서 | 관련 회의록과 업무 이력을 바탕으로 실용적인 설명을 제공 | 전문용어를 맥락에 맞게 이해하기 위해 | ✅ |
|
||||||
|
| UFR-COLLAB-010 | Meeting | 회의 참석자 | 회의록수정동기화 | 회의 참석자로서 | 회의록을 수정하고 실시간으로 다른 참석자와 동기화 | 회의록을 함께 검증하기 위해 | ✅ |
|
||||||
|
| UFR-COLLAB-020 | Meeting | 회의 참석자 | 충돌해결 | 회의 참석자로서 | 안건별로 충돌 없이 편집 | 동시 수정 상황에서도 내용을 잃지 않기 위해 | ✅ |
|
||||||
|
| UFR-COLLAB-030 | Meeting | 회의 참석자 | 검증완료 | 회의 참석자로서 | 각 안건을 검증하고 완료 표시 | 회의록의 정확성을 보장하기 위해 | ✅ |
|
||||||
|
| UFR-NOTI-010 | Notification | 시스템 | 알림발송 | Notification 시스템으로서 | 주기적으로 알림 대상을 확인하여 이메일을 발송 | 사용자에게 중요한 이벤트를 알리기 위해 | ✅ |
|
||||||
|
| UFR-PART-010 | Meeting | 회의 참석자 | 회의입장 | 회의 참석자로서 | 대시보드에서 "참여하기" 버튼으로 회의에 입장 | 예정된 회의에 참여하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-PART-020 | Meeting | 회의 참석자 | AI기반메모작성 | 회의 참석자로서 | AI가 추천한 주요 내용을 메모 입력창에 추가하고 편집 | 중요한 내용을 메모로 기록하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-PART-030 | Meeting | 회의 참석자 | 회의중도퇴장 | 회의 참석자로서 | "나가기" 버튼으로 회의에서 퇴장 | 회의를 중간에 나가야 할 때 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-HOST-010 | Meeting | 회의 생성자 | 회의종료권한 | 회의 생성자로서 | "회의 종료" 버튼으로만 회의를 종료 | 회의를 마무리하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-HOST-020 | Meeting | 회의 생성자 | 녹음제어권한 | 회의 생성자로서 | 녹음 일시정지/재개/종료 권한을 가짐 | 녹음을 관리하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-TERM-010 | AI | 회의 참석자 | 용어자동감지 | 회의 참석자로서 | AI가 자동으로 감지한 용어를 "용어" 탭에서 확인 | 전문용어를 이해하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-TERM-020 | AI | 회의 참석자 | 회사용어사전 | 회의 참석자로서 | 회사 용어 사전에 등록된 용어를 우선 표시 | 회사 특화 용어를 정확히 이해하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
| UFR-TERM-030 | AI | 관리자 | 용어관리 | 관리자로서 | 용어 사전을 등록/수정 | 회사 특화 용어를 관리하기 위해 | ✅ v2.4.1 신규 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 서비스별 유저스토리 개수
|
||||||
|
|
||||||
|
| 서비스 | 개수 | 유저스토리 ID |
|
||||||
|
|---|:---:|---|
|
||||||
|
| **User** | 2 | UFR-USER-010, UFR-USER-020 |
|
||||||
|
| **Meeting** | 16 | UFR-MEET-010, UFR-MEET-015, UFR-MEET-020, UFR-MEET-030, UFR-MEET-040, UFR-MEET-050, UFR-MEET-046, UFR-MEET-047, UFR-MEET-055, UFR-COLLAB-010, UFR-COLLAB-020, UFR-COLLAB-030, UFR-PART-010, UFR-PART-020, UFR-PART-030, UFR-HOST-010, UFR-HOST-020 |
|
||||||
|
| **AI** | 9 | UFR-AI-010, UFR-AI-020, UFR-AI-030, UFR-AI-036, UFR-AI-040, UFR-RAG-010, UFR-RAG-020, UFR-TERM-010, UFR-TERM-020, UFR-TERM-030 |
|
||||||
|
| **STT** | 2 | UFR-STT-010, UFR-STT-020 |
|
||||||
|
| **Notification** | 1 | UFR-NOTI-010 |
|
||||||
|
| **전체** | **32** | - |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 👥 역할별 유저스토리 분류
|
||||||
|
|
||||||
|
### 회의 생성자 (Host) - 7개
|
||||||
|
| ID | 제목 | 핵심 기능 |
|
||||||
|
|---|---|---|
|
||||||
|
| UFR-MEET-010 | 회의예약 | 회의 예약 및 참석자 초대 |
|
||||||
|
| UFR-MEET-020 | 템플릿선택 | 회의 템플릿 선택 |
|
||||||
|
| UFR-MEET-030 | 회의시작 | 회의 시작 및 녹음 준비 |
|
||||||
|
| UFR-MEET-040 | 회의종료 | 회의 종료 및 요약 확인 |
|
||||||
|
| UFR-MEET-050 | 최종확정 | 회의록 최종 확정 |
|
||||||
|
| UFR-HOST-010 | 회의종료권한 | 회의 종료 전용 권한 |
|
||||||
|
| UFR-HOST-020 | 녹음제어권한 | 녹음 제어 전용 권한 |
|
||||||
|
|
||||||
|
### 회의 참석자 (Participant) - 19개
|
||||||
|
| ID | 제목 | 핵심 기능 |
|
||||||
|
|---|---|---|
|
||||||
|
| UFR-MEET-015 | 회의진행 중 참석자 초대 | 실시간 참석자 추가 |
|
||||||
|
| UFR-MEET-046 | 회의록목록조회 | 회의록 목록 조회 및 필터링 |
|
||||||
|
| UFR-MEET-047 | 회의록상세조회 | 회의록 상세 정보 조회 |
|
||||||
|
| UFR-MEET-055 | 회의록수정 | 회의록 수정 및 검증 |
|
||||||
|
| UFR-AI-010 | 회의록자동작성 | AI 회의록 자동 작성 |
|
||||||
|
| UFR-AI-020 | Todo자동추출 | AI Todo 자동 추출 |
|
||||||
|
| UFR-AI-030 | 실시간AI제안 | 실시간 AI 주요 내용 제안 |
|
||||||
|
| UFR-AI-036 | AI한줄요약 | AI 한줄 요약 생성 |
|
||||||
|
| UFR-AI-040 | 관련회의록연결 | AI 관련 회의록 자동 연결 |
|
||||||
|
| UFR-STT-010 | 음성녹음인식 | 음성 실시간 녹음 및 인식 |
|
||||||
|
| UFR-RAG-010 | 전문용어감지 | 전문용어 자동 감지 |
|
||||||
|
| UFR-RAG-020 | 맥락기반용어설명 | 맥락 기반 용어 설명 |
|
||||||
|
| UFR-COLLAB-010 | 회의록수정동기화 | 실시간 회의록 동기화 |
|
||||||
|
| UFR-COLLAB-020 | 충돌해결 | 안건별 충돌 방지 |
|
||||||
|
| UFR-COLLAB-030 | 검증완료 | 안건 검증 완료 표시 |
|
||||||
|
| UFR-PART-010 | 회의입장 | 회의 입장 |
|
||||||
|
| UFR-PART-020 | AI기반메모작성 | AI 추천 메모 작성 |
|
||||||
|
| UFR-PART-030 | 회의중도퇴장 | 회의 중도 퇴장 |
|
||||||
|
| UFR-TERM-010 | 용어자동감지 | 용어 자동 감지 및 표시 |
|
||||||
|
| UFR-TERM-020 | 회사용어사전 | 회사 특화 용어 우선 표시 |
|
||||||
|
|
||||||
|
### 관리자 (Admin) - 1개
|
||||||
|
| ID | 제목 | 핵심 기능 |
|
||||||
|
|---|---|---|
|
||||||
|
| UFR-TERM-030 | 용어관리 | 용어 사전 등록/수정 |
|
||||||
|
|
||||||
|
### 시스템 (System) - 3개
|
||||||
|
| ID | 제목 | 핵심 기능 |
|
||||||
|
|---|---|---|
|
||||||
|
| UFR-STT-020 | 텍스트변환 | 음성-텍스트 변환 |
|
||||||
|
| UFR-NOTI-010 | 알림발송 | 이메일 알림 자동 발송 |
|
||||||
|
| UFR-USER-010 | 로그인 | 사용자 인증 |
|
||||||
|
| UFR-USER-020 | 대시보드 | 대시보드 조회 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🆕 v2.4.1 변경 사항 (2025-10-27)
|
||||||
|
|
||||||
|
### 신규 유저스토리 (8개)
|
||||||
|
|
||||||
|
| ID | 제목 | 분류 | 설명 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| UFR-PART-010 | 회의입장 | 참석자 공통 | 대시보드에서 "참여하기" 버튼으로 회의 입장 |
|
||||||
|
| UFR-PART-020 | AI기반메모작성 | 참석자 공통 | AI 추천 주요 내용을 메모 입력창에 추가 및 편집 |
|
||||||
|
| UFR-PART-030 | 회의중도퇴장 | 참석자 공통 | "나가기" 버튼으로 회의 퇴장 |
|
||||||
|
| UFR-HOST-010 | 회의종료권한 | 생성자 전용 | 생성자만 "회의 종료" 버튼 사용 가능 |
|
||||||
|
| UFR-HOST-020 | 녹음제어권한 | 생성자 전용 | 생성자만 녹음 일시정지/재개/종료 가능 |
|
||||||
|
| UFR-TERM-010 | 용어자동감지 | AI 기능 | AI가 자동으로 감지한 용어를 "용어" 탭에 표시 |
|
||||||
|
| UFR-TERM-020 | 회사용어사전 | AI 기능 | 회사 용어 사전(JSON) 우선 표시 |
|
||||||
|
| UFR-TERM-030 | 용어관리 | 관리 기능 | 관리자가 용어 사전 등록/수정 |
|
||||||
|
|
||||||
|
### 수정된 유저스토리 (3개)
|
||||||
|
|
||||||
|
| ID | 제목 | 수정 내용 |
|
||||||
|
|---|---|---|
|
||||||
|
| UFR-MEET-040 | 회의종료 | 회의 종료 권한을 생성자 전용으로 명확화, "확인 전용" 화면 정책 추가, 3가지 옵션 명확화 (회의록 수정/바로 최종 확정/대시보드) |
|
||||||
|
| UFR-MEET-030 | 회의시작 | 회의 진입 경로 2가지 명시 (바로시작, 참여하기), AI 제안 탭에 개인 메모 작성 영역 추가 (참석자별 독립) |
|
||||||
|
| UFR-AI-040 | 관련회의록연결 | 유사 내용 요약 추가 (최대 3개 추천, 관련도 퍼센트, 3-5문장 요약, 성능 목표 1초 이내) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 주요 기능별 유저스토리 매핑
|
||||||
|
|
||||||
|
### 회의 생명주기 (Meeting Lifecycle)
|
||||||
|
1. **회의 예약**: UFR-MEET-010
|
||||||
|
2. **템플릿 선택**: UFR-MEET-020
|
||||||
|
3. **회의 시작**: UFR-MEET-030, UFR-PART-010
|
||||||
|
4. **회의 진행**: UFR-STT-010, UFR-AI-010, UFR-AI-030, UFR-PART-020
|
||||||
|
5. **회의 종료**: UFR-MEET-040, UFR-HOST-010
|
||||||
|
6. **회의록 수정**: UFR-MEET-055, UFR-COLLAB-010, UFR-COLLAB-020
|
||||||
|
7. **최종 확정**: UFR-MEET-050, UFR-COLLAB-030
|
||||||
|
|
||||||
|
### AI 기능 (AI Features)
|
||||||
|
- **회의록 자동 작성**: UFR-AI-010
|
||||||
|
- **Todo 자동 추출**: UFR-AI-020
|
||||||
|
- **실시간 AI 제안**: UFR-AI-030
|
||||||
|
- **AI 한줄 요약**: UFR-AI-036
|
||||||
|
- **관련 회의록 연결**: UFR-AI-040
|
||||||
|
- **전문 용어 감지**: UFR-RAG-010, UFR-TERM-010
|
||||||
|
- **맥락 기반 용어 설명**: UFR-RAG-020, UFR-TERM-020
|
||||||
|
|
||||||
|
### 실시간 협업 (Real-time Collaboration)
|
||||||
|
- **참석자 초대**: UFR-MEET-015
|
||||||
|
- **수정 동기화**: UFR-COLLAB-010
|
||||||
|
- **충돌 해결**: UFR-COLLAB-020
|
||||||
|
- **검증 완료**: UFR-COLLAB-030
|
||||||
|
|
||||||
|
### 권한 관리 (Authorization)
|
||||||
|
- **생성자 전용**: UFR-HOST-010, UFR-HOST-020
|
||||||
|
- **참석자 공통**: UFR-PART-010, UFR-PART-020, UFR-PART-030
|
||||||
|
- **관리자 전용**: UFR-TERM-030
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 유저스토리 작성 규칙
|
||||||
|
|
||||||
|
본 문서의 유저스토리는 다음 형식을 따릅니다:
|
||||||
|
|
||||||
|
```
|
||||||
|
UFR-{SERVICE}-{NUMBER}: [{기능명}] {역할}로서 | 나는, {목적}를 위해 | {행동}을 하고 싶다.
|
||||||
|
```
|
||||||
|
|
||||||
|
### 서비스 코드
|
||||||
|
- **USER**: 사용자 인증 및 대시보드
|
||||||
|
- **MEET**: 회의 및 회의록 관리
|
||||||
|
- **AI**: AI 기반 자동화 기능
|
||||||
|
- **STT**: 음성-텍스트 변환
|
||||||
|
- **RAG**: 벡터 검색 및 맥락 기반 설명
|
||||||
|
- **COLLAB**: 실시간 협업 (Meeting 서비스에 통합)
|
||||||
|
- **NOTI**: 알림 발송
|
||||||
|
- **PART**: 회의 참석자 공통 기능
|
||||||
|
- **HOST**: 회의 생성자 전용 기능
|
||||||
|
- **TERM**: 용어 관리 기능
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📌 백로그 및 향후 계획
|
||||||
|
|
||||||
|
### Phase 2 후보 기능
|
||||||
|
- 회의 템플릿 커스터마이징
|
||||||
|
- Todo 대시보드 및 칸반 보드
|
||||||
|
- 회의록 버전 관리 및 변경 이력
|
||||||
|
- 회의 통계 및 분석 대시보드
|
||||||
|
- 다국어 지원 (음성 인식 및 UI)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 참고 문서
|
||||||
|
- 유저스토리 원본: [design/userstory.md](./userstory.md)
|
||||||
|
- UI/UX 설계서: [design/uiux/uiux.md](./uiux/uiux.md)
|
||||||
|
- 프로토타입: [design/uiux/prototype/](./uiux/prototype/)
|
||||||
@ -1,4 +1,4 @@
|
|||||||
# AI기반 회의록 작성 및 이력 관리 개선 서비스 - 유저스토리 (v2.4.0)
|
# AI기반 회의록 작성 및 이력 관리 개선 서비스 - 유저스토리 (v2.4.1)
|
||||||
|
|
||||||
## 목차
|
## 목차
|
||||||
- [차별화 전략](#차별화-전략)
|
- [차별화 전략](#차별화-전략)
|
||||||
@ -490,12 +490,30 @@
|
|||||||
- AI 상세 요약
|
- AI 상세 요약
|
||||||
- 관련회의록 링크
|
- 관련회의록 링크
|
||||||
4. "수정" 버튼 클릭 시 회의록 수정 화면으로 이동
|
4. "수정" 버튼 클릭 시 회의록 수정 화면으로 이동
|
||||||
|
5. Todo 리스트 영역 (대시보드 탭):
|
||||||
|
- "추가" 버튼: 모든 참석자에게 노출, 클릭 시 Todo 추가 모달 표시
|
||||||
|
- Todo 항목별 "편집" 버튼: 회의 생성자에게만 노출
|
||||||
|
- Todo 추가 모달: 제목, 담당자, 마감일 입력
|
||||||
|
- Todo 편집 모달: 제목, 마감일 수정 (회의 생성자만 담당자 변경 가능)
|
||||||
|
|
||||||
**입력:**
|
**입력:**
|
||||||
- 탭 클릭: 대시보드 / 회의록
|
- 탭 클릭: 대시보드 / 회의록
|
||||||
|
- Todo 추가 클릭: "추가" 버튼
|
||||||
|
- Todo 편집 클릭: Todo 항목별 "편집(✏️)" 버튼 (회의 생성자만)
|
||||||
|
- Todo 추가/편집 모달 입력:
|
||||||
|
- 제목: 텍스트, 필수
|
||||||
|
- 담당자: 드롭다운 선택, 필수 (추가 시 또는 편집 시 생성자만)
|
||||||
|
- 마감일: 날짜 선택, 필수
|
||||||
|
|
||||||
**출력/결과:**
|
**출력/결과:**
|
||||||
- 헤더: 회의 제목, "수정" 버튼 (제목 텍스트 바로 옆에 배치, 권한에 따라 표시)
|
- 헤더: 회의 제목, "수정" 버튼 (제목 텍스트 바로 옆에 배치, 권한에 따라 표시)
|
||||||
|
- Todo 리스트 (대시보드 탭):
|
||||||
|
- "추가" 버튼: 모든 참석자에게 표시
|
||||||
|
- Todo 항목별 "편집(✏️)" 버튼: 회의 생성자만 표시
|
||||||
|
- Todo 추가 성공: "Todo가 추가되었습니다" 성공 메시지 → "담당자에게 알림이 전송되었습니다" 정보 메시지 → "캘린더가 업데이트되었습니다" 정보 메시지
|
||||||
|
- Todo 편집 성공: "Todo가 수정되었습니다" 성공 메시지
|
||||||
|
- 담당자 변경 시: "이전 담당자와 새 담당자에게 알림이 전송되었습니다" 정보 메시지
|
||||||
|
- 마감일 변경 시: "캘린더가 업데이트되었습니다" 정보 메시지
|
||||||
- 대시보드 탭:
|
- 대시보드 탭:
|
||||||
- 통계, 키워드, 핵심내용, 결정사항, Todo 진행상황, 관련회의록
|
- 통계, 키워드, 핵심내용, 결정사항, Todo 진행상황, 관련회의록
|
||||||
- Todo 카드: 제목, 담당자, 마감일만 표시 (D-day, 우선순위 라벨 없음)
|
- Todo 카드: 제목, 담당자, 마감일만 표시 (D-day, 우선순위 라벨 없음)
|
||||||
@ -506,6 +524,18 @@
|
|||||||
- 회의록 조회 실패: "회의록 조회 중 오류가 발생했습니다" 에러 메시지
|
- 회의록 조회 실패: "회의록 조회 중 오류가 발생했습니다" 에러 메시지
|
||||||
- Todo 없음: "등록된 Todo가 없습니다" 빈 상태 표시
|
- Todo 없음: "등록된 Todo가 없습니다" 빈 상태 표시
|
||||||
- 관련회의록 없음: "관련 회의록이 없습니다" 빈 상태 표시
|
- 관련회의록 없음: "관련 회의록이 없습니다" 빈 상태 표시
|
||||||
|
- Todo 추가/편집 시 필수 입력 누락: "제목/담당자/마감일을 입력해주세요" 에러 메시지
|
||||||
|
- Todo 편집 권한 없음 (일반 참석자): 편집 버튼 미표시
|
||||||
|
|
||||||
|
**Todo 권한 정책 (v2.4.1 신규):**
|
||||||
|
- **Todo 추가**: 모든 회의 참석자 가능
|
||||||
|
- "추가" 버튼 모든 참석자에게 노출
|
||||||
|
- 추가 모달에서 제목, 담당자, 마감일 입력
|
||||||
|
- 담당자는 회의 참석자 중 선택
|
||||||
|
- **Todo 편집**: 회의 생성자만 가능
|
||||||
|
- 편집(✏️) 버튼은 회의 생성자에게만 노출
|
||||||
|
- 편집 모달에서 제목, 담당자, 마감일 수정 가능
|
||||||
|
- 일반 참석자는 편집 버튼이 보이지 않음
|
||||||
|
|
||||||
**관련 유저스토리:**
|
**관련 유저스토리:**
|
||||||
- UFR-MEET-046: 회의록목록조회
|
- UFR-MEET-046: 회의록목록조회
|
||||||
@ -1405,6 +1435,7 @@
|
|||||||
|
|
||||||
| 버전 | 날짜 | 작성자 | 변경 내용 |
|
| 버전 | 날짜 | 작성자 | 변경 내용 |
|
||||||
|------|------|--------|-----------|
|
|------|------|--------|-----------|
|
||||||
|
| v2.4.1 | 2025-10-27 | 팀 전체 | • UFR-MEET-047 개선: Todo 추가/편집 권한 정책 명확화<br> - Todo 추가: 모든 회의 참석자 가능 ("추가" 버튼 모든 참석자에게 노출)<br> - Todo 편집: 회의 생성자만 가능 (편집 버튼은 생성자에게만 노출)<br> - Todo 추가 모달: 제목, 담당자, 마감일 입력 (모든 참석자)<br> - Todo 편집 모달: 제목, 담당자, 마감일 수정 (생성자만, 바텀시트 스타일)<br>• 프로토타입 UI 개선: 10-회의록상세조회.html<br> - Todo 추가 모달과 편집 모달 바텀시트 스타일 통일<br> - 편집 버튼에 creator-only 클래스 적용하여 권한별 표시/숨김 처리 |
|
||||||
| v2.4.0 | 2025-10-27 | 팀 전체 | • MVP 스코프 축소: Todo 관리 기능 제거<br>• AI 요약 기능 통합 및 단순화<br>• UFR-USER-020 수정: 대시보드에서 "나의 Todo" 제거, "작성중 회의록" 추가<br>• UFR-PART-020 변경: AI주요내용체크 → AI기반메모작성 (메모 입력창 + AI 추천)<br>• UFR-AI-010 개선: 회의록 생성 시 참석자 메모 참조<br>• UFR-MEET-055 개선: 회의록 수정 시 실시간 협업 제거, 검증완료 체크로 보호<br> - 프로토타입 UI 개선: 안건별 검증완료 UI 단순화 (참석자: 체크박스만, 생성자: 검증완료 시 잠금해제 버튼)<br>• TODO 서비스 전체 제거 (UFR-TODO-010/030/040)<br>• NOTIFICATION 서비스: Todo 관련 알림 제거<br>• 네비게이션 간소화: Todo 관리 메뉴 제거 (대시보드, 회의록만 유지)<br>• UFR-MEET-030 개선: AI 제안 탭 내 개인 메모 작성 기능 명확화 (수동 저장만), 하단 고정 버튼 역할별 차별화 (생성자: 일시정지/재개+종료, 참석자: 나가기)<br>• UFR-AI-035 삭제: 섹션AI요약 제거 (중복 기능)<br>• UFR-AI-036 개선: AI 한줄요약 확인 및 재생성 기능 통합<br> - 회의 종료 시: 자동 생성 (읽기 전용)<br> - 회의록 수정 시: 텍스트 편집 영역 내용 기반 재생성 기능 추가<br> - "AI 상세요약" → "AI 요약"으로 명칭 변경<br> - 회의록 상세조회 화면의 대시보드 및 회의록 탭에 한줄요약 표시<br> - 프로토타입 UI 개선: AI 재생성 버튼 스타일 통일 (btn-secondary → btn-primary)<br>• UFR-COLLAB-030 개선: 안건 기반 충돌 방지 메커니즘 (검증완료 체크로 보호)|
|
| v2.4.0 | 2025-10-27 | 팀 전체 | • MVP 스코프 축소: Todo 관리 기능 제거<br>• AI 요약 기능 통합 및 단순화<br>• UFR-USER-020 수정: 대시보드에서 "나의 Todo" 제거, "작성중 회의록" 추가<br>• UFR-PART-020 변경: AI주요내용체크 → AI기반메모작성 (메모 입력창 + AI 추천)<br>• UFR-AI-010 개선: 회의록 생성 시 참석자 메모 참조<br>• UFR-MEET-055 개선: 회의록 수정 시 실시간 협업 제거, 검증완료 체크로 보호<br> - 프로토타입 UI 개선: 안건별 검증완료 UI 단순화 (참석자: 체크박스만, 생성자: 검증완료 시 잠금해제 버튼)<br>• TODO 서비스 전체 제거 (UFR-TODO-010/030/040)<br>• NOTIFICATION 서비스: Todo 관련 알림 제거<br>• 네비게이션 간소화: Todo 관리 메뉴 제거 (대시보드, 회의록만 유지)<br>• UFR-MEET-030 개선: AI 제안 탭 내 개인 메모 작성 기능 명확화 (수동 저장만), 하단 고정 버튼 역할별 차별화 (생성자: 일시정지/재개+종료, 참석자: 나가기)<br>• UFR-AI-035 삭제: 섹션AI요약 제거 (중복 기능)<br>• UFR-AI-036 개선: AI 한줄요약 확인 및 재생성 기능 통합<br> - 회의 종료 시: 자동 생성 (읽기 전용)<br> - 회의록 수정 시: 텍스트 편집 영역 내용 기반 재생성 기능 추가<br> - "AI 상세요약" → "AI 요약"으로 명칭 변경<br> - 회의록 상세조회 화면의 대시보드 및 회의록 탭에 한줄요약 표시<br> - 프로토타입 UI 개선: AI 재생성 버튼 스타일 통일 (btn-secondary → btn-primary)<br>• UFR-COLLAB-030 개선: 안건 기반 충돌 방지 메커니즘 (검증완료 체크로 보호)|
|
||||||
| v2.3.1 | 2025-10-27 | 팀 전체 | • MVP 개선: 회의 참석자 권한 단순화<br>• 신규 유저스토리: UFR-PART-010/020/030 (참석자 공통), UFR-HOST-010/020 (생성자 전용)<br>• 신규 유저스토리: UFR-TERM-010/020/030 (용어 기능 MVP 단순화)<br>• UFR-MEET-040 수정: 회의 종료 권한 생성자 전용으로 명확화<br>• UFR-MEET-030 개선: 회의 진입 경로 2가지 명시 (바로시작, 참여하기)<br>• UFR-AI-040 개선: 관련 회의록 유사 내용 요약 추가 (최대 3개, 퍼센트 표시, 3-5문장 요약)<br>• 메모 기능 단순화: 체크박스 방식으로 변경<br>• 용어 설명 단순화: JSON 용어 사전 방식 도입 |
|
| v2.3.1 | 2025-10-27 | 팀 전체 | • MVP 개선: 회의 참석자 권한 단순화<br>• 신규 유저스토리: UFR-PART-010/020/030 (참석자 공통), UFR-HOST-010/020 (생성자 전용)<br>• 신규 유저스토리: UFR-TERM-010/020/030 (용어 기능 MVP 단순화)<br>• UFR-MEET-040 수정: 회의 종료 권한 생성자 전용으로 명확화<br>• UFR-MEET-030 개선: 회의 진입 경로 2가지 명시 (바로시작, 참여하기)<br>• UFR-AI-040 개선: 관련 회의록 유사 내용 요약 추가 (최대 3개, 퍼센트 표시, 3-5문장 요약)<br>• 메모 기능 단순화: 체크박스 방식으로 변경<br>• 용어 설명 단순화: JSON 용어 사전 방식 도입 |
|
||||||
| v2.3.0 | 2025-10-24 | 이미준 | • 프로토타입 분석을 통한 유저스토리 전면 재정비<br>• 신규 유저스토리 추가: UFR-MEET-015 (참석자 실시간 초대), UFR-NOTI-010 (알림 발송)<br>• 알림 아키텍처 폴링 방식으로 통일 (실시간 발송 → 주기적 폴링)<br>• 10개 프로토타입 화면 반영 완료<br>• 마이크로서비스 구성 재정의 (User, Meeting, STT, AI, Notification)<br>• 기존 24개 유저스토리 ID 승계 및 정리 |
|
| v2.3.0 | 2025-10-24 | 이미준 | • 프로토타입 분석을 통한 유저스토리 전면 재정비<br>• 신규 유저스토리 추가: UFR-MEET-015 (참석자 실시간 초대), UFR-NOTI-010 (알림 발송)<br>• 알림 아키텍처 폴링 방식으로 통일 (실시간 발송 → 주기적 폴링)<br>• 10개 프로토타입 화면 반영 완료<br>• 마이크로서비스 구성 재정의 (User, Meeting, STT, AI, Notification)<br>• 기존 24개 유저스토리 ID 승계 및 정리 |
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user