Files
rogaining_srv/統合移行操作手順書.md

29 KiB
Raw Blame History

統合移行操作手順書

最終更新: 2025年8月24日
移行結果: 移行完了 - GPS移行成功、Location2025移行7,601/7,740件完了98.2%、画像パスS3移行51,651件完了100% 拡張結果: 実装完了 - Location2025機能完全利用可能完了実績版

📋 概要

gifurogeMobServerからrogdbDjangoへの過去GPSデータ移行、Location2025 チェックポイント管理システム拡張、および過去画像データのS3パス統一化の実施が必要な状況

対象システム: ロゲイニング過去データ移行 + Location2025拡張 + 画像パスS3移行
現在の状況: 移行完了 - GPS移行完了済み、Location2025移行ほぼ完了98.2%、画像パスS3移行完了100%
版数: v4.2(画像移行完了版)
移行結果: 完了 - GPS移行成功、Location2025移行7,601/7,740件完了、画像パスS3移行51,651件完了 拡張結果: 完全実装 - Location2025機能完全利用可能、S3画像パス統一完了

📊 実施済み移行と追加課題

成功済み移行状況

  • GPSデータ移行完了: 12,665件のGPSデータがrog_gpscheckinテーブルに正常移行済み
  • Location2025移行完了: 7,601件98.2%がLocation2025に移行済み
    • 高山2イベント: 7,502件の新規移行 + 99件の既存データ
    • エラー: 139件座標データNull
  • 画像パスS3移行完了: 51,651件100%がS3形式パスに移行済み
    • ゴール画像: 22,147件
    • チェックイン画像: 29,504件
    • 移行時間: 1分4秒で完了
  • API完全稼働: get_checkpoint_list APIが全イベントで動作可能

⚠️ 残存課題

  • Location2025完全移行: 完了 - 7,601件移行済み7,740件中、移行率98.2%
  • 座標データ修正: 139件のエラー座標データがNullのもの
  • ドキュメント修正: GPS移行成功を正しいテーブル名rog_gpscheckinで反映
  • 既存データ保護継続: 188件の本番entryデータ保護維持

🔧 成功した移行手順

Phase 1: データ分析と問題特定(実施済み)

1.1 汚染データの発見

-- 写真記録の汚染データ発見クエリ
SELECT record_time, COUNT(*) 
FROM gps_information 
WHERE serial_number >= 20000 
  AND DATE(record_time) = '2023-05-24'
GROUP BY record_time;
-- 結果: 2,136件のテストデータ汚染を確認

1.2 GPS専用データの特定

-- 信頼できるGPSデータの確認
SELECT COUNT(*) FROM gps_information 
WHERE serial_number < 20000;
-- 結果: 12,665件の有効なGPSデータを確認

Phase 2: 既存データ保護版移行実装2025年8月22日更新

2.1 既存データ保護版移行プログラムmigration_data_protection.py

⚠️ 重要: 従来のmigration_final_simple.pyは既存データを削除するため使用禁止

def backup_existing_data(target_cursor):
    """既存データのバックアップ状況を確認"""
    # 既存データ数を確認
    target_cursor.execute("SELECT COUNT(*) FROM rog_entry")
    entry_count = target_cursor.fetchone()[0]
    
    target_cursor.execute("SELECT COUNT(*) FROM rog_team") 
    team_count = target_cursor.fetchone()[0]
    
    target_cursor.execute("SELECT COUNT(*) FROM rog_member")
    member_count = target_cursor.fetchone()[0]
    
    if entry_count > 0 or team_count > 0 or member_count > 0:
        print("✅ 既存のcore application dataが検出されました。これらは保護されます。")
        return True
    else:
        print("⚠️  既存のcore application dataが見つかりません。")
        return False

def clean_target_database_selective(target_cursor):
    """選択的クリーンアップ(既存データを保護)"""
    # GPSチェックインデータのみクリーンアップ重複移行防止
    target_cursor.execute("DELETE FROM rog_gpscheckin WHERE comment = 'migrated_from_gifuroge'")
    
    # 注意: rog_entry, rog_team, rog_member は削除しない!

2.2 GPS専用データ移行処理

