Implement TED Scraper and Configuration Management
- Introduced a new TED scraper in `cmd/scraper` to handle downloading and parsing TED XML files. - Added configuration management for the scraper, including a new `Config` struct and YAML configuration file. - Created necessary handler, service, and repository layers for tender management, adhering to Clean Architecture principles. - Implemented comprehensive logging and error handling throughout the scraper functionality. - Updated API routes to include tender management operations, enhancing the overall system capabilities.
This commit is contained in:
+18
-5
@@ -35,9 +35,18 @@ package main
|
||||
// @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-Tenders
|
||||
// @tag.description Administrative tender management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
|
||||
|
||||
// @tag.name Admin-Scraping
|
||||
// @tag.description Administrative scraping job management operations for TED XML data collection including job control, monitoring, and status tracking
|
||||
|
||||
// @tag.name Authorization
|
||||
// @tag.description Customer authentication and authorization operations for mobile application including login, logout, token refresh, and profile access
|
||||
|
||||
// @tag.name Tenders
|
||||
// @tag.description Public tender information access for mobile application including active tender listings and detailed tender information
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
@@ -45,6 +54,7 @@ import (
|
||||
"time"
|
||||
"tm/internal/company"
|
||||
"tm/internal/customer"
|
||||
"tm/internal/tender"
|
||||
"tm/internal/user"
|
||||
|
||||
_ "tm/cmd/web/docs" // This is generated by swag
|
||||
@@ -87,9 +97,10 @@ func main() {
|
||||
userRepository := user.NewUserRepository(mongoManager, logger)
|
||||
customerRepository := customer.NewCustomerRepository(mongoManager, logger)
|
||||
companyRepository := company.NewCompanyRepository(mongoManager, logger)
|
||||
tenderRepository := tender.NewTenderRepository(mongoManager, logger)
|
||||
|
||||
logger.Info("Repositories initialized successfully", map[string]interface{}{
|
||||
"repositories": []string{"customer", "user", "company"},
|
||||
"repositories": []string{"customer", "user", "company", "tender"},
|
||||
})
|
||||
|
||||
// Initialize validation service
|
||||
@@ -99,26 +110,28 @@ func main() {
|
||||
userService := user.NewUserService(userRepository, logger, userAuthService, userValidator)
|
||||
companyService := company.NewCompanyService(companyRepository, logger)
|
||||
customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService, companyService)
|
||||
tenderService := tender.NewTenderService(tenderRepository, logger)
|
||||
|
||||
logger.Info("Services initialized successfully", map[string]interface{}{
|
||||
"services": []string{"customer", "user", "company"},
|
||||
"services": []string{"customer", "user", "company", "tender"},
|
||||
})
|
||||
|
||||
// Initialize handlers with services
|
||||
userHandler := user.NewUserHandler(userService, logger, userValidator, userAuthService)
|
||||
customerHandler := customer.NewHandler(customerService, userHandler, customerAuthService, logger)
|
||||
companyHandler := company.NewHandler(companyService, userHandler, logger)
|
||||
tenderHandler := tender.NewTenderHandler(tenderService, logger)
|
||||
|
||||
logger.Info("Handlers initialized successfully", map[string]interface{}{
|
||||
"handlers": []string{"customer", "user", "company"},
|
||||
"handlers": []string{"customer", "user", "company", "tender"},
|
||||
})
|
||||
|
||||
// Initialize HTTP server
|
||||
e := initHTTPServer(conf, logger)
|
||||
|
||||
// Register routes
|
||||
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler)
|
||||
router.RegisterPublicRoutes(e, customerHandler)
|
||||
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler)
|
||||
router.RegisterPublicRoutes(e, customerHandler, tenderHandler)
|
||||
|
||||
// Start server
|
||||
serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port)
|
||||
|
||||
@@ -3,12 +3,13 @@ package router
|
||||
import (
|
||||
"tm/internal/company"
|
||||
"tm/internal/customer"
|
||||
"tm/internal/tender"
|
||||
"tm/internal/user"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler) {
|
||||
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler) {
|
||||
adminV1 := e.Group("/admin/v1")
|
||||
|
||||
// Admin Users Routes
|
||||
@@ -87,9 +88,33 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
|
||||
customersGP.POST("/:id/companies/assign", customerHandler.AssignCompaniesToCustomer)
|
||||
customersGP.POST("/:id/companies/remove", customerHandler.RemoveCompaniesFromCustomer)
|
||||
}
|
||||
|
||||
// Admin Tenders Routes
|
||||
tendersGP := adminV1.Group("/tenders")
|
||||
{
|
||||
tendersGP.Use(userHandler.AuthMiddleware())
|
||||
tendersGP.POST("", tenderHandler.CreateTender)
|
||||
tendersGP.GET("", tenderHandler.ListTenders)
|
||||
tendersGP.GET("/:id", tenderHandler.GetTender)
|
||||
tendersGP.PUT("/:id", tenderHandler.UpdateTender)
|
||||
tendersGP.DELETE("/:id", tenderHandler.DeleteTender)
|
||||
tendersGP.POST("/search", tenderHandler.SearchTenders)
|
||||
tendersGP.GET("/statistics", tenderHandler.GetTenderStatistics)
|
||||
tendersGP.GET("/dashboard", tenderHandler.GetDashboard)
|
||||
}
|
||||
|
||||
// Admin Scraping Routes
|
||||
scrapingGP := adminV1.Group("/scraping")
|
||||
{
|
||||
scrapingGP.Use(userHandler.AuthMiddleware())
|
||||
scrapingGP.POST("/jobs", tenderHandler.StartScrapingJob)
|
||||
scrapingGP.GET("/jobs", tenderHandler.ListScrapingJobs)
|
||||
scrapingGP.GET("/jobs/:id", tenderHandler.GetScrapingJob)
|
||||
scrapingGP.POST("/jobs/:id/cancel", tenderHandler.CancelScrapingJob)
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler) {
|
||||
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler) {
|
||||
v1 := e.Group("/api/v1")
|
||||
|
||||
customerGP := v1.Group("/profile")
|
||||
@@ -103,4 +128,10 @@ func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler) {
|
||||
profileGP.DELETE("/logout", customerHandler.Logout)
|
||||
}
|
||||
|
||||
// Public Tenders Routes
|
||||
tendersGP := v1.Group("/tenders")
|
||||
{
|
||||
tendersGP.GET("", tenderHandler.GetPublicTenders)
|
||||
tendersGP.GET("/:id", tenderHandler.GetPublicTenderDetails)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user