Add tender submission functionality and related routes
- Introduced the `tender_submission` domain, including entity, repository, service, and handler implementations for managing tender submissions. - Added new routes for both admin and public access to tender submissions, allowing for listing, ensuring, and retrieving submissions by ID and tender. - Enhanced the tender approval service to synchronize submission workflows with approval changes, ensuring proper state management. - Implemented validation and response structures for tender submission operations, improving API consistency and usability. - Added unit tests for tender submission status transitions and workflow logic, ensuring robust functionality. This update enhances the tender management system by providing comprehensive support for tender submissions, improving overall workflow and user experience.
This commit is contained in:
+10
-6
@@ -119,6 +119,7 @@ import (
|
||||
"tm/internal/notification"
|
||||
"tm/internal/tender"
|
||||
"tm/internal/tender_approval"
|
||||
"tm/internal/tender_submission"
|
||||
"tm/internal/user"
|
||||
"tm/pkg/filestore"
|
||||
"tm/pkg/security"
|
||||
@@ -201,6 +202,7 @@ func main() {
|
||||
tenderRepository := tender.NewRepository(mongoManager, logger)
|
||||
feedbackRepo := feedback.NewRepository(mongoManager, logger)
|
||||
tenderApprovalRepository := tender_approval.NewRepository(mongoManager, logger)
|
||||
tenderSubmissionRepository := tender_submission.NewRepository(mongoManager, logger)
|
||||
inquiryRepository := inquiry.NewRepository(mongoManager, logger)
|
||||
contactRepository := contact.NewContactRepository(mongoManager, logger)
|
||||
cmsRepository := cms.NewRepository(mongoManager, logger)
|
||||
@@ -210,7 +212,7 @@ func main() {
|
||||
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"},
|
||||
"repositories": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "tender_submission", "inquiry", "contact", "cms", "notice", "kanban_board", "kanban_column", "kanban_card", "notification"},
|
||||
})
|
||||
|
||||
// Initialize validation services
|
||||
@@ -262,7 +264,8 @@ func main() {
|
||||
}
|
||||
}
|
||||
feedbackService := feedback.NewService(feedbackRepo, tenderService, companyService, logger)
|
||||
tenderApprovalService := tender_approval.NewService(tenderApprovalRepository, tenderService, logger)
|
||||
tenderSubmissionService := tender_submission.NewService(tenderSubmissionRepository, tenderApprovalRepository, tenderService, logger)
|
||||
tenderApprovalService := tender_approval.NewService(tenderApprovalRepository, tenderService, logger, tenderSubmissionService)
|
||||
inquiryService := inquiry.NewService(inquiryRepository, notificationSDK, logger, xssPolicy)
|
||||
flagService := assets.NewService(logger, conf.Assets.FlagsPath)
|
||||
notificationService := notification.NewService(notificationSDK, notificationRepository, userService, customerService, logger)
|
||||
@@ -276,7 +279,7 @@ func main() {
|
||||
auditLogRepository := auditlog.NewRepository(auditStore)
|
||||
auditLogService := auditlog.NewService(auditLogRepository, 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", "ai_pipeline", "auditlog"},
|
||||
"services": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "tender_submission", "inquiry", "flag", "notification", "contact", "cms", "scraper", "kanban", "document_scraper", "dashboard", "ai_pipeline", "auditlog"},
|
||||
})
|
||||
|
||||
// Initialize handlers with services
|
||||
@@ -287,6 +290,7 @@ func main() {
|
||||
tenderHandler := tender.NewHandler(tenderService, logger)
|
||||
feedbackHandler := feedback.NewHandler(feedbackService, userHandler, customerHandler, logger)
|
||||
tenderApprovalHandler := tender_approval.NewHandler(tenderApprovalService, logger)
|
||||
tenderSubmissionHandler := tender_submission.NewHandler(tenderSubmissionService, logger)
|
||||
inquiryHandler := inquiry.NewHandler(inquiryService, logger, hcaptchaVerifier, xssPolicy)
|
||||
flagHandler := assets.NewHandler(flagService, logger)
|
||||
notificationHandler := notification.NewHandler(notificationService)
|
||||
@@ -299,7 +303,7 @@ func main() {
|
||||
aiPipelineHandler := ai_pipeline.NewHandler(aiPipelineService)
|
||||
auditLogHandler := auditlog.NewHandler(auditLogService)
|
||||
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", "ai_pipeline", "auditlog"},
|
||||
"handlers": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "tender_submission", "inquiry", "flag", "notification", "contact", "cms", "scraper", "kanban", "filestore", "document_scraper", "dashboard", "ai_pipeline", "auditlog"},
|
||||
})
|
||||
|
||||
// Initialize HTTP server
|
||||
@@ -308,8 +312,8 @@ func main() {
|
||||
router.SetupCSPSecurity(e)
|
||||
|
||||
// Register routes
|
||||
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, dashboardHandler, aiPipelineHandler, auditLogHandler, xssPolicy)
|
||||
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, xssPolicy)
|
||||
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, tenderSubmissionHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, dashboardHandler, aiPipelineHandler, auditLogHandler, xssPolicy)
|
||||
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, tenderSubmissionHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, xssPolicy)
|
||||
router.RegisterDocumentScraperRoutes(e, documentScraperHandler, conf.DocumentScraper.APIKey)
|
||||
|
||||
// Start server
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"tm/internal/notification"
|
||||
"tm/internal/tender"
|
||||
"tm/internal/tender_approval"
|
||||
"tm/internal/tender_submission"
|
||||
"tm/internal/user"
|
||||
"tm/pkg/filestore"
|
||||
"tm/pkg/security"
|
||||
@@ -36,7 +37,7 @@ func SetupCSPSecurity(e *echo.Echo) {
|
||||
e.POST("/api/v1/csp-report", security.CSPReportHandler)
|
||||
}
|
||||
|
||||
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, kanbanHandler *kanban.Handler, fileStoreHandler *filestore.Handler, dashboardHandler *dashboard.Handler, aiPipelineHandler *ai_pipeline.Handler, auditLogHandler *auditlog.Handler, xssPolicy *security.XSSPolicy) {
|
||||
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, tenderSubmissionHandler *tender_submission.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, kanbanHandler *kanban.Handler, fileStoreHandler *filestore.Handler, dashboardHandler *dashboard.Handler, aiPipelineHandler *ai_pipeline.Handler, auditLogHandler *auditlog.Handler, xssPolicy *security.XSSPolicy) {
|
||||
adminV1 := e.Group("/admin/v1")
|
||||
|
||||
// Admin Users Routes
|
||||
@@ -156,6 +157,15 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
|
||||
tenderApprovalGP.GET("/status/:status", tenderApprovalHandler.GetTenderApprovalsByStatus)
|
||||
}
|
||||
|
||||
// Admin Tender-Submissions Routes
|
||||
tenderSubmissionGP := adminV1.Group("/tender-submissions")
|
||||
{
|
||||
tenderSubmissionGP.Use(userHandler.AuthMiddleware())
|
||||
tenderSubmissionGP.GET("", tenderSubmissionHandler.AdminListSubmissions)
|
||||
tenderSubmissionGP.GET("/stats", tenderSubmissionHandler.AdminGetSubmissionStats)
|
||||
tenderSubmissionGP.GET("/:id", tenderSubmissionHandler.AdminGetSubmissionByID)
|
||||
}
|
||||
|
||||
// Admin Inquiry Routes
|
||||
inquiryGP := adminV1.Group("/inquiries")
|
||||
{
|
||||
@@ -260,7 +270,7 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, companyHandler *company.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, kanbanHandler *kanban.Handler, fileStoreHandler *filestore.Handler, xssPolicy *security.XSSPolicy) {
|
||||
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, tenderSubmissionHandler *tender_submission.Handler, companyHandler *company.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, kanbanHandler *kanban.Handler, fileStoreHandler *filestore.Handler, xssPolicy *security.XSSPolicy) {
|
||||
v1 := e.Group("/api/v1")
|
||||
|
||||
customerGP := v1.Group("/profile")
|
||||
@@ -317,6 +327,18 @@ func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tende
|
||||
tenderApprovalGP.GET("/stats", tenderApprovalHandler.GetCompanyTenderApprovalStats)
|
||||
}
|
||||
|
||||
// Public Tender Submissions Routes
|
||||
tenderSubmissionGP := v1.Group("/tender-submissions")
|
||||
{
|
||||
tenderSubmissionGP.Use(customerHandler.AuthMiddleware(), customerHandler.CompanyContextMiddleware())
|
||||
tenderSubmissionGP.GET("", tenderSubmissionHandler.ListCompanySubmissions)
|
||||
tenderSubmissionGP.GET("/stats", tenderSubmissionHandler.GetCompanySubmissionStats)
|
||||
tenderSubmissionGP.POST("/tender/:tender_id/ensure", tenderSubmissionHandler.EnsureSubmission)
|
||||
tenderSubmissionGP.GET("/tender/:tender_id", tenderSubmissionHandler.GetSubmissionByTender)
|
||||
tenderSubmissionGP.PATCH("/:id/status", tenderSubmissionHandler.UpdateSubmissionStatus)
|
||||
tenderSubmissionGP.GET("/:id", tenderSubmissionHandler.GetSubmissionByID)
|
||||
}
|
||||
|
||||
// Public Company Routes
|
||||
companiesGP := v1.Group("/companies")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user