feat: refactor skills API and database schema

- Replaced file-based skill category loading with API calls in the GET and POST methods of the skills route.
- Added new `SkillsService` for handling skill category operations.
- Updated SQL initialization script to create `skill_categories`, `skills`, and `skill_links` tables with appropriate relationships.
- Enhanced `ApiClient` with methods for loading skill categories and creating new skills, improving API interaction.
- Introduced error handling for skill category creation and loading processes.
This commit is contained in:
Julien Froidefond
2025-08-21 09:55:35 +02:00
parent 345ff5baa0
commit 72b653de19
10 changed files with 715 additions and 28 deletions

View File

@@ -1,4 +1,11 @@
import { UserEvaluation, UserProfile, SkillLevel, Team } from "../lib/types";
import {
UserEvaluation,
UserProfile,
SkillLevel,
Team,
SkillCategory,
Skill,
} from "../lib/types";
export class ApiClient {
private baseUrl: string;
@@ -321,6 +328,131 @@ export class ApiClient {
return false;
}
}
/**
* Charge toutes les catégories de skills
*/
async loadSkillCategories(): Promise<SkillCategory[]> {
try {
const response = await fetch(`${this.baseUrl}/api/skills`);
if (!response.ok) {
throw new Error("Erreur lors du chargement des catégories de skills");
}
return await response.json();
} catch (error) {
console.error(
"Erreur lors du chargement des catégories de skills:",
error
);
return [];
}
}
/**
* Charge les skills d'une catégorie
*/
async loadSkillsByCategory(categoryId: string): Promise<Skill[]> {
try {
const response = await fetch(`${this.baseUrl}/api/skills/${categoryId}`);
if (!response.ok) {
throw new Error("Erreur lors du chargement des skills par catégorie");
}
return await response.json();
} catch (error) {
console.error(
"Erreur lors du chargement des skills par catégorie:",
error
);
return [];
}
}
/**
* Migre les skills depuis JSON vers PostgreSQL
*/
async migrateSkills(): Promise<{
success: boolean;
stats?: any;
error?: string;
}> {
try {
const response = await fetch(`${this.baseUrl}/api/skills/migrate`, {
method: "POST",
});
if (!response.ok) {
throw new Error("Erreur lors de la migration des skills");
}
return await response.json();
} catch (error) {
console.error("Erreur lors de la migration des skills:", error);
return {
success: false,
error: error instanceof Error ? error.message : "Unknown error",
};
}
}
/**
* Crée une nouvelle catégorie de skill
*/
async createSkillCategory(category: {
id: string;
name: string;
icon: string;
}): Promise<boolean> {
try {
const response = await fetch(`${this.baseUrl}/api/skills`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(category),
});
return response.ok;
} catch (error) {
console.error(
"Erreur lors de la création de la catégorie de skill:",
error
);
return false;
}
}
/**
* Crée une nouvelle skill
*/
async createSkill(
categoryId: string,
skill: {
id: string;
name: string;
description: string;
icon?: string;
links: string[];
}
): Promise<boolean> {
try {
const response = await fetch(`${this.baseUrl}/api/skills/${categoryId}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(skill),
});
return response.ok;
} catch (error) {
console.error("Erreur lors de la création de la skill:", error);
return false;
}
}
}
// Instance singleton