fix: resolved user profile 500 error, fixed frontend build types, enhanced logging, increases test coverage

This commit is contained in:
Tiago Yamamoto 2025-12-26 01:35:34 -03:00
parent 3fa875ed98
commit f51a8dd99c
7 changed files with 46 additions and 7 deletions

View file

@ -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 |
---

View file

@ -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 {

View file

@ -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

View file

@ -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))

View file

@ -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)
}
}

View file

@ -23,6 +23,7 @@ export async function login(
role?: "candidate" | "admin" | "company" // Deprecated argument, kept for signature compatibility if needed, but ignored
): Promise<User | null> {
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;
}

View file

@ -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;