package main import ( "context" "os" "os/signal" "syscall" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/bot/telegram" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/config" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/logger" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/provider/bybit" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/repository/postgresql" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/service/alerter" "gitea.computernetthings.ru/yash/crypto_alert_bot/internal/usecase" ) func main() { ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer cancel() // config cfg := config.MustLoad() // logger log := logger.NewAppLogger(&cfg.Logger) log.Info("app started") // storage storage, err := postgresql.New(ctx, log, &cfg.Postgresql) if err != nil { log.Error("failed to connect to postgresql", "err", err) os.Exit(1) } // usecases uc := usecase.New(log, storage) // price provider priceProvider := bybit.New(log, &cfg.Providers.Bybit) // telegram bot bot, err := telegram.New(cfg.Telegram.Token, log, uc, priceProvider) if err != nil { log.Error("failed to create telegram bot", "err", err) os.Exit(1) } // alerter service — bot acts as the notifier al := alerter.New(log, priceProvider, bot, storage) // inject alerter into bot to keep the cache in sync when alerts are created/removed bot.SetAlerter(al) // load existing active alerts into the alerter cache if err := al.LoadAlerts(ctx); err != nil { log.Error("failed to load alerts", "err", err) os.Exit(1) } // start background price-checking loop al.Run(ctx) // run bot (blocks until ctx is cancelled) bot.Run(ctx) log.Info("app stopped") }