Add Company Category Management Functionality and Update API Documentation

- Introduced a new company category management feature, including CRUD operations for categories in both admin and public API endpoints.
- Implemented category entity, service, repository, and handler layers following clean architecture principles.
- Added new API routes for searching, retrieving, updating, deleting, and toggling publish status of categories, enhancing the overall functionality of the system.
- Updated Swagger and YAML documentation to include detailed descriptions and examples for the new category endpoints, ensuring clarity for API consumers.
- Enhanced error handling for duplicate categories and validation, improving the robustness of the category management process.
- Updated existing routes to integrate category handling, ensuring a seamless user experience across the application.
This commit is contained in:
n.nakhostin
2025-09-08 12:31:49 +03:30
parent 617547def8
commit 991771ee19
10 changed files with 2156 additions and 7 deletions
+509
View File
@@ -904,6 +904,454 @@ const docTemplate = `{
}
}
},
"/admin/v1/company-categories": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Search categories with filtering capabilities",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Search categories",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query"
},
{
"type": "boolean",
"description": "Published status filter",
"name": "published",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
},
{
"enum": [
"name",
"created_at",
"updated_at",
"published_at"
],
"type": "string",
"description": "Sort by field",
"name": "sort_by",
"in": "query"
},
{
"enum": [
"asc",
"desc"
],
"type": "string",
"description": "Sort order",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "Categories search completed",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid query parameters",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid query parameters",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new category with name, description, and thumbnail",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Create a new category",
"parameters": [
{
"description": "Category information",
"name": "category",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/company_category.CategoryForm"
}
}
],
"responses": {
"201": {
"description": "Category created successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid input data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"409": {
"description": "Conflict - Category with this name already exists",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid request data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/company-categories/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve detailed category information by category ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Get category by ID",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Category retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid category ID",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update category information including name, description, and thumbnail",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Update category information",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Category update information",
"name": "category",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/company_category.CategoryForm"
}
}
],
"responses": {
"200": {
"description": "Category updated successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid input data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"409": {
"description": "Conflict - Category with this name already exists",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid request data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a category permanently",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Delete category",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Category deleted successfully",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad request - Invalid category ID",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/company-categories/{id}/publish": {
"patch": {
"security": [
{
"BearerAuth": []
}
],
"description": "Toggle category publish/unpublish status",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Toggle category publish status",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Category publish status updated successfully",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad request - Invalid input data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid request data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/customers": {
"get": {
"security": [
@@ -5487,6 +5935,63 @@ const docTemplate = `{
}
}
},
"company_category.CategoryForm": {
"type": "object",
"properties": {
"description": {
"type": "string",
"example": "Technology related companies"
},
"name": {
"type": "string",
"example": "Technology"
},
"thumbnail": {
"type": "string",
"example": "https://example.com/thumbnail.jpg"
}
}
},
"company_category.CategoryListResponse": {
"type": "object",
"properties": {
"categories": {
"type": "array",
"items": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
},
"company_category.CategoryResponse": {
"type": "object",
"properties": {
"created_at": {
"type": "integer"
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"published": {
"type": "boolean"
},
"published_at": {
"type": "integer"
},
"thumbnail": {
"type": "string"
},
"updated_at": {
"type": "integer"
}
}
},
"customer.AuthResponse": {
"type": "object",
"properties": {
@@ -6552,6 +7057,10 @@ const docTemplate = `{
"description": "Administrative company management operations for web panel including CRUD operations, tag management, verification, status updates, comprehensive search and filtering, and statistical reporting",
"name": "Admin-Companies"
},
{
"description": "Administrative company category management operations for web panel including CRUD operations, publish/unpublish status, and comprehensive filtering with pagination",
"name": "Admin-Company-Categories"
},
{
"description": "Administrative tender management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination",
"name": "Admin-Tenders"
+509
View File
@@ -898,6 +898,454 @@
}
}
},
"/admin/v1/company-categories": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Search categories with filtering capabilities",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Search categories",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query"
},
{
"type": "boolean",
"description": "Published status filter",
"name": "published",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
},
{
"enum": [
"name",
"created_at",
"updated_at",
"published_at"
],
"type": "string",
"description": "Sort by field",
"name": "sort_by",
"in": "query"
},
{
"enum": [
"asc",
"desc"
],
"type": "string",
"description": "Sort order",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "Categories search completed",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid query parameters",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid query parameters",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new category with name, description, and thumbnail",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Create a new category",
"parameters": [
{
"description": "Category information",
"name": "category",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/company_category.CategoryForm"
}
}
],
"responses": {
"201": {
"description": "Category created successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid input data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"409": {
"description": "Conflict - Category with this name already exists",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid request data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/company-categories/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Retrieve detailed category information by category ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Get category by ID",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Category retrieved successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid category ID",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update category information including name, description, and thumbnail",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Update category information",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Category update information",
"name": "category",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/company_category.CategoryForm"
}
}
],
"responses": {
"200": {
"description": "Category updated successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
]
}
},
"400": {
"description": "Bad request - Invalid input data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"409": {
"description": "Conflict - Category with this name already exists",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid request data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a category permanently",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Delete category",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Category deleted successfully",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad request - Invalid category ID",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/company-categories/{id}/publish": {
"patch": {
"security": [
{
"BearerAuth": []
}
],
"description": "Toggle category publish/unpublish status",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Admin-Company-Categories"
],
"summary": "Toggle category publish status",
"parameters": [
{
"type": "string",
"description": "Category ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Category publish status updated successfully",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad request - Invalid input data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not found - Category not found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"422": {
"description": "Validation error - Invalid request data",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/customers": {
"get": {
"security": [
@@ -5481,6 +5929,63 @@
}
}
},
"company_category.CategoryForm": {
"type": "object",
"properties": {
"description": {
"type": "string",
"example": "Technology related companies"
},
"name": {
"type": "string",
"example": "Technology"
},
"thumbnail": {
"type": "string",
"example": "https://example.com/thumbnail.jpg"
}
}
},
"company_category.CategoryListResponse": {
"type": "object",
"properties": {
"categories": {
"type": "array",
"items": {
"$ref": "#/definitions/company_category.CategoryResponse"
}
}
}
},
"company_category.CategoryResponse": {
"type": "object",
"properties": {
"created_at": {
"type": "integer"
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"published": {
"type": "boolean"
},
"published_at": {
"type": "integer"
},
"thumbnail": {
"type": "string"
},
"updated_at": {
"type": "integer"
}
}
},
"customer.AuthResponse": {
"type": "object",
"properties": {
@@ -6546,6 +7051,10 @@
"description": "Administrative company management operations for web panel including CRUD operations, tag management, verification, status updates, comprehensive search and filtering, and statistical reporting",
"name": "Admin-Companies"
},
{
"description": "Administrative company category management operations for web panel including CRUD operations, publish/unpublish status, and comprehensive filtering with pagination",
"name": "Admin-Company-Categories"
},
{
"description": "Administrative tender management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination",
"name": "Admin-Tenders"
+321
View File
@@ -263,6 +263,44 @@ definitions:
is_verified:
type: boolean
type: object
company_category.CategoryForm:
properties:
description:
example: Technology related companies
type: string
name:
example: Technology
type: string
thumbnail:
example: https://example.com/thumbnail.jpg
type: string
type: object
company_category.CategoryListResponse:
properties:
categories:
items:
$ref: '#/definitions/company_category.CategoryResponse'
type: array
type: object
company_category.CategoryResponse:
properties:
created_at:
type: integer
description:
type: string
id:
type: string
name:
type: string
published:
type: boolean
published_at:
type: integer
thumbnail:
type: string
updated_at:
type: integer
type: object
customer.AuthResponse:
properties:
access_token:
@@ -1545,6 +1583,285 @@ paths:
summary: Update company verification status
tags:
- Admin-Companies
/admin/v1/company-categories:
get:
consumes:
- application/json
description: Search categories with filtering capabilities
parameters:
- description: Search query
in: query
name: q
type: string
- description: Published status filter
in: query
name: published
type: boolean
- default: 20
description: Limit
in: query
name: limit
type: integer
- default: 0
description: Offset
in: query
name: offset
type: integer
- description: Sort by field
enum:
- name
- created_at
- updated_at
- published_at
in: query
name: sort_by
type: string
- description: Sort order
enum:
- asc
- desc
in: query
name: sort_order
type: string
produces:
- application/json
responses:
"200":
description: Categories search completed
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/company_category.CategoryListResponse'
type: object
"400":
description: Bad request - Invalid query parameters
schema:
$ref: '#/definitions/response.APIResponse'
"422":
description: Validation error - Invalid query parameters
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Search categories
tags:
- Admin-Company-Categories
post:
consumes:
- application/json
description: Create a new category with name, description, and thumbnail
parameters:
- description: Category information
in: body
name: category
required: true
schema:
$ref: '#/definitions/company_category.CategoryForm'
produces:
- application/json
responses:
"201":
description: Category created successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/company_category.CategoryResponse'
type: object
"400":
description: Bad request - Invalid input data
schema:
$ref: '#/definitions/response.APIResponse'
"409":
description: Conflict - Category with this name already exists
schema:
$ref: '#/definitions/response.APIResponse'
"422":
description: Validation error - Invalid request data
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Create a new category
tags:
- Admin-Company-Categories
/admin/v1/company-categories/{id}:
delete:
consumes:
- application/json
description: Delete a category permanently
parameters:
- description: Category ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Category deleted successfully
schema:
$ref: '#/definitions/response.APIResponse'
"400":
description: Bad request - Invalid category ID
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not found - Category not found
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Delete category
tags:
- Admin-Company-Categories
get:
consumes:
- application/json
description: Retrieve detailed category information by category ID
parameters:
- description: Category ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Category retrieved successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/company_category.CategoryResponse'
type: object
"400":
description: Bad request - Invalid category ID
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not found - Category not found
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Get category by ID
tags:
- Admin-Company-Categories
put:
consumes:
- application/json
description: Update category information including name, description, and thumbnail
parameters:
- description: Category ID
in: path
name: id
required: true
type: string
- description: Category update information
in: body
name: category
required: true
schema:
$ref: '#/definitions/company_category.CategoryForm'
produces:
- application/json
responses:
"200":
description: Category updated successfully
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/company_category.CategoryResponse'
type: object
"400":
description: Bad request - Invalid input data
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not found - Category not found
schema:
$ref: '#/definitions/response.APIResponse'
"409":
description: Conflict - Category with this name already exists
schema:
$ref: '#/definitions/response.APIResponse'
"422":
description: Validation error - Invalid request data
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Update category information
tags:
- Admin-Company-Categories
/admin/v1/company-categories/{id}/publish:
patch:
consumes:
- application/json
description: Toggle category publish/unpublish status
parameters:
- description: Category ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Category publish status updated successfully
schema:
$ref: '#/definitions/response.APIResponse'
"400":
description: Bad request - Invalid input data
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not found - Category not found
schema:
$ref: '#/definitions/response.APIResponse'
"422":
description: Validation error - Invalid request data
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/response.APIResponse'
security:
- BearerAuth: []
summary: Toggle category publish status
tags:
- Admin-Company-Categories
/admin/v1/customers:
get:
consumes:
@@ -4185,6 +4502,10 @@ tags:
CRUD operations, tag management, verification, status updates, comprehensive search
and filtering, and statistical reporting
name: Admin-Companies
- description: Administrative company category management operations for web panel
including CRUD operations, publish/unpublish status, and comprehensive filtering
with pagination
name: Admin-Company-Categories
- description: Administrative tender management operations for web panel including
CRUD operations, search, statistics, and comprehensive filtering with pagination
name: Admin-Tenders
+12 -5
View File
@@ -35,6 +35,9 @@ package main
// @tag.name Admin-Companies
// @tag.description Administrative company management operations for web panel including CRUD operations, tag management, verification, status updates, comprehensive search and filtering, and statistical reporting
// @tag.name Admin-Company-Categories
// @tag.description Administrative company category management operations for web panel including CRUD operations, publish/unpublish status, and comprehensive filtering with pagination
// @tag.name Admin-Tenders
// @tag.description Administrative tender management operations for web panel including CRUD operations, search, statistics, and comprehensive filtering with pagination
@@ -71,6 +74,7 @@ import (
"net/http"
"time"
"tm/internal/company"
"tm/internal/company_category"
"tm/internal/customer"
"tm/internal/feedback"
"tm/internal/inquiry"
@@ -119,12 +123,13 @@ func main() {
userRepository := user.NewUserRepository(mongoManager, logger)
customerRepository := customer.NewCustomerRepository(mongoManager, logger)
companyRepository := company.NewCompanyRepository(mongoManager, logger)
categoryRepository := company_category.NewCategoryRepository(mongoManager, logger)
tenderRepository := tender.NewTenderRepository(mongoManager, logger)
feedbackRepo := feedback.NewFeedbackRepository(mongoManager, logger)
tenderApprovalRepository := tender_approval.NewTenderApprovalRepository(mongoManager, logger)
inquiryRepository := inquiry.NewInquiryRepository(mongoManager, logger)
logger.Info("Repositories initialized successfully", map[string]interface{}{
"repositories": []string{"customer", "user", "company", "tender", "feedback", "tender_approval"},
"repositories": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval"},
})
// Initialize validation service
@@ -133,33 +138,35 @@ func main() {
// Initialize services with repositories
userService := user.NewUserService(userRepository, logger, userAuthService, userValidator)
companyService := company.NewCompanyService(companyRepository, logger)
categoryService := company_category.NewCategoryService(categoryRepository, logger)
customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService, companyService)
tenderService := tender.NewTenderService(tenderRepository, companyService, logger)
feedbackService := feedback.NewFeedbackService(feedbackRepo, tenderService, logger)
tenderApprovalService := tender_approval.NewTenderApprovalService(tenderApprovalRepository, tenderService, logger)
inquiryService := inquiry.NewInquiryService(inquiryRepository, logger)
logger.Info("Services initialized successfully", map[string]interface{}{
"services": []string{"customer", "user", "company", "tender", "feedback", "tender_approval"},
"services": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval"},
})
// Initialize handlers with services
userHandler := user.NewUserHandler(userService, logger, userValidator, userAuthService)
customerHandler := customer.NewHandler(customerService, userHandler, customerAuthService, logger)
companyHandler := company.NewHandler(companyService, userHandler, logger)
categoryHandler := company_category.NewHandler(categoryService, logger)
tenderHandler := tender.NewTenderHandler(tenderService, logger)
feedbackHandler := feedback.NewFeedbackHandler(feedbackService, userHandler, customerHandler, logger)
tenderApprovalHandler := tender_approval.NewHandler(tenderApprovalService, logger)
inquiryHandler := inquiry.NewHandler(inquiryService, logger)
logger.Info("Handlers initialized successfully", map[string]interface{}{
"handlers": []string{"customer", "user", "company", "tender", "feedback", "tender_approval"},
"handlers": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval"},
})
// Initialize HTTP server
e := bootstrap.InitHTTPServer(conf, logger)
// Register routes
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler)
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler)
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler)
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler)
// Start server
serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port)
+15 -2
View File
@@ -2,6 +2,7 @@ package router
import (
"tm/internal/company"
"tm/internal/company_category"
"tm/internal/customer"
"tm/internal/feedback"
"tm/internal/inquiry"
@@ -12,7 +13,7 @@ import (
"github.com/labstack/echo/v4"
)
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, inquiryHandler *inquiry.Handler) {
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler) {
adminV1 := e.Group("/admin/v1")
// Admin Users Routes
@@ -56,6 +57,18 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
companiesGP.PATCH("/:id/verification", companyHandler.UpdateVerification)
}
// Admin Categories Routes
categoriesGP := adminV1.Group("/company-categories")
{
categoriesGP.Use(userHandler.AuthMiddleware())
categoriesGP.POST("", categoryHandler.Create)
categoriesGP.GET("", categoryHandler.Search)
categoriesGP.GET("/:id", categoryHandler.Get)
categoriesGP.PUT("/:id", categoryHandler.Update)
categoriesGP.DELETE("/:id", categoryHandler.Delete)
categoriesGP.PATCH("/:id/publish", categoryHandler.TogglePublish)
}
// Admin Customers Routes
customersGP := adminV1.Group("/customers")
{
@@ -109,7 +122,7 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
}
}
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, companyHandler *company.Handler, inquiryHandler *inquiry.Handler) {
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, companyHandler *company.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler) {
v1 := e.Group("/api/v1")
customerGP := v1.Group("/profile")