259 lines
7.7 KiB
Markdown
259 lines
7.7 KiB
Markdown
# サーバーAPI変更要求書
|
|
|
|
**文書番号:** API-REQ-20250901
|
|
**作成日:** 2025年9月1日
|
|
**作成者:** アプリ開発チーム
|
|
**対象システム:** 岐阜ロゲイニングアプリ サーバーAPI
|
|
|
|
## 概要
|
|
|
|
岐阜ロゲイニングアプリにおいて、ユーザーのエントリー参加後にアプリ側とサーバー側のデータ同期に問題が発生しています。具体的には、ユーザー情報に含まれる`event_code`とEntryControllerで管理されている実際のエントリー情報が一致しないため、競技開始時にValidationErrorが発生している状況です。
|
|
|
|
## 問題の詳細
|
|
|
|
### 現在の問題
|
|
1. **データ同期の不整合**
|
|
- ユーザー情報: `event_code: "TestEvent"` (Event ID: 140)
|
|
- 実際のエントリー: `event: "揖斐川"` (Event ID: 128, Entry ID: 747)
|
|
|
|
2. **競技開始時のエラー**
|
|
- API: `PATCH /api/entries/747/update-status/`
|
|
- エラー: `ValidationError at /api/entries/747/update-status/`
|
|
- ステータス: HTTP 500
|
|
|
|
3. **ユーザー情報の未更新**
|
|
- エントリー参加後にユーザー情報(`currentUser`)が最新のエントリー情報で更新されない
|
|
|
|
## 要求される変更
|
|
|
|
### 1. 新規API追加
|
|
|
|
#### API 1: ユーザーの最新エントリー情報取得API
|
|
|
|
**エンドポイント:** `GET /api/user/current-entry-info/`
|
|
|
|
**目的:** ユーザーの最新エントリー情報を取得し、アプリ側とサーバー側のデータ同期を確保
|
|
|
|
**認証:** Token認証必須
|
|
|
|
**リクエスト**
|
|
```http
|
|
GET /api/user/current-entry-info/
|
|
Authorization: Token <user_token>
|
|
Content-Type: application/json; charset=UTF-8
|
|
```
|
|
|
|
**成功レスポンス (HTTP 200)**
|
|
```json
|
|
{
|
|
"user": {
|
|
"id": 1765,
|
|
"email": "akira.miyata@gifuai.net",
|
|
"firstname": "明",
|
|
"lastname": "宮田",
|
|
"is_staff": true,
|
|
"event_code": "揖斐川"
|
|
},
|
|
"current_entry": {
|
|
"id": 747,
|
|
"team": {
|
|
"id": 155,
|
|
"team_name": "狸の宮家_v2",
|
|
"category": {
|
|
"id": 1,
|
|
"category_name": "一般-5時間"
|
|
}
|
|
},
|
|
"event": {
|
|
"id": 128,
|
|
"event_name": "揖斐川",
|
|
"start_datetime": "2025-01-25T10:00:00+09:00",
|
|
"end_datetime": "2025-01-25T16:00:00+09:00"
|
|
},
|
|
"date": "2025-01-25",
|
|
"has_participated": false,
|
|
"has_goaled": false
|
|
},
|
|
"entries_count": 6,
|
|
"latest_entry_date": "2025-01-25T10:00:00+09:00"
|
|
}
|
|
```
|
|
|
|
**エラーレスポンス (HTTP 404)**
|
|
```json
|
|
{
|
|
"error": "No active entry found for user",
|
|
"detail": "User has no current entries"
|
|
}
|
|
```
|
|
|
|
**実装要件:**
|
|
- ユーザーの最新エントリーを`team__owner`で検索
|
|
- エントリーは`created_at`の降順でソート
|
|
- ユーザー情報の`event_code`は最新エントリーのイベント名を反映
|
|
- Team, Event, Category情報を含む完全な情報を返却
|
|
|
|
### 2. 既存API修正
|
|
|
|
#### API 2: エントリーステータス更新API修正
|
|
|
|
**エンドポイント:** `PATCH /api/entries/{entry_id}/update-status/`
|
|
|
|
**問題:** 現在ValidationErrorが発生
|
|
|
|
**現在のリクエストボディ:**
|
|
```json
|
|
{
|
|
"hasParticipated": true,
|
|
"hasGoaled": false
|
|
}
|
|
```
|
|
|
|
**期待されるフィールド名 (要確認):**
|
|
```json
|
|
{
|
|
"has_participated": true,
|
|
"has_goaled": false
|
|
}
|
|
```
|
|
|
|
**対応要求:**
|
|
1. フィールド名の整合性確認
|
|
2. バリデーションエラーの原因調査
|
|
3. 適切なエラーレスポンスの実装
|
|
|
|
## 実装方針
|
|
|
|
### Django REST Framework実装例
|
|
|
|
```python
|
|
# views.py
|
|
from rest_framework.decorators import api_view, permission_classes
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
@api_view(['GET'])
|
|
@permission_classes([IsAuthenticated])
|
|
def current_entry_info(request):
|
|
user = request.user
|
|
|
|
# ユーザーの最新エントリーを取得
|
|
latest_entry = Entry.objects.filter(
|
|
team__owner=user
|
|
).order_by('-created_at').first()
|
|
|
|
if not latest_entry:
|
|
return Response({
|
|
'error': 'No active entry found for user',
|
|
'detail': 'User has no current entries'
|
|
}, status=404)
|
|
|
|
# レスポンスデータを構築
|
|
response_data = {
|
|
'user': {
|
|
'id': user.id,
|
|
'email': user.email,
|
|
'firstname': user.first_name,
|
|
'lastname': user.last_name,
|
|
'is_staff': user.is_staff,
|
|
'event_code': latest_entry.event.event_name # 最新エントリーのイベント名
|
|
},
|
|
'current_entry': {
|
|
'id': latest_entry.id,
|
|
'team': {
|
|
'id': latest_entry.team.id,
|
|
'team_name': latest_entry.team.team_name,
|
|
'category': {
|
|
'id': latest_entry.category.id,
|
|
'category_name': latest_entry.category.category_name
|
|
}
|
|
},
|
|
'event': {
|
|
'id': latest_entry.event.id,
|
|
'event_name': latest_entry.event.event_name,
|
|
'start_datetime': latest_entry.event.start_datetime,
|
|
'end_datetime': latest_entry.event.end_datetime
|
|
},
|
|
'date': latest_entry.date,
|
|
'has_participated': latest_entry.has_participated,
|
|
'has_goaled': latest_entry.has_goaled
|
|
},
|
|
'entries_count': Entry.objects.filter(team__owner=user).count(),
|
|
'latest_entry_date': latest_entry.created_at
|
|
}
|
|
|
|
return Response(response_data)
|
|
```
|
|
|
|
```python
|
|
# urls.py
|
|
urlpatterns = [
|
|
path('api/user/current-entry-info/', views.current_entry_info, name='current_entry_info'),
|
|
# ... 他のURL
|
|
]
|
|
```
|
|
|
|
## 期待される効果
|
|
|
|
1. **データ整合性の確保**
|
|
- アプリ側とサーバー側のエントリー情報が常に同期
|
|
- 正しいentry_idとevent_codeを使用した通信
|
|
|
|
2. **エラーの解消**
|
|
- 競技開始時のValidationErrorの解決
|
|
- 適切なAPI呼び出しの実現
|
|
|
|
3. **ユーザビリティの向上**
|
|
- 競技開始がスムーズに行える
|
|
- データの不整合によるアプリクラッシュの防止
|
|
|
|
## 実装スケジュール
|
|
|
|
| 項目 | 期限 | 担当 |
|
|
|------|------|------|
|
|
| API設計レビュー | 2025年9月3日 | サーバーチーム |
|
|
| 新規API実装 | 2025年9月5日 | サーバーチーム |
|
|
| 既存API修正 | 2025年9月5日 | サーバーチーム |
|
|
| 結合テスト | 2025年9月6日 | 全チーム |
|
|
| 本番環境デプロイ | 2025年9月8日 | インフラチーム |
|
|
|
|
## テスト要件
|
|
|
|
### 1. 単体テスト
|
|
- [ ] 新規API: 正常系レスポンス確認
|
|
- [ ] 新規API: エラーケース確認
|
|
- [ ] 既存API: バリデーションエラー修正確認
|
|
|
|
### 2. 結合テスト
|
|
- [ ] アプリからの新規API呼び出し
|
|
- [ ] データ同期確認
|
|
- [ ] 競技開始フロー確認
|
|
|
|
### 3. 性能テスト
|
|
- [ ] 新規APIのレスポンス時間測定
|
|
- [ ] 同時アクセス時の動作確認
|
|
|
|
## リスク評価
|
|
|
|
| リスク | 影響度 | 対策 |
|
|
|--------|--------|------|
|
|
| 既存API変更による影響 | 中 | 下位互換性の維持 |
|
|
| データ移行の必要性 | 低 | 新規APIのため影響なし |
|
|
| 性能劣化 | 低 | インデックス最適化 |
|
|
|
|
## 承認
|
|
|
|
| 役割 | 氏名 | 承認日 | 署名 |
|
|
|------|------|--------|------|
|
|
| アプリ開発リーダー | | | |
|
|
| サーバー開発リーダー | | | |
|
|
| プロジェクトマネージャー | | | |
|
|
|
|
---
|
|
|
|
**注意事項:**
|
|
- 本変更要求は岐阜ロゲイニングアプリの安定運用のために必要な修正です
|
|
- 実装前に必ずステージング環境での検証を行ってください
|
|
- 本番環境デプロイ時はユーザーへの事前通知を行ってください
|