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:
n.nakhostin
2025-08-13 16:52:24 +03:30
parent b7fa012d13
commit 96c21b8b78
16 changed files with 6970 additions and 7 deletions
+33 -2
View File
@@ -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)
}
}