Files
rogaining_srv/サーバーAPI変更要求書.md
2025-08-27 15:01:06 +09:00

725 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# サーバーAPI変更要求書
## 概要
2025年8月27日時点のFlutterアプリコード解析に基づき、サーバー側APIで新規実装・変更が必要な機能を特定しました。
### 📋 最新の実装状況
- ✅ APKビルドシステム修正完了
- ✅ 画像マルチアップロード機能実装完了iOS/Android対応
- ✅ QRコードスキャナー統合完了
- ✅ GPXルートシミュレーション機能実装完了
- ✅ アプリバージョンチェック機能実装完了(クライアント側)
- ⚠️ サーバー側API実装が必要な項目を以下に記載
---
## 🆕 緊急実装が必要なAPI
### 1. **画像マルチアップロードAPI** 🔴最優先
#### **エンドポイント**: `POST /api/images/multi-upload`
**目的**: 複数画像の一括アップロードiOS Share Extension / Android Intent対応
**リクエストパラメータ**:
```json
{
"event_code": "岐阜ロゲイニング2025",
"team_name": "チーム名",
"cp_number": 1,
"images": [
{
"file_data": "base64_encoded_image_data",
"filename": "checkpoint1_photo1.jpg",
"mime_type": "image/jpeg",
"file_size": 2048576,
"capture_timestamp": "2025-09-15T11:30:00Z"
},
{
"file_data": "base64_encoded_image_data",
"filename": "checkpoint1_photo2.jpg",
"mime_type": "image/jpeg",
"file_size": 1854232,
"capture_timestamp": "2025-09-15T11:30:15Z"
}
],
"upload_source": "sharing_intent",
"device_platform": "ios"
}
```
**レスポンス**:
```json
{
"status": "success",
"uploaded_count": 2,
"failed_count": 0,
"uploaded_files": [
{
"original_filename": "checkpoint1_photo1.jpg",
"server_filename": "uploads/2025/08/27/cp1_team1_001.jpg",
"file_url": "https://server.com/uploads/2025/08/27/cp1_team1_001.jpg",
"file_size": 2048576
},
{
"original_filename": "checkpoint1_photo2.jpg",
"server_filename": "uploads/2025/08/27/cp1_team1_002.jpg",
"file_url": "https://server.com/uploads/2025/08/27/cp1_team1_002.jpg",
"file_size": 1854232
}
],
"total_upload_size": 3902808,
"processing_time_ms": 1250
}
```
**実装要件**:
- 複数ファイルの同時処理最大10ファイル
- MIMEタイプ検証image/jpeg, image/png, image/heic対応
- ファイルサイズ制限単一ファイル最大10MB、合計最大50MB
- 重複ファイル検出とスキップ
- プラットフォーム別の最適化iOS HEIC→JPEG変換等
- 非同期処理によるタイムアウト防止
---
### 2. **GPXテストルート情報API** 🔴最優先
#### **エンドポイント**: `GET /api/routes/gpx-test-data`
**目的**: GPXシミュレーション用のテストルートデータ取得
**リクエストパラメータ**:
```json
{
"event_code": "岐阜ロゲイニング2025",
"route_type": "sample"
}
```
**レスポンス**:
```json
{
"routes": [
{
"route_name": "岐阜市内サンプルルート",
"description": "チェックポイント1-5を巡回するテストルート",
"estimated_time": "45分",
"waypoints": [
{
"lat": 35.4122,
"lng": 136.7514,
"timestamp": "2025-09-15T10:00:00Z",
"cp_number": 1,
"description": "岐阜公園"
},
{
"lat": 35.4089,
"lng": 136.7581,
"timestamp": "2025-09-15T10:15:00Z",
"cp_number": 2,
"description": "岐阜城天守閣"
}
],
"gpx_data": "<?xml version=\"1.0\"?>...</gpx>"
}
]
}
```
**実装要件**:
- イベント毎のサンプルルート管理
- GPXフォーマットでのウェイポイント情報
- 所要時間の見積もり情報
- チェックポイント連携情報
---
### 3. アプリバージョンチェックAPI
#### **エンドポイント**: `POST /api/app/version-check`
**目的**: アプリ起動時のバージョンチェックと強制/任意更新制御
**リクエストパラメータ**:
```json
{
"current_version": "1.2.3",
"platform": "android",
"build_number": "123"
}
```
**レスポンス(成功時)**:
```json
{
"latest_version": "1.3.0",
"update_required": false,
"update_available": true,
"update_message": "新機能が追加されました。更新をお勧めします。",
"download_url": "https://play.google.com/store/apps/details?id=com.example.app",
"release_date": "2025-08-25T00:00:00Z"
}
```
**実装要件**:
- バージョン比較ロジック(セマンティックバージョニング対応)
- プラットフォーム別Android/iOSの管理
- 強制更新フラグ制御
- カスタムメッセージ設定機能
- アプリストアURL管理
---
### 4. イベントステータス管理の拡張
#### **エンドポイント**: `GET /newevent2-list/` (既存APIの拡張)
**変更内容**: イベントのステータス情報追加
**現在のレスポンス**:
```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
}
]
```
**変更後のレスポンス**:
```json
[
{
"id": 1,
"event_name": "岐阜ロゲイニング2025",
"start_datetime": "2025-09-15T10:00:00Z",
"end_datetime": "2025-09-15T16:00:00Z",
"deadline_datetime": "2025-09-10T23:59:59Z",
"status": "public",
"hour_3": true,
"hour_5": true
}
]
```
**実装要件**:
- `status`フィールド追加: `"public"`, `"private"`, `"draft"`, `"closed"`
- `public`フィールドから`status`フィールドへの移行
- スタッフ権限による非公開イベント参加制御
- `deadlineDateTime`から`deadline_datetime`への統一
---
### 5. チェックポイント詳細情報API (Location2025対応)
#### **エンドポイント**: `GET /api/checkpoints/detail`
**目的**: 拡張されたチェックポイント情報の取得
**リクエストパラメータ**:
```json
{
"event_code": "岐阜ロゲイニング2025",
"cp_number": 5
}
```
**レスポンス**:
```json
{
"cp_number": 5,
"event_code": "岐阜ロゲイニング2025",
"cp_name": "岐阜公園",
"latitude": 35.4122,
"longitude": 136.7514,
"point_value": 15,
"description": "信長居館跡",
"image_path": "/static/checkpoints/gifu_park.jpg",
"buy_flag": false,
"evaluation_type": 1,
"tags": "歴史,公園",
"detailed_scoring": {
"base_points": 15,
"bonus_conditions": [
{
"condition": "camera_required",
"bonus_points": 5,
"description": "写真撮影必須"
}
]
}
}
```
**実装要件**:
- `rog_location2025`テーブルとの連携
- 詳細スコアリング情報
- チェックポイントタグ情報
- 評価方法の詳細カメラ撮影、QR等
---
## 🔄 既存APIの拡張が必要な項目
### 1. **チェックイン登録API拡張マルチ画像対応** 🟡高優先度
#### **エンドポイント**: `POST /checkin_from_rogapp` (既存APIの拡張)
**追加パラメータ**:
```json
{
"event_code": "岐阜ロゲイニング2025",
"team_name": "チーム名",
"cp_number": 1,
"images": [
"https://server.com/uploads/2025/08/27/cp1_team1_001.jpg",
"https://server.com/uploads/2025/08/27/cp1_team1_002.jpg"
],
"buy_flag": false,
"gps_coordinates": {
"latitude": 35.4091,
"longitude": 136.7581,
"accuracy": 5.2,
"timestamp": "2025-09-15T11:30:00Z"
},
"camera_metadata": {
"capture_time": "2025-09-15T11:30:00Z",
"device_info": "iPhone 16 Plus",
"sharing_source": "photos_app"
},
"checkin_method": "multi_image_upload"
}
```
**実装要件**:
- 複数画像URLの配列対応
- 画像アップロードAPIとの連携
- 共有アプリ経由でのチェックイン識別
- GPS精度向上による位置検証
### 2. エントリー情報API拡張
#### **エンドポイント**: `GET /entry/` (既存APIの拡張)
**追加フィールド**:
```json
{
"id": 1,
"team": 1,
"event": 1,
"category": 1,
"zekken_number": 101,
"date": "2025-09-15T10:00:00Z",
"hasParticipated": false,
"hasGoaled": false,
"staff_privileges": false,
"can_access_private_events": false,
"team_validation_status": "approved",
"app_permissions": {
"can_upload_multiple_images": true,
"can_use_sharing_intent": true,
"can_simulate_gps": false
}
}
```
**実装要件**:
- スタッフ権限フラグ
- 非公開イベント参加権限
- チーム承認状況
- アプリ機能別権限制御
---
### 3. チェックイン登録API拡張
#### **エンドポイント**: `POST /checkin_from_rogapp` (既存APIの拡張)
**追加パラメータ**:
```json
{
"event_code": "岐阜ロゲイニング2025",
"team_name": "チーム名",
"cp_number": 1,
"image": "https://example.com/photos/checkpoint1.jpg",
"buy_flag": false,
"gps_coordinates": {
"latitude": 35.4091,
"longitude": 136.7581,
"accuracy": 5.2,
"timestamp": "2025-09-15T11:30:00Z"
},
"camera_metadata": {
"capture_time": "2025-09-15T11:30:00Z",
"device_info": "iPhone 12"
}
}
```
**追加レスポンス**:
```json
{
"status": "OK",
"message": "チェックポイントが正常に登録されました",
"team_name": "チーム名",
"cp_number": 1,
"checkpoint_id": 123,
"checkin_time": "2025-09-15 11:30:00",
"point_value": 10,
"bonus_points": 5,
"scoring_breakdown": {
"base_points": 10,
"camera_bonus": 5,
"total_points": 15
},
"validation_status": "pending",
"requires_manual_review": false
}
```
**実装要件**:
- GPS座標と精度情報の記録
- カメラメタデータの保存
- 詳細スコアリング
- 自動審査機能
---
## 🗄️ データベース拡張要件
### 1. **画像管理テーブル新規作成** 🔴最優先
```sql
CREATE TABLE rog_uploaded_images (
id SERIAL PRIMARY KEY,
event_code VARCHAR(50) NOT NULL,
team_name VARCHAR(100),
cp_number INTEGER,
original_filename VARCHAR(255) NOT NULL,
server_filename VARCHAR(255) NOT NULL,
file_path TEXT NOT NULL,
file_url TEXT NOT NULL,
file_size BIGINT NOT NULL,
mime_type VARCHAR(50) NOT NULL,
capture_timestamp TIMESTAMP WITH TIME ZONE,
upload_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
upload_source VARCHAR(20) DEFAULT 'camera' CHECK (upload_source IN ('camera', 'sharing_intent', 'gallery')),
device_platform VARCHAR(10) CHECK (device_platform IN ('android', 'ios')),
is_processed BOOLEAN DEFAULT FALSE,
processing_status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_uploaded_images_event_team ON rog_uploaded_images(event_code, team_name);
CREATE INDEX idx_uploaded_images_cp ON rog_uploaded_images(cp_number);
CREATE INDEX idx_uploaded_images_upload_time ON rog_uploaded_images(upload_timestamp);
```
### 2. アプリバージョン管理テーブル
```sql
CREATE TABLE app_versions (
id SERIAL PRIMARY KEY,
version VARCHAR(20) NOT NULL,
platform VARCHAR(10) NOT NULL CHECK (platform IN ('android', 'ios')),
build_number VARCHAR(20),
is_latest BOOLEAN DEFAULT FALSE,
is_required BOOLEAN DEFAULT FALSE,
update_message TEXT,
download_url TEXT,
release_date TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(version, platform)
);
```
### 3. **GPXテストルート管理テーブル**
```sql
CREATE TABLE rog_gpx_test_routes (
id SERIAL PRIMARY KEY,
event_code VARCHAR(50) NOT NULL,
route_name VARCHAR(100) NOT NULL,
description TEXT,
estimated_time VARCHAR(20),
gpx_data TEXT NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
created_by INTEGER REFERENCES rog_customuser(id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE TABLE rog_gpx_waypoints (
id SERIAL PRIMARY KEY,
route_id INTEGER REFERENCES rog_gpx_test_routes(id),
latitude DECIMAL(10, 8) NOT NULL,
longitude DECIMAL(11, 8) NOT NULL,
timestamp_offset INTEGER NOT NULL, -- 開始からの秒数
cp_number INTEGER,
description TEXT,
waypoint_order INTEGER NOT NULL
);
```
### 4. イベントテーブル拡張
```sql
-- rog_newevent2テーブルにstatus列追加
ALTER TABLE rog_newevent2 ADD COLUMN status VARCHAR(20) DEFAULT 'draft'
CHECK (status IN ('public', 'private', 'draft', 'closed'));
-- 既存のpublicフィールドからstatusフィールドへの移行
UPDATE rog_newevent2 SET status = CASE
WHEN public = true THEN 'public'
ELSE 'draft'
END;
```
### 5. エントリーテーブル拡張
```sql
-- rog_entryテーブルにスタッフ権限追加
ALTER TABLE rog_entry ADD COLUMN staff_privileges BOOLEAN DEFAULT FALSE;
ALTER TABLE rog_entry ADD COLUMN team_validation_status VARCHAR(20) DEFAULT 'approved';
ALTER TABLE rog_entry ADD COLUMN app_permissions JSONB DEFAULT '{}';
```
### 6. チェックイン拡張情報テーブル
```sql
CREATE TABLE rog_checkin_extended (
id SERIAL PRIMARY KEY,
gpslog_id INTEGER REFERENCES rog_gpslog(id),
uploaded_images_ids INTEGER[] DEFAULT '{}', -- 関連画像IDの配列
gps_latitude DECIMAL(10, 8),
gps_longitude DECIMAL(11, 8),
gps_accuracy DECIMAL(6, 2),
gps_timestamp TIMESTAMP WITH TIME ZONE,
camera_capture_time TIMESTAMP WITH TIME ZONE,
device_info TEXT,
sharing_source VARCHAR(50), -- photos_app, file_manager等
checkin_method VARCHAR(30) DEFAULT 'camera' CHECK (checkin_method IN ('camera', 'qr_code', 'multi_image_upload')),
validation_status VARCHAR(20) DEFAULT 'pending',
validation_comment TEXT,
validated_by INTEGER REFERENCES rog_customuser(id),
validated_at TIMESTAMP WITH TIME ZONE,
bonus_points INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
```
---
## 🔐 認証・権限管理拡張
### 1. スタッフ権限システム
**実装要件**:
- ユーザーレベルでのスタッフ権限管理
- イベントレベルでのスタッフ権限付与
- 非公開イベント参加権限制御
- 管理者向けAPI認証強化
### 2. APIキー管理システム
**新規エンドポイント**: `POST /api/auth/api-key-generate`
```json
{
"app_version": "1.3.0",
"platform": "android",
"device_id": "unique_device_identifier"
}
```
**レスポンス**:
```json
{
"api_key": "app_1234567890abcdef",
"expires_at": "2025-12-31T23:59:59Z",
"rate_limit": 1000
}
```
---
## 📊 管理者向け機能拡張
### 1. リアルタイム監視API
#### **エンドポイント**: `GET /api/admin/realtime-stats`
```json
{
"event_code": "岐阜ロゲイニング2025",
"current_participants": 150,
"active_teams": 45,
"total_checkins": 1250,
"pending_validations": 23,
"system_status": "normal",
"last_updated": "2025-09-15T12:30:00Z"
}
```
### 2. 一括操作API
#### **エンドポイント**: `POST /api/admin/bulk-operations`
```json
{
"operation": "approve_checkins",
"target": {
"event_code": "岐阜ロゲイニング2025",
"zekken_numbers": ["001", "002", "003"],
"cp_numbers": [1, 2, 3]
},
"comment": "GPS位置確認により一括承認"
}
```
---
## 🚀 パフォーマンス最適化要件
### 1. キャッシュ機能
**実装要件**:
- チェックポイント情報のRedisキャッシュ
- イベント情報のメモリキャッシュ
- バージョン情報のキャッシュ1時間TTL
### 2. 非同期処理
**実装要件**:
- 写真アップロード処理の非同期化
- スコア計算の非同期処理
- 通知配信の非同期処理
---
## 📱 プッシュ通知システム
### 1. 通知管理API
#### **エンドポイント**: `POST /api/notifications/register-device`
```json
{
"device_token": "fcm_token_here",
"platform": "android",
"app_version": "1.3.0",
"user_id": 123
}
```
### 2. 通知配信API
#### **エンドポイント**: `POST /api/notifications/send`
```json
{
"target": "event_participants",
"event_code": "岐阜ロゲイニング2025",
"message": {
"title": "重要なお知らせ",
"body": "イベント開始時刻が変更されました",
"data": {
"type": "event_update",
"event_id": 1
}
}
}
```
---
## 🔧 実装優先度
### 🔴 最高優先度(即時実装必要)
1. **画像マルチアップロードAPI** - iOS/Android共有機能に必須
2. **GPXテストルート情報API** - GPS機能テストに必要
3. **アプリバージョンチェックAPI** - アプリの更新制御に必須
4. **画像管理データベーステーブル** - 画像アップロード機能の基盤
5. **チェックイン拡張(マルチ画像対応)** - 新しいチェックイン方式に対応
### 🟡 高優先度2週間以内
1. **イベントステータス管理拡張** - 非公開イベント制御に必要
2. **チェックポイント詳細情報API** - 新機能の完全動作に必要
3. **スタッフ権限システム** - 運営機能強化
4. **GPXルート管理システム** - テスト機能の完全実装
### 🟢 中優先度1ヶ月以内
1. **管理者向け機能拡張** - 運営効率化
2. **パフォーマンス最適化** - スケーラビリティ向上
3. **プッシュ通知システム** - ユーザー体験向上
---
## 📋 実装チェックリスト
### バックエンド実装
- [ ] **画像マルチアップロードAPI実装** 🔴
- [ ] **画像管理データベーステーブル作成** 🔴
- [ ] **GPXテストルート情報API実装** 🔴
- [ ] アプリバージョン管理テーブル作成
- [ ] バージョンチェックAPI実装
- [ ] イベントステータス管理拡張
- [ ] チェックポイント詳細API実装
- [ ] **チェックイン拡張(マルチ画像対応)** 🟡
- [ ] GPS拡張情報記録
- [ ] スタッフ権限システム
- [ ] 管理者向けAPI拡張
### フロントエンド連携
- [x] **iOS Share Extension設定完了**
- [x] **Android Intent Filter設定完了**
- [x] **画像マルチアップロード機能実装完了**
- [x] **GPXシミュレーション機能実装完了**
- [x] **QRコードスキャナー統合完了**
- [ ] API仕様書更新
- [ ] エラーコード追加定義
- [ ] レスポンス形式統一
- [ ] 認証方式更新
### テスト・運用
- [ ] 単体テスト作成
- [ ] 統合テスト実装
- [ ] パフォーマンステスト
- [ ] 運用監視設定
---
## 📞 連絡事項
### 技術的な質問・相談窓口
- **Flutter開発チーム**: アプリ側実装の詳細
- **サーバー開発チーム**: API仕様の詳細
- **インフラチーム**: データベース設計の相談
### 実装期間の目安
- **画像マルチアップロード関連**: 2-3営業日🔴緊急
- **GPXルート管理関連**: 2-3営業日🔴緊急
- **最高優先度項目**: 3-5営業日
- **高優先度項目**: 1-2週間
- **中優先度項目**: 2-4週間
### 特記事項
- **iOS Share Extension対応完了**: iOSデバイスから写真アプリ経由で直接画像アップロード可能
- **Android Intent対応完了**: Androidデバイスからギャラリーアプリ経由で画像共有可能
- **GPXシミュレーション完了**: 開発・テスト用のGPS位置シミュレーション機能実装済み
- **QRコードスキャン完了**: カメラとQRコードの両方でチェックイン可能
---
**作成日**: 2025年8月27日
**作成者**: Flutter開発チーム
**版数**: v2.0マルチ画像アップロード・GPX機能追加版
**次回レビュー予定**: 2025年9月3日