Enhance API documentation and restructure routes for improved clarity
- Updated README.md to include comprehensive Swagger documentation details, highlighting new features and endpoint categories. - Introduced a new router structure to streamline route registration for admin and public endpoints, enhancing maintainability. - Updated health check endpoint documentation to reflect comprehensive server status information. - Enhanced customer and company management routes with improved descriptions and examples in Swagger. - Refactored customer and user handlers to remove obsolete route registrations, aligning with the new router structure. - Improved response handling in customer and user services to utilize string IDs consistently. - Updated validation rules and forms for customer management to support multiple company assignments. - Enhanced logging practices across services to ensure better traceability and error handling.
This commit is contained in:
+935
-458
File diff suppressed because it is too large
Load Diff
+935
-457
File diff suppressed because it is too large
Load Diff
+680
-313
File diff suppressed because it is too large
Load Diff
+13
-8
@@ -7,24 +7,29 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// @Summary Health check
|
||||
// @Description Get server health status
|
||||
// @Summary Health check endpoint
|
||||
// @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.
|
||||
// @Tags Health
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} HealthResponse
|
||||
// @Success 200 {object} HealthResponse "System is healthy and operational"
|
||||
// @Failure 503 {object} HealthResponse "System is unhealthy or experiencing issues"
|
||||
// @Router /admin/v1/health [get]
|
||||
func healthHandler(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, HealthResponse{
|
||||
Status: "healthy",
|
||||
Time: time.Now().Unix(),
|
||||
Version: "1.0.0",
|
||||
Version: "2.0.0",
|
||||
Service: "tender-management-api",
|
||||
Uptime: time.Since(time.Now()).String(),
|
||||
})
|
||||
}
|
||||
|
||||
// HealthResponse represents the health check response
|
||||
// HealthResponse represents the comprehensive health check response
|
||||
type HealthResponse struct {
|
||||
Status string `json:"status"`
|
||||
Time int64 `json:"time"`
|
||||
Version string `json:"version"`
|
||||
Status string `json:"status" example:"healthy"` // Current health status
|
||||
Time int64 `json:"time" example:"1699123456"` // Current Unix timestamp
|
||||
Version string `json:"version" example:"2.0.0"` // API version
|
||||
Service string `json:"service" example:"tender-management-api"` // Service name
|
||||
Uptime string `json:"uptime,omitempty" example:"24h30m15s"` // Service uptime duration
|
||||
}
|
||||
|
||||
+33
-29
@@ -1,41 +1,45 @@
|
||||
package main
|
||||
|
||||
// @title Tender Management API
|
||||
// @version 1.0.0
|
||||
// @description This is the API documentation for the Tender Management System.
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
// @version 2.0.0
|
||||
// @description This is a comprehensive API for the Tender Management System built with Clean Architecture principles and Domain-Driven Design (DDD) patterns. The API provides endpoints for user management, customer management, company management, and authentication for both web panel administration and mobile application access.
|
||||
// @termsOfService https://tender-management.com/terms
|
||||
|
||||
// @contact.name API Support
|
||||
// @contact.url http://www.swagger.io/support
|
||||
// @contact.email support@swagger.io
|
||||
// @contact.name Tender Management API Support
|
||||
// @contact.url https://tender-management.com/support
|
||||
// @contact.email api-support@tender-management.com
|
||||
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
// @license.name MIT
|
||||
// @license.url https://opensource.org/licenses/MIT
|
||||
|
||||
// @host localhost:8081
|
||||
// @BasePath /
|
||||
|
||||
// @securityDefinitions.apikey BearerAuth
|
||||
// @in header
|
||||
// @name Authorization
|
||||
// @description Type "Bearer" followed by a space and JWT token.
|
||||
|
||||
// @tag.name Users
|
||||
// @tag.description User management operations including authentication, profile management, and admin operations
|
||||
|
||||
// @tag.name Authorization
|
||||
// @tag.description Authentication operations including login, logout, and token management
|
||||
|
||||
// @tag.name Customers-Admin
|
||||
// @tag.description Customer management operations including authentication, profile management, and admin operations
|
||||
|
||||
// @tag.name Customers-Authorization
|
||||
// @tag.description Customer authentication operations including login, logout, and token management
|
||||
|
||||
// @tag.name Companies-Admin
|
||||
// @tag.description Company management operations for web panel including CRUD, customer assignment, and tag management
|
||||
// @description Type "Bearer" followed by a space and JWT token. Example: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
|
||||
// @tag.name Health
|
||||
// @tag.description Health check operations
|
||||
// @tag.description System health check operations for monitoring application status and dependencies
|
||||
|
||||
// @tag.name Authorization
|
||||
// @tag.description User authentication and authorization operations including login, logout, token refresh, and password management for web panel administration
|
||||
|
||||
// @tag.name Users
|
||||
// @tag.description Administrative user management operations including CRUD operations, role management, status updates, and profile management for web panel administrators
|
||||
|
||||
// @tag.name Customers-Admin
|
||||
// @tag.description Administrative customer management operations for web panel including CRUD operations, company assignment, verification, status management, and comprehensive filtering with pagination
|
||||
|
||||
// @tag.name Customers-Authorization
|
||||
// @tag.description Customer authentication and authorization operations for mobile application including login, logout, token refresh, and profile access
|
||||
|
||||
// @tag.name Companies-Admin
|
||||
// @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 Companies-Mobile
|
||||
// @tag.description Company-related operations for mobile application including company lookup, search, and basic information retrieval
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -47,6 +51,7 @@ import (
|
||||
"tm/internal/user"
|
||||
|
||||
_ "tm/cmd/web/docs" // This is generated by swag
|
||||
"tm/cmd/web/router"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -95,8 +100,8 @@ func main() {
|
||||
|
||||
// Initialize services with repositories
|
||||
userService := user.NewUserService(userRepository, logger, userAuthService, userValidator)
|
||||
customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService)
|
||||
companyService := company.NewCompanyService(companyRepository, logger)
|
||||
customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService, companyService)
|
||||
|
||||
logger.Info("Services initialized successfully", map[string]interface{}{
|
||||
"services": []string{"customer", "user", "company"},
|
||||
@@ -115,9 +120,8 @@ func main() {
|
||||
e := initHTTPServer(conf, logger)
|
||||
|
||||
// Register routes
|
||||
userHandler.RegisterRoutes(e)
|
||||
customerHandler.RegisterRoutes(e)
|
||||
companyHandler.RegisterRoutes(e)
|
||||
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler)
|
||||
router.RegisterPublicRoutes(e, customerHandler)
|
||||
|
||||
// Start server
|
||||
serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port)
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"tm/internal/company"
|
||||
"tm/internal/customer"
|
||||
"tm/internal/user"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler) {
|
||||
adminV1 := e.Group("/admin/v1")
|
||||
|
||||
// Admin Users Routes
|
||||
adminUsersGP := adminV1.Group("/users")
|
||||
{
|
||||
adminUsersGP.Use(userHandler.AuthMiddleware())
|
||||
adminUsersGP.POST("", userHandler.CreateUser)
|
||||
adminUsersGP.GET("", userHandler.ListUsers)
|
||||
adminUsersGP.GET("/:id", userHandler.GetUserByID)
|
||||
adminUsersGP.PUT("/:id", userHandler.UpdateUser)
|
||||
adminUsersGP.DELETE("/:id", userHandler.DeleteUser)
|
||||
adminUsersGP.PUT("/:id/status", userHandler.UpdateUserStatus)
|
||||
adminUsersGP.PUT("/:id/role", userHandler.UpdateUserRole)
|
||||
adminUsersGP.GET("/company/:company_id", userHandler.GetUsersByCompanyID)
|
||||
adminUsersGP.GET("/role/:role", userHandler.GetUsersByRole)
|
||||
}
|
||||
|
||||
// Admin user profile
|
||||
profileGP := adminV1.Group("/profile")
|
||||
{
|
||||
userAuthorizationGP := profileGP.Group("")
|
||||
userAuthorizationGP.POST("/login", userHandler.Login)
|
||||
userAuthorizationGP.POST("/refresh-token", userHandler.RefreshToken)
|
||||
userAuthorizationGP.POST("/reset-password", userHandler.ResetPassword)
|
||||
|
||||
userProfileGP := profileGP.Group("")
|
||||
userProfileGP.Use(userHandler.AuthMiddleware())
|
||||
userProfileGP.GET("", userHandler.GetProfile)
|
||||
userProfileGP.PUT("", userHandler.UpdateProfile)
|
||||
userProfileGP.PUT("/change-password", userHandler.ChangePassword)
|
||||
userProfileGP.DELETE("/logout", userHandler.Logout)
|
||||
}
|
||||
|
||||
// Admin Companies Routes
|
||||
companiesGP := adminV1.Group("/companies")
|
||||
{
|
||||
companiesGP.Use(userHandler.AuthMiddleware())
|
||||
companiesGP.POST("", companyHandler.CreateCompany)
|
||||
companiesGP.GET("", companyHandler.ListCompanies)
|
||||
companiesGP.GET("/:id", companyHandler.GetCompany)
|
||||
companiesGP.PUT("/:id", companyHandler.UpdateCompany)
|
||||
companiesGP.DELETE("/:id", companyHandler.DeleteCompany)
|
||||
companiesGP.GET("/search", companyHandler.SearchCompanies)
|
||||
companiesGP.PATCH("/:id/status", companyHandler.UpdateCompanyStatus)
|
||||
companiesGP.PATCH("/:id/verification", companyHandler.UpdateCompanyVerification)
|
||||
companiesGP.PUT("/:id/tags", companyHandler.UpdateCompanyTags)
|
||||
companiesGP.POST("/:id/tags/add", companyHandler.AddTags)
|
||||
companiesGP.POST("/:id/tags/remove", companyHandler.RemoveTags)
|
||||
companiesGP.POST("/:id/verify", companyHandler.VerifyCompany)
|
||||
companiesGP.POST("/:id/suspend", companyHandler.SuspendCompany)
|
||||
companiesGP.POST("/:id/activate", companyHandler.ActivateCompany)
|
||||
companiesGP.GET("/stats", companyHandler.GetCompanyStats)
|
||||
companiesGP.GET("/type/:type", companyHandler.GetCompaniesByType)
|
||||
companiesGP.GET("/status/:status", companyHandler.GetCompaniesByStatus)
|
||||
companiesGP.GET("/industry/:industry", companyHandler.GetCompaniesByIndustry)
|
||||
}
|
||||
|
||||
// Admin Customers Routes
|
||||
|
||||
customersGP := adminV1.Group("/customers")
|
||||
{
|
||||
customersGP.Use(userHandler.AuthMiddleware())
|
||||
customersGP.POST("", customerHandler.CreateCustomer)
|
||||
customersGP.GET("", customerHandler.ListCustomers)
|
||||
customersGP.GET("/with-companies", customerHandler.ListCustomersWithCompanies)
|
||||
customersGP.GET("/:id", customerHandler.GetCustomerByID)
|
||||
customersGP.GET("/:id/with-companies", customerHandler.GetCustomerByIDWithCompanies)
|
||||
customersGP.PUT("/:id", customerHandler.UpdateCustomer)
|
||||
customersGP.DELETE("/:id", customerHandler.DeleteCustomer)
|
||||
customersGP.PATCH("/:id/status", customerHandler.UpdateCustomerStatus)
|
||||
customersGP.PATCH("/:id/verification", customerHandler.UpdateCustomerVerification)
|
||||
customersGP.POST("/:id/verify", customerHandler.VerifyCustomer)
|
||||
customersGP.POST("/:id/suspend", customerHandler.SuspendCustomer)
|
||||
customersGP.POST("/:id/activate", customerHandler.ActivateCustomer)
|
||||
customersGP.GET("/company/:companyId", customerHandler.GetCustomersByCompanyID)
|
||||
customersGP.GET("/type/:type", customerHandler.GetCustomersByType)
|
||||
customersGP.GET("/status/:status", customerHandler.GetCustomersByStatus)
|
||||
customersGP.POST("/:id/companies/assign", customerHandler.AssignCompaniesToCustomer)
|
||||
customersGP.POST("/:id/companies/remove", customerHandler.RemoveCompaniesFromCustomer)
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler) {
|
||||
v1 := e.Group("/api/v1")
|
||||
|
||||
customerGP := v1.Group("/profile")
|
||||
{
|
||||
customerGP.POST("/login", customerHandler.Login)
|
||||
customerGP.POST("/refresh-token", customerHandler.RefreshToken)
|
||||
|
||||
profileGP := v1.Group("")
|
||||
profileGP.Use(customerHandler.AuthMiddleware())
|
||||
profileGP.GET("", customerHandler.GetProfile)
|
||||
profileGP.GET("/with-companies", customerHandler.GetProfileWithCompanies)
|
||||
profileGP.DELETE("/logout", customerHandler.Logout)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user