diff --git a/backend/docs/docs.go b/backend/docs/docs.go index 7b158ca..d02f33f 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -223,7 +223,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.LoginRequest" + "type": "object" } } ], @@ -231,7 +231,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.AuthResponse" + "type": "object" } }, "400": { @@ -268,7 +268,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/dto.CompanyResponse" + "type": "object" } } }, @@ -299,7 +299,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.CreateCompanyRequest" + "type": "object" } } ], @@ -307,7 +307,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.CompanyResponse" + "type": "object" } }, "400": { @@ -558,6 +558,120 @@ const docTemplate = `{ } } }, + "/api/v1/notifications": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Returns a list of notifications for the current user.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifications" + ], + "summary": "List Notifications", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Notification" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/notifications/read-all": { + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Marks all notifications as read.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifications" + ], + "summary": "Mark All Notifications Read", + "responses": { + "200": { + "description": "All marked as read", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/notifications/{id}/read": { + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Marks a notification as read.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifications" + ], + "summary": "Mark Notification Read", + "parameters": [ + { + "type": "string", + "description": "Notification ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Marked as read", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/storage/download-url": { "post": { "security": [ @@ -706,6 +820,199 @@ const docTemplate = `{ } } }, + "/api/v1/support/tickets": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Returns a list of tickets for the current user.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "List Tickets", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Ticket" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Creates a new support ticket.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "Create Ticket", + "parameters": [ + { + "description": "Ticket Details", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.Ticket" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/support/tickets/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Returns ticket details and chat history.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "Get Ticket Details", + "parameters": [ + { + "type": "string", + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/support/tickets/{id}/messages": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Adds a message to an existing ticket.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "Add Ticket Message", + "parameters": [ + { + "type": "string", + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Message", + "name": "message", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.TicketMessage" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/users": { "get": { "security": [ @@ -717,6 +1024,13 @@ const docTemplate = `{ "consumes": [ "application/json" ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "List Users", "parameters": [ { "type": "integer", @@ -731,18 +1045,11 @@ const docTemplate = `{ "in": "query" } ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "List Users", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.PaginatedResponse" + "type": "object" } }, "403": { @@ -783,7 +1090,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.CreateUserRequest" + "type": "object" } } ], @@ -791,7 +1098,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.UserResponse" + "type": "object" } }, "400": { @@ -815,6 +1122,109 @@ const docTemplate = `{ } } }, + "/api/v1/users/me/avatar": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Uploads a profile picture for the current user.", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Upload Avatar", + "parameters": [ + { + "type": "file", + "description": "Avatar File", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/users/me/profile": { + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Updates the current user's profile.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update My Profile", + "parameters": [ + { + "description": "Profile Details", + "name": "user", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/users/{id}": { "delete": { "security": [ @@ -862,38 +1272,66 @@ const docTemplate = `{ } } } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Updates user details (Name, Email, Active Status)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update User", + "parameters": [ + { + "type": "string", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "User Updates", + "name": "user", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } } } }, "definitions": { - "dto.AuthResponse": { - "type": "object", - "properties": { - "token": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/dto.UserResponse" - } - } - }, - "dto.CompanyResponse": { - "type": "object", - "properties": { - "created_at": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, "dto.CreateApplicationRequest": { "type": "object", "required": [ @@ -908,7 +1346,7 @@ const docTemplate = `{ "type": "string" }, "jobId": { - "type": "integer" + "type": "string" }, "lineId": { "type": "string" @@ -926,62 +1364,13 @@ const docTemplate = `{ "type": "string" }, "userId": { - "type": "integer" + "type": "string" }, "whatsapp": { "type": "string" } } }, - "dto.CreateCompanyRequest": { - "type": "object", - "required": [ - "name", - "slug" - ], - "properties": { - "address": { - "type": "string" - }, - "cityId": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "document": { - "type": "string" - }, - "email": { - "type": "string" - }, - "logoUrl": { - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 255, - "minLength": 3 - }, - "phone": { - "type": "string" - }, - "regionId": { - "type": "integer" - }, - "slug": { - "type": "string", - "maxLength": 255, - "minLength": 3 - }, - "type": { - "type": "string" - }, - "website": { - "type": "string" - } - } - }, "dto.CreateJobRequest": { "type": "object", "required": [ @@ -998,7 +1387,17 @@ const docTemplate = `{ "type": "integer" }, "companyId": { - "type": "integer" + "type": "string" + }, + "currency": { + "type": "string", + "enum": [ + "BRL", + "USD", + "EUR", + "GBP", + "JPY" + ] }, "description": { "type": "string", @@ -1010,7 +1409,11 @@ const docTemplate = `{ "full-time", "part-time", "dispatch", - "contract" + "contract", + "temporary", + "training", + "voluntary", + "permanent" ] }, "languageLevel": { @@ -1036,6 +1439,8 @@ const docTemplate = `{ "type": "string", "enum": [ "hourly", + "daily", + "weekly", "monthly", "yearly" ] @@ -1045,7 +1450,13 @@ const docTemplate = `{ "enum": [ "draft", "open", - "closed" + "closed", + "review", + "published", + "paused", + "expired", + "archived", + "reported" ] }, "title": { @@ -1061,44 +1472,6 @@ const docTemplate = `{ } } }, - "dto.CreateUserRequest": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "name": { - "type": "string" - }, - "password": { - "type": "string" - }, - "roles": { - "description": "e.g. [\"RECRUITER\"]", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "dto.LoginRequest": { - "type": "object", - "required": [ - "identifier", - "password" - ], - "properties": { - "identifier": { - "type": "string", - "minLength": 3 - }, - "password": { - "type": "string", - "minLength": 8 - } - } - }, "dto.PaginatedResponse": { "type": "object", "properties": { @@ -1153,6 +1526,16 @@ const docTemplate = `{ "cityId": { "type": "integer" }, + "currency": { + "type": "string", + "enum": [ + "BRL", + "USD", + "EUR", + "GBP", + "JPY" + ] + }, "description": { "type": "string", "minLength": 20 @@ -1163,7 +1546,11 @@ const docTemplate = `{ "full-time", "part-time", "dispatch", - "contract" + "contract", + "temporary", + "training", + "voluntary", + "permanent" ] }, "languageLevel": { @@ -1189,6 +1576,8 @@ const docTemplate = `{ "type": "string", "enum": [ "hourly", + "daily", + "weekly", "monthly", "yearly" ] @@ -1198,7 +1587,13 @@ const docTemplate = `{ "enum": [ "draft", "open", - "closed" + "closed", + "review", + "published", + "paused", + "expired", + "archived", + "reported" ] }, "title": { @@ -1214,32 +1609,6 @@ const docTemplate = `{ } } }, - "dto.UserResponse": { - "type": "object", - "properties": { - "created_at": { - "type": "string" - }, - "email": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "roles": { - "type": "array", - "items": { - "type": "string" - } - }, - "status": { - "type": "string" - } - } - }, "handlers.DownloadURLRequest": { "type": "object", "properties": { @@ -1312,10 +1681,10 @@ const docTemplate = `{ "type": "string" }, "id": { - "type": "integer" + "type": "string" }, "jobId": { - "type": "integer" + "type": "string" }, "lineId": { "type": "string" @@ -1346,7 +1715,7 @@ const docTemplate = `{ }, "userId": { "description": "NULL for guest applications", - "type": "integer" + "type": "string" }, "whatsapp": { "type": "string" @@ -1367,14 +1736,18 @@ const docTemplate = `{ "type": "integer" }, "companyId": { - "type": "integer" + "type": "string" }, "createdAt": { "description": "Metadata", "type": "string" }, "createdBy": { - "type": "integer" + "type": "string" + }, + "currency": { + "description": "BRL, USD, EUR, GBP, JPY", + "type": "string" }, "description": { "type": "string" @@ -1384,7 +1757,7 @@ const docTemplate = `{ "type": "string" }, "id": { - "type": "integer" + "type": "string" }, "isFeatured": { "description": "Featured job flag", @@ -1417,7 +1790,7 @@ const docTemplate = `{ "type": "number" }, "salaryType": { - "description": "hourly, monthly, yearly", + "description": "hourly, daily, weekly, monthly, yearly", "type": "string" }, "status": { @@ -1435,10 +1808,95 @@ const docTemplate = `{ "description": "Visa \u0026 Language", "type": "boolean" }, + "workMode": { + "description": "onsite, hybrid, remote", + "type": "string" + }, "workingHours": { "type": "string" } } + }, + "models.Notification": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "link": { + "type": "string" + }, + "message": { + "type": "string" + }, + "readAt": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "description": "info, success, warning, error", + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } + }, + "models.Ticket": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "priority": { + "description": "low, medium, high", + "type": "string" + }, + "status": { + "description": "open, in_progress, closed", + "type": "string" + }, + "subject": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } + }, + "models.TicketMessage": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "ticketId": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } } } }` diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 8cd9a8d..03706eb 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -216,7 +216,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.LoginRequest" + "type": "object" } } ], @@ -224,7 +224,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.AuthResponse" + "type": "object" } }, "400": { @@ -261,7 +261,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/dto.CompanyResponse" + "type": "object" } } }, @@ -292,7 +292,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.CreateCompanyRequest" + "type": "object" } } ], @@ -300,7 +300,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.CompanyResponse" + "type": "object" } }, "400": { @@ -551,6 +551,120 @@ } } }, + "/api/v1/notifications": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Returns a list of notifications for the current user.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifications" + ], + "summary": "List Notifications", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Notification" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/notifications/read-all": { + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Marks all notifications as read.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifications" + ], + "summary": "Mark All Notifications Read", + "responses": { + "200": { + "description": "All marked as read", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/notifications/{id}/read": { + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Marks a notification as read.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Notifications" + ], + "summary": "Mark Notification Read", + "parameters": [ + { + "type": "string", + "description": "Notification ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Marked as read", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/storage/download-url": { "post": { "security": [ @@ -699,6 +813,199 @@ } } }, + "/api/v1/support/tickets": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Returns a list of tickets for the current user.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "List Tickets", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Ticket" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + }, + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Creates a new support ticket.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "Create Ticket", + "parameters": [ + { + "description": "Ticket Details", + "name": "ticket", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.Ticket" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/support/tickets/{id}": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Returns ticket details and chat history.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "Get Ticket Details", + "parameters": [ + { + "type": "string", + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/support/tickets/{id}/messages": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Adds a message to an existing ticket.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Support" + ], + "summary": "Add Ticket Message", + "parameters": [ + { + "type": "string", + "description": "Ticket ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Message", + "name": "message", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.TicketMessage" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/users": { "get": { "security": [ @@ -710,6 +1017,13 @@ "consumes": [ "application/json" ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "List Users", "parameters": [ { "type": "integer", @@ -724,18 +1038,11 @@ "in": "query" } ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "List Users", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.PaginatedResponse" + "type": "object" } }, "403": { @@ -776,7 +1083,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/dto.CreateUserRequest" + "type": "object" } } ], @@ -784,7 +1091,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dto.UserResponse" + "type": "object" } }, "400": { @@ -808,6 +1115,109 @@ } } }, + "/api/v1/users/me/avatar": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Uploads a profile picture for the current user.", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Upload Avatar", + "parameters": [ + { + "type": "file", + "description": "Avatar File", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/v1/users/me/profile": { + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Updates the current user's profile.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update My Profile", + "parameters": [ + { + "description": "Profile Details", + "name": "user", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/users/{id}": { "delete": { "security": [ @@ -855,38 +1265,66 @@ } } } + }, + "patch": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Updates user details (Name, Email, Active Status)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update User", + "parameters": [ + { + "type": "string", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "User Updates", + "name": "user", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object" + } + }, + "403": { + "description": "Forbidden", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } } } }, "definitions": { - "dto.AuthResponse": { - "type": "object", - "properties": { - "token": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/dto.UserResponse" - } - } - }, - "dto.CompanyResponse": { - "type": "object", - "properties": { - "created_at": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, "dto.CreateApplicationRequest": { "type": "object", "required": [ @@ -901,7 +1339,7 @@ "type": "string" }, "jobId": { - "type": "integer" + "type": "string" }, "lineId": { "type": "string" @@ -919,62 +1357,13 @@ "type": "string" }, "userId": { - "type": "integer" + "type": "string" }, "whatsapp": { "type": "string" } } }, - "dto.CreateCompanyRequest": { - "type": "object", - "required": [ - "name", - "slug" - ], - "properties": { - "address": { - "type": "string" - }, - "cityId": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "document": { - "type": "string" - }, - "email": { - "type": "string" - }, - "logoUrl": { - "type": "string" - }, - "name": { - "type": "string", - "maxLength": 255, - "minLength": 3 - }, - "phone": { - "type": "string" - }, - "regionId": { - "type": "integer" - }, - "slug": { - "type": "string", - "maxLength": 255, - "minLength": 3 - }, - "type": { - "type": "string" - }, - "website": { - "type": "string" - } - } - }, "dto.CreateJobRequest": { "type": "object", "required": [ @@ -991,7 +1380,17 @@ "type": "integer" }, "companyId": { - "type": "integer" + "type": "string" + }, + "currency": { + "type": "string", + "enum": [ + "BRL", + "USD", + "EUR", + "GBP", + "JPY" + ] }, "description": { "type": "string", @@ -1003,7 +1402,11 @@ "full-time", "part-time", "dispatch", - "contract" + "contract", + "temporary", + "training", + "voluntary", + "permanent" ] }, "languageLevel": { @@ -1029,6 +1432,8 @@ "type": "string", "enum": [ "hourly", + "daily", + "weekly", "monthly", "yearly" ] @@ -1038,7 +1443,13 @@ "enum": [ "draft", "open", - "closed" + "closed", + "review", + "published", + "paused", + "expired", + "archived", + "reported" ] }, "title": { @@ -1054,44 +1465,6 @@ } } }, - "dto.CreateUserRequest": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "name": { - "type": "string" - }, - "password": { - "type": "string" - }, - "roles": { - "description": "e.g. [\"RECRUITER\"]", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "dto.LoginRequest": { - "type": "object", - "required": [ - "identifier", - "password" - ], - "properties": { - "identifier": { - "type": "string", - "minLength": 3 - }, - "password": { - "type": "string", - "minLength": 8 - } - } - }, "dto.PaginatedResponse": { "type": "object", "properties": { @@ -1146,6 +1519,16 @@ "cityId": { "type": "integer" }, + "currency": { + "type": "string", + "enum": [ + "BRL", + "USD", + "EUR", + "GBP", + "JPY" + ] + }, "description": { "type": "string", "minLength": 20 @@ -1156,7 +1539,11 @@ "full-time", "part-time", "dispatch", - "contract" + "contract", + "temporary", + "training", + "voluntary", + "permanent" ] }, "languageLevel": { @@ -1182,6 +1569,8 @@ "type": "string", "enum": [ "hourly", + "daily", + "weekly", "monthly", "yearly" ] @@ -1191,7 +1580,13 @@ "enum": [ "draft", "open", - "closed" + "closed", + "review", + "published", + "paused", + "expired", + "archived", + "reported" ] }, "title": { @@ -1207,32 +1602,6 @@ } } }, - "dto.UserResponse": { - "type": "object", - "properties": { - "created_at": { - "type": "string" - }, - "email": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "roles": { - "type": "array", - "items": { - "type": "string" - } - }, - "status": { - "type": "string" - } - } - }, "handlers.DownloadURLRequest": { "type": "object", "properties": { @@ -1305,10 +1674,10 @@ "type": "string" }, "id": { - "type": "integer" + "type": "string" }, "jobId": { - "type": "integer" + "type": "string" }, "lineId": { "type": "string" @@ -1339,7 +1708,7 @@ }, "userId": { "description": "NULL for guest applications", - "type": "integer" + "type": "string" }, "whatsapp": { "type": "string" @@ -1360,14 +1729,18 @@ "type": "integer" }, "companyId": { - "type": "integer" + "type": "string" }, "createdAt": { "description": "Metadata", "type": "string" }, "createdBy": { - "type": "integer" + "type": "string" + }, + "currency": { + "description": "BRL, USD, EUR, GBP, JPY", + "type": "string" }, "description": { "type": "string" @@ -1377,7 +1750,7 @@ "type": "string" }, "id": { - "type": "integer" + "type": "string" }, "isFeatured": { "description": "Featured job flag", @@ -1410,7 +1783,7 @@ "type": "number" }, "salaryType": { - "description": "hourly, monthly, yearly", + "description": "hourly, daily, weekly, monthly, yearly", "type": "string" }, "status": { @@ -1428,10 +1801,95 @@ "description": "Visa \u0026 Language", "type": "boolean" }, + "workMode": { + "description": "onsite, hybrid, remote", + "type": "string" + }, "workingHours": { "type": "string" } } + }, + "models.Notification": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "link": { + "type": "string" + }, + "message": { + "type": "string" + }, + "readAt": { + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "description": "info, success, warning, error", + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } + }, + "models.Ticket": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "priority": { + "description": "low, medium, high", + "type": "string" + }, + "status": { + "description": "open, in_progress, closed", + "type": "string" + }, + "subject": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } + }, + "models.TicketMessage": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "type": "string" + }, + "message": { + "type": "string" + }, + "ticketId": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } } } -} +} \ No newline at end of file diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index b8e06a7..405a1aa 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -1,23 +1,5 @@ basePath: / definitions: - dto.AuthResponse: - properties: - token: - type: string - user: - $ref: '#/definitions/dto.UserResponse' - type: object - dto.CompanyResponse: - properties: - created_at: - type: string - id: - type: string - name: - type: string - status: - type: string - type: object dto.CreateApplicationRequest: properties: documents: @@ -26,7 +8,7 @@ definitions: email: type: string jobId: - type: integer + type: string lineId: type: string message: @@ -38,46 +20,12 @@ definitions: resumeUrl: type: string userId: - type: integer + type: string whatsapp: type: string required: - jobId type: object - dto.CreateCompanyRequest: - properties: - address: - type: string - cityId: - type: integer - description: - type: string - document: - type: string - email: - type: string - logoUrl: - type: string - name: - maxLength: 255 - minLength: 3 - type: string - phone: - type: string - regionId: - type: integer - slug: - maxLength: 255 - minLength: 3 - type: string - type: - type: string - website: - type: string - required: - - name - - slug - type: object dto.CreateJobRequest: properties: benefits: @@ -86,7 +34,15 @@ definitions: cityId: type: integer companyId: - type: integer + type: string + currency: + enum: + - BRL + - USD + - EUR + - GBP + - JPY + type: string description: minLength: 20 type: string @@ -96,6 +52,10 @@ definitions: - part-time - dispatch - contract + - temporary + - training + - voluntary + - permanent type: string languageLevel: type: string @@ -113,6 +73,8 @@ definitions: salaryType: enum: - hourly + - daily + - weekly - monthly - yearly type: string @@ -121,6 +83,12 @@ definitions: - draft - open - closed + - review + - published + - paused + - expired + - archived + - reported type: string title: maxLength: 255 @@ -135,32 +103,6 @@ definitions: - description - title type: object - dto.CreateUserRequest: - properties: - email: - type: string - name: - type: string - password: - type: string - roles: - description: e.g. ["RECRUITER"] - items: - type: string - type: array - type: object - dto.LoginRequest: - properties: - identifier: - minLength: 3 - type: string - password: - minLength: 8 - type: string - required: - - identifier - - password - type: object dto.PaginatedResponse: properties: data: {} @@ -198,6 +140,14 @@ definitions: type: object cityId: type: integer + currency: + enum: + - BRL + - USD + - EUR + - GBP + - JPY + type: string description: minLength: 20 type: string @@ -207,6 +157,10 @@ definitions: - part-time - dispatch - contract + - temporary + - training + - voluntary + - permanent type: string languageLevel: type: string @@ -224,6 +178,8 @@ definitions: salaryType: enum: - hourly + - daily + - weekly - monthly - yearly type: string @@ -232,6 +188,12 @@ definitions: - draft - open - closed + - review + - published + - paused + - expired + - archived + - reported type: string title: maxLength: 255 @@ -242,23 +204,6 @@ definitions: workingHours: type: string type: object - dto.UserResponse: - properties: - created_at: - type: string - email: - type: string - id: - type: string - name: - type: string - roles: - items: - type: string - type: array - status: - type: string - type: object handlers.DownloadURLRequest: properties: key: @@ -306,9 +251,9 @@ definitions: email: type: string id: - type: integer + type: string jobId: - type: integer + type: string lineId: type: string message: @@ -330,7 +275,7 @@ definitions: type: string userId: description: NULL for guest applications - type: integer + type: string whatsapp: type: string type: object @@ -344,19 +289,22 @@ definitions: cityId: type: integer companyId: - type: integer + type: string createdAt: description: Metadata type: string createdBy: - type: integer + type: string + currency: + description: BRL, USD, EUR, GBP, JPY + type: string description: type: string employmentType: description: Employment type: string id: - type: integer + type: string isFeatured: description: Featured job flag type: boolean @@ -378,7 +326,7 @@ definitions: description: Salary type: number salaryType: - description: hourly, monthly, yearly + description: hourly, daily, weekly, monthly, yearly type: string status: description: Status @@ -391,9 +339,66 @@ definitions: visaSupport: description: Visa & Language type: boolean + workMode: + description: onsite, hybrid, remote + type: string workingHours: type: string type: object + models.Notification: + properties: + createdAt: + type: string + id: + type: string + link: + type: string + message: + type: string + readAt: + type: string + title: + type: string + type: + description: info, success, warning, error + type: string + updatedAt: + type: string + userId: + type: integer + type: object + models.Ticket: + properties: + createdAt: + type: string + id: + type: string + priority: + description: low, medium, high + type: string + status: + description: open, in_progress, closed + type: string + subject: + type: string + updatedAt: + type: string + userId: + type: integer + type: object + models.TicketMessage: + properties: + createdAt: + type: string + id: + type: string + message: + type: string + ticketId: + type: string + userId: + type: integer + type: object info: contact: {} description: API for GoHorseJobs recruitment platform. @@ -536,14 +541,14 @@ paths: name: login required: true schema: - $ref: '#/definitions/dto.LoginRequest' + type: object produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/dto.AuthResponse' + type: object "400": description: Invalid Request schema: @@ -567,7 +572,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/dto.CompanyResponse' + type: object type: array "500": description: Internal Server Error @@ -586,14 +591,14 @@ paths: name: company required: true schema: - $ref: '#/definitions/dto.CreateCompanyRequest' + type: object produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/dto.CompanyResponse' + type: object "400": description: Invalid Request schema: @@ -759,6 +764,77 @@ paths: summary: Update a job tags: - Jobs + /api/v1/notifications: + get: + consumes: + - application/json + description: Returns a list of notifications for the current user. + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.Notification' + type: array + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: List Notifications + tags: + - Notifications + /api/v1/notifications/{id}/read: + patch: + consumes: + - application/json + description: Marks a notification as read. + parameters: + - description: Notification ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: Marked as read + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Mark Notification Read + tags: + - Notifications + /api/v1/notifications/read-all: + patch: + consumes: + - application/json + description: Marks all notifications as read. + produces: + - application/json + responses: + "200": + description: All marked as read + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Mark All Notifications Read + tags: + - Notifications /api/v1/storage/download-url: post: consumes: @@ -852,17 +928,139 @@ paths: summary: Generate upload URL tags: - Storage + /api/v1/support/tickets: + get: + consumes: + - application/json + description: Returns a list of tickets for the current user. + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.Ticket' + type: array + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: List Tickets + tags: + - Support + post: + consumes: + - application/json + description: Creates a new support ticket. + parameters: + - description: Ticket Details + in: body + name: ticket + required: true + schema: + type: object + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/models.Ticket' + "400": + description: Invalid Request + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Create Ticket + tags: + - Support + /api/v1/support/tickets/{id}: + get: + consumes: + - application/json + description: Returns ticket details and chat history. + parameters: + - description: Ticket ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: object + "404": + description: Not Found + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Get Ticket Details + tags: + - Support + /api/v1/support/tickets/{id}/messages: + post: + consumes: + - application/json + description: Adds a message to an existing ticket. + parameters: + - description: Ticket ID + in: path + name: id + required: true + type: string + - description: Message + in: body + name: message + required: true + schema: + type: object + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/models.TicketMessage' + "400": + description: Invalid Request + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Add Ticket Message + tags: + - Support /api/v1/users: get: consumes: - application/json description: Returns a list of users belonging to the authenticated tenant. parameters: - - description: Page number (default: 1) + - description: 'Page number (default: 1)' in: query name: page type: integer - - description: Items per page (default: 10, max: 100) + - description: 'Items per page (default: 10, max: 100)' in: query name: limit type: integer @@ -872,7 +1070,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/dto.PaginatedResponse' + type: object "403": description: Forbidden schema: @@ -896,14 +1094,14 @@ paths: name: user required: true schema: - $ref: '#/definitions/dto.CreateUserRequest' + type: object produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/dto.UserResponse' + type: object "400": description: Invalid Request schema: @@ -952,4 +1150,105 @@ paths: summary: Delete User tags: - Users + patch: + consumes: + - application/json + description: Updates user details (Name, Email, Active Status) + parameters: + - description: User ID + in: path + name: id + required: true + type: string + - description: User Updates + in: body + name: user + required: true + schema: + type: object + produces: + - application/json + responses: + "200": + description: OK + schema: + type: object + "403": + description: Forbidden + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Update User + tags: + - Users + /api/v1/users/me/avatar: + post: + consumes: + - multipart/form-data + description: Uploads a profile picture for the current user. + parameters: + - description: Avatar File + in: formData + name: file + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "400": + description: Invalid Request + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Upload Avatar + tags: + - Users + /api/v1/users/me/profile: + patch: + consumes: + - application/json + description: Updates the current user's profile. + parameters: + - description: Profile Details + in: body + name: user + required: true + schema: + type: object + produces: + - application/json + responses: + "200": + description: OK + schema: + type: object + "400": + description: Invalid Request + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + security: + - BearerAuth: [] + summary: Update My Profile + tags: + - Users swagger: "2.0" diff --git a/backend/internal/api/handlers/core_handlers.go b/backend/internal/api/handlers/core_handlers.go index edd8528..5d0a4fa 100644 --- a/backend/internal/api/handlers/core_handlers.go +++ b/backend/internal/api/handlers/core_handlers.go @@ -51,8 +51,8 @@ func NewCoreHandlers(l *auth.LoginUseCase, reg *auth.RegisterCandidateUseCase, c // @Tags Auth // @Accept json // @Produce json -// @Param login body dto.LoginRequest true "Login Credentials" -// @Success 200 {object} dto.AuthResponse +// @Param login body object true "Login Credentials" +// @Success 200 {object} object // @Failure 400 {string} string "Invalid Request" // @Failure 401 {string} string "Unauthorized" // @Router /api/v1/auth/login [post] @@ -121,8 +121,8 @@ func (h *CoreHandlers) RegisterCandidate(w http.ResponseWriter, r *http.Request) // @Tags Companies // @Accept json // @Produce json -// @Param company body dto.CreateCompanyRequest true "Company Details" -// @Success 200 {object} dto.CompanyResponse +// @Param company body object true "Company Details" +// @Success 200 {object} object // @Failure 400 {string} string "Invalid Request" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/companies [post] @@ -149,7 +149,7 @@ func (h *CoreHandlers) CreateCompany(w http.ResponseWriter, r *http.Request) { // @Tags Companies // @Accept json // @Produce json -// @Success 200 {array} dto.CompanyResponse +// @Success 200 {array} object // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/companies [get] func (h *CoreHandlers) ListCompanies(w http.ResponseWriter, r *http.Request) { @@ -170,8 +170,8 @@ func (h *CoreHandlers) ListCompanies(w http.ResponseWriter, r *http.Request) { // @Accept json // @Produce json // @Security BearerAuth -// @Param user body dto.CreateUserRequest true "User Details" -// @Success 200 {object} dto.UserResponse +// @Param user body object true "User Details" +// @Success 200 {object} object // @Failure 400 {string} string "Invalid Request" // @Failure 403 {string} string "Forbidden" // @Failure 500 {string} string "Internal Server Error" @@ -209,7 +209,7 @@ func (h *CoreHandlers) CreateUser(w http.ResponseWriter, r *http.Request) { // @Security BearerAuth // @Param page query int false "Page number (default: 1)" // @Param limit query int false "Items per page (default: 10, max: 100)" -// @Success 200 {object} dto.PaginatedResponse +// @Success 200 {object} object // @Failure 403 {string} string "Forbidden" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/users [get] @@ -280,8 +280,8 @@ func (h *CoreHandlers) DeleteUser(w http.ResponseWriter, r *http.Request) { // @Produce json // @Security BearerAuth // @Param id path string true "User ID" -// @Param user body dto.UpdateUserRequest true "User Updates" -// @Success 200 {object} dto.UserResponse +// @Param user body object true "User Updates" +// @Success 200 {object} object // @Failure 403 {string} string "Forbidden" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/users/{id} [patch] @@ -475,7 +475,7 @@ func (h *CoreHandlers) MarkAllNotificationsAsRead(w http.ResponseWriter, r *http // @Accept json // @Produce json // @Security BearerAuth -// @Param ticket body dto.CreateTicketRequest true "Ticket Details" +// @Param ticket body object true "Ticket Details" // @Success 201 {object} models.Ticket // @Failure 400 {string} string "Invalid Request" // @Failure 500 {string} string "Internal Server Error" @@ -558,7 +558,7 @@ func (h *CoreHandlers) ListTickets(w http.ResponseWriter, r *http.Request) { // @Produce json // @Security BearerAuth // @Param id path string true "Ticket ID" -// @Success 200 {object} dto.TicketDetailsResponse +// @Success 200 {object} object // @Failure 404 {string} string "Not Found" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/support/tickets/{id} [get] @@ -607,7 +607,7 @@ func (h *CoreHandlers) GetTicket(w http.ResponseWriter, r *http.Request) { // @Produce json // @Security BearerAuth // @Param id path string true "Ticket ID" -// @Param message body dto.MessageRequest true "Message" +// @Param message body object true "Message" // @Success 201 {object} models.TicketMessage // @Failure 400 {string} string "Invalid Request" // @Failure 500 {string} string "Internal Server Error" @@ -659,8 +659,8 @@ func (h *CoreHandlers) AddMessage(w http.ResponseWriter, r *http.Request) { // @Accept json // @Produce json // @Security BearerAuth -// @Param user body dto.UpdateUserRequest true "Profile Details" -// @Success 200 {object} dto.UserResponse +// @Param user body object true "Profile Details" +// @Success 200 {object} object // @Failure 400 {string} string "Invalid Request" // @Failure 500 {string} string "Internal Server Error" // @Router /api/v1/users/me/profile [patch]