// Package main runs a daily (cron-invoked) job: for paid tiers without an // active or trialling Stripe subscription, disable Firebase login and turn // off all alert rules until billing is restored via Stripe webhook / checkout. package main import ( "context" "log" "github.com/joho/godotenv" "github.com/kjannette/koin-ping/backend/internal/config" "github.com/kjannette/koin-ping/backend/internal/database" "github.com/kjannette/koin-ping/backend/internal/firebase" "github.com/kjannette/koin-ping/backend/internal/models" ) func main() { _ = godotenv.Load() cfg, err := config.Load() if err != nil { log.Fatalf("Failed to load config: %v", err) } if err := firebase.Init(cfg.FirebaseProjectID); err != nil { log.Fatalf("Failed to initialize Firebase: %v", err) } pool, connErr := database.Connect(cfg.DSN()) if connErr != nil { log.Fatalf("Failed to connect to database: %v", connErr) } defer database.Close() ctx := context.Background() userModel := models.NewUserModel(pool) alertModel := models.NewAlertRuleModel(pool) users, listErr := userModel.ListPaidUsersWithoutActiveSubscription(ctx) if listErr != nil { log.Fatalf("Failed to list lapsed subscriptions: %v", listErr) } if len(users) == 0 { log.Println("Subscription sweep: no lapsed paid users") return } for _, u := range users { if disableErr := firebase.SetUserDisabled(ctx, u.FirebaseUID, true); disableErr != nil { log.Printf("Subscription sweep: Firebase disable failed user %s: %v", u.ID, disableErr) continue } n, rulesErr := alertModel.DisableAllForUser(ctx, u.ID) if rulesErr != nil { log.Printf("Subscription sweep: disabling alerts failed for user %s: %v", u.ID, rulesErr) continue } log.Printf( "Subscription sweep: suspended user %s (%s tier, status=%s), disabled %d alert rules", u.ID, u.SubscriptionTier, u.SubscriptionStatus, n, ) } }