From 25efe243f4e896b2602d812d30d748e58e8d603a Mon Sep 17 00:00:00 2001 From: hiondal Date: Tue, 21 Oct 2025 16:29:21 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8C=80=EC=8B=9C=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=86=A0=ED=83=80=EC=9E=85=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EB=B0=8F=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회의 자료 섹션 삭제 - Todo undefined 문제 해결 (네임스페이스 충돌 수정) - JavaScript 디버깅 로그 추가 - 기존 prototype 디렉토리 삭제 - prototype-gappa 디렉토리 추가 - 유저스토리 gappa 버전 추가 - 엑셀 변환 스크립트 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .claude/settings.local.json | 3 +- convert_userstory_to_excel.py | 214 +++ .../01-로그인.html | 0 design/uiux/prototype-gappa/02-대시보드.html | 691 +++++++++ .../03-회의예약.html | 0 .../04-템플릿선택.html | 0 .../05-회의진행.html | 0 .../06-검증완료.html | 0 .../07-회의종료.html | 0 .../08-회의록공유.html | 0 .../09-Todo관리.html | 16 +- .../10-회의록확정.html} | 0 .../11-회의록수정.html | 2 +- .../uiux/prototype-gappa/12-회의록목록.html | 765 ++++++++++ .../13-회의록상세조회.html} | 9 +- .../{prototype => prototype-gappa}/common.css | 0 .../{prototype => prototype-gappa}/common.js | 0 design/uiux/prototype/02-대시보드.html | 1316 ----------------- design/uiux/prototype/12-회의록목록조회.html | 831 ----------- design/{userstory.md => userstory-gappa.md} | 236 ++- design/userstory.xlsx | Bin 0 -> 5207 bytes ...식업 소상공인 이벤트 방법 종합 연구보고서.md | 378 +++++ design/소상공인 이벤트 설계 방법론.md | 600 ++++++++ 23 files changed, 2891 insertions(+), 2170 deletions(-) create mode 100644 convert_userstory_to_excel.py rename design/uiux/{prototype => prototype-gappa}/01-로그인.html (100%) create mode 100644 design/uiux/prototype-gappa/02-대시보드.html rename design/uiux/{prototype => prototype-gappa}/03-회의예약.html (100%) rename design/uiux/{prototype => prototype-gappa}/04-템플릿선택.html (100%) rename design/uiux/{prototype => prototype-gappa}/05-회의진행.html (100%) rename design/uiux/{prototype => prototype-gappa}/06-검증완료.html (100%) rename design/uiux/{prototype => prototype-gappa}/07-회의종료.html (100%) rename design/uiux/{prototype => prototype-gappa}/08-회의록공유.html (100%) rename design/uiux/{prototype => prototype-gappa}/09-Todo관리.html (96%) rename design/uiux/{prototype/10-회의록상세조회.html => prototype-gappa/10-회의록확정.html} (100%) rename design/uiux/{prototype => prototype-gappa}/11-회의록수정.html (99%) create mode 100644 design/uiux/prototype-gappa/12-회의록목록.html rename design/uiux/{prototype/11-회의록대시보드.html => prototype-gappa/13-회의록상세조회.html} (99%) rename design/uiux/{prototype => prototype-gappa}/common.css (100%) rename design/uiux/{prototype => prototype-gappa}/common.js (100%) delete mode 100644 design/uiux/prototype/02-대시보드.html delete mode 100644 design/uiux/prototype/12-회의록목록조회.html rename design/{userstory.md => userstory-gappa.md} (78%) create mode 100644 design/userstory.xlsx create mode 100644 design/국내 외식업 소상공인 이벤트 방법 종합 연구보고서.md create mode 100644 design/소상공인 이벤트 설계 방법론.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json index b053c98..404dc4d 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -32,7 +32,8 @@ "Bash(curl -s https://raw.githubusercontent.com/cna-bootcamp/clauding-guide/refs/heads/main/guides/design/logical-architecture-design.md -o claude/logical-architecture-design.md)", "Bash(curl:*)", "Bash(chmod:*)", - "Bash(./tools/check-mermaid.sh:*)" + "Bash(./tools/check-mermaid.sh:*)", + "Bash(mv:*)" ], "deny": [], "ask": [] diff --git a/convert_userstory_to_excel.py b/convert_userstory_to_excel.py new file mode 100644 index 0000000..1a3680f --- /dev/null +++ b/convert_userstory_to_excel.py @@ -0,0 +1,214 @@ +""" +유저스토리를 엑셀로 변환하는 스크립트 +""" +import re +from openpyxl import Workbook +from openpyxl.styles import Font, Alignment, PatternFill, Border, Side +from openpyxl.utils import get_column_letter + +def parse_userstory(file_path): + """유저스토리 파일 파싱""" + with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + + # 유저스토리 섹션 추출 (``` 사이의 내용) + match = re.search(r'```\n(.*?)\n```', content, re.DOTALL) + if not match: + raise ValueError("유저스토리 섹션을 찾을 수 없습니다.") + + userstory_content = match.group(1) + + # 유저스토리 파싱 + stories = [] + current_service = None + current_epic = None + + lines = userstory_content.split('\n') + i = 0 + + while i < len(lines): + line = lines[i].strip() + + # 서비스 감지 (숫자. 서비스명 또는 숫자. 서비스명 서비스) + service_match = re.match(r'^(\d+)\.\s+(.+?)$', line) + if service_match and not line.startswith('UFR-') and not line.startswith('AFR-') and not re.match(r'^\d+\)\s+', line): + service_name = service_match.group(2).strip() + # "서비스" 문자열 제거 + if service_name.endswith(' 서비스'): + service_name = service_name[:-3] + elif service_name.endswith('서비스'): + service_name = service_name[:-2] + current_service = f"{service_match.group(1)}. {service_name}" + current_epic = None + i += 1 + continue + + # Epic 감지 (숫자) Epic명) + epic_match = re.match(r'^(\d+)\)\s+(.+)$', line) + if epic_match: + current_epic = f"{epic_match.group(1)}. {epic_match.group(2).strip()}" + i += 1 + continue + + # 유저스토리 ID 감지 (UFR-XXX-YYY: 또는 AFR-XXX-YYY:) + story_match = re.match(r'^([UA]FR-[A-Z]+-\d+):\s+\[(.+?)\]\s*(.*)$', line) + if story_match: + story_id = story_match.group(1) + story_title = story_match.group(2) + # 콜론 다음에 유저스토리 내용이 있는 경우 + remaining = story_match.group(3).strip() + + # 다음 줄이 유저스토리 내용인지 확인 + i += 1 + story_desc = "" + + # 남은 부분이 있으면 사용, 없으면 다음 줄 확인 + if remaining and remaining.startswith(':'): + story_desc = remaining[1:].strip() + elif i < len(lines): + next_line = lines[i].strip() + # 다음 줄이 시나리오가 아니면 유저스토리 내용으로 간주 + if not next_line.startswith('-') and not next_line.startswith('[') and next_line: + story_desc = next_line + i += 1 + + # 인수시나리오와 점수 추출 + acceptance_criteria = [] + biz_score = "" + + while i < len(lines): + next_line = lines[i] + + # 다음 유저스토리나 서비스 시작 + if (re.match(r'^[UA]FR-[A-Z]+-\d+:', next_line.strip()) or + re.match(r'^\d+\.\s+[A-Z]', next_line.strip()) or + re.match(r'^\d+\)\s+', next_line.strip()) or + next_line.strip() == '---'): + break + + # Biz중요도/Score 추출 + score_match = re.match(r'^-\s+([A-Z])/(\d+)$', next_line.strip()) + if score_match: + biz_score = f"{score_match.group(1)}/{score_match.group(2)}" + i += 1 + break + + # 인수시나리오 수집 (빈 줄 제외) + if next_line.strip() and not next_line.strip().startswith('---'): + acceptance_criteria.append(next_line) + + i += 1 + + # 인수시나리오를 하나의 문자열로 합치기 + acceptance_text = '\n'.join(acceptance_criteria) + + stories.append({ + 'service': current_service or '', + 'epic': current_epic or '', + 'story_id': story_id, + 'story_title': story_title, + 'story_desc': story_desc, + 'acceptance': acceptance_text, + 'biz_score': biz_score + }) + + continue + + i += 1 + + return stories + +def create_excel(stories, output_path): + """엑셀 파일 생성""" + wb = Workbook() + ws = wb.active + ws.title = "유저스토리" + + # 헤더 정의 + headers = [ + '서비스', + 'Epic', + '유저스토리 ID', + '유저스토리 제목', + '유저스토리', + '인수시나리오', + 'Biz중요도/Score' + ] + + # 헤더 스타일 + header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid") + header_font = Font(bold=True, color="FFFFFF", size=11) + header_alignment = Alignment(horizontal="center", vertical="center", wrap_text=True) + + # 테두리 스타일 + thin_border = Border( + left=Side(style='thin'), + right=Side(style='thin'), + top=Side(style='thin'), + bottom=Side(style='thin') + ) + + # 헤더 작성 + for col_num, header in enumerate(headers, 1): + cell = ws.cell(row=1, column=col_num) + cell.value = header + cell.fill = header_fill + cell.font = header_font + cell.alignment = header_alignment + cell.border = thin_border + + # 데이터 작성 + for row_num, story in enumerate(stories, 2): + ws.cell(row=row_num, column=1).value = story['service'] + ws.cell(row=row_num, column=2).value = story['epic'] + ws.cell(row=row_num, column=3).value = story['story_id'] + ws.cell(row=row_num, column=4).value = story['story_title'] + ws.cell(row=row_num, column=5).value = story['story_desc'] + ws.cell(row=row_num, column=6).value = story['acceptance'] + ws.cell(row=row_num, column=7).value = story['biz_score'] + + # 데이터 스타일 적용 + for col_num in range(1, 8): + cell = ws.cell(row=row_num, column=col_num) + cell.alignment = Alignment(vertical="top", wrap_text=True) + cell.border = thin_border + + # 컬럼 너비 조정 + column_widths = { + 'A': 20, # 서비스 + 'B': 25, # Epic + 'C': 15, # 유저스토리 ID + 'D': 25, # 유저스토리 제목 + 'E': 50, # 유저스토리 + 'F': 60, # 인수시나리오 + 'G': 15 # Biz중요도/Score + } + + for col_letter, width in column_widths.items(): + ws.column_dimensions[col_letter].width = width + + # 헤더 행 높이 + ws.row_dimensions[1].height = 30 + + # 저장 + wb.save(output_path) + print(f"[OK] Excel file created: {output_path}") + print(f"[INFO] Total {len(stories)} user stories converted.") + +if __name__ == "__main__": + input_file = "design/userstory.md" + output_file = "design/userstory.xlsx" + + try: + print("[INFO] Parsing user story file...") + stories = parse_userstory(input_file) + + print(f"[OK] Parsed {len(stories)} user stories.") + + print("[INFO] Creating Excel file...") + create_excel(stories, output_file) + + except Exception as e: + print(f"[ERROR] {e}") + import traceback + traceback.print_exc() diff --git a/design/uiux/prototype/01-로그인.html b/design/uiux/prototype-gappa/01-로그인.html similarity index 100% rename from design/uiux/prototype/01-로그인.html rename to design/uiux/prototype-gappa/01-로그인.html diff --git a/design/uiux/prototype-gappa/02-대시보드.html b/design/uiux/prototype-gappa/02-대시보드.html new file mode 100644 index 0000000..a4f8852 --- /dev/null +++ b/design/uiux/prototype-gappa/02-대시보드.html @@ -0,0 +1,691 @@ + + + + + + 대시보드 - 회의록 서비스 + + + + + +
+
+ + 회의록 서비스 +
+
+
+ + +
+
+
+ + +
+ + + + +
+ +
+

