Skip to content

HSH-Phira バックエンドリメイク版

実行方法

開発環境

本プロジェクトは uv を使用して管理されています。リポジトリ(完全版)を HSNPhira ディレクトリにクローンし、uv をインストール済みであることを前提とします。以下のコマンドを順に実行してください:

bash
# バックエンドディレクトリに移動
cd HSNPhira/backend
# 依存関係をインストール
uv sync
# データベースを初期化(初回サーバー実行前のみ)
uv run flask seed_db
# 実行
uv run flask run --debug --host=0.0.0.0 --port=5000

本番環境

準備中。

API ドキュメント

ユーザー管理 API

ユーザー権限

本プロジェクトはユーザーグループによる権限管理を実装しています。各グループは permissions 属性を持ち、これはビットマスクです。主な値は以下の通りです:

識別子説明
NONE0権限なし
ALL0xffffffffすべての権限
IMPORT0x00000001重要ユーザー
USER_MANAGEMENT0x00000002ユーザー管理権限
GROUP_MANAGEMENT0x00000004ユーザーグループ管理権限

初期状態では1人のユーザーと3つのユーザーグループが作成されます:

ユーザー名ユーザー ID所属グループ
root1super_admin
グループ名グループ ID保有権限
root1ALL
admin2IMPORTANTUSER_MANAGEMENT
user3NONE

POST /api/auth/login

説明:ユーザーログイン

リクエストデータ形式

json
{
  "username": /*文字列、ユーザー名*/,
  "password": /*文字列、パスワード*/,
  "remember": /*ブール値、ユーザーを記憶するかどうか*/
}

レスポンスデータ形式:ログインユーザー情報、形式は /api/auth/me を参照。


POST /api/auth/logout

説明:ユーザーログアウト


GET /api/auth/me

説明:現在のユーザー情報を取得

レスポンスデータ形式

json
{
  "id": /*整数、ユーザー ID*/,
  "group_id": /*整数、ユーザーが所属するグループ ID*/,
  "username": /*文字列、ユーザー名*/,
  "phira_id": /*整数、ユーザーに紐づけられた Phira アカウント ID*/,
  "phira_username": /*文字列、ユーザーの Phira ユーザー名*/,
  "phira_rks": /*浮動小数点数、ユーザーの Phira rks*/,
  "phira_avatar": /*文字列、ユーザーの Phira アバターリンク*/,
  "register_time": /*時刻文字列、ユーザー登録時間*/,
  "last_login_time": /*時刻文字列、ユーザー最終ログイン時間*/,
  "last_sync_time": /*時刻文字列、ユーザー最終 Phira アカウントデータ同期時間*/
}

POST /api/auth/users

説明:ユーザー作成

リクエストデータ形式

json
{
  "group_id": /*整数、オプション、ユーザー所属グループ ID、デフォルト値は 3(user グループ)*/,
  "username": /*文字列、ユーザー名*/,
  "phira_id_or_username": /*文字列、ユーザーが紐づけようとする Phira アカウント ID(文字列形式)または Phira ユーザー名*/,
  "password": /*文字列、ユーザーパスワード*/
}

レスポンスデータ形式:SSE イベントストリームを返します。形式は以下のいずれかです:

  • event: validating
    data: <文字列、検証に使用する token>

    説明:このイベントはリクエスト直後に1回送信されます。その後ユーザーは5分以内に、紐づけようとする Phira アカウントで token を名前に持つルームを作成して検証を完了する必要があります。

  • event: timeout

    説明:タイムアウト後に送信され、その後ストリームは閉じられます。

  • event: success
    data: <JSON 形式文字列、/api/auth/me と同じ形式、新規登録ユーザー情報>

    説明:検証成功後に送信され、その後ストリームは閉じられます。

  • event: error
    data: <文字列、エラーメッセージ>

    説明:サーバーエラー発生時に送信され、その後ストリームは閉じられます。

  • : heartbeat

    説明:クライアントの生存確認用で、実際の意味はありません。ブラウザは通常これを無視します。

特別な説明group_id フィールドが指定された場合、リクエスト元は GROUP_MANAGEMENT 権限を持っている必要があります。


GET /api/auth/users

説明:ユーザー一覧を取得

レスポンスデータ形式

json
[
  { /*各項目は /api/auth/me のレスポンス形式に準拠したオブジェクト*/ }
]

GET /api/auth/users/<int:id>

説明:ユーザー ID が id のユーザー情報を取得

レスポンスデータ形式/api/auth/me のレスポンス形式に準拠したオブジェクト


PATCH /api/auth/users/<int:id>

説明:ユーザー ID が id のユーザー情報を変更

リクエストデータ形式

json
{
  "current_password": /*文字列、リクエスト元アカウントの現在のパスワード*/,
  "group_id": /*整数、オプション、ユーザー所属グループ ID、デフォルト値は 3(user グループ)*/,
  "username": /*文字列、オプション、ユーザー名*/,
  "phira_id": /*整数、オプション、ユーザーに紐づけられた Phira アカウント ID*/,
  "password": /*文字列、オプション、ユーザーパスワード*/
}

レスポンスデータ形式:変更後のユーザー情報、形式は /api/auth/me を参照。


DELETE /api/auth/users/<int:id>

説明:ユーザー ID が id のユーザーを削除

レスポンスデータ形式

json
{
  "message": "success"
}

GET /api/auth/groups

説明:ユーザーグループ一覧を取得

レスポンスデータ形式

