Files
tm_back/cmd/web/main.go
T
2026-05-25 13:23:49 +03:30

278 lines
14 KiB
Go

package main
// @title Opplens API
// @version 1.0.0
// @description This is a comprehensive API for the Opplens built with Clean Architecture principles and Domain-Driven Design (DDD) patterns. The API provides endpoints for user management, customer management, company management, and authentication for both web panel administration and mobile application access.
// @termsOfService https://opplens.com/terms
// @contact.name Opplens API Support
// @contact.url https://opplens.com
// @contact.email info@opplens.com
// @license.name MIT
// @license.url https://opensource.org/licenses/MIT
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and JWT token. Example: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
// @tag.name Admin-Health
// @tag.description System health check operations for monitoring application status and dependencies
// @tag.name Admin-Authorization
// @tag.description User authentication and authorization operations including login, logout, token refresh, and password management for web panel administration
// @tag.name Admin-Users
// @tag.description Administrative user management operations including CRUD operations, role management, status updates, and profile management for web panel administrators
// @tag.name Admin-Customers
// @tag.description Administrative customer management operations for web panel including CRUD operations, company assignment, verification, status management, and comprehensive filtering with pagination
// @tag.name Admin-Companies
// @tag.description Administrative company management operations for web panel including CRUD operations, tag management, verification, status updates, comprehensive search and filtering, and statistical reporting
// @tag.name Admin-Company-Categories
// @tag.description Administrative company category management operations for web panel including CRUD operations, publish/unpublish status, and comprehensive filtering with pagination
// @tag.name Admin-Tenders
// @tag.description Administrative tender management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
// @tag.name Admin-Feedback
// @tag.description Administrative feedback management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
// @tag.name Admin-TenderApprovals
// @tag.description Administrative tender approval management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
// @tag.name Admin-Inquiries
// @tag.description Administrative inquiry management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
// @tag.name Admin-Flags
// @tag.description Administrative flag management operations for web panel including flag listing and retrieval
// @tag.name Admin-Notification
// @tag.description Administrative notification management operations for web panel including CRUD operations, bulk notifications, queue management, and comprehensive filtering with pagination
// @tag.name Admin-Contacts
// @tag.description Administrative contact management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
// @tag.name Admin-CMS
// @tag.description Administrative CMS management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
// @tag.name Authorization
// @tag.description Customer authentication and authorization operations for mobile application including login, logout, token refresh, and profile access
// @tag.name Company
// @tag.description Company information access for mobile application including company profile and company tenders
// @tag.name Tenders
// @tag.description Public tender information access for mobile application including active tender listings and detailed tender information
// @tag.name Feedback
// @tag.description Public feedback management operations for mobile application including like, dislike, and comment on tenders
// @tag.name TenderApprovals
// @tag.description Public tender approval management operations for mobile application including tender approval listing and detailed tender approval information
// @tag.name Inquiries
// @tag.description Public inquiry management operations for mobile application including inquiry submission and inquiry listing
// @tag.name Flags
// @tag.description Public flag management operations for mobile application including flag retrieval and listing
// @tag.name Notification
// @tag.description Public notification management operations for mobile application including notification listing and detailed notification information
// @tag.name Contacts
// @tag.description Public contact management operations for mobile application including contact submission and contact listing
// @tag.name CMS
// @tag.description Public CMS management operations for mobile application including CMS listing and detailed CMS information
// @tag.name Admin-Dashboard
// @tag.description Administrative dashboard analytics for the OppLens admin home page
import (
"context"
"fmt"
"net/http"
"time"
"tm/internal/assets"
"tm/internal/cms"
"tm/internal/company"
"tm/internal/company_category"
"tm/internal/contact"
"tm/internal/customer"
"tm/internal/dashboard"
"tm/internal/document_scraper"
"tm/internal/feedback"
"tm/internal/inquiry"
"tm/internal/kanban"
"tm/internal/notification"
"tm/internal/tender"
"tm/internal/tender_approval"
"tm/internal/user"
"tm/pkg/filestore"
"tm/pkg/security"
"tm/cmd/web/bootstrap"
_ "tm/cmd/web/docs" // This is generated by swag
"tm/cmd/web/router"
)
func main() {
conf := bootstrap.InitConfig()
logger := bootstrap.InitLogger(conf.Logging)
defer logger.Sync()
// Initialize MongoDB connection manager
mongoManager := bootstrap.InitMongoDB(conf.Database.MongoDB, logger)
defer func() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := mongoManager.Close(ctx); err != nil {
logger.Error("Failed to close MongoDB connection", map[string]interface{}{
"error": err.Error(),
})
}
}()
// Initialize Redis connection manager
redisClient := bootstrap.InitRedis(conf.Cache.Redis, logger)
defer func() {
if err := redisClient.Close(); err != nil {
logger.Error("Failed to close Redis connection", map[string]interface{}{
"error": err.Error(),
})
}
}()
// Initialize notification service
notificationSDK := bootstrap.InitNotificationService(conf.Notification, logger)
xssPolicy := security.NewXSSPolicy()
// Initialize file store service
fileStoreService, err := bootstrap.InitFileStore(mongoManager, logger)
if err != nil {
logger.Fatal("Failed to initialize file store service", map[string]interface{}{
"error": err.Error(),
})
}
// Initialize hCaptcha verifier
hcaptchaVerifier := bootstrap.InitHCaptchaService(conf.HCaptcha, logger)
// Initialize AI Summarizer service
var aiSummarizerClient tender.AISummarizerClient
var aiSummarizerStorage tender.AISummarizerStorage
if c := bootstrap.InitAISummarizerClient(conf.AISummarizer, logger); c != nil {
aiSummarizerClient = c
}
if s := bootstrap.InitAISummarizerStorage(conf.AISummarizer, logger); s != nil {
aiSummarizerStorage = s
}
// Initialize authorization service
userAuthService := bootstrap.InitAuthorizationService(conf.UserAuth.JWT, redisClient, logger)
customerAuthService := bootstrap.InitAuthorizationService(conf.CustomerAuth.JWT, redisClient, logger)
// Initialize repositories with MongoDB connection manager
userRepository := user.NewRepository(mongoManager, logger)
customerRepository := customer.NewRepository(mongoManager, logger)
companyRepository := company.NewRepository(mongoManager, logger)
categoryRepository := company_category.NewRepository(mongoManager, logger)
tenderRepository := tender.NewRepository(mongoManager, logger)
feedbackRepo := feedback.NewRepository(mongoManager, logger)
tenderApprovalRepository := tender_approval.NewRepository(mongoManager, logger)
inquiryRepository := inquiry.NewRepository(mongoManager, logger)
contactRepository := contact.NewContactRepository(mongoManager, logger)
cmsRepository := cms.NewRepository(mongoManager, logger)
// noticeRepository := notice.NewRepository(mongoManager, logger)
boardRepository := kanban.NewBoardRepository(mongoManager, logger)
columnRepository := kanban.NewColumnRepository(mongoManager, logger)
cardRepository := kanban.NewCardRepository(mongoManager, logger)
notificationRepository := notification.NewRepository(mongoManager, logger)
logger.Info("Repositories initialized successfully", map[string]interface{}{
"repositories": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "contact", "cms", "notice", "kanban_board", "kanban_column", "kanban_card", "notification"},
})
// Initialize validation services
userValidator := user.NewValidationService()
customerValidator := customer.NewValidationService()
_ = kanban.NewValidationService() // Register hexcolor validator
// Initialize services with repositories
userService := user.NewService(userRepository, logger, userAuthService, userValidator, notificationSDK)
categoryService := company_category.NewService(categoryRepository, logger)
companyService := company.NewService(companyRepository, categoryService, logger)
customerService := customer.NewService(customerRepository, logger, customerAuthService, companyService, redisClient, notificationSDK, customerValidator)
tenderService := tender.NewService(tenderRepository, companyService, customerService, logger, aiSummarizerClient, aiSummarizerStorage, conf.AISummarizer.DefaultLanguage)
feedbackService := feedback.NewService(feedbackRepo, tenderService, companyService, logger)
tenderApprovalService := tender_approval.NewService(tenderApprovalRepository, tenderService, logger)
inquiryService := inquiry.NewService(inquiryRepository, notificationSDK, logger, xssPolicy)
flagService := assets.NewService(logger, conf.Assets.FlagsPath)
notificationService := notification.NewService(notificationSDK, notificationRepository, userService, customerService, logger)
contactService := contact.NewService(contactRepository, logger, notificationSDK)
cmsService := cms.NewService(cmsRepository, logger)
kanbanService := kanban.NewService(boardRepository, columnRepository, cardRepository, logger)
documentScraperService := document_scraper.NewService(tenderRepository, logger)
dashboardRepository := dashboard.NewRepository(mongoManager, logger)
dashboardService := dashboard.NewService(dashboardRepository, logger)
logger.Info("Services initialized successfully", map[string]interface{}{
"services": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification", "contact", "cms", "scraper", "kanban", "document_scraper", "dashboard"},
})
// Initialize handlers with services
userHandler := user.NewHandler(userService, logger, userValidator, userAuthService)
customerHandler := customer.NewHandler(customerService, userHandler, customerAuthService, logger, customerValidator)
companyHandler := company.NewHandler(companyService, userHandler, logger)
categoryHandler := company_category.NewHandler(categoryService, logger)
tenderHandler := tender.NewHandler(tenderService, logger)
feedbackHandler := feedback.NewHandler(feedbackService, userHandler, customerHandler, logger)
tenderApprovalHandler := tender_approval.NewHandler(tenderApprovalService, logger)
inquiryHandler := inquiry.NewHandler(inquiryService, logger, hcaptchaVerifier, xssPolicy)
flagHandler := assets.NewHandler(flagService, logger)
notificationHandler := notification.NewHandler(notificationService)
contactHandler := contact.NewHandler(contactService, hcaptchaVerifier)
cmsHandler := cms.NewHandler(cmsService)
kanbanHandler := kanban.NewHandler(kanbanService)
fileStoreHandler := filestore.NewHandler(fileStoreService, logger)
documentScraperHandler := document_scraper.NewHandler(documentScraperService, logger)
dashboardHandler := dashboard.NewHandler(dashboardService)
logger.Info("Handlers initialized successfully", map[string]interface{}{
"handlers": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification", "contact", "cms", "scraper", "kanban", "filestore", "document_scraper", "dashboard"},
})
// Initialize HTTP server
e := bootstrap.InitHTTPServer(conf, logger)
router.SetupCSPSecurity(e)
// Register routes
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, dashboardHandler, xssPolicy)
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, fileStoreHandler, xssPolicy)
router.RegisterDocumentScraperRoutes(e, documentScraperHandler, conf.DocumentScraper.APIKey)
// Start server
serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port)
logger.Info("HTTP server starting", map[string]interface{}{
"address": serverAddr,
"version": "1.0.0",
"host": conf.Server.Host,
"port": conf.Server.Port,
})
if err := e.Start(serverAddr); err != nil && err != http.ErrServerClosed {
logger.Error("Failed to start HTTP server", map[string]interface{}{
"error": err.Error(),
"address": serverAddr,
"version": "1.0.0",
"host": conf.Server.Host,
"port": conf.Server.Port,
})
panic(fmt.Sprintf("Failed to start HTTP server: %v", err))
}
}