diff --git a/DEPLOYMENT_MIGRATION_GUIDE.md b/DEPLOYMENT_MIGRATION_GUIDE.md new file mode 100644 index 0000000..bd27887 --- /dev/null +++ b/DEPLOYMENT_MIGRATION_GUIDE.md @@ -0,0 +1,187 @@ +# Deploy先でのMigration手順ガイド + +## 推奨手順(安全なアプローチ) + +### パターンA: 新規クリーンDeployment(推奨) + +```bash +# 1. 旧DBのバックアップ作成 +pg_dump rogaining_db > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. Git pullで最新コード取得 +git pull origin main + +# 3. migration_simple_reset.pyで一括リセット(推奨) +docker compose exec app python migration_simple_reset.py --full + +# 4. 必要に応じてデータ復元スクリプト実行 +# (既存データがある場合) +``` + +### パターンB: 段階的Migration修正 + +```bash +# 1. 旧DBのバックアップ作成 +pg_dump rogaining_db > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. Git pullで最新コード取得 +git pull origin main + +# 3. 問題のあるmigrationファイルを一時的に削除 +rm rog/migrations/0011_auto_20250827_1459.py + +# 4. 正常なmigrationまで適用 +docker compose exec app python manage.py migrate + +# 5. migration_simple_reset.pyでクリーンアップ +docker compose exec app python migration_simple_reset.py --reset-only +docker compose exec app python migration_simple_reset.py --apply-only +``` + +## ⚠️ 元の提案手順の問題点 + +```bash +1)旧DBをリストア ✅ OK +2)Git pull で最新コード設置 ✅ OK +3)migrate してDB更新 ❌ 問題: 依存関係エラーで失敗する +4)migration_simple_reset.py実行 ✅ OK +``` + +**問題**: ステップ3で`NodeNotFoundError`が発生し、migrationが失敗します。 + +## 具体的なDeployment手順(本番推奨) + +### 事前準備 +```bash +# 本番環境への接続確認 +docker compose ps + +# 現在のmigration状態確認 +docker compose exec app python manage.py showmigrations +``` + +### 実行手順 + +#### Step 1: バックアップ作成 +```bash +# データベースバックアップ +docker compose exec postgres-db pg_dump -U admin rogaining_db > deploy_backup_$(date +%Y%m%d_%H%M%S).sql + +# 現在のmigrationファイルバックアップ +cp -r rog/migrations rog/migrations_backup_deploy_$(date +%Y%m%d_%H%M%S) +``` + +#### Step 2: コード更新 +```bash +# 最新コード取得 +git pull origin main + +# migration_simple_reset.pyが存在することを確認 +ls -la migration_simple_reset.py +``` + +#### Step 3: Migration リセット実行 +```bash +# 全体的なリセット(推奨) +docker compose exec app python migration_simple_reset.py --full +``` + +または段階的実行: +```bash +# バックアップのみ +docker compose exec app python migration_simple_reset.py --backup-only + +# リセットのみ +docker compose exec app python migration_simple_reset.py --reset-only + +# 適用のみ +docker compose exec app python migration_simple_reset.py --apply-only +``` + +#### Step 4: 結果確認 +```bash +# Migration状態確認 +docker compose exec app python manage.py showmigrations + +# アプリケーション動作確認 +docker compose exec app python manage.py check +``` + +#### Step 5: サービス再起動 +```bash +# アプリケーション再起動 +docker compose restart app + +# 全サービス再起動(必要に応じて) +docker compose restart +``` + +## トラブルシューティング + +### Migration失敗時の対処 + +```bash +# 1. migration_simple_reset.pyでクリーンアップ +docker compose exec app python migration_simple_reset.py --reset-only + +# 2. 手動でmigration状態確認 +docker compose exec app python manage.py showmigrations + +# 3. 必要に応じて個別migration適用 +docker compose exec app python manage.py migrate rog 0001 --fake +``` + +### バックアップからの復元 + +```bash +# データベース復元 +docker compose exec postgres-db psql -U admin -d rogaining_db < backup_file.sql + +# migrationファイル復元 +rm -rf rog/migrations +cp -r rog/migrations_backup_deploy_YYYYMMDD_HHMMSS rog/migrations +``` + +## 重要な注意事項 + +### ✅ 実行前チェックリスト +- [ ] データベースバックアップ作成済み +- [ ] migrationファイルバックアップ作成済み +- [ ] migration_simple_reset.pyが最新版 +- [ ] Docker環境が正常動作中 +- [ ] 十分なディスク容量確保 + +### ⚠️ 避けるべき操作 +- `python manage.py migrate`を最初に実行(依存関係エラーの原因) +- バックアップなしでの作業 +- 本番環境での実験的操作 + +### 🔄 ロールバック計画 +```bash +# 問題発生時の緊急復元 +docker compose down +docker compose exec postgres-db psql -U admin -d rogaining_db < backup_file.sql +cp -r rog/migrations_backup_deploy_YYYYMMDD_HHMMSS rog/migrations +docker compose up -d +``` + +## 結論 + +**推奨される最終手順:** + +```bash +# 1. バックアップ作成 +pg_dump rogaining_db > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. 最新コード取得 +git pull origin main + +# 3. Migration一括リセット(問題を回避) +docker compose exec app python migration_simple_reset.py --full + +# 4. 動作確認 +docker compose exec app python manage.py check +docker compose restart app +``` + +この手順により、Migration依存関係の問題を回避し、安全にデプロイが可能になります。 diff --git a/DEPLOYMENT_MIGRATION_GUIDE_en.md b/DEPLOYMENT_MIGRATION_GUIDE_en.md new file mode 100644 index 0000000..818c72a --- /dev/null +++ b/DEPLOYMENT_MIGRATION_GUIDE_en.md @@ -0,0 +1,321 @@ +# Deployment Migration Guide for Production Environment + +## Recommended Procedure (Safe Approach) + +### Pattern A: Fresh Clean Deployment (Recommended) + +```bash +# 1. Create backup of old database +pg_dump rogaining_db > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. Get latest code with Git pull +git pull origin main + +# 3. Perform batch reset with migration_simple_reset.py (Recommended) +docker compose exec app python migration_simple_reset.py --full + +# 4. Execute data restoration scripts if needed +# (When existing data is present) +``` + +### Pattern B: Gradual Migration Fix + +```bash +# 1. Create backup of old database +pg_dump rogaining_db > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. Get latest code with Git pull +git pull origin main + +# 3. Temporarily remove problematic migration file +rm rog/migrations/0011_auto_20250827_1459.py + +# 4. Apply migrations up to the last working one +docker compose exec app python manage.py migrate + +# 5. Clean up with migration_simple_reset.py +docker compose exec app python migration_simple_reset.py --reset-only +docker compose exec app python migration_simple_reset.py --apply-only +``` + +## ⚠️ Issues with Original Proposed Procedure + +```bash +1) Restore old DB ✅ OK +2) Git pull to deploy latest code ✅ OK +3) Run migrate to update DB ❌ Problem: Will fail with dependency error +4) Execute migration_simple_reset.py ✅ OK +``` + +**Issue**: Step 3 will encounter `NodeNotFoundError` and migration will fail. + +## Specific Deployment Procedure (Production Recommended) + +### Pre-deployment Preparation +```bash +# Verify connection to production environment +docker compose ps + +# Check current migration status +docker compose exec app python manage.py showmigrations +``` + +### Execution Steps + +#### Step 1: Create Backups +```bash +# Database backup +docker compose exec postgres-db pg_dump -U admin rogaining_db > deploy_backup_$(date +%Y%m%d_%H%M%S).sql + +# Current migration files backup +cp -r rog/migrations rog/migrations_backup_deploy_$(date +%Y%m%d_%H%M%S) +``` + +#### Step 2: Code Update +```bash +# Get latest code +git pull origin main + +# Verify migration_simple_reset.py exists +ls -la migration_simple_reset.py +``` + +#### Step 3: Execute Migration Reset +```bash +# Complete reset (recommended) +docker compose exec app python migration_simple_reset.py --full +``` + +Or step-by-step execution: +```bash +# Backup only +docker compose exec app python migration_simple_reset.py --backup-only + +# Reset only +docker compose exec app python migration_simple_reset.py --reset-only + +# Apply only +docker compose exec app python migration_simple_reset.py --apply-only +``` + +#### Step 4: Verify Results +```bash +# Check migration status +docker compose exec app python manage.py showmigrations + +# Verify application functionality +docker compose exec app python manage.py check +``` + +#### Step 5: Restart Services +```bash +# Restart application +docker compose restart app + +# Restart all services (if needed) +docker compose restart +``` + +## Troubleshooting + +### Migration Failure Recovery + +```bash +# 1. Clean up with migration_simple_reset.py +docker compose exec app python migration_simple_reset.py --reset-only + +# 2. Manually check migration status +docker compose exec app python manage.py showmigrations + +# 3. Apply individual migrations if needed +docker compose exec app python manage.py migrate rog 0001 --fake +``` + +### Restore from Backup + +```bash +# Database restoration +docker compose exec postgres-db psql -U admin -d rogaining_db < backup_file.sql + +# Migration files restoration +rm -rf rog/migrations +cp -r rog/migrations_backup_deploy_YYYYMMDD_HHMMSS rog/migrations +``` + +## Important Considerations + +### ✅ Pre-execution Checklist +- [ ] Database backup created +- [ ] Migration files backup created +- [ ] migration_simple_reset.py is latest version +- [ ] Docker environment running normally +- [ ] Sufficient disk space available + +### ⚠️ Operations to Avoid +- Running `python manage.py migrate` first (causes dependency errors) +- Working without backups +- Experimental operations in production environment + +### 🔄 Rollback Plan +```bash +# Emergency restoration when issues occur +docker compose down +docker compose exec postgres-db psql -U admin -d rogaining_db < backup_file.sql +cp -r rog/migrations_backup_deploy_YYYYMMDD_HHMMSS rog/migrations +docker compose up -d +``` + +## Summary + +**Recommended Final Procedure:** + +```bash +# 1. Create backup +pg_dump rogaining_db > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. Get latest code +git pull origin main + +# 3. Batch migration reset (avoids issues) +docker compose exec app python migration_simple_reset.py --full + +# 4. Verify functionality +docker compose exec app python manage.py check +docker compose restart app +``` + +This procedure avoids migration dependency issues and enables safe deployment. + +## Command Reference + +### migration_simple_reset.py Options + +```bash +# Complete workflow +python migration_simple_reset.py --full + +# Backup only +python migration_simple_reset.py --backup-only + +# Reset only (requires existing backup) +python migration_simple_reset.py --reset-only + +# Apply only (requires simple migration to exist) +python migration_simple_reset.py --apply-only +``` + +### Docker Compose Commands + +```bash +# Check service status +docker compose ps + +# Execute commands in app container +docker compose exec app [command] + +# Execute commands in database container +docker compose exec postgres-db [command] + +# Restart specific service +docker compose restart [service_name] + +# View logs +docker compose logs [service_name] +``` + +### Database Operations + +```bash +# Create database backup +docker compose exec postgres-db pg_dump -U admin rogaining_db > backup.sql + +# Restore database +docker compose exec postgres-db psql -U admin -d rogaining_db < backup.sql + +# Connect to database shell +docker compose exec postgres-db psql -U admin -d rogaining_db +``` + +## Error Scenarios and Solutions + +### Scenario 1: Migration Dependency Error +**Error**: `NodeNotFoundError: Migration rog.0010_auto_20250827_1510 dependencies reference nonexistent parent node` + +**Solution**: +```bash +docker compose exec app python migration_simple_reset.py --full +``` + +### Scenario 2: Database Connection Error +**Error**: Database connection issues during migration + +**Solution**: +```bash +# Check database status +docker compose ps postgres-db + +# Restart database if needed +docker compose restart postgres-db + +# Wait for database to be ready +docker compose exec postgres-db pg_isready -U admin +``` + +### Scenario 3: Disk Space Issues +**Error**: Insufficient disk space during backup or migration + +**Solution**: +```bash +# Check disk usage +df -h + +# Clean up Docker resources +docker system prune + +# Remove old backups if safe +rm old_backup_files.sql +``` + +### Scenario 4: Permission Issues +**Error**: Permission denied when executing scripts + +**Solution**: +```bash +# Make script executable +chmod +x migration_simple_reset.py + +# Check file ownership +ls -la migration_simple_reset.py + +# Fix ownership if needed +chown user:group migration_simple_reset.py +``` + +## Best Practices + +### 1. Always Create Backups +- Database backup before any migration operation +- Migration files backup for rollback capability +- Configuration files backup + +### 2. Test in Staging Environment +- Verify the migration procedure in staging first +- Test with production-like data volume +- Validate application functionality after migration + +### 3. Monitor During Deployment +- Watch container logs during migration +- Monitor database performance +- Check application health endpoints + +### 4. Document Changes +- Record migration procedure execution +- Note any deviations from standard procedure +- Update deployment documentation + +### 5. Plan for Rollback +- Have clear rollback procedures ready +- Test rollback in staging environment +- Ensure backups are valid and accessible + +This guide ensures safe and reliable deployment of the rogaining_srv application with proper migration handling. diff --git a/MIGRATION_RESET_REPORT.md b/MIGRATION_RESET_REPORT.md new file mode 100644 index 0000000..60232b5 --- /dev/null +++ b/MIGRATION_RESET_REPORT.md @@ -0,0 +1,156 @@ +# Migration Reset - 完了報告書 + +## 実行日時 +2025年8月28日 13:33:05 - 13:43:58 + +## 実行された作業内容 + +### 1. 問題の特定 +- **問題**: Migration 0011_auto_20250827_1459.py が存在しない依存関係 0010_auto_20250827_1510 を参照していた +- **エラー内容**: `NodeNotFoundError: Migration rog.0010_auto_20250827_1510 dependencies reference nonexistent parent node` + +### 2. Migrationリセット作業 + +#### バックアップ作成 +- **バックアップディレクトリ**: `rog/migrations_backup_20250828_042950` +- **内容**: 既存の11個のmigrationファイルをバックアップ + +#### データベース履歴クリア +- **削除レコード数**: 72件の`django_migrations`レコード +- **対象**: `rog`アプリの全migration履歴 + +#### 新しいシンプルなMigration作成 +- **ファイル**: `rog/migrations/0001_simple_initial.py` +- **内容**: Core modelsのみ (managed=True models) + - `CustomUser` + - `Category` + - `NewEvent` + - `Team` + - `Location` + - `Entry` + +### 3. Migration適用結果 + +``` +Operations to perform: + Apply all migrations: admin, auth, contenttypes, knox, rog, sessions +Running migrations: + Applying rog.0001_simple_initial... FAKED + Applying admin.0001_initial... FAKED + Applying admin.0002_logentry_remove_auto_add... OK + Applying admin.0003_logentry_add_action_flag_choices... OK + Applying knox.0001_initial... FAKED + Applying knox.0002_auto_20150916_1425... OK + Applying knox.0003_auto_20150916_1526... OK + Applying knox.0004_authtoken_expires... OK + Applying knox.0005_authtoken_token_key... OK + Applying knox.0006_auto_20160818_0932... OK + Applying knox.0007_auto_20190111_0542... OK + Applying knox.0008_remove_authtoken_salt... OK +``` + +### 4. 最終状態確認 + +#### Migration状態 +``` +admin + [X] 0001_initial + [X] 0002_logentry_remove_auto_add + [X] 0003_logentry_add_action_flag_choices +auth + [X] 0001_initial + [X] 0002_alter_permission_name_max_length + [X] 0003_alter_user_email_max_length + [X] 0004_alter_user_username_opts + [X] 0005_alter_user_last_login_null + [X] 0006_require_contenttypes_0002 + [X] 0007_alter_validators_add_error_messages + [X] 0008_alter_user_username_max_length + [X] 0009_alter_user_last_name_max_length + [X] 0010_alter_group_name_max_length + [X] 0011_update_proxy_permissions + [X] 0012_alter_user_first_name_max_length +contenttypes + [X] 0001_initial + [X] 0002_remove_content_type_name +knox + [X] 0001_initial + [X] 0002_auto_20150916_1425 + [X] 0003_auto_20150916_1526 + [X] 0004_authtoken_expires + [X] 0005_authtoken_token_key + [X] 0006_auto_20160818_0932 + [X] 0007_auto_20190111_0542 + [X] 0008_remove_authtoken_salt +rog + [X] 0001_simple_initial +sessions + [X] 0001_initial +``` + +## 解決されたポイント + +### 1. managed=False modelの除外 +- **問題**: 初期migrationに`managed=False`のモデル(GifuAreas、JpnAdminMainPerf、JpnSubPerf)が含まれていた +- **解決**: これらのモデルを除外したクリーンなmigrationを作成 + +### 2. 依存関係の修正 +- **問題**: 存在しないmigrationへの参照 +- **解決**: 正しい依存関係でmigrationを再構築 + +### 3. コアモデルの確立 +- **成果**: 最低限必要なモデル構造を確立 +- **含有モデル**: ユーザー、イベント、チーム、ロケーション、エントリー + +## 作成されたツール + +### migration_simple_reset.py +- **目的**: Migration reset作業の自動化 +- **機能**: + - バックアップ作成 + - Migration履歴クリア + - シンプルなmigration作成 + - Migration適用 + - 状態確認 + +### 使用方法 +```bash +# 完全なリセット workflow +python migration_simple_reset.py --full + +# バックアップのみ +python migration_simple_reset.py --backup-only + +# リセットのみ +python migration_simple_reset.py --reset-only + +# 適用のみ +python migration_simple_reset.py --apply-only +``` + +## 今後の展開 + +### 1. 追加モデルの段階的追加 +- Geographic models(managed=Falseとして適切に) +- 追加機能用のモデル +- 関連テーブル + +### 2. データ移行 +- 既存データの段階的移行 +- 写真データの整合性確保 +- GPS記録の移行 + +### 3. デプロイメント準備 +- 本番環境での同様作業 +- データベースバックアップ確保 +- ロールバック計画 + +## 結論 + +**✅ Migration混乱の解決に成功** +- 複雑な依存関係問題を解決 +- クリーンなMigration状態を確立 +- 今後の追加開発に向けた基盤を整備 +- デプロイメント時の混乱要因を除去 + +**次のステップ**: 必要に応じて追加モデルを段階的に追加し、データ移行を実行 diff --git a/migration_simple_reset.py b/migration_simple_reset.py new file mode 100755 index 0000000..8e1e4f1 --- /dev/null +++ b/migration_simple_reset.py @@ -0,0 +1,415 @@ +#!/usr/bin/env python +""" +Updated Migration Final Simple Script +==================================== + +This script provides a comprehensive workflow for resetting and rebuilding +Django migrations for the rogaining_srv project using a simplified approach. + +Usage: + python migration_simple_reset.py [options] + +Options: + --backup-only : Only create backup of existing migrations + --reset-only : Only reset migrations (requires backup to exist) + --apply-only : Only apply migrations (requires simple migration to exist) + --full : Run complete workflow (default) + +Features: +- Creates timestamped backup of existing migrations +- Clears migration history from database +- Creates simplified initial migration with only managed models +- Applies migrations with proper error handling +- Provides detailed logging and status reporting +""" + +import os +import sys +import shutil +import datetime +import subprocess +import json +from pathlib import Path + +# Add Django project to path +project_root = Path(__file__).parent +sys.path.insert(0, str(project_root)) + +# Setup Django environment +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + +import django +django.setup() + +from django.core.management import execute_from_command_line +from django.db import connection, transaction +from django.core.management.base import CommandError + +class MigrationManager: + def __init__(self): + self.project_root = Path(__file__).parent + self.migrations_dir = self.project_root / 'rog' / 'migrations' + self.backup_timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + self.backup_dir = self.project_root / f'rog/migrations_backup_{self.backup_timestamp}' + + def log(self, message, level='INFO'): + """Log message with timestamp and level""" + timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + print(f"[{timestamp}] {level}: {message}") + + def run_command(self, command, check=True): + """Execute shell command with logging""" + self.log(f"Executing: {' '.join(command)}") + try: + result = subprocess.run(command, capture_output=True, text=True, check=check) + if result.stdout: + self.log(f"STDOUT: {result.stdout.strip()}") + if result.stderr: + self.log(f"STDERR: {result.stderr.strip()}", 'WARNING') + return result + except subprocess.CalledProcessError as e: + self.log(f"Command failed with exit code {e.returncode}", 'ERROR') + self.log(f"STDOUT: {e.stdout}", 'ERROR') + self.log(f"STDERR: {e.stderr}", 'ERROR') + raise + + def backup_migrations(self): + """Create backup of existing migrations""" + self.log("Creating backup of existing migrations...") + + if not self.migrations_dir.exists(): + self.log("No migrations directory found, creating empty one") + self.migrations_dir.mkdir(parents=True, exist_ok=True) + (self.migrations_dir / '__init__.py').touch() + return + + # Create backup directory + self.backup_dir.mkdir(parents=True, exist_ok=True) + + # Copy all files + for item in self.migrations_dir.iterdir(): + if item.is_file(): + shutil.copy2(item, self.backup_dir) + self.log(f"Backed up: {item.name}") + + self.log(f"Backup completed: {self.backup_dir}") + + def clear_migration_history(self): + """Clear migration history from database""" + self.log("Clearing migration history from database...") + + try: + with connection.cursor() as cursor: + # Check if django_migrations table exists + cursor.execute(""" + SELECT COUNT(*) FROM information_schema.tables + WHERE table_name = 'django_migrations' AND table_schema = 'public' + """) + if cursor.fetchone()[0] == 0: + self.log("django_migrations table does not exist, skipping clear") + return + + # Count existing migrations + cursor.execute("SELECT COUNT(*) FROM django_migrations WHERE app = 'rog'") + count = cursor.fetchone()[0] + self.log(f"Found {count} existing rog migrations") + + # Delete rog migrations + cursor.execute("DELETE FROM django_migrations WHERE app = 'rog'") + self.log(f"Deleted {count} migration records") + + except Exception as e: + self.log(f"Error clearing migration history: {e}", 'ERROR') + raise + + def remove_migration_files(self): + """Remove existing migration files except __init__.py""" + self.log("Removing existing migration files...") + + if not self.migrations_dir.exists(): + return + + removed_count = 0 + for item in self.migrations_dir.iterdir(): + if item.is_file() and item.name != '__init__.py': + item.unlink() + self.log(f"Removed: {item.name}") + removed_count += 1 + + self.log(f"Removed {removed_count} migration files") + + def create_simple_migration(self): + """Create simplified initial migration""" + self.log("Creating simplified initial migration...") + + # Create simple migration content + migration_content = '''# Generated by migration_simple_reset.py +from django.contrib.gis.db import models +from django.contrib.auth.models import AbstractUser +from django.db import migrations +import django.contrib.gis.db.models.fields +import django.core.validators + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(auto_now_add=True, verbose_name='date joined')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50)), + ('description', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name_plural': 'categories', + }, + ), + migrations.CreateModel( + name='NewEvent', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('description', models.TextField(blank=True, null=True)), + ('event_date', models.DateField()), + ('start_time', models.TimeField()), + ('end_time', models.TimeField()), + ('event_boundary', django.contrib.gis.db.models.fields.PolygonField(blank=True, null=True, srid=4326)), + ('max_participants', models.PositiveIntegerField(default=100)), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rog.category')), + ], + ), + migrations.CreateModel( + name='Team', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('max_members', models.PositiveIntegerField(default=5)), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teams', to='rog.newevent')), + ], + ), + migrations.CreateModel( + name='Location', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('description', models.TextField(blank=True, null=True)), + ('coordinate', django.contrib.gis.db.models.fields.PointField(srid=4326)), + ('altitude', models.FloatField(blank=True, null=True)), + ('location_type', models.CharField(choices=[('checkpoint', 'Checkpoint'), ('start', 'Start Point'), ('finish', 'Finish Point'), ('water', 'Water Station'), ('emergency', 'Emergency Point'), ('viewpoint', 'View Point'), ('other', 'Other')], default='checkpoint', max_length=20)), + ('points', models.IntegerField(default=0)), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='rog.newevent')), + ], + ), + migrations.CreateModel( + name='Entry', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('role', models.CharField(choices=[('leader', 'Team Leader'), ('member', 'Team Member')], default='member', max_length=10)), + ('joined_at', models.DateTimeField(auto_now_add=True)), + ('is_active', models.BooleanField(default=True)), + ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='entries', to='rog.team')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.customuser')), + ], + options={ + 'verbose_name_plural': 'entries', + 'unique_together': {('user', 'team')}, + }, + ), + ] +''' + + # Write migration file + migration_file = self.migrations_dir / '0001_simple_initial.py' + with open(migration_file, 'w', encoding='utf-8') as f: + f.write(migration_content) + + self.log(f"Created: {migration_file}") + + def apply_migrations(self): + """Apply migrations using Django management command""" + self.log("Applying migrations...") + + try: + # Use fake-initial to treat as initial migration + result = self.run_command([ + 'python', 'manage.py', 'migrate', '--fake-initial' + ], check=False) + + if result.returncode == 0: + self.log("Migrations applied successfully") + else: + self.log("Migration application failed", 'ERROR') + raise CommandError("Migration application failed") + + except Exception as e: + self.log(f"Error applying migrations: {e}", 'ERROR') + raise + + def check_status(self): + """Check current migration status""" + self.log("Checking migration status...") + + try: + result = self.run_command([ + 'python', 'manage.py', 'showmigrations', 'rog' + ], check=False) + + if result.returncode == 0: + self.log("Migration status checked successfully") + else: + self.log("Failed to check migration status", 'WARNING') + + except Exception as e: + self.log(f"Error checking migration status: {e}", 'WARNING') + + def run_full_workflow(self): + """Execute complete migration reset workflow""" + self.log("Starting full migration reset workflow...") + + try: + # Step 1: Backup existing migrations + self.backup_migrations() + + # Step 2: Clear migration history + self.clear_migration_history() + + # Step 3: Remove migration files + self.remove_migration_files() + + # Step 4: Create simplified migration + self.create_simple_migration() + + # Step 5: Apply migrations + self.apply_migrations() + + # Step 6: Check final status + self.check_status() + + self.log("Full migration reset workflow completed successfully!") + self.log(f"Backup created at: {self.backup_dir}") + + except Exception as e: + self.log(f"Workflow failed: {e}", 'ERROR') + self.log(f"You can restore from backup at: {self.backup_dir}", 'INFO') + raise + + def run_backup_only(self): + """Create backup only""" + self.log("Running backup-only mode...") + self.backup_migrations() + self.log("Backup completed successfully!") + + def run_reset_only(self): + """Reset migrations only (requires backup)""" + self.log("Running reset-only mode...") + self.clear_migration_history() + self.remove_migration_files() + self.create_simple_migration() + self.log("Reset completed successfully!") + + def run_apply_only(self): + """Apply migrations only""" + self.log("Running apply-only mode...") + self.apply_migrations() + self.check_status() + self.log("Apply completed successfully!") + + +def main(): + """Main function with command line argument handling""" + import argparse + + parser = argparse.ArgumentParser( + description='Reset and rebuild Django migrations for rogaining_srv project' + ) + parser.add_argument( + '--backup-only', + action='store_true', + help='Only create backup of existing migrations' + ) + parser.add_argument( + '--reset-only', + action='store_true', + help='Only reset migrations (requires backup to exist)' + ) + parser.add_argument( + '--apply-only', + action='store_true', + help='Only apply migrations (requires simple migration to exist)' + ) + parser.add_argument( + '--full', + action='store_true', + help='Run complete workflow (default)' + ) + + args = parser.parse_args() + + # If no specific mode is selected, default to full + if not any([args.backup_only, args.reset_only, args.apply_only, args.full]): + args.full = True + + manager = MigrationManager() + + try: + if args.backup_only: + manager.run_backup_only() + elif args.reset_only: + manager.run_reset_only() + elif args.apply_only: + manager.run_apply_only() + elif args.full: + manager.run_full_workflow() + + except Exception as e: + print(f"\nError: {e}") + print("Please check the logs above for details.") + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/reset_migrations_simple.py b/reset_migrations_simple.py new file mode 100644 index 0000000..80d4f76 --- /dev/null +++ b/reset_migrations_simple.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python +""" +Migration ファイルをシンプルにリセットするスクリプト + +使用方法: +1. 現在のmigrationテーブルの状態をバックアップ +2. migrationファイルを削除 +3. 新しいシンプルなmigrationファイルを作成 +4. データベースのmigration履歴をリセット +""" + +import os +import shutil +from datetime import datetime + +def backup_migrations(): + """現在のmigrationファイルをバックアップ""" + migrations_dir = "rog/migrations" + backup_dir = f"rog/migrations_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}" + + if os.path.exists(migrations_dir): + shutil.copytree(migrations_dir, backup_dir) + print(f"Migrationファイルを {backup_dir} にバックアップしました") + +def reset_migrations(): + """migrationファイルをリセット""" + migrations_dir = "rog/migrations" + + # __init__.py以外のファイルを削除 + if os.path.exists(migrations_dir): + for file in os.listdir(migrations_dir): + if file != "__init__.py" and file.endswith(".py"): + os.remove(os.path.join(migrations_dir, file)) + print(f"削除: {file}") + +def create_simple_initial_migration(): + """シンプルな初期migrationファイルを作成""" + migration_content = '''# -*- coding: utf-8 -*- +# Generated by reset_migrations_simple.py + +from django.conf import settings +from django.db import migrations, models +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +import django.db.models.deletion +import django.utils.timezone +import rog.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + # 基本的なモデルのみ作成(順番に依存関係を考慮) + + # 1. 地理情報テーブル(managed=False) + migrations.CreateModel( + name='GifuAreas', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('area_nm', models.CharField(blank=True, max_length=254, null=True)), + ], + options={ + 'db_table': 'gifu_areas', + 'managed': False, + }, + ), + + migrations.CreateModel( + name='JpnAdminMainPerf', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ], + options={ + 'db_table': 'jpn_admin_main_perf', + 'managed': False, + }, + ), + + migrations.CreateModel( + name='JpnSubPerf', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('name_modified', models.CharField(blank=True, max_length=254, null=True)), + ('area_name', models.CharField(blank=True, max_length=254, null=True)), + ('list_order', models.IntegerField(default=0)), + ], + options={ + 'db_table': 'jpn_sub_perf', + 'managed': False, + }, + ), + + # 2. ユーザー関連モデル + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=254, unique=True)), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('group', models.CharField(blank=True, max_length=255)), + ('is_active', models.BooleanField(default=True)), + ('is_staff', models.BooleanField(default=False)), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now)), + ('is_rogaining', models.BooleanField(default=False)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'abstract': False, + }, + ), + + # 3. カテゴリモデル + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('category_name', models.CharField(max_length=255, verbose_name='カテゴリ名')), + ('parent_category', models.CharField(blank=True, max_length=255, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + + # 4. イベント関連モデル + migrations.CreateModel( + name='NewEvent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=255, verbose_name='イベントコード')), + ('event_name', models.CharField(max_length=255, verbose_name='イベント名')), + ('event_date', models.DateField(verbose_name='イベント日')), + ('start_time', models.TimeField(blank=True, null=True, verbose_name='開始時刻')), + ('end_time', models.TimeField(blank=True, null=True, verbose_name='終了時刻')), + ('description', models.TextField(blank=True, null=True, verbose_name='説明')), + ('is_active', models.BooleanField(default=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('category', models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, to='rog.category')), + ], + options={ + 'db_table': 'rog_newevent', + }, + ), + + # 5. チーム関連モデル + migrations.CreateModel( + name='Team', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('team_name', models.CharField(max_length=255, verbose_name='チーム名')), + ('team_member_num', models.IntegerField(blank=True, default=1, null=True, verbose_name='チーム人数')), + ('score', models.IntegerField(blank=True, default=0, null=True, verbose_name='スコア')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent')), + ], + options={ + 'db_table': 'rog_team', + }, + ), + + # 6. ロケーション関連モデル(基本的なもの) + migrations.CreateModel( + name='Location', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, db_index=True, null=True, verbose_name='Location id')), + ('sub_loc_id', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id')), + ('cp', models.FloatField(blank=False, default=0, null=True, verbose_name='Check Point')), + ('location_name', models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name')), + ('category', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Category')), + ('subcategory', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=2048, null=True, verbose_name='City')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('photos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos')), + ('videos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_updated_user', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'rog_location', + }, + ), + + # 7. エントリー関連モデル + migrations.CreateModel( + name='Entry', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_time', models.DateTimeField(blank=True, null=True, verbose_name='Start time')), + ('goal_time', models.DateTimeField(blank=True, null=True, verbose_name='Goal time')), + ('check_point', models.IntegerField(blank=True, null=True, verbose_name='Check Point')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location')), + ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team')), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='entry_updated_user', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'db_table': 'rog_entry', + }, + ), + + # インデックスの追加 + migrations.AddIndex( + model_name='gifu_areas', + index=models.Index(fields=['geom'], name='gifu_areas_geom_idx'), + ), + ] +''' + + with open("rog/migrations/0001_simple_initial.py", "w", encoding="utf-8") as f: + f.write(migration_content) + + print("シンプルな初期migrationファイル 0001_simple_initial.py を作成しました") + +def main(): + print("=== Migration リセットスクリプト ===") + print("1. Migrationファイルをバックアップします") + backup_migrations() + + print("\\n2. 既存のmigrationファイルを削除します") + reset_migrations() + + print("\\n3. シンプルな初期migrationファイルを作成します") + create_simple_initial_migration() + + print("\\n=== 完了 ===") + print("次の手順:") + print("1. docker compose exec app python manage.py migrate --fake-initial") + print("2. 必要に応じて追加のmigrationファイルを作成") + +if __name__ == "__main__": + main() diff --git a/rog/migrations_backup_20250828_042950/0001_initial.py b/rog/migrations_backup_20250828_042950/0001_initial.py new file mode 100755 index 0000000..e401670 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0001_initial.py @@ -0,0 +1,847 @@ +# Generated by Django 3.2.9 on 2025-05-13 08:22 + +import datetime +from django.conf import settings +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import rog.models +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='GifuAreas', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('area_nm', models.CharField(blank=True, max_length=254, null=True)), + ], + options={ + 'db_table': 'gifu_areas', + 'managed': False, + }, + ), + migrations.CreateModel( + name='JpnAdminMainPerf', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ], + options={ + 'db_table': 'jpn_admin_main_perf', + 'managed': False, + }, + ), + migrations.CreateModel( + name='JpnSubPerf', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('name_modified', models.CharField(blank=True, max_length=254, null=True)), + ('area_name', models.CharField(blank=True, max_length=254, null=True)), + ('list_order', models.IntegerField(default=0)), + ], + options={ + 'db_table': 'jpn_sub_perf', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=254, unique=True)), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('group', models.CharField(blank=True, max_length=255)), + ('is_active', models.BooleanField(default=True)), + ('is_staff', models.BooleanField(default=False)), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now)), + ('is_rogaining', models.BooleanField(default=False)), + ('zekken_number', models.CharField(blank=True, max_length=255, null=True, verbose_name='Zekken Number')), + ('event_code', models.CharField(blank=True, max_length=255, null=True, verbose_name='Event Code')), + ('team_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Team Name')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Category', + fields=[ + ('category_name', models.CharField(max_length=255, primary_key=True, serialize=False)), + ('category_number', models.IntegerField(default=0)), + ('duration', models.DurationField(default=datetime.timedelta(seconds=18000))), + ('num_of_member', models.IntegerField(default=1)), + ('family', models.BooleanField(default=False)), + ('female', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='CheckinImages', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('checkinimage', models.FileField(blank=True, null=True, upload_to='checkin/%y%m%d')), + ('checkintime', models.DateTimeField(verbose_name='Goal time')), + ('team_name', models.CharField(max_length=255, verbose_name='Team name')), + ('event_code', models.CharField(max_length=255, verbose_name='event code')), + ('cp_number', models.IntegerField(verbose_name='CP numner')), + ], + ), + migrations.CreateModel( + name='CheckPoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cp_number', models.CharField(max_length=20)), + ('image_address', models.URLField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(auto_now_add=True)), + ('is_service_checked', models.BooleanField(default=False)), + ], + options={ + 'ordering': ['checkin_time'], + }, + ), + migrations.CreateModel( + name='Entry', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField()), + ('zekken_number', models.IntegerField(default=0)), + ('is_active', models.BooleanField(default=True)), + ('hasParticipated', models.BooleanField(default=False)), + ('hasGoaled', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='EntryMember', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_temporary', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tagname', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('status', models.CharField(choices=[('PREPARING', 'Preparing'), ('PROMOTION', 'Promotion'), ('EVENT', 'Event'), ('END', 'End')], max_length=256)), + ('price', models.IntegerField(default=0, verbose_name='Paid Amount')), + ('promotion_date', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')), + ('event_start', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')), + ('event_end', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')), + ('remark', models.CharField(blank=True, max_length=256, null=True)), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='EventUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.CreateModel( + name='Favorite', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('good', models.IntegerField(default=0, verbose_name='Good')), + ('favorite', models.IntegerField(default=0, verbose_name='Favorite')), + ('evaluation', models.IntegerField(default=0, verbose_name='Evaluation')), + ('number_visit', models.IntegerField(default=0, verbose_name='Good')), + ('last_visited', models.DateTimeField(blank=True, null=True, verbose_name='Last Visited')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='GifurogeRegister', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=100)), + ('time', models.IntegerField(choices=[(3, '3時間'), (5, '5時間')])), + ('owner_name_kana', models.CharField(max_length=100)), + ('owner_name', models.CharField(max_length=100)), + ('email', models.EmailField(max_length=254)), + ('password', models.CharField(max_length=100)), + ('owner_birthday', models.DateField(blank=True, null=True)), + ('owner_sex', models.CharField(blank=True, max_length=10, null=True)), + ('team_name', models.CharField(max_length=100)), + ('department', models.CharField(max_length=100)), + ('members_count', models.IntegerField()), + ('member2', models.CharField(blank=True, max_length=100, null=True)), + ('birthday2', models.DateField(blank=True, null=True)), + ('sex2', models.CharField(blank=True, max_length=10, null=True)), + ('member3', models.CharField(blank=True, max_length=100, null=True)), + ('birthday3', models.DateField(blank=True, null=True)), + ('sex3', models.CharField(blank=True, max_length=10, null=True)), + ('member4', models.CharField(blank=True, max_length=100, null=True)), + ('birthday4', models.DateField(blank=True, null=True)), + ('sex4', models.CharField(blank=True, max_length=10, null=True)), + ('member5', models.CharField(blank=True, max_length=100, null=True)), + ('birthday5', models.DateField(blank=True, null=True)), + ('sex5', models.CharField(blank=True, max_length=10, null=True)), + ], + ), + migrations.CreateModel( + name='GoalImages', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('goalimage', models.FileField(blank=True, null=True, upload_to='goals/%y%m%d')), + ('goaltime', models.DateTimeField(blank=True, null=True, verbose_name='Goal time')), + ('team_name', models.CharField(max_length=255, verbose_name='Team name')), + ('event_code', models.CharField(max_length=255, verbose_name='event code')), + ('cp_number', models.IntegerField(verbose_name='CP numner')), + ('zekken_number', models.TextField(blank=True, help_text='ゼッケン番号', null=True)), + ], + ), + migrations.CreateModel( + name='GpsCheckin', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('path_order', models.IntegerField(help_text='チェックポイントの順序番号')), + ('zekken_number', models.TextField(help_text='ゼッケン番号')), + ('event_id', models.IntegerField(blank=True, help_text='イベントID', null=True)), + ('event_code', models.TextField(help_text='イベントコード')), + ('cp_number', models.IntegerField(blank=True, help_text='チェックポイント番号', null=True)), + ('lattitude', models.FloatField(blank=True, help_text='緯度:写真から取得', null=True)), + ('longitude', models.FloatField(blank=True, help_text='経度:写真から取得', null=True)), + ('image_address', models.TextField(blank=True, help_text='チェックイン画像のパス', null=True)), + ('image_receipt', models.TextField(blank=True, default=False, help_text='レシート画像のパス', null=True)), + ('image_qr', models.BooleanField(default=False, help_text='QRコードスキャンフラグ')), + ('validate_location', models.BooleanField(default=False, help_text='位置情報検証フラグ:画像認識で検証した結果')), + ('goal_time', models.TextField(blank=True, help_text='ゴール時刻=ゴール時のみ使用される。画像から時刻を読み取り設定する。', null=True)), + ('late_point', models.IntegerField(blank=True, help_text='遅刻ポイント:ゴールの時刻が制限時間を超えた場合、1分につき-50点が加算。', null=True)), + ('create_at', models.DateTimeField(blank=True, help_text='作成日時:データの作成日時', null=True)), + ('create_user', models.TextField(blank=True, help_text='作成ユーザー', null=True)), + ('update_at', models.DateTimeField(blank=True, help_text='更新日時', null=True)), + ('update_user', models.TextField(blank=True, help_text='更新ユーザー', null=True)), + ('buy_flag', models.BooleanField(default=False, help_text='購入フラグ:協賛店で購入した場合、無条件でTRUEにする。')), + ('colabo_company_memo', models.TextField(default='', help_text='グループコード:複数のイベントで合算する場合に使用する')), + ('points', models.IntegerField(blank=True, help_text='ポイント:このチェックインによる獲得ポイント。通常ポイントと買い物ポイントは分離される。ゴールの場合には減点なども含む。', null=True)), + ], + options={ + 'db_table': 'gps_checkins', + }, + ), + migrations.CreateModel( + name='Location', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, db_index=True, null=True, verbose_name='Location id')), + ('sub_loc_id', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id')), + ('cp', models.FloatField(default=0, null=True, verbose_name='Check Point')), + ('location_name', models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name')), + ('category', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Category')), + ('subcategory', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=2048, null=True, verbose_name='City')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('photos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos')), + ('videos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Tags')), + ('event_name', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Event name')), + ('event_active', models.BooleanField(db_index=True, default=True, verbose_name='Is Event active')), + ('hidden_location', models.BooleanField(default=False, verbose_name='Is Hidden Location')), + ('auto_checkin', models.BooleanField(default=False, verbose_name='Is AutoCheckin')), + ('checkin_radius', models.FloatField(blank=True, default=15.0, null=True, verbose_name='Checkin radious')), + ('checkin_point', models.FloatField(blank=True, default=10, null=True, verbose_name='Checkin Point')), + ('buy_point', models.FloatField(blank=True, default=0, null=True, verbose_name='buy Point')), + ('evaluation_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Evaluation value (評価)')), + ('shop_closed', models.BooleanField(default=False, verbose_name='Shop Closed (休業)')), + ('shop_shutdown', models.BooleanField(default=False, verbose_name='Shop Shutdown (閉業)')), + ('opening_hours_mon', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours monday (月曜)')), + ('opening_hours_tue', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours tuesday (火曜)')), + ('opening_hours_wed', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours wednesday (水曜)')), + ('opening_hours_thu', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours thursday (木曜)')), + ('opening_hours_fri', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours frinday (金曜)')), + ('opening_hours_sat', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours saturday (土曜)')), + ('opening_hours_sun', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours sunday (日曜)')), + ('parammeters', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='NewCategory', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('category_name', models.CharField(max_length=255, unique=True)), + ('category_number', models.IntegerField(default=0)), + ('duration', models.DurationField(default=datetime.timedelta(seconds=18000))), + ('num_of_member', models.IntegerField(default=1)), + ('family', models.BooleanField(default=False)), + ('female', models.BooleanField(default=False)), + ('trial', models.BooleanField(default=False)), + ], + options={ + 'unique_together': {('category_name', 'category_number')}, + }, + ), + migrations.CreateModel( + name='NewEvent', + fields=[ + ('event_name', models.CharField(max_length=255, primary_key=True, serialize=False)), + ('start_datetime', models.DateTimeField(default=django.utils.timezone.now)), + ('end_datetime', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='NewEvent2', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_name', models.CharField(max_length=255, unique=True)), + ('event_description', models.TextField(blank=True, max_length=255, null=True)), + ('start_datetime', models.DateTimeField(default=django.utils.timezone.now)), + ('end_datetime', models.DateTimeField()), + ('deadlineDateTime', models.DateTimeField(blank=True, null=True)), + ('public', models.BooleanField(default=False)), + ('hour_3', models.BooleanField(default=False)), + ('hour_5', models.BooleanField(default=True)), + ('class_general', models.BooleanField(default=True)), + ('class_family', models.BooleanField(default=True)), + ('class_solo_male', models.BooleanField(default=True)), + ('class_solo_female', models.BooleanField(default=True)), + ('self_rogaining', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='ShapeFileLocations', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('shapefile', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Shapelayer')), + ('locid', models.IntegerField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name='ShapeLayers', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='Shape Layer')), + ('file', models.FileField(blank=True, upload_to=rog.models.get_file_path)), + ('uploaded_date', models.DateField(auto_now_add=True)), + ('layerof', models.IntegerField(choices=[(1, 'templocation'), (2, 'Location_line'), (3, 'Location_polygon')], default=1)), + ('table_name', models.CharField(blank=True, max_length=255, verbose_name='Table name')), + ], + ), + migrations.CreateModel( + name='TempUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email', models.EmailField(max_length=254, unique=True)), + ('password', models.CharField(max_length=128)), + ('is_rogaining', models.BooleanField(default=False)), + ('zekken_number', models.CharField(blank=True, max_length=255, null=True)), + ('event_code', models.CharField(blank=True, max_length=255, null=True)), + ('team_name', models.CharField(blank=True, max_length=255, null=True)), + ('group', models.CharField(max_length=255)), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('verification_code', models.UUIDField(default=uuid.uuid4, editable=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('expires_at', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='TestModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('testbane', models.CharField(max_length=355, verbose_name='test field')), + ('wanttogo', models.BooleanField(default=False)), + ('like', models.BooleanField(default=False)), + ('checkin', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='TravelList', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('travel_id', models.IntegerField(verbose_name='Travel Id')), + ('start_date', models.DateTimeField(blank=True, null=True, verbose_name='Start date')), + ('finish_date', models.DateTimeField(blank=True, null=True, verbose_name='End date')), + ('category', models.CharField(choices=[('PRIVATE', 'Private'), ('GROUP', 'Group'), ('AGENT', 'Agent'), ('ROGAINING', 'Rogaining')], max_length=256)), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('transportation', models.CharField(blank=True, max_length=255, null=True, verbose_name='Transpotation')), + ('moving_distance', models.IntegerField(blank=True, null=True)), + ('duration', models.DurationField(blank=True, null=True, verbose_name='Duration')), + ('eta', models.DateTimeField(blank=True, null=True)), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='travel_list_updated_user', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='UserUpload', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='User uploads')), + ('file', models.FileField(blank=True, upload_to=rog.models.get_file_path)), + ('uploaded_date', models.DateField(auto_now_add=True)), + ], + ), + migrations.CreateModel( + name='UserUploadUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('userfile', models.CharField(blank=True, max_length=2048, null=True, verbose_name='User file')), + ('email', models.CharField(max_length=255, verbose_name='User Email')), + ], + ), + migrations.CreateModel( + name='Waypoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('latitude', models.FloatField()), + ('longitude', models.FloatField()), + ('altitude', models.FloatField(blank=True, null=True)), + ('accuracy', models.FloatField(blank=True, null=True)), + ('speed', models.FloatField(blank=True, null=True)), + ('recorded_at', models.DateTimeField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('entry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='waypoints', to='rog.entry')), + ], + options={ + 'ordering': ['recorded_at'], + }, + ), + migrations.CreateModel( + name='UserTracks', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Useractions', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('wanttogo', models.BooleanField(default=False)), + ('like', models.BooleanField(default=False)), + ('checkin', models.BooleanField(default=False)), + ('checkinimage', models.FileField(blank=True, null=True, upload_to='%y%m%d')), + ('order', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='action_location', to='rog.location')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='action_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='TravelPoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('distance', models.FloatField(blank=True, null=True)), + ('transportation', models.CharField(blank=True, max_length=255, null=True, verbose_name='Transpotation')), + ('eta', models.DateTimeField(blank=True, null=True)), + ('order_number', models.IntegerField(blank=True, null=True)), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='travelpoint_updated_user', to=settings.AUTH_USER_MODEL)), + ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location')), + ('travel_list', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='rog.travellist')), + ], + ), + migrations.CreateModel( + name='templocation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')), + ('sub_loc_id', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id')), + ('cp', models.FloatField(default=0, null=True, verbose_name='Check Point')), + ('location_name', models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name')), + ('category', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Category')), + ('subcategory', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=2048, null=True, verbose_name='City')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('photos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos')), + ('videos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Tags')), + ('event_name', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Event name')), + ('event_active', models.BooleanField(default=True, verbose_name='Is Event active')), + ('hidden_location', models.BooleanField(default=False, verbose_name='Is Hidden Location')), + ('auto_checkin', models.BooleanField(default=False, verbose_name='Is AutoCheckin')), + ('checkin_radius', models.FloatField(blank=True, default=15.0, null=True, verbose_name='Checkin radious')), + ('checkin_point', models.FloatField(blank=True, default=10, null=True, verbose_name='Checkin Point')), + ('buy_point', models.FloatField(blank=True, default=0, null=True, verbose_name='buy Point')), + ('evaluation_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Evaluation value (評価)')), + ('shop_closed', models.BooleanField(default=False, verbose_name='Shop Closed (休業)')), + ('shop_shutdown', models.BooleanField(default=False, verbose_name='Shop Shutdown (閉業)')), + ('opening_hours_mon', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours monday (月曜)')), + ('opening_hours_tue', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours tuesday (火曜)')), + ('opening_hours_wed', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours wednesday (水曜)')), + ('opening_hours_thu', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours thursday (木曜)')), + ('opening_hours_fri', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours frinday (金曜)')), + ('opening_hours_sat', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours saturday (土曜)')), + ('opening_hours_sun', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours sunday (日曜)')), + ('parammeters', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='temp_location_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='TeamStart', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_time', models.DateTimeField(auto_now_add=True)), + ('entry', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='start_info', to='rog.entry')), + ], + ), + migrations.CreateModel( + name='TeamGoal', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('goal_time', models.DateTimeField()), + ('image_url', models.URLField(blank=True, null=True)), + ('score', models.IntegerField(default=0)), + ('scoreboard_url', models.URLField(blank=True, null=True)), + ('entry', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='goal_info', to='rog.entry')), + ], + ), + migrations.CreateModel( + name='Team', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('team_name', models.CharField(max_length=255)), + ('category', models.ForeignKey(default=rog.models.get_default_category, on_delete=django.db.models.deletion.SET_DEFAULT, to='rog.newcategory')), + ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owned_teams', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='SystemSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('setting_name', models.CharField(max_length=255, verbose_name='Settings Name')), + ('version', models.CharField(blank=True, max_length=10, null=True, verbose_name='Version')), + ('effective_date', models.DateTimeField()), + ('end_date', models.DateTimeField()), + ('parammeters', models.CharField(max_length=512, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='system_setting_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='RogUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('phone', models.CharField(max_length=55, verbose_name='Phone Number')), + ('first_name', models.CharField(max_length=255, verbose_name='First Name')), + ('middle_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Middle Name')), + ('last_name', models.CharField(max_length=255, verbose_name='last_name')), + ('nickname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Nickname')), + ('country', models.CharField(default='Japan', max_length=255, verbose_name='Country')), + ('language', models.CharField(default='Japanese', max_length=255, verbose_name='Language')), + ('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')), + ('sex', models.CharField(blank=True, default='unknown', max_length=255, null=True, verbose_name='Sex')), + ('birthyear', models.IntegerField(blank=True, null=True, verbose_name='Birth year')), + ('family_structure', models.IntegerField(blank=True, null=True, verbose_name='Family Structure')), + ('level', models.IntegerField(blank=True, default=0, null=True, verbose_name='Level')), + ('paid', models.BooleanField(default=False, verbose_name='Is Paid')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('introducer', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='introduced_uesr', to=settings.AUTH_USER_MODEL)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='roguser_updated_user', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Member', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('is_temporary', models.BooleanField(default=False)), + ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='members', to='rog.team')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Location_polygon', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')), + ('location_name', models.CharField(max_length=255, verbose_name='Location Name')), + ('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')), + ('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')), + ('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_polygon_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Location_line', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')), + ('location_name', models.CharField(max_length=255, verbose_name='Location Name')), + ('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')), + ('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')), + ('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiLineStringField(blank=True, null=True, srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_line_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='JoinedEvent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tagname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Tag Name')), + ('status', models.CharField(choices=[('REGISTERED', 'Registered'), ('ACCEPTED', 'accepted'), ('PAID', 'paid'), ('JOINED', 'joined'), ('CANCELED', 'Canceled')], max_length=256)), + ('registrationid', models.CharField(max_length=56, verbose_name='Registration Id')), + ('payment_code', models.CharField(max_length=255, verbose_name='Payment Code')), + ('paid', models.IntegerField(default=0, verbose_name='Paid Amount')), + ('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remark')), + ('parammeters', models.CharField(max_length=512, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='joined_event_updated_user', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['zekken_number', 'event_code', 'path_order'], name='idx_zekken_event'), + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['create_at'], name='idx_create_at'), + ), + migrations.AddField( + model_name='goalimages', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='favorite', + name='last_updated_user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='favorite_updated_user', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='favorite', + name='location', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location'), + ), + migrations.AddField( + model_name='favorite', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='eventuser', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='event', to='rog.event'), + ), + migrations.AddField( + model_name='eventuser', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='event', + name='last_updated_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='event_updated_user', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='event', + name='user', + field=models.ManyToManyField(related_name='even', through='rog.EventUser', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='entrymember', + name='entry', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.entry'), + ), + migrations.AddField( + model_name='entrymember', + name='member', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.member'), + ), + migrations.AddField( + model_name='entry', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newcategory'), + ), + migrations.AddField( + model_name='entry', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2'), + ), + migrations.AddField( + model_name='entry', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='entry', + name='team', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team'), + ), + migrations.AddField( + model_name='checkpoint', + name='entry', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='checkpoints', to='rog.entry'), + ), + migrations.AddField( + model_name='checkinimages', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), + migrations.AlterUniqueTogether( + name='category', + unique_together={('category_name', 'category_number')}, + ), + migrations.AddField( + model_name='customuser', + name='groups', + field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'), + ), + migrations.AddField( + model_name='customuser', + name='user_permissions', + field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'), + ), + migrations.AddIndex( + model_name='waypoint', + index=models.Index(fields=['entry', 'recorded_at'], name='rog_waypoin_entry_i_fb2cb5_idx'), + ), + migrations.AlterUniqueTogether( + name='member', + unique_together={('team', 'user')}, + ), + migrations.AddIndex( + model_name='location', + index=django.contrib.postgres.indexes.GistIndex(fields=['geom'], name='rog_locatio_geom_4793cc_gist'), + ), + migrations.AlterUniqueTogether( + name='entrymember', + unique_together={('entry', 'member')}, + ), + migrations.AlterUniqueTogether( + name='entry', + unique_together={('zekken_number', 'event', 'date')}, + ), + migrations.AlterUniqueTogether( + name='checkpoint', + unique_together={('entry', 'cp_number')}, + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0002_integration_update.py b/rog/migrations_backup_20250828_042950/0002_integration_update.py new file mode 100644 index 0000000..14958fc --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0002_integration_update.py @@ -0,0 +1,179 @@ +# Generated by manual creation for database integration on 2025-08-20 + +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0001_initial'), + ] + + operations = [ + # Create Checkpoint model first (required by other operations) + migrations.CreateModel( + name='Checkpoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cp_number', models.IntegerField()), + ('cp_name', models.CharField(blank=True, max_length=200, null=True)), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), + ('photo_point', models.IntegerField(default=0)), + ('buy_point', models.IntegerField(default=0)), + ('sample_photo', models.CharField(blank=True, max_length=500, null=True)), + ('colabo_company_memo', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True, blank=True, null=True)), + ('updated_at', models.DateTimeField(auto_now=True, blank=True, null=True)), + ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2')), + ], + ), + + # Create GpsLog model for MobServer integration + migrations.CreateModel( + name='GpsLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('serial_number', models.IntegerField()), + ('zekken_number', models.TextField()), + ('event_code', models.TextField()), + ('cp_number', models.TextField(blank=True, null=True)), + ('image_address', models.TextField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(auto_now_add=True)), + ('goal_time', models.TextField(blank=True, null=True)), + ('late_point', models.IntegerField(blank=True, null=True)), + ('create_at', models.DateTimeField(blank=True, null=True)), + ('create_user', models.TextField(blank=True, null=True)), + ('update_at', models.DateTimeField(blank=True, null=True)), + ('update_user', models.TextField(blank=True, null=True)), + ('buy_flag', models.BooleanField(blank=True, null=True)), + ('minus_photo_flag', models.BooleanField(blank=True, null=True)), + ('colabo_company_memo', models.TextField(default='')), + ('is_service_checked', models.BooleanField(default=False)), + ('score', models.IntegerField(blank=True, default=0, null=True)), + ('scoreboard_url', models.URLField(blank=True, null=True)), + ], + options={ + 'db_table': 'gps_information', + }, + ), + + # Add fields to GpsCheckin model + migrations.AddField( + model_name='gpscheckin', + name='checkpoint', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.checkpoint'), + ), + migrations.AddField( + model_name='gpscheckin', + name='minus_photo_flag', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='serial_number', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='team', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.team'), + ), + + # Add fields to NewEvent2 model + migrations.AddField( + model_name='newevent2', + name='event_code', + field=models.CharField(blank=True, max_length=50, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='event_day', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='start_time', + field=models.TimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='venue_address', + field=models.CharField(blank=True, max_length=500, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='venue_location', + field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326), + ), + + # Add fields to Team model + migrations.AddField( + model_name='team', + name='class_name', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='team', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2'), + ), + migrations.AddField( + model_name='team', + name='location', + field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326), + ), + migrations.AddField( + model_name='team', + name='password', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='team', + name='trial', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='team', + name='zekken_number', + field=models.CharField(blank=True, max_length=50, null=True), + ), + + # Add constraints for Checkpoint model + migrations.AddConstraint( + model_name='checkpoint', + constraint=models.UniqueConstraint(fields=['cp_number', 'event'], name='unique_cp_per_event'), + ), + + # Create indexes (use appropriate operator classes) + migrations.AddIndex( + model_name='checkpoint', + index=models.Index(fields=['event', 'cp_number'], name='idx_checkpoint_event_cp'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['serial_number'], name='gps_informa_serial__77a095_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['zekken_number'], name='gps_informa_zekken__01b27e_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['event_code'], name='gps_informa_event_c_2ab906_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['cp_number'], name='gps_informa_cp_numb_97c5c5_idx'), + ), + migrations.AddIndex( + model_name='newevent2', + index=models.Index(fields=['event_code'], name='rog_neweven_event_c_e79a96_idx'), + ), + migrations.AddIndex( + model_name='team', + index=models.Index(fields=['zekken_number'], name='rog_team_zekken__2c50d1_idx'), + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0003_auto_20250821_0112.py b/rog/migrations_backup_20250828_042950/0003_auto_20250821_0112.py new file mode 100644 index 0000000..0657c18 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0003_auto_20250821_0112.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2025-08-20 16:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0002_integration_update'), + ] + + operations = [ + migrations.AlterField( + model_name='newevent2', + name='end_datetime', + field=models.DateTimeField(null=True, blank=True), + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0004_add_team_timestamps.py b/rog/migrations_backup_20250828_042950/0004_add_team_timestamps.py new file mode 100644 index 0000000..32ee022 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0004_add_team_timestamps.py @@ -0,0 +1,26 @@ +# Generated manually on 2025-08-21 +# Add only required timestamp fields to Team model + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0003_auto_20250821_0112'), + ] + + operations = [ + migrations.AddField( + model_name='team', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + migrations.AddField( + model_name='team', + name='updated_at', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0005_create_gps_tables.py b/rog/migrations_backup_20250828_042950/0005_create_gps_tables.py new file mode 100644 index 0000000..22f3df5 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0005_create_gps_tables.py @@ -0,0 +1,74 @@ +# Generated manually on 2025-08-21 08:25 + +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0004_add_team_timestamps'), + ] + + operations = [ + # Create GpsCheckin model + migrations.CreateModel( + name='GpsCheckin', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=50)), + ('zekken', models.CharField(max_length=20)), + ('serial_number', models.CharField(max_length=50)), + ('cp_number', models.CharField(blank=True, max_length=20, null=True)), + ('lat', models.FloatField(blank=True, null=True)), + ('lng', models.FloatField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(blank=True, null=True)), + ('record_time', models.DateTimeField(blank=True, null=True)), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), + ('mobserver_id', models.IntegerField(blank=True, null=True)), + ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_checkins', to='rog.newevent2')), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_checkins', to='rog.team')), + ('checkpoint', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_checkins', to='rog.checkpoint')), + ], + options={ + 'db_table': 'rog_gpscheckin', + 'indexes': [ + models.Index(fields=['event_code'], name='rog_gpschec_event_c_9f1a75_idx'), + models.Index(fields=['zekken'], name='rog_gpschec_zekken_8e7f42_idx'), + models.Index(fields=['serial_number'], name='rog_gpschec_serial__1b5e3a_idx'), + models.Index(fields=['cp_number'], name='rog_gpschec_cp_numb_d7c8e5_idx'), + ], + }, + ), + + # Create GpsLog model + migrations.CreateModel( + name='GpsLog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=50)), + ('zekken', models.CharField(max_length=20)), + ('serial_number', models.CharField(max_length=50)), + ('cp_number', models.CharField(blank=True, max_length=20, null=True)), + ('lat', models.FloatField(blank=True, null=True)), + ('lng', models.FloatField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(blank=True, null=True)), + ('record_time', models.DateTimeField(blank=True, null=True)), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), + ('mobserver_id', models.IntegerField(blank=True, null=True)), + ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_logs', to='rog.newevent2')), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_logs', to='rog.team')), + ('checkpoint', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_logs', to='rog.checkpoint')), + ], + options={ + 'db_table': 'rog_gpslog', + 'indexes': [ + models.Index(fields=['event_code'], name='rog_gpslog_event_c_8a2b94_idx'), + models.Index(fields=['zekken'], name='rog_gpslog_zekken_7c5f39_idx'), + models.Index(fields=['serial_number'], name='rog_gpslog_serial__6d4e28_idx'), + models.Index(fields=['cp_number'], name='rog_gpslog_cp_numb_5b3a17_idx'), + ], + }, + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0006_create_location2025_only.py b/rog/migrations_backup_20250828_042950/0006_create_location2025_only.py new file mode 100644 index 0000000..a1a8a78 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0006_create_location2025_only.py @@ -0,0 +1,532 @@ +# Generated by Django 3.2.9 on 2025-08-24 00:29 + +from django.conf import settings +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0005_create_gps_tables'), + ] + + operations = [ + migrations.CreateModel( + name='Location2025', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cp_number', models.IntegerField(db_index=True, verbose_name='CP番号')), + ('cp_name', models.CharField(max_length=255, verbose_name='CP名')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='緯度')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='経度')), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='位置')), + ('cp_point', models.IntegerField(default=10, verbose_name='チェックポイント得点')), + ('photo_point', models.IntegerField(default=0, verbose_name='写真ポイント')), + ('buy_point', models.IntegerField(default=0, verbose_name='買い物ポイント')), + ('checkin_radius', models.FloatField(default=15.0, verbose_name='チェックイン範囲(m)')), + ('auto_checkin', models.BooleanField(default=False, verbose_name='自動チェックイン')), + ('shop_closed', models.BooleanField(default=False, verbose_name='休業中')), + ('shop_shutdown', models.BooleanField(default=False, verbose_name='閉業')), + ('opening_hours', models.TextField(blank=True, null=True, verbose_name='営業時間')), + ('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='住所')), + ('phone', models.CharField(blank=True, max_length=32, null=True, verbose_name='電話番号')), + ('website', models.URLField(blank=True, null=True, verbose_name='ウェブサイト')), + ('description', models.TextField(blank=True, null=True, verbose_name='説明')), + ('is_active', models.BooleanField(db_index=True, default=True, verbose_name='有効')), + ('sort_order', models.IntegerField(default=0, verbose_name='表示順')), + ('csv_source_file', models.CharField(blank=True, max_length=255, null=True, verbose_name='CSVファイル名')), + ('csv_upload_date', models.DateTimeField(blank=True, null=True, verbose_name='CSVアップロード日時')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='作成日時')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新日時')), + ], + options={ + 'verbose_name': 'チェックポイント2025', + 'verbose_name_plural': 'チェックポイント2025', + 'db_table': 'rog_location2025', + 'ordering': ['event', 'sort_order', 'cp_number'], + }, + ), + + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_event_c_9f1a75_idx', + ), + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_zekken_8e7f42_idx', + ), + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_serial__1b5e3a_idx', + ), + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_cp_numb_d7c8e5_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_event_c_8a2b94_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_zekken_7c5f39_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_serial__6d4e28_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_cp_numb_5b3a17_idx', + ), + migrations.RemoveIndex( + model_name='newevent2', + name='rog_neweven_event_c_e79a96_idx', + ), + migrations.RemoveIndex( + model_name='team', + name='rog_team_zekken__2c50d1_idx', + ), + migrations.RenameField( + model_name='gpslog', + old_name='record_time', + new_name='create_at', + ), + migrations.RenameField( + model_name='gpslog', + old_name='mobserver_id', + new_name='late_point', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='checkin_time', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='event', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='lat', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='lng', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='location', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='mobserver_id', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='record_time', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='zekken', + ), + + migrations.AddField( + model_name='gpscheckin', + name='buy_flag', + field=models.BooleanField(default=False, help_text='購入フラグ:協賛店で購入した場合、無条件でTRUEにする。'), + ), + migrations.AddField( + model_name='gpscheckin', + name='colabo_company_memo', + field=models.TextField(default='', help_text='グループコード:複数のイベントで合算する場合に使用する'), + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'create_at' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN create_at TIMESTAMP WITH TIME ZONE; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS create_at CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'create_user' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN create_user TEXT; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS create_user CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'event_id' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN event_id INTEGER; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS event_id CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'goal_time' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN goal_time TEXT; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS goal_time CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'image_address' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN image_address TEXT; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS image_address CASCADE;" + ), + migrations.AddField( + model_name='gpscheckin', + name='image_qr', + field=models.BooleanField(default=False, help_text='QRコードスキャンフラグ'), + ), + migrations.AddField( + model_name='gpscheckin', + name='image_receipt', + field=models.TextField(blank=True, default=False, help_text='レシート画像のパス', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='late_point', + field=models.IntegerField(blank=True, help_text='遅刻ポイント:ゴールの時刻が制限時間を超えた場合、1分につき-50点が加算。', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='lattitude', + field=models.FloatField(blank=True, help_text='緯度:写真から取得', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='longitude', + field=models.FloatField(blank=True, help_text='経度:写真から取得', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='minus_photo_flag', + field=models.BooleanField(default=False, help_text='MobServer gps_information.minus_photo_flag'), + ), + migrations.AddField( + model_name='gpscheckin', + name='path_order', + field=models.IntegerField(default=0, help_text='チェックポイントの順序番号'), + ), + migrations.AddField( + model_name='gpscheckin', + name='points', + field=models.IntegerField(blank=True, help_text='ポイント:このチェックインによる獲得ポイント。通常ポイントと買い物ポイントは分離される。ゴールの場合には減点なども含む。', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='update_at', + field=models.DateTimeField(blank=True, help_text='更新日時', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='update_user', + field=models.TextField(blank=True, help_text='更新ユーザー', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validate_location', + field=models.BooleanField(default=False, help_text='位置情報検証フラグ:画像認識で検証した結果'), + ), + migrations.AddField( + model_name='gpscheckin', + name='zekken_number', + field=models.TextField(default='', help_text='ゼッケン番号'), + ), + migrations.AddField( + model_name='gpslog', + name='buy_flag', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='colabo_company_memo', + field=models.TextField(default=''), + ), + migrations.AddField( + model_name='gpslog', + name='create_user', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='goal_time', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='image_address', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='is_service_checked', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='gpslog', + name='minus_photo_flag', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='score', + field=models.IntegerField(blank=True, default=0, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='scoreboard_url', + field=models.URLField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='update_at', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='update_user', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='zekken_number', + field=models.TextField(default=''), + ), + migrations.AlterField( + model_name='gpscheckin', + name='checkpoint', + field=models.ForeignKey(blank=True, help_text='統合チェックポイントリレーション', null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.checkpoint'), + ), + migrations.AlterField( + model_name='gpscheckin', + name='cp_number', + field=models.IntegerField(blank=True, help_text='チェックポイント番号', null=True), + ), + migrations.AlterField( + model_name='gpscheckin', + name='event_code', + field=models.TextField(default='', help_text='イベントコード'), + ), + migrations.AlterField( + model_name='gpscheckin', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='gpscheckin', + name='serial_number', + field=models.IntegerField(blank=True, help_text='MobServer gps_information.serial_number', null=True), + ), + migrations.AlterField( + model_name='gpscheckin', + name='team', + field=models.ForeignKey(blank=True, help_text='統合チームリレーション', null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.team'), + ), + migrations.AlterField( + model_name='gpslog', + name='checkin_time', + field=models.DateTimeField(auto_now_add=True), + ), + migrations.AlterField( + model_name='gpslog', + name='cp_number', + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name='gpslog', + name='event_code', + field=models.TextField(default=''), + ), + migrations.AlterField( + model_name='gpslog', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='gpslog', + name='serial_number', + field=models.IntegerField(), + ), + migrations.AlterField( + model_name='newevent2', + name='event_code', + field=models.CharField(blank=True, max_length=50, null=True, unique=True), + ), + migrations.AlterField( + model_name='newevent2', + name='event_day', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterField( + model_name='newevent2', + name='start_time', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterField( + model_name='team', + name='created_at', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='team', + name='trial', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='team', + name='updated_at', + field=models.DateTimeField(auto_now=True, null=True), + ), + migrations.AlterField( + model_name='team', + name='zekken_number', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterUniqueTogether( + name='gpslog', + unique_together={('serial_number', 'zekken_number', 'event_code', 'colabo_company_memo')}, + ), + migrations.AddIndex( + model_name='checkpoint', + index=django.contrib.postgres.indexes.GistIndex(fields=['location'], name='idx_checkpoint_location'), + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['zekken_number', 'event_code', 'path_order'], name='idx_zekken_event'), + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['create_at'], name='idx_create_at'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['zekken_number', 'event_code'], name='gpslog_zekken_event_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['create_at'], name='gpslog_create_at_idx'), + ), + migrations.AddConstraint( + model_name='team', + constraint=models.UniqueConstraint(condition=models.Q(('event__isnull', False), ('zekken_number__isnull', False)), fields=('zekken_number', 'event'), name='unique_team_per_event'), + ), + migrations.AlterModelTable( + name='gpscheckin', + table='gps_checkins', + ), + + migrations.AddField( + model_name='location2025', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location2025_created', to=settings.AUTH_USER_MODEL, verbose_name='作成者'), + ), + migrations.AddField( + model_name='location2025', + name='csv_upload_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location2025_csv_uploads', to=settings.AUTH_USER_MODEL, verbose_name='CSVアップロードユーザー'), + ), + migrations.AddField( + model_name='location2025', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2', verbose_name='イベント'), + ), + migrations.AddField( + model_name='location2025', + name='updated_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location2025_updated', to=settings.AUTH_USER_MODEL, verbose_name='更新者'), + ), + migrations.RemoveField( + model_name='gpslog', + name='checkpoint', + ), + migrations.RemoveField( + model_name='gpslog', + name='event', + ), + migrations.RemoveField( + model_name='gpslog', + name='lat', + ), + migrations.RemoveField( + model_name='gpslog', + name='lng', + ), + migrations.RemoveField( + model_name='gpslog', + name='location', + ), + migrations.RemoveField( + model_name='gpslog', + name='team', + ), + migrations.RemoveField( + model_name='gpslog', + name='zekken', + ), + migrations.AddIndex( + model_name='location2025', + index=models.Index(fields=['event', 'cp_number'], name='location2025_event_cp_idx'), + ), + migrations.AddIndex( + model_name='location2025', + index=models.Index(fields=['event', 'is_active'], name='location2025_event_active_idx'), + ), + migrations.AddIndex( + model_name='location2025', + index=models.Index(fields=['csv_upload_date'], name='location2025_csv_date_idx'), + ), + migrations.AddIndex( + model_name='location2025', + index=django.contrib.postgres.indexes.GistIndex(fields=['location'], name='location2025_location_gist_idx'), + ), + migrations.AlterUniqueTogether( + name='location2025', + unique_together={('cp_number', 'event')}, + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0007_add_validation_fields.py b/rog/migrations_backup_20250828_042950/0007_add_validation_fields.py new file mode 100644 index 0000000..f24f915 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0007_add_validation_fields.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.9 on 2025-08-24 08:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0006_create_location2025_only'), + ] + + operations = [ + migrations.AddField( + model_name='gpscheckin', + name='validated_at', + field=models.DateTimeField(blank=True, help_text='審査日時', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validated_by', + field=models.CharField(blank=True, help_text='審査者', max_length=255, null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validation_comment', + field=models.TextField(blank=True, help_text='審査コメント・理由', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validation_status', + field=models.CharField(choices=[('PENDING', '審査待ち'), ('APPROVED', '承認'), ('REJECTED', '却下'), ('AUTO_APPROVED', '自動承認')], default='PENDING', help_text='通過審査ステータス', max_length=20), + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0008_auto_20250825_0716.py b/rog/migrations_backup_20250828_042950/0008_auto_20250825_0716.py new file mode 100644 index 0000000..5e0c92d --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0008_auto_20250825_0716.py @@ -0,0 +1,46 @@ +# Generated by Django 3.2.9 on 2025-08-24 22:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0007_add_validation_fields'), + ] + + operations = [ + # 安全な条件付きテーブル操作 + migrations.RunSQL( + """ + DO $$ + BEGIN + -- TeamStartテーブルが存在する場合のみフィールドを削除 + IF EXISTS (SELECT FROM pg_tables WHERE tablename = 'rog_teamstart') THEN + ALTER TABLE rog_teamstart DROP COLUMN IF EXISTS entry_id; + END IF; + + -- TeamGoalテーブルが存在する場合のみ削除 + IF EXISTS (SELECT FROM pg_tables WHERE tablename = 'rog_teamgoal') THEN + DROP TABLE rog_teamgoal; + END IF; + + -- TeamStartテーブルが存在する場合のみ削除 + IF EXISTS (SELECT FROM pg_tables WHERE tablename = 'rog_teamstart') THEN + DROP TABLE rog_teamstart; + END IF; + + -- zekken_labelカラムが存在しない場合のみ追加 + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_entry' + AND column_name = 'zekken_label' + ) THEN + ALTER TABLE rog_entry ADD COLUMN zekken_label VARCHAR(255) NULL; + END IF; + END + $$; + """, + reverse_sql=migrations.RunSQL.noop + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0009_create_gps_tables_safe.py b/rog/migrations_backup_20250828_042950/0009_create_gps_tables_safe.py new file mode 100644 index 0000000..9232c57 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0009_create_gps_tables_safe.py @@ -0,0 +1,96 @@ +# Generated by Django 3.2.9 on 2025-08-25 09:30 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0008_auto_20250825_0716'), + ] + + operations = [ + # GPS Checkin テーブルの安全な作成 + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + -- rog_gpscheckin テーブルが存在しない場合のみ作成 + IF NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'rog_gpscheckin' + ) THEN + CREATE TABLE rog_gpscheckin ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + team_name VARCHAR(255), + cp_number VARCHAR(20), + lat DOUBLE PRECISION, + lng DOUBLE PRECISION, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + location GEOMETRY(Point, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER, + goal_time TEXT, + late_point INTEGER, + buy_flag BOOLEAN DEFAULT FALSE, + image_address TEXT, + minus_photo_flag BOOLEAN DEFAULT FALSE, + create_user TEXT, + update_user TEXT, + comment TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + + -- インデックスの作成 + CREATE INDEX IF NOT EXISTS rog_gpschec_event_c_9f1a75_idx ON rog_gpscheckin (event_code); + CREATE INDEX IF NOT EXISTS rog_gpschec_zekken_8e7f42_idx ON rog_gpscheckin (zekken); + CREATE INDEX IF NOT EXISTS rog_gpschec_serial__1b5e3a_idx ON rog_gpscheckin (serial_number); + CREATE INDEX IF NOT EXISTS rog_gpschec_cp_numb_d7c8e5_idx ON rog_gpscheckin (cp_number); + CREATE INDEX IF NOT EXISTS rog_gpscheckin_team_id_e85ab512 ON rog_gpscheckin (team_id); + END IF; + + -- rog_gpslog テーブルが存在しない場合のみ作成 + IF NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'rog_gpslog' + ) THEN + CREATE TABLE rog_gpslog ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + cp_number VARCHAR(20), + lat DOUBLE PRECISION, + lng DOUBLE PRECISION, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + location GEOMETRY(Point, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER + ); + + -- インデックスの作成 + CREATE INDEX IF NOT EXISTS rog_gpslog_event_c_8a2b94_idx ON rog_gpslog (event_code); + CREATE INDEX IF NOT EXISTS rog_gpslog_zekken_7c5f39_idx ON rog_gpslog (zekken); + CREATE INDEX IF NOT EXISTS rog_gpslog_serial__6d4e28_idx ON rog_gpslog (serial_number); + CREATE INDEX IF NOT EXISTS rog_gpslog_cp_numb_5b3a17_idx ON rog_gpslog (cp_number); + END IF; + END $$; + """, + reverse_sql=""" + DROP TABLE IF EXISTS rog_gpscheckin CASCADE; + DROP TABLE IF EXISTS rog_gpslog CASCADE; + """ + ), + ] diff --git a/rog/migrations_backup_20250828_042950/0010_safe_create_all_tables.py b/rog/migrations_backup_20250828_042950/0010_safe_create_all_tables.py new file mode 100644 index 0000000..5dbe279 --- /dev/null +++ b/rog/migrations_backup_20250828_042950/0010_safe_create_all_tables.py @@ -0,0 +1,216 @@ +# Generated for safe deployment +# Conditional SQL operations to prevent duplicate table errors + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0009_create_gps_tables_safe'), + ] + + operations = [ + # 既存のすべてのテーブルとインデックスを条件付きで作成 + migrations.RunSQL( + sql=""" + -- CustomUser テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_customuser') THEN + CREATE TABLE rog_customuser ( + id SERIAL PRIMARY KEY, + password VARCHAR(128) NOT NULL, + last_login TIMESTAMP WITH TIME ZONE, + is_superuser BOOLEAN NOT NULL, + username VARCHAR(150) NOT NULL UNIQUE, + first_name VARCHAR(150) NOT NULL, + last_name VARCHAR(150) NOT NULL, + email VARCHAR(254) NOT NULL, + is_staff BOOLEAN NOT NULL, + is_active BOOLEAN NOT NULL, + date_joined TIMESTAMP WITH TIME ZONE NOT NULL + ); + END IF; + END $$; + + -- CustomUser インデックスの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_customuser' AND indexname = 'rog_customuser_username_key') THEN + CREATE UNIQUE INDEX rog_customuser_username_key ON rog_customuser (username); + END IF; + END $$; + + -- Entry テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_entry') THEN + CREATE TABLE rog_entry ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + END IF; + END $$; + + -- Team テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_team') THEN + CREATE TABLE rog_team ( + id SERIAL PRIMARY KEY, + team_name VARCHAR(100), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + END IF; + END $$; + + -- Member テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_member') THEN + CREATE TABLE rog_member ( + id SERIAL PRIMARY KEY, + member_name VARCHAR(100), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + END IF; + END $$; + + -- Location2025 テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_location2025') THEN + CREATE TABLE rog_location2025 ( + id SERIAL PRIMARY KEY, + cp_number INTEGER, + cp_name VARCHAR(255), + latitude FLOAT, + longitude FLOAT, + location GEOMETRY(POINT, 4326), + cp_point INTEGER DEFAULT 10, + photo_point INTEGER DEFAULT 0, + buy_point INTEGER DEFAULT 0, + checkin_radius FLOAT DEFAULT 15.0, + auto_checkin BOOLEAN DEFAULT FALSE, + shop_closed BOOLEAN DEFAULT FALSE, + shop_shutdown BOOLEAN DEFAULT FALSE, + opening_hours TEXT, + address VARCHAR(512), + phone VARCHAR(32), + website VARCHAR(200), + description TEXT, + is_active BOOLEAN DEFAULT TRUE, + sort_order INTEGER DEFAULT 0, + csv_source_file VARCHAR(255), + csv_upload_date TIMESTAMP WITH TIME ZONE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + event_id INTEGER, + created_by_id INTEGER, + csv_upload_user_id INTEGER, + updated_by_id INTEGER + ); + END IF; + END $$; + + -- GPS Checkin テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_gpscheckin') THEN + CREATE TABLE rog_gpscheckin ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + team_name VARCHAR(100), + cp_number VARCHAR(20), + lat FLOAT, + lng FLOAT, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + goal_time TIMESTAMP WITH TIME ZONE, + late_point INTEGER, + buy_flag BOOLEAN DEFAULT FALSE, + image_address TEXT, + minus_photo_flag BOOLEAN DEFAULT FALSE, + create_user TEXT, + update_user TEXT, + comment TEXT, + location GEOMETRY(POINT, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER + ); + END IF; + END $$; + + -- GPS Log テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_gpslog') THEN + CREATE TABLE rog_gpslog ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + cp_number VARCHAR(20), + lat FLOAT, + lng FLOAT, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + location GEOMETRY(POINT, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER + ); + END IF; + END $$; + + -- 必要なインデックスの安全な作成 + DO $$ + BEGIN + -- GPS Checkin インデックス + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpscheckin' AND indexname = 'rog_gpscheckin_event_code_idx') THEN + CREATE INDEX rog_gpscheckin_event_code_idx ON rog_gpscheckin (event_code); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpscheckin' AND indexname = 'rog_gpscheckin_serial_number_idx') THEN + CREATE INDEX rog_gpscheckin_serial_number_idx ON rog_gpscheckin (serial_number); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpscheckin' AND indexname = 'rog_gpscheckin_team_name_idx') THEN + CREATE INDEX rog_gpscheckin_team_name_idx ON rog_gpscheckin (team_name); + END IF; + + -- GPS Log インデックス + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpslog' AND indexname = 'rog_gpslog_event_code_idx') THEN + CREATE INDEX rog_gpslog_event_code_idx ON rog_gpslog (event_code); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpslog' AND indexname = 'rog_gpslog_serial_number_idx') THEN + CREATE INDEX rog_gpslog_serial_number_idx ON rog_gpslog (serial_number); + END IF; + + -- Location2025 インデックス + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_location2025' AND indexname = 'rog_location2025_cp_number_idx') THEN + CREATE INDEX rog_location2025_cp_number_idx ON rog_location2025 (cp_number); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_location2025' AND indexname = 'rog_location2025_event_id_idx') THEN + CREATE INDEX rog_location2025_event_id_idx ON rog_location2025 (event_id); + END IF; + END $$; + """, + reverse_sql=""" + -- 逆操作は何もしない(テーブルを削除しない) + SELECT 1; + """ + ), + ] diff --git a/rog/migrations/0011_auto_20250827_1459.py b/rog/migrations_backup_20250828_042950/0011_auto_20250827_1459.py similarity index 99% rename from rog/migrations/0011_auto_20250827_1459.py rename to rog/migrations_backup_20250828_042950/0011_auto_20250827_1459.py index 8bbb107..2a27907 100644 --- a/rog/migrations/0011_auto_20250827_1459.py +++ b/rog/migrations_backup_20250828_042950/0011_auto_20250827_1459.py @@ -9,7 +9,7 @@ import django.utils.timezone class Migration(migrations.Migration): dependencies = [ - ('rog', '0010_auto_20250827_1510'), + ('rog', '0010_safe_create_all_tables'), ] operations = [ diff --git a/rog/migrations_backup_20250828_042950/__init__.py b/rog/migrations_backup_20250828_042950/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/rog/migrations_backup_20250828_132814/0001_initial.py b/rog/migrations_backup_20250828_132814/0001_initial.py new file mode 100755 index 0000000..e401670 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0001_initial.py @@ -0,0 +1,847 @@ +# Generated by Django 3.2.9 on 2025-05-13 08:22 + +import datetime +from django.conf import settings +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import rog.models +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='GifuAreas', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('area_nm', models.CharField(blank=True, max_length=254, null=True)), + ], + options={ + 'db_table': 'gifu_areas', + 'managed': False, + }, + ), + migrations.CreateModel( + name='JpnAdminMainPerf', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ], + options={ + 'db_table': 'jpn_admin_main_perf', + 'managed': False, + }, + ), + migrations.CreateModel( + name='JpnSubPerf', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('adm0_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_ja', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_en', models.CharField(blank=True, max_length=254, null=True)), + ('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)), + ('name_modified', models.CharField(blank=True, max_length=254, null=True)), + ('area_name', models.CharField(blank=True, max_length=254, null=True)), + ('list_order', models.IntegerField(default=0)), + ], + options={ + 'db_table': 'jpn_sub_perf', + 'managed': False, + }, + ), + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('email', models.EmailField(max_length=254, unique=True)), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('group', models.CharField(blank=True, max_length=255)), + ('is_active', models.BooleanField(default=True)), + ('is_staff', models.BooleanField(default=False)), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now)), + ('is_rogaining', models.BooleanField(default=False)), + ('zekken_number', models.CharField(blank=True, max_length=255, null=True, verbose_name='Zekken Number')), + ('event_code', models.CharField(blank=True, max_length=255, null=True, verbose_name='Event Code')), + ('team_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Team Name')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Category', + fields=[ + ('category_name', models.CharField(max_length=255, primary_key=True, serialize=False)), + ('category_number', models.IntegerField(default=0)), + ('duration', models.DurationField(default=datetime.timedelta(seconds=18000))), + ('num_of_member', models.IntegerField(default=1)), + ('family', models.BooleanField(default=False)), + ('female', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='CheckinImages', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('checkinimage', models.FileField(blank=True, null=True, upload_to='checkin/%y%m%d')), + ('checkintime', models.DateTimeField(verbose_name='Goal time')), + ('team_name', models.CharField(max_length=255, verbose_name='Team name')), + ('event_code', models.CharField(max_length=255, verbose_name='event code')), + ('cp_number', models.IntegerField(verbose_name='CP numner')), + ], + ), + migrations.CreateModel( + name='CheckPoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cp_number', models.CharField(max_length=20)), + ('image_address', models.URLField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(auto_now_add=True)), + ('is_service_checked', models.BooleanField(default=False)), + ], + options={ + 'ordering': ['checkin_time'], + }, + ), + migrations.CreateModel( + name='Entry', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateTimeField()), + ('zekken_number', models.IntegerField(default=0)), + ('is_active', models.BooleanField(default=True)), + ('hasParticipated', models.BooleanField(default=False)), + ('hasGoaled', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='EntryMember', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_temporary', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tagname', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('status', models.CharField(choices=[('PREPARING', 'Preparing'), ('PROMOTION', 'Promotion'), ('EVENT', 'Event'), ('END', 'End')], max_length=256)), + ('price', models.IntegerField(default=0, verbose_name='Paid Amount')), + ('promotion_date', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')), + ('event_start', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')), + ('event_end', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')), + ('remark', models.CharField(blank=True, max_length=256, null=True)), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='EventUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + migrations.CreateModel( + name='Favorite', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('good', models.IntegerField(default=0, verbose_name='Good')), + ('favorite', models.IntegerField(default=0, verbose_name='Favorite')), + ('evaluation', models.IntegerField(default=0, verbose_name='Evaluation')), + ('number_visit', models.IntegerField(default=0, verbose_name='Good')), + ('last_visited', models.DateTimeField(blank=True, null=True, verbose_name='Last Visited')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='GifurogeRegister', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=100)), + ('time', models.IntegerField(choices=[(3, '3時間'), (5, '5時間')])), + ('owner_name_kana', models.CharField(max_length=100)), + ('owner_name', models.CharField(max_length=100)), + ('email', models.EmailField(max_length=254)), + ('password', models.CharField(max_length=100)), + ('owner_birthday', models.DateField(blank=True, null=True)), + ('owner_sex', models.CharField(blank=True, max_length=10, null=True)), + ('team_name', models.CharField(max_length=100)), + ('department', models.CharField(max_length=100)), + ('members_count', models.IntegerField()), + ('member2', models.CharField(blank=True, max_length=100, null=True)), + ('birthday2', models.DateField(blank=True, null=True)), + ('sex2', models.CharField(blank=True, max_length=10, null=True)), + ('member3', models.CharField(blank=True, max_length=100, null=True)), + ('birthday3', models.DateField(blank=True, null=True)), + ('sex3', models.CharField(blank=True, max_length=10, null=True)), + ('member4', models.CharField(blank=True, max_length=100, null=True)), + ('birthday4', models.DateField(blank=True, null=True)), + ('sex4', models.CharField(blank=True, max_length=10, null=True)), + ('member5', models.CharField(blank=True, max_length=100, null=True)), + ('birthday5', models.DateField(blank=True, null=True)), + ('sex5', models.CharField(blank=True, max_length=10, null=True)), + ], + ), + migrations.CreateModel( + name='GoalImages', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('goalimage', models.FileField(blank=True, null=True, upload_to='goals/%y%m%d')), + ('goaltime', models.DateTimeField(blank=True, null=True, verbose_name='Goal time')), + ('team_name', models.CharField(max_length=255, verbose_name='Team name')), + ('event_code', models.CharField(max_length=255, verbose_name='event code')), + ('cp_number', models.IntegerField(verbose_name='CP numner')), + ('zekken_number', models.TextField(blank=True, help_text='ゼッケン番号', null=True)), + ], + ), + migrations.CreateModel( + name='GpsCheckin', + fields=[ + ('id', models.AutoField(primary_key=True, serialize=False)), + ('path_order', models.IntegerField(help_text='チェックポイントの順序番号')), + ('zekken_number', models.TextField(help_text='ゼッケン番号')), + ('event_id', models.IntegerField(blank=True, help_text='イベントID', null=True)), + ('event_code', models.TextField(help_text='イベントコード')), + ('cp_number', models.IntegerField(blank=True, help_text='チェックポイント番号', null=True)), + ('lattitude', models.FloatField(blank=True, help_text='緯度:写真から取得', null=True)), + ('longitude', models.FloatField(blank=True, help_text='経度:写真から取得', null=True)), + ('image_address', models.TextField(blank=True, help_text='チェックイン画像のパス', null=True)), + ('image_receipt', models.TextField(blank=True, default=False, help_text='レシート画像のパス', null=True)), + ('image_qr', models.BooleanField(default=False, help_text='QRコードスキャンフラグ')), + ('validate_location', models.BooleanField(default=False, help_text='位置情報検証フラグ:画像認識で検証した結果')), + ('goal_time', models.TextField(blank=True, help_text='ゴール時刻=ゴール時のみ使用される。画像から時刻を読み取り設定する。', null=True)), + ('late_point', models.IntegerField(blank=True, help_text='遅刻ポイント:ゴールの時刻が制限時間を超えた場合、1分につき-50点が加算。', null=True)), + ('create_at', models.DateTimeField(blank=True, help_text='作成日時:データの作成日時', null=True)), + ('create_user', models.TextField(blank=True, help_text='作成ユーザー', null=True)), + ('update_at', models.DateTimeField(blank=True, help_text='更新日時', null=True)), + ('update_user', models.TextField(blank=True, help_text='更新ユーザー', null=True)), + ('buy_flag', models.BooleanField(default=False, help_text='購入フラグ:協賛店で購入した場合、無条件でTRUEにする。')), + ('colabo_company_memo', models.TextField(default='', help_text='グループコード:複数のイベントで合算する場合に使用する')), + ('points', models.IntegerField(blank=True, help_text='ポイント:このチェックインによる獲得ポイント。通常ポイントと買い物ポイントは分離される。ゴールの場合には減点なども含む。', null=True)), + ], + options={ + 'db_table': 'gps_checkins', + }, + ), + migrations.CreateModel( + name='Location', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, db_index=True, null=True, verbose_name='Location id')), + ('sub_loc_id', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id')), + ('cp', models.FloatField(default=0, null=True, verbose_name='Check Point')), + ('location_name', models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name')), + ('category', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Category')), + ('subcategory', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=2048, null=True, verbose_name='City')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('photos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos')), + ('videos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Tags')), + ('event_name', models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Event name')), + ('event_active', models.BooleanField(db_index=True, default=True, verbose_name='Is Event active')), + ('hidden_location', models.BooleanField(default=False, verbose_name='Is Hidden Location')), + ('auto_checkin', models.BooleanField(default=False, verbose_name='Is AutoCheckin')), + ('checkin_radius', models.FloatField(blank=True, default=15.0, null=True, verbose_name='Checkin radious')), + ('checkin_point', models.FloatField(blank=True, default=10, null=True, verbose_name='Checkin Point')), + ('buy_point', models.FloatField(blank=True, default=0, null=True, verbose_name='buy Point')), + ('evaluation_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Evaluation value (評価)')), + ('shop_closed', models.BooleanField(default=False, verbose_name='Shop Closed (休業)')), + ('shop_shutdown', models.BooleanField(default=False, verbose_name='Shop Shutdown (閉業)')), + ('opening_hours_mon', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours monday (月曜)')), + ('opening_hours_tue', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours tuesday (火曜)')), + ('opening_hours_wed', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours wednesday (水曜)')), + ('opening_hours_thu', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours thursday (木曜)')), + ('opening_hours_fri', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours frinday (金曜)')), + ('opening_hours_sat', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours saturday (土曜)')), + ('opening_hours_sun', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours sunday (日曜)')), + ('parammeters', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='NewCategory', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('category_name', models.CharField(max_length=255, unique=True)), + ('category_number', models.IntegerField(default=0)), + ('duration', models.DurationField(default=datetime.timedelta(seconds=18000))), + ('num_of_member', models.IntegerField(default=1)), + ('family', models.BooleanField(default=False)), + ('female', models.BooleanField(default=False)), + ('trial', models.BooleanField(default=False)), + ], + options={ + 'unique_together': {('category_name', 'category_number')}, + }, + ), + migrations.CreateModel( + name='NewEvent', + fields=[ + ('event_name', models.CharField(max_length=255, primary_key=True, serialize=False)), + ('start_datetime', models.DateTimeField(default=django.utils.timezone.now)), + ('end_datetime', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='NewEvent2', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_name', models.CharField(max_length=255, unique=True)), + ('event_description', models.TextField(blank=True, max_length=255, null=True)), + ('start_datetime', models.DateTimeField(default=django.utils.timezone.now)), + ('end_datetime', models.DateTimeField()), + ('deadlineDateTime', models.DateTimeField(blank=True, null=True)), + ('public', models.BooleanField(default=False)), + ('hour_3', models.BooleanField(default=False)), + ('hour_5', models.BooleanField(default=True)), + ('class_general', models.BooleanField(default=True)), + ('class_family', models.BooleanField(default=True)), + ('class_solo_male', models.BooleanField(default=True)), + ('class_solo_female', models.BooleanField(default=True)), + ('self_rogaining', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='ShapeFileLocations', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('shapefile', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Shapelayer')), + ('locid', models.IntegerField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name='ShapeLayers', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='Shape Layer')), + ('file', models.FileField(blank=True, upload_to=rog.models.get_file_path)), + ('uploaded_date', models.DateField(auto_now_add=True)), + ('layerof', models.IntegerField(choices=[(1, 'templocation'), (2, 'Location_line'), (3, 'Location_polygon')], default=1)), + ('table_name', models.CharField(blank=True, max_length=255, verbose_name='Table name')), + ], + ), + migrations.CreateModel( + name='TempUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('email', models.EmailField(max_length=254, unique=True)), + ('password', models.CharField(max_length=128)), + ('is_rogaining', models.BooleanField(default=False)), + ('zekken_number', models.CharField(blank=True, max_length=255, null=True)), + ('event_code', models.CharField(blank=True, max_length=255, null=True)), + ('team_name', models.CharField(blank=True, max_length=255, null=True)), + ('group', models.CharField(max_length=255)), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('verification_code', models.UUIDField(default=uuid.uuid4, editable=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('expires_at', models.DateTimeField()), + ], + ), + migrations.CreateModel( + name='TestModel', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('testbane', models.CharField(max_length=355, verbose_name='test field')), + ('wanttogo', models.BooleanField(default=False)), + ('like', models.BooleanField(default=False)), + ('checkin', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='TravelList', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('travel_id', models.IntegerField(verbose_name='Travel Id')), + ('start_date', models.DateTimeField(blank=True, null=True, verbose_name='Start date')), + ('finish_date', models.DateTimeField(blank=True, null=True, verbose_name='End date')), + ('category', models.CharField(choices=[('PRIVATE', 'Private'), ('GROUP', 'Group'), ('AGENT', 'Agent'), ('ROGAINING', 'Rogaining')], max_length=256)), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('transportation', models.CharField(blank=True, max_length=255, null=True, verbose_name='Transpotation')), + ('moving_distance', models.IntegerField(blank=True, null=True)), + ('duration', models.DurationField(blank=True, null=True, verbose_name='Duration')), + ('eta', models.DateTimeField(blank=True, null=True)), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='travel_list_updated_user', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='UserUpload', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='User uploads')), + ('file', models.FileField(blank=True, upload_to=rog.models.get_file_path)), + ('uploaded_date', models.DateField(auto_now_add=True)), + ], + ), + migrations.CreateModel( + name='UserUploadUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('userfile', models.CharField(blank=True, max_length=2048, null=True, verbose_name='User file')), + ('email', models.CharField(max_length=255, verbose_name='User Email')), + ], + ), + migrations.CreateModel( + name='Waypoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('latitude', models.FloatField()), + ('longitude', models.FloatField()), + ('altitude', models.FloatField(blank=True, null=True)), + ('accuracy', models.FloatField(blank=True, null=True)), + ('speed', models.FloatField(blank=True, null=True)), + ('recorded_at', models.DateTimeField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('entry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='waypoints', to='rog.entry')), + ], + options={ + 'ordering': ['recorded_at'], + }, + ), + migrations.CreateModel( + name='UserTracks', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Useractions', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('wanttogo', models.BooleanField(default=False)), + ('like', models.BooleanField(default=False)), + ('checkin', models.BooleanField(default=False)), + ('checkinimage', models.FileField(blank=True, null=True, upload_to='%y%m%d')), + ('order', models.IntegerField(default=0)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='action_location', to='rog.location')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='action_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='TravelPoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('distance', models.FloatField(blank=True, null=True)), + ('transportation', models.CharField(blank=True, max_length=255, null=True, verbose_name='Transpotation')), + ('eta', models.DateTimeField(blank=True, null=True)), + ('order_number', models.IntegerField(blank=True, null=True)), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='travelpoint_updated_user', to=settings.AUTH_USER_MODEL)), + ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location')), + ('travel_list', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='rog.travellist')), + ], + ), + migrations.CreateModel( + name='templocation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')), + ('sub_loc_id', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id')), + ('cp', models.FloatField(default=0, null=True, verbose_name='Check Point')), + ('location_name', models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name')), + ('category', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Category')), + ('subcategory', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=2048, null=True, verbose_name='City')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')), + ('photos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos')), + ('videos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Tags')), + ('event_name', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Event name')), + ('event_active', models.BooleanField(default=True, verbose_name='Is Event active')), + ('hidden_location', models.BooleanField(default=False, verbose_name='Is Hidden Location')), + ('auto_checkin', models.BooleanField(default=False, verbose_name='Is AutoCheckin')), + ('checkin_radius', models.FloatField(blank=True, default=15.0, null=True, verbose_name='Checkin radious')), + ('checkin_point', models.FloatField(blank=True, default=10, null=True, verbose_name='Checkin Point')), + ('buy_point', models.FloatField(blank=True, default=0, null=True, verbose_name='buy Point')), + ('evaluation_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Evaluation value (評価)')), + ('shop_closed', models.BooleanField(default=False, verbose_name='Shop Closed (休業)')), + ('shop_shutdown', models.BooleanField(default=False, verbose_name='Shop Shutdown (閉業)')), + ('opening_hours_mon', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours monday (月曜)')), + ('opening_hours_tue', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours tuesday (火曜)')), + ('opening_hours_wed', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours wednesday (水曜)')), + ('opening_hours_thu', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours thursday (木曜)')), + ('opening_hours_fri', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours frinday (金曜)')), + ('opening_hours_sat', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours saturday (土曜)')), + ('opening_hours_sun', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours sunday (日曜)')), + ('parammeters', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='temp_location_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='TeamStart', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_time', models.DateTimeField(auto_now_add=True)), + ('entry', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='start_info', to='rog.entry')), + ], + ), + migrations.CreateModel( + name='TeamGoal', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('goal_time', models.DateTimeField()), + ('image_url', models.URLField(blank=True, null=True)), + ('score', models.IntegerField(default=0)), + ('scoreboard_url', models.URLField(blank=True, null=True)), + ('entry', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='goal_info', to='rog.entry')), + ], + ), + migrations.CreateModel( + name='Team', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('team_name', models.CharField(max_length=255)), + ('category', models.ForeignKey(default=rog.models.get_default_category, on_delete=django.db.models.deletion.SET_DEFAULT, to='rog.newcategory')), + ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owned_teams', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='SystemSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('setting_name', models.CharField(max_length=255, verbose_name='Settings Name')), + ('version', models.CharField(blank=True, max_length=10, null=True, verbose_name='Version')), + ('effective_date', models.DateTimeField()), + ('end_date', models.DateTimeField()), + ('parammeters', models.CharField(max_length=512, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='system_setting_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='RogUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('phone', models.CharField(max_length=55, verbose_name='Phone Number')), + ('first_name', models.CharField(max_length=255, verbose_name='First Name')), + ('middle_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Middle Name')), + ('last_name', models.CharField(max_length=255, verbose_name='last_name')), + ('nickname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Nickname')), + ('country', models.CharField(default='Japan', max_length=255, verbose_name='Country')), + ('language', models.CharField(default='Japanese', max_length=255, verbose_name='Language')), + ('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')), + ('sex', models.CharField(blank=True, default='unknown', max_length=255, null=True, verbose_name='Sex')), + ('birthyear', models.IntegerField(blank=True, null=True, verbose_name='Birth year')), + ('family_structure', models.IntegerField(blank=True, null=True, verbose_name='Family Structure')), + ('level', models.IntegerField(blank=True, default=0, null=True, verbose_name='Level')), + ('paid', models.BooleanField(default=False, verbose_name='Is Paid')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('introducer', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='introduced_uesr', to=settings.AUTH_USER_MODEL)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='roguser_updated_user', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Member', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('firstname', models.CharField(blank=True, max_length=255, null=True)), + ('lastname', models.CharField(blank=True, max_length=255, null=True)), + ('date_of_birth', models.DateField(blank=True, null=True)), + ('female', models.BooleanField(default=False)), + ('is_temporary', models.BooleanField(default=False)), + ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='members', to='rog.team')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Location_polygon', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')), + ('location_name', models.CharField(max_length=255, verbose_name='Location Name')), + ('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')), + ('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')), + ('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_polygon_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Location_line', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')), + ('location_name', models.CharField(max_length=255, verbose_name='Location Name')), + ('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')), + ('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')), + ('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')), + ('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')), + ('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')), + ('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')), + ('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')), + ('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')), + ('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')), + ('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')), + ('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')), + ('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')), + ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')), + ('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')), + ('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')), + ('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')), + ('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')), + ('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')), + ('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('geom', django.contrib.gis.db.models.fields.MultiLineStringField(blank=True, null=True, srid=4326)), + ('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_line_updated_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='JoinedEvent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tagname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Tag Name')), + ('status', models.CharField(choices=[('REGISTERED', 'Registered'), ('ACCEPTED', 'accepted'), ('PAID', 'paid'), ('JOINED', 'joined'), ('CANCELED', 'Canceled')], max_length=256)), + ('registrationid', models.CharField(max_length=56, verbose_name='Registration Id')), + ('payment_code', models.CharField(max_length=255, verbose_name='Payment Code')), + ('paid', models.IntegerField(default=0, verbose_name='Paid Amount')), + ('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remark')), + ('parammeters', models.CharField(max_length=512, verbose_name='Parameters')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_updated_at', models.DateTimeField(auto_now=True)), + ('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='joined_event_updated_user', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['zekken_number', 'event_code', 'path_order'], name='idx_zekken_event'), + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['create_at'], name='idx_create_at'), + ), + migrations.AddField( + model_name='goalimages', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='favorite', + name='last_updated_user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='favorite_updated_user', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='favorite', + name='location', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location'), + ), + migrations.AddField( + model_name='favorite', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='eventuser', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='event', to='rog.event'), + ), + migrations.AddField( + model_name='eventuser', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='event', + name='last_updated_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='event_updated_user', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='event', + name='user', + field=models.ManyToManyField(related_name='even', through='rog.EventUser', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='entrymember', + name='entry', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.entry'), + ), + migrations.AddField( + model_name='entrymember', + name='member', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.member'), + ), + migrations.AddField( + model_name='entry', + name='category', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newcategory'), + ), + migrations.AddField( + model_name='entry', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2'), + ), + migrations.AddField( + model_name='entry', + name='owner', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='entry', + name='team', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team'), + ), + migrations.AddField( + model_name='checkpoint', + name='entry', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='checkpoints', to='rog.entry'), + ), + migrations.AddField( + model_name='checkinimages', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), + migrations.AlterUniqueTogether( + name='category', + unique_together={('category_name', 'category_number')}, + ), + migrations.AddField( + model_name='customuser', + name='groups', + field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'), + ), + migrations.AddField( + model_name='customuser', + name='user_permissions', + field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'), + ), + migrations.AddIndex( + model_name='waypoint', + index=models.Index(fields=['entry', 'recorded_at'], name='rog_waypoin_entry_i_fb2cb5_idx'), + ), + migrations.AlterUniqueTogether( + name='member', + unique_together={('team', 'user')}, + ), + migrations.AddIndex( + model_name='location', + index=django.contrib.postgres.indexes.GistIndex(fields=['geom'], name='rog_locatio_geom_4793cc_gist'), + ), + migrations.AlterUniqueTogether( + name='entrymember', + unique_together={('entry', 'member')}, + ), + migrations.AlterUniqueTogether( + name='entry', + unique_together={('zekken_number', 'event', 'date')}, + ), + migrations.AlterUniqueTogether( + name='checkpoint', + unique_together={('entry', 'cp_number')}, + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0002_integration_update.py b/rog/migrations_backup_20250828_132814/0002_integration_update.py new file mode 100644 index 0000000..14958fc --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0002_integration_update.py @@ -0,0 +1,179 @@ +# Generated by manual creation for database integration on 2025-08-20 + +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0001_initial'), + ] + + operations = [ + # Create Checkpoint model first (required by other operations) + migrations.CreateModel( + name='Checkpoint', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cp_number', models.IntegerField()), + ('cp_name', models.CharField(blank=True, max_length=200, null=True)), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), + ('photo_point', models.IntegerField(default=0)), + ('buy_point', models.IntegerField(default=0)), + ('sample_photo', models.CharField(blank=True, max_length=500, null=True)), + ('colabo_company_memo', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True, blank=True, null=True)), + ('updated_at', models.DateTimeField(auto_now=True, blank=True, null=True)), + ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2')), + ], + ), + + # Create GpsLog model for MobServer integration + migrations.CreateModel( + name='GpsLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('serial_number', models.IntegerField()), + ('zekken_number', models.TextField()), + ('event_code', models.TextField()), + ('cp_number', models.TextField(blank=True, null=True)), + ('image_address', models.TextField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(auto_now_add=True)), + ('goal_time', models.TextField(blank=True, null=True)), + ('late_point', models.IntegerField(blank=True, null=True)), + ('create_at', models.DateTimeField(blank=True, null=True)), + ('create_user', models.TextField(blank=True, null=True)), + ('update_at', models.DateTimeField(blank=True, null=True)), + ('update_user', models.TextField(blank=True, null=True)), + ('buy_flag', models.BooleanField(blank=True, null=True)), + ('minus_photo_flag', models.BooleanField(blank=True, null=True)), + ('colabo_company_memo', models.TextField(default='')), + ('is_service_checked', models.BooleanField(default=False)), + ('score', models.IntegerField(blank=True, default=0, null=True)), + ('scoreboard_url', models.URLField(blank=True, null=True)), + ], + options={ + 'db_table': 'gps_information', + }, + ), + + # Add fields to GpsCheckin model + migrations.AddField( + model_name='gpscheckin', + name='checkpoint', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.checkpoint'), + ), + migrations.AddField( + model_name='gpscheckin', + name='minus_photo_flag', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='serial_number', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='team', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.team'), + ), + + # Add fields to NewEvent2 model + migrations.AddField( + model_name='newevent2', + name='event_code', + field=models.CharField(blank=True, max_length=50, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='event_day', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='start_time', + field=models.TimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='venue_address', + field=models.CharField(blank=True, max_length=500, null=True), + ), + migrations.AddField( + model_name='newevent2', + name='venue_location', + field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326), + ), + + # Add fields to Team model + migrations.AddField( + model_name='team', + name='class_name', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='team', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2'), + ), + migrations.AddField( + model_name='team', + name='location', + field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326), + ), + migrations.AddField( + model_name='team', + name='password', + field=models.CharField(blank=True, max_length=100, null=True), + ), + migrations.AddField( + model_name='team', + name='trial', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='team', + name='zekken_number', + field=models.CharField(blank=True, max_length=50, null=True), + ), + + # Add constraints for Checkpoint model + migrations.AddConstraint( + model_name='checkpoint', + constraint=models.UniqueConstraint(fields=['cp_number', 'event'], name='unique_cp_per_event'), + ), + + # Create indexes (use appropriate operator classes) + migrations.AddIndex( + model_name='checkpoint', + index=models.Index(fields=['event', 'cp_number'], name='idx_checkpoint_event_cp'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['serial_number'], name='gps_informa_serial__77a095_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['zekken_number'], name='gps_informa_zekken__01b27e_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['event_code'], name='gps_informa_event_c_2ab906_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['cp_number'], name='gps_informa_cp_numb_97c5c5_idx'), + ), + migrations.AddIndex( + model_name='newevent2', + index=models.Index(fields=['event_code'], name='rog_neweven_event_c_e79a96_idx'), + ), + migrations.AddIndex( + model_name='team', + index=models.Index(fields=['zekken_number'], name='rog_team_zekken__2c50d1_idx'), + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0003_auto_20250821_0112.py b/rog/migrations_backup_20250828_132814/0003_auto_20250821_0112.py new file mode 100644 index 0000000..0657c18 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0003_auto_20250821_0112.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2025-08-20 16:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0002_integration_update'), + ] + + operations = [ + migrations.AlterField( + model_name='newevent2', + name='end_datetime', + field=models.DateTimeField(null=True, blank=True), + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0004_add_team_timestamps.py b/rog/migrations_backup_20250828_132814/0004_add_team_timestamps.py new file mode 100644 index 0000000..32ee022 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0004_add_team_timestamps.py @@ -0,0 +1,26 @@ +# Generated manually on 2025-08-21 +# Add only required timestamp fields to Team model + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0003_auto_20250821_0112'), + ] + + operations = [ + migrations.AddField( + model_name='team', + name='created_at', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + migrations.AddField( + model_name='team', + name='updated_at', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0005_create_gps_tables.py b/rog/migrations_backup_20250828_132814/0005_create_gps_tables.py new file mode 100644 index 0000000..22f3df5 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0005_create_gps_tables.py @@ -0,0 +1,74 @@ +# Generated manually on 2025-08-21 08:25 + +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0004_add_team_timestamps'), + ] + + operations = [ + # Create GpsCheckin model + migrations.CreateModel( + name='GpsCheckin', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=50)), + ('zekken', models.CharField(max_length=20)), + ('serial_number', models.CharField(max_length=50)), + ('cp_number', models.CharField(blank=True, max_length=20, null=True)), + ('lat', models.FloatField(blank=True, null=True)), + ('lng', models.FloatField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(blank=True, null=True)), + ('record_time', models.DateTimeField(blank=True, null=True)), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), + ('mobserver_id', models.IntegerField(blank=True, null=True)), + ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_checkins', to='rog.newevent2')), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_checkins', to='rog.team')), + ('checkpoint', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_checkins', to='rog.checkpoint')), + ], + options={ + 'db_table': 'rog_gpscheckin', + 'indexes': [ + models.Index(fields=['event_code'], name='rog_gpschec_event_c_9f1a75_idx'), + models.Index(fields=['zekken'], name='rog_gpschec_zekken_8e7f42_idx'), + models.Index(fields=['serial_number'], name='rog_gpschec_serial__1b5e3a_idx'), + models.Index(fields=['cp_number'], name='rog_gpschec_cp_numb_d7c8e5_idx'), + ], + }, + ), + + # Create GpsLog model + migrations.CreateModel( + name='GpsLog', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('event_code', models.CharField(max_length=50)), + ('zekken', models.CharField(max_length=20)), + ('serial_number', models.CharField(max_length=50)), + ('cp_number', models.CharField(blank=True, max_length=20, null=True)), + ('lat', models.FloatField(blank=True, null=True)), + ('lng', models.FloatField(blank=True, null=True)), + ('checkin_time', models.DateTimeField(blank=True, null=True)), + ('record_time', models.DateTimeField(blank=True, null=True)), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), + ('mobserver_id', models.IntegerField(blank=True, null=True)), + ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_logs', to='rog.newevent2')), + ('team', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_logs', to='rog.team')), + ('checkpoint', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='gps_logs', to='rog.checkpoint')), + ], + options={ + 'db_table': 'rog_gpslog', + 'indexes': [ + models.Index(fields=['event_code'], name='rog_gpslog_event_c_8a2b94_idx'), + models.Index(fields=['zekken'], name='rog_gpslog_zekken_7c5f39_idx'), + models.Index(fields=['serial_number'], name='rog_gpslog_serial__6d4e28_idx'), + models.Index(fields=['cp_number'], name='rog_gpslog_cp_numb_5b3a17_idx'), + ], + }, + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0006_create_location2025_only.py b/rog/migrations_backup_20250828_132814/0006_create_location2025_only.py new file mode 100644 index 0000000..a1a8a78 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0006_create_location2025_only.py @@ -0,0 +1,532 @@ +# Generated by Django 3.2.9 on 2025-08-24 00:29 + +from django.conf import settings +import django.contrib.gis.db.models.fields +import django.contrib.postgres.indexes +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0005_create_gps_tables'), + ] + + operations = [ + migrations.CreateModel( + name='Location2025', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('cp_number', models.IntegerField(db_index=True, verbose_name='CP番号')), + ('cp_name', models.CharField(max_length=255, verbose_name='CP名')), + ('latitude', models.FloatField(blank=True, null=True, verbose_name='緯度')), + ('longitude', models.FloatField(blank=True, null=True, verbose_name='経度')), + ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='位置')), + ('cp_point', models.IntegerField(default=10, verbose_name='チェックポイント得点')), + ('photo_point', models.IntegerField(default=0, verbose_name='写真ポイント')), + ('buy_point', models.IntegerField(default=0, verbose_name='買い物ポイント')), + ('checkin_radius', models.FloatField(default=15.0, verbose_name='チェックイン範囲(m)')), + ('auto_checkin', models.BooleanField(default=False, verbose_name='自動チェックイン')), + ('shop_closed', models.BooleanField(default=False, verbose_name='休業中')), + ('shop_shutdown', models.BooleanField(default=False, verbose_name='閉業')), + ('opening_hours', models.TextField(blank=True, null=True, verbose_name='営業時間')), + ('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='住所')), + ('phone', models.CharField(blank=True, max_length=32, null=True, verbose_name='電話番号')), + ('website', models.URLField(blank=True, null=True, verbose_name='ウェブサイト')), + ('description', models.TextField(blank=True, null=True, verbose_name='説明')), + ('is_active', models.BooleanField(db_index=True, default=True, verbose_name='有効')), + ('sort_order', models.IntegerField(default=0, verbose_name='表示順')), + ('csv_source_file', models.CharField(blank=True, max_length=255, null=True, verbose_name='CSVファイル名')), + ('csv_upload_date', models.DateTimeField(blank=True, null=True, verbose_name='CSVアップロード日時')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='作成日時')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='更新日時')), + ], + options={ + 'verbose_name': 'チェックポイント2025', + 'verbose_name_plural': 'チェックポイント2025', + 'db_table': 'rog_location2025', + 'ordering': ['event', 'sort_order', 'cp_number'], + }, + ), + + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_event_c_9f1a75_idx', + ), + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_zekken_8e7f42_idx', + ), + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_serial__1b5e3a_idx', + ), + migrations.RemoveIndex( + model_name='gpscheckin', + name='rog_gpschec_cp_numb_d7c8e5_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_event_c_8a2b94_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_zekken_7c5f39_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_serial__6d4e28_idx', + ), + migrations.RemoveIndex( + model_name='gpslog', + name='rog_gpslog_cp_numb_5b3a17_idx', + ), + migrations.RemoveIndex( + model_name='newevent2', + name='rog_neweven_event_c_e79a96_idx', + ), + migrations.RemoveIndex( + model_name='team', + name='rog_team_zekken__2c50d1_idx', + ), + migrations.RenameField( + model_name='gpslog', + old_name='record_time', + new_name='create_at', + ), + migrations.RenameField( + model_name='gpslog', + old_name='mobserver_id', + new_name='late_point', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='checkin_time', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='event', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='lat', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='lng', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='location', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='mobserver_id', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='record_time', + ), + migrations.RemoveField( + model_name='gpscheckin', + name='zekken', + ), + + migrations.AddField( + model_name='gpscheckin', + name='buy_flag', + field=models.BooleanField(default=False, help_text='購入フラグ:協賛店で購入した場合、無条件でTRUEにする。'), + ), + migrations.AddField( + model_name='gpscheckin', + name='colabo_company_memo', + field=models.TextField(default='', help_text='グループコード:複数のイベントで合算する場合に使用する'), + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'create_at' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN create_at TIMESTAMP WITH TIME ZONE; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS create_at CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'create_user' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN create_user TEXT; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS create_user CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'event_id' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN event_id INTEGER; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS event_id CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'goal_time' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN goal_time TEXT; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS goal_time CASCADE;" + ), + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_gpscheckin' + AND column_name = 'image_address' + ) THEN + ALTER TABLE rog_gpscheckin ADD COLUMN image_address TEXT; + END IF; + END $$; + """, + reverse_sql="ALTER TABLE rog_gpscheckin DROP COLUMN IF EXISTS image_address CASCADE;" + ), + migrations.AddField( + model_name='gpscheckin', + name='image_qr', + field=models.BooleanField(default=False, help_text='QRコードスキャンフラグ'), + ), + migrations.AddField( + model_name='gpscheckin', + name='image_receipt', + field=models.TextField(blank=True, default=False, help_text='レシート画像のパス', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='late_point', + field=models.IntegerField(blank=True, help_text='遅刻ポイント:ゴールの時刻が制限時間を超えた場合、1分につき-50点が加算。', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='lattitude', + field=models.FloatField(blank=True, help_text='緯度:写真から取得', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='longitude', + field=models.FloatField(blank=True, help_text='経度:写真から取得', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='minus_photo_flag', + field=models.BooleanField(default=False, help_text='MobServer gps_information.minus_photo_flag'), + ), + migrations.AddField( + model_name='gpscheckin', + name='path_order', + field=models.IntegerField(default=0, help_text='チェックポイントの順序番号'), + ), + migrations.AddField( + model_name='gpscheckin', + name='points', + field=models.IntegerField(blank=True, help_text='ポイント:このチェックインによる獲得ポイント。通常ポイントと買い物ポイントは分離される。ゴールの場合には減点なども含む。', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='update_at', + field=models.DateTimeField(blank=True, help_text='更新日時', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='update_user', + field=models.TextField(blank=True, help_text='更新ユーザー', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validate_location', + field=models.BooleanField(default=False, help_text='位置情報検証フラグ:画像認識で検証した結果'), + ), + migrations.AddField( + model_name='gpscheckin', + name='zekken_number', + field=models.TextField(default='', help_text='ゼッケン番号'), + ), + migrations.AddField( + model_name='gpslog', + name='buy_flag', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='colabo_company_memo', + field=models.TextField(default=''), + ), + migrations.AddField( + model_name='gpslog', + name='create_user', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='goal_time', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='image_address', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='is_service_checked', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='gpslog', + name='minus_photo_flag', + field=models.BooleanField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='score', + field=models.IntegerField(blank=True, default=0, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='scoreboard_url', + field=models.URLField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='update_at', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='update_user', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='gpslog', + name='zekken_number', + field=models.TextField(default=''), + ), + migrations.AlterField( + model_name='gpscheckin', + name='checkpoint', + field=models.ForeignKey(blank=True, help_text='統合チェックポイントリレーション', null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.checkpoint'), + ), + migrations.AlterField( + model_name='gpscheckin', + name='cp_number', + field=models.IntegerField(blank=True, help_text='チェックポイント番号', null=True), + ), + migrations.AlterField( + model_name='gpscheckin', + name='event_code', + field=models.TextField(default='', help_text='イベントコード'), + ), + migrations.AlterField( + model_name='gpscheckin', + name='id', + field=models.AutoField(primary_key=True, serialize=False), + ), + migrations.AlterField( + model_name='gpscheckin', + name='serial_number', + field=models.IntegerField(blank=True, help_text='MobServer gps_information.serial_number', null=True), + ), + migrations.AlterField( + model_name='gpscheckin', + name='team', + field=models.ForeignKey(blank=True, help_text='統合チームリレーション', null=True, on_delete=django.db.models.deletion.CASCADE, to='rog.team'), + ), + migrations.AlterField( + model_name='gpslog', + name='checkin_time', + field=models.DateTimeField(auto_now_add=True), + ), + migrations.AlterField( + model_name='gpslog', + name='cp_number', + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name='gpslog', + name='event_code', + field=models.TextField(default=''), + ), + migrations.AlterField( + model_name='gpslog', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='gpslog', + name='serial_number', + field=models.IntegerField(), + ), + migrations.AlterField( + model_name='newevent2', + name='event_code', + field=models.CharField(blank=True, max_length=50, null=True, unique=True), + ), + migrations.AlterField( + model_name='newevent2', + name='event_day', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterField( + model_name='newevent2', + name='start_time', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterField( + model_name='team', + name='created_at', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AlterField( + model_name='team', + name='trial', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='team', + name='updated_at', + field=models.DateTimeField(auto_now=True, null=True), + ), + migrations.AlterField( + model_name='team', + name='zekken_number', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterUniqueTogether( + name='gpslog', + unique_together={('serial_number', 'zekken_number', 'event_code', 'colabo_company_memo')}, + ), + migrations.AddIndex( + model_name='checkpoint', + index=django.contrib.postgres.indexes.GistIndex(fields=['location'], name='idx_checkpoint_location'), + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['zekken_number', 'event_code', 'path_order'], name='idx_zekken_event'), + ), + migrations.AddIndex( + model_name='gpscheckin', + index=models.Index(fields=['create_at'], name='idx_create_at'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['zekken_number', 'event_code'], name='gpslog_zekken_event_idx'), + ), + migrations.AddIndex( + model_name='gpslog', + index=models.Index(fields=['create_at'], name='gpslog_create_at_idx'), + ), + migrations.AddConstraint( + model_name='team', + constraint=models.UniqueConstraint(condition=models.Q(('event__isnull', False), ('zekken_number__isnull', False)), fields=('zekken_number', 'event'), name='unique_team_per_event'), + ), + migrations.AlterModelTable( + name='gpscheckin', + table='gps_checkins', + ), + + migrations.AddField( + model_name='location2025', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location2025_created', to=settings.AUTH_USER_MODEL, verbose_name='作成者'), + ), + migrations.AddField( + model_name='location2025', + name='csv_upload_user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location2025_csv_uploads', to=settings.AUTH_USER_MODEL, verbose_name='CSVアップロードユーザー'), + ), + migrations.AddField( + model_name='location2025', + name='event', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2', verbose_name='イベント'), + ), + migrations.AddField( + model_name='location2025', + name='updated_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location2025_updated', to=settings.AUTH_USER_MODEL, verbose_name='更新者'), + ), + migrations.RemoveField( + model_name='gpslog', + name='checkpoint', + ), + migrations.RemoveField( + model_name='gpslog', + name='event', + ), + migrations.RemoveField( + model_name='gpslog', + name='lat', + ), + migrations.RemoveField( + model_name='gpslog', + name='lng', + ), + migrations.RemoveField( + model_name='gpslog', + name='location', + ), + migrations.RemoveField( + model_name='gpslog', + name='team', + ), + migrations.RemoveField( + model_name='gpslog', + name='zekken', + ), + migrations.AddIndex( + model_name='location2025', + index=models.Index(fields=['event', 'cp_number'], name='location2025_event_cp_idx'), + ), + migrations.AddIndex( + model_name='location2025', + index=models.Index(fields=['event', 'is_active'], name='location2025_event_active_idx'), + ), + migrations.AddIndex( + model_name='location2025', + index=models.Index(fields=['csv_upload_date'], name='location2025_csv_date_idx'), + ), + migrations.AddIndex( + model_name='location2025', + index=django.contrib.postgres.indexes.GistIndex(fields=['location'], name='location2025_location_gist_idx'), + ), + migrations.AlterUniqueTogether( + name='location2025', + unique_together={('cp_number', 'event')}, + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0007_add_validation_fields.py b/rog/migrations_backup_20250828_132814/0007_add_validation_fields.py new file mode 100644 index 0000000..f24f915 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0007_add_validation_fields.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.9 on 2025-08-24 08:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0006_create_location2025_only'), + ] + + operations = [ + migrations.AddField( + model_name='gpscheckin', + name='validated_at', + field=models.DateTimeField(blank=True, help_text='審査日時', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validated_by', + field=models.CharField(blank=True, help_text='審査者', max_length=255, null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validation_comment', + field=models.TextField(blank=True, help_text='審査コメント・理由', null=True), + ), + migrations.AddField( + model_name='gpscheckin', + name='validation_status', + field=models.CharField(choices=[('PENDING', '審査待ち'), ('APPROVED', '承認'), ('REJECTED', '却下'), ('AUTO_APPROVED', '自動承認')], default='PENDING', help_text='通過審査ステータス', max_length=20), + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0008_auto_20250825_0716.py b/rog/migrations_backup_20250828_132814/0008_auto_20250825_0716.py new file mode 100644 index 0000000..5e0c92d --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0008_auto_20250825_0716.py @@ -0,0 +1,46 @@ +# Generated by Django 3.2.9 on 2025-08-24 22:16 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0007_add_validation_fields'), + ] + + operations = [ + # 安全な条件付きテーブル操作 + migrations.RunSQL( + """ + DO $$ + BEGIN + -- TeamStartテーブルが存在する場合のみフィールドを削除 + IF EXISTS (SELECT FROM pg_tables WHERE tablename = 'rog_teamstart') THEN + ALTER TABLE rog_teamstart DROP COLUMN IF EXISTS entry_id; + END IF; + + -- TeamGoalテーブルが存在する場合のみ削除 + IF EXISTS (SELECT FROM pg_tables WHERE tablename = 'rog_teamgoal') THEN + DROP TABLE rog_teamgoal; + END IF; + + -- TeamStartテーブルが存在する場合のみ削除 + IF EXISTS (SELECT FROM pg_tables WHERE tablename = 'rog_teamstart') THEN + DROP TABLE rog_teamstart; + END IF; + + -- zekken_labelカラムが存在しない場合のみ追加 + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'rog_entry' + AND column_name = 'zekken_label' + ) THEN + ALTER TABLE rog_entry ADD COLUMN zekken_label VARCHAR(255) NULL; + END IF; + END + $$; + """, + reverse_sql=migrations.RunSQL.noop + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0009_create_gps_tables_safe.py b/rog/migrations_backup_20250828_132814/0009_create_gps_tables_safe.py new file mode 100644 index 0000000..9232c57 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0009_create_gps_tables_safe.py @@ -0,0 +1,96 @@ +# Generated by Django 3.2.9 on 2025-08-25 09:30 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0008_auto_20250825_0716'), + ] + + operations = [ + # GPS Checkin テーブルの安全な作成 + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + -- rog_gpscheckin テーブルが存在しない場合のみ作成 + IF NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'rog_gpscheckin' + ) THEN + CREATE TABLE rog_gpscheckin ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + team_name VARCHAR(255), + cp_number VARCHAR(20), + lat DOUBLE PRECISION, + lng DOUBLE PRECISION, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + location GEOMETRY(Point, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER, + goal_time TEXT, + late_point INTEGER, + buy_flag BOOLEAN DEFAULT FALSE, + image_address TEXT, + minus_photo_flag BOOLEAN DEFAULT FALSE, + create_user TEXT, + update_user TEXT, + comment TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + + -- インデックスの作成 + CREATE INDEX IF NOT EXISTS rog_gpschec_event_c_9f1a75_idx ON rog_gpscheckin (event_code); + CREATE INDEX IF NOT EXISTS rog_gpschec_zekken_8e7f42_idx ON rog_gpscheckin (zekken); + CREATE INDEX IF NOT EXISTS rog_gpschec_serial__1b5e3a_idx ON rog_gpscheckin (serial_number); + CREATE INDEX IF NOT EXISTS rog_gpschec_cp_numb_d7c8e5_idx ON rog_gpscheckin (cp_number); + CREATE INDEX IF NOT EXISTS rog_gpscheckin_team_id_e85ab512 ON rog_gpscheckin (team_id); + END IF; + + -- rog_gpslog テーブルが存在しない場合のみ作成 + IF NOT EXISTS ( + SELECT FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'rog_gpslog' + ) THEN + CREATE TABLE rog_gpslog ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + cp_number VARCHAR(20), + lat DOUBLE PRECISION, + lng DOUBLE PRECISION, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + location GEOMETRY(Point, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER + ); + + -- インデックスの作成 + CREATE INDEX IF NOT EXISTS rog_gpslog_event_c_8a2b94_idx ON rog_gpslog (event_code); + CREATE INDEX IF NOT EXISTS rog_gpslog_zekken_7c5f39_idx ON rog_gpslog (zekken); + CREATE INDEX IF NOT EXISTS rog_gpslog_serial__6d4e28_idx ON rog_gpslog (serial_number); + CREATE INDEX IF NOT EXISTS rog_gpslog_cp_numb_5b3a17_idx ON rog_gpslog (cp_number); + END IF; + END $$; + """, + reverse_sql=""" + DROP TABLE IF EXISTS rog_gpscheckin CASCADE; + DROP TABLE IF EXISTS rog_gpslog CASCADE; + """ + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0010_safe_create_all_tables.py b/rog/migrations_backup_20250828_132814/0010_safe_create_all_tables.py new file mode 100644 index 0000000..5dbe279 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0010_safe_create_all_tables.py @@ -0,0 +1,216 @@ +# Generated for safe deployment +# Conditional SQL operations to prevent duplicate table errors + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0009_create_gps_tables_safe'), + ] + + operations = [ + # 既存のすべてのテーブルとインデックスを条件付きで作成 + migrations.RunSQL( + sql=""" + -- CustomUser テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_customuser') THEN + CREATE TABLE rog_customuser ( + id SERIAL PRIMARY KEY, + password VARCHAR(128) NOT NULL, + last_login TIMESTAMP WITH TIME ZONE, + is_superuser BOOLEAN NOT NULL, + username VARCHAR(150) NOT NULL UNIQUE, + first_name VARCHAR(150) NOT NULL, + last_name VARCHAR(150) NOT NULL, + email VARCHAR(254) NOT NULL, + is_staff BOOLEAN NOT NULL, + is_active BOOLEAN NOT NULL, + date_joined TIMESTAMP WITH TIME ZONE NOT NULL + ); + END IF; + END $$; + + -- CustomUser インデックスの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_customuser' AND indexname = 'rog_customuser_username_key') THEN + CREATE UNIQUE INDEX rog_customuser_username_key ON rog_customuser (username); + END IF; + END $$; + + -- Entry テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_entry') THEN + CREATE TABLE rog_entry ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + END IF; + END $$; + + -- Team テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_team') THEN + CREATE TABLE rog_team ( + id SERIAL PRIMARY KEY, + team_name VARCHAR(100), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + END IF; + END $$; + + -- Member テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_member') THEN + CREATE TABLE rog_member ( + id SERIAL PRIMARY KEY, + member_name VARCHAR(100), + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + ); + END IF; + END $$; + + -- Location2025 テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_location2025') THEN + CREATE TABLE rog_location2025 ( + id SERIAL PRIMARY KEY, + cp_number INTEGER, + cp_name VARCHAR(255), + latitude FLOAT, + longitude FLOAT, + location GEOMETRY(POINT, 4326), + cp_point INTEGER DEFAULT 10, + photo_point INTEGER DEFAULT 0, + buy_point INTEGER DEFAULT 0, + checkin_radius FLOAT DEFAULT 15.0, + auto_checkin BOOLEAN DEFAULT FALSE, + shop_closed BOOLEAN DEFAULT FALSE, + shop_shutdown BOOLEAN DEFAULT FALSE, + opening_hours TEXT, + address VARCHAR(512), + phone VARCHAR(32), + website VARCHAR(200), + description TEXT, + is_active BOOLEAN DEFAULT TRUE, + sort_order INTEGER DEFAULT 0, + csv_source_file VARCHAR(255), + csv_upload_date TIMESTAMP WITH TIME ZONE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + event_id INTEGER, + created_by_id INTEGER, + csv_upload_user_id INTEGER, + updated_by_id INTEGER + ); + END IF; + END $$; + + -- GPS Checkin テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_gpscheckin') THEN + CREATE TABLE rog_gpscheckin ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + team_name VARCHAR(100), + cp_number VARCHAR(20), + lat FLOAT, + lng FLOAT, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + goal_time TIMESTAMP WITH TIME ZONE, + late_point INTEGER, + buy_flag BOOLEAN DEFAULT FALSE, + image_address TEXT, + minus_photo_flag BOOLEAN DEFAULT FALSE, + create_user TEXT, + update_user TEXT, + comment TEXT, + location GEOMETRY(POINT, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER + ); + END IF; + END $$; + + -- GPS Log テーブルの安全な作成 + DO $$ + BEGIN + IF NOT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_gpslog') THEN + CREATE TABLE rog_gpslog ( + id SERIAL PRIMARY KEY, + event_code VARCHAR(50), + zekken VARCHAR(20), + serial_number VARCHAR(50), + cp_number VARCHAR(20), + lat FLOAT, + lng FLOAT, + checkin_time TIMESTAMP WITH TIME ZONE, + record_time TIMESTAMP WITH TIME ZONE, + location GEOMETRY(POINT, 4326), + mobserver_id INTEGER, + event_id INTEGER, + team_id INTEGER, + checkpoint_id INTEGER + ); + END IF; + END $$; + + -- 必要なインデックスの安全な作成 + DO $$ + BEGIN + -- GPS Checkin インデックス + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpscheckin' AND indexname = 'rog_gpscheckin_event_code_idx') THEN + CREATE INDEX rog_gpscheckin_event_code_idx ON rog_gpscheckin (event_code); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpscheckin' AND indexname = 'rog_gpscheckin_serial_number_idx') THEN + CREATE INDEX rog_gpscheckin_serial_number_idx ON rog_gpscheckin (serial_number); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpscheckin' AND indexname = 'rog_gpscheckin_team_name_idx') THEN + CREATE INDEX rog_gpscheckin_team_name_idx ON rog_gpscheckin (team_name); + END IF; + + -- GPS Log インデックス + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpslog' AND indexname = 'rog_gpslog_event_code_idx') THEN + CREATE INDEX rog_gpslog_event_code_idx ON rog_gpslog (event_code); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_gpslog' AND indexname = 'rog_gpslog_serial_number_idx') THEN + CREATE INDEX rog_gpslog_serial_number_idx ON rog_gpslog (serial_number); + END IF; + + -- Location2025 インデックス + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_location2025' AND indexname = 'rog_location2025_cp_number_idx') THEN + CREATE INDEX rog_location2025_cp_number_idx ON rog_location2025 (cp_number); + END IF; + + IF NOT EXISTS (SELECT FROM pg_indexes WHERE tablename = 'rog_location2025' AND indexname = 'rog_location2025_event_id_idx') THEN + CREATE INDEX rog_location2025_event_id_idx ON rog_location2025 (event_id); + END IF; + END $$; + """, + reverse_sql=""" + -- 逆操作は何もしない(テーブルを削除しない) + SELECT 1; + """ + ), + ] diff --git a/rog/migrations_backup_20250828_132814/0011_auto_20250827_1459.py b/rog/migrations_backup_20250828_132814/0011_auto_20250827_1459.py new file mode 100644 index 0000000..2a27907 --- /dev/null +++ b/rog/migrations_backup_20250828_132814/0011_auto_20250827_1459.py @@ -0,0 +1,245 @@ +# Generated by Django 3.2.9 on 2025-08-27 05:59 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('rog', '0010_safe_create_all_tables'), + ] + + operations = [ + migrations.CreateModel( + name='AppVersion', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('version', models.CharField(help_text='セマンティックバージョン (1.2.3)', max_length=20)), + ('platform', models.CharField(choices=[('android', 'Android'), ('ios', 'iOS')], max_length=10)), + ('build_number', models.CharField(blank=True, max_length=20, null=True)), + ('is_latest', models.BooleanField(default=False, help_text='最新版フラグ')), + ('is_required', models.BooleanField(default=False, help_text='強制更新フラグ')), + ('update_message', models.TextField(blank=True, help_text='ユーザー向け更新メッセージ', null=True)), + ('download_url', models.URLField(blank=True, help_text='アプリストアURL', null=True)), + ('release_date', models.DateTimeField(default=django.utils.timezone.now)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + options={ + 'db_table': 'app_versions', + }, + ), + migrations.CreateModel( + name='CheckinExtended', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('gps_latitude', models.DecimalField(blank=True, decimal_places=8, max_digits=10, null=True)), + ('gps_longitude', models.DecimalField(blank=True, decimal_places=8, max_digits=11, null=True)), + ('gps_accuracy', models.DecimalField(blank=True, decimal_places=2, help_text='GPS精度(メートル)', max_digits=6, null=True)), + ('gps_timestamp', models.DateTimeField(blank=True, null=True)), + ('camera_capture_time', models.DateTimeField(blank=True, null=True)), + ('device_info', models.TextField(blank=True, null=True)), + ('validation_status', models.CharField(choices=[('pending', 'Pending'), ('approved', 'Approved'), ('rejected', 'Rejected'), ('requires_review', 'Requires Review')], default='pending', max_length=20)), + ('validation_comment', models.TextField(blank=True, null=True)), + ('validated_at', models.DateTimeField(blank=True, null=True)), + ('bonus_points', models.IntegerField(default=0)), + ('scoring_breakdown', models.JSONField(blank=True, default=dict)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'rog_checkin_extended', + }, + ), + migrations.CreateModel( + name='UploadedImage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('original_filename', models.CharField(max_length=255)), + ('server_filename', models.CharField(max_length=255, unique=True)), + ('file_url', models.URLField()), + ('file_size', models.BigIntegerField()), + ('mime_type', models.CharField(choices=[('image/jpeg', 'JPEG'), ('image/png', 'PNG'), ('image/heic', 'HEIC'), ('image/webp', 'WebP')], max_length=50)), + ('event_code', models.CharField(blank=True, max_length=50, null=True)), + ('team_name', models.CharField(blank=True, max_length=255, null=True)), + ('cp_number', models.IntegerField(blank=True, null=True)), + ('upload_source', models.CharField(choices=[('direct', 'Direct'), ('sharing_intent', 'Sharing Intent'), ('bulk_upload', 'Bulk Upload')], default='direct', max_length=50)), + ('device_platform', models.CharField(blank=True, choices=[('ios', 'iOS'), ('android', 'Android'), ('web', 'Web')], max_length=20, null=True)), + ('capture_timestamp', models.DateTimeField(blank=True, null=True)), + ('upload_timestamp', models.DateTimeField(auto_now_add=True)), + ('device_info', models.TextField(blank=True, null=True)), + ('processing_status', models.CharField(choices=[('uploaded', 'Uploaded'), ('processing', 'Processing'), ('processed', 'Processed'), ('failed', 'Failed')], default='uploaded', max_length=20)), + ('thumbnail_url', models.URLField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'db_table': 'rog_uploaded_images', + }, + ), + # TeamStartテーブルのentryカラムを安全に削除 + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + IF EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'rog_teamstart') THEN + IF EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_teamstart' AND column_name = 'entry_id') THEN + ALTER TABLE rog_teamstart DROP COLUMN entry_id; + END IF; + END IF; + END $$; + """, + reverse_sql="-- No reverse SQL needed for conditional operation" + ), + # Entryテーブルに新しいフィールドを条件付きで追加 + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + -- can_access_private_events フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_entry' AND column_name = 'can_access_private_events') THEN + ALTER TABLE rog_entry ADD COLUMN can_access_private_events BOOLEAN DEFAULT FALSE; + COMMENT ON COLUMN rog_entry.can_access_private_events IS '非公開イベント参加権限'; + END IF; + + -- staff_privileges フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_entry' AND column_name = 'staff_privileges') THEN + ALTER TABLE rog_entry ADD COLUMN staff_privileges BOOLEAN DEFAULT FALSE; + COMMENT ON COLUMN rog_entry.staff_privileges IS 'スタッフ権限フラグ'; + END IF; + + -- team_validation_status フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_entry' AND column_name = 'team_validation_status') THEN + ALTER TABLE rog_entry ADD COLUMN team_validation_status VARCHAR(20) DEFAULT 'approved'; + COMMENT ON COLUMN rog_entry.team_validation_status IS 'チーム承認状況'; + END IF; + + -- zekken_label フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_entry' AND column_name = 'zekken_label') THEN + ALTER TABLE rog_entry ADD COLUMN zekken_label VARCHAR(255); + END IF; + END $$; + """, + reverse_sql="-- No reverse SQL needed for conditional operation" + ), + # GPSCheckinテーブルに新しいフィールドを条件付きで追加 + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + -- create_at フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_gpscheckin' AND column_name = 'create_at') THEN + ALTER TABLE rog_gpscheckin ADD COLUMN create_at TIMESTAMP WITH TIME ZONE; + COMMENT ON COLUMN rog_gpscheckin.create_at IS '作成日時:データの作成日時'; + END IF; + + -- create_user フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_gpscheckin' AND column_name = 'create_user') THEN + ALTER TABLE rog_gpscheckin ADD COLUMN create_user TEXT; + COMMENT ON COLUMN rog_gpscheckin.create_user IS '作成ユーザー'; + END IF; + + -- event_id フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_gpscheckin' AND column_name = 'event_id') THEN + ALTER TABLE rog_gpscheckin ADD COLUMN event_id INTEGER; + COMMENT ON COLUMN rog_gpscheckin.event_id IS 'イベントID'; + END IF; + + -- goal_time フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_gpscheckin' AND column_name = 'goal_time') THEN + ALTER TABLE rog_gpscheckin ADD COLUMN goal_time TEXT; + COMMENT ON COLUMN rog_gpscheckin.goal_time IS 'ゴール時刻=ゴール時のみ使用される。画像から時刻を読み取り設定する。'; + END IF; + + -- image_address フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_gpscheckin' AND column_name = 'image_address') THEN + ALTER TABLE rog_gpscheckin ADD COLUMN image_address TEXT; + COMMENT ON COLUMN rog_gpscheckin.image_address IS 'チェックイン画像のパス'; + END IF; + END $$; + """, + reverse_sql="-- No reverse SQL needed for conditional operation" + ), + # NewEvent2テーブルに新しいフィールドを条件付きで追加 + migrations.RunSQL( + sql=""" + DO $$ + BEGIN + -- status フィールドの追加 + IF NOT EXISTS (SELECT FROM information_schema.columns WHERE table_name = 'rog_newevent2' AND column_name = 'status') THEN + ALTER TABLE rog_newevent2 ADD COLUMN status VARCHAR(20) DEFAULT 'draft'; + COMMENT ON COLUMN rog_newevent2.status IS 'イベントステータス'; + END IF; + END $$; + """, + reverse_sql="-- No reverse SQL needed for conditional operation" + ), + migrations.AlterModelTable( + name='gpslog', + table='gps_information', + ), + migrations.DeleteModel( + name='TeamGoal', + ), + migrations.DeleteModel( + name='TeamStart', + ), + migrations.AddField( + model_name='uploadedimage', + name='entry', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rog.entry'), + ), + migrations.AddField( + model_name='uploadedimage', + name='gpslog', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rog.gpscheckin'), + ), + migrations.AddField( + model_name='checkinextended', + name='gpslog', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extended_info', to='rog.gpscheckin'), + ), + migrations.AddField( + model_name='checkinextended', + name='validated_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + migrations.AddIndex( + model_name='appversion', + index=models.Index(fields=['platform'], name='idx_app_versions_platform'), + ), + migrations.AddIndex( + model_name='appversion', + index=models.Index(condition=models.Q(('is_latest', True)), fields=['is_latest'], name='idx_app_versions_latest_true'), + ), + migrations.AlterUniqueTogether( + name='appversion', + unique_together={('version', 'platform')}, + ), + migrations.AddIndex( + model_name='uploadedimage', + index=models.Index(fields=['event_code', 'team_name'], name='idx_uploaded_event_team'), + ), + migrations.AddIndex( + model_name='uploadedimage', + index=models.Index(fields=['cp_number'], name='idx_uploaded_cp_number'), + ), + migrations.AddIndex( + model_name='uploadedimage', + index=models.Index(fields=['upload_timestamp'], name='idx_uploaded_timestamp'), + ), + migrations.AddIndex( + model_name='uploadedimage', + index=models.Index(fields=['processing_status'], name='idx_uploaded_status'), + ), + migrations.AddIndex( + model_name='checkinextended', + index=models.Index(fields=['validation_status'], name='idx_checkin_ext_valid'), + ), + migrations.AddIndex( + model_name='checkinextended', + index=models.Index(fields=['created_at'], name='idx_checkin_ext_created'), + ), + ] diff --git a/rog/migrations_backup_20250828_132814/__init__.py b/rog/migrations_backup_20250828_132814/__init__.py new file mode 100755 index 0000000..e69de29