chore: Phase 1 code quality improvements - POSIMAI_BASE_URL explicit, no emoji in logs, model comment update
Made-with: Cursor
This commit is contained in:
parent
0caf370302
commit
b3e1f5d0a3
|
|
@ -20,8 +20,11 @@ Get-Content $envFile | ForEach-Object {
|
|||
}
|
||||
}
|
||||
|
||||
$maitaKey = $env:GEMINI_API_KEY_MAITA
|
||||
$eijiKey = $env:GEMINI_API_KEY_EIJI
|
||||
$maitaKey = $env:GEMINI_API_KEY_MAITA
|
||||
$eijiKey = $env:GEMINI_API_KEY_EIJI
|
||||
# POSIMAI_BASE_URL: .env.local で上書き可能。未設定時は secrets.dart のデフォルト値と一致させる
|
||||
$posimaiBaseUrl = if ($env:POSIMAI_BASE_URL) { $env:POSIMAI_BASE_URL } else { 'https://api.soar-enrich.com' }
|
||||
|
||||
if (-not $maitaKey) { Write-Error "GEMINI_API_KEY_MAITA not set in .env.local"; exit 1 }
|
||||
if (-not $eijiKey) { Write-Error "GEMINI_API_KEY_EIJI not set in .env.local"; exit 1 }
|
||||
|
||||
|
|
@ -33,14 +36,16 @@ New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
|
|||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host " Ponshu Room - Consumer APK Build" -ForegroundColor Cyan
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host " Output: $outputDir" -ForegroundColor Gray
|
||||
Write-Host " Output: $outputDir" -ForegroundColor Gray
|
||||
Write-Host " POSIMAI_BASE_URL: $posimaiBaseUrl" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# --- 1. Maita ---
|
||||
Write-Host "[1/2] Building Maita..." -ForegroundColor Yellow
|
||||
flutter build apk --release `
|
||||
--dart-define=GEMINI_API_KEY=$maitaKey `
|
||||
--dart-define=IS_BUSINESS_APP=false
|
||||
--dart-define=IS_BUSINESS_APP=false `
|
||||
--dart-define=POSIMAI_BASE_URL=$posimaiBaseUrl
|
||||
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "Maita build failed"; exit 1 }
|
||||
|
||||
|
|
@ -53,7 +58,8 @@ Write-Host " OK: ponshu_room_consumer_maita.apk ($sz MB)" -ForegroundColor Gree
|
|||
Write-Host "[2/2] Building Eiji..." -ForegroundColor Yellow
|
||||
flutter build apk --release `
|
||||
--dart-define=GEMINI_API_KEY=$eijiKey `
|
||||
--dart-define=IS_BUSINESS_APP=false
|
||||
--dart-define=IS_BUSINESS_APP=false `
|
||||
--dart-define=POSIMAI_BASE_URL=$posimaiBaseUrl
|
||||
|
||||
if ($LASTEXITCODE -ne 0) { Write-Error "Eiji build failed"; exit 1 }
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class BackupService {
|
|||
try {
|
||||
await _googleSignIn.signInSilently();
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ サイレントサインインエラー: $e');
|
||||
debugPrint('[BACKUP] Silent sign-in error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ class BackupService {
|
|||
final account = await _googleSignIn.signIn();
|
||||
return account;
|
||||
} catch (error) {
|
||||
debugPrint('❌ Google Sign In エラー: $error');
|
||||
debugPrint('[BACKUP] Google Sign In error: $error');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -89,14 +89,14 @@ class BackupService {
|
|||
// 1. サインイン確認
|
||||
final account = _googleSignIn.currentUser;
|
||||
if (account == null) {
|
||||
debugPrint('❌ サインインが必要です');
|
||||
debugPrint('[BACKUP] Sign-in required');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Drive APIクライアントを作成
|
||||
final authClient = await _googleSignIn.authenticatedClient();
|
||||
if (authClient == null) {
|
||||
debugPrint('❌ 認証クライアントの取得に失敗しました');
|
||||
debugPrint('[BACKUP] Failed to get authenticated client');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ class BackupService {
|
|||
// 3. バックアップZIPファイルを作成
|
||||
final zipFile = await _createBackupZip();
|
||||
if (zipFile == null) {
|
||||
debugPrint('❌ バックアップファイルの作成に失敗しました');
|
||||
debugPrint('[BACKUP] Failed to create backup ZIP');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ class BackupService {
|
|||
|
||||
return success;
|
||||
} catch (error) {
|
||||
debugPrint('❌ バックアップ作成エラー: $error');
|
||||
debugPrint('[BACKUP] Backup creation error: $error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ class BackupService {
|
|||
}).toList();
|
||||
final sakeItemsFile = File(path.join(backupDir.path, 'sake_items.json'));
|
||||
await sakeItemsFile.writeAsString(json.encode(sakeItems));
|
||||
debugPrint('📄 sake_items.json 作成: ${await sakeItemsFile.length()} bytes');
|
||||
debugPrint('[BACKUP] sake_items.json created: ${await sakeItemsFile.length()} bytes');
|
||||
|
||||
// 3. settings.jsonを作成
|
||||
final settings = Map<String, dynamic>.from(settingsBox.toMap());
|
||||
|
|
@ -221,10 +221,10 @@ class BackupService {
|
|||
// 6. 一時ディレクトリを削除
|
||||
await backupDir.delete(recursive: true);
|
||||
|
||||
debugPrint('✅ バックアップZIPファイル作成完了: $zipPath');
|
||||
debugPrint('[BACKUP] ZIP created: $zipPath');
|
||||
return File(zipPath);
|
||||
} catch (error) {
|
||||
debugPrint('❌ ZIP作成エラー: $error');
|
||||
debugPrint('[BACKUP] ZIP creation error: $error');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +232,7 @@ class BackupService {
|
|||
/// Google DriveにZIPファイルをアップロード
|
||||
Future<bool> _uploadToDrive(drive.DriveApi driveApi, File zipFile) async {
|
||||
try {
|
||||
debugPrint('[BACKUP] 📤 アップロード開始: ${zipFile.lengthSync()} bytes');
|
||||
debugPrint('[BACKUP] Upload start: ${zipFile.lengthSync()} bytes');
|
||||
// 1. 既存のバックアップファイルを検索
|
||||
final fileList = await driveApi.files.list(
|
||||
q: "name = '$backupFileName' and trashed = false",
|
||||
|
|
@ -244,9 +244,9 @@ class BackupService {
|
|||
for (var file in fileList.files!) {
|
||||
try {
|
||||
await driveApi.files.delete(file.id!);
|
||||
debugPrint('🗑️ [BACKUP] 既存ファイルを削除: ${file.id}');
|
||||
debugPrint('[BACKUP] Deleted existing file: ${file.id}');
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ [BACKUP] 既存ファイル削除失敗 (無視): $e');
|
||||
debugPrint('[BACKUP] Failed to delete existing file (ignored): $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -257,7 +257,7 @@ class BackupService {
|
|||
|
||||
final media = drive.Media(zipFile.openRead(), zipFile.lengthSync());
|
||||
|
||||
debugPrint('[BACKUP] 🚀 Driveへ送信中...');
|
||||
debugPrint('[BACKUP] Uploading to Drive...');
|
||||
final uploadedFile = await driveApi.files.create(
|
||||
driveFile,
|
||||
uploadMedia: media,
|
||||
|
|
@ -266,11 +266,11 @@ class BackupService {
|
|||
});
|
||||
|
||||
if (uploadedFile.id == null) {
|
||||
debugPrint('❌ [BACKUP] ID取得失敗');
|
||||
debugPrint('[BACKUP] Upload failed: no file ID returned');
|
||||
return false;
|
||||
}
|
||||
|
||||
debugPrint('✅ [BACKUP] アップロード完了 ID: ${uploadedFile.id}');
|
||||
debugPrint('[BACKUP] Upload complete. ID: ${uploadedFile.id}');
|
||||
|
||||
// 4. 検証ステップ
|
||||
int retryCount = 0;
|
||||
|
|
@ -281,16 +281,16 @@ class BackupService {
|
|||
try {
|
||||
await driveApi.files.get(uploadedFile.id!);
|
||||
verified = true;
|
||||
debugPrint('✅ [BACKUP] 検証成功');
|
||||
debugPrint('[BACKUP] Verification succeeded');
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ [BACKUP] 検証試行 ${retryCount + 1} 失敗: $e');
|
||||
debugPrint('[BACKUP] Verification attempt ${retryCount + 1} failed: $e');
|
||||
}
|
||||
retryCount++;
|
||||
}
|
||||
|
||||
return verified;
|
||||
} catch (error) {
|
||||
debugPrint('❌ [BACKUP] アップロードエラー: $error');
|
||||
debugPrint('[BACKUP] Upload error: $error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -312,14 +312,14 @@ class BackupService {
|
|||
// 1. サインイン確認
|
||||
final account = _googleSignIn.currentUser;
|
||||
if (account == null) {
|
||||
debugPrint('❌ サインインが必要です');
|
||||
debugPrint('[RESTORE] Sign-in required');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Drive APIクライアントを作成
|
||||
final authClient = await _googleSignIn.authenticatedClient();
|
||||
if (authClient == null) {
|
||||
debugPrint('❌ 認証クライアントの取得に失敗しました');
|
||||
debugPrint('[RESTORE] Failed to get authenticated client');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ class BackupService {
|
|||
// 4. Google Driveからダウンロード
|
||||
final zipFile = await _downloadFromDrive(driveApi);
|
||||
if (zipFile == null) {
|
||||
debugPrint('❌ ダウンロードに失敗しました');
|
||||
debugPrint('[RESTORE] Download failed');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -343,7 +343,7 @@ class BackupService {
|
|||
|
||||
return success;
|
||||
} catch (error) {
|
||||
debugPrint('❌ 復元エラー: $error');
|
||||
debugPrint('[RESTORE] Restore error: $error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -358,10 +358,10 @@ class BackupService {
|
|||
if (zipFile != null) {
|
||||
await zipFile.copy(backupPath);
|
||||
await zipFile.delete();
|
||||
debugPrint('✅ 復元前のデータを退避しました: $backupPath');
|
||||
debugPrint('[RESTORE] Pre-restore backup saved: $backupPath');
|
||||
}
|
||||
} catch (error) {
|
||||
debugPrint('⚠️ データ退避エラー: $error');
|
||||
debugPrint('[RESTORE] Pre-restore backup error: $error');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ class BackupService {
|
|||
);
|
||||
|
||||
if (fileList.files == null || fileList.files!.isEmpty) {
|
||||
debugPrint('❌ バックアップファイルが見つかりません');
|
||||
debugPrint('[RESTORE] No backup file found on Drive');
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -395,10 +395,10 @@ class BackupService {
|
|||
final sink = downloadFile.openWrite();
|
||||
await media.stream.pipe(sink);
|
||||
|
||||
debugPrint('✅ ダウンロード完了: $downloadPath');
|
||||
debugPrint('[RESTORE] Download complete: $downloadPath');
|
||||
return downloadFile;
|
||||
} catch (error) {
|
||||
debugPrint('❌ ダウンロードエラー: $error');
|
||||
debugPrint('[RESTORE] Download error: $error');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -430,12 +430,12 @@ class BackupService {
|
|||
final outFile = File(extractPath);
|
||||
await outFile.create(recursive: true);
|
||||
await outFile.writeAsBytes(data);
|
||||
debugPrint('📦 展開: $filename (${data.length} bytes)');
|
||||
debugPrint('[RESTORE] Extracted: $filename (${data.length} bytes)');
|
||||
}
|
||||
}
|
||||
|
||||
// デバッグ: 展開されたファイル一覧を表示
|
||||
debugPrint('📂 展開ディレクトリの中身:');
|
||||
debugPrint('[RESTORE] Extracted directory contents:');
|
||||
extractDir.listSync(recursive: true).forEach((f) => debugPrint(' - ${path.basename(f.path)}'));
|
||||
|
||||
// 2. sake_items.jsonを検索 (ルートまたはサブディレクトリ)
|
||||
|
|
@ -446,12 +446,12 @@ class BackupService {
|
|||
sakeItemsFile = potentialFiles.firstWhere((f) => path.basename(f.path) == 'sake_items.json');
|
||||
} catch (e) {
|
||||
// 見つからない場合
|
||||
debugPrint('❌ sake_items.json が見つかりません');
|
||||
debugPrint('[RESTORE] sake_items.json not found');
|
||||
}
|
||||
|
||||
if (sakeItemsFile != null && await sakeItemsFile.exists()) {
|
||||
final sakeItemsJson = json.decode(await sakeItemsFile.readAsString()) as List;
|
||||
debugPrint('🔍 復元対象データ数: ${sakeItemsJson.length}件');
|
||||
debugPrint('[RESTORE] Items to restore: ${sakeItemsJson.length}');
|
||||
final sakeBox = Hive.box<SakeItem>('sake_items');
|
||||
|
||||
await sakeBox.clear();
|
||||
|
|
@ -499,7 +499,7 @@ class BackupService {
|
|||
// IDを保持するためにput()を使用(add()は新しいキーを生成してしまう)
|
||||
await sakeBox.put(item.id, item);
|
||||
}
|
||||
debugPrint('✅ SakeItemsを復元しました(${sakeItemsJson.length}件)');
|
||||
debugPrint('[RESTORE] SakeItems restored (${sakeItemsJson.length} items)');
|
||||
// UI更新のためにわずかに待機
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
|
@ -509,7 +509,7 @@ class BackupService {
|
|||
try {
|
||||
settingsFile = potentialFiles.firstWhere((f) => path.basename(f.path) == 'settings.json');
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ settings.json が見つかりません (スキップ)');
|
||||
debugPrint('[RESTORE] settings.json not found (skipped)');
|
||||
}
|
||||
|
||||
if (settingsFile != null && await settingsFile.exists()) {
|
||||
|
|
@ -520,7 +520,7 @@ class BackupService {
|
|||
for (var entry in settingsJson.entries) {
|
||||
await settingsBox.put(entry.key, entry.value);
|
||||
}
|
||||
debugPrint('✅ 設定を復元しました');
|
||||
debugPrint('[RESTORE] Settings restored');
|
||||
}
|
||||
|
||||
// 4. 画像ファイルを復元 (sake_items.jsonと同じ階層のimagesフォルダを探す)
|
||||
|
|
@ -538,17 +538,17 @@ class BackupService {
|
|||
await imageFile.copy(path.join(appDir.path, fileName));
|
||||
}
|
||||
}
|
||||
debugPrint('✅ 画像ファイルを復元しました(${imageFiles.length}ファイル)');
|
||||
debugPrint('[RESTORE] Images restored (${imageFiles.length} files)');
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 一時ディレクトリを削除
|
||||
await extractDir.delete(recursive: true);
|
||||
|
||||
debugPrint('✅ データの復元が完了しました');
|
||||
debugPrint('[RESTORE] Restore complete');
|
||||
return true;
|
||||
} catch (error) {
|
||||
debugPrint('❌ 復元処理エラー: $error');
|
||||
debugPrint('[RESTORE] Restore process error: $error');
|
||||
// スタックトレースも出す
|
||||
debugPrint(error.toString());
|
||||
if (error is Error) {
|
||||
|
|
@ -576,7 +576,7 @@ class BackupService {
|
|||
|
||||
return fileList.files != null && fileList.files!.isNotEmpty;
|
||||
} catch (error) {
|
||||
debugPrint('❌ バックアップ確認エラー: $error');
|
||||
debugPrint('[BACKUP] Check error: $error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,8 +199,10 @@ class GeminiService {
|
|||
}
|
||||
|
||||
// モデル候補: 503/UNAVAILABLE 時にフォールバック
|
||||
const primaryModel = 'gemini-2.5-flash'; // ⚠️ FIXED - confirmed 2026-01-17
|
||||
const fallbackModel = 'gemini-2.0-flash'; // 503 連続時のフォールバック
|
||||
// NOTE: Google は予告なしでモデルを廃止することがある。定期的に動作確認を行うこと。
|
||||
// Phase 2(プロキシ移行)後はサーバー側から設定を取得する設計に変更する予定。
|
||||
const primaryModel = 'gemini-2.5-flash';
|
||||
const fallbackModel = 'gemini-2.0-flash';
|
||||
|
||||
// Prepare Prompt (customPrompt が null のケースは通常発生しないが念のため同じ内容を保持)
|
||||
final promptText = customPrompt ?? '''
|
||||
|
|
|
|||
Loading…
Reference in New Issue