Enhance tender management with recommended tenders endpoint and search form update
continuous-integration/drone/push Build is passing

- Added a new endpoint in the `tender` handler for retrieving AI-ranked tender recommendations for a company, improving the functionality of the admin panel.
- Updated the `SearchForm` to include a query parameter for `only_active_deadlines`, allowing for more flexible search options.
- Enhanced API documentation for the new endpoint to provide clear usage instructions and expected parameters.

This update improves the tender management system by providing administrators with better tools for accessing relevant tender information.
This commit is contained in:
Mazyar
2026-06-23 13:09:27 +03:30
parent 8fad771b7a
commit a7a49fc411
3 changed files with 44 additions and 1 deletions
+1
View File
@@ -73,6 +73,7 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
companiesGP.Use(userHandler.AuthMiddleware())
companiesGP.POST("", companyHandler.Create)
companiesGP.GET("", companyHandler.Search)
companiesGP.GET("/:id/recommended-tenders", tenderHandler.AdminRecommendTenders)
companiesGP.GET("/:id", companyHandler.Get)
companiesGP.PUT("/:id", companyHandler.Update)
companiesGP.DELETE("/:id", companyHandler.Delete)
+1 -1
View File
@@ -60,7 +60,7 @@ type SearchForm struct {
BuyerOrganizationID *string `query:"buyer_organization_id" valid:"optional"`
NoticePublicationID *string `query:"notice_publication_id" valid:"optional"`
Languages []string `query:"languages" valid:"optional"`
OnlyActiveDeadlines bool `query:"-" valid:"optional"`
OnlyActiveDeadlines bool `query:"only_active_deadlines" valid:"optional"`
Language *string `query:"lang" valid:"optional"`
DocumentsScraped bool `query:"documents_scraped" valid:"optional"`
// ContractFolderIDsWithDocuments is populated by the service from MinIO when DocumentsScraped is true.
+42
View File
@@ -198,6 +198,44 @@ func (h *TenderHandler) Search(c echo.Context) error {
return response.SuccessWithMeta(c, tenders, tenders.Metadata, "Tenders retrieved successfully")
}
// AdminRecommendTenders returns AI-ranked tender recommendations for a company (Web Panel)
// @Summary Get recommended tenders for a company
// @Description Retrieve AI-ranked tenders with full tender details for the given company. Unlike the customer API, active-only filters are not applied unless requested via query parameters.
// @Tags Admin-Companies
// @Produce json
// @Param id path string true "Company ID"
// @Param limit query int false "Number of items per page (default: 10, max: 100)"
// @Param offset query int false "Number of items to skip (default: 0)"
// @Param lang query string false "Response language code (defaults to en)"
// @Param status query []string false "Filter by status (comma-separated)"
// @Param only_active_deadlines query bool false "When true, exclude tenders past their deadline"
// @Success 200 {object} response.APIResponse{data=SearchResponse}
// @Failure 400 {object} response.APIResponse
// @Failure 404 {object} response.APIResponse
// @Failure 503 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Security BearerAuth
// @Router /admin/v1/companies/{id}/recommended-tenders [get]
func (h *TenderHandler) AdminRecommendTenders(c echo.Context) error {
companyID := strings.TrimSpace(c.Param("id"))
if companyID == "" {
return response.BadRequest(c, "Company ID is required", "")
}
form, err := response.Parse[SearchForm](c)
if err != nil {
return response.BadRequest(c, "Invalid request format", "")
}
if _, err := govalidator.ValidateStruct(form); err != nil {
return response.ValidationError(c, err.Error(), "")
}
form.CompanyID = &companyID
return h.serveRecommendTenders(c, form)
}
// *****************************************************
// * PUBLIC HANDLERS *
// *****************************************************
@@ -319,6 +357,10 @@ func (h *TenderHandler) RecommendTenders(c echo.Context) error {
form.CompanyID = &customerCompanyID
}
return h.serveRecommendTenders(c, form)
}
func (h *TenderHandler) serveRecommendTenders(c echo.Context, form *SearchForm) error {
pagination, err := response.NewPagination(c)
if err != nil {
return response.PaginationBadRequest(c, err)