안녕하세요!

+

오늘의 일정을 확인하세요

+
+ + +
+
+
📅
+
예정된 회의
+
0
+
+
+
+
진행 중 Todo
+
0
+
+
+
📈
+
Todo 완료율
+
0%
+
+
+ + +
+
+

최근 회의

+ 전체 보기 → +
+
+ +
+
+ + +
+
+

할당된 Todo

+ 전체 보기 → +
+
+ +
+
+
+
+ + + + + + + + + + + + diff --git a/design/uiux/prototype/03-회의예약.html b/design/uiux/prototype-gappa/03-회의예약.html similarity index 100% rename from design/uiux/prototype/03-회의예약.html rename to design/uiux/prototype-gappa/03-회의예약.html diff --git a/design/uiux/prototype/04-템플릿선택.html b/design/uiux/prototype-gappa/04-템플릿선택.html similarity index 100% rename from design/uiux/prototype/04-템플릿선택.html rename to design/uiux/prototype-gappa/04-템플릿선택.html diff --git a/design/uiux/prototype/05-회의진행.html b/design/uiux/prototype-gappa/05-회의진행.html similarity index 100% rename from design/uiux/prototype/05-회의진행.html rename to design/uiux/prototype-gappa/05-회의진행.html diff --git a/design/uiux/prototype/06-검증완료.html b/design/uiux/prototype-gappa/06-검증완료.html similarity index 100% rename from design/uiux/prototype/06-검증완료.html rename to design/uiux/prototype-gappa/06-검증완료.html diff --git a/design/uiux/prototype/07-회의종료.html b/design/uiux/prototype-gappa/07-회의종료.html similarity index 100% rename from design/uiux/prototype/07-회의종료.html rename to design/uiux/prototype-gappa/07-회의종료.html diff --git a/design/uiux/prototype/08-회의록공유.html b/design/uiux/prototype-gappa/08-회의록공유.html similarity index 100% rename from design/uiux/prototype/08-회의록공유.html rename to design/uiux/prototype-gappa/08-회의록공유.html diff --git a/design/uiux/prototype/09-Todo관리.html b/design/uiux/prototype-gappa/09-Todo관리.html similarity index 96% rename from design/uiux/prototype/09-Todo관리.html rename to design/uiux/prototype-gappa/09-Todo관리.html index f467203..1a35714 100644 --- a/design/uiux/prototype/09-Todo관리.html +++ b/design/uiux/prototype-gappa/09-Todo관리.html @@ -243,7 +243,7 @@
@@ -264,7 +264,7 @@
@@ -293,7 +293,7 @@
@@ -314,7 +314,7 @@
@@ -343,7 +343,7 @@
@@ -366,7 +366,7 @@ 진행 중 @@ -386,7 +386,7 @@ 진행 중 @@ -405,7 +405,7 @@ 완료 diff --git a/design/uiux/prototype/10-회의록상세조회.html b/design/uiux/prototype-gappa/10-회의록확정.html similarity index 100% rename from design/uiux/prototype/10-회의록상세조회.html rename to design/uiux/prototype-gappa/10-회의록확정.html diff --git a/design/uiux/prototype/11-회의록수정.html b/design/uiux/prototype-gappa/11-회의록수정.html similarity index 99% rename from design/uiux/prototype/11-회의록수정.html rename to design/uiux/prototype-gappa/11-회의록수정.html index e5a69cb..cf720a8 100644 --- a/design/uiux/prototype/11-회의록수정.html +++ b/design/uiux/prototype-gappa/11-회의록수정.html @@ -780,7 +780,7 @@ UIComponents.showToast('회의록이 저장되었습니다', 'success'); setTimeout(() => { - window.location.href = '12-회의록목록조회.html'; + window.location.href = '12-회의록상세조회.html'; }, 1000); }, 800); } diff --git a/design/uiux/prototype-gappa/12-회의록목록.html b/design/uiux/prototype-gappa/12-회의록목록.html new file mode 100644 index 0000000..2b545ef --- /dev/null +++ b/design/uiux/prototype-gappa/12-회의록목록.html @@ -0,0 +1,765 @@ + + + + + + 회의록 목록 - 회의록 서비스 + + + + + + + + +
+ +
+
+ 📋 +
+ 전체 회의록 + 0 +
+
+
+ +
+ 확정 완료 + 0 +
+
+
+ 📌 +
+ 진행 중 Todo + 0 +
+
+
+ + +
+ +
+ + + +
+ + + + + + diff --git a/design/uiux/prototype/11-회의록대시보드.html b/design/uiux/prototype-gappa/13-회의록상세조회.html similarity index 99% rename from design/uiux/prototype/11-회의록대시보드.html rename to design/uiux/prototype-gappa/13-회의록상세조회.html index 5471719..24927b5 100644 --- a/design/uiux/prototype/11-회의록대시보드.html +++ b/design/uiux/prototype-gappa/13-회의록상세조회.html @@ -546,8 +546,8 @@
- - ← 대시보드 + + ← 회의록 목록

