본문으로 이동

사용자:Senouis/도전과제 서버 명세: 두 판 사이의 차이

리버티게임(개발), 모두가 만들어가는 자유로운 게임
Senouis (토론 | 기여)
명세 최종 변경
Senouis (토론 | 기여)
 
(같은 사용자의 중간 판 4개는 보이지 않습니다)
5번째 줄: 5번째 줄:
2025년 6월 전까지 동작하는 물건을 만드는 것이 목표, 1월에 계획을 시작할 예정
2025년 6월 전까지 동작하는 물건을 만드는 것이 목표, 1월에 계획을 시작할 예정


==예상 기술 스택==
== 기술 스택==
*백엔드 개발 환경: Java + Spring<ref>Apache Tomcat이 포함됩니다.</ref> 기반
*백엔드 개발 환경: Java + Spring<ref>Apache Tomcat이 포함됩니다.</ref> 기반
**현재 임시로 만든 임시 리포지토리에는 Node.js 기반으로 환경이 구축되어 있습니다. 아직 작업 시작한 부분이 없어 처음 상태 그대로입니다. 리셋 예정입니다.
*DB: Oracle DB + JPA로 확정
*DB: MongoDB로 확정
* 스키마를 고정할 방법을 찾은 관계로 기존 기획이었던 MongoDB 대신
**도전과제 서버의 진행도 데이터는 금융권 DB마냥 ACID가 중요한 데이터 종류가 아님: 빠른 로드가 우선됨
* 도전과제를 생성 가능한 유저와 달성 가능한 유저 사이의 권한을 분리
**기존의 JSON 파일 저장 방식 대신 BSON 스키마를 사용해 저장하는 MongoDB 채택
 
** Spring Data for MongoDB로 DB를 연결할 예정
== 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 토큰이 모두 없는 경우
33번째 줄: 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 ->> MongoDB: Create database
     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
42번째 줄: 77번째 줄:
libertyga.me/achievement/v0/addition
libertyga.me/achievement/v0/addition


* 웹 페이지에 진입하면 Access Token이 있는 경우에만 사용자 이름과 토큰을 헤더에 삽입하여 Create 수행, 없으면 로그인 요청을 mw.notification.notify()로 알림
* 고유한 값을 가지는 도전과제 이름(title)과 설명, 그리고 도전 과제 달성까지 필요한 행동 횟수를 요청함
** 다음과 같은 상황에서 스키마에 항목을 추가
* 성공시 도전과제 이름 반환, 실패할 경우 에러 처리
*** 특정 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()]로 알려야 함


{{#mermaid:
{{#mermaid:
61번째 줄: 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 update to MongoDB
     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
70번째 줄: 94번째 줄:
   "title": String,
   "title": String,
   "description": String,
   "description": String,
   "useIdx": Number
   "MaxNumber": Number
}
}
</syntaxhighlight>
</syntaxhighlight>
85번째 줄: 109번째 줄:
* 아이템 조회 과정
* 아이템 조회 과정
* 파라미터: user URL 파라미터는 숫자 ID
* 파라미터: user URL 파라미터는 숫자 ID
** 필터링 통과 실패 -> '제작자가 도전과제 이름을 잘못 지정했습니다.'라는 오류 메세지를 반환하여 mw.notification으로 송출하도록 함


{{#mermaid:
{{#mermaid:
92번째 줄: 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 database
     Achievement Server-)MongoDB: Request read DATABASE achievement TABLE progress
     MongoDB -->> Achievement Server: Response Success
     MongoDB -->> Achievement Server: Response Success
     Achievement Server-->>User: Response Success
     Achievement Server-->>User: Response Success
107번째 줄: 130번째 줄:
       "progress": Number,
       "progress": Number,
       "maxProgress": 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
    Achievement Server-->>User: Response Success
}}
 
==== Request Body ====
<syntaxhighlight lang=json>
{
  "title": String,
}
</syntaxhighlight>
==== Response Body ====
<syntaxhighlight lang=json>
{
  "success": true,
  "result" : [
    {
      "title": String,
      "description": String,
      "progress": Number,
      "maxProgress": Number
    },
    ...
   ]
   ]
}
}
117번째 줄: 192번째 줄:
* 도전과제를 초기화하고 스키마만 남김
* 도전과제를 초기화하고 스키마만 남김
* DELETE 요청이므로 헤더에 Access 토큰 부착할 것
* DELETE 요청이므로 헤더에 Access 토큰 부착할 것
** 성공 후에는 사용자 LocalStorage도 초기화하여 다시 요청하도록 함


{{#mermaid:
{{#mermaid:
123번째 줄: 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 database
     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 브라우저 캐싱 기능을 추가할 것
* HEAD 요청이 추가로 필요할 수 있으며, 자신의 데이터베이스 스키마의 SHA-256 해시값을 헤더에 포함해 반환할 것
** 반환한 해시값이 다르면 통짜 조회
<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주 유효기간으로 설정
  • 아래 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 브라우저 캐싱 기능을 추가할 것
  1. Apache Tomcat이 포함됩니다.