package document_scraper import ( "strconv" "tm/pkg/logger" "tm/pkg/response" "github.com/labstack/echo/v4" ) // Handler handles HTTP requests for the document scraper API type Handler struct { service Service logger logger.Logger } // NewHandler creates a new document scraper handler func NewHandler(service Service, logger logger.Logger) *Handler { return &Handler{ service: service, logger: logger, } } // ListPendingTenders retrieves tenders that need document scraping // @Summary List pending tenders for document scraping // @Description Retrieve tenders that have not yet been scraped for documents. Each item includes contract_folder_id, notice_publication_id, document_url, title, and description. // @Tags Document-Scraper // @Produce json // @Param limit query int false "Number of items per page (default: 20, max: 100)" // @Param offset query int false "Number of items to skip (default: 0)" // @Success 200 {object} response.APIResponse{data=DocumentScraperListResponse} "List of pending tenders" // @Failure 401 {object} response.APIResponse "Invalid or missing API key" // @Failure 500 {object} response.APIResponse "Internal server error" // @Security ApiKeyAuth // @Router /api/v1/scraper/tenders [get] func (h *Handler) ListPendingTenders(c echo.Context) error { // Parse pagination parameters limit, err := strconv.Atoi(c.QueryParam("limit")) if err != nil || limit <= 0 { limit = 20 } if limit > 100 { limit = 100 } offset, err := strconv.Atoi(c.QueryParam("offset")) if err != nil || offset < 0 { offset = 0 } tenders, meta, err := h.service.ListPendingTenders(c.Request().Context(), limit, offset) if err != nil { h.logger.Error("Failed to list pending tenders", map[string]interface{}{ "error": err.Error(), }) return response.InternalServerError(c, "Failed to list pending tenders") } return response.SuccessWithMeta(c, tenders, meta, "Pending tenders retrieved successfully") } // GetTenderByNoticeID retrieves a specific tender by its notice publication ID // @Summary Get tender by notice ID for document scraping // @Description Retrieve a specific tender by its notice publication ID (contract_folder_id, notice_publication_id, document_url, title, description). // @Tags Document-Scraper // @Produce json // @Param notice_id path string true "Notice Publication ID" // @Success 200 {object} response.APIResponse{data=DocumentScraperTenderResponse} "Tender details" // @Failure 400 {object} response.APIResponse "Invalid notice ID" // @Failure 401 {object} response.APIResponse "Invalid or missing API key" // @Failure 404 {object} response.APIResponse "Tender not found" // @Failure 500 {object} response.APIResponse "Internal server error" // @Security ApiKeyAuth // @Router /api/v1/scraper/tenders/{notice_id} [get] func (h *Handler) GetTenderByNoticeID(c echo.Context) error { noticeID := c.Param("notice_id") if noticeID == "" { return response.BadRequest(c, "Notice ID is required", "notice_id parameter cannot be empty") } tender, err := h.service.GetTenderByNoticeID(c.Request().Context(), noticeID) if err != nil { if err.Error() == "tender not found" { return response.NotFound(c, "Tender not found") } h.logger.Error("Failed to get tender by notice ID", map[string]interface{}{ "notice_id": noticeID, "error": err.Error(), }) return response.InternalServerError(c, "Failed to get tender") } return response.Success(c, tender, "Tender retrieved successfully") }