2024 Q4 마케팅 전략 회의

@@ -564,11 +564,6 @@ 참석자 5명
-
diff --git a/design/uiux/prototype/common.css b/design/uiux/prototype-gappa/common.css similarity index 100% rename from design/uiux/prototype/common.css rename to design/uiux/prototype-gappa/common.css diff --git a/design/uiux/prototype/common.js b/design/uiux/prototype-gappa/common.js similarity index 100% rename from design/uiux/prototype/common.js rename to design/uiux/prototype-gappa/common.js diff --git a/design/uiux/prototype/02-대시보드.html b/design/uiux/prototype/02-대시보드.html deleted file mode 100644 index 21150b0..0000000 --- a/design/uiux/prototype/02-대시보드.html +++ /dev/null @@ -1,1316 +0,0 @@ - - - - - - 대시보드 - 회의록 서비스 - - - - - -
-
- - 회의록 서비스 -
-
-
- - -
-
-
- - -
- - - - -
- -
-

안녕하세요!

-

오늘의 일정을 확인하세요

-
- - -
- - -
- - -
-
-
📅
-
예정된 회의
-
0
-
-
-
-
진행 중 Todo
-
0
-
-
-
📈
-
Todo 완료율
-
0%
-
-
- - -
-
-

예정된 회의

