Enhance Tender Search API with Advanced Filtering and Documentation Updates

- Updated the Tender Search API to include additional query parameters for enhanced filtering capabilities, such as currency, deadline ranges, publication dates, languages, and buyer organization ID.
- Changed existing query parameter types from integer to string for better flexibility in search queries.
- Improved Swagger and YAML documentation to reflect the new parameters and their descriptions, ensuring clarity for API consumers.
- Updated handler comments to align with the new query structure, providing comprehensive details for each parameter.
- Enhanced response structures to return a well-defined SearchResponse, improving the overall API usability and documentation consistency.
This commit is contained in:
n.nakhostin
2025-09-08 14:25:02 +03:30
parent 3911180486
commit a76aa16cba
4 changed files with 639 additions and 120 deletions
+221 -36
View File
@@ -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": {
+221 -36
View File
@@ -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": {
+159 -34
View File
@@ -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
+38 -14
View File
@@ -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