diff --git a/backend/.env.example b/backend/.env.example index 45db2ce..f5204c4 100755 --- a/backend/.env.example +++ b/backend/.env.example @@ -2,6 +2,12 @@ # GoHorse Jobs Backend - Environment Variables # ============================================================================= +# ============================================================================= +# Seeding Configuration +# ============================================================================= +ADMIN_EMAIL=master@gohorsejobs.com +ADMIN_PASSWORD=teste1234 + # Database Configuration (use DATABASE_URL format) DATABASE_URL=postgresql://user:password@localhost:5432/gohorsejobs?sslmode=disable diff --git a/backend/docs/docs.go b/backend/docs/docs.go index 7f7749a..ee1ba8b 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go @@ -65,7 +65,7 @@ const docTemplate = `{ "summary": "List Applications", "parameters": [ { - "type": "integer", + "type": "string", "description": "Filter applications by job ID", "name": "jobId", "in": "query", @@ -78,7 +78,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } } }, @@ -115,7 +115,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.CreateApplicationRequest" + "$ref": "#/definitions/dto.CreateApplicationRequest" } } ], @@ -123,7 +123,7 @@ const docTemplate = `{ "201": { "description": "Created", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } }, "400": { @@ -141,6 +141,44 @@ const docTemplate = `{ } } }, + "/api/v1/applications/me": { + "get": { + "description": "List all applications for the logged-in user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Applications" + ], + "summary": "Get My Applications", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.ApplicationWithDetails" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/applications/{id}": { "get": { "description": "Retrieve a job application by its ID", @@ -156,7 +194,7 @@ const docTemplate = `{ "summary": "Get Application", "parameters": [ { - "type": "integer", + "type": "string", "description": "Application ID", "name": "id", "in": "path", @@ -167,7 +205,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } }, "400": { @@ -239,7 +277,7 @@ const docTemplate = `{ "summary": "Update Application Status", "parameters": [ { - "type": "integer", + "type": "string", "description": "Application ID", "name": "id", "in": "path", @@ -251,7 +289,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateApplicationStatusRequest" + "$ref": "#/definitions/dto.UpdateApplicationStatusRequest" } } ], @@ -259,7 +297,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } }, "400": { @@ -340,6 +378,52 @@ const docTemplate = `{ } } }, + "/api/v1/auth/register": { + "post": { + "description": "Register a new candidate account.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Register Candidate", + "parameters": [ + { + "description": "Registration Details", + "name": "register", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.RegisterCandidateRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/companies": { "get": { "description": "Returns a list of all companies.", @@ -522,7 +606,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateCompanyRequest" + "$ref": "#/definitions/dto.UpdateCompanyRequest" } } ], @@ -578,7 +662,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Conversation" + "$ref": "#/definitions/services.Conversation" } } } @@ -618,7 +702,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Message" + "$ref": "#/definitions/services.Message" } } } @@ -666,7 +750,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Message" + "$ref": "#/definitions/services.Message" } } } @@ -699,7 +783,7 @@ const docTemplate = `{ "in": "query" }, { - "type": "integer", + "type": "string", "description": "Filter by company ID", "name": "companyId", "in": "query" @@ -715,7 +799,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.PaginatedResponse" + "$ref": "#/definitions/dto.PaginatedResponse" } }, "500": { @@ -745,7 +829,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.CreateJobRequest" + "$ref": "#/definitions/dto.CreateJobRequest" } } ], @@ -753,7 +837,7 @@ const docTemplate = `{ "201": { "description": "Created", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job" + "$ref": "#/definitions/models.Job" } }, "400": { @@ -792,7 +876,7 @@ const docTemplate = `{ "summary": "Get job by ID", "parameters": [ { - "type": "integer", + "type": "string", "description": "Job ID", "name": "id", "in": "path", @@ -803,7 +887,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job" + "$ref": "#/definitions/models.Job" } }, "400": { @@ -834,7 +918,7 @@ const docTemplate = `{ "summary": "Update a job", "parameters": [ { - "type": "integer", + "type": "string", "description": "Job ID", "name": "id", "in": "path", @@ -846,7 +930,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateJobRequest" + "$ref": "#/definitions/dto.UpdateJobRequest" } } ], @@ -854,7 +938,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job" + "$ref": "#/definitions/models.Job" } }, "400": { @@ -885,7 +969,7 @@ const docTemplate = `{ "summary": "Delete a job", "parameters": [ { - "type": "integer", + "type": "string", "description": "Job ID", "name": "id", "in": "path", @@ -1050,7 +1134,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/internal_handlers.CreateCheckoutRequest" + "$ref": "#/definitions/handlers.CreateCheckoutRequest" } } ], @@ -1058,7 +1142,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/internal_handlers.CreateCheckoutResponse" + "$ref": "#/definitions/handlers.CreateCheckoutResponse" } }, "400": { @@ -1166,7 +1250,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/internal_handlers.DownloadURLRequest" + "$ref": "#/definitions/handlers.DownloadURLRequest" } } ], @@ -1174,7 +1258,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/internal_handlers.DownloadURLResponse" + "$ref": "#/definitions/handlers.DownloadURLResponse" } }, "400": { @@ -1263,7 +1347,7 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/internal_handlers.UploadURLRequest" + "$ref": "#/definitions/handlers.UploadURLRequest" } } ], @@ -1271,7 +1355,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/internal_handlers.UploadURLResponse" + "$ref": "#/definitions/handlers.UploadURLResponse" } }, "400": { @@ -2164,29 +2248,7 @@ const docTemplate = `{ } }, "definitions": { - "github_com_rede5_gohorsejobs_backend_internal_core_dto.LoginRequest": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "password": { - "type": "string" - } - } - }, - "github_com_rede5_gohorsejobs_backend_internal_core_dto.SaveFCMTokenRequest": { - "type": "object", - "properties": { - "platform": { - "type": "string" - }, - "token": { - "type": "string" - } - } - }, - "github_com_rede5_gohorsejobs_backend_internal_dto.CreateApplicationRequest": { + "dto.CreateApplicationRequest": { "type": "object", "required": [ "jobId" @@ -2225,7 +2287,7 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.CreateJobRequest": { + "dto.CreateJobRequest": { "type": "object", "required": [ "companyId", @@ -2334,16 +2396,16 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.PaginatedResponse": { + "dto.PaginatedResponse": { "type": "object", "properties": { "data": {}, "pagination": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.Pagination" + "$ref": "#/definitions/dto.Pagination" } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.Pagination": { + "dto.Pagination": { "type": "object", "properties": { "limit": { @@ -2357,7 +2419,54 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.UpdateApplicationStatusRequest": { + "dto.RegisterCandidateRequest": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "birthDate": { + "type": "string" + }, + "city": { + "type": "string" + }, + "education": { + "type": "string" + }, + "email": { + "type": "string" + }, + "experience": { + "type": "string" + }, + "name": { + "type": "string" + }, + "objective": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "skills": { + "type": "string" + }, + "state": { + "type": "string" + }, + "username": { + "type": "string" + }, + "zipCode": { + "type": "string" + } + } + }, + "dto.UpdateApplicationStatusRequest": { "type": "object", "required": [ "status" @@ -2378,7 +2487,7 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.UpdateCompanyRequest": { + "dto.UpdateCompanyRequest": { "type": "object", "properties": { "active": { @@ -2429,7 +2538,7 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.UpdateJobRequest": { + "dto.UpdateJobRequest": { "type": "object", "properties": { "benefits": { @@ -2530,7 +2639,113 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_models.Application": { + "github_com_rede5_gohorsejobs_backend_internal_core_dto.LoginRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "github_com_rede5_gohorsejobs_backend_internal_core_dto.SaveFCMTokenRequest": { + "type": "object", + "properties": { + "platform": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "handlers.CreateCheckoutRequest": { + "type": "object", + "properties": { + "cancelUrl": { + "description": "URL after cancel", + "type": "string" + }, + "jobId": { + "type": "integer" + }, + "priceId": { + "description": "Stripe Price ID", + "type": "string" + }, + "successUrl": { + "description": "URL after success", + "type": "string" + } + } + }, + "handlers.CreateCheckoutResponse": { + "type": "object", + "properties": { + "checkoutUrl": { + "type": "string" + }, + "sessionId": { + "type": "string" + } + } + }, + "handlers.DownloadURLRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, + "handlers.DownloadURLResponse": { + "type": "object", + "properties": { + "downloadUrl": { + "type": "string" + }, + "expiresIn": { + "description": "seconds", + "type": "integer" + } + } + }, + "handlers.UploadURLRequest": { + "type": "object", + "properties": { + "contentType": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "folder": { + "description": "Optional: logos, resumes, documents", + "type": "string" + } + } + }, + "handlers.UploadURLResponse": { + "type": "object", + "properties": { + "expiresIn": { + "description": "seconds", + "type": "integer" + }, + "key": { + "type": "string" + }, + "publicUrl": { + "type": "string" + }, + "uploadUrl": { + "type": "string" + } + } + }, + "models.Application": { "type": "object", "properties": { "createdAt": { @@ -2541,7 +2756,7 @@ const docTemplate = `{ "description": "Array of {type, url}", "allOf": [ { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap" + "$ref": "#/definitions/models.JSONMap" } ] }, @@ -2590,15 +2805,91 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_models.JSONMap": { + "models.ApplicationWithDetails": { + "type": "object", + "properties": { + "applicantName": { + "description": "From user or guest name", + "type": "string" + }, + "applicantPhone": { + "type": "string" + }, + "companyId": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "createdAt": { + "description": "Metadata", + "type": "string" + }, + "documents": { + "description": "Array of {type, url}", + "allOf": [ + { + "$ref": "#/definitions/models.JSONMap" + } + ] + }, + "email": { + "type": "string" + }, + "id": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "jobTitle": { + "type": "string" + }, + "lineId": { + "type": "string" + }, + "message": { + "description": "Application Content", + "type": "string" + }, + "name": { + "description": "Applicant Info (for guest applications)", + "type": "string" + }, + "notes": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "resumeUrl": { + "type": "string" + }, + "status": { + "description": "Status \u0026 Notes", + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "userId": { + "description": "NULL for guest applications", + "type": "string" + }, + "whatsapp": { + "type": "string" + } + } + }, + "models.JSONMap": { "type": "object", "additionalProperties": true }, - "github_com_rede5_gohorsejobs_backend_internal_models.Job": { + "models.Job": { "type": "object", "properties": { "benefits": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap" + "$ref": "#/definitions/models.JSONMap" }, "cityId": { "type": "integer" @@ -2646,7 +2937,7 @@ const docTemplate = `{ "description": "Requirements \u0026 Benefits (JSONB arrays)", "allOf": [ { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap" + "$ref": "#/definitions/models.JSONMap" } ] }, @@ -2689,7 +2980,7 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_services.Conversation": { + "services.Conversation": { "type": "object", "properties": { "candidateId": { @@ -2721,7 +3012,7 @@ const docTemplate = `{ } } }, - "github_com_rede5_gohorsejobs_backend_internal_services.Message": { + "services.Message": { "type": "object", "properties": { "content": { @@ -2744,90 +3035,6 @@ const docTemplate = `{ "type": "string" } } - }, - "internal_handlers.CreateCheckoutRequest": { - "type": "object", - "properties": { - "cancelUrl": { - "description": "URL after cancel", - "type": "string" - }, - "jobId": { - "type": "integer" - }, - "priceId": { - "description": "Stripe Price ID", - "type": "string" - }, - "successUrl": { - "description": "URL after success", - "type": "string" - } - } - }, - "internal_handlers.CreateCheckoutResponse": { - "type": "object", - "properties": { - "checkoutUrl": { - "type": "string" - }, - "sessionId": { - "type": "string" - } - } - }, - "internal_handlers.DownloadURLRequest": { - "type": "object", - "properties": { - "key": { - "type": "string" - } - } - }, - "internal_handlers.DownloadURLResponse": { - "type": "object", - "properties": { - "downloadUrl": { - "type": "string" - }, - "expiresIn": { - "description": "seconds", - "type": "integer" - } - } - }, - "internal_handlers.UploadURLRequest": { - "type": "object", - "properties": { - "contentType": { - "type": "string" - }, - "filename": { - "type": "string" - }, - "folder": { - "description": "Optional: logos, resumes, documents", - "type": "string" - } - } - }, - "internal_handlers.UploadURLResponse": { - "type": "object", - "properties": { - "expiresIn": { - "description": "seconds", - "type": "integer" - }, - "key": { - "type": "string" - }, - "publicUrl": { - "type": "string" - }, - "uploadUrl": { - "type": "string" - } - } } }, "securityDefinitions": { diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 03cfa0d..7315c45 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json @@ -58,7 +58,7 @@ "summary": "List Applications", "parameters": [ { - "type": "integer", + "type": "string", "description": "Filter applications by job ID", "name": "jobId", "in": "query", @@ -71,7 +71,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } } }, @@ -108,7 +108,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.CreateApplicationRequest" + "$ref": "#/definitions/dto.CreateApplicationRequest" } } ], @@ -116,7 +116,7 @@ "201": { "description": "Created", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } }, "400": { @@ -134,6 +134,44 @@ } } }, + "/api/v1/applications/me": { + "get": { + "description": "List all applications for the logged-in user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Applications" + ], + "summary": "Get My Applications", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.ApplicationWithDetails" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "string" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/applications/{id}": { "get": { "description": "Retrieve a job application by its ID", @@ -149,7 +187,7 @@ "summary": "Get Application", "parameters": [ { - "type": "integer", + "type": "string", "description": "Application ID", "name": "id", "in": "path", @@ -160,7 +198,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } }, "400": { @@ -232,7 +270,7 @@ "summary": "Update Application Status", "parameters": [ { - "type": "integer", + "type": "string", "description": "Application ID", "name": "id", "in": "path", @@ -244,7 +282,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateApplicationStatusRequest" + "$ref": "#/definitions/dto.UpdateApplicationStatusRequest" } } ], @@ -252,7 +290,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application" + "$ref": "#/definitions/models.Application" } }, "400": { @@ -333,6 +371,52 @@ } } }, + "/api/v1/auth/register": { + "post": { + "description": "Register a new candidate account.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "summary": "Register Candidate", + "parameters": [ + { + "description": "Registration Details", + "name": "register", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/dto.RegisterCandidateRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object" + } + }, + "400": { + "description": "Invalid Request", + "schema": { + "type": "string" + } + }, + "409": { + "description": "Conflict", + "schema": { + "type": "string" + } + } + } + } + }, "/api/v1/companies": { "get": { "description": "Returns a list of all companies.", @@ -515,7 +599,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateCompanyRequest" + "$ref": "#/definitions/dto.UpdateCompanyRequest" } } ], @@ -571,7 +655,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Conversation" + "$ref": "#/definitions/services.Conversation" } } } @@ -611,7 +695,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Message" + "$ref": "#/definitions/services.Message" } } } @@ -659,7 +743,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Message" + "$ref": "#/definitions/services.Message" } } } @@ -692,7 +776,7 @@ "in": "query" }, { - "type": "integer", + "type": "string", "description": "Filter by company ID", "name": "companyId", "in": "query" @@ -708,7 +792,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.PaginatedResponse" + "$ref": "#/definitions/dto.PaginatedResponse" } }, "500": { @@ -738,7 +822,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.CreateJobRequest" + "$ref": "#/definitions/dto.CreateJobRequest" } } ], @@ -746,7 +830,7 @@ "201": { "description": "Created", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job" + "$ref": "#/definitions/models.Job" } }, "400": { @@ -785,7 +869,7 @@ "summary": "Get job by ID", "parameters": [ { - "type": "integer", + "type": "string", "description": "Job ID", "name": "id", "in": "path", @@ -796,7 +880,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job" + "$ref": "#/definitions/models.Job" } }, "400": { @@ -827,7 +911,7 @@ "summary": "Update a job", "parameters": [ { - "type": "integer", + "type": "string", "description": "Job ID", "name": "id", "in": "path", @@ -839,7 +923,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateJobRequest" + "$ref": "#/definitions/dto.UpdateJobRequest" } } ], @@ -847,7 +931,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job" + "$ref": "#/definitions/models.Job" } }, "400": { @@ -878,7 +962,7 @@ "summary": "Delete a job", "parameters": [ { - "type": "integer", + "type": "string", "description": "Job ID", "name": "id", "in": "path", @@ -1043,7 +1127,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/internal_handlers.CreateCheckoutRequest" + "$ref": "#/definitions/handlers.CreateCheckoutRequest" } } ], @@ -1051,7 +1135,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/internal_handlers.CreateCheckoutResponse" + "$ref": "#/definitions/handlers.CreateCheckoutResponse" } }, "400": { @@ -1159,7 +1243,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/internal_handlers.DownloadURLRequest" + "$ref": "#/definitions/handlers.DownloadURLRequest" } } ], @@ -1167,7 +1251,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/internal_handlers.DownloadURLResponse" + "$ref": "#/definitions/handlers.DownloadURLResponse" } }, "400": { @@ -1256,7 +1340,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/internal_handlers.UploadURLRequest" + "$ref": "#/definitions/handlers.UploadURLRequest" } } ], @@ -1264,7 +1348,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/internal_handlers.UploadURLResponse" + "$ref": "#/definitions/handlers.UploadURLResponse" } }, "400": { @@ -2157,29 +2241,7 @@ } }, "definitions": { - "github_com_rede5_gohorsejobs_backend_internal_core_dto.LoginRequest": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "password": { - "type": "string" - } - } - }, - "github_com_rede5_gohorsejobs_backend_internal_core_dto.SaveFCMTokenRequest": { - "type": "object", - "properties": { - "platform": { - "type": "string" - }, - "token": { - "type": "string" - } - } - }, - "github_com_rede5_gohorsejobs_backend_internal_dto.CreateApplicationRequest": { + "dto.CreateApplicationRequest": { "type": "object", "required": [ "jobId" @@ -2218,7 +2280,7 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.CreateJobRequest": { + "dto.CreateJobRequest": { "type": "object", "required": [ "companyId", @@ -2327,16 +2389,16 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.PaginatedResponse": { + "dto.PaginatedResponse": { "type": "object", "properties": { "data": {}, "pagination": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.Pagination" + "$ref": "#/definitions/dto.Pagination" } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.Pagination": { + "dto.Pagination": { "type": "object", "properties": { "limit": { @@ -2350,7 +2412,54 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.UpdateApplicationStatusRequest": { + "dto.RegisterCandidateRequest": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "birthDate": { + "type": "string" + }, + "city": { + "type": "string" + }, + "education": { + "type": "string" + }, + "email": { + "type": "string" + }, + "experience": { + "type": "string" + }, + "name": { + "type": "string" + }, + "objective": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "skills": { + "type": "string" + }, + "state": { + "type": "string" + }, + "username": { + "type": "string" + }, + "zipCode": { + "type": "string" + } + } + }, + "dto.UpdateApplicationStatusRequest": { "type": "object", "required": [ "status" @@ -2371,7 +2480,7 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.UpdateCompanyRequest": { + "dto.UpdateCompanyRequest": { "type": "object", "properties": { "active": { @@ -2422,7 +2531,7 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_dto.UpdateJobRequest": { + "dto.UpdateJobRequest": { "type": "object", "properties": { "benefits": { @@ -2523,7 +2632,113 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_models.Application": { + "github_com_rede5_gohorsejobs_backend_internal_core_dto.LoginRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "github_com_rede5_gohorsejobs_backend_internal_core_dto.SaveFCMTokenRequest": { + "type": "object", + "properties": { + "platform": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "handlers.CreateCheckoutRequest": { + "type": "object", + "properties": { + "cancelUrl": { + "description": "URL after cancel", + "type": "string" + }, + "jobId": { + "type": "integer" + }, + "priceId": { + "description": "Stripe Price ID", + "type": "string" + }, + "successUrl": { + "description": "URL after success", + "type": "string" + } + } + }, + "handlers.CreateCheckoutResponse": { + "type": "object", + "properties": { + "checkoutUrl": { + "type": "string" + }, + "sessionId": { + "type": "string" + } + } + }, + "handlers.DownloadURLRequest": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, + "handlers.DownloadURLResponse": { + "type": "object", + "properties": { + "downloadUrl": { + "type": "string" + }, + "expiresIn": { + "description": "seconds", + "type": "integer" + } + } + }, + "handlers.UploadURLRequest": { + "type": "object", + "properties": { + "contentType": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "folder": { + "description": "Optional: logos, resumes, documents", + "type": "string" + } + } + }, + "handlers.UploadURLResponse": { + "type": "object", + "properties": { + "expiresIn": { + "description": "seconds", + "type": "integer" + }, + "key": { + "type": "string" + }, + "publicUrl": { + "type": "string" + }, + "uploadUrl": { + "type": "string" + } + } + }, + "models.Application": { "type": "object", "properties": { "createdAt": { @@ -2534,7 +2749,7 @@ "description": "Array of {type, url}", "allOf": [ { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap" + "$ref": "#/definitions/models.JSONMap" } ] }, @@ -2583,15 +2798,91 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_models.JSONMap": { + "models.ApplicationWithDetails": { + "type": "object", + "properties": { + "applicantName": { + "description": "From user or guest name", + "type": "string" + }, + "applicantPhone": { + "type": "string" + }, + "companyId": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "createdAt": { + "description": "Metadata", + "type": "string" + }, + "documents": { + "description": "Array of {type, url}", + "allOf": [ + { + "$ref": "#/definitions/models.JSONMap" + } + ] + }, + "email": { + "type": "string" + }, + "id": { + "type": "string" + }, + "jobId": { + "type": "string" + }, + "jobTitle": { + "type": "string" + }, + "lineId": { + "type": "string" + }, + "message": { + "description": "Application Content", + "type": "string" + }, + "name": { + "description": "Applicant Info (for guest applications)", + "type": "string" + }, + "notes": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "resumeUrl": { + "type": "string" + }, + "status": { + "description": "Status \u0026 Notes", + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "userId": { + "description": "NULL for guest applications", + "type": "string" + }, + "whatsapp": { + "type": "string" + } + } + }, + "models.JSONMap": { "type": "object", "additionalProperties": true }, - "github_com_rede5_gohorsejobs_backend_internal_models.Job": { + "models.Job": { "type": "object", "properties": { "benefits": { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap" + "$ref": "#/definitions/models.JSONMap" }, "cityId": { "type": "integer" @@ -2639,7 +2930,7 @@ "description": "Requirements \u0026 Benefits (JSONB arrays)", "allOf": [ { - "$ref": "#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap" + "$ref": "#/definitions/models.JSONMap" } ] }, @@ -2682,7 +2973,7 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_services.Conversation": { + "services.Conversation": { "type": "object", "properties": { "candidateId": { @@ -2714,7 +3005,7 @@ } } }, - "github_com_rede5_gohorsejobs_backend_internal_services.Message": { + "services.Message": { "type": "object", "properties": { "content": { @@ -2737,90 +3028,6 @@ "type": "string" } } - }, - "internal_handlers.CreateCheckoutRequest": { - "type": "object", - "properties": { - "cancelUrl": { - "description": "URL after cancel", - "type": "string" - }, - "jobId": { - "type": "integer" - }, - "priceId": { - "description": "Stripe Price ID", - "type": "string" - }, - "successUrl": { - "description": "URL after success", - "type": "string" - } - } - }, - "internal_handlers.CreateCheckoutResponse": { - "type": "object", - "properties": { - "checkoutUrl": { - "type": "string" - }, - "sessionId": { - "type": "string" - } - } - }, - "internal_handlers.DownloadURLRequest": { - "type": "object", - "properties": { - "key": { - "type": "string" - } - } - }, - "internal_handlers.DownloadURLResponse": { - "type": "object", - "properties": { - "downloadUrl": { - "type": "string" - }, - "expiresIn": { - "description": "seconds", - "type": "integer" - } - } - }, - "internal_handlers.UploadURLRequest": { - "type": "object", - "properties": { - "contentType": { - "type": "string" - }, - "filename": { - "type": "string" - }, - "folder": { - "description": "Optional: logos, resumes, documents", - "type": "string" - } - } - }, - "internal_handlers.UploadURLResponse": { - "type": "object", - "properties": { - "expiresIn": { - "description": "seconds", - "type": "integer" - }, - "key": { - "type": "string" - }, - "publicUrl": { - "type": "string" - }, - "uploadUrl": { - "type": "string" - } - } } }, "securityDefinitions": { diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index b210c25..1b85fb8 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml @@ -1,20 +1,6 @@ basePath: / definitions: - github_com_rede5_gohorsejobs_backend_internal_core_dto.LoginRequest: - properties: - email: - type: string - password: - type: string - type: object - github_com_rede5_gohorsejobs_backend_internal_core_dto.SaveFCMTokenRequest: - properties: - platform: - type: string - token: - type: string - type: object - github_com_rede5_gohorsejobs_backend_internal_dto.CreateApplicationRequest: + dto.CreateApplicationRequest: properties: documents: additionalProperties: true @@ -40,7 +26,7 @@ definitions: required: - jobId type: object - github_com_rede5_gohorsejobs_backend_internal_dto.CreateJobRequest: + dto.CreateJobRequest: properties: benefits: additionalProperties: true @@ -124,13 +110,13 @@ definitions: - description - title type: object - github_com_rede5_gohorsejobs_backend_internal_dto.PaginatedResponse: + dto.PaginatedResponse: properties: data: {} pagination: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.Pagination' + $ref: '#/definitions/dto.Pagination' type: object - github_com_rede5_gohorsejobs_backend_internal_dto.Pagination: + dto.Pagination: properties: limit: type: integer @@ -139,7 +125,38 @@ definitions: total: type: integer type: object - github_com_rede5_gohorsejobs_backend_internal_dto.UpdateApplicationStatusRequest: + dto.RegisterCandidateRequest: + properties: + address: + type: string + birthDate: + type: string + city: + type: string + education: + type: string + email: + type: string + experience: + type: string + name: + type: string + objective: + type: string + password: + type: string + phone: + type: string + skills: + type: string + state: + type: string + username: + type: string + zipCode: + type: string + type: object + dto.UpdateApplicationStatusRequest: properties: notes: type: string @@ -154,7 +171,7 @@ definitions: required: - status type: object - github_com_rede5_gohorsejobs_backend_internal_dto.UpdateCompanyRequest: + dto.UpdateCompanyRequest: properties: active: type: boolean @@ -189,7 +206,7 @@ definitions: website: type: string type: object - github_com_rede5_gohorsejobs_backend_internal_dto.UpdateJobRequest: + dto.UpdateJobRequest: properties: benefits: additionalProperties: true @@ -267,14 +284,84 @@ definitions: workingHours: type: string type: object - github_com_rede5_gohorsejobs_backend_internal_models.Application: + github_com_rede5_gohorsejobs_backend_internal_core_dto.LoginRequest: + properties: + email: + type: string + password: + type: string + type: object + github_com_rede5_gohorsejobs_backend_internal_core_dto.SaveFCMTokenRequest: + properties: + platform: + type: string + token: + type: string + type: object + handlers.CreateCheckoutRequest: + properties: + cancelUrl: + description: URL after cancel + type: string + jobId: + type: integer + priceId: + description: Stripe Price ID + type: string + successUrl: + description: URL after success + type: string + type: object + handlers.CreateCheckoutResponse: + properties: + checkoutUrl: + type: string + sessionId: + type: string + type: object + handlers.DownloadURLRequest: + properties: + key: + type: string + type: object + handlers.DownloadURLResponse: + properties: + downloadUrl: + type: string + expiresIn: + description: seconds + type: integer + type: object + handlers.UploadURLRequest: + properties: + contentType: + type: string + filename: + type: string + folder: + description: 'Optional: logos, resumes, documents' + type: string + type: object + handlers.UploadURLResponse: + properties: + expiresIn: + description: seconds + type: integer + key: + type: string + publicUrl: + type: string + uploadUrl: + type: string + type: object + models.Application: properties: createdAt: description: Metadata type: string documents: allOf: - - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap' + - $ref: '#/definitions/models.JSONMap' description: Array of {type, url} email: type: string @@ -307,13 +394,64 @@ definitions: whatsapp: type: string type: object - github_com_rede5_gohorsejobs_backend_internal_models.JSONMap: + models.ApplicationWithDetails: + properties: + applicantName: + description: From user or guest name + type: string + applicantPhone: + type: string + companyId: + type: string + companyName: + type: string + createdAt: + description: Metadata + type: string + documents: + allOf: + - $ref: '#/definitions/models.JSONMap' + description: Array of {type, url} + email: + type: string + id: + type: string + jobId: + type: string + jobTitle: + type: string + lineId: + type: string + message: + description: Application Content + type: string + name: + description: Applicant Info (for guest applications) + type: string + notes: + type: string + phone: + type: string + resumeUrl: + type: string + status: + description: Status & Notes + type: string + updatedAt: + type: string + userId: + description: NULL for guest applications + type: string + whatsapp: + type: string + type: object + models.JSONMap: additionalProperties: true type: object - github_com_rede5_gohorsejobs_backend_internal_models.Job: + models.Job: properties: benefits: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap' + $ref: '#/definitions/models.JSONMap' cityId: type: integer companyId: @@ -346,7 +484,7 @@ definitions: type: integer requirements: allOf: - - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.JSONMap' + - $ref: '#/definitions/models.JSONMap' description: Requirements & Benefits (JSONB arrays) salaryMax: type: number @@ -376,7 +514,7 @@ definitions: workingHours: type: string type: object - github_com_rede5_gohorsejobs_backend_internal_services.Conversation: + services.Conversation: properties: candidateId: type: string @@ -397,7 +535,7 @@ definitions: unreadCount: type: integer type: object - github_com_rede5_gohorsejobs_backend_internal_services.Message: + services.Message: properties: content: type: string @@ -413,62 +551,6 @@ definitions: senderId: type: string type: object - internal_handlers.CreateCheckoutRequest: - properties: - cancelUrl: - description: URL after cancel - type: string - jobId: - type: integer - priceId: - description: Stripe Price ID - type: string - successUrl: - description: URL after success - type: string - type: object - internal_handlers.CreateCheckoutResponse: - properties: - checkoutUrl: - type: string - sessionId: - type: string - type: object - internal_handlers.DownloadURLRequest: - properties: - key: - type: string - type: object - internal_handlers.DownloadURLResponse: - properties: - downloadUrl: - type: string - expiresIn: - description: seconds - type: integer - type: object - internal_handlers.UploadURLRequest: - properties: - contentType: - type: string - filename: - type: string - folder: - description: 'Optional: logos, resumes, documents' - type: string - type: object - internal_handlers.UploadURLResponse: - properties: - expiresIn: - description: seconds - type: integer - key: - type: string - publicUrl: - type: string - uploadUrl: - type: string - type: object info: contact: {} description: API for GoHorseJobs recruitment platform. @@ -509,7 +591,7 @@ paths: in: query name: jobId required: true - type: integer + type: string produces: - application/json responses: @@ -517,7 +599,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application' + $ref: '#/definitions/models.Application' type: array "400": description: Bad Request @@ -540,14 +622,14 @@ paths: name: application required: true schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.CreateApplicationRequest' + $ref: '#/definitions/dto.CreateApplicationRequest' produces: - application/json responses: "201": description: Created schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application' + $ref: '#/definitions/models.Application' "400": description: Bad Request schema: @@ -595,14 +677,14 @@ paths: in: path name: id required: true - type: integer + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application' + $ref: '#/definitions/models.Application' "400": description: Bad Request schema: @@ -624,20 +706,20 @@ paths: in: path name: id required: true - type: integer + type: string - description: Status update in: body name: body required: true schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateApplicationStatusRequest' + $ref: '#/definitions/dto.UpdateApplicationStatusRequest' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Application' + $ref: '#/definitions/models.Application' "400": description: Bad Request schema: @@ -649,6 +731,31 @@ paths: summary: Update Application Status tags: - Applications + /api/v1/applications/me: + get: + consumes: + - application/json + description: List all applications for the logged-in user + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.ApplicationWithDetails' + type: array + "401": + description: Unauthorized + schema: + type: string + "500": + description: Internal Server Error + schema: + type: string + summary: Get My Applications + tags: + - Applications /api/v1/auth/login: post: consumes: @@ -691,6 +798,36 @@ paths: summary: User Logout tags: - Auth + /api/v1/auth/register: + post: + consumes: + - application/json + description: Register a new candidate account. + parameters: + - description: Registration Details + in: body + name: register + required: true + schema: + $ref: '#/definitions/dto.RegisterCandidateRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + type: object + "400": + description: Invalid Request + schema: + type: string + "409": + description: Conflict + schema: + type: string + summary: Register Candidate + tags: + - Auth /api/v1/companies: get: consumes: @@ -805,7 +942,7 @@ paths: name: body required: true schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateCompanyRequest' + $ref: '#/definitions/dto.UpdateCompanyRequest' produces: - application/json responses: @@ -842,7 +979,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Conversation' + $ref: '#/definitions/services.Conversation' type: array security: - BearerAuth: [] @@ -867,7 +1004,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Message' + $ref: '#/definitions/services.Message' type: array security: - BearerAuth: [] @@ -898,7 +1035,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_services.Message' + $ref: '#/definitions/services.Message' security: - BearerAuth: [] summary: Send Message @@ -921,7 +1058,7 @@ paths: - description: Filter by company ID in: query name: companyId - type: integer + type: string - description: Filter by featured status in: query name: featured @@ -932,7 +1069,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.PaginatedResponse' + $ref: '#/definitions/dto.PaginatedResponse' "500": description: Internal Server Error schema: @@ -950,14 +1087,14 @@ paths: name: job required: true schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.CreateJobRequest' + $ref: '#/definitions/dto.CreateJobRequest' produces: - application/json responses: "201": description: Created schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job' + $ref: '#/definitions/models.Job' "400": description: Bad Request schema: @@ -983,7 +1120,7 @@ paths: in: path name: id required: true - type: integer + type: string produces: - application/json responses: @@ -1009,14 +1146,14 @@ paths: in: path name: id required: true - type: integer + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job' + $ref: '#/definitions/models.Job' "400": description: Bad Request schema: @@ -1037,20 +1174,20 @@ paths: in: path name: id required: true - type: integer + type: string - description: Updated job data in: body name: job required: true schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_dto.UpdateJobRequest' + $ref: '#/definitions/dto.UpdateJobRequest' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/github_com_rede5_gohorsejobs_backend_internal_models.Job' + $ref: '#/definitions/models.Job' "400": description: Bad Request schema: @@ -1144,14 +1281,14 @@ paths: name: request required: true schema: - $ref: '#/definitions/internal_handlers.CreateCheckoutRequest' + $ref: '#/definitions/handlers.CreateCheckoutRequest' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/internal_handlers.CreateCheckoutResponse' + $ref: '#/definitions/handlers.CreateCheckoutResponse' "400": description: Bad Request schema: @@ -1219,14 +1356,14 @@ paths: name: request required: true schema: - $ref: '#/definitions/internal_handlers.DownloadURLRequest' + $ref: '#/definitions/handlers.DownloadURLRequest' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/internal_handlers.DownloadURLResponse' + $ref: '#/definitions/handlers.DownloadURLResponse' "400": description: Bad Request schema: @@ -1280,14 +1417,14 @@ paths: name: request required: true schema: - $ref: '#/definitions/internal_handlers.UploadURLRequest' + $ref: '#/definitions/handlers.UploadURLRequest' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/internal_handlers.UploadURLResponse' + $ref: '#/definitions/handlers.UploadURLResponse' "400": description: Bad Request schema: diff --git a/backend/internal/api/handlers/core_handlers.go b/backend/internal/api/handlers/core_handlers.go index c29630c..2fd4a92 100644 --- a/backend/internal/api/handlers/core_handlers.go +++ b/backend/internal/api/handlers/core_handlers.go @@ -134,6 +134,16 @@ func (h *CoreHandlers) Logout(w http.ResponseWriter, r *http.Request) { } // RegisterCandidate handles public registration for candidates +// @Summary Register Candidate +// @Description Register a new candidate account. +// @Tags Auth +// @Accept json +// @Produce json +// @Param register body dto.RegisterCandidateRequest true "Registration Details" +// @Success 201 {object} object +// @Failure 400 {string} string "Invalid Request" +// @Failure 409 {string} string "Conflict" +// @Router /api/v1/auth/register [post] func (h *CoreHandlers) RegisterCandidate(w http.ResponseWriter, r *http.Request) { var req dto.RegisterCandidateRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { diff --git a/backend/internal/services/seeder_service.go b/backend/internal/services/seeder_service.go index c72d70a..4f3c202 100644 --- a/backend/internal/services/seeder_service.go +++ b/backend/internal/services/seeder_service.go @@ -5,6 +5,7 @@ import ( "database/sql" "fmt" "math/rand" + "os" "strings" "time" @@ -61,6 +62,39 @@ func (s *SeederService) Reset(ctx context.Context) error { func (s *SeederService) Seed(ctx context.Context, logChan chan string) error { s.SendEvent(logChan, "🚀 Starting Database Seed...") + // 0. Auto-Create Superadmin from Env + adminEmail := os.Getenv("ADMIN_EMAIL") + adminPass := os.Getenv("ADMIN_PASSWORD") + + if adminEmail != "" && adminPass != "" { + s.SendEvent(logChan, fmt.Sprintf("🛡️ Found ADMIN_EMAIL env. Creating Superadmin: %s", adminEmail)) + + // Hash password + hash, err := bcrypt.GenerateFromPassword([]byte(adminPass), bcrypt.DefaultCost) + if err == nil { + tx, err := s.DB.BeginTx(ctx, nil) + if err == nil { + adminID := uuid.New().String() + _, execErr := tx.ExecContext(ctx, ` + INSERT INTO users (id, identifier, full_name, password_hash, role, created_at, updated_at) + VALUES ($1, $2, 'System Master', $3, 'superadmin', NOW(), NOW()) + ON CONFLICT (identifier) DO UPDATE + SET password_hash = EXCLUDED.password_hash, + role = 'superadmin', + updated_at = NOW() + `, adminID, adminEmail, string(hash)) + + if execErr == nil { + tx.Commit() + s.SendEvent(logChan, "✅ Superadmin created/verified successfully.") + } else { + tx.Rollback() + s.SendEvent(logChan, fmt.Sprintf("❌ Failed to create Superadmin: %v", execErr)) + } + } + } + } + // Create Random Source rnd := rand.New(rand.NewSource(time.Now().UnixNano()))