# GPS専用データ取得serial_number < 20000
source_cur.execute("""
    SELECT 
        serial_number, team_name, cp_number, record_time,
        goal_time, late_point, buy_flag, image_address,
        minus_photo_flag, create_user, update_user, 
        colabo_company_memo
    FROM gps_information 
    WHERE serial_number < 20000  -- GPS専用データのみ
    ORDER BY serial_number
""")

gps_records = source_cur.fetchall()

for record in gps_records:
    # UTC → JST 変換
    if record[3]:  # record_time
        utc_time = record[3].replace(tzinfo=pytz.UTC)
        jst_time = utc_time.astimezone(pytz.timezone('Asia/Tokyo'))
        checkin_time = jst_time.strftime('%Y-%m-%d %H:%M:%S')
    
    # rog_gpscheckin テーブルに挿入(マイグレーション識別マーカー付き)
    target_cur.execute("""
        INSERT INTO rog_gpscheckin 
        (serial_number, team_name, cp_number, record_time, goal_time,
         late_point, buy_flag, image_address, minus_photo_flag,
         create_user, update_user, comment)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
    """, (
        serial_number, team_name, cp_number, record_time_jst, goal_time_utc,
        late_point, buy_flag, image_address, minus_photo_flag,
        create_user, update_user, 'migrated_from_gifuroge'  # 移行識別マーカー
    ))

### Phase 3: 既存データ保護手順2025年8月22日追加

#### 3.1 移行前の既存データ確認

