# サーバー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": "..." } ] } ``` **実装要件**: - イベント毎のサンプルルート管理 - 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日