Add Contact Management Functionality

- Introduced a new contact management feature, including the ability to create, retrieve, search, update, and delete contact messages.
- Implemented the Contact entity, repository, service, and handler layers following Clean Architecture principles.
- Added API endpoints for contact operations in Swagger documentation, ensuring comprehensive API specifications.
- Enhanced error handling and validation for contact data, improving robustness and user experience.
- Updated the main application to initialize the contact repository and service, integrating them into the existing system.
This commit is contained in:
n.nakhostin
2025-10-25 18:15:39 +03:30
parent 889a56a9f9
commit 875447ac58
11 changed files with 2151 additions and 10 deletions
+492
View File
@@ -1043,6 +1043,337 @@ const docTemplate = `{
}
}
},
"/admin/v1/contacts": {
"get": {
"description": "Search contacts with filters and pagination (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Search contacts",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query"
},
{
"enum": [
"pending",
"in_progress",
"resolved",
"closed"
],
"type": "string",
"description": "Contact status",
"name": "status",
"in": "query"
},
{
"type": "integer",
"description": "Date from (Unix timestamp)",
"name": "date_from",
"in": "query"
},
{
"type": "integer",
"description": "Date to (Unix timestamp)",
"name": "date_to",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"default": 20,
"description": "Number of contacts per page (1-100)",
"name": "limit",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"default": 0,
"description": "Number of contacts to skip for pagination",
"name": "offset",
"in": "query"
},
{
"enum": [
"full_name",
"email",
"created_at",
"updated_at",
"status"
],
"type": "string",
"default": "created_at",
"description": "Field to sort by",
"name": "sort_by",
"in": "query"
},
{
"enum": [
"asc",
"desc"
],
"type": "string",
"default": "desc",
"description": "Sort order",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/contacts/stats": {
"get": {
"description": "Get contact statistics by status (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Get contact statistics",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactStats"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/contacts/{id}": {
"get": {
"description": "Retrieve a contact message by its ID (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Get contact by ID",
"parameters": [
{
"type": "string",
"description": "Contact ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"description": "Delete a contact message by ID (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Delete contact",
"parameters": [
{
"type": "string",
"description": "Contact ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/contacts/{id}/status": {
"put": {
"description": "Update the status of a contact message (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Update contact status",
"parameters": [
{
"type": "string",
"description": "Contact ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Status update information",
"name": "status",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/contact.UpdateContactStatusForm"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/customers": {
"get": {
"security": [
@@ -4699,6 +5030,64 @@ const docTemplate = `{
}
}
},
"/api/v1/contacts": {
"post": {
"description": "Create a new contact message from a user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Create a new contact message",
"parameters": [
{
"description": "Contact information",
"name": "contact",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/contact.CreateContactForm"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/feedback": {
"get": {
"security": [
@@ -7369,6 +7758,109 @@ const docTemplate = `{
}
}
},
"contact.ContactListResponse": {
"type": "object",
"properties": {
"contacts": {
"type": "array",
"items": {
"$ref": "#/definitions/contact.ContactResponse"
}
}
}
},
"contact.ContactResponse": {
"type": "object",
"properties": {
"admin_notes": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"email": {
"type": "string"
},
"full_name": {
"type": "string"
},
"id": {
"type": "string"
},
"message": {
"type": "string"
},
"phone": {
"type": "string"
},
"resolved_at": {
"type": "integer"
},
"resolved_by": {
"type": "string"
},
"status": {
"type": "string"
},
"updated_at": {
"type": "integer"
}
}
},
"contact.ContactStats": {
"type": "object",
"properties": {
"closed": {
"type": "integer"
},
"in_progress": {
"type": "integer"
},
"pending": {
"type": "integer"
},
"resolved": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"contact.CreateContactForm": {
"type": "object",
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"full_name": {
"type": "string",
"example": "John Doe"
},
"message": {
"type": "string",
"example": "I have a question about your services"
},
"phone": {
"type": "string",
"example": "+1234567890"
}
}
},
"contact.UpdateContactStatusForm": {
"type": "object",
"properties": {
"admin_notes": {
"type": "string",
"example": "Customer inquiry handled"
},
"status": {
"type": "string",
"example": "in_progress"
}
}
},
"customer.AssignCompaniesForm": {
"type": "object",
"properties": {
+492
View File
@@ -1035,6 +1035,337 @@
}
}
},
"/admin/v1/contacts": {
"get": {
"description": "Search contacts with filters and pagination (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Search contacts",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query"
},
{
"enum": [
"pending",
"in_progress",
"resolved",
"closed"
],
"type": "string",
"description": "Contact status",
"name": "status",
"in": "query"
},
{
"type": "integer",
"description": "Date from (Unix timestamp)",
"name": "date_from",
"in": "query"
},
{
"type": "integer",
"description": "Date to (Unix timestamp)",
"name": "date_to",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"default": 20,
"description": "Number of contacts per page (1-100)",
"name": "limit",
"in": "query"
},
{
"minimum": 0,
"type": "integer",
"default": 0,
"description": "Number of contacts to skip for pagination",
"name": "offset",
"in": "query"
},
{
"enum": [
"full_name",
"email",
"created_at",
"updated_at",
"status"
],
"type": "string",
"default": "created_at",
"description": "Field to sort by",
"name": "sort_by",
"in": "query"
},
{
"enum": [
"asc",
"desc"
],
"type": "string",
"default": "desc",
"description": "Sort order",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactListResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/contacts/stats": {
"get": {
"description": "Get contact statistics by status (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Get contact statistics",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactStats"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/contacts/{id}": {
"get": {
"description": "Retrieve a contact message by its ID (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Get contact by ID",
"parameters": [
{
"type": "string",
"description": "Contact ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"description": "Delete a contact message by ID (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Delete contact",
"parameters": [
{
"type": "string",
"description": "Contact ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/contacts/{id}/status": {
"put": {
"description": "Update the status of a contact message (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Update contact status",
"parameters": [
{
"type": "string",
"description": "Contact ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Status update information",
"name": "status",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/contact.UpdateContactStatusForm"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/admin/v1/customers": {
"get": {
"security": [
@@ -4691,6 +5022,64 @@
}
}
},
"/api/v1/contacts": {
"post": {
"description": "Create a new contact message from a user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"contacts"
],
"summary": "Create a new contact message",
"parameters": [
{
"description": "Contact information",
"name": "contact",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/contact.CreateContactForm"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/contact.ContactResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/feedback": {
"get": {
"security": [
@@ -7361,6 +7750,109 @@
}
}
},
"contact.ContactListResponse": {
"type": "object",
"properties": {
"contacts": {
"type": "array",
"items": {
"$ref": "#/definitions/contact.ContactResponse"
}
}
}
},
"contact.ContactResponse": {
"type": "object",
"properties": {
"admin_notes": {
"type": "string"
},
"created_at": {
"type": "integer"
},
"email": {
"type": "string"
},
"full_name": {
"type": "string"
},
"id": {
"type": "string"
},
"message": {
"type": "string"
},
"phone": {
"type": "string"
},
"resolved_at": {
"type": "integer"
},
"resolved_by": {
"type": "string"
},
"status": {
"type": "string"
},
"updated_at": {
"type": "integer"
}
}
},
"contact.ContactStats": {
"type": "object",
"properties": {
"closed": {
"type": "integer"
},
"in_progress": {
"type": "integer"
},
"pending": {
"type": "integer"
},
"resolved": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
},
"contact.CreateContactForm": {
"type": "object",
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"full_name": {
"type": "string",
"example": "John Doe"
},
"message": {
"type": "string",
"example": "I have a question about your services"
},
"phone": {
"type": "string",
"example": "+1234567890"
}
}
},
"contact.UpdateContactStatusForm": {
"type": "object",
"properties": {
"admin_notes": {
"type": "string",
"example": "Customer inquiry handled"
},
"status": {
"type": "string",
"example": "in_progress"
}
}
},
"customer.AssignCompaniesForm": {
"type": "object",
"properties": {
+319
View File
@@ -302,6 +302,75 @@ definitions:
updated_at:
type: integer
type: object
contact.ContactListResponse:
properties:
contacts:
items:
$ref: '#/definitions/contact.ContactResponse'
type: array
type: object
contact.ContactResponse:
properties:
admin_notes:
type: string
created_at:
type: integer
email:
type: string
full_name:
type: string
id:
type: string
message:
type: string
phone:
type: string
resolved_at:
type: integer
resolved_by:
type: string
status:
type: string
updated_at:
type: integer
type: object
contact.ContactStats:
properties:
closed:
type: integer
in_progress:
type: integer
pending:
type: integer
resolved:
type: integer
total:
type: integer
type: object
contact.CreateContactForm:
properties:
email:
example: john.doe@example.com
type: string
full_name:
example: John Doe
type: string
message:
example: I have a question about your services
type: string
phone:
example: "+1234567890"
type: string
type: object
contact.UpdateContactStatusForm:
properties:
admin_notes:
example: Customer inquiry handled
type: string
status:
example: in_progress
type: string
type: object
customer.AssignCompaniesForm:
properties:
companies:
@@ -1999,6 +2068,221 @@ paths:
summary: Toggle category publish status
tags:
- Admin-Company-Categories
/admin/v1/contacts:
get:
consumes:
- application/json
description: Search contacts with filters and pagination (admin only)
parameters:
- description: Search query
in: query
name: q
type: string
- description: Contact status
enum:
- pending
- in_progress
- resolved
- closed
in: query
name: status
type: string
- description: Date from (Unix timestamp)
in: query
name: date_from
type: integer
- description: Date to (Unix timestamp)
in: query
name: date_to
type: integer
- default: 20
description: Number of contacts per page (1-100)
in: query
maximum: 100
minimum: 1
name: limit
type: integer
- default: 0
description: Number of contacts to skip for pagination
in: query
minimum: 0
name: offset
type: integer
- default: created_at
description: Field to sort by
enum:
- full_name
- email
- created_at
- updated_at
- status
in: query
name: sort_by
type: string
- default: desc
description: Sort order
enum:
- asc
- desc
in: query
name: sort_order
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/contact.ContactListResponse'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Search contacts
tags:
- contacts
/admin/v1/contacts/{id}:
delete:
consumes:
- application/json
description: Delete a contact message by ID (admin only)
parameters:
- description: Contact ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.APIResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Delete contact
tags:
- contacts
get:
consumes:
- application/json
description: Retrieve a contact message by its ID (admin only)
parameters:
- description: Contact ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/contact.ContactResponse'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Get contact by ID
tags:
- contacts
/admin/v1/contacts/{id}/status:
put:
consumes:
- application/json
description: Update the status of a contact message (admin only)
parameters:
- description: Contact ID
in: path
name: id
required: true
type: string
- description: Status update information
in: body
name: status
required: true
schema:
$ref: '#/definitions/contact.UpdateContactStatusForm'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.APIResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Update contact status
tags:
- contacts
/admin/v1/contacts/stats:
get:
consumes:
- application/json
description: Get contact statistics by status (admin only)
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/contact.ContactStats'
type: object
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Get contact statistics
tags:
- contacts
/admin/v1/customers:
get:
consumes:
@@ -4314,6 +4598,41 @@ paths:
summary: Get my company profile
tags:
- Company
/api/v1/contacts:
post:
consumes:
- application/json
description: Create a new contact message from a user
parameters:
- description: Contact information
in: body
name: contact
required: true
schema:
$ref: '#/definitions/contact.CreateContactForm'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/response.APIResponse'
- properties:
data:
$ref: '#/definitions/contact.ContactResponse'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Create a new contact message
tags:
- contacts
/api/v1/feedback:
get:
consumes:
+10 -6
View File
@@ -85,6 +85,7 @@ import (
"tm/internal/assets"
"tm/internal/company"
"tm/internal/company_category"
"tm/internal/contact"
"tm/internal/customer"
"tm/internal/feedback"
"tm/internal/inquiry"
@@ -142,8 +143,9 @@ func main() {
feedbackRepo := feedback.NewRepository(mongoManager, logger)
tenderApprovalRepository := tender_approval.NewRepository(mongoManager, logger)
inquiryRepository := inquiry.NewRepository(mongoManager, logger)
contactRepository := contact.NewContactRepository(mongoManager, logger)
logger.Info("Repositories initialized successfully", map[string]interface{}{
"repositories": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry"},
"repositories": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "contact"},
})
// Initialize validation services
@@ -161,8 +163,9 @@ func main() {
inquiryService := inquiry.NewService(inquiryRepository, notificationSDK, logger)
flagService := assets.NewService(logger, conf.Assets.FlagsPath)
notificationService := notification.NewService(notificationSDK, userService, customerService, logger)
contactService := contact.NewService(contactRepository, logger)
logger.Info("Services initialized successfully", map[string]interface{}{
"services": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification"},
"services": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification", "contact"},
})
// Initialize handlers with services
@@ -175,17 +178,18 @@ func main() {
tenderApprovalHandler := tender_approval.NewHandler(tenderApprovalService, logger)
inquiryHandler := inquiry.NewHandler(inquiryService, logger)
flagHandler := assets.NewHandler(flagService, logger)
notificationHandler := notification.NewHandler(notificationService, logger)
notificationHandler := notification.NewHandler(notificationService)
contactHandler := contact.NewHandler(contactService)
logger.Info("Handlers initialized successfully", map[string]interface{}{
"handlers": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification"},
"handlers": []string{"customer", "user", "company", "category", "tender", "feedback", "tender_approval", "inquiry", "flag", "notification", "contact"},
})
// Initialize HTTP server
e := bootstrap.InitHTTPServer(conf, logger)
// Register routes
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler)
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler)
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler)
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler)
// Start server
serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port)