diff --git a/cmd/web/docs/docs.go b/cmd/web/docs/docs.go index daf5f09..e78a883 100644 --- a/cmd/web/docs/docs.go +++ b/cmd/web/docs/docs.go @@ -5370,21 +5370,51 @@ const docTemplate = `{ "summary": "Get public tenders", "parameters": [ { - "type": "integer", - "description": "Number of items per page (default: 20, max: 50)", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items to skip (default: 0)", - "name": "offset", + "type": "string", + "description": "Search query for title and description", + "name": "q", "in": "query" }, { "type": "string", - "description": "Filter by country code", - "name": "country_code", + "description": "Filter by notice type code", + "name": "notice_type", + "in": "query" + }, + { + "type": "string", + "description": "Filter by procurement type code", + "name": "procurement_type", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by country codes (comma-separated)", + "name": "country_codes", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by status (comma-separated)", + "name": "status", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by source (comma-separated)", + "name": "source", "in": "query" }, { @@ -5400,15 +5430,73 @@ const docTemplate = `{ "in": "query" }, { - "type": "number", - "description": "Publication from", - "name": "publication_from", + "type": "string", + "description": "Filter by currency", + "name": "currency", "in": "query" }, { "type": "number", - "description": "Publication to", - "name": "publication_to", + "description": "Deadline from", + "name": "deadline_from", + "in": "query" + }, + { + "type": "number", + "description": "Deadline to", + "name": "deadline_to", + "in": "query" + }, + { + "type": "number", + "description": "Publication date from", + "name": "publication_date_from", + "in": "query" + }, + { + "type": "number", + "description": "Publication date to", + "name": "publication_date_to", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by languages (comma-separated)", + "name": "languages", + "in": "query" + }, + { + "type": "string", + "description": "Filter by buyer organization ID", + "name": "buyer_organization_id", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items per page (default: 20, max: 100)", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items to skip (default: 0)", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Sort by field", + "name": "sort_by", + "in": "query" + }, + { + "type": "string", + "description": "Sort order (asc or desc)", + "name": "sort_order", "in": "query" } ], @@ -5424,8 +5512,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/tender.SearchResponse" } } } @@ -5523,21 +5610,51 @@ const docTemplate = `{ "summary": "Get public tenders", "parameters": [ { - "type": "integer", - "description": "Number of items per page (default: 20, max: 50)", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items to skip (default: 0)", - "name": "offset", + "type": "string", + "description": "Search query for title and description", + "name": "q", "in": "query" }, { "type": "string", - "description": "Filter by country code", - "name": "country_code", + "description": "Filter by notice type code", + "name": "notice_type", + "in": "query" + }, + { + "type": "string", + "description": "Filter by procurement type code", + "name": "procurement_type", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by country codes (comma-separated)", + "name": "country_codes", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by status (comma-separated)", + "name": "status", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by source (comma-separated)", + "name": "source", "in": "query" }, { @@ -5553,15 +5670,73 @@ const docTemplate = `{ "in": "query" }, { - "type": "number", - "description": "Publication from", - "name": "publication_from", + "type": "string", + "description": "Filter by currency", + "name": "currency", "in": "query" }, { "type": "number", - "description": "Publication to", - "name": "publication_to", + "description": "Deadline from", + "name": "deadline_from", + "in": "query" + }, + { + "type": "number", + "description": "Deadline to", + "name": "deadline_to", + "in": "query" + }, + { + "type": "number", + "description": "Publication date from", + "name": "publication_date_from", + "in": "query" + }, + { + "type": "number", + "description": "Publication date to", + "name": "publication_date_to", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by languages (comma-separated)", + "name": "languages", + "in": "query" + }, + { + "type": "string", + "description": "Filter by buyer organization ID", + "name": "buyer_organization_id", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items per page (default: 20, max: 100)", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items to skip (default: 0)", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Sort by field", + "name": "sort_by", + "in": "query" + }, + { + "type": "string", + "description": "Sort order (asc or desc)", + "name": "sort_order", "in": "query" } ], @@ -5577,8 +5752,7 @@ const docTemplate = `{ "type": "object", "properties": { "data": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/tender.SearchResponse" } } } @@ -6509,6 +6683,17 @@ const docTemplate = `{ } } }, + "tender.SearchResponse": { + "type": "object", + "properties": { + "tenders": { + "type": "array", + "items": { + "$ref": "#/definitions/tender.TenderResponse" + } + } + } + }, "tender.TenderResponse": { "type": "object", "properties": { diff --git a/cmd/web/docs/swagger.json b/cmd/web/docs/swagger.json index 84f9cc7..9fc6e9b 100644 --- a/cmd/web/docs/swagger.json +++ b/cmd/web/docs/swagger.json @@ -5364,21 +5364,51 @@ "summary": "Get public tenders", "parameters": [ { - "type": "integer", - "description": "Number of items per page (default: 20, max: 50)", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items to skip (default: 0)", - "name": "offset", + "type": "string", + "description": "Search query for title and description", + "name": "q", "in": "query" }, { "type": "string", - "description": "Filter by country code", - "name": "country_code", + "description": "Filter by notice type code", + "name": "notice_type", + "in": "query" + }, + { + "type": "string", + "description": "Filter by procurement type code", + "name": "procurement_type", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by country codes (comma-separated)", + "name": "country_codes", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by status (comma-separated)", + "name": "status", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by source (comma-separated)", + "name": "source", "in": "query" }, { @@ -5394,15 +5424,73 @@ "in": "query" }, { - "type": "number", - "description": "Publication from", - "name": "publication_from", + "type": "string", + "description": "Filter by currency", + "name": "currency", "in": "query" }, { "type": "number", - "description": "Publication to", - "name": "publication_to", + "description": "Deadline from", + "name": "deadline_from", + "in": "query" + }, + { + "type": "number", + "description": "Deadline to", + "name": "deadline_to", + "in": "query" + }, + { + "type": "number", + "description": "Publication date from", + "name": "publication_date_from", + "in": "query" + }, + { + "type": "number", + "description": "Publication date to", + "name": "publication_date_to", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by languages (comma-separated)", + "name": "languages", + "in": "query" + }, + { + "type": "string", + "description": "Filter by buyer organization ID", + "name": "buyer_organization_id", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items per page (default: 20, max: 100)", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items to skip (default: 0)", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Sort by field", + "name": "sort_by", + "in": "query" + }, + { + "type": "string", + "description": "Sort order (asc or desc)", + "name": "sort_order", "in": "query" } ], @@ -5418,8 +5506,7 @@ "type": "object", "properties": { "data": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/tender.SearchResponse" } } } @@ -5517,21 +5604,51 @@ "summary": "Get public tenders", "parameters": [ { - "type": "integer", - "description": "Number of items per page (default: 20, max: 50)", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Number of items to skip (default: 0)", - "name": "offset", + "type": "string", + "description": "Search query for title and description", + "name": "q", "in": "query" }, { "type": "string", - "description": "Filter by country code", - "name": "country_code", + "description": "Filter by notice type code", + "name": "notice_type", + "in": "query" + }, + { + "type": "string", + "description": "Filter by procurement type code", + "name": "procurement_type", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by country codes (comma-separated)", + "name": "country_codes", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by status (comma-separated)", + "name": "status", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by source (comma-separated)", + "name": "source", "in": "query" }, { @@ -5547,15 +5664,73 @@ "in": "query" }, { - "type": "number", - "description": "Publication from", - "name": "publication_from", + "type": "string", + "description": "Filter by currency", + "name": "currency", "in": "query" }, { "type": "number", - "description": "Publication to", - "name": "publication_to", + "description": "Deadline from", + "name": "deadline_from", + "in": "query" + }, + { + "type": "number", + "description": "Deadline to", + "name": "deadline_to", + "in": "query" + }, + { + "type": "number", + "description": "Publication date from", + "name": "publication_date_from", + "in": "query" + }, + { + "type": "number", + "description": "Publication date to", + "name": "publication_date_to", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "description": "Filter by languages (comma-separated)", + "name": "languages", + "in": "query" + }, + { + "type": "string", + "description": "Filter by buyer organization ID", + "name": "buyer_organization_id", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items per page (default: 20, max: 100)", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Number of items to skip (default: 0)", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "description": "Sort by field", + "name": "sort_by", + "in": "query" + }, + { + "type": "string", + "description": "Sort order (asc or desc)", + "name": "sort_order", "in": "query" } ], @@ -5571,8 +5746,7 @@ "type": "object", "properties": { "data": { - "type": "object", - "additionalProperties": true + "$ref": "#/definitions/tender.SearchResponse" } } } @@ -6503,6 +6677,17 @@ } } }, + "tender.SearchResponse": { + "type": "object", + "properties": { + "tenders": { + "type": "array", + "items": { + "$ref": "#/definitions/tender.TenderResponse" + } + } + } + }, "tender.TenderResponse": { "type": "object", "properties": { diff --git a/cmd/web/docs/swagger.yaml b/cmd/web/docs/swagger.yaml index d14a663..02d15ca 100644 --- a/cmd/web/docs/swagger.yaml +++ b/cmd/web/docs/swagger.yaml @@ -612,6 +612,13 @@ definitions: name: type: string type: object + tender.SearchResponse: + properties: + tenders: + items: + $ref: '#/definitions/tender.TenderResponse' + type: array + type: object tender.TenderResponse: properties: application_deadline: @@ -4364,18 +4371,39 @@ paths: description: Retrieve active tenders for mobile application users with automatic company-based matching from customer profile parameters: - - description: 'Number of items per page (default: 20, max: 50)' + - description: Search query for title and description in: query - name: limit - type: integer - - description: 'Number of items to skip (default: 0)' - in: query - name: offset - type: integer - - description: Filter by country code - in: query - name: country_code + name: q type: string + - description: Filter by notice type code + in: query + name: notice_type + type: string + - description: Filter by procurement type code + in: query + name: procurement_type + type: string + - collectionFormat: csv + description: Filter by country codes (comma-separated) + in: query + items: + type: string + name: country_codes + type: array + - collectionFormat: csv + description: Filter by status (comma-separated) + in: query + items: + type: string + name: status + type: array + - collectionFormat: csv + description: Filter by source (comma-separated) + in: query + items: + type: string + name: source + type: array - description: Minimum estimated value in: query name: min_estimated_value @@ -4384,14 +4412,53 @@ paths: in: query name: max_estimated_value type: number - - description: Publication from + - description: Filter by currency in: query - name: publication_from - type: number - - description: Publication to + name: currency + type: string + - description: Deadline from in: query - name: publication_to + name: deadline_from type: number + - description: Deadline to + in: query + name: deadline_to + type: number + - description: Publication date from + in: query + name: publication_date_from + type: number + - description: Publication date to + in: query + name: publication_date_to + type: number + - collectionFormat: csv + description: Filter by languages (comma-separated) + in: query + items: + type: string + name: languages + type: array + - description: Filter by buyer organization ID + in: query + name: buyer_organization_id + type: string + - description: 'Number of items per page (default: 20, max: 100)' + in: query + name: limit + type: integer + - description: 'Number of items to skip (default: 0)' + in: query + name: offset + type: integer + - description: Sort by field + in: query + name: sort_by + type: string + - description: Sort order (asc or desc) + in: query + name: sort_order + type: string produces: - application/json responses: @@ -4402,8 +4469,7 @@ paths: - $ref: '#/definitions/response.APIResponse' - properties: data: - additionalProperties: true - type: object + $ref: '#/definitions/tender.SearchResponse' type: object "400": description: Bad Request @@ -4459,18 +4525,39 @@ paths: description: Retrieve active tenders for mobile application users with automatic company-based matching from customer profile parameters: - - description: 'Number of items per page (default: 20, max: 50)' + - description: Search query for title and description in: query - name: limit - type: integer - - description: 'Number of items to skip (default: 0)' - in: query - name: offset - type: integer - - description: Filter by country code - in: query - name: country_code + name: q type: string + - description: Filter by notice type code + in: query + name: notice_type + type: string + - description: Filter by procurement type code + in: query + name: procurement_type + type: string + - collectionFormat: csv + description: Filter by country codes (comma-separated) + in: query + items: + type: string + name: country_codes + type: array + - collectionFormat: csv + description: Filter by status (comma-separated) + in: query + items: + type: string + name: status + type: array + - collectionFormat: csv + description: Filter by source (comma-separated) + in: query + items: + type: string + name: source + type: array - description: Minimum estimated value in: query name: min_estimated_value @@ -4479,14 +4566,53 @@ paths: in: query name: max_estimated_value type: number - - description: Publication from + - description: Filter by currency in: query - name: publication_from - type: number - - description: Publication to + name: currency + type: string + - description: Deadline from in: query - name: publication_to + name: deadline_from type: number + - description: Deadline to + in: query + name: deadline_to + type: number + - description: Publication date from + in: query + name: publication_date_from + type: number + - description: Publication date to + in: query + name: publication_date_to + type: number + - collectionFormat: csv + description: Filter by languages (comma-separated) + in: query + items: + type: string + name: languages + type: array + - description: Filter by buyer organization ID + in: query + name: buyer_organization_id + type: string + - description: 'Number of items per page (default: 20, max: 100)' + in: query + name: limit + type: integer + - description: 'Number of items to skip (default: 0)' + in: query + name: offset + type: integer + - description: Sort by field + in: query + name: sort_by + type: string + - description: Sort order (asc or desc) + in: query + name: sort_order + type: string produces: - application/json responses: @@ -4497,8 +4623,7 @@ paths: - $ref: '#/definitions/response.APIResponse' - properties: data: - additionalProperties: true - type: object + $ref: '#/definitions/tender.SearchResponse' type: object "400": description: Bad Request diff --git a/internal/tender/handler.go b/internal/tender/handler.go index abf890c..ab25c5a 100644 --- a/internal/tender/handler.go +++ b/internal/tender/handler.go @@ -179,14 +179,26 @@ func (h *TenderHandler) Search(c echo.Context) error { // @Description Retrieve active tenders for mobile application users with automatic company-based matching from customer profile // @Tags Tenders // @Produce json -// @Param limit query int false "Number of items per page (default: 20, max: 50)" -// @Param offset query int false "Number of items to skip (default: 0)" -// @Param country_code query string false "Filter by country code" +// @Param q query string false "Search query for title and description" +// @Param notice_type query string false "Filter by notice type code" +// @Param procurement_type query string false "Filter by procurement type code" +// @Param country_codes query []string false "Filter by country codes (comma-separated)" +// @Param status query []string false "Filter by status (comma-separated)" +// @Param source query []string false "Filter by source (comma-separated)" // @Param min_estimated_value query number false "Minimum estimated value" // @Param max_estimated_value query number false "Maximum estimated value" -// @Param publication_from query number false "Publication from" -// @Param publication_to query number false "Publication to" -// @Success 200 {object} response.APIResponse{data=map[string]interface{}} +// @Param currency query string false "Filter by currency" +// @Param deadline_from query number false "Deadline from" +// @Param deadline_to query number false "Deadline to" +// @Param publication_date_from query number false "Publication date from" +// @Param publication_date_to query number false "Publication date to" +// @Param languages query []string false "Filter by languages (comma-separated)" +// @Param buyer_organization_id query string false "Filter by buyer organization ID" +// @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)" +// @Param sort_by query string false "Sort by field" +// @Param sort_order query string false "Sort order (asc or desc)" +// @Success 200 {object} response.APIResponse{data=SearchResponse} // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Security BearerAuth @@ -216,7 +228,7 @@ func (h *TenderHandler) GetPublicTenders(c echo.Context) error { return response.InternalServerError(c, "Failed to retrieve tenders") } - return response.Success(c, result, "Tenders retrieved successfully") + return response.SuccessWithMeta(c, result, result.Metadata, "Tenders retrieved successfully") } // GetPublicTenders retrieves public tenders for mobile app @@ -224,14 +236,26 @@ func (h *TenderHandler) GetPublicTenders(c echo.Context) error { // @Description Retrieve active tenders for mobile application users with automatic company-based matching from customer profile // @Tags Tenders // @Produce json -// @Param limit query int false "Number of items per page (default: 20, max: 50)" -// @Param offset query int false "Number of items to skip (default: 0)" -// @Param country_code query string false "Filter by country code" +// @Param q query string false "Search query for title and description" +// @Param notice_type query string false "Filter by notice type code" +// @Param procurement_type query string false "Filter by procurement type code" +// @Param country_codes query []string false "Filter by country codes (comma-separated)" +// @Param status query []string false "Filter by status (comma-separated)" +// @Param source query []string false "Filter by source (comma-separated)" // @Param min_estimated_value query number false "Minimum estimated value" // @Param max_estimated_value query number false "Maximum estimated value" -// @Param publication_from query number false "Publication from" -// @Param publication_to query number false "Publication to" -// @Success 200 {object} response.APIResponse{data=map[string]interface{}} +// @Param currency query string false "Filter by currency" +// @Param deadline_from query number false "Deadline from" +// @Param deadline_to query number false "Deadline to" +// @Param publication_date_from query number false "Publication date from" +// @Param publication_date_to query number false "Publication date to" +// @Param languages query []string false "Filter by languages (comma-separated)" +// @Param buyer_organization_id query string false "Filter by buyer organization ID" +// @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)" +// @Param sort_by query string false "Sort by field" +// @Param sort_order query string false "Sort order (asc or desc)" +// @Success 200 {object} response.APIResponse{data=SearchResponse} // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Security BearerAuth @@ -261,7 +285,7 @@ func (h *TenderHandler) RecommendTenders(c echo.Context) error { return response.InternalServerError(c, "Failed to retrieve tenders") } - return response.Success(c, result, "Tenders retrieved successfully") + return response.SuccessWithMeta(c, result, result.Metadata, "Tenders retrieved successfully") } // GetPublicTenderDetails retrieves public tender details for mobile app