document is built now
This commit is contained in:
parent
0d9b376bb9
commit
fc11b930d4
@ -1,6 +1,6 @@
|
|||||||
[book]
|
[book]
|
||||||
authors = ["monoid"]
|
authors = ["monoid"]
|
||||||
language = "en"
|
language = "ko"
|
||||||
multilingual = false
|
multilingual = false
|
||||||
src = "src"
|
src = "build"
|
||||||
title = "Software Requirement Specification"
|
title = "Software Requirement Specification"
|
||||||
|
10
cli.py
10
cli.py
@ -7,22 +7,22 @@ import os
|
|||||||
|
|
||||||
|
|
||||||
def build(args):
|
def build(args):
|
||||||
parser = argparse.ArgumentParser(description='Compiling the documentation')
|
parser = argparse.ArgumentParser(description='Compiling the documentation', prog="cli.py build")
|
||||||
parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode')
|
parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode')
|
||||||
parser.add_argument('--update_issues', action='store_true', help='update issues')
|
parser.add_argument('--update_issues', action='store_true', help='update issues')
|
||||||
|
parser.add_argument('--outDir', default="build", help='output directory')
|
||||||
|
|
||||||
args = parser.parse_args(args)
|
args = parser.parse_args(args)
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
print("build start")
|
print("build start")
|
||||||
if args.update_issues:
|
if args.update_issues:
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
print("get issues")
|
print("get issues")
|
||||||
p = subprocess.run(["deno", "run", "-A","tools/getIssue.ts", "--path","./build/issues.json"])
|
p = subprocess.run(["deno", "run", "-A","tools/getIssue.ts", "--path",os.path.join(args.outDir,"/issues.json")])
|
||||||
p.check_returncode()
|
p.check_returncode()
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
print("build issues")
|
print("build issues")
|
||||||
p = subprocess.run(["deno", "run", "-A","tools/printDocument.ts", "--overall", "--path", "./build/issues.json", "--outpath", "./build/overall.md"])
|
p = subprocess.run(["deno", "run", "-A","tools/printDocument.ts", "--issue_path", "./build/issues.json", "--outDir", args.outDir])
|
||||||
p.check_returncode()
|
|
||||||
p = subprocess.run(["deno", "run", "-A","tools/printDocument.ts", "--issue_path", "./build/issues.json", "--outpath", "./build/specific.md"])
|
|
||||||
p.check_returncode()
|
p.check_returncode()
|
||||||
|
|
||||||
def help(_args):
|
def help(_args):
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
# 2. 전체 시스템 개요(Overall description)
|
|
||||||
|
|
||||||
### 2.1. 제품 관점(Product perspective)
|
|
||||||
|
|
||||||
### 2.1.1. 시스템 인터페이스(System interfaces)
|
|
||||||
|
|
||||||
본 시스템은 Cross-platform 소프트웨어이다. 다음과 같은 브라우저가 원활히 실행될 수 있는 시스템에서 동작 할 수 있다.
|
|
||||||
- Chrome 버전 61 이상
|
|
||||||
- Firefox 버전 60 이상
|
|
||||||
- Edge 버전 79 이상
|
|
||||||
- Safari 버전 11 이상
|
|
||||||
- Chrome for Android 버전 100 이상
|
|
||||||
- Samsung internet 버전 8.2 이상
|
|
||||||
|
|
||||||
### 2.1.2. 사용자 인터페이스(User interfaces)
|
|
||||||
|
|
||||||
웹으로 동작하는 GUI이다. 키보드와 마우스, 터치 인터페이스로 동작할 수 있다. GUI의 디자인은 Material Design이나 Metro Design 같이 플랫한 디자인을 추구한다.
|
|
||||||
|
|
||||||
### 2.1.3. 하드웨어 인터페이스(Hardware interfaces)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
|
|
||||||
### 2.1.4. 소프트웨어 인터페이스(Software interfaces)
|
|
||||||
|
|
||||||
이 프로젝트의 결과물은 클립보드를 통해서 여러 타입의 데이터를 import/export한다.
|
|
||||||
|
|
||||||
### 2.1.5. 통신 인터페이스(Communications interfaces)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
### 2.1.6. 메모리 제약사항(Memory constraints)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
|
|
||||||
### 2.1.7. 운영(Operations)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
|
|
||||||
### 2.1.8. 사이트 적용 요건(Site adaption requirements)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
|
|
||||||
## 2.2. 제품 기능(Product functions)
|
|
||||||
|
|
||||||
본 프로젝트의 결과물은 다음과 같은 기능을 수행한다.
|
|
||||||
|
|
||||||
### 2.2.1 Chunk Operation
|
|
||||||
|
|
||||||
1. #1 Chunk: Focus/Unfocus
|
|
||||||
2. #2 Chunk: remove
|
|
||||||
3. #3 Chunk: read
|
|
||||||
4. #4 Chunk: previews
|
|
||||||
5. #10 Chunk: autocomplete
|
|
||||||
6. #11 Chunk: swap positions
|
|
||||||
7. #27 Chunk: edit
|
|
||||||
|
|
||||||
### 2.2.2 Document Operation
|
|
||||||
|
|
||||||
1. #5 Document: view Chunk
|
|
||||||
2. #6 Document: remove
|
|
||||||
3. #7 Document: add/delete tag
|
|
||||||
4. #8 Document: Drag And Drop Upload
|
|
||||||
5. #9 Document: Auto-Refresh
|
|
||||||
6. #12 Document: Share
|
|
||||||
7. #13 Document: Navigator
|
|
||||||
|
|
||||||
### 2.2.3 File Operation
|
|
||||||
|
|
||||||
1. #14 File: create/delete/rename file
|
|
||||||
2. #15 File: upload/download files
|
|
||||||
3. #18 File: export document
|
|
||||||
|
|
||||||
### 2.2.4 Search Operation
|
|
||||||
|
|
||||||
1. #16 Search: Document Search
|
|
||||||
|
|
||||||
### 2.2.5 Stash Operation
|
|
||||||
|
|
||||||
1. #17 Stash: read
|
|
||||||
2. #19 Stash: add
|
|
||||||
3. #20 Stash: remove
|
|
||||||
4. #21 Stash: Drag and Drop to Document
|
|
||||||
|
|
||||||
### 2.2.6 Management Operation
|
|
||||||
|
|
||||||
1. #22 Management: Login
|
|
||||||
2. #23 Management: Configure
|
|
||||||
3. #24 Management: Localization
|
|
||||||
4. #25 Management: Theme
|
|
||||||
|
|
||||||
### 2.2.7 Extension Operation
|
|
||||||
|
|
||||||
1. #28 Extension: API
|
|
||||||
2. #29 Extension: Plugin
|
|
||||||
|
|
||||||
### 2.2.8 비기능적 기능
|
|
||||||
- Docker 배포
|
|
||||||
- .env 설정
|
|
||||||
- 첫 로드후 로딩 0.5s 이내
|
|
||||||
- 동시 편집 이용자 5명 이내
|
|
||||||
- 1000 RPS 정도 버티기
|
|
||||||
|
|
||||||
## 2.3. 사용자 특성(User characteristics)
|
|
||||||
|
|
||||||
사용자는 기본적인 GUI 조작을 할 줄 알며 인터넷 사용을 원활히 할 수 있고 기본적인 영어를 읽고 쓸 줄 알며, markdown을 작성할 수 있는 사용자로 한정한다. 일반적으로 13세 이상 65세 이하의 사람을 사용자로 가정한다.
|
|
||||||
|
|
||||||
## 2.4. 제약사항(Constraints)
|
|
||||||
|
|
||||||
- 이 프로젝트는 MIT License로 개발되고 있으므로 라이브러리의 라이센스도 신경을 쓴다.
|
|
||||||
- XSS 공격에 안전해야 한다.
|
|
||||||
- 1000 RPS에서 문제없이 작동한다.
|
|
||||||
- 첫 로드후 로딩하면 0.5s 이내에 동작해야합ㄴ.다
|
|
||||||
- 동시 편집 이용자를 5명까지는 허용해야 합니다.
|
|
||||||
|
|
||||||
## 2.5. 가정 및 의존성(Assumptions and dependencies)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
|
|
||||||
## 2.6. 단계별 요구사항(Apportioning of requirements)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
@ -1,6 +0,0 @@
|
|||||||
# Summary
|
|
||||||
|
|
||||||
- [Introduction](./introduction.md)
|
|
||||||
- [Overall Description](./OverallDescription.md)
|
|
||||||
- [Specific Requirement](./SpecificRequirements.md)
|
|
||||||
- [Supporting information](./SupportingInformation.md)
|
|
@ -1,439 +0,0 @@
|
|||||||
# 3. 상세요구사항(Specific Requirements)
|
|
||||||
|
|
||||||
> - 설계자가 요구사항을 만족하는 시스템을 설계할 수 있도록 모든 요구사항을 상세하게 포함해야 한다.
|
|
||||||
> - 테스터가 시스템이 위 요건을 충족하는지 테스트해야 한다.
|
|
||||||
> - 모든 요구사항은 사용자, 운영자, 다른 외부 시스템에 의해 외부적으로 인지할 수 있어야 한다.
|
|
||||||
> - 이 요구사항에는 시스템에 대한 모든 입력(자극)과 출력(응답) 그리고 입력 또는 출력 지원에 대한 응답으로 실행되는 모든 기능에 관한 설명이 포함되어야 한다.
|
|
||||||
> - 상세 요구사항을 작성하기 위한 원칙
|
|
||||||
> 1. 상세 요구사항은 "Characteristics of a good SRS"에 설명한 모든 특성을 준수하도록 작성되어야 한다.
|
|
||||||
> 1. 상세 요구사항은 관련이 있는 이전 문서들과 상호 참조되어야 한다.
|
|
||||||
> 1. 모든 요구사항은 고유하게 식별할 수 있어야 한다.
|
|
||||||
> 1. 가독성을 높이기 위해 요구사항을 구성할 때 주의를 기울여야 한다.
|
|
||||||
|
|
||||||
## 3.1. 외부 인터페이스 요구사항(External interface requirements)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
## 3.2. 기능 요구사항(Functional requirements)
|
|
||||||
|
|
||||||
### (1) Chunk: Focus/Unfocus
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: Chunk를 편집할 수 있는 권한을 가져야 한다.
|
|
||||||
목표: 지금 편집하고자 하는 Chunk를 보여준다.
|
|
||||||
|
|
||||||
1. 사용자가 Chunk의 영역에 클릭을 했을때, Focus 된다. 그떄 다른 Chunk의 Focus를 사라지게 한다.
|
|
||||||
2. Focus를 얻었을때, Focus를 얻은 Chunk을 눈에 띄이도록 표시한다.
|
|
||||||
3. Focus가 사라졌을때, 변경되었으면 변경된 Chunk를 저장한다.
|
|
||||||
|
|
||||||
### (2) Chunk: remove
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: Chunk를 수정가능한 권한을 가지고 있어야함.
|
|
||||||
목표: Chunk를 지운다.
|
|
||||||
|
|
||||||
1. Chunk의 좌측 상단의 Context Menu에 삭제 아이콘을 클릭할 때나 빈 내용의 Chunk에서 <kbd>Backspace</kbd>나 <kbd>Del</kbd>를 입력할 때 시작한다.
|
|
||||||
2. 해당 Chunk를 삭제한다.
|
|
||||||
3. 서버에서 그 Chunk를 삭제한다.
|
|
||||||
4. 아래의 Chunk가 있다면 끌어 올린다.
|
|
||||||
|
|
||||||
### (3) Chunk: read
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 없음
|
|
||||||
목표: Chunk를 보여준다.
|
|
||||||
|
|
||||||
1. 서버에서 내용을 읽는다.
|
|
||||||
2. 그 내용을 chunk안 영역에 사람이 보기 좋게 그 타입에 따라 렌더링한다.
|
|
||||||
render하는 대상 목록은 다음과 같다.
|
|
||||||
- markdown
|
|
||||||
- latex
|
|
||||||
- link (image, video, site)
|
|
||||||
- FEN
|
|
||||||
- etc
|
|
||||||
|
|
||||||
대안 흐름:
|
|
||||||
|
|
||||||
A. 렌더링 실패
|
|
||||||
1. 렌더링 실패에 실패하면 실패의 이유를 보여준다.
|
|
||||||
|
|
||||||
### (4) Chunk: previews
|
|
||||||
액터: 사용자
|
|
||||||
사용조건: 편집 중일때
|
|
||||||
목표: 미리보기를 보여주어 편집을 편하게 한다.
|
|
||||||
|
|
||||||
1. Chunk의 내용을 바꾸면 시작된다.
|
|
||||||
2. 보기모드에서 어떻게 보여질지 미리보기 창을 띄워준다. 미리보기는 기본적으로 하단에 띄우고 밑에 공간이 없으면 상단에 띄운다.
|
|
||||||
3. 내용이 바뀌면 미리보기 창의 내용도 갱신한다.
|
|
||||||
|
|
||||||
### (5) Document: view Chunk
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 읽기 권한이 있어야 한다.
|
|
||||||
목표: Chunk들을 보여준다.
|
|
||||||
|
|
||||||
1. Document가 로딩되면 시작한다.
|
|
||||||
2. 경로가 주어지면 Document Component에서 그 경로의 문서를 읽고 파싱한다. 그동안 로딩 바를 보여준다.
|
|
||||||
3. 로딩이 완료되면 파싱된 결과물인 Chunk들을 보여준다.
|
|
||||||
|
|
||||||
대안흐름:
|
|
||||||
|
|
||||||
A. 읽기 실패:
|
|
||||||
1. 읽기에 실패한 경우 읽기에 실패한 이유를 띄운다.
|
|
||||||
|
|
||||||
B. 파싱 실패:
|
|
||||||
1. 파싱에 실패한 경우 파싱에 실패한 이유를 띄우고 raw text가 담긴 Chunk로 렌더링한다.
|
|
||||||
|
|
||||||
### (6) Document: remove
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 문서를 삭제할 권한이 있어야함.
|
|
||||||
목표: 앱에서 문서를 삭제한다.
|
|
||||||
|
|
||||||
1. Document의 AppBar에 놓여있는 삭제 아이콘을 클릭하면 시작한다.
|
|
||||||
2. 정말로 삭제하겠냐는 다이얼로고가 띄운다.
|
|
||||||
3. 거기서 예스를 누르면 Document를 삭제한다.
|
|
||||||
|
|
||||||
대안 흐름:
|
|
||||||
1. 다이얼로그에서 아니오를 누르면 다이얼로고를 닫고 종료한다.
|
|
||||||
|
|
||||||
### (7) Document: add/delete tag
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 태그 수정 권한이 있을 때
|
|
||||||
목표: 문서의 태그를 추가/수정/삭제한다.
|
|
||||||
|
|
||||||
1. Document의 AppBar에 놓여있는 태그 수정 아이콘을 클릭하면 시작한다. 태그 수정 다이얼로그를 띄운다.
|
|
||||||
2. 태그 수정 다이얼로그에서 태그를 생성, 삭제한다.
|
|
||||||
3. 수정을 완료하고 저장 버튼을 누르면 태그 수정이 종료된다.
|
|
||||||
|
|
||||||
대안 흐름:
|
|
||||||
|
|
||||||
1. 취소 버튼을 누르면 다이얼로그를 닫고 종료한다.
|
|
||||||
|
|
||||||
### (8) Document: Drag And Drop Upload
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 문서 수정 권한이 있어야 한다.
|
|
||||||
목표: 업로드를 드래그 앤 드롭으로 한다.
|
|
||||||
|
|
||||||
1. 웹사이트의 그림이나 비디오 등의 파일을 Drag And Drop 해서 Chunk 사이에 놓으면 시작된다.
|
|
||||||
2. Drag And Drop된 파일을 서버에 업로드한다. 업로드시 파일 이름이 중복될 때 파일 이름이 밑줄과 숫자로 끝나지 않으면 이름의 뒤에 "_1"을 붙여 업로드 한다. 숫자로 끝나면 다음 숫자를 붙여서 업로드 한다. 파일 이름이 없다면 임의의 이름을 붙여서 업로드 한다.
|
|
||||||
3. 그 파일을 새로운 Chunk로 추가한다. 이때 웹에서 표시가능한 파일(이미지, 동영상)이면 파일을 표시하는 Chunk를 추가하고 아니면 다운로드 링크를 가진 Chunk를 추가한다.
|
|
||||||
|
|
||||||
대체흐름:
|
|
||||||
|
|
||||||
A. 파일 사이즈 큼
|
|
||||||
1. 기본단계 2에서 파일 사이즈가 설정보다 크면 시작한다.
|
|
||||||
2. 파일 크기가 너무 크다는 메세지로 띄우고 종료한다.
|
|
||||||
|
|
||||||
B. 작은 파일 사이즈
|
|
||||||
1. 기본단계 2에서 파일 사이즈가 설정보다 작으면 시작한다.
|
|
||||||
2. 파일을 base64로 인코딩해서 Chunk로 삽입한다.
|
|
||||||
|
|
||||||
### (9) Document: Auto-Refresh
|
|
||||||
액터: 외부 편집기
|
|
||||||
시작조건: 없음
|
|
||||||
목적: 변화를 실시간으로 따라갈 수 있게 한다.
|
|
||||||
|
|
||||||
1. Document나 Document가 포함하는 미디어의 파일이 다른 편집 프로그램에 의해서 변경되었을 시에 시작한다.
|
|
||||||
2. 보고 있는 사용자의 Document 뷰를 변경 부분만 Refresh한다. 이때 보고 있던 스크롤이 변하지 않게 유의한다.
|
|
||||||
|
|
||||||
### (10) Chunk: autocomplete
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: chunk 수정시어야 한다.
|
|
||||||
목표: 링크 등을 자동으로 완성해서 편집을 편하게 한다.
|
|
||||||
|
|
||||||
1. <kbd>Ctrl+Space</kbd>로 자동완성 창을 띄울 수 있다.
|
|
||||||
2. 방향키로 고른다.
|
|
||||||
3. <kbd>Tab</kbd>이나 <kbd>Enter</kbd>를 통해 선택한다.
|
|
||||||
4. 선택한 단어로 완성시킨다.
|
|
||||||
|
|
||||||
### (11) Chunk: swap positions
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: Document 수정권한이 있어야 한다.
|
|
||||||
목적: 앱에서 Chunk 위치를 바꿀 수 있다.
|
|
||||||
|
|
||||||
1. Focus를 얻고 핸들 아이콘을 누를때 시작한다.
|
|
||||||
2. 이때 오버레이를 표시해서 놓여졌을 때의 상황을 미리 볼 수 있게 한다.
|
|
||||||
3. 드래그해서 원하는 장소에 놓으면 위치를 바꿀 수 있다.
|
|
||||||
|
|
||||||
### (12) Document: Share
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: 문서를 공유할 수 있는 권한을 가져야한다.
|
|
||||||
목표: 문서를 공유한다.
|
|
||||||
|
|
||||||
1. Document의 AppBar에 놓여있는 공유 아이콘을 누르면 시작한다.
|
|
||||||
2. 공유 링크를 복사한다. 그리고 공유 설정아이콘을 띄워준다. 여기서 종료할 수 있다.
|
|
||||||
3. 공유 설정아이콘을 클릭하면 공유 설정 다이얼로그를 띄운다. 이 다이얼로그에서는 공유 기간과 편집 가능여부 등을 설정할 수 있고 공유 링크를 복사할 수 있다. 공류를 취소할 수도 있다.
|
|
||||||
|
|
||||||
### (13) Document: Navigator
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: 없음
|
|
||||||
목표: 문서들을 쉽게 이동할 수 있는 네비게이터를 보여준다.
|
|
||||||
|
|
||||||
1. 만일 문서가 속하는 디렉토리에 Summary.md 가 있고 올바른 형식(링크와 리스트로 이루어져 있음)이면 시작한다.
|
|
||||||
2. Document의 왼쪽에 Summary의 내용을 네비게이터 역할로 표시한다.
|
|
||||||
|
|
||||||
### (14) File: create/delete/rename file
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 디렉토리에 대한 권한을 가지고 있어야한다.
|
|
||||||
목표: 앱상에서 파일을 생성하거나 삭제 할 수 있어야 한다.
|
|
||||||
|
|
||||||
1. Treeview에 포커스가 간 상태에서 시작한다.
|
|
||||||
2. Treeview에서 오른쪽 클릭을 하면 Context Menu가 나오고 새파일을 클릭하면 이름을 지정해서 파일을 생성할 수 있다.
|
|
||||||
3. Context Menu에서 삭제를 클릭하면 해당 파일을 삭제한다.
|
|
||||||
4. 이름 바꾸기를 클릭하거나 Treeview에서 파일에 포커스가 간 상태에서 <kbd>F2</kbd>를 입력하면 이름을 바꿀 수 있도록 한다.
|
|
||||||
|
|
||||||
### (15) File: upload/download files
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 디렉토리의 권한이 있어야 한다.
|
|
||||||
목표: 파일을 업로드하거나 다운로드 할 수 있어야 한다.
|
|
||||||
|
|
||||||
1. Treeview의 Context menu에서 다운로드 버튼을 클릭해서 다운로드 할 수 있다.
|
|
||||||
2. Treeview에 파일을 드래그 앤 드롭하는 것으로 업로드 할 수 있다.
|
|
||||||
|
|
||||||
### (16) Search: Document Search
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 문서를 읽을 수 있는 권한이 있어야 한다.
|
|
||||||
목표: 문서나 문서들을 검색할 수 있다.
|
|
||||||
|
|
||||||
1. Drawer에서 문서 검색 버튼을 누르면 문서 검색 창이 뜬다.
|
|
||||||
2. 문서 검색창에서 범위를 지정한다. 기본 범위는 현재 보고 있는 문서로 한다.
|
|
||||||
3. 문서 검색 창에서 태그를 검색할지 내용으로 검색을 할지 지정한다. 기본값은 내용이다.
|
|
||||||
4. 정규식을 사용할 것인지 지정한다. 기본값은 사용 안함이다.
|
|
||||||
5. 검색 버튼을 누르면 해당 조건을 만족하는 문서를 리스트로 보여준다.
|
|
||||||
|
|
||||||
### (17) Stash: read
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 화면크기가 768px 이상일때 보여준다.
|
|
||||||
목표: Stash를 보여준다.
|
|
||||||
|
|
||||||
1. 오른쪽에 작은 버튼을 두고 버튼을 클릭하면 시작한다.
|
|
||||||
2. 오른쪽 Drawer가 열려서 Stash의 내용을 보여준다. 최대 지정된 숫자만큼의 내용들을 보여준다.
|
|
||||||
3. 다시 버튼을 누르면 Stash Drawer를 닫는다.
|
|
||||||
|
|
||||||
### (18) File: export document
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 문서를 읽을 수 있는 권한이 있어야 한다. 문서 타입에만 가능하다.
|
|
||||||
목표: 문서를 보기 모드에서 보이는 것처럼 출력할 수 있다.
|
|
||||||
|
|
||||||
1. 메뉴의 Context menu에서 접근 할 때 시작한다.
|
|
||||||
2. 출력하기를 누르면 출력 다이얼로그가 뜬다.
|
|
||||||
3. 출력할 문서 타입을 문서 타입을 설정한다. 출력할 수 있는 문서 타입은 다음과 같다.
|
|
||||||
- pdf
|
|
||||||
- html
|
|
||||||
4. 출력하기를 누르면 출력된 문서를 다운로드한다.
|
|
||||||
|
|
||||||
대안흐름:
|
|
||||||
|
|
||||||
A. 취소
|
|
||||||
1. 단계 2에서 시작한다.
|
|
||||||
2. 취소하기를 누르면 다이얼로그 창을 닫고 종료한다.
|
|
||||||
|
|
||||||
### (19) Stash: add
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: Stash 창을 연 상태에서 포커스가 Stash 창에 주어져 있어야 한다.
|
|
||||||
목표: Stash를 추가한다.
|
|
||||||
|
|
||||||
1. \<\< 포함 #17 \>\>
|
|
||||||
2. <kbd>Ctrl+V</kbd>를 누르면 Stash에 클립보드의 내용이 Stash로 추가되고 클립보드는 비워진다.
|
|
||||||
3. <kbd>Ctrl+Z</kbd>를 눌러서 추가를 되돌릴 수 있다.
|
|
||||||
|
|
||||||
### (20) Stash: remove
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: Stash 창을 연 상태에서 포커스가 Stash 창에 주어져 있어야 한다.
|
|
||||||
목표: 원하는 Stash를 삭제한다.
|
|
||||||
|
|
||||||
1. Stash 창의 각각 항목의 삭제 아이콘을 클릭하면 선택된 항목을 삭제한다.
|
|
||||||
2. Stash에 붙어있는 삭제 아이콘을 클릭하면 전체 항목을 삭제한다.
|
|
||||||
3. <kbd>Ctrl+Z</kbd>를 눌러서 삭제를 되돌릴 수 있다.
|
|
||||||
|
|
||||||
### (21) Stash: Drag and Drop to Document
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: 문서 편집 권한이 있어야 한다.
|
|
||||||
목표: 드래그 앤 드롭으로 Chunk를 Stash에서 꺼내 삽입할 수 있다.
|
|
||||||
|
|
||||||
1. Stash 창의 Stash을 Document에 드래그하면 시작된다.
|
|
||||||
2. Document의 Chunk 사이에 Stash을 드롭하면 그 자리에 Chunk가 삽입된다. 사이의 결정은 제일 가까운 청크로 정한다.
|
|
||||||
3. Stash을 그 위치로 업로드시킨다. 업로드는 #8 와 한 것 같이 한다.
|
|
||||||
4. 해당 Stash를 Stash창에서 삭제한다.
|
|
||||||
|
|
||||||
대안흐름:
|
|
||||||
|
|
||||||
A. 취소
|
|
||||||
1. Stash 창에 놓으면 작업을 취소한다.
|
|
||||||
|
|
||||||
### (22) Management: Login
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 없음.
|
|
||||||
목표: 사용자가 액세스하기 위해 로그인할 수 있다.
|
|
||||||
|
|
||||||
1. 사용자가 로컬에서 지정된 프로그램이 아닌 외부에서 접근한다면 시작한다.
|
|
||||||
2. 로그인 암호를 요구한다. 초기 로그인 암호는 환경변수에 의해서 결정된다.
|
|
||||||
3. 알맞은 암호를 입력했다면 권한을 부여한다.
|
|
||||||
|
|
||||||
### (23) Management: Configure
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 없음.
|
|
||||||
목표: 앱 정책등에 대해 앱에서 설정할 수 있다.
|
|
||||||
|
|
||||||
1. 편집기 내부에서 설정 아이콘을 클릭하면 설정창을 보여준다. 설정창은 프로그램의 속성을 설정할 수 있고 로그를 볼 수 있다. 설정창은 다음 항목들을 포함한다.
|
|
||||||
- 로그인 암호
|
|
||||||
- 테마 설정
|
|
||||||
- 언어 설정
|
|
||||||
이것은 권한에 따라 선택적으로 렌더링된다.
|
|
||||||
2. 다시 설정 아이콘을 클릭하면 설정창을 닫는다.
|
|
||||||
|
|
||||||
### (24) Management: Localization
|
|
||||||
> 어플리케이션을 여러가지 다양한 언어로 제공한다.
|
|
||||||
> 다음은 다른 언어로 바꾸는 사용 사례이다.
|
|
||||||
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 없음.
|
|
||||||
목표: 설정창에서 다른 언어로 바꿀 수 있다.
|
|
||||||
|
|
||||||
1. 설정창을 연다.
|
|
||||||
2. 언어 항목으로 간다. 지원되는 언어 리스트 창이 놓여저있다.
|
|
||||||
3. 언어 항목에서 다른 언어로 바꾼다. 이때 창을 다시 렌더링한다.
|
|
||||||
|
|
||||||
### (25) Management: Theme
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: 없음.
|
|
||||||
목표: 설정창에서 테마를 설정할 수 있다.
|
|
||||||
|
|
||||||
1. 설정창에서 테마로 이동한다.
|
|
||||||
2. 기본적으로 제공하는 밝은 테마과 어두운 테마를 고른다. 기본값은 밝은 색이다. 바꾸는 즉시 테마를 변경한다.
|
|
||||||
3. 커스텀 css 를 올려서 테마로 등록한다.
|
|
||||||
|
|
||||||
### (27) Chunk: edit
|
|
||||||
액터: 사용자
|
|
||||||
시작조건: Chunk의 Focus를 얻어야 한다.
|
|
||||||
목표: Chunk안의 컨텐츠를 수정할 수 있다.
|
|
||||||
|
|
||||||
1. 수정가능한 타입인지 확인한다.
|
|
||||||
2. 타입에 맞는 에디터를 띄운다. 예를 들어 text 타입이면 해당 Chunk 안의 text를 수정할 수 있게 한다.
|
|
||||||
|
|
||||||
### (28) Extension: API
|
|
||||||
액터: API 사용자
|
|
||||||
시작조건: 없음.
|
|
||||||
목표: 외부에서 API를 가지고 접근가능하도록 인터페이스를 제공한다.
|
|
||||||
|
|
||||||
1. 설정에 들어가서 API 토큰을 발급받는다.
|
|
||||||
2. api를 사용할때 Header에 발급받은 토큰을 넣고 통신한다.
|
|
||||||
|
|
||||||
### (29) Extension: Plugin
|
|
||||||
액터: 사용자
|
|
||||||
시작 조건: 없음
|
|
||||||
목표: Plugin으로 편집환경을 확장 가능하게 한다.
|
|
||||||
|
|
||||||
1. 플러그인을 폴더에 추가해 플러그인을 설치한다.
|
|
||||||
2. 플러그인을 사용한다.
|
|
||||||
> - 기능 요구사항은 소프트웨어가 입력을 처리하고 출력을 생성하는 기본적인 행동을 정의해야 한다.
|
|
||||||
> - 포함하는 행동들
|
|
||||||
> 1. Validity checks on the inputs
|
|
||||||
> 1. Exact sequence of operations
|
|
||||||
> 1. Responses to abnormal situations, including
|
|
||||||
> 1. Overflow
|
|
||||||
> 1. Communication facilities
|
|
||||||
> 1. Error handling and recovery
|
|
||||||
> 1. Effect of parameters
|
|
||||||
> 1. Relationship of outputs to inputs, including
|
|
||||||
> 1. Input/output sequences
|
|
||||||
> 1. Formulas for input to output conversion
|
|
||||||
|
|
||||||
## 3.3. 성능 요구사항(Performance requirements)
|
|
||||||
|
|
||||||
> - 소프트웨어 또는 소프트웨어와 사람의 상호작용에 대하여 수치화된 정적/동적 요구사항이 명시되어야 한다.
|
|
||||||
> - 수치화된 정적 요구사항의 종류
|
|
||||||
> 1. 지원할 터미널 수
|
|
||||||
> 1. 지원할 동시 접속 사용자 수
|
|
||||||
> 1. 처리할 정보의 양과 유형작업 및 데이터의 양
|
|
||||||
|
|
||||||
## 3.4. 논리적 데이터베이스 요구사항(Logical database requirements)
|
|
||||||
|
|
||||||
> - 데이터베이스에 저장할 정보에 관한 논리적 요구사항을 지정해야 한다.
|
|
||||||
> - 논리적 요구사항의 종류
|
|
||||||
> 1. Types of information used by various functuons
|
|
||||||
> 1. Frequency of use
|
|
||||||
> 1. Accessing capabilities
|
|
||||||
> 1. Data entities and their relationships
|
|
||||||
> 1. Integrity constraints
|
|
||||||
> 1. Data retention requirements
|
|
||||||
|
|
||||||
## 3.5. 설계 제약사항(Design constraints)
|
|
||||||
|
|
||||||
> - 다른 표준, 하드웨어 한계 등에 의해 부과될 수 있는 설계 제약사항을 명시해야 한다.
|
|
||||||
|
|
||||||
### 3.5.1. 표준 준수(Standards compliance)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
## 3.6. 소프트웨어 시스템 속성(Software system attributes)
|
|
||||||
|
|
||||||
> - 요구사항으로 사용될 수 있는 소프트웨어의 여러 가지 속성 중 제품이 객관적으로 입증되는 데 필요한 속성을 명시해야 한다.
|
|
||||||
|
|
||||||
### 3.6.1. 신뢰성(Reliability)
|
|
||||||
|
|
||||||
> - 배포될 때 소프트웨어 시스템의 필수 신뢰성을 확립하는 데 필요한 요소를 명시해야 한다.
|
|
||||||
|
|
||||||
### 3.6.2. 가용성(Availability)
|
|
||||||
|
|
||||||
> - 검사, 복구, 재시작과 같이 전체 시스템에 대해 정의된 가용성 수준을 보장하는 데 필요한 요소가 지정되어야 한다.
|
|
||||||
|
|
||||||
### 3.6.3. 보안성(Security)
|
|
||||||
|
|
||||||
> - 실수 또는 악의적인 접근, 사용, 수정, 파괴, 공개로부터 소프트웨어를 보호하기 위한 요소를 명시해야 한다.
|
|
||||||
> - 포함될 수 있는 요구사항
|
|
||||||
> 1. Utilize certain cryptographical techinques
|
|
||||||
> 1. Keep specific log or history data sets
|
|
||||||
> 1. Assign certain functions to diffrent modules
|
|
||||||
> 1. Restrict communication between some areas of the program
|
|
||||||
> 1. Check data integrity for critical variables
|
|
||||||
|
|
||||||
### 3.6.4. 유지 보수성(Maintainability)
|
|
||||||
|
|
||||||
> - 소프트웨어 자체를 쉽게 유지 보수할 수 있는 속성을 명시해야 한다.
|
|
||||||
> - 모듈화, 인터페이스, 복잡성 등과 관련된 요구사항이 있을 수 있다.
|
|
||||||
|
|
||||||
### 3.6.5. 이식성(Portability)
|
|
||||||
|
|
||||||
해당되지 않음.
|
|
||||||
|
|
||||||
## 3.7. 상세 요구사항의 구성(Organizing the specific requirements)
|
|
||||||
|
|
||||||
> - 시스템의 세부 요구사항은 광범위한 경향이 있으므로 자료를 이해하기에 가장 적합한 방식으로 구성하는 방법을 세심하게 고려해야 한다.
|
|
||||||
|
|
||||||
### 3.7.1. 시스템 모드(System mode)
|
|
||||||
|
|
||||||
> - 일부 시스템은 운영 모드에 따라 상당히 다르게 작동할 수 있다.
|
|
||||||
> - 예: 제어 시스템은 연습, 일반, 긴급 등의 여러 모드가 있을 수 있다.
|
|
||||||
|
|
||||||
### 3.7.2. 사용자 부류(User class)
|
|
||||||
|
|
||||||
> - 일부 시스템은 사용자의 부류에 따라 서로 다른 기능을 제공한다.
|
|
||||||
> - 예: 엘리베이터 제어 시스템은 승객, 정비원, 소방관에게 서로 다른 기능을 제공한다.
|
|
||||||
|
|
||||||
### 3.7.3. 객체(Objects)
|
|
||||||
|
|
||||||
> - 객체는 시스템에서 현실 세계와 대응되는 개체이다.
|
|
||||||
> - 객체에는 각 각체의 상태(attributes) 및 객체의 행위(functions)가 포함된다.
|
|
||||||
> - 이러한 행위는 services, methods, processes라고도 한다.
|
|
||||||
|
|
||||||
### 3.7.4. 특징(Feature)
|
|
||||||
|
|
||||||
> - 특징은 시스템에 의해 외부적으로 요구되는 서비스로서 원하는 결과를 얻기 위해서는 입력이 필요할 수도 있다.
|
|
||||||
> - 예: 전화 시스템에서 특징들은 지역 내 통화, 착신 전환, 화상 통화를 포함한다.
|
|
||||||
> - 일반적으로 각 특징은 자극-반응의 순서로 설명된다.
|
|
||||||
|
|
||||||
### 3.7.5. 자극(Stimulus)
|
|
||||||
|
|
||||||
> - 일부 시스템은 자극의 측면에서 기능들을 설명할 때 가장 잘 구성될 수 있다.
|
|
||||||
> - 예: 항공기 자동 착륙 시스템은 동력 상실, 윈드시어 등을 위해 구성될 수 있다.
|
|
||||||
|
|
||||||
### 3.7.6. 반응(Response)
|
|
||||||
|
|
||||||
> - 일부 시스템은 반응 생성을 지원하는 기능들을 설명할 때 가장 잘 구성될 수 있다.
|
|
||||||
> - 예: 직원 시스템의 기능은 급여 생성과 관련된 기능들, 직원 목록 생성과 관련된 기능 등으로 구성될 수 있다.
|
|
||||||
|
|
||||||
### 3.7.7. 기능 계층(Functional hierarchy)
|
|
||||||
|
|
||||||
> - 위 조직 체계 중 유용한 수단이 없다면, 전체 기능은 공통 입력, 공통 출력 또는 공통 내부 데이터 접근에 의해 구성된 기능의 계층으로 구성될 수 있다.
|
|
||||||
> - 데이터 흐름 다이어그램과 데이터 사전을 사용하여 기능과 데이터 사이의 관계를 보여줄 수 있다.
|
|
||||||
|
|
||||||
|
|
||||||
### 3.7.8. Additional comments
|
|
||||||
|
|
||||||
> - 새로운 SRS를 고려할 때 두 가지 이상의 조직 기법이 적합할 수 있다.
|
|
||||||
> - 이 경우 명세에 따른 시스템의 상세 요구사항에 맞춘 다중 계층의 요구사항을 구성한다.
|
|
@ -21,7 +21,6 @@ deno run --allow-read --allow-write printDocument.ts --overall --path ./issues.j
|
|||||||
으로 실행하면 됩니다.
|
으로 실행하면 됩니다.
|
||||||
|
|
||||||
다음과 같은 인자를 가집니다:
|
다음과 같은 인자를 가집니다:
|
||||||
- `overall`: overall을 출력
|
- `outDir`: 지정된 경로에 출력. 설정되지 않으면 `stdout`에 출력함.
|
||||||
- `outpath`: 지정된 경로에 출력. 설정되지 않으면 `stdout`에 출력함.
|
|
||||||
- `issue_path`: json 파일 위치. 지정되지 않으면 `stdin`에서 읽으려고 시도.
|
- `issue_path`: json 파일 위치. 지정되지 않으면 `stdin`에서 읽으려고 시도.
|
||||||
- `w`, `watch`: 파일에 변경이 있을 때 자동으로 업데이트.
|
- `w`, `watch`: 파일에 변경이 있을 때 자동으로 업데이트.
|
@ -3,7 +3,7 @@ import { Issue } from "./githubType.ts";
|
|||||||
import { readAll } from "https://deno.land/std@0.135.0/streams/mod.ts"
|
import { readAll } from "https://deno.land/std@0.135.0/streams/mod.ts"
|
||||||
import { parse as argParse } from "https://deno.land/std@0.135.0/flags/mod.ts";
|
import { parse as argParse } from "https://deno.land/std@0.135.0/flags/mod.ts";
|
||||||
import { normalize, join as pathJoin, fromFileUrl } from "https://deno.land/std@0.135.0/path/mod.ts";
|
import { normalize, join as pathJoin, fromFileUrl } from "https://deno.land/std@0.135.0/path/mod.ts";
|
||||||
import * as Eta from "https://deno.land/x/eta/mod.ts";
|
import * as Eta from "https://deno.land/x/eta@v1.12.3/mod.ts";
|
||||||
|
|
||||||
async function readContent(path?: string): Promise<string> {
|
async function readContent(path?: string): Promise<string> {
|
||||||
let content = "[]";
|
let content = "[]";
|
||||||
@ -19,49 +19,66 @@ async function readContent(path?: string): Promise<string> {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readAndPrint(args: {
|
type DocType = "overall.md" | "specific.md" |"intro.md" | "SUMMARY.md" | "support.md";
|
||||||
path?: string,
|
const targets: DocType[] = ["SUMMARY.md", "overall.md", "specific.md", "intro.md", "support.md"];
|
||||||
overall?: boolean,
|
|
||||||
outpath?: string
|
type printDocParam = {
|
||||||
|
target: DocType,
|
||||||
|
data:{
|
||||||
|
issues: Issue[]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function printDoc(param: printDocParam,option? : {
|
||||||
|
outDir?: string
|
||||||
}){
|
}){
|
||||||
const c = await readContent(args.path);
|
option = option ?? {};
|
||||||
const issues = JSON.parse(c) as Issue[];
|
const {target , data } = param;
|
||||||
issues.sort((a, b) => a.number - b.number);
|
const { outDir } = option;
|
||||||
|
|
||||||
let print: string = "";
|
let print: string = "";
|
||||||
if (args.overall) {
|
print = await Eta.renderFile(target, data) as string;
|
||||||
print = await Eta.renderFile("overall.md", {
|
if (outDir) {
|
||||||
issues: issues
|
const outPath = pathJoin(outDir, target);
|
||||||
}) as string;
|
await Deno.mkdir(pathJoin(outDir), { recursive: true });
|
||||||
}
|
await Deno.writeTextFile(outPath, print);
|
||||||
else {
|
|
||||||
print = await Eta.renderFile("specific.md", {
|
|
||||||
issues: issues
|
|
||||||
}) as string;
|
|
||||||
}
|
|
||||||
if (args.outpath) {
|
|
||||||
Deno.writeTextFileSync(args.outpath, print);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(print);
|
console.log(print);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function readAndPrint(args: {
|
||||||
|
issue_path?: string,
|
||||||
|
outDir?: string
|
||||||
|
}) {
|
||||||
|
const c = await readContent(args.issue_path);
|
||||||
|
const issues = JSON.parse(c) as Issue[];
|
||||||
|
issues.sort((a, b) => a.number - b.number);
|
||||||
|
for(const target of targets){
|
||||||
|
await printDoc({
|
||||||
|
target: target,
|
||||||
|
data: {
|
||||||
|
issues
|
||||||
|
}}
|
||||||
|
,{
|
||||||
|
outDir: args.outDir
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const parsedArg = argParse(Deno.args);
|
const parsedArg = argParse(Deno.args);
|
||||||
const { issue_path, outpath, overall, w, watch } = parsedArg;
|
const { issue_path, outDir, w, watch } = parsedArg;
|
||||||
const watchMode = w || watch;
|
const watchMode = w || watch;
|
||||||
if (typeof issue_path !== "undefined" && typeof issue_path !== "string") {
|
if (typeof issue_path !== "undefined" && typeof issue_path !== "string") {
|
||||||
console.log("Please provide a path to the json file.");
|
console.log("Please provide a path to the json file.");
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
if (typeof outpath !== "undefined" && typeof outpath !== "string") {
|
if (typeof outDir !== "undefined" && typeof outDir !== "string") {
|
||||||
console.log("Please provide a path to the output file.");
|
console.log("Please provide a path to the output file.");
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
if (typeof overall !== "undefined" && typeof overall !== "boolean") {
|
|
||||||
console.log("Please provide a boolean value for overall.");
|
|
||||||
Deno.exit(1);
|
|
||||||
}
|
|
||||||
if (typeof watchMode !== "undefined" && typeof watchMode !== "boolean") {
|
if (typeof watchMode !== "undefined" && typeof watchMode !== "boolean") {
|
||||||
console.log("Please provide a boolean value for w.");
|
console.log("Please provide a boolean value for w.");
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
@ -82,9 +99,9 @@ async function main() {
|
|||||||
const c = await readContent(issue_path);
|
const c = await readContent(issue_path);
|
||||||
const issues = JSON.parse(c) as Issue[];
|
const issues = JSON.parse(c) as Issue[];
|
||||||
issues.sort((a, b) => a.number - b.number);
|
issues.sort((a, b) => a.number - b.number);
|
||||||
await readAndPrint({ path, outpath, overall });
|
await readAndPrint({ issue_path, outDir });
|
||||||
if (watchMode) {
|
if (watchMode) {
|
||||||
const watcher = Deno.watchFs([viewPath, path as string]);
|
const watcher = Deno.watchFs([viewPath, issue_path as string]);
|
||||||
for await (const event of watcher) {
|
for await (const event of watcher) {
|
||||||
if (event.kind === "modify") {
|
if (event.kind === "modify") {
|
||||||
Deno.stdout.write(
|
Deno.stdout.write(
|
||||||
@ -92,9 +109,8 @@ async function main() {
|
|||||||
);
|
);
|
||||||
console.log(`reloading ${event.paths.join(", ")}`);
|
console.log(`reloading ${event.paths.join(", ")}`);
|
||||||
readAndPrint({
|
readAndPrint({
|
||||||
path: path as string,
|
issue_path: issue_path as string,
|
||||||
overall: overall as boolean,
|
outDir: outDir as string
|
||||||
outpath: outpath as string
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
tools/template/SUMMARY.md
Normal file
6
tools/template/SUMMARY.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Summary
|
||||||
|
|
||||||
|
- [Introduction](./intro.md)
|
||||||
|
- [Overall Description](./overall.md)
|
||||||
|
- [Specific Requirement](./specific.md)
|
||||||
|
- [Supporting information](./support.md)
|
Loading…
Reference in New Issue
Block a user