json
[
  {
    "id": /*整数、ユーザーグループ ID*/,
    "name": /*文字列、ユーザーグループ名*/,
    "permissions": /*整数、ユーザーグループのビットマスク値*/
  },
  /*各項目は上記形式に準拠したオブジェクト*/
]

POST /api/auth/groups

説明:ユーザーグループを作成

リクエストデータ形式

json
{
  "name": /*文字列、ユーザーグループ名*/,
  "permissions": /*整数、ユーザーグループ権限*/
}

特別な説明GROUP_MANAGEMENT 権限が必要です。


GET /api/auth/groups/<int:id>

説明:グループ ID が id のユーザーグループ情報を取得

レスポンスデータ形式/api/auth/groups の各項目と同じ形式のオブジェクト


PATCH /api/auth/groups/<int:id>

説明:グループ ID が id のユーザーグループ情報を変更

リクエストデータ形式

json
{
  "current_password": /*文字列、リクエスト元ユーザーの現在のパスワード*/,
  "name": /*文字列、ユーザーグループ名*/,
  "permissions": /*整数、ユーザーグループ権限*/
}

レスポンスデータ形式:変更後のグループ情報、形式は /api/auth/groups の各項目を参照。


DELETE /api/auth/groups/<int:id>

説明:グループ ID が id のユーザーグループを削除

レスポンスデータ形式

json
{
  "message": "success"
}

GET /api/auth/visited

説明:これまでサーバーを利用したことのある Phira ユーザー一覧を取得

レスポンスデータ形式

json
[
  {
    "phira_id": /*整数、ユーザーの Phira ID*/
  },
  /*各項目は上記形式に準拠したオブジェクト*/
]

GET /api/auth/visited/count

説明:これまでサーバーを利用したことのある Phira ユーザー数を取得

レスポンスデータ形式

json
/*整数、ユーザー数を表す*/

ルーム管理 API

GET /api/rooms/info

説明:ルーム一覧を取得

レスポンスデータ形式

json
[
  {
    "name": /*文字列、ルーム名*/,
    "data": { // ルームデータ
      "host": /*整数、ルームホストの Phira ID*/,
      "users": /*リスト、ルーム内全ユーザーの Phira ID*/,
      "lock": /*ブール値、ルームがロックされているか*/,
      "cycle": /*ブール値、ルームがサイクルモードか*/,
      "chart": /*整数または null、ルームで現在選択中の譜面 ID*/,
      "state": /*文字列、SELECTING_CHART または WAITING_FOR_READY または PLAYING*/,
      "playing_users": /*リスト、現在プレイ中のユーザー ID*/,
      "rounds": [ // ルームで行われた全ラウンドの情報
        {
          "chart": /*整数、該当ラウンドの譜面 ID*/,
          "records": [ // 該当ラウンドのプレイヤー成績情報
            {
              "id": /*整数、レコード ID*/,
              "player": /*整数、プレイヤー ID*/,
              "score": /*整数、スコア*/,
              "perfect": /*整数、Perfect 数*/,
              "good": /*整数、Good 数*/,
              "bad": /*整数、Bad 数*/,
              "miss": /*整数、Miss 数*/,
              "max_combo": /*整数、最大コンボ数*/,
              "accuracy": /*浮動小数点数、精度*/,
              "full_combo": /*ブール値、フルコンボかどうか*/,
              "std": /*浮動小数点数、無瑕度*/,
              "std_score": /*浮動小数点数、無瑕度スコア*/
            },
            /*各項目は上記形式に準拠したオブジェクト*/
          ]
        },
        /*各項目は上記形式に準拠したオブジェクト*/
      ],
    }
  },
  /*各項目は上記形式に準拠したオブジェクト*/
]

GET /api/rooms/info/<string:name>

説明:ルーム名が name のルーム情報を取得

レスポンスデータ形式/api/rooms/info の各項目と同じ形式のオブジェクト


GET /api/rooms/user/<int:user_id>

説明:ユーザー ID が user_id のユーザーが所属するルーム情報を取得

レスポンスデータ形式/api/rooms/info/<string:name> のレスポンス形式に準拠したオブジェクト


GET /api/rooms/listen

説明:ルーム情報の更新を監視

レスポンスデータ形式:SSE イベントストリーム。各イベントの形式は以下の通り:

json
event: /*文字列、イベントタイプ*/
data: /*文字列、JSON オブジェクトとしてパース可能*/

特別な説明:このインターフェースは Server-Sent Events(SSE)プロトコルを使用します。クライアントは SSE をサポートしている必要があります。イベントタイプは以下の通り:

イベントタイプデータ形式説明
create_room{"room": /*文字列、ルーム名*/, "data": /*ルームデータ、形式は上記参照*/}新規ルーム
update_room{"room": /*文字列、ルーム名*/, "data": /*部分的なルームデータ*/}ルームデータ更新
join_room{"room": /*文字列、ルーム名*/, "user": /*整数、ユーザーの Phira ID*/}ユーザーがルームに参加
leave_room{"room": /*文字列、ルーム名*/, "user": /*整数、ユーザーの Phira ID*/}ユーザーがルームから退出
player_score{"room": /*文字列、ルーム名*/, "record": /*レコードデータ、形式は上記参照*/}プレイヤーがゲームを完了
start_round{"room": /*文字列、ルーム名*/}ルームが新ラウンドを開始

Last modified byFireflyF09on2026-06-26 15:41

Built with VitePress