사용자:Senouis/도전과제 서버 명세: 두 판 사이의 차이
보이기
잔글 →예상 기술 스택 |
잔글 →DB 스키마 |
||
(같은 사용자의 중간 판 2개는 보이지 않습니다) | |||
5번째 줄: | 5번째 줄: | ||
2025년 6월 전까지 동작하는 물건을 만드는 것이 목표, 1월에 계획을 시작할 예정 | 2025년 6월 전까지 동작하는 물건을 만드는 것이 목표, 1월에 계획을 시작할 예정 | ||
== | == 기술 스택== | ||
*백엔드 개발 환경: Java + Spring<ref>Apache Tomcat이 포함됩니다.</ref> 기반 | *백엔드 개발 환경: Java + Spring<ref>Apache Tomcat이 포함됩니다.</ref> 기반 | ||
** | *DB: Oracle DB + JPA로 확정 | ||
*DB: | * 스키마를 고정할 방법을 찾은 관계로 기존 기획이었던 MongoDB 대신 | ||
* 도전과제를 생성 가능한 유저와 달성 가능한 유저 사이의 권한을 분리 | |||
== DB 스키마 == | |||
{{#mermaid: | |||
erDiagram | |||
Progress||--||Achievement : "achieve specific achievement" | |||
User||--o{Progress : "user have progress" | |||
User||--o|Promote : "ADVANCED promotion request" | |||
Achievement { | |||
id Long | |||
name String | |||
description String | |||
maxProgress Integer | |||
} | |||
Progress { | |||
id Long | |||
achievement_id Long | |||
user_id Long | |||
progress Integer | |||
} | |||
User { | |||
id Long | |||
name String | |||
email String | |||
password String | |||
promote_id Integer | |||
} | |||
Promote { | |||
id Long | |||
user_id Long | |||
} | |||
}} | |||
==기능== | ==기능== | ||
===처음 시작할 때=== | ===처음 시작할 때=== | ||
* OAuth 2.0으로만 로그인 가능하고, 'BASIC' 권한이 발행됨 | |||
** BASIC 권한: 도전과제 달성만 가능 | |||
** ADVANCED 권한: 도전과제 생성 및 삭제 가능 | |||
*** ADVANCED 권한 신청 API를 요청하면 관리자에게 허가 요청 메일이 날아감(허가 및 거부 API 링크 포함됨) | |||
** ADMIN 권한: ADVANCED 권한 부여 가능한 권한, DB에서 서버 제작자 포함하여 직접 설정할 예정 | |||
*안내문(수집하게 되는 개인정보 등을 공시)과 함께 OAuth 2.0 인증 절차를 수행하는 링크를 추가 | *안내문(수집하게 되는 개인정보 등을 공시)과 함께 OAuth 2.0 인증 절차를 수행하는 링크를 추가 | ||
**웹 페이지에 진입했을 때 Authorization Token과 Refresh 토큰이 모두 없는 경우 | **웹 페이지에 진입했을 때 Authorization Token과 Refresh 토큰이 모두 없는 경우 | ||
34번째 줄: | 68번째 줄: | ||
Achievement Server ->> OAuth Server: Request Profile with AT | Achievement Server ->> OAuth Server: Request Profile with AT | ||
OAuth Server-->>Achievement Server: Give User Profile if it is right | OAuth Server-->>Achievement Server: Give User Profile if it is right | ||
Achievement Server ->> | Achievement Server ->> Oracle DB: Create database | ||
MongoDB -->> Achievement Server: Response Success | MongoDB -->> Achievement Server: Response Success | ||
Achievement Server -->> User: Response Success | Achievement Server -->> User: Response Success | ||
43번째 줄: | 77번째 줄: | ||
libertyga.me/achievement/v0/addition | libertyga.me/achievement/v0/addition | ||
* | * 고유한 값을 가지는 도전과제 이름(title)과 설명, 그리고 도전 과제 달성까지 필요한 행동 횟수를 요청함 | ||
* 성공시 도전과제 이름 반환, 실패할 경우 에러 처리 | |||
* | |||
{{#mermaid: | {{#mermaid: | ||
62번째 줄: | 85번째 줄: | ||
Achievement Server->>OAuth Server: Request Profile with AT | Achievement Server->>OAuth Server: Request Profile with AT | ||
OAuth Server-->>Achievement Server: Give User Profile if it is right | OAuth Server-->>Achievement Server: Give User Profile if it is right | ||
Achievement Server-)MongoDB: Request | Achievement Server-)MongoDB: Request addition to TABLE achievement TABLE achievement | ||
MongoDB -->> Achievement Server: Response Success | MongoDB -->> Achievement Server: Response Success | ||
Achievement Server -->> User: Response Success | Achievement Server -->> User: Response Success | ||
71번째 줄: | 94번째 줄: | ||
"title": String, | "title": String, | ||
"description": String, | "description": String, | ||
" | "MaxNumber": Number | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
86번째 줄: | 109번째 줄: | ||
* 아이템 조회 과정 | * 아이템 조회 과정 | ||
* 파라미터: user URL 파라미터는 숫자 ID | * 파라미터: user URL 파라미터는 숫자 ID | ||
{{#mermaid: | {{#mermaid: | ||
93번째 줄: | 115번째 줄: | ||
Achievement Server ->> OAuth Server: Request Profile with AT | Achievement Server ->> OAuth Server: Request Profile with AT | ||
OAuth Server-->>Achievement Server: Give User Profile if it is right | OAuth Server-->>Achievement Server: Give User Profile if it is right | ||
Achievement Server-)MongoDB: Request read | Achievement Server-)MongoDB: Request read DATABASE achievement TABLE progress | ||
MongoDB -->> Achievement Server: Response Success | |||
Achievement Server-->>User: Response Success | |||
}} | |||
==== Response Body ==== | |||
<syntaxhighlight lang=json> | |||
{ | |||
"success": true, | |||
"result" : [ | |||
{ | |||
"title": String, | |||
"description": String, | |||
"progress": Number, | |||
"maxProgress": Number | |||
}, | |||
... | |||
] | |||
} | |||
</syntaxhighlight> | |||
=== Update === | |||
libertyga.me/achievement/v0/achieved | |||
* 웹 페이지에 진입하면 Access Token이 있는 경우에만 사용자 이름과 토큰을 헤더에 삽입하여 Create 수행, 없으면 로그인 요청을 mw.notification.notify()로 알림 | |||
** 다음과 같은 상황에서 스키마에 항목을 추가 | |||
*** 특정 classname을 가진 링크를 클릭했을 때 | |||
*** 특정 classname을 가진 div 태그를 발견했을 때 innerHTML에 있는 데이터를 itemname에 밀어넣음 | |||
**요청 종류는 POST으로 설정 | |||
**POST 요청을 받은 서버는 profile 리소스를 요청하여 인증 성공시 DB에 사용자 이름으로 된 스키마 내에 항목을 하나 추가 | |||
***스키마 내부에는 항목 이름 및 설명을 문자와 숫자의 조합으로 자유롭게 생성 가능하며, 리버티게임 계정 유저의 DB ID 번호를 넘김 | |||
***max_value를 설정해야 함: data-value 커스텀 HTML attribute에 기록된 값을 읽어야 함, 기본값은 1로 할 것 | |||
***value는 1로 초기화 | |||
**결과 반환은 상황에 따라 다름 | |||
***value == maxvalue == 1이면 즉시 달성으로 결과 반환 | |||
***value < maxvalue면 (1/n)을 붙여 결과 반환, 이후 달성할 때마다 value를 늘림 | |||
*성공/실패할 경우 [https://doc.wikimedia.org/mediawiki-core/REL1_39/js/#!/api/mw.notification mw.notification.notify()]로 알려야 함 | |||
** 성공 후에는 사용자 LocalStorage에 기록하여 다시 요청하지 않도록 함 | |||
{{#mermaid: | |||
sequenceDiagram | |||
User->>Achievement Server: Request collection read with AT | |||
Achievement Server ->> OAuth Server: Request Profile with AT | |||
OAuth Server-->>Achievement Server: Give User Profile if it is right | |||
Achievement Server-)MongoDB: Request update DATABASE achievement TABLE progress | |||
MongoDB -->> Achievement Server: Response Success | MongoDB -->> Achievement Server: Response Success | ||
Achievement Server-->>User: Response Success | Achievement Server-->>User: Response Success | ||
}} | }} | ||
==== Request Body ==== | |||
<syntaxhighlight lang=json> | |||
{ | |||
"title": String, | |||
} | |||
</syntaxhighlight> | |||
==== Response Body ==== | ==== Response Body ==== | ||
<syntaxhighlight lang=json> | <syntaxhighlight lang=json> | ||
119번째 줄: | 192번째 줄: | ||
* 도전과제를 초기화하고 스키마만 남김 | * 도전과제를 초기화하고 스키마만 남김 | ||
* DELETE 요청이므로 헤더에 Access 토큰 부착할 것 | * DELETE 요청이므로 헤더에 Access 토큰 부착할 것 | ||
** 성공 후에는 사용자 LocalStorage도 초기화하여 다시 요청하도록 함 | |||
{{#mermaid: | {{#mermaid: | ||
125번째 줄: | 199번째 줄: | ||
Achievement Server-)OAuth Server: Request Profile with AT | Achievement Server-)OAuth Server: Request Profile with AT | ||
OAuth Server-->>Achievement Server: Give User Profile if it is right | OAuth Server-->>Achievement Server: Give User Profile if it is right | ||
Achievement Server-)MongoDB: Request delete | Achievement Server-)MongoDB: Request delete DATABASE achievement TABLE Progress (user = '...') | ||
MongoDB -->> Achievement Server: Response Success | MongoDB -->> Achievement Server: Response Success | ||
Achievement Server-->>User: Response Success | Achievement Server-->>User: Response Success | ||
}} | }} | ||
==== Request Body ==== | |||
<syntaxhighlight lang=json> | |||
{ | |||
"username": String | |||
} | |||
</syntaxhighlight> | |||
== 기타 == | == 기타 == | ||
* LocalStorage 브라우저 캐싱 기능을 추가할 것 | * LocalStorage 브라우저 캐싱 기능을 추가할 것 | ||
<references /> | <references /> |
2025년 3월 13일 (목) 11:43 기준 최신판
'미디어위키:Gadget-Achievement.js'를 통해 다음 과정을 수행
모든 결과에는 HTTP 응답 코드와 메세지를 응답 헤더에 포함할 것
2025년 6월 전까지 동작하는 물건을 만드는 것이 목표, 1월에 계획을 시작할 예정
기술 스택
- 백엔드 개발 환경: Java + Spring[1] 기반
- DB: Oracle DB + JPA로 확정
- 스키마를 고정할 방법을 찾은 관계로 기존 기획이었던 MongoDB 대신
- 도전과제를 생성 가능한 유저와 달성 가능한 유저 사이의 권한을 분리
DB 스키마
기능
처음 시작할 때
- OAuth 2.0으로만 로그인 가능하고, 'BASIC' 권한이 발행됨
- BASIC 권한: 도전과제 달성만 가능
- ADVANCED 권한: 도전과제 생성 및 삭제 가능
- ADVANCED 권한 신청 API를 요청하면 관리자에게 허가 요청 메일이 날아감(허가 및 거부 API 링크 포함됨)
- ADMIN 권한: ADVANCED 권한 부여 가능한 권한, DB에서 서버 제작자 포함하여 직접 설정할 예정
- 안내문(수집하게 되는 개인정보 등을 공시)과 함께 OAuth 2.0 인증 절차를 수행하는 링크를 추가
- 웹 페이지에 진입했을 때 Authorization Token과 Refresh 토큰이 모두 없는 경우
- OAuth 확장 기능의 절차대로 리버티게임 서버 내 OAuth 기능에 Authorization 토큰 발급 요청
- Authorization 코드 발급 기능을 먼저 구현한 후 PKCE 과정을 추가해 code_challenge 수행 필요
- Redirect URI는 요청한 페이지로 설정
- 웹 페이지에 진입했을 때 Authorization 토큰이 있는 경우 or Refresh 토큰이 있는 경우
- 즉시 OAuth 확장 기능의 절차대로 리버티게임 서버 내 OAuth 기능에 Access 토큰 및 Refresh 토큰 발급 요청
- 쿠키에 Access 토큰 및 Refresh 토큰을 1주 유효기간으로 설정
- 웹 페이지에 진입했을 때 Authorization Token과 Refresh 토큰이 모두 없는 경우
- 아래 CRUD 요청에서 Access Token 뿐만 아니라 Refresh 토큰까지 만료된 경우 mw.notification으로 재연동을 요청할 것
Create
libertyga.me/achievement/v0/addition
- 고유한 값을 가지는 도전과제 이름(title)과 설명, 그리고 도전 과제 달성까지 필요한 행동 횟수를 요청함
- 성공시 도전과제 이름 반환, 실패할 경우 에러 처리
Request Body
{
"title": String,
"description": String,
"MaxNumber": Number
}
Response Body
{
"success": true,
"result": String
}
Read
libertyga.me:6400/achievement/v0/list/{user}
- 아이템 조회 과정
- 파라미터: user URL 파라미터는 숫자 ID
Response Body
{
"success": true,
"result" : [
{
"title": String,
"description": String,
"progress": Number,
"maxProgress": Number
},
...
]
}
Update
libertyga.me/achievement/v0/achieved
- 웹 페이지에 진입하면 Access Token이 있는 경우에만 사용자 이름과 토큰을 헤더에 삽입하여 Create 수행, 없으면 로그인 요청을 mw.notification.notify()로 알림
- 다음과 같은 상황에서 스키마에 항목을 추가
- 특정 classname을 가진 링크를 클릭했을 때
- 특정 classname을 가진 div 태그를 발견했을 때 innerHTML에 있는 데이터를 itemname에 밀어넣음
- 요청 종류는 POST으로 설정
- POST 요청을 받은 서버는 profile 리소스를 요청하여 인증 성공시 DB에 사용자 이름으로 된 스키마 내에 항목을 하나 추가
- 스키마 내부에는 항목 이름 및 설명을 문자와 숫자의 조합으로 자유롭게 생성 가능하며, 리버티게임 계정 유저의 DB ID 번호를 넘김
- max_value를 설정해야 함: data-value 커스텀 HTML attribute에 기록된 값을 읽어야 함, 기본값은 1로 할 것
- value는 1로 초기화
- 결과 반환은 상황에 따라 다름
- value == maxvalue == 1이면 즉시 달성으로 결과 반환
- value < maxvalue면 (1/n)을 붙여 결과 반환, 이후 달성할 때마다 value를 늘림
- 다음과 같은 상황에서 스키마에 항목을 추가
- 성공/실패할 경우 mw.notification.notify()로 알려야 함
- 성공 후에는 사용자 LocalStorage에 기록하여 다시 요청하지 않도록 함
Request Body
{
"title": String,
}
Response Body
{
"success": true,
"result" : [
{
"title": String,
"description": String,
"progress": Number,
"maxProgress": Number
},
...
]
}
Delete (선택 구현)
libertyga.me:6400/achievement/v0/deletion
- 도전과제를 초기화하고 스키마만 남김
- DELETE 요청이므로 헤더에 Access 토큰 부착할 것
- 성공 후에는 사용자 LocalStorage도 초기화하여 다시 요청하도록 함
Request Body
{
"username": String
}
기타
- LocalStorage 브라우저 캐싱 기능을 추가할 것
- ↑ Apache Tomcat이 포함됩니다.