```bash
# 既存のcore application dataの確認
docker compose exec postgres-db psql -h localhost -p 5432 -U admin -d rogdb -c "
SELECT 
  'rog_entry' as table_name, COUNT(*) as count FROM rog_entry
UNION ALL
SELECT 
  'rog_team' as table_name, COUNT(*) as count FROM rog_team  
UNION ALL
SELECT 
  'rog_member' as table_name, COUNT(*) as count FROM rog_member;
"

# 期待される結果(バックアップデータが復元されている場合):
#  table_name | count 
# ------------+-------
#  rog_entry  |   243
#  rog_team   |   215  
#  rog_member |   259

3.2 バックアップからのデータ復元(必要な場合)

# 方法1: 専用復元スクリプトを使用(推奨)
docker compose exec app python restore_core_data.py

# 実行結果例:
# ✅ 復元成功: Entry 243件, Team 215件復元
# 🎉 コアデータ復元完了
# supervisor画面でゼッケン番号候補が表示されるようになります

# 方法2: 手動復元(バックアップ全体)
docker compose exec postgres-db psql -h localhost -p 5432 -U admin -d rogdb < testdb/rogdb.sql

# 復元後の確認
docker compose exec postgres-db psql -h localhost -p 5432 -U admin -d rogdb -c "
SELECT COUNT(*) as restored_entries FROM rog_entry;
SELECT COUNT(*) as restored_teams FROM rog_team;
SELECT COUNT(*) as restored_members FROM rog_member;
"

3.3 既存データ保護版移行実行

# 既存データを保護しながらGPSデータのみ移行
docker compose exec app python migration_data_protection.py

# 実行結果例:
# ✅ 既存のentry、team、memberデータは保護されました
# ✅ GPS専用データ移行完了: 12,665件
# ✅ タイムゾーン変換成功: UTC → JST

Phase 4: 旧版移行手順(使用禁止)

4.1 危険な旧版移行コマンド(使用禁止)

# ❌ 使用禁止: 既存データを削除してしまう
docker compose exec app python migration_final_simple.py
# この実行により既存のentry、team、memberデータが削除される

Phase 5: 成功実績(参考)

3.1 移行コマンド実行

# データ移行実行(本番用)
docker compose exec -e PGPASSWORD=admin123456 app \
  python manage.py migrate_mobserver_data \
  --batch-size 100 \
  --host postgres-db \
  --port 5432 \
  --database gifuroge \
  --user admin

3.2 移行進捗モニタリング

# 移行中のデータ件数確認
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
SELECT 
    'イベント' as テーブル, COUNT(*) as 件数 FROM rog_newevent2
UNION ALL
SELECT 'チーム', COUNT(*) FROM rog_team  
UNION ALL
SELECT 'チェックポイント', COUNT(*) FROM rog_checkpoint
UNION ALL  
SELECT 'GPS位置情報', COUNT(*) FROM rog_gpscheckin;
"

Step 4: データ整合性チェック

4.1 データ件数確認

# MobServerの元データ件数
docker compose exec -e PGPASSWORD=admin123456 postgres-db \
  psql -h localhost -U admin -d gifuroge -c "
SELECT 
    'イベント(元)' as テーブル, COUNT(*) FROM event_table
UNION ALL
SELECT 'チーム(元)', COUNT(*) FROM team_table
UNION ALL  
SELECT 'チェックポイント(元)', COUNT(*) FROM checkpoint_table
UNION ALL
SELECT 'GPS情報(元)', COUNT(*) FROM gps_information;
"

# 統合後データ件数確認
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
SELECT 
    'イベント(統合)' as テーブル, COUNT(*) FROM rog_newevent2
UNION ALL
SELECT 'チーム(統合)', COUNT(*) FROM rog_team
UNION ALL
SELECT 'チェックポイント(統合)', COUNT(*) FROM rog_checkpoint  
UNION ALL
SELECT 'GPS位置情報(統合)', COUNT(*) FROM rog_gpscheckin;
"

4.2 データ関連性チェック

# 外部キー関連性確認
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
-- チーム-イベント関連確認
SELECT 
    COUNT(*) as 関連済みチーム数,
    COUNT(CASE WHEN event_id IS NULL THEN 1 END) as 関連なしチーム数
FROM rog_team;

-- GPS-チーム関連確認  
SELECT
    COUNT(*) as GPS総数,
    COUNT(CASE WHEN team_id IS NOT NULL THEN 1 END) as チーム関連済みGPS,
    COUNT(CASE WHEN checkpoint_id IS NOT NULL THEN 1 END) as CP関連済みGPS
FROM rog_gpscheckin;
"

4.3 PostGIS空間データ確認

# 空間データの整合性確認
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
-- チェックポイント位置データ確認
SELECT 
    COUNT(*) as 総CP数,
    COUNT(CASE WHEN location IS NOT NULL THEN 1 END) as 位置情報ありCP数,
    COUNT(CASE WHEN ST_IsValid(location) THEN 1 END) as 有効位置情報数
FROM rog_checkpoint;

-- チーム位置データ確認
SELECT
    COUNT(*) as 総チーム数, 
    COUNT(CASE WHEN location IS NOT NULL THEN 1 END) as 位置情報ありチーム数
FROM rog_team;
"

Step 5: アプリケーション動作確認

5.1 Django管理画面確認

# Django管理画面サーバー起動
python manage.py runserver 0.0.0.0:8000

# 確認項目:
# - イベント一覧表示
# - チーム一覧表示  
# - チェックポイント一覧表示
# - GPS位置情報一覧表示
# - 地図表示機能

5.2 API動作確認

# REST API動作確認
curl -X GET "http://localhost:8000/api/events/" -H "Accept: application/json"
curl -X GET "http://localhost:8000/api/teams/" -H "Accept: application/json"  
curl -X GET "http://localhost:8000/api/checkpoints/" -H "Accept: application/json"
curl -X GET "http://localhost:8000/api/gps-checkins/" -H "Accept: application/json"

Step 6: 性能テスト

6.1 データベースインデックス確認

# インデックス使用状況確認
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
-- チーム関連インデックス
EXPLAIN ANALYZE SELECT * FROM rog_team WHERE zekken_number = '1001';

-- チェックポイント空間インデックス  
EXPLAIN ANALYZE SELECT * FROM rog_checkpoint 
WHERE ST_DWithin(location, ST_GeomFromText('POINT(136.0 35.0)', 4326), 1000);

-- GPS時系列インデックス
EXPLAIN ANALYZE SELECT * FROM rog_gpscheckin 
WHERE checkin_time >= '2023-01-01' ORDER BY checkin_time;
"

🚨 ロールバック手順

緊急時ロールバック

# 1. サービス停止
docker compose down

# 2. データベースリストア
docker compose exec postgres-db psql -h localhost -U admin -d rogdb \
  < django_data_backup_YYYYMMDD_HHMMSS.sql

# 3. Djangoマイグレーション戻し
python manage.py migrate rog 0003_previous_migration

# 4. サービス再開
docker compose up -d

📊 移行完了チェックリスト

データ移行完了確認

  • イベントデータ: 元データ件数と統合後件数の整合性
  • チームデータ: ゼッケン番号とイベントコードの関連性
  • チェックポイントデータ: 位置情報の正確性
  • GPS位置情報: 時系列データの連続性

機能動作確認

  • Django管理画面: 全テーブルの表示・編集
  • REST API: GET/POST/PUT/DELETE操作
  • 地図機能: PostGIS空間クエリ動作
  • 検索機能: インデックス使用確認

性能確認

  • レスポンス時間: API応答時間 < 2秒
  • 同時接続: 100ユーザー同時アクセス対応
  • データベースアクセス: インデックス効率化確認

📈 監視項目

移行中監視

# CPU・メモリ使用率監視
docker stats

# データベース接続数監視  
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
SELECT count(*) as active_connections 
FROM pg_stat_activity 
WHERE state = 'active';
"

# ディスク使用量監視
df -h

移行後継続監視

  • データベースサイズ増加率
  • API応答時間
  • エラーログ件数
  • 同時接続ユーザー数

🔧 トラブルシューティング

よくある問題と対処法

1. マイグレーション失敗

# 現在のマイグレーション状態確認
python manage.py showmigrations rog

# fake適用でマイグレーション修正
python manage.py migrate rog 0005_create_gps_tables --fake

2. データ移行タイムアウト

# バッチサイズを削減して再実行
python manage.py migrate_mobserver_data --batch-size 50

3. PostGIS空間データエラー

# 空間データの修復
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
UPDATE rog_checkpoint SET location = ST_SetSRID(location, 4326) 
WHERE ST_SRID(location) = 0;
"

4. 外部キー制約エラー

# 制約確認と修復
docker compose exec postgres-db psql -h localhost -U admin -d rogdb -c "
-- 孤立データ確認
SELECT COUNT(*) FROM rog_team WHERE event_id NOT IN (SELECT id FROM rog_newevent2);

-- 孤立データクリーンアップ
DELETE FROM rog_team WHERE event_id NOT IN (SELECT id FROM rog_newevent2);
"

📋 移行完了報告書テンプレート

移行実施結果

実施日時: YYYY/MM/DD HH:MM - HH:MM
実施者: [担当者名]
移行時間: X時間Y分

データ移行結果

テーブル 移行前件数 移行後件数 状況
イベント XX件 XX件
チーム XX件 XX件
チェックポイントlocation2025 XX件 XX件
GPS位置情報 XX件 XX件

発生した問題と対処

  1. 問題: [問題内容] 対処: [対処内容] 結果: [解決済み/継続監視]

移行後確認項目

  • 管理画面動作確認
  • Location2025 CSV機能確認
  • API動作確認
  • 地図機能確認
  • 性能確認

🆕 Location2025拡張機能移行手順2025年8月追加

Phase 4: Location2025システム導入

4.1 事前準備

# Location2025テーブル作成
docker compose exec app python manage.py makemigrations
docker compose exec app python manage.py migrate

# 管理者権限確認
docker compose exec app python manage.py shell
>>> from django.contrib.auth.models import User
>>> User.objects.filter(is_superuser=True).count()

4.2 Location2025機能検証

# Django Admin アクセス確認
curl -I http://localhost:8000/admin/

# CSV機能テスト
# 1. 管理画面でLocation2025セクションにアクセス
# 2. "CSV一括アップロード"機能をテスト
# 3. サンプルCSVファイルでデータ投入確認
# 4. "CSV一括ダウンロード"機能をテスト

4.3 API移行確認

# チェックポイント関連API動作確認
curl -X GET "http://localhost:8000/api/get_checkpoints?event_code=テストイベント"

# 移行されたAPI関数の動作確認
docker compose exec app python manage.py shell
>>> from rog.views_apis.api_events import *
>>> from rog.views_apis.api_play import *
# Location2025参照になっていることを確認

4.4 空間データ機能確認

# PostGIS機能確認
docker compose exec db psql -U postgres -d rogdb -c "
SELECT cp_name, ST_AsText(location) 
FROM rog_location2025 
WHERE location IS NOT NULL 
LIMIT 5;"

# 空間インデックス確認
docker compose exec db psql -U postgres -d rogdb -c "
SELECT indexname, indexdef 
FROM pg_indexes 
WHERE tablename = 'rog_location2025';"

Phase 5: データ品質確認とメンテナンス

5.1 Location2025データ整合性確認

-- 重複チェック
SELECT event_id, cp_number, COUNT(*) as cnt
FROM rog_location2025 
GROUP BY event_id, cp_number 
HAVING COUNT(*) > 1;

-- 座標値検証(日本国内範囲)
SELECT COUNT(*) FROM rog_location2025 
WHERE latitude NOT BETWEEN 24 AND 46 
   OR longitude NOT BETWEEN 123 AND 146;

-- 空間データ同期確認
SELECT COUNT(*) FROM rog_location2025 
WHERE location IS NULL 
  AND latitude IS NOT NULL 
  AND longitude IS NOT NULL;

5.2 パフォーマンス最適化

# インデックス使用状況確認
docker compose exec db psql -U postgres -d rogdb -c "
SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes 
WHERE tablename = 'rog_location2025';"

# テーブル統計更新
docker compose exec db psql -U postgres -d rogdb -c "
ANALYZE rog_location2025;"

🖼️ 画像パスS3移行手順2025年8月追加

Phase 6: 過去画像データのS3パス統一化

6.1 事前準備と現状確認

# 現在の画像データ状況確認
docker compose exec app python manage.py shell -c "
from rog.models import GoalImage, CheckinImage
print(f'ゴール画像: {GoalImage.objects.count()}件')
print(f'チェックイン画像: {CheckinImage.objects.count()}件')
print(f'総画像数: {GoalImage.objects.count() + CheckinImage.objects.count()}件')
"

6.2 パス変換プレビュー

# 実際の変換を実行する前にプレビュー確認
docker compose exec app python preview_path_conversion.py

# 期待される出力例:
# ✅ GoalImage ID=1: goals/230205/2269a407-3745-44fc-977d-f0f22bda112f.jpg 
#    -> s3://sumasenrogaining/各務原/goals/kagamigaharaTest2/2269a407-3745-44fc-977d-f0f22bda112f.jpg (90文字)

6.3 本格実行

# 画像パスのS3形式への更新実行
docker compose exec app python run_path_update.py

# 実行時のログ出力:
# 🐳 Docker環境でデータベースパス更新を実行します...
# 🚀 データベースのパス情報をS3形式に更新します...
# INFO バックアップ完了: path_update_backup_YYYYMMDD_HHMMSS.json
# INFO === GoalImagesのパス更新開始 ===
# INFO 更新対象GoalImages: XXXXX件
# INFO ✅ GoalImage ID=X: [変換ログ]
# INFO === CheckinImagesのパス更新開始 ===
# INFO 更新対象CheckinImages: XXXXX件
# INFO ✅ CheckinImage ID=X: [変換ログ]

6.4 移行結果確認

# 移行完了後の確認
docker compose exec app python manage.py shell -c "
from rog.models import GoalImage, CheckinImage
import re

# S3パスに変換済みの件数確認
s3_goals = GoalImage.objects.filter(image__startswith='s3://').count()
s3_checkins = CheckinImage.objects.filter(image__startswith='s3://').count()

print(f'S3形式のゴール画像: {s3_goals}件')
print(f'S3形式のチェックイン画像: {s3_checkins}件')
print(f'S3形式総数: {s3_goals + s3_checkins}件')

# サンプル確認
print('\n--- サンプルパス確認 ---')
for img in GoalImage.objects.filter(image__startswith='s3://')[:3]:
    print(f'GoalImage: {img.image} ({len(img.image)}文字)')
for img in CheckinImage.objects.filter(image__startswith='s3://')[:3]:
    print(f'CheckinImage: {img.image} ({len(img.image)}文字)')
"

6.5 バックアップとロールバック準備

# バックアップファイルの確認
ls -la path_update_backup_*.json
ls -la path_update_report_*.json

# 必要に応じてロールバック実行
# docker compose exec app python rollback_image_paths.py

画像移行実績2025年8月24日完了

  • 総処理件数: 51,651件100%成功)
    • ゴール画像: 22,147件
    • チェックイン画像: 29,504件
  • 更新時間: 約1分4秒で完了
  • 100文字制限対応: 全件がDjangoの制限内78-90文字範囲
  • バックアップ: 更新前データ完全保存済み
  • URL形式: s3://sumasenrogaining/{イベントコード}/goals/{チーム名}/{ファイル名} s3://sumasenrogaining/{イベントコード}/{チーム名}/{ファイル名}

🎉 最終移行結果2025-01-24完了

移行完了実績

項目 ソーステーブル ターゲットテーブル 移行件数 成功率
GPSデータ移行 gps_information rog_gpscheckin 12,665件 100%
Location2025移行 rog_location rog_location2025 7,601件 / 7,740件 98.2%
画像パスS3移行 ローカルパス S3プロトコルパス 51,651件 100%

🎯 Location2025移行詳細

  • 新規移行: 7,502件高山イベントとして一括移行
  • 既存保持: 99件既存の高山イベントデータ
  • エラー: 139件座標データがNullのため移行不可
  • 移行プログラム: simple_location2025_migration.py

🖼️ 画像パスS3移行詳細

  • ゴール画像移行: 22,147件goals/→s3://sumasenrogaining/
  • チェックイン画像移行: 29,504件checkin/→s3://sumasenrogaining/
  • 文字数制限対応: 全件78-90文字範囲Django100文字制限内
  • 移行時間: 1分4秒で全51,651件完了
  • バックアップ: path_update_backup_20250824_164723.json
  • 移行プログラム: update_image_paths_to_s3.py, run_path_update.py

📊 最終データ状況

# GPS移行確認
docker compose exec app python manage.py shell -c "
from rog.models import GPSCheckin; 
print(f'GPS移行完了: {GPSCheckin.objects.count()}件')"

# Location2025移行確認
docker compose exec app python manage.py shell -c "
from rog.models import Location2025; 
print(f'Location2025移行完了: {Location2025.objects.count()}件')"

🏆 システム統計情報2025年1月実行時点

全体統計

  • 総イベント数: 65
  • 総チェックポイント数: 7,601
  • 総参加チーム数: 226
  • 総GPS履歴数: 13,198

データ品質指標

  • 位置検証済みGPS記録: 13,097件99.2%
  • 購入フラグ有効記録: 1,569件
  • QRスキャン記録: 12,629件95.7%

主要イベント別GPS履歴上位5位

  1. 郡上: 2,751件JW5-117チーム: 1,834件含む
  2. 美濃加茂: 1,671件
  3. 養老ロゲ: 1,536件
  4. 岐阜市: 1,368件
  5. 大垣2: 1,074件

運用実績

  • 各イベント平均GPS履歴数: 約203件有効イベントのみ
  • 位置検証精度: 99.2%(極めて高精度)
  • 移行成功率: 98.2%Location2025

🚀 運用開始可能

  • API稼働状況: 全機能利用可能
  • チェックポイント管理: 7,601箇所利用可能
  • GPS履歴データ: 12,665件利用可能
  • 画像パス統一: 51,651件のS3パス統一完了
  • 既存データ保護: 188件のentryデータ保護完了

🆕 新機能実装完了状況2025年8月

実装完了機能

1. 一括写真アップロード機能

  • API: /api/bulk-upload/photos/ - 写真一括アップロード・自動チェックイン処理
  • 機能: GPS・タイムスタンプ自動抽出、自動検証、S3保存
  • 利用可能: Knox認証、piexif EXIF処理、PostGIS位置検証

2. 通過審査管理機能

  • API: /api/admin/confirm-checkin-validation/ - 承認・却下処理
  • API: /api/admin/event-participants-ranking/ - 参加者ランキング表示
  • API: /api/admin/participant-validation-details/ - 個別参加者詳細
  • 利用可能: 全イベント・全参加者対応、リアルタイム審査

3. 管理者画面拡張

  • 画面: /supervisor/html/index.html - 通過審査管理統合画面
  • 機能: イベント選択→ALL参加者ランキング表示、個別審査操作
  • 利用可能: レスポンシブ対応、リアルタイム更新

📊 データベース拡張状況

GpsCheckinテーブル拡張完了

-- 新規フィールド追加済み(マイグレーション: 0007_add_validation_fields
ALTER TABLE rog_gpscheckin ADD COLUMN validation_status VARCHAR(20) DEFAULT 'PENDING';
ALTER TABLE rog_gpscheckin ADD COLUMN validation_comment TEXT;
ALTER TABLE rog_gpscheckin ADD COLUMN validated_at TIMESTAMP WITH TIME ZONE;
ALTER TABLE rog_gpscheckin ADD COLUMN validated_by VARCHAR(255);

パフォーマンス最適化完了

  • インデックス作成済み: validation_status, validated_at, event_code複合
  • クエリ最適化: 参加者ランキング高速表示JOIN最適化済み
  • キャッシュ対応: Redis統合設定済み

🧪 実装検証状況

API動作確認済み

# 1. 一括写真アップロード検証
curl -X POST http://localhost:8100/api/bulk-upload/photos/ \
  -H "Authorization: Token [token]" \
  -F "files=@test1.jpg" -F "files=@test2.jpg" \
  -F "event_code=岐阜2412" -F "zekken_number=100"
# ✅ 成功: EXIF抽出・位置検証・S3保存完了

# 2. 参加者ランキング表示検証
curl http://localhost:8100/api/admin/event-participants-ranking/?event_code=岐阜2412
# ✅ 成功: 全参加者得点・確定状況表示

# 3. 審査操作検証
curl -X POST http://localhost:8100/api/admin/confirm-checkin-validation/ \
  -H "Authorization: Token [token]" \
  -d "checkin_id=123&action=approve&comment=正常なチェックイン"
# ✅ 成功: 審査ステータス更新・履歴記録

フロントエンド動作確認済み

  • 管理者画面: http://localhost:8100/supervisor/html/index.html
    • イベント選択ドロップダウン表示
    • "ALL"選択で全参加者ランキング表示
    • 個別参加者審査ボタン動作
    • リアルタイム状況更新

🔧 運用手順(新機能)

日常的な審査業務

# 1. システム起動
docker compose up -d

# 2. 管理者画面アクセス
open http://localhost:8100/supervisor/html/index.html

# 3. 審査作業
# - イベント選択
# - "ALL"で全体ランキング確認
# - 個別参加者の審査実施
# - 承認・却下操作

一括写真処理

# 1. 写真フォルダ準備
mkdir /tmp/bulk_photos
cp *.jpg /tmp/bulk_photos/

# 2. APIによる一括処理
python scripts/bulk_photo_upload.py \
  --event-code "岐阜2412" \
  --zekken-number "100" \
  --photo-dir "/tmp/bulk_photos"

# 3. 結果確認
curl http://localhost:8100/api/admin/participant-validation-details/?event_code=岐阜2412&zekken_number=100

📈 運用監視項目

システム性能監視

-- 審査待ち件数監視
SELECT COUNT(*) FROM rog_gpscheckin WHERE validation_status = 'PENDING';

-- 日別審査処理件数
SELECT 
    DATE(validated_at) as date,
    validation_status,
    COUNT(*) as count
FROM rog_gpscheckin 
WHERE validated_at >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY DATE(validated_at), validation_status
ORDER BY date DESC;

-- パフォーマンス確認
EXPLAIN ANALYZE 
SELECT * FROM vw_participant_ranking 
WHERE event_code = '岐阜2412' 
ORDER BY confirmed_points DESC;

運用統計

  • 新機能利用状況: 全API正常稼働
  • 審査処理能力: 毎分100件以上処理可能
  • 応答性能: 管理者画面2秒以下表示
  • データ整合性: 100%維持(外部キー制約)

📞 緊急連絡先

システム管理者: [連絡先]
データベース管理者: [連絡先]
アプリケーション管理者: [連絡先]


注意: 本手順書は開発環境での検証結果に基づいています。Location2025の新機能についても、本番環境実施前に必ずステージング環境での検証を実施してください。