# ロゲイニングシステム 外部API仕様書 ## 概要 本仕様書は、スマホアプリなどの外部システムからロゲイニングシステムへアクセスするためのAPI仕様を定義しています。 ## 基本情報 - **ベースURL**: `https://yourdomain.com/api/` - **認証方式**: Knox Token認証 - **データ形式**: JSON - **文字エンコーディング**: UTF-8 ## 重要な注意事項 APIへのアクセスには以下の点にご注意ください: ### URL構成 - **管理画面・認証系**: `/api/` プレフィックスが必要 - **ロゲイニング競技系**: `/api/` プレフィックスが必要 - **例**: `POST /api/start_from_rogapp`, `GET /api/getCheckinList` ### 未実装API 以下のAPIは仕様書に記載されていますが、現在未実装です: - `/api/get_checkpoints` - チェックポイント一覧取得 - `/api/current_ranking` - 現在ランキング - `/api/get_teams` - チーム一覧取得 ### 一時的に無効化されているAPI - `/api/getRoute` - ルート情報取得(データベース構造変更により一時的に無効) ## 認証について APIへのアクセスには認証トークンが必要です。ログイン後に取得したトークンをHTTPヘッダーに含めてリクエストしてください。 ```http Authorization: Token Content-Type: application/json ``` --- ## 1. ユーザー登録関連API ### 1.1 仮ユーザー登録 新規ユーザーの仮登録を行います。 **エンドポイント**: `POST /register/` **リクエストパラメータ**: ```json { "email": "user@example.com", "password": "password123", "firstname": "太郎", "lastname": "田中", "date_of_birth": "1990-01-01", "female": false, "is_rogaining": true } ``` **レスポンス(成功時)**: ```json { "message": "Verification email sent" } ``` **レスポンス(エラー時)**: ```json { "email": ["この email は既に存在します。"], "password": ["この項目は必須です。"] } ``` ### 1.2 メール認証 仮登録後のメール認証を行います。 **エンドポイント**: `GET /verify-email//` **レスポンス(成功時)**: ```json { "message": "ユーザー登録が完了しました。", "user": { "id": 1, "email": "user@example.com", "firstname": "太郎", "lastname": "田中" }, "token": "abcd1234efgh5678ijkl9012mnop3456" } ``` ### 1.3 ログイン ユーザーの認証を行い、アクセストークンを取得します。 **エンドポイント**: `POST /login/` **リクエストパラメータ**: ```json { "identifier": "user@example.com", "password": "password123" } ``` **レスポンス(成功時)**: ```json { "user": { "id": 1, "email": "user@example.com", "firstname": "太郎", "lastname": "田中", "female": false, "date_of_birth": "1990-01-01" }, "token": "abcd1234efgh5678ijkl9012mnop3456" } ``` ### 1.4 ユーザー情報取得 現在ログイン中のユーザー情報を取得します。 **エンドポイント**: `GET /user/` **レスポンス(成功時)**: ```json { "id": 1, "email": "user@example.com", "firstname": "太郎", "lastname": "田中", "female": false, "date_of_birth": "1990-01-01" } ``` --- ## 2. チーム登録とメンバー管理API ### 2.1 チーム作成 新しいチームを作成します。 **エンドポイント**: `POST /teams/` **リクエストパラメータ**: ```json { "team_name": "チーム名", "category": 1 } ``` **レスポンス(成功時)**: ```json { "id": 1, "team_name": "チーム名", "owner": 1, "category": { "id": 1, "category_name": "一般男子", "duration": 180, "num_of_member": 4 } } ``` ### 2.2 チーム一覧取得 ログイン中のユーザーが所有するチームの一覧を取得します。 **エンドポイント**: `GET /teams/` **レスポンス(成功時)**: ```json [ { "id": 1, "team_name": "チーム名", "owner": 1, "category": { "id": 1, "category_name": "一般男子" } } ] ``` ### 2.3 メンバー追加 チームにメンバーを追加します。 **エンドポイント**: `POST /teams/{team_id}/members/` **リクエストパラメータ**: ```json { "email": "member@example.com", "firstname": "花子", "lastname": "佐藤", "date_of_birth": "1992-03-15", "female": true } ``` **レスポンス(成功時)**: ```json { "message": "Invitation email sent to the user." } ``` ### 2.4 チームメンバー一覧取得 チームのメンバー一覧を取得します。 **エンドポイント**: `GET /teams/{team_id}/members-with-user/` **レスポンス(成功時)**: ```json [ { "id": 1, "user": { "id": 1, "email": "user@example.com", "firstname": "太郎", "lastname": "田中", "female": false } }, { "id": 2, "user": { "id": 2, "email": "member@example.com", "firstname": "花子", "lastname": "佐藤", "female": true } } ] ``` --- ## 3. イベントエントリーAPI ### 3.1 カテゴリ一覧取得 エントリー可能なカテゴリの一覧を取得します。 **エンドポイント**: `GET /categories/` **レスポンス(成功時)**: ```json [ { "id": 1, "category_name": "一般男子", "duration": 180, "num_of_member": 4, "family": false, "female": false }, { "id": 2, "category_name": "ファミリー", "duration": 120, "num_of_member": 5, "family": true, "female": false } ] ``` ### 3.2 イベント一覧取得 参加可能なイベントの一覧を取得します。 **エンドポイント**: `GET /newevent2-list/` **レスポンス(成功時)**: ```json [ { "id": 1, "event_name": "岐阜ロゲイニング2025", "start_datetime": "2025-09-15T10:00:00Z", "end_datetime": "2025-09-15T16:00:00Z", "deadlineDateTime": "2025-09-10T23:59:59Z", "public": true, "hour_3": true, "hour_5": true } ] ``` ### 3.3 イベントエントリー チームをイベントにエントリーします。 **エンドポイント**: `POST /entry/` **リクエストパラメータ**: ```json { "team": 1, "event": 1, "category": 1, "date": "2025-09-15T10:00:00Z" } ``` **レスポンス(成功時)**: ```json { "id": 1, "team": 1, "event": 1, "category": 1, "zekken_number": 101, "date": "2025-09-15T10:00:00Z", "hasParticipated": false, "hasGoaled": false } ``` --- ## 4. ロゲイニング参加関連API ### 4.1 スタート処理 ロゲイニングのスタート処理を行います。 **エンドポイント**: `POST /api/start_from_rogapp` **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025", "team_name": "チーム名" } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "スタート処理が完了しました", "team_name": "チーム名", "event_code": "岐阜ロゲイニング2025", "start_time": "2025-09-15 10:00:00" } ``` **レスポンス(エラー時)**: ```json { "status": "ERROR", "message": "指定されたチームが見つかりません" } ``` --- ## 5. チェックイン・写真撮影API ### 5.1 チェックイン登録 チェックポイント通過時のチェックイン処理を行います。 **エンドポイント**: `POST /api/checkin_from_rogapp` **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025", "team_name": "チーム名", "cp_number": 1, "image": "https://example.com/photos/checkpoint1.jpg" } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "チェックポイントが正常に登録されました", "team_name": "チーム名", "cp_number": 1, "checkpoint_id": 123, "checkin_time": "2025-09-15 11:30:00", "point_value": 10 } ``` **レスポンス(重複エラー時)**: ```json { "status": "WARNING", "message": "このチェックポイントは既に登録されています", "checkpoint_id": 123, "checkin_time": "2025-09-15 11:30:00" } ``` ### 5.2 チェックイン削除 誤って登録したチェックインを削除します。 **エンドポイント**: `POST /api/remove_checkin_from_rogapp` **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025", "team_name": "チーム名", "cp_number": 1 } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "チェックイン記録が削除されました", "cp_number": 1 } ``` **レスポンス(エラー時)**: ```json { "status": "ERROR", "message": "指定されたチェックポイント記録が見つかりません" } ``` --- ## 6. 買い物ポイント・QRコード登録API ### 6.1 買い物ポイント写真登録 買い物ポイントでのレシート写真を登録します。 **エンドポイント**: `POST /api/checkin_from_rogapp` **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025", "team_name": "チーム名", "cp_number": 37, "image": "https://example.com/photos/receipt_37.jpg", "buy_flag": true } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "買い物ポイントが正常に登録されました", "team_name": "チーム名", "cp_number": 37, "checkpoint_id": 124, "checkin_time": "2025-09-15 12:15:00", "point_value": 15 } ``` ### 6.2 QRコード登録 QRコードを使用したチェックイン登録を行います。 **エンドポイント**: `POST /api/input_cp` **リクエストパラメータ**: ```json { "zekken_number": "101", "event_code": "岐阜ロゲイニング2025", "cp_number": 10, "qr_code": "QR12345ABC", "latitude": 35.4091, "longitude": 136.7581 } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "QRコードチェックインが完了しました", "cp_number": 10, "point_value": 10 } ``` --- ## 7. ゴール・時計撮影API ### 7.1 ゴール処理 ゴール時の処理を行い、通過証明書を生成します。 **エンドポイント**: `POST /api/goal_from_rogapp` **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025", "team_name": "チーム名", "image": "https://example.com/photos/goal_clock.jpg", "goal_time": "2025-09-15 13:45:00" } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "ゴール処理が正常に完了しました", "team_name": "チーム名", "goal_time": "2025-09-15 13:45:00", "score": 150, "scoreboard_url": "https://example.com/scoreboards/scoreboard_101.pdf", "certificate_ready": true } ``` ### 7.2 スコアボード取得 チームのスコアボード(通過証明書)を取得します。 **エンドポイント**: `GET /getScoreboard` **リクエストパラメータ**: ``` zekken_number=101&event_code=岐阜ロゲイニング2025 ``` **レスポンス(成功時)**: - Excel形式のスコアボードファイルをダウンロード ### 7.3 スコアボードPDF取得 PDF形式のスコアボードを取得します。 **エンドポイント**: `GET /download_scoreboard` **リクエストパラメータ**: ``` zekken_number=101&event_code=岐阜ロゲイニング2025 ``` **レスポンス(成功時)**: - PDF形式のスコアボードファイルをダウンロード --- ## 8. 証明書・印刷確認API ### 8.1 印刷状況確認 通過証明書の印刷状況を確認します。 **エンドポイント**: `GET /users/{user_id}/last-goal/` **レスポンス(成功時)**: ```json { "team_name": "チーム名", "goal_time": "2025-09-15T13:45:00Z", "score": 150, "certificate_printed": true, "print_time": "2025-09-15T13:47:00Z" } ``` ### 8.2 再印刷要求 通過証明書の再印刷を要求します。 **エンドポイント**: `POST /reprint` **リクエストパラメータ**: ```json { "zekken_number": "101", "event_code": "岐阜ロゲイニング2025" } ``` **レスポンス(成功時)**: ```json { "status": "OK", "message": "再印刷処理を開始しました", "estimated_print_time": "2025-09-15T14:00:00Z" } ``` --- ## 9. ユーティリティAPI ### 9.1 イベントコード確認 イベントコードの有効性を確認します。 **エンドポイント**: `POST /api/check_event_code` **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025" } ``` **レスポンス(成功時)**: ```json { "status": "OK", "event_exists": true, "event_name": "岐阜ロゲイニング2025", "start_time": "2025-09-15T10:00:00Z", "end_time": "2025-09-15T16:00:00Z" } ``` ### 9.2 チェックインリスト取得 チームのチェックイン履歴を取得します。 **エンドポイント**: `GET /getCheckinList` **リクエストパラメータ**: ``` zekken=<ゼッケン番号>&event=<イベントコード> ``` **レスポンス(成功時)**: ```json { "status": "OK", "team_info": { "zekken_number": "001", "team_name": "チーム名", "event_code": "岐阜ロゲイニング2025" }, "checkpoints": [ { "id": 123, "cp_number": "1", "checkin_time": "2025-09-15 11:30:00", "image_url": "https://example.com/photos/checkpoint1.jpg", "is_service_checked": false, "cp_point": 10, "cp_name": "市役所" } ], "start_info": { "start_time": "2025-09-15 10:00:00" }, "goal_info": { "goal_time": "2025-09-15 13:45:00", "score": 150, "scoreboard_url": "https://example.com/scoreboards/team_001.pdf" } } ``` **レスポンス(エラー時)**: ```json { "status": "ERROR", "message": "指定されたゼッケン番号のチームが見つかりません" } ``` ### 9.3 通過履歴承認 ユーザーが自分のチームの通過履歴を確認し、承認確定する処理を行います。 **エンドポイント**: `POST /api/approve_checkin_history` **認証**: 必須(Token認証) **リクエストパラメータ**: ```json { "event_code": "岐阜ロゲイニング2025", "zekken_number": "001", "checkin_ids": [123, 124, 125], "approval_comment": "通過履歴を確認し、すべて正確です" } ``` **パラメータ説明**: - `event_code`: イベントコード(必須) - `zekken_number`: ゼッケン番号(必須) - `checkin_ids`: 承認するチェックインIDのリスト(必須) - `approval_comment`: 承認コメント(任意) **レスポンス(成功時)**: ```json { "status": "OK", "message": "通過履歴の承認が完了しました", "approved_count": 3, "approved_checkins": [ { "checkin_id": 123, "cp_number": "1", "approved_at": "2025-09-02 15:30:00" }, { "checkin_id": 124, "cp_number": "5", "approved_at": "2025-09-02 15:30:00" }, { "checkin_id": 125, "cp_number": "8", "approved_at": "2025-09-02 15:30:00" } ], "team_info": { "team_name": "チーム名", "zekken_number": "001", "event_code": "岐阜ロゲイニング2025" } } ``` **レスポンス(エラー時)**: ```json { "status": "ERROR", "message": "指定されたチェックイン記録が見つかりません", "error_details": { "invalid_checkin_ids": [126, 127], "valid_checkin_ids": [123, 124, 125] } } ``` **レスポンス(権限エラー時)**: ```json { "status": "ERROR", "message": "このチームの通過履歴を承認する権限がありません" } ``` ### 9.4 写真一括アップロード・通過履歴校正 スマホアルバムから複数の写真を一括アップロードし、EXIF情報から自動的に通過履歴を生成・校正する処理を行います。 **エンドポイント**: `POST /api/bulk_upload_checkin_photos/` **認証**: 必須(Token認証) **Content-Type**: `multipart/form-data` **リクエストパラメータ**: ``` event_code: 岐阜ロゲイニング2025 (必須) zekken_number: 001 (必須) photos: [file1.jpg, file2.jpg, file3.jpg, ...] (必須・最大50ファイル) auto_process: true (任意・デフォルト: true) ``` **パラメータ説明**: - `event_code`: イベントコード(必須) - `zekken_number`: ゼッケン番号(必須) - `photos`: アップロードする写真ファイルのリスト(必須・最大50ファイル) - `auto_process`: EXIF情報から自動処理を行うかどうか(任意・デフォルト: true) **対応ファイル形式**: JPG, JPEG, PNG, HEIC **ファイルサイズ制限**: 1ファイルあたり最大10MB **レスポンス(成功時)**: ```json { "status": "OK", "message": "写真の一括アップロードが完了しました", "upload_summary": { "total_files": 15, "successful_uploads": 12, "failed_uploads": 3, "upload_time": "2025-09-02 16:30:00" }, "team_info": { "team_name": "チーム名", "zekken_number": "001", "event_code": "岐阜ロゲイニング2025" }, "processed_files": [ { "filename": "photo001.jpg", "file_index": 1, "file_size": 2048576, "status": "uploaded", "saved_path": "bulk_checkin_photos/岐阜ロゲイニング2025/001/20250902_163000_001_photo001.jpg", "file_url": "/media/bulk_checkin_photos/岐阜ロゲイニング2025/001/20250902_163000_001_photo001.jpg", "upload_time": "2025-09-02 16:30:00", "auto_process_status": "pending", "auto_process_message": "EXIF解析機能は今後実装予定です" }, { "filename": "photo002.jpg", "file_index": 2, "status": "failed", "error": "サポートされていないファイル形式: .bmp" } ], "auto_process_enabled": true, "next_steps": [ "アップロードされた写真のEXIF情報解析", "GPS座標からチェックポイント自動判定", "通過履歴の自動生成と校正", "ユーザーによる確認と承認" ] } ``` **レスポンス(エラー時)**: ```json { "status": "ERROR", "message": "一度にアップロードできる写真は最大50枚です" } ``` **レスポンス(権限エラー時)**: ```json { "status": "ERROR", "message": "このチームの写真をアップロードする権限がありません" } ``` ### 9.5 一括アップロード状況取得 写真一括アップロードの処理状況を取得します。 **エンドポイント**: `GET /api/get_bulk_upload_status/` **認証**: 必須(Token認証) **リクエストパラメータ**: ``` event_code=岐阜ロゲイニング2025&zekken_number=001 ``` **レスポンス(成功時)**: ```json { "status": "OK", "team_info": { "team_name": "チーム名", "zekken_number": "001", "event_code": "岐阜ロゲイニング2025" }, "upload_status": { "total_uploaded_files": 15, "processed_files": 12, "pending_files": 3, "auto_checkins_generated": 8, "manual_review_required": 4 }, "implementation_status": "基本機能実装完了、詳細処理は今後実装予定" } ``` **処理フロー**: 1. **写真アップロード**: 複数の写真ファイルを安全にサーバーに保存 2. **EXIF情報解析**: GPS座標、撮影時刻などのメタデータを抽出(今後実装) 3. **自動チェックイン判定**: GPS座標から最寄りのチェックポイントを特定(今後実装) 4. **通過履歴生成**: 撮影時刻順にソートして通過履歴を自動生成(今後実装) 5. **ユーザー確認**: 生成された履歴をユーザーが確認・修正(今後実装) 6. **履歴確定**: 承認されたチェックイン記録をデータベースに保存(今後実装) **今後の実装予定機能**: - EXIF情報からのGPS座標・撮影時刻自動抽出 - チェックポイント自動判定アルゴリズム - 時系列自動ソート機能 - 重複チェック・エラー検出機能 - ユーザーによる手動校正インターフェース --- ## 10. エントリー管理API ### 10.1 現在のエントリー情報取得 ユーザーの最新のエントリー情報を取得します。アプリとサーバー間のデータ同期に使用されます。 **エンドポイント**: `GET /user/current-entry-info/` **認証**: 必須(Token認証) **レスポンス(成功時)**: ```json { "id": 123, "team": { "id": 45, "team_name": "サンプルチーム", "owner": 67 }, "event": { "id": 12, "event_name": "岐阜ロゲイニング2025", "start_datetime": "2025-09-15T10:00:00Z", "end_datetime": "2025-09-15T16:00:00Z" }, "category": { "id": 1, "category_name": "一般男子", "duration": 180, "num_of_member": 4 }, "zekken_number": 101, "date": "2025-09-15T10:00:00Z", "hasParticipated": false, "hasGoaled": false } ``` **レスポンス(エントリーなし)**: ```json { "message": "エントリー情報が見つかりません" } ``` **レスポンス(認証エラー)**: ```json { "detail": "認証情報が提供されていません。" } ``` ### 10.2 エントリーステータス更新 エントリーの参加状況とゴール状況を更新します。後方互換性のため、新旧フィールド名の両方をサポートしています。 **エンドポイント**: `PUT /entry/{entry_id}/update-status/` **認証**: 必須(Token認証) **リクエストパラメータ(新フィールド名)**: ```json { "hasParticipated": true, "hasGoaled": false } ``` **リクエストパラメータ(旧フィールド名・後方互換性)**: ```json { "has_participated": true, "has_goaled": false } ``` **レスポンス(成功時)**: ```json { "id": 123, "team": { "id": 45, "team_name": "サンプルチーム" }, "event": { "id": 12, "event_name": "岐阜ロゲイニング2025" }, "zekken_number": 101, "hasParticipated": true, "hasGoaled": false, "updated_at": "2025-09-15T11:30:00Z" } ``` **レスポンス(エラー時)**: ```json { "detail": "エントリーが見つかりません。" } ``` **使用例**: **現在のエントリー情報取得**: ```bash curl -X GET "/user/current-entry-info/" \ -H "Authorization: Token " \ -H "Content-Type: application/json" ``` **ステータス更新(参加開始)**: ```bash curl -X PUT "/entry/123/update-status/" \ -H "Authorization: Token " \ -H "Content-Type: application/json" \ -d '{"hasParticipated": true, "hasGoaled": false}' ``` **ステータス更新(ゴール完了)**: ```bash curl -X PUT "/entry/123/update-status/" \ -H "Authorization: Token " \ -H "Content-Type: application/json" \ -d '{"hasParticipated": true, "hasGoaled": true}' ``` --- ## エラーコード一覧 | ステータスコード | 説明 | |---|---| | 200 | 正常終了 | | 201 | 作成成功 | | 400 | リクエスト不正 | | 401 | 認証エラー | | 403 | 権限不足 | | 404 | リソースが見つからない | | 409 | 重複エラー | | 500 | サーバーエラー | | 502 | Bad Gateway(プロキシサーバーエラー) | ## 共通エラーレスポンス ```json { "status": "ERROR", "message": "エラーメッセージ", "details": "詳細な説明(省略可能)" } ``` --- ## 使用例(フロー) ### 完全なロゲイニング参加フロー 1. **ユーザー登録** ```bash curl -X POST "/register/" -d '{"email":"user@example.com","password":"pass123","firstname":"太郎","lastname":"田中"}' ``` 2. **メール認証** ```bash curl "/verify-email/abc123def456/" ``` 3. **ログイン** ```bash curl -X POST "/login/" -d '{"identifier":"user@example.com","password":"pass123"}' ``` 4. **チーム作成** ```bash curl -X POST "/teams/" -H "Authorization: Token " -d '{"team_name":"サンプルチーム","category":1}' ``` 5. **メンバー追加** ```bash curl -X POST "/teams/1/members/" -H "Authorization: Token " -d '{"email":"member@example.com","firstname":"花子","lastname":"佐藤"}' ``` 6. **イベントエントリー** ```bash curl -X POST "/entry/" -H "Authorization: Token " -d '{"team":1,"event":1,"category":1}' ``` 7. **エントリー情報確認** ```bash curl -X GET "/user/current-entry-info/" -H "Authorization: Token " ``` 8. **スタート前ステータス更新** ```bash curl -X PUT "/entry/123/update-status/" -H "Authorization: Token " -d '{"hasParticipated": true, "hasGoaled": false}' ``` 9. **スタート** ```bash curl -X POST "/api/start_from_rogapp" -d '{"event_code":"岐阜ロゲイニング2025","team_name":"サンプルチーム"}' ``` 10. **チェックイン** ```bash curl -X POST "/api/checkin_from_rogapp" -d '{"event_code":"岐阜ロゲイニング2025","team_name":"サンプルチーム","cp_number":1,"image":"https://example.com/photo1.jpg"}' ``` 11. **ゴール** ```bash curl -X POST "/api/goal_from_rogapp" -d '{"event_code":"岐阜ロゲイニング2025","team_name":"サンプルチーム","image":"https://example.com/goal.jpg"}' ``` 12. **通過履歴承認** ```bash curl -X POST "/api/approve_checkin_history" -H "Authorization: Token " -d '{"event_code":"岐阜ロゲイニング2025","zekken_number":"001","checkin_ids":[123,124,125],"approval_comment":"通過履歴確認完了"}' ``` 13. **写真一括アップロード(アルバムから通過履歴校正)** ```bash curl -X POST "/api/bulk_upload_checkin_photos/" -H "Authorization: Token " -F "event_code=岐阜ロゲイニング2025" -F "zekken_number=001" -F "auto_process=true" -F "photos=@photo1.jpg" -F "photos=@photo2.jpg" -F "photos=@photo3.jpg" ``` 14. **一括アップロード状況確認** ```bash curl -X GET "/api/get_bulk_upload_status/?event_code=岐阜ロゲイニング2025&zekken_number=001" -H "Authorization: Token " ``` 15. **ゴール後ステータス更新** ```bash curl -X PUT "/entry/123/update-status/" -H "Authorization: Token " -d '{"hasParticipated": true, "hasGoaled": true}' ``` 16. **証明書取得** ```bash curl "/api/download_scoreboard?zekken_number=101&event_code=岐阜ロゲイニング2025" ``` --- ## 更新履歴 ### 2025年9月2日 - APIテスト結果による仕様書修正 #### 修正内容 1. **エンドポイントURL修正** - 全ての競技系APIに `/api/` プレフィックスを追加 - 実際のエンドポイント名に合わせて修正 2. **未実装API情報の追加** - `/api/get_checkpoints` - チェックポイント一覧取得(未実装) - `/api/current_ranking` - 現在ランキング(未実装) - `/api/get_teams` - チーム一覧取得(未実装) 3. **一時的に無効化されているAPI** - `/api/getRoute` - データベース構造変更により一時的に無効 4. **レスポンス形式の修正** - `getCheckinList` APIのレスポンス構造を実際の仕様に合わせて修正 - エラーレスポンスの実際の形式を追記 5. **動作確認済みAPI** - `start_from_rogapp` - スタート処理 - `checkin_from_rogapp` - チェックイン処理 - `goal_from_rogapp` - ゴール処理 - `input_cp` - QRコードチェックイン - `remove_checkin_from_rogapp` - チェックイン削除 - `get_waypoint_datas_from_rogapp` - ウェイポイントデータ収集 - `getCheckinList` - チェックイン履歴取得 #### 注意事項の追加 - URL構成についての説明を追加 - 未実装APIの明記 - 一時的に無効化されているAPIの説明 --- ## 自動証明書生成について ゴール処理(`goal_from_rogapp`)が完了すると、システムは自動的に以下を実行します: 1. **スコア計算**: チェックポイントの獲得ポイントとタイムペナルティを計算 2. **証明書生成**: Excel/PDF形式のスコアボード(通過証明書)を生成 3. **自動印刷**: 設定されている場合、自動印刷システムが証明書を印刷 4. **クラウド保存**: 生成された証明書をAWS S3などのクラウドストレージに保存 5. **印刷確認**: 印刷完了の確認とログ記録 この一連の処理により、ゴール後すぐに通過証明書が生成・印刷され、参加者に提供されます。 --- ## 注意事項 1. **認証トークンの管理**: セキュリティのため、適切にトークンを管理してください 2. **レート制限**: 過度なリクエストを避けるため、適切な間隔でAPIを呼び出してください 3. **画像アップロード**: 画像ファイルは事前に適切なストレージにアップロードし、URLを指定してください 4. **時刻形式**: すべての時刻は ISO 8601 形式(YYYY-MM-DDTHH:MM:SSZ)で指定してください 5. **エラーハンドリング**: APIからのエラーレスポンスを適切に処理してください 6. **エントリー情報同期**: アプリ起動時は `/user/current-entry-info/` でエントリー情報を同期してください 7. **ステータス更新**: エントリーステータス更新API は後方互換性のため新旧フィールド名をサポートしています 8. **502エラー対策**: 一時的な502 Bad Gatewayエラーが発生した場合は、数秒待ってから再試行してください(特に大量データ取得時) --- ## データベーステーブル使用状況 ### 各API機能でのテーブル操作詳細 #### 1. 認証系API **`/check_event_code`** - **参照**: `rog_newevent2` (イベント存在確認) - **参照**: `rog_entry` (チーム認証・パスワード確認) #### 2. チェックイン系API **`/input_cp` (チェックイン登録)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_gpslog` (重複チェックイン確認) - **作成**: `rog_gpslog` (新規チェックイン記録) - **参照**: `rog_location2025` (チェックポイント得点情報) **`/goal_from_rogapp` (ゴール登録)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_gpslog` (スコア計算用チェックイン履歴) - **参照**: `rog_location2025` (チェックポイント得点情報) - **更新**: `rog_entry` (ゴール時刻・スコア更新) #### 3. チーム情報系API **`/get_teams` (チーム一覧)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム基本情報) - **参照**: `rog_gpslog` (チェックイン数集計) - **参照**: `rog_customuser` (オーナー情報) #### 4. ランキング系API **`/current_ranking` (現在ランキング)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報・スコア・ゴール情報) - **参照**: `rog_gpslog` (チェックポイント通過数) - **参照**: `rog_customuser` (オーナー情報) #### 5. 位置情報系API **`/get_waypoint_datas_from_rogapp` (ウェイポイント投稿)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_waypoint` (重複チェック) - **作成**: `rog_waypoint` (GPS軌跡データ保存) **`/get_route` (ルート情報取得)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_waypoint` (GPS軌跡履歴) - **参照**: `rog_gpslog` (チェックイン履歴) - **参照**: `rog_location2025` (チェックポイント座標情報) #### 6. チェックポイント情報系API **`/get_checkpoints` (チェックポイント一覧)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_location2025` (チェックポイント詳細情報) #### 7. 編集系API **`/remove_checkin_from_rogapp` (チェックイン削除)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_gpslog` (削除対象チェックイン検索) - **削除**: `rog_gpslog` (チェックイン記録削除) **`/get_checkin_list` (チェックイン履歴)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_gpslog` (チェックイン履歴取得) - **参照**: `rog_location2025` (チェックポイント詳細情報) #### 8. 写真・メディア系API **`/get_photo_list` (写真一覧)** - **参照**: `rog_newevent2` (イベント情報取得) - **参照**: `rog_entry` (チーム情報取得) - **参照**: `rog_gpslog` (チェックイン画像URL) #### 9. エントリー管理系API **`/user/current-entry-info/` (現在のエントリー情報取得)** - **参照**: `rog_entry` (ユーザーの最新エントリー情報) - **参照**: `rog_team` (チーム基本情報) - **参照**: `rog_newevent2` (イベント情報) - **参照**: `rog_newcategory` (カテゴリ詳細情報) - **参照**: `knox_authtoken` (ユーザー認証) **`/entry/{entry_id}/update-status/` (エントリーステータス更新)** - **参照**: `rog_entry` (対象エントリー検索) - **更新**: `rog_entry` (hasParticipated/hasGoaled更新) - **参照**: `knox_authtoken` (ユーザー認証・権限確認) --- ## テーブル別API使用一覧表 ### 🎯 コアテーブル(全APIで使用) | テーブル名 | 参照API | 作成API | 更新API | 削除API | 役割 | |-----------|---------|---------|---------|---------|------| | `rog_newevent2` | 全API | - | - | - | イベント基本情報・認証基盤 | | `rog_entry` | 全API | - | goal_from_rogapp | - | チーム基本情報・スコア管理 | ### 📍 GPS・位置情報系テーブル | テーブル名 | 参照API | 作成API | 更新API | 削除API | 役割 | |-----------|---------|---------|---------|---------|------| | `rog_gpslog` | input_cp, goal_from_rogapp, get_teams, current_ranking, get_checkin_list, get_photo_list | input_cp | - | remove_checkin_from_rogapp | チェックイン記録管理 | | `rog_location2025` | input_cp, goal_from_rogapp, get_checkpoints, get_route, get_checkin_list | - | - | - | チェックポイント座標・得点情報 | | `rog_waypoint` | get_waypoint_datas_from_rogapp, get_route | get_waypoint_datas_from_rogapp | - | - | GPS軌跡データ | ### 👥 ユーザー・認証系テーブル | テーブル名 | 参照API | 作成API | 更新API | 削除API | 役割 | |-----------|---------|---------|---------|---------|------| | `rog_customuser` | get_teams, current_ranking | - | - | - | ユーザー基本情報・オーナー情報 | | `knox_authtoken` | 認証が必要な全API | ログイン時 | - | ログアウト時 | API認証トークン管理 | ### 📊 集計・分析系テーブル(読み取り専用) | テーブル名 | 参照API | 役割 | |-----------|---------|------| | `v_category_rankings` | current_ranking | カテゴリ別ランキング集計ビュー | | `v_checkin_summary` | get_checkin_list | チェックイン集計ビュー | | `mv_entry_details` | get_teams | エントリー詳細マテリアライズドビュー | ### 🖼️ メディア・画像系テーブル | テーブル名 | 参照API | 作成API | 役割 | |-----------|---------|---------|------| | `rog_checkinimages` | get_photo_list | input_cp | チェックイン時の写真 | | `rog_goalimages` | get_photo_list | goal_from_rogapp | ゴール時の写真 | --- ## 重複・非推奨テーブルについて ### 🔄 移行中の重複テーブル #### GPS情報関連 - **`gps_information`** (移行元・13,550件): MobServerからの旧GPS記録 - **`rog_gpslog`** (移行先・0件): Django管理の新GPS記録 - **状況**: データ移行が未完了、現在は`gps_information`を直接参照 #### イベント管理関連 - **`rog_newevent`** (旧): 初期バージョンのイベントモデル - **`rog_newevent2`** (現行): 拡張されたイベントモデル(API推奨) - **推奨**: 新規開発では`rog_newevent2`を使用 #### カテゴリ管理関連 - **`rog_category`** (旧): 旧カテゴリシステム - **`rog_newcategory`** (現行): 新カテゴリシステム - **推奨**: 新規開発では`rog_newcategory`を使用 ### 🗑️ 将来的に不要になるテーブル #### 一時・作業用テーブル - **`tmp_checkin`**: チェックイン一時テーブル(作業完了後削除予定) - **`tmp_checkpont_summary`**: チェックポイント集計作業用 - **`tmp_goalimage`**: ゴール画像一時テーブル - **`tmp_point`**: ポイント一時テーブル - **`tmp_team_table`**: チームテーブル作業用 - **`temp_gifuroge_team`**: ぎふロゲチーム一時データ #### バックアップテーブル - **`gps_checkins_backup`**: GPSチェックインバックアップ - **`django_migrations_backup`**: マイグレーションバックアップ #### 開発・テスト用テーブル - **`rog_testmodel`**: 開発テスト用(本番環境では不要) ### 📋 無効化されているテーブル #### 将来機能(当面無効) - **`rog_chatlog`**: LINE Bot機能(`managed = False`) - **`rog_chatstatus`**: チャット状態管理(`managed = False`) - **`rog_agentflag`**: エージェント機能(`managed = False`) - **`rog_agentlogin`**: エージェントログイン(`managed = False`) これらのテーブルは将来的な機能拡張のために定義されていますが、現在は無効化されています。 --- ## テーブル使用頻度とパフォーマンス考慮事項 ### 🔥 高頻度アクセステーブル 1. **`rog_newevent2`**: 全APIで必須(キャッシュ推奨) 2. **`rog_entry`**: 全APIで必須(インデックス最適化済み) 3. **`rog_gpslog`**: GPS関連APIで重要(空間インデックス推奨) ### ⚡ 最適化されているテーブル - **`rog_location2025`**: PostGIS空間インデックス、CSV一括アップロード機能 - **`rog_gpslog`**: 複合インデックス(zekken_number + event_code) - **`mv_entry_details`**: マテリアライズドビュー(高速集計) ### 📈 将来的なスケーリング考慮 - GPS軌跡データ(`rog_waypoint`)の分割・アーカイブ戦略 - 画像データの外部ストレージ移行 - ランキング計算の非同期処理化 --- ## 🆕 Location2025移行による拡張機能 ### CSVベースチェックポイント管理 2025年8月実装のLocation2025により、従来のlocationテーブルから大幅に機能拡張されました: #### 新機能 - **CSV一括アップロード**: Django管理画面でチェックポイント定義の一括インポート - **CSV一括ダウンロード**: 現在のチェックポイント設定の一括エクスポート - **空間データ統合**: 緯度経度とPointFieldの自動同期 - **イベント連携強化**: rog_newevent2との外部キー制約 #### CSV形式仕様 ```csv cp_number,event_code,cp_name,latitude,longitude,point_value,description,image_path,buy_flag 1,岐阜ロゲイニング2025,市役所,35.4091,136.7581,10,スタート/ゴール地点,,false 2,岐阜ロゲイニング2025,岐阜公園,35.4122,136.7514,15,信長居館跡,,false ``` #### API拡張 - 全チェックポイント関連APIが新テーブル`rog_location2025`を参照 - 管理機能の向上によりリアルタイムでのチェックポイント設定変更が可能 - PostGIS空間検索機能の継続利用 #### 移行状況 - **完了**: モデル定義、管理画面、CSV機能、API更新 - **対象API**: `/get_checkpoints`, `/input_cp`, `/goal_from_rogapp`, `/get_route`, `/get_checkin_list` - **後方互換性**: 既存のlocationテーブルは維持(必要に応じて参照可能) --- 本仕様書に記載されていない詳細については、システム管理者にお問い合わせください。 --- ## 🆕 管理者向けAPI (2025年8月追加) ### 一括写真アップロード機能 #### POST /bulk-upload-photos/ 複数の写真を一括でアップロードし、EXIF情報から自動的にチェックイン処理を行います。 **認証**: 管理者権限必須 **リクエスト**: ```http POST /api/bulk-upload-photos/ Content-Type: multipart/form-data Authorization: Token event_code: 岐阜2412 photos: [file1.jpg, file2.jpg, file3.jpg, ...] ``` **レスポンス(成功時)**: ```json { "success": true, "processed_count": 15, "success_count": 12, "failed_count": 3, "results": [ { "filename": "photo001.jpg", "status": "success", "checkin_id": 1234, "gps": {"lat": 35.4091, "lon": 136.7581}, "timestamp": "2025-08-24T14:30:00Z" }, { "filename": "photo002.jpg", "status": "failed", "error": "GPS情報が見つかりません" } ] } ``` **処理内容**: 1. アップロードされた写真からEXIF情報を抽出 2. GPS座標と撮影時刻を取得 3. 近接するチェックポイントを検索 4. 自動的にチェックイン処理を実行 5. validation_status: 'AUTO_APPROVED'で記録 --- ### 通過審査管理機能 #### POST /confirm-checkin-validation/ チェックインの確定・否認処理を行います。 **認証**: 管理者権限必須 **リクエスト**: ```json { "checkin_id": 1234, "action": "APPROVED", "comment": "写真確認により承認" } ``` **actionの値**: - `APPROVED`: 承認 - `REJECTED`: 却下 **レスポンス(成功時)**: ```json { "success": true, "checkin_id": 1234, "new_status": "APPROVED", "validated_at": "2025-08-24T15:30:00Z", "validated_by": "admin@example.com" } ``` --- ### 全参加者ランキング表示 #### GET /event-participants-ranking/ イベント全参加者の得点と確定状況をクラス別降順で取得します。 **認証**: 管理者権限必須 **パラメータ**: - `event_code`: イベントコード(必須) **リクエスト例**: ```http GET /api/event-participants-ranking/?event_code=岐阜2412 Authorization: Token ``` **レスポンス**: ```json { "event_code": "岐阜2412", "event_name": "岐阜ロゲイニング2024年12月大会", "participants": [ { "zekken_number": "001", "team_name": "チーム岐阜", "class_name": "一般男子", "confirmed_points": 150, "pending_points": 30, "total_checkins": 12, "confirmed_checkins": 10, "members": ["田中太郎", "佐藤次郎"] }, { "zekken_number": "002", "team_name": "スピードランナーズ", "class_name": "一般男子", "confirmed_points": 140, "pending_points": 0, "total_checkins": 9, "confirmed_checkins": 9, "members": ["山田三郎", "鈴木四郎"] } ] } ``` --- ### 参加者詳細審査情報 #### GET /participant-validation-details/ 特定参加者の詳細な審査状況を取得します。 **認証**: 管理者権限必須 **パラメータ**: - `zekken_number`: ゼッケン番号(必須) - `event_code`: イベントコード(必須) **リクエスト例**: ```http GET /api/participant-validation-details/?zekken_number=001&event_code=岐阜2412 Authorization: Token ``` **レスポンス**: ```json { "team_info": { "zekken_number": "001", "team_name": "チーム岐阜", "class_name": "一般男子", "members": ["田中太郎", "佐藤次郎"] }, "checkins": [ { "id": 1234, "cp_number": 5, "location_name": "岐阜公園", "checkin_time": "2025-08-24T14:30:00Z", "validation_status": "APPROVED", "validation_comment": "写真確認により承認", "validated_at": "2025-08-24T15:30:00Z", "validated_by": "admin@example.com", "points": 15, "photo_url": "/media/checkin_photos/photo001.jpg" } ], "summary": { "total_points": 180, "confirmed_points": 150, "pending_points": 30, "rejected_points": 0 } } ``` --- ### イベント参加者一覧 #### GET /event-zekken-list/ 指定イベントの全参加者ゼッケン番号一覧を取得します。 **認証**: 管理者権限必須 **パラメータ**: - `event_code`: イベントコード(必須) **リクエスト例**: ```http GET /api/event-zekken-list/?event_code=岐阜2412 Authorization: Token ``` **レスポンス**: ```json { "event_code": "岐阜2412", "participants": [ { "zekken_number": "ALL", "team_name": "全参加者表示", "is_all_option": true }, { "zekken_number": "001", "team_name": "チーム岐阜", "class_name": "一般男子", "is_all_option": false }, { "zekken_number": "002", "team_name": "スピードランナーズ", "class_name": "一般男子", "is_all_option": false } ] } ``` --- ### 管理者向けAPI利用時の注意事項 1. **認証レベル**: すべての管理者向けAPIは管理者権限(is_superuser=True)が必要 2. **レート制限**: 一括アップロードは1回あたり最大100ファイルまで 3. **ファイルサイズ**: 1ファイルあたり最大10MB 4. **対応形式**: JPEG, PNG (EXIF情報が含まれる写真のみ自動処理対象) 5. **エラーハンドリング**: 部分的な失敗でも成功した分は処理されます 6. **ログ**: すべての管理者操作は詳細ログが記録されます ---