Refactor Feedback Module for Consistency and Clarity

- Updated feedback repository and service methods to use a consistent naming convention, changing `NewTenderRepository` and similar methods to `NewRepository`.
- Refactored feedback handler methods to improve clarity by renaming methods such as `ListFeedback` to `Search` and `GetFeedback` to `Get`.
- Enhanced feedback response structures to include detailed company and tender information, improving the clarity of feedback data returned to API consumers.
- Updated Swagger documentation to reflect changes in feedback response structures and endpoint paths, ensuring accurate representation of the API for consumers.
This commit is contained in:
n.nakhostin
2025-09-24 12:20:19 +03:30
parent cdf15c9d49
commit a342da193e
29 changed files with 666 additions and 702 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ func InitMongoDB(conf config.MongoConfig, log logger.Logger) *mongo.ConnectionMa
// init TED scraper
func InitTEDScraper(config Config, mongoManager *mongo.ConnectionManager, appLogger logger.Logger) {
// Initialize tender repository
tenderRepo := tender.NewTenderRepository(mongoManager, appLogger)
tenderRepo := tender.NewRepository(mongoManager, appLogger)
// Initialize TED scraper
tedScraper := ted.NewTEDScraper(
+102 -22
View File
@@ -5026,7 +5026,7 @@ const docTemplate = `{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.CompanyFeedbackStatsResponse"
"$ref": "#/definitions/feedback.StatsResponse"
}
}
}
@@ -7675,27 +7675,6 @@ const docTemplate = `{
}
}
},
"feedback.CompanyFeedbackStatsResponse": {
"type": "object",
"properties": {
"company_id": {
"type": "string"
},
"last_updated": {
"description": "Unix timestamp",
"type": "integer"
},
"total_dislikes": {
"type": "integer"
},
"total_feedback": {
"type": "integer"
},
"total_likes": {
"type": "integer"
}
}
},
"feedback.FeedbackListResponse": {
"type": "object",
"properties": {
@@ -7713,6 +7692,9 @@ const docTemplate = `{
"feedback.FeedbackResponse": {
"type": "object",
"properties": {
"company": {
"$ref": "#/definitions/feedback.companyResponse"
},
"company_id": {
"type": "string"
},
@@ -7729,6 +7711,9 @@ const docTemplate = `{
"type": "string"
},
"tender": {
"$ref": "#/definitions/feedback.tenderResponse"
},
"tender_id": {
"type": "string"
},
"updated_at": {
@@ -7747,6 +7732,29 @@ const docTemplate = `{
"FeedbackTypeDislike"
]
},
"feedback.StatsResponse": {
"type": "object",
"properties": {
"company": {
"$ref": "#/definitions/feedback.companyResponse"
},
"company_id": {
"type": "string"
},
"last_updated": {
"type": "integer"
},
"total_dislikes": {
"type": "integer"
},
"total_feedback": {
"type": "integer"
},
"total_likes": {
"type": "integer"
}
}
},
"feedback.ToggleFeedbackForm": {
"type": "object",
"required": [
@@ -7770,6 +7778,78 @@ const docTemplate = `{
}
}
},
"feedback.companyResponse": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"feedback.organizationResponse": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"feedback.tenderResponse": {
"type": "object",
"properties": {
"buyer_organization": {
"$ref": "#/definitions/feedback.organizationResponse"
},
"country_code": {
"type": "string"
},
"currency": {
"type": "string"
},
"description": {
"type": "string"
},
"duration": {
"type": "string"
},
"duration_unit": {
"type": "string"
},
"estimated_value": {
"type": "number"
},
"id": {
"type": "string"
},
"notice_publication_id": {
"type": "string"
},
"procedure_code": {
"type": "string"
},
"procurement_type_code": {
"type": "string"
},
"publication_date": {
"type": "integer"
},
"status": {
"type": "string"
},
"submission_deadline": {
"type": "integer"
},
"tender_deadline": {
"type": "integer"
},
"title": {
"type": "string"
}
}
},
"inquiry.CreateInquiryForm": {
"type": "object",
"properties": {
+102 -22
View File
@@ -5020,7 +5020,7 @@
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.CompanyFeedbackStatsResponse"
"$ref": "#/definitions/feedback.StatsResponse"
}
}
}
@@ -7669,27 +7669,6 @@
}
}
},
"feedback.CompanyFeedbackStatsResponse": {
"type": "object",
"properties": {
"company_id": {
"type": "string"
},
"last_updated": {
"description": "Unix timestamp",
"type": "integer"
},
"total_dislikes": {
"type": "integer"
},
"total_feedback": {
"type": "integer"
},
"total_likes": {
"type": "integer"
}
}
},
"feedback.FeedbackListResponse": {
"type": "object",
"properties": {
@@ -7707,6 +7686,9 @@
"feedback.FeedbackResponse": {
"type": "object",
"properties": {
"company": {
"$ref": "#/definitions/feedback.companyResponse"
},
"company_id": {
"type": "string"
},
@@ -7723,6 +7705,9 @@
"type": "string"
},
"tender": {
"$ref": "#/definitions/feedback.tenderResponse"
},
"tender_id": {
"type": "string"
},
"updated_at": {
@@ -7741,6 +7726,29 @@
"FeedbackTypeDislike"
]
},
"feedback.StatsResponse": {
"type": "object",
"properties": {
"company": {
"$ref": "#/definitions/feedback.companyResponse"
},
"company_id": {
"type": "string"
},
"last_updated": {
"type": "integer"
},
"total_dislikes": {
"type": "integer"
},
"total_feedback": {
"type": "integer"
},
"total_likes": {
"type": "integer"
}
}
},
"feedback.ToggleFeedbackForm": {
"type": "object",
"required": [
@@ -7764,6 +7772,78 @@
}
}
},
"feedback.companyResponse": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"feedback.organizationResponse": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"feedback.tenderResponse": {
"type": "object",
"properties": {
"buyer_organization": {
"$ref": "#/definitions/feedback.organizationResponse"
},
"country_code": {
"type": "string"
},
"currency": {
"type": "string"
},
"description": {
"type": "string"
},
"duration": {
"type": "string"
},
"duration_unit": {
"type": "string"
},
"estimated_value": {
"type": "number"
},
"id": {
"type": "string"
},
"notice_publication_id": {
"type": "string"
},
"procedure_code": {
"type": "string"
},
"procurement_type_code": {
"type": "string"
},
"publication_date": {
"type": "integer"
},
"status": {
"type": "string"
},
"submission_deadline": {
"type": "integer"
},
"tender_deadline": {
"type": "integer"
},
"title": {
"type": "string"
}
}
},
"inquiry.CreateInquiryForm": {
"type": "object",
"properties": {
+67 -15
View File
@@ -512,20 +512,6 @@ definitions:
example: reset_token_here
type: string
type: object
feedback.CompanyFeedbackStatsResponse:
properties:
company_id:
type: string
last_updated:
description: Unix timestamp
type: integer
total_dislikes:
type: integer
total_feedback:
type: integer
total_likes:
type: integer
type: object
feedback.FeedbackListResponse:
properties:
feedback:
@@ -537,6 +523,8 @@ definitions:
type: object
feedback.FeedbackResponse:
properties:
company:
$ref: '#/definitions/feedback.companyResponse'
company_id:
type: string
created_at:
@@ -548,6 +536,8 @@ definitions:
id:
type: string
tender:
$ref: '#/definitions/feedback.tenderResponse'
tender_id:
type: string
updated_at:
type: integer
@@ -560,6 +550,21 @@ definitions:
x-enum-varnames:
- FeedbackTypeLike
- FeedbackTypeDislike
feedback.StatsResponse:
properties:
company:
$ref: '#/definitions/feedback.companyResponse'
company_id:
type: string
last_updated:
type: integer
total_dislikes:
type: integer
total_feedback:
type: integer
total_likes:
type: integer
type: object
feedback.ToggleFeedbackForm:
properties:
feedback_type:
@@ -574,6 +579,53 @@ definitions:
- feedback_type
- tender_id
type: object
feedback.companyResponse:
properties:
id:
type: string
name:
type: string
type: object
feedback.organizationResponse:
properties:
name:
type: string
type: object
feedback.tenderResponse:
properties:
buyer_organization:
$ref: '#/definitions/feedback.organizationResponse'
country_code:
type: string
currency:
type: string
description:
type: string
duration:
type: string
duration_unit:
type: string
estimated_value:
type: number
id:
type: string
notice_publication_id:
type: string
procedure_code:
type: string
procurement_type_code:
type: string
publication_date:
type: integer
status:
type: string
submission_deadline:
type: integer
tender_deadline:
type: integer
title:
type: string
type: object
inquiry.CreateInquiryForm:
properties:
company_name:
@@ -4508,7 +4560,7 @@ paths:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/feedback.CompanyFeedbackStatsResponse'
$ref: '#/definitions/feedback.StatsResponse'
type: object
"400":
description: Bad request - Missing company association
+21 -21
View File
@@ -134,14 +134,14 @@ func main() {
customerAuthService := bootstrap.InitAuthorizationService(conf.CustomerAuth.JWT, redisClient, logger)
// Initialize repositories with MongoDB connection manager
userRepository := user.NewUserRepository(mongoManager, logger)
customerRepository := customer.NewCustomerRepository(mongoManager, logger)
companyRepository := company.NewCompanyRepository(mongoManager, logger)
categoryRepository := company_category.NewCategoryRepository(mongoManager, logger)
tenderRepository := tender.NewTenderRepository(mongoManager, logger)
feedbackRepo := feedback.NewFeedbackRepository(mongoManager, logger)
tenderApprovalRepository := tender_approval.NewTenderApprovalRepository(mongoManager, logger)
inquiryRepository := inquiry.NewInquiryRepository(mongoManager, logger)
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)
logger.Info("Repositories initialized successfully", map[string]interface{}{
"repositories": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry"},
})
@@ -150,27 +150,27 @@ func main() {
userValidator := user.NewValidationService()
// Initialize services with repositories
userService := user.NewUserService(userRepository, logger, userAuthService, userValidator, notificationSDK)
categoryService := company_category.NewCategoryService(categoryRepository, logger)
companyService := company.NewCompanyService(companyRepository, categoryService, logger)
customerService := customer.New(customerRepository, logger, customerAuthService, companyService, redisClient, notificationSDK)
tenderService := tender.NewTenderService(tenderRepository, companyService, logger)
feedbackService := feedback.NewFeedbackService(feedbackRepo, tenderService, logger)
tenderApprovalService := tender_approval.NewTenderApprovalService(tenderApprovalRepository, tenderService, logger)
inquiryService := inquiry.NewInquiryService(inquiryRepository, notificationSDK, logger)
flagService := assets.NewFlagService(logger, conf.Assets.FlagsPath)
notificationService := notification.NewNotificationService(notificationSDK, userService, customerService, logger)
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)
tenderService := tender.NewService(tenderRepository, companyService, logger)
feedbackService := feedback.NewService(feedbackRepo, tenderService, companyService, logger)
tenderApprovalService := tender_approval.NewService(tenderApprovalRepository, tenderService, logger)
inquiryService := inquiry.NewService(inquiryRepository, notificationSDK, logger)
flagService := assets.NewService(logger, conf.Assets.FlagsPath)
notificationService := notification.NewService(notificationSDK, userService, customerService, logger)
logger.Info("Services initialized successfully", map[string]interface{}{
"services": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification"},
})
// Initialize handlers with services
userHandler := user.NewUserHandler(userService, logger, userValidator, userAuthService)
userHandler := user.NewHandler(userService, logger, userValidator, userAuthService)
customerHandler := customer.NewHandler(customerService, userHandler, customerAuthService, logger)
companyHandler := company.NewHandler(companyService, userHandler, logger)
categoryHandler := company_category.NewHandler(categoryService, logger)
tenderHandler := tender.NewTenderHandler(tenderService, logger)
feedbackHandler := feedback.NewFeedbackHandler(feedbackService, userHandler, customerHandler, logger)
tenderHandler := tender.NewHandler(tenderService, logger)
feedbackHandler := feedback.NewHandler(feedbackService, userHandler, customerHandler, logger)
tenderApprovalHandler := tender_approval.NewHandler(tenderApprovalService, logger)
inquiryHandler := inquiry.NewHandler(inquiryService, logger)
flagHandler := assets.NewHandler(flagService, logger)
+8 -8
View File
@@ -99,9 +99,9 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
feedbackGP := adminV1.Group("/feedback")
{
feedbackGP.Use(userHandler.AuthMiddleware())
feedbackGP.GET("", feedbackHandler.ListFeedback)
feedbackGP.GET("/:id", feedbackHandler.GetFeedback)
feedbackGP.DELETE("/:id", feedbackHandler.DeleteFeedback)
feedbackGP.GET("", feedbackHandler.Search)
feedbackGP.GET("/:id", feedbackHandler.Get)
feedbackGP.DELETE("/:id", feedbackHandler.Delete)
}
// Admin Tender-Approvals Routes
@@ -175,11 +175,11 @@ func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tende
feedbackGP := v1.Group("/feedback")
{
feedbackGP.Use(customerHandler.AuthMiddleware())
feedbackGP.POST("", feedbackHandler.ToggleFeedback)
feedbackGP.GET("", feedbackHandler.PublicListFeedback)
feedbackGP.GET("/tender/:tender_id", feedbackHandler.PublicGetFeedbackByTenderID)
feedbackGP.GET("/:id", feedbackHandler.PublicGetFeedback)
feedbackGP.GET("/stats/company", feedbackHandler.GetCompanyFeedbackStats)
feedbackGP.POST("", feedbackHandler.Toggle)
feedbackGP.GET("", feedbackHandler.PublicList)
feedbackGP.GET("/tender/:tender_id", feedbackHandler.PublicGetByTenderID)
feedbackGP.GET("/:id", feedbackHandler.PublicGet)
feedbackGP.GET("/stats/company", feedbackHandler.GetCompanyStats)
}
// Public Tender Approvals Routes