From f51a8dd99c62eebaa51bbc059e8e8c9a29304c53 Mon Sep 17 00:00:00 2001 From: Tiago Yamamoto Date: Fri, 26 Dec 2025 01:35:34 -0300 Subject: [PATCH] fix: resolved user profile 500 error, fixed frontend build types, enhanced logging, increases test coverage --- backend/README.md | 1 + .../internal/api/handlers/core_handlers.go | 3 ++ backend/internal/services/admin_service.go | 2 +- .../internal/services/admin_service_test.go | 2 +- .../services/application_service_test.go | 31 +++++++++++++++++++ frontend/src/lib/auth.ts | 12 ++++--- frontend/src/lib/types.ts | 2 +- 7 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 backend/internal/services/application_service_test.go diff --git a/backend/README.md b/backend/README.md index 598ee92..69e887d 100755 --- a/backend/README.md +++ b/backend/README.md @@ -80,6 +80,7 @@ O endpoint `/jobs` suporta filtros avançados via query params: | `DELETE` | `/api/v1/users/{id}` | `superadmin` | Deletar usuário | | `POST` | `/jobs` | `admin`, `recruiter` | Criar vaga | | `GET` | `/api/v1/users/me` | `any` (authed) | Perfil do usuário | +| `DELETE` | `/api/v1/applications/{id}` | `admin`, `recruiter` | Deletar candidatura | --- diff --git a/backend/internal/api/handlers/core_handlers.go b/backend/internal/api/handlers/core_handlers.go index 055a44f..a2e9833 100644 --- a/backend/internal/api/handlers/core_handlers.go +++ b/backend/internal/api/handlers/core_handlers.go @@ -2,6 +2,7 @@ package handlers import ( "encoding/json" + "log" "net" "net/http" "strconv" @@ -836,9 +837,11 @@ func (h *CoreHandlers) Me(w http.ResponseWriter, r *http.Request) { user, err := h.adminService.GetUser(ctx, userID) if err != nil { + log.Printf("ERROR [Me Handler] GetUser failed for userID %s: %v", userID, err) http.Error(w, err.Error(), http.StatusInternalServerError) return } + log.Printf("SUCCESS [Me Handler] User retrieved: %s", user.Email) company, _ := h.adminService.GetCompanyByUserID(ctx, userID) if company != nil { diff --git a/backend/internal/services/admin_service.go b/backend/internal/services/admin_service.go index d07e7d2..4102006 100644 --- a/backend/internal/services/admin_service.go +++ b/backend/internal/services/admin_service.go @@ -565,7 +565,7 @@ func (s *AdminService) getTagByID(ctx context.Context, id int) (*models.Tag, err // GetUser fetches a user by ID func (s *AdminService) GetUser(ctx context.Context, id string) (*dto.User, error) { query := ` - SELECT id, name, email, role, created_at + SELECT id, full_name, email, role, created_at FROM users WHERE id = $1 ` var u dto.User diff --git a/backend/internal/services/admin_service_test.go b/backend/internal/services/admin_service_test.go index 9ea4135..1eb7bd4 100644 --- a/backend/internal/services/admin_service_test.go +++ b/backend/internal/services/admin_service_test.go @@ -160,7 +160,7 @@ func TestAdminService_GetUser(t *testing.T) { t.Run("returns user by id", func(t *testing.T) { userID := "019b5290-9680-7c06-9ee3-c9e0e117251b" now := time.Now() - mock.ExpectQuery("SELECT id, name, email, role, created_at FROM users WHERE id"). + mock.ExpectQuery("SELECT id, full_name, email, role, created_at FROM users WHERE id"). WithArgs(userID). WillReturnRows(sqlmock.NewRows([]string{"id", "name", "email", "role", "created_at"}). AddRow(userID, "Test User", "test@example.com", "admin", now)) diff --git a/backend/internal/services/application_service_test.go b/backend/internal/services/application_service_test.go new file mode 100644 index 0000000..2c01f4d --- /dev/null +++ b/backend/internal/services/application_service_test.go @@ -0,0 +1,31 @@ +package services + +import ( + "testing" + + "github.com/DATA-DOG/go-sqlmock" +) + +func TestApplicationService_DeleteApplication(t *testing.T) { + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + defer db.Close() + + s := NewApplicationService(db) + appID := "test-app-id" + + mock.ExpectExec("DELETE FROM applications WHERE id = \\$1"). + WithArgs(appID). + WillReturnResult(sqlmock.NewResult(1, 1)) + + err = s.DeleteApplication(appID) + if err != nil { + t.Errorf("error was not expected while deleting application: %s", err) + } + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("there were unfulfilled expectations: %s", err) + } +} diff --git a/frontend/src/lib/auth.ts b/frontend/src/lib/auth.ts index d48f4ad..7293b9d 100644 --- a/frontend/src/lib/auth.ts +++ b/frontend/src/lib/auth.ts @@ -23,6 +23,7 @@ export async function login( role?: "candidate" | "admin" | "company" // Deprecated argument, kept for signature compatibility if needed, but ignored ): Promise { try { + console.log("%c[AUTH] Attempting login...", "color: #3b82f6; font-weight: bold", { email }); const res = await fetch(`${API_URL}/auth/login`, { method: "POST", headers: { @@ -43,10 +44,10 @@ export async function login( // Map backend response to frontend User type // Note: The backend returns roles as an array of strings. The frontend expects a single 'role' or we need to adapt. // For now we map the first role or main role to the 'role' field. - let userRole: "candidate" | "admin" | "company" = "candidate"; + let userRole: "candidate" | "admin" | "company" | "superadmin" = "candidate"; // Check for SuperAdmin (Platform Admin) if (data.user.roles.includes("superadmin") || data.user.roles.includes("SUPERADMIN")) { - userRole = "admin"; + userRole = "superadmin"; // Check for Company Admin (now called 'admin') or Recruiter } else if (data.user.roles.includes("admin") || data.user.roles.includes("recruiter")) { userRole = "company"; @@ -69,7 +70,7 @@ export async function login( return user; } catch (error) { - console.error("Login error:", error); + console.error("%c[AUTH] Login Error:", "color: #ef4444; font-weight: bold", error); throw error; } } @@ -85,9 +86,12 @@ export function getCurrentUser(): User | null { if (typeof window !== "undefined") { const stored = localStorage.getItem(AUTH_KEY); if (stored) { - return JSON.parse(stored); + const user = JSON.parse(stored); + console.log("%c[AUTH] User Loaded from Storage", "color: #10b981", user.email); + return user; } } + console.warn("%c[AUTH] No user found in storage", "color: #f59e0b"); return null; } diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index caf52da..66b48b1 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -25,7 +25,7 @@ export interface User { id: string; name: string; email: string; - role: "candidate" | "admin" | "company"; + role: "candidate" | "admin" | "company" | "superadmin"; roles?: string[]; // Added to match backend response structure avatar?: string; area?: string;