diff --git a/cmd/web/docs/docs.go b/cmd/web/docs/docs.go index e9e6254..500804c 100644 --- a/cmd/web/docs/docs.go +++ b/cmd/web/docs/docs.go @@ -5069,6 +5069,58 @@ const docTemplate = `{ } } }, + "/api/v1/companies": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Retrieve the profile of the company associated with the authenticated user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Company" + ], + "summary": "Get my company profile", + "responses": { + "200": { + "description": "Company retrieved successfully", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.APIResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/company.CompanyProfileResponse" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized - User not authenticated", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/feedback": { "get": { "security": [ @@ -6513,6 +6565,32 @@ const docTemplate = `{ } } }, + "company.CompanyProfileResponse": { + "type": "object", + "properties": { + "country": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "founded_year": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "industry": { + "type": "string" + }, + "name": { + "type": "string" + }, + "registration_number": { + "type": "string" + } + } + }, "company.CompanyResponse": { "type": "object", "properties": { diff --git a/cmd/web/docs/swagger.json b/cmd/web/docs/swagger.json index 3022f98..dab8bbd 100644 --- a/cmd/web/docs/swagger.json +++ b/cmd/web/docs/swagger.json @@ -5063,6 +5063,58 @@ } } }, + "/api/v1/companies": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Retrieve the profile of the company associated with the authenticated user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Company" + ], + "summary": "Get my company profile", + "responses": { + "200": { + "description": "Company retrieved successfully", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.APIResponse" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/company.CompanyProfileResponse" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized - User not authenticated", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/feedback": { "get": { "security": [ @@ -6507,6 +6559,32 @@ } } }, + "company.CompanyProfileResponse": { + "type": "object", + "properties": { + "country": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "founded_year": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "industry": { + "type": "string" + }, + "name": { + "type": "string" + }, + "registration_number": { + "type": "string" + } + } + }, "company.CompanyResponse": { "type": "object", "properties": { diff --git a/cmd/web/docs/swagger.yaml b/cmd/web/docs/swagger.yaml index 9395446..7f29b63 100644 --- a/cmd/web/docs/swagger.yaml +++ b/cmd/web/docs/swagger.yaml @@ -78,6 +78,23 @@ definitions: total_pages: type: integer type: object + company.CompanyProfileResponse: + properties: + country: + type: string + created_at: + type: integer + founded_year: + type: integer + id: + type: string + industry: + type: string + name: + type: string + registration_number: + type: string + type: object company.CompanyResponse: properties: address: @@ -4501,6 +4518,37 @@ paths: summary: Get users by role tags: - Admin-Users + /api/v1/companies: + get: + consumes: + - application/json + description: Retrieve the profile of the company associated with the authenticated + user + produces: + - application/json + responses: + "200": + description: Company retrieved successfully + schema: + allOf: + - $ref: '#/definitions/response.APIResponse' + - properties: + data: + $ref: '#/definitions/company.CompanyProfileResponse' + type: object + "401": + description: Unauthorized - User not authenticated + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal server error + schema: + $ref: '#/definitions/response.APIResponse' + security: + - BearerAuth: [] + summary: Get my company profile + tags: + - Company /api/v1/feedback: get: consumes: diff --git a/cmd/web/main.go b/cmd/web/main.go index 150353a..34f0418 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -47,6 +47,9 @@ package main // @tag.name Authorization // @tag.description Customer authentication and authorization operations for mobile application including login, logout, token refresh, and profile access +// @tag.name Company +// @tag.description Company information access for mobile application including company profile and company tenders + // @tag.name Tenders // @tag.description Public tender information access for mobile application including active tender listings and detailed tender information @@ -146,7 +149,7 @@ func main() { // Register routes router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler) - router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler) + router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler) // Start server serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port) diff --git a/cmd/web/router/routes.go b/cmd/web/router/routes.go index 7eec87c..09afc57 100644 --- a/cmd/web/router/routes.go +++ b/cmd/web/router/routes.go @@ -121,7 +121,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) { +func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, companyHandler *company.Handler) { v1 := e.Group("/api/v1") customerGP := v1.Group("/profile") @@ -164,4 +164,11 @@ func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tende tenderApprovalGP.GET("/tender/:tender_id", tenderApprovalHandler.GetTenderApprovalByTenderAndCompany) tenderApprovalGP.GET("/stats", tenderApprovalHandler.GetCompanyTenderApprovalStats) } + + // Public Company Routes + companiesGP := v1.Group("/companies") + { + companiesGP.Use(customerHandler.AuthMiddleware()) + companiesGP.GET("", companyHandler.MyCompany) + } } diff --git a/internal/company/entity.go b/internal/company/entity.go index 7cbe899..60c904c 100644 --- a/internal/company/entity.go +++ b/internal/company/entity.go @@ -202,3 +202,25 @@ func (c *Company) ToResponse() *CompanyResponse { UpdatedBy: c.UpdatedBy, } } + +type CompanyProfileResponse struct { + ID string `json:"id"` + Name string `json:"name"` + RegistrationNumber string `json:"registration_number"` + Industry string `json:"industry"` + Country string `json:"country"` + FoundedYear *int `json:"founded_year,omitempty"` + CreatedAt int64 `json:"created_at"` +} + +// ToResponse converts Company to CompanyResponse +func (c *Company) ToProfileResponse() *CompanyProfileResponse { + return &CompanyProfileResponse{ + ID: c.ID.Hex(), + Name: c.Name, + RegistrationNumber: c.RegistrationNumber, + Industry: c.Industry, + FoundedYear: c.FoundedYear, + CreatedAt: c.CreatedAt, + } +} diff --git a/internal/company/handler.go b/internal/company/handler.go index 984d468..bf2778c 100644 --- a/internal/company/handler.go +++ b/internal/company/handler.go @@ -25,6 +25,35 @@ func NewHandler(service Service, userHandler *user.Handler, logger logger.Logger } } +// **************************** PUBLIC ENDPOINTS **************************** + +// MyCompany returns the authenticated user's company profile (Mobile App) +// @Summary Get my company profile +// @Description Retrieve the profile of the company associated with the authenticated user +// @Tags Company +// @Accept json +// @Produce json +// @Success 200 {object} response.APIResponse{data=CompanyProfileResponse} "Company retrieved successfully" +// @Failure 401 {object} response.APIResponse "Unauthorized - User not authenticated" +// @Failure 500 {object} response.APIResponse "Internal server error" +// @Security BearerAuth +// @Router /api/v1/companies [get] +func (h *Handler) MyCompany(c echo.Context) error { + companyID, err := user.GetCompanyIDFromContext(c) + if err != nil { + return response.Unauthorized(c, "User not authenticated") + } + + company, err := h.service.GetCompanyByID(c.Request().Context(), companyID) + if err != nil { + return response.InternalServerError(c, "Failed to get company") + } + + return response.Success(c, company.ToProfileResponse(), "Company retrieved successfully") +} + +// **************************** ADMIN ENDPOINTS **************************** + // CreateCompany creates a new company (Web Panel) // @Summary Create a new company // @Description Create a new company with comprehensive information including business details, address, tags, and customer assignment. This endpoint is used by the web panel for full company registration.