mnemo_cards/mnemo_cards_backend/lib/main.dart

158 lines
5.1 KiB
Dart
Raw Normal View History

2025-11-16 11:25:27 +00:00
import 'dart:developer';
import 'dart:io';
import 'package:mnemo_cards_backend/api/mnemo_shelf.dart';
import 'package:mnemo_cards_backend/cron/add_free_packs.dart';
import 'package:mnemo_cards_backend/cron/backup.dart';
import 'package:mnemo_cards_backend/cron/cron_executor.dart';
import 'package:mnemo_cards_backend/cron/generate_promocodes.dart';
2025-12-13 13:27:05 +00:00
import 'package:mnemo_cards_backend/database/database.dart';
2025-11-16 11:25:27 +00:00
import 'package:mnemo_cards_backend/discounts/discounts_manager.dart';
import 'package:mnemo_cards_backend/user/user_manager.dart';
import 'package:mnemo_cards_backend/tests/test_manager.dart';
2026-01-08 16:32:25 +00:00
import 'package:mnemo_cards_backend/user/user_repository.dart';
2025-11-16 11:25:27 +00:00
import 'api/di/injector.dart';
import 'cron/check_admins.dart';
import 'cron/check_payment.dart';
import 'cron/delete_old_archives.dart';
import 'cron/discount_campaign_task.dart';
import 'cron/tasks_seeder.dart';
import 'cron/test_generator.dart';
import 'cron/update_online_users.dart';
import 'packs/free_packs_distributor.dart';
2025-12-19 00:56:58 +00:00
import 'storage/minio_service.dart';
2025-11-16 11:25:27 +00:00
2025-12-13 13:27:05 +00:00
late AppDatabase database;
2025-11-16 11:25:27 +00:00
late final String WORK_DIR;
2025-12-13 13:27:05 +00:00
/// Инициализация подключения к PostgreSQL
Future<AppDatabase> _initDatabase() async {
2025-12-11 20:57:26 +00:00
var attempt = 0;
2025-12-13 13:27:05 +00:00
const maxAttempts = 5;
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
while (attempt < maxAttempts) {
print('Attempt ${attempt + 1}/$maxAttempts to connect to PostgreSQL...');
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
try {
// Создать подключение из environment variables
final db = AppDatabase.fromEnvironment();
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
// Проверить подключение
await db.customSelect('SELECT 1').getSingle();
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
print('✅ Successfully connected to PostgreSQL');
return database = db;
} catch (e, s) {
print('❌ Error connecting to PostgreSQL: $e');
log('Error connecting to PostgreSQL: $e', error: e, stackTrace: s);
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
attempt++;
if (attempt < maxAttempts) {
final delay = Duration(seconds: attempt * 5);
print('Retrying in ${delay.inSeconds} seconds...');
await Future.delayed(delay);
}
}
2025-12-11 20:57:26 +00:00
}
2025-12-20 18:26:15 +00:00
throw Exception(
'Failed to connect to PostgreSQL after $maxAttempts attempts',
);
2025-12-11 20:57:26 +00:00
}
2025-12-11 17:49:15 +00:00
void main() async {
2025-12-13 13:27:05 +00:00
print('🚀 Starting Mnemo Cards Backend...');
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
// Читаем environment variables
final backupDir = Platform.environment['BACKUP_DIR'] ?? '../backups/';
2025-12-11 17:49:15 +00:00
WORK_DIR = Platform.environment['WORK_DIR'] ?? '/root/mnemo_cards_backend';
2025-12-20 18:26:15 +00:00
final debugMode =
Platform.environment['DEBUG'] == 'true' ||
2025-12-13 13:27:05 +00:00
Platform.environment['DEBUG'] == '1';
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
print('📂 Working directory: $WORK_DIR');
print('🐛 Debug mode: $debugMode');
2025-12-20 18:26:15 +00:00
2025-11-16 11:25:27 +00:00
print(
'running server in ${(await Process.run('pwd', [], runInShell: true)).stdout}',
);
// For rustore payments
2025-12-13 14:48:00 +00:00
// final rustoreEnabled = false;
// if (rustoreEnabled) {
// final pythonInit = await Process.run(
// workingDirectory: WORK_DIR,
// './prepare_python.sh',
// [],
// runInShell: true,
// );
// print(pythonInit.stdout);
// print(pythonInit.stderr);
// } else {
// log('\n\n*******\nRUSTORE IS DISABLED\n******\n\n', level: 1000);
// }
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
// Инициализация PostgreSQL
try {
await _initDatabase();
2025-12-20 18:26:15 +00:00
2025-12-13 22:10:19 +00:00
// Настройка зависимостей (AppDatabase уже регистрируется через @singleton в modules.dart)
2025-12-13 13:27:05 +00:00
configureDependencies();
2025-12-20 18:26:15 +00:00
2025-12-19 00:56:58 +00:00
// Инициализация MinIO
print('📦 Initializing MinIO...');
try {
await getIt<MinioService>().ensureBucketsExist();
print('✅ MinIO initialized successfully');
} catch (e, s) {
print('❌ Error initializing MinIO: $e');
log('Error initializing MinIO: $e', error: e, stackTrace: s);
// Не прерываем запуск, но логируем ошибку
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
// Запуск API сервера
print('🌐 Starting API server...');
await getIt<MnemoShelf>().initV2();
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
// Запуск cron jobs
print('⏰ Starting cron jobs...');
// ignore: unawaited_futures
CronManager([
DeleteOldArchives(),
2026-01-08 16:32:25 +00:00
CheckAdminsTask(getIt.get<UserRepository>()),
2025-12-13 13:27:05 +00:00
getIt.get<CheckPaymentTask>(),
2026-01-08 16:32:25 +00:00
AddFreePacks(getIt.get<FreePacksDistributor>(), getIt.get<UserRepository>()),
2025-12-13 13:27:05 +00:00
Backup(backupDir),
2025-12-13 14:48:00 +00:00
GeneratePromocodes(database),
DiscountCampaignTask(getIt.get<DiscountsManager>(), database),
2025-12-13 13:27:05 +00:00
UpdateOnlineUsersTask(getIt.get<UserManager>()),
2025-12-13 14:48:00 +00:00
TasksSeederTask(database),
2025-12-16 23:26:49 +00:00
TestGeneratorTask(getIt.get<TestManager>(), database),
2025-12-13 13:27:05 +00:00
]).init();
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
print('✅ Backend started successfully!');
} catch (e, s) {
print('❌ Fatal error starting backend: $e');
log('Fatal error starting backend: $e', error: e, stackTrace: s);
exit(1);
}
2025-12-20 18:26:15 +00:00
2025-12-13 13:27:05 +00:00
// Обработка SIGTERM для graceful shutdown
2025-12-11 20:50:30 +00:00
ProcessSignal.sigterm.watch().listen((signal) async {
2025-12-13 13:27:05 +00:00
print('🛑 Received SIGTERM, shutting down gracefully...');
2025-12-20 18:26:15 +00:00
2025-12-11 20:57:26 +00:00
try {
2025-12-13 13:27:05 +00:00
// Закрыть подключение к БД
await database.close();
print('✅ Database connection closed');
2025-12-11 20:57:26 +00:00
} catch (e, s) {
2025-12-13 13:27:05 +00:00
print('❌ Error closing database: $e');
log('Error closing database: $e', error: e, stackTrace: s);
2025-12-11 20:57:26 +00:00
}
2025-12-20 18:26:15 +00:00
2025-12-11 20:50:30 +00:00
exit(0);
});
2025-11-16 11:25:27 +00:00
}