- 전체 보기 → -
-
- -
-
- - -
-
-

내 회의록

- 전체 보기 → -
-
- -
-
- - -
-
-

할당된 Todo

- 전체 보기 → -
-
- -
-
- - -
-
-

공유받은 회의록

- 전체 보기 → -
-
- -
-
-
-
- - - - - - - - -
-
-

무엇을 하시겠습니까?

-
-
🚀
-
-
새 회의 시작
-
템플릿을 선택하여 회의를 바로 시작합니다
-
-
-
-
📅
-
-
회의 예약
-
향후 진행할 회의를 미리 예약합니다
-
-
-
-
- - - - - - diff --git a/design/uiux/prototype/12-회의록목록조회.html b/design/uiux/prototype/12-회의록목록조회.html deleted file mode 100644 index 21d9b9c..0000000 --- a/design/uiux/prototype/12-회의록목록조회.html +++ /dev/null @@ -1,831 +0,0 @@ - - - - - - 회의록 목록 - 회의록 서비스 - - - - - - - - -
- -
- -
-
- - -
-
- - -
-
- - -
- - - - -
- - -
- - -
-
- - -
-
-
전체
-
0
-
-
-
작성중
-
0
-
-
-
확정완료
-
0
-
-
- - -
- -
- - - -
- - - - - - - - - - - - diff --git a/design/userstory.md b/design/userstory-gappa.md similarity index 78% rename from design/userstory.md rename to design/userstory-gappa.md index fbe5d7d..ecae1f6 100644 --- a/design/userstory.md +++ b/design/userstory-gappa.md @@ -1,6 +1,6 @@ -# 회의록 작성 및 공유 개선 서비스 - 유저스토리 (v2.0) +# 회의록 작성 및 공유 개선 서비스 - 유저스토리 (v2.1) -- [회의록 작성 및 공유 개선 서비스 - 유저스토리 (v2.0)](#회의록-작성-및-공유-개선-서비스---유저스토리-v20) +- [회의록 작성 및 공유 개선 서비스 - 유저스토리 (v2.1)](#회의록-작성-및-공유-개선-서비스---유저스토리-v21) - [차별화 전략](#차별화-전략) - [마이크로서비스 구성](#마이크로서비스-구성) - [유저스토리](#유저스토리) @@ -104,18 +104,60 @@ UFR-MEET-030: [회의시작] 회의록 작성자로서 | 나는, 회의를 시 - 회의록 작성자가 시작 권한을 가짐 - 이미 시작된 회의일 경우, 진행중으로 표시 + [참석자 상태 실시간 표시] + - 참석자 목록 표시 + - 참석자 아바타 (이니셜 또는 프로필 이미지) + - 참석자 이름 + - 실시간 상태 표시 + - 발언 중 ✍️ + - 온라인 (초록색 점) + - 오프라인 (회색 점) + - 참석자 수 표시 (예: 3명) + - 참석자 상태 변경 시 실시간 업데이트 (웹소켓) + [처리 결과] - 회의 세션이 생성됨 (세션 ID) - 음성 녹음 준비 완료 - - 참석자 목록 표시 + - 참석자 목록 및 상태 표시 - 회의 시작 시간 기록 - 실시간 회의록 주요 항목 추천 + - 회의 타이머 시작 (00:00부터 카운트업) - M/8 --- 2) 회의 종료 및 완료 +UFR-MEET-015: [대시보드] 사용자로서 | 나는, 나의 회의 및 Todo 현황을 한눈에 파악하기 위해 | 대시보드에서 요약 정보를 확인하고 싶다. +- 시나리오: 대시보드 조회 + 로그인한 상황에서 | 대시보드에 접근하면 | 예정된 회의, 진행 중 Todo, 완료율 등 핵심 정보가 표시된다. + + [대시보드 표시 정보] + - 통계 카드 + - 📅 예정된 회의 개수 + - ✅ 진행 중 Todo 개수 + - 📈 Todo 완료율 (%) + - 최근 회의 목록 (최대 5개) + - 회의 제목 + - 회의 일시 + - 참석자 수 + - 결정사항/Todo 개수 + - 할당된 Todo 목록 (최대 5개) + - Todo 제목 + - 마감일 + - 담당자 + - 진행 상태 + - 빠른 회의 생성 버튼 (+) + + [처리 결과] + - 대시보드 정보가 표시됨 + - "전체 보기" 링크로 상세 화면 이동 가능 + - Mobile/Tablet/Desktop 반응형 레이아웃 + +- M/8 + +--- + UFR-MEET-040: [회의종료] 회의록 작성자로서 | 나는, 회의를 종료하고 회의록을 정리하기 위해 | 회의를 종료하고 통계를 확인하고 싶다. - 시나리오: 회의 종료 회의가 진행 중인 상황에서 | 회의 종료 버튼을 클릭하면 | 음성 녹음이 중지되고 회의 통계가 생성된다. @@ -173,6 +215,7 @@ UFR-MEET-045: [회의록상세조회] 회의록 작성자로서 | 나는, 지난 - 회의 제목 - 회의 일시 (날짜 및 시간) - 참석자 목록 (역할 구분: 주관자/참석자/불참자) + - 참석자 수 - 회의 장소 (온라인/오프라인) - 사용된 템플릿 유형 - 회의록 상태 (작성중/확정완료) @@ -208,6 +251,109 @@ UFR-MEET-045: [회의록상세조회] 회의록 작성자로서 | 나는, 지난 --- +UFR-MEET-046: [회의록목록조회] 회의록 작성자로서 | 나는, 과거 회의록을 쉽게 찾기 위해 | 회의록 목록을 조회하고 검색하고 싶다. +- 시나리오: 회의록 목록 조회 및 검색 + 대시보드에서 "회의 목록" 메뉴를 클릭하면 | 회의록 목록이 표시되고 | 상태별/기간별 필터링 및 키워드 검색이 가능하다. + + [필터링 옵션] + - 상태별 필터: 전체 / 확정 / 예정 / 진행중 + - 기간별 필터: 전체 / 1주 / 1개월 / 3개월 + - 검색 기능: 회의록 제목, 참석자, 키워드 + + [회의록 목록 표시 정보] + - 통계 카드 + - 📋 전체 회의록 개수 + - ✅ 확정 완료 개수 + - 📌 진행 중 Todo 개수 + - 회의록 카드 (각 항목별) + - 회의 제목 + - 회의 일시 (날짜 및 시간) + - 회의 장소 + - 회의 시간 (분) + - 참석자 아바타 (최대 4명 표시, 나머지는 +N) + - 회의록 상태 (✓ 확정 완료 / 🔄 진행중 / 📅 예정) + - 결정사항 개수 + - Todo 개수 + - 요약 설명 (1줄) + + [정렬 옵션] + - 최신순 (기본) + - 회의일시순 + - 제목순 + + [처리 결과] + - 회의록 목록이 표시됨 + - 카드 클릭 시 회의록 상세 화면으로 이동 + - Mobile/Tablet/Desktop 반응형 레이아웃 + - 무한 스크롤 또는 페이지네이션 + +- M/8 + +--- + +UFR-MEET-047: [회의록대시보드] 회의록 작성자로서 | 나는, 회의의 핵심 정보를 빠르게 파악하기 위해 | 회의록 대시보드를 통해 요약 정보를 확인하고 싶다. +- 시나리오: 회의록 대시보드 조회 + 회의록 목록에서 특정 회의록을 클릭하면 | 회의록 대시보드 화면이 표시되고 | 핵심내용, 결정사항, Todo 진행상황, 참고자료를 한눈에 확인할 수 있다. + + [회의 기본 정보] + - 회의 제목 + - 회의 일시 (📅 날짜 시간) + - 회의 장소 (📍 장소) + - 참석자 수 (👥 N명) + + [💡 핵심내용 섹션] + - 주요 포인트 요약 (번호 매김 리스트) + - 태그/키워드 (해시태그 형태) + - 회의 통계 + - 참석자 수 + - 회의 시간 (분) + - 발언 횟수 + - 주요 의제 개수 + + [✅ 결정사항 섹션] + - 결정사항 목록 (각 항목별) + - 결정 내용 + - 결정자 정보 (👤 이름 + 직책) + - 결정 시간 (🕐 시간) + - 배경 설명 + - 결정사항이 없는 경우 "결정사항이 없습니다" 표시 + + [📋 Todo 진행상황 섹션] + - 상태별 필터: 전체 / 시작 전 / 진행 중 / 완료 + - 담당자별 그룹핑 + - 담당자 정보 (👤 이름 + 직책) + - 담당 Todo 개수 + - Todo 항목 (각 항목별) + - Todo 내용 + - 진행률 표시 (프로그레스 바) + - 마감일 표시 (D-N, 오늘, D+N 지남, 완료) + - 우선순위 표시 (긴급/높음/보통/낮음) + - 펼치기/접기 기능 + + [📚 참고자료 섹션] + - 탭 메뉴: 관련 회의록 / 프로젝트 문서 / 이슈 트래커 / 위키 페이지 + - 관련 회의록 (각 항목별) + - 📄 아이콘 + - 회의 제목 + - 회의 일시 + - 작성자 + - 관련도 점수 (%) + - 연관성 설명 (1-2문장) + - 참고자료가 없는 경우 "참고자료가 없습니다" 표시 + + [네비게이션] + - ← 회의록 목록으로 돌아가기 버튼 + + [처리 결과] + - 회의록 대시보드가 표시됨 + - 각 섹션별로 정보 그룹핑 + - Mobile/Tablet/Desktop 반응형 레이아웃 + - 섹션별 접기/펼치기 기능 + +- M/13 + +--- + UFR-MEET-055: [회의록수정] 회의록 작성자로서 | 나는, 검증이 완료되지 않았거나 수정이 필요한 | 지난 회의록을 조회하고 수정하고 싶다. - 시나리오: 지난 회의록 조회 및 수정 대시보드에서 "내 회의록" 메뉴를 클릭하면 | 작성한 회의록 목록이 표시되고 | 특정 회의록을 선택하여 수정할 수 있다. @@ -469,14 +615,21 @@ UFR-AI-040: [관련회의록연결] 회의록 작성자로서 | 나는, 이전 - 제목 - 날짜 - 참석자 - - 관련도 점수 + - 관련도 점수 (%) - 시각적으로 강조 표시 - 연관 키워드 + - 연관성 설명 (1-2문장) - 회의록 상단에 "관련 회의록" 섹션 자동 추가 - 클릭 시 해당 회의록으로 이동 + [관련도 점수 표시 방식] + - 관련도 90% 이상: 매우 높음 (진한 초록색) + - 관련도 80-89%: 높음 (초록색) + - 관련도 70-79%: 보통 (주황색) + [Policy/Rule] - 관련도 70% 이상만 자동 연결 - 최대 5개까지 표시 + - 관련도 점수 내림차순 정렬 - S/13 @@ -652,6 +805,8 @@ UFR-COLLAB-030: [검증완료] 회의 참석자로서 | 나는, 회의록의 정 - 검증 대상 섹션 기록 - 검증 상태 업데이트 - 미검증 → 검증 중 → 검증 완료 + - 검증 완료율 계산 + - (검증 완료 섹션 수 / 전체 섹션 수) × 100 [섹션 잠금 기능] - 회의 생성자만 가능 @@ -659,17 +814,25 @@ UFR-COLLAB-030: [검증완료] 회의 참석자로서 | 나는, 회의록의 정 - 잠긴 섹션은 추가 수정 불가 - 회의 생성자가 잠그면 검증 완료로 표시 + [검증 상태 표시] + - 검증 완료 아이콘: ✓ (체크 마크) + - 검증 중 아이콘: ⏳ (모래시계) + - 미검증 아이콘: ⊝ (빈 원) + - 검증 완료율 표시: 프로그레스 바 또는 퍼센트 (예: 75%) + [처리 결과] - 검증이 완료됨 - 검증자 정보 - 검증 상태 (검증 완료) - 완료 시간 + - 검증 완료율 업데이트 - 검증 완료 상태 실시간 동기화 - - 검증 배지 표시 (체크 아이콘) + - 검증 배지 표시 (✓ 체크 아이콘) - 검증 완료 시 전체 메일로 알림이 발송된다. [Policy/Rule] - 주요 섹션 검증 완료 시 해당 섹션 잠금 가능 + - 모든 섹션 검증 완료 시 회의록 상태를 확정완료로 변경 - M/8 @@ -687,13 +850,21 @@ UFR-TODO-010: [Todo할당] Todo 시스템으로서 | 나는, AI가 추출한 Tod - Todo 내용 - 담당자 (AI 자동 식별 또는 수동 지정) - 마감일 (언급된 경우 자동 설정, 없으면 수동 설정) - - 우선순위 (높음/보통/낮음) + - 우선순위 (긴급/높음/보통/낮음) - 관련 회의록 링크 (섹션 위치 포함) + - 진행 상태 (시작 전/진행 중/완료) + - 진행률 (0-100%) [회의록 실시간 연결] - 회의록 해당 섹션에 Todo 뱃지 표시 - Todo 클릭 시 Todo 상세 정보 표시 - 양방향 연결 (Todo → 회의록, 회의록 → Todo) + - 회의록 링크 표시 형식: 📄 [회의 제목] (날짜) + + [담당자별 그룹핑] + - Todo 관리 화면에서 담당자별로 그룹화 + - 각 담당자별 Todo 개수 표시 + - 담당자 정보 표시 (아바타 + 이름 + 직책) [알림 발송] - 담당자에게 즉시 알림 @@ -727,6 +898,59 @@ UFR-TODO-010: [Todo할당] Todo 시스템으로서 | 나는, AI가 추출한 Tod --- +UFR-TODO-020: [Todo칸반관리] Todo 담당자로서 | 나는, Todo 진행 상황을 시각적으로 관리하기 위해 | 칸반 보드 형태로 Todo를 관리하고 싶다. +- 시나리오: Todo 칸반 보드 관리 + Todo 관리 화면에 접근한 상황에서 | 칸반 보드 또는 리스트 뷰를 선택하면 | Todo가 상태별(시작 전/진행 중/완료)로 분류되어 표시되고 드래그앤드롭으로 상태를 변경할 수 있다. + + [뷰 전환] + - 칸반 뷰 / 리스트 뷰 토글 버튼 + - 사용자 선택 상태 저장 (쿠키 또는 로컬스토리지) + + [칸반 보드 구성] + - 3개 컬럼: 시작 전 / 진행 중 / 완료 + - 각 컬럼별 Todo 개수 표시 + - 컬럼별 색상 구분 + - 시작 전: 빨간 테두리 + - 진행 중: 주황 테두리 + - 완료: 초록 채움 + + [Todo 카드 표시 정보] + - Todo 내용 (제목) + - 담당자 아바타 + 이름 + - 마감일 표시 + - D-N (남은 일수) + - 오늘 + - D+N (지남) - 빨간색 표시 + - 완료 + - 진행률 표시 (프로그레스 바) + - 우선순위 표시 (긴급/높음/보통/낮음) + - 회의록 링크 (📄 [회의 제목]) + + [드래그앤드롭 기능] + - Todo 카드를 다른 컬럼으로 드래그 + - 드롭 시 상태 자동 변경 + - 변경 애니메이션 효과 + - 변경 완료 알림 (토스트 메시지) + + [필터링 및 정렬] + - 담당자별 필터 + - 우선순위별 필터 + - 마감일 임박순 정렬 + - 생성일순 정렬 + + [처리 결과] + - Todo 칸반 보드가 표시됨 + - 드래그앤드롭으로 상태 변경 가능 + - 상태 변경 시 실시간 동기화 + - Mobile/Tablet/Desktop 반응형 레이아웃 + + [비고] + - 모바일에서는 드래그 대신 터치 후 상태 선택 메뉴 표시 + +- M/13 + +--- + UFR-TODO-030: [Todo완료처리] Todo 담당자로서 | 나는, 완료된 Todo를 처리하고 회의록에 반영하기 위해 | Todo를 완료하고 회의록에 자동 반영하고 싶다. - 시나리오: Todo 완료 처리 및 회의록 자동 반영 Todo 작업이 완료된 상황에서 | 담당자가 완료 버튼을 클릭하면 | Todo가 완료 상태로 변경되고 연결된 회의록에 완료 상태가 실시간으로 반영된다. diff --git a/design/userstory.xlsx b/design/userstory.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..86c9c140911076a936a00d3a57492e7a7823494c GIT binary patch literal 5207 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