Implement Feedback Management System with CRUD Operations and API Enhancements

- Introduced a new feedback management system, including the creation of feedback entities, services, and repositories.
- Implemented CRUD operations for feedback, allowing users to submit likes and dislikes on tenders.
- Developed administrative endpoints for listing and retrieving feedback with comprehensive filtering options.
- Enhanced public API to allow users to view feedback related to tenders.
- Updated Swagger documentation to reflect new feedback endpoints and their functionalities.
- Removed obsolete configuration file `config.yaml` as part of the transition to a modular configuration system.
- Ensured adherence to Clean Architecture principles throughout the implementation.
This commit is contained in:
n.nakhostin
2025-08-16 16:00:03 +03:30
parent 126913365f
commit 21b736b55b
15 changed files with 3548 additions and 108 deletions
+933
View File
@@ -3431,6 +3431,436 @@ const docTemplate = `{
}
}
},
"/admin/v1/feedback": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve paginated list of feedback with optional filtering by various criteria. This endpoint is for administrative use and provides comprehensive filtering options.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Feedback"
],
"summary": "List feedback with filters",
"parameters": [
{
"type": "string",
"description": "Filter by tender ID (MongoDB ObjectID format)",
"name": "tender_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by customer ID (MongoDB ObjectID format)",
"name": "customer_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by company ID (MongoDB ObjectID format)",
"name": "company_id",
"in": "query"
},
{
"enum": [
"like",
"dislike"
],
"type": "string",
"description": "Filter by feedback type",
"name": "feedback_type",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "Filter by creation date from (Unix timestamp in seconds)",
"name": "date_from",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "Filter by creation date to (Unix timestamp in seconds)",
"name": "date_to",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"description": "Number of items per page (default: 20, max: 100)",
"name": "limit",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"description": "Number of items to skip for pagination (default: 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Feedback list retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid query parameters",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"422": {
"description": "Validation error - Invalid filter criteria",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/admin/v1/feedback/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve feedback details by its unique identifier with loaded tender, customer, and company information. This endpoint provides comprehensive feedback data including related entity details.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Feedback"
],
"summary": "Get feedback by ID",
"parameters": [
{
"maxLength": 24,
"minLength": 24,
"type": "string",
"description": "Feedback ID (MongoDB ObjectID format)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "feedback retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid feedback ID format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Feedback not found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark feedback as deleted without permanently removing it from the database. The feedback will be marked as deleted and hidden from normal queries but can be restored if needed.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Feedback"
],
"summary": "Soft delete feedback",
"parameters": [
{
"maxLength": 24,
"minLength": 24,
"type": "string",
"description": "Feedback ID (MongoDB ObjectID format)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Feedback soft deleted successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid feedback ID format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"401": {
"description": "Unauthorized - User not authenticated",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"403": {
"description": "Forbidden - User not authorized to delete this feedback",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Not found - Feedback not found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/admin/v1/health": {
"get": {
"description": "Get comprehensive server health status including system information, dependencies status, and performance metrics. This endpoint is used for monitoring and load balancer health checks.",
@@ -4663,6 +5093,417 @@ const docTemplate = `{
}
}
},
"/api/v1/feedback": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve paginated list of feedback with optional filtering by various criteria. This endpoint is for public use and filters results based on the authenticated user's company.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Feedback"
],
"summary": "List feedback with filters",
"parameters": [
{
"type": "string",
"description": "Filter by tender ID (MongoDB ObjectID format)",
"name": "tender_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by customer ID (MongoDB ObjectID format)",
"name": "customer_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by company ID (MongoDB ObjectID format)",
"name": "company_id",
"in": "query"
},
{
"enum": [
"like",
"dislike"
],
"type": "string",
"description": "Filter by feedback type",
"name": "feedback_type",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"format": "int64",
"description": "Filter by creation date from (Unix timestamp in seconds)",
"name": "date_from",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"format": "int64",
"description": "Filter by creation date to (Unix timestamp in seconds)",
"name": "date_to",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"description": "Number of items per page (default: 20, max: 100)",
"name": "limit",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"description": "Number of items to skip for pagination (default: 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Feedback list retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid query parameters or missing company association",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"422": {
"description": "Validation error - Invalid filter criteria",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Toggle between like and dislike for a tender, or create a like if no feedback exists. This endpoint allows users to express their preference for tenders and automatically handles the toggle logic.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Feedback"
],
"summary": "Toggle feedback for a tender",
"parameters": [
{
"description": "Feedback toggle request containing tender ID",
"name": "feedback",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/feedback.ToggleFeedbackForm"
}
}
],
"responses": {
"200": {
"description": "Feedback toggled successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid input data or missing customer/company association",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"401": {
"description": "Unauthorized - User not authenticated",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"422": {
"description": "Validation error - Invalid request data format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/api/v1/feedback/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve feedback details by its unique identifier. This endpoint provides basic feedback information for public users.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Feedback"
],
"summary": "Get feedback by ID",
"parameters": [
{
"maxLength": 24,
"minLength": 24,
"type": "string",
"description": "Feedback ID (MongoDB ObjectID format)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Feedback retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid feedback ID format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Feedback not found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/api/v1/profile": {
"get": {
"security": [
@@ -4903,6 +5744,11 @@ const docTemplate = `{
},
"/api/v1/tenders": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve active tenders for mobile application users with automatic company-based matching from customer profile",
"produces": [
"application/json"
@@ -4980,6 +5826,11 @@ const docTemplate = `{
},
"/api/v1/tenders/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve detailed information about a specific tender for mobile application users",
"produces": [
"application/json"
@@ -6156,6 +7007,80 @@ const docTemplate = `{
}
}
},
"feedback.FeedbackListResponse": {
"type": "object",
"properties": {
"feedback": {
"type": "array",
"items": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
},
"meta": {
"$ref": "#/definitions/response.Meta"
}
}
},
"feedback.FeedbackResponse": {
"type": "object",
"properties": {
"company_id": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"customer_id": {
"type": "string"
},
"feedback_type": {
"$ref": "#/definitions/feedback.FeedbackType"
},
"id": {
"type": "string"
},
"tender": {
"type": "string"
},
"updated_at": {
"type": "integer"
}
}
},
"feedback.FeedbackType": {
"type": "string",
"enum": [
"like",
"dislike"
],
"x-enum-varnames": [
"FeedbackTypeLike",
"FeedbackTypeDislike"
]
},
"feedback.ToggleFeedbackForm": {
"type": "object",
"required": [
"feedback_type",
"tender_id"
],
"properties": {
"feedback_type": {
"enum": [
"like",
"dislike"
],
"allOf": [
{
"$ref": "#/definitions/feedback.FeedbackType"
}
]
},
"tender_id": {
"type": "string"
}
}
},
"main.HealthResponse": {
"type": "object",
"properties": {
@@ -7271,6 +8196,10 @@ const docTemplate = `{
"description": "Administrative scraping job management operations for TED XML data collection including job control, monitoring, and status tracking",
"name": "Admin-Scraping"
},
{
"description": "Administrative feedback management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination",
"name": "Admin-Feedback"
},
{
"description": "Customer authentication and authorization operations for mobile application including login, logout, token refresh, and profile access",
"name": "Authorization"
@@ -7278,6 +8207,10 @@ const docTemplate = `{
{
"description": "Public tender information access for mobile application including active tender listings and detailed tender information",
"name": "Tenders"
},
{
"description": "Public feedback management operations for mobile application including like, dislike, and comment on tenders",
"name": "Feedback"
}
]
}`
+933
View File
@@ -3425,6 +3425,436 @@
}
}
},
"/admin/v1/feedback": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve paginated list of feedback with optional filtering by various criteria. This endpoint is for administrative use and provides comprehensive filtering options.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Feedback"
],
"summary": "List feedback with filters",
"parameters": [
{
"type": "string",
"description": "Filter by tender ID (MongoDB ObjectID format)",
"name": "tender_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by customer ID (MongoDB ObjectID format)",
"name": "customer_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by company ID (MongoDB ObjectID format)",
"name": "company_id",
"in": "query"
},
{
"enum": [
"like",
"dislike"
],
"type": "string",
"description": "Filter by feedback type",
"name": "feedback_type",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "Filter by creation date from (Unix timestamp in seconds)",
"name": "date_from",
"in": "query"
},
{
"type": "integer",
"format": "int64",
"description": "Filter by creation date to (Unix timestamp in seconds)",
"name": "date_to",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"description": "Number of items per page (default: 20, max: 100)",
"name": "limit",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"description": "Number of items to skip for pagination (default: 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Feedback list retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid query parameters",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"422": {
"description": "Validation error - Invalid filter criteria",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/admin/v1/feedback/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve feedback details by its unique identifier with loaded tender, customer, and company information. This endpoint provides comprehensive feedback data including related entity details.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Feedback"
],
"summary": "Get feedback by ID",
"parameters": [
{
"maxLength": 24,
"minLength": 24,
"type": "string",
"description": "Feedback ID (MongoDB ObjectID format)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "feedback retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid feedback ID format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Feedback not found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Mark feedback as deleted without permanently removing it from the database. The feedback will be marked as deleted and hidden from normal queries but can be restored if needed.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Feedback"
],
"summary": "Soft delete feedback",
"parameters": [
{
"maxLength": 24,
"minLength": 24,
"type": "string",
"description": "Feedback ID (MongoDB ObjectID format)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Feedback soft deleted successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid feedback ID format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"401": {
"description": "Unauthorized - User not authenticated",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"403": {
"description": "Forbidden - User not authorized to delete this feedback",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Not found - Feedback not found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/admin/v1/health": {
"get": {
"description": "Get comprehensive server health status including system information, dependencies status, and performance metrics. This endpoint is used for monitoring and load balancer health checks.",
@@ -4657,6 +5087,417 @@
}
}
},
"/api/v1/feedback": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve paginated list of feedback with optional filtering by various criteria. This endpoint is for public use and filters results based on the authenticated user's company.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Feedback"
],
"summary": "List feedback with filters",
"parameters": [
{
"type": "string",
"description": "Filter by tender ID (MongoDB ObjectID format)",
"name": "tender_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by customer ID (MongoDB ObjectID format)",
"name": "customer_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by company ID (MongoDB ObjectID format)",
"name": "company_id",
"in": "query"
},
{
"enum": [
"like",
"dislike"
],
"type": "string",
"description": "Filter by feedback type",
"name": "feedback_type",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"format": "int64",
"description": "Filter by creation date from (Unix timestamp in seconds)",
"name": "date_from",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"format": "int64",
"description": "Filter by creation date to (Unix timestamp in seconds)",
"name": "date_to",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"description": "Number of items per page (default: 20, max: 100)",
"name": "limit",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"description": "Number of items to skip for pagination (default: 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "Feedback list retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid query parameters or missing company association",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"422": {
"description": "Validation error - Invalid filter criteria",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Toggle between like and dislike for a tender, or create a like if no feedback exists. This endpoint allows users to express their preference for tenders and automatically handles the toggle logic.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Feedback"
],
"summary": "Toggle feedback for a tender",
"parameters": [
{
"description": "Feedback toggle request containing tender ID",
"name": "feedback",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/feedback.ToggleFeedbackForm"
}
}
],
"responses": {
"200": {
"description": "Feedback toggled successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid input data or missing customer/company association",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"401": {
"description": "Unauthorized - User not authenticated",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"422": {
"description": "Validation error - Invalid request data format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/api/v1/feedback/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve feedback details by its unique identifier. This endpoint provides basic feedback information for public users.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Feedback"
],
"summary": "Get feedback by ID",
"parameters": [
{
"maxLength": 24,
"minLength": 24,
"type": "string",
"description": "Feedback ID (MongoDB ObjectID format)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Feedback retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid feedback ID format",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"404": {
"description": "Feedback not found",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
},
"500": {
"description": "Internal server error",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
]
}
}
}
}
},
"/api/v1/profile": {
"get": {
"security": [
@@ -4897,6 +5738,11 @@
},
"/api/v1/tenders": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve active tenders for mobile application users with automatic company-based matching from customer profile",
"produces": [
"application/json"
@@ -4974,6 +5820,11 @@
},
"/api/v1/tenders/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve detailed information about a specific tender for mobile application users",
"produces": [
"application/json"
@@ -6150,6 +7001,80 @@
}
}
},
"feedback.FeedbackListResponse": {
"type": "object",
"properties": {
"feedback": {
"type": "array",
"items": {
"$ref": "#/definitions/feedback.FeedbackResponse"
}
},
"meta": {
"$ref": "#/definitions/response.Meta"
}
}
},
"feedback.FeedbackResponse": {
"type": "object",
"properties": {
"company_id": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"customer_id": {
"type": "string"
},
"feedback_type": {
"$ref": "#/definitions/feedback.FeedbackType"
},
"id": {
"type": "string"
},
"tender": {
"type": "string"
},
"updated_at": {
"type": "integer"
}
}
},
"feedback.FeedbackType": {
"type": "string",
"enum": [
"like",
"dislike"
],
"x-enum-varnames": [
"FeedbackTypeLike",
"FeedbackTypeDislike"
]
},
"feedback.ToggleFeedbackForm": {
"type": "object",
"required": [
"feedback_type",
"tender_id"
],
"properties": {
"feedback_type": {
"enum": [
"like",
"dislike"
],
"allOf": [
{
"$ref": "#/definitions/feedback.FeedbackType"
}
]
},
"tender_id": {
"type": "string"
}
}
},
"main.HealthResponse": {
"type": "object",
"properties": {
@@ -7265,6 +8190,10 @@
"description": "Administrative scraping job management operations for TED XML data collection including job control, monitoring, and status tracking",
"name": "Admin-Scraping"
},
{
"description": "Administrative feedback management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination",
"name": "Admin-Feedback"
},
{
"description": "Customer authentication and authorization operations for mobile application including login, logout, token refresh, and profile access",
"name": "Authorization"
@@ -7272,6 +8201,10 @@
{
"description": "Public tender information access for mobile application including active tender listings and detailed tender information",
"name": "Tenders"
},
{
"description": "Public feedback management operations for mobile application including like, dislike, and comment on tenders",
"name": "Feedback"
}
]
}
+546
View File
@@ -731,6 +731,54 @@ definitions:
is_verified:
type: boolean
type: object
feedback.FeedbackListResponse:
properties:
feedback:
items:
$ref: '#/definitions/feedback.FeedbackResponse'
type: array
meta:
$ref: '#/definitions/response.Meta'
type: object
feedback.FeedbackResponse:
properties:
company_id:
type: string
created_at:
type: integer
customer_id:
type: string
feedback_type:
$ref: '#/definitions/feedback.FeedbackType'
id:
type: string
tender:
type: string
updated_at:
type: integer
type: object
feedback.FeedbackType:
enum:
- like
- dislike
type: string
x-enum-varnames:
- FeedbackTypeLike
- FeedbackTypeDislike
feedback.ToggleFeedbackForm:
properties:
feedback_type:
allOf:
- $ref: '#/definitions/feedback.FeedbackType'
enum:
- like
- dislike
tender_id:
type: string
required:
- feedback_type
- tender_id
type: object
main.HealthResponse:
properties:
service:
@@ -3661,6 +3709,255 @@ paths:
summary: Get customers by type
tags:
- Admin-Customers
/admin/v1/feedback:
get:
consumes:
- application/json
description: Retrieve paginated list of feedback with optional filtering by
various criteria. This endpoint is for administrative use and provides comprehensive
filtering options.
parameters:
- description: Filter by tender ID (MongoDB ObjectID format)
in: query
name: tender_id
type: string
- description: Filter by customer ID (MongoDB ObjectID format)
in: query
name: customer_id
type: string
- description: Filter by company ID (MongoDB ObjectID format)
in: query
name: company_id
type: string
- description: Filter by feedback type
enum:
- like
- dislike
in: query
name: feedback_type
type: string
- description: Filter by creation date from (Unix timestamp in seconds)
format: int64
in: query
name: date_from
type: integer
- description: Filter by creation date to (Unix timestamp in seconds)
format: int64
in: query
name: date_to
type: integer
- description: 'Number of items per page (default: 20, max: 100)'
in: query
maximum: 100
minimum: 1
name: limit
type: integer
- description: 'Number of items to skip for pagination (default: 0)'
in: query
minimum: 0
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: Feedback list retrieved successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/feedback.FeedbackListResponse'
type: object
"400":
description: Bad request - Invalid query parameters
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"422":
description: Validation error - Invalid filter criteria
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"500":
description: Internal server error
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
security:
- BearerAuth: []
summary: List feedback with filters
tags:
- Admin-Feedback
/admin/v1/feedback/{id}:
delete:
consumes:
- application/json
description: Mark feedback as deleted without permanently removing it from the
database. The feedback will be marked as deleted and hidden from normal queries
but can be restored if needed.
parameters:
- description: Feedback ID (MongoDB ObjectID format)
in: path
maxLength: 24
minLength: 24
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Feedback soft deleted successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
message:
type: string
type: object
"400":
description: Bad request - Invalid feedback ID format
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"401":
description: Unauthorized - User not authenticated
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"403":
description: Forbidden - User not authorized to delete this feedback
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"404":
description: Not found - Feedback not found
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"500":
description: Internal server error
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
security:
- BearerAuth: []
summary: Soft delete feedback
tags:
- Admin-Feedback
get:
consumes:
- application/json
description: Retrieve feedback details by its unique identifier with loaded
tender, customer, and company information. This endpoint provides comprehensive
feedback data including related entity details.
parameters:
- description: Feedback ID (MongoDB ObjectID format)
in: path
maxLength: 24
minLength: 24
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: feedback retrieved successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/feedback.FeedbackResponse'
type: object
"400":
description: Bad request - Invalid feedback ID format
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"404":
description: Feedback not found
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"500":
description: Internal server error
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
security:
- BearerAuth: []
summary: Get feedback by ID
tags:
- Admin-Feedback
/admin/v1/health:
get:
consumes:
@@ -4452,6 +4749,245 @@ paths:
summary: Get users by role
tags:
- Admin-Users
/api/v1/feedback:
get:
consumes:
- application/json
description: Retrieve paginated list of feedback with optional filtering by
various criteria. This endpoint is for public use and filters results based
on the authenticated user's company.
parameters:
- description: Filter by tender ID (MongoDB ObjectID format)
in: query
name: tender_id
type: string
- description: Filter by customer ID (MongoDB ObjectID format)
in: query
name: customer_id
type: string
- description: Filter by company ID (MongoDB ObjectID format)
in: query
name: company_id
type: string
- description: Filter by feedback type
enum:
- like
- dislike
in: query
name: feedback_type
type: string
- description: Filter by creation date from (Unix timestamp in seconds)
format: int64
in: query
minimum: 0
name: date_from
type: integer
- description: Filter by creation date to (Unix timestamp in seconds)
format: int64
in: query
minimum: 0
name: date_to
type: integer
- description: 'Number of items per page (default: 20, max: 100)'
in: query
maximum: 100
minimum: 1
name: limit
type: integer
- description: 'Number of items to skip for pagination (default: 0)'
in: query
minimum: 0
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: Feedback list retrieved successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/feedback.FeedbackListResponse'
type: object
"400":
description: Bad request - Invalid query parameters or missing company association
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"422":
description: Validation error - Invalid filter criteria
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"500":
description: Internal server error
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
security:
- BearerAuth: []
summary: List feedback with filters
tags:
- Feedback
post:
consumes:
- application/json
description: Toggle between like and dislike for a tender, or create a like
if no feedback exists. This endpoint allows users to express their preference
for tenders and automatically handles the toggle logic.
parameters:
- description: Feedback toggle request containing tender ID
in: body
name: feedback
required: true
schema:
$ref: '#/definitions/feedback.ToggleFeedbackForm'
produces:
- application/json
responses:
"200":
description: Feedback toggled successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/feedback.FeedbackResponse'
type: object
"400":
description: Bad request - Invalid input data or missing customer/company
association
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"401":
description: Unauthorized - User not authenticated
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"422":
description: Validation error - Invalid request data format
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"500":
description: Internal server error
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
security:
- BearerAuth: []
summary: Toggle feedback for a tender
tags:
- Feedback
/api/v1/feedback/{id}:
get:
consumes:
- application/json
description: Retrieve feedback details by its unique identifier. This endpoint
provides basic feedback information for public users.
parameters:
- description: Feedback ID (MongoDB ObjectID format)
in: path
maxLength: 24
minLength: 24
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Feedback retrieved successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/feedback.FeedbackResponse'
type: object
"400":
description: Bad request - Invalid feedback ID format
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"404":
description: Feedback not found
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
"500":
description: Internal server error
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
error:
type: string
message:
type: string
type: object
security:
- BearerAuth: []
summary: Get feedback by ID
tags:
- Feedback
/api/v1/profile:
get:
consumes:
@@ -4645,6 +5181,8 @@ paths:
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Get public tenders
tags:
- Tenders
@@ -4679,6 +5217,8 @@ paths:
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Get public tender details
tags:
- Tenders
@@ -4714,9 +5254,15 @@ tags:
- description: Administrative scraping job management operations for TED XML data
collection including job control, monitoring, and status tracking
name: Admin-Scraping
- description: Administrative feedback management operations for web panel including
CRUD operations, search, statistics, and comprehensive filtering with pagination
name: Admin-Feedback
- description: Customer authentication and authorization operations for mobile application
including login, logout, token refresh, and profile access
name: Authorization
- description: Public tender information access for mobile application including active
tender listings and detailed tender information
name: Tenders
- description: Public feedback management operations for mobile application including
like, dislike, and comment on tenders
name: Feedback