mnemo_cards/mnemo_cards_backend/lib/main.dart
Dmitry 0f49280805
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Mobile App CI / test (push) Waiting to run
Mobile App CI / build-android (push) Blocked by required conditions
Mobile App CI / build-ios (push) Blocked by required conditions
Web App CI / test (push) Waiting to run
Web App CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Deploy Telegram Bot / Deploy Telegram Bot (push) Waiting to run
fixes and format
2025-12-20 21:26:15 +03:00

156 lines
5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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';
import 'package:mnemo_cards_backend/database/database.dart';
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';
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';
import 'storage/minio_service.dart';
late AppDatabase database;
late final String WORK_DIR;
/// Инициализация подключения к PostgreSQL
Future<AppDatabase> _initDatabase() async {
var attempt = 0;
const maxAttempts = 5;
while (attempt < maxAttempts) {
print('Attempt ${attempt + 1}/$maxAttempts to connect to PostgreSQL...');
try {
// Создать подключение из environment variables
final db = AppDatabase.fromEnvironment();
// Проверить подключение
await db.customSelect('SELECT 1').getSingle();
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);
attempt++;
if (attempt < maxAttempts) {
final delay = Duration(seconds: attempt * 5);
print('Retrying in ${delay.inSeconds} seconds...');
await Future.delayed(delay);
}
}
}
throw Exception(
'Failed to connect to PostgreSQL after $maxAttempts attempts',
);
}
void main() async {
print('🚀 Starting Mnemo Cards Backend...');
// Читаем environment variables
final backupDir = Platform.environment['BACKUP_DIR'] ?? '../backups/';
WORK_DIR = Platform.environment['WORK_DIR'] ?? '/root/mnemo_cards_backend';
final debugMode =
Platform.environment['DEBUG'] == 'true' ||
Platform.environment['DEBUG'] == '1';
print('📂 Working directory: $WORK_DIR');
print('🐛 Debug mode: $debugMode');
print(
'running server in ${(await Process.run('pwd', [], runInShell: true)).stdout}',
);
// For rustore payments
// 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);
// }
// Инициализация PostgreSQL
try {
await _initDatabase();
// Настройка зависимостей (AppDatabase уже регистрируется через @singleton в modules.dart)
configureDependencies();
// Инициализация 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);
// Не прерываем запуск, но логируем ошибку
}
// Запуск API сервера
print('🌐 Starting API server...');
await getIt<MnemoShelf>().initV2();
// Запуск cron jobs
print('⏰ Starting cron jobs...');
// ignore: unawaited_futures
CronManager([
DeleteOldArchives(),
CheckAdminsTask(database),
getIt.get<CheckPaymentTask>(),
AddFreePacks(getIt.get<FreePacksDistributor>(), database),
Backup(backupDir),
GeneratePromocodes(database),
DiscountCampaignTask(getIt.get<DiscountsManager>(), database),
UpdateOnlineUsersTask(getIt.get<UserManager>()),
TasksSeederTask(database),
TestGeneratorTask(getIt.get<TestManager>(), database),
]).init();
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);
}
// Обработка SIGTERM для graceful shutdown
ProcessSignal.sigterm.watch().listen((signal) async {
print('🛑 Received SIGTERM, shutting down gracefully...');
try {
// Закрыть подключение к БД
await database.close();
print('✅ Database connection closed');
} catch (e, s) {
print('❌ Error closing database: $e');
log('Error closing database: $e', error: e, stackTrace: s);
}
exit(0);
});
}