package main import ( "github.com/food-ai/backend/internal/adapters/firebase" "github.com/food-ai/backend/internal/domain/auth" "github.com/food-ai/backend/internal/domain/diary" "github.com/food-ai/backend/internal/domain/dish" "github.com/food-ai/backend/internal/domain/home" "github.com/food-ai/backend/internal/domain/menu" "github.com/food-ai/backend/internal/domain/product" "github.com/food-ai/backend/internal/domain/recipe" "github.com/food-ai/backend/internal/domain/recognition" "github.com/food-ai/backend/internal/domain/recommendation" "github.com/food-ai/backend/internal/domain/savedrecipe" "github.com/food-ai/backend/internal/domain/user" "github.com/food-ai/backend/internal/domain/userproduct" "github.com/food-ai/backend/internal/infra/config" "github.com/jackc/pgx/v5/pgxpool" ) func initApp(appConfig *config.Config, pool *pgxpool.Pool) (*App, error) { credentialsFile := newFirebaseCredentialsFile(appConfig) tokenVerifier, firebaseError := firebase.NewAuthOrNoop(credentialsFile) if firebaseError != nil { return nil, firebaseError } userRepository := user.NewRepository(pool) mainJwtSecret := newJWTSecret(appConfig) mainJwtAccessDuration := newJWTAccessDuration(appConfig) mainJwtRefreshDuration := newJWTRefreshDuration(appConfig) jwtManager := newJWTManager(mainJwtSecret, mainJwtAccessDuration, mainJwtRefreshDuration) authService := auth.NewService(tokenVerifier, userRepository, jwtManager) authHandler := auth.NewHandler(authService) userService := user.NewService(userRepository) userHandler := user.NewHandler(userService) mainGeminiAPIKey := newOpenAIAPIKey(appConfig) openaiClient := newOpenAIClient(mainGeminiAPIKey) mainPexelsAPIKey := newPexelsAPIKey(appConfig) pexelsClient := newPexelsClient(mainPexelsAPIKey) userProductRepository := userproduct.NewRepository(pool) recommendationHandler := recommendation.NewHandler(openaiClient, openaiClient, pexelsClient, userRepository, userProductRepository) dishRepository := dish.NewRepository(pool) savedrecipeRepository := savedrecipe.NewRepository(pool, dishRepository) savedrecipeHandler := savedrecipe.NewHandler(savedrecipeRepository) productRepository := product.NewRepository(pool) openFoodFactsClient := product.NewOpenFoodFacts() productHandler := product.NewHandler(productRepository, openFoodFactsClient) userProductHandler := userproduct.NewHandler(userProductRepository) // Kafka producer kafkaProducer, kafkaProducerError := newKafkaProducer(appConfig) if kafkaProducerError != nil { return nil, kafkaProducerError } // Recognition pipeline jobRepository := recognition.NewJobRepository(pool) sseBroker := recognition.NewSSEBroker(pool, jobRepository) recognitionHandler := recognition.NewHandler(openaiClient, productRepository, jobRepository, kafkaProducer, sseBroker) menuRepository := menu.NewRepository(pool) menuHandler := menu.NewHandler(menuRepository, openaiClient, openaiClient, dishRepository, pexelsClient, userRepository, userProductRepository, dishRepository) diaryRepository := diary.NewRepository(pool) diaryHandler := diary.NewHandler(diaryRepository, dishRepository, dishRepository) homeHandler := home.NewHandler(pool) dishHandler := dish.NewHandler(dishRepository) recipeRepository := recipe.NewRepository(pool) recipeHandler := recipe.NewHandler(recipeRepository) mainJwtAdapter := newJWTAdapter(jwtManager) authMiddlewareFn := newAuthMiddleware(mainJwtAdapter) mainAllowedOrigins := newAllowedOrigins(appConfig) mainUnitsListHandler := newUnitsListHandler(pool) mainCuisineListHandler := newCuisineListHandler(pool) mainTagListHandler := newTagListHandler(pool) httpHandler := newRouter( pool, authHandler, userHandler, recommendationHandler, savedrecipeHandler, productHandler, userProductHandler, recognitionHandler, menuHandler, diaryHandler, homeHandler, dishHandler, recipeHandler, authMiddlewareFn, mainAllowedOrigins, mainUnitsListHandler, mainCuisineListHandler, mainTagListHandler, ) return &App{ handler: httpHandler, sseBroker: sseBroker, }, nil }