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:
@@ -13,6 +13,15 @@ export async function loadSkillCategories(): Promise<SkillCategory[]> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load skill categories from local files (fallback or development mode)
|
||||
* This is a client-side safe alternative that still uses the API
|
||||
* For server-side file loading, use loadSkillCategoriesFromFiles from skill-file-loader
|
||||
*/
|
||||
export async function loadSkillCategoriesFromAPI(): Promise<SkillCategory[]> {
|
||||
return loadSkillCategories();
|
||||
}
|
||||
|
||||
export async function loadTeams(): Promise<Team[]> {
|
||||
try {
|
||||
const response = await fetch("/api/teams");
|
||||
|
||||
94
lib/skill-file-loader.ts
Normal file
94
lib/skill-file-loader.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { SkillCategory } from "./types";
|
||||
|
||||
/**
|
||||
* Load all skill categories from JSON files in the data/skills directory
|
||||
*/
|
||||
export function loadSkillCategoriesFromFiles(): SkillCategory[] {
|
||||
const dataDir = path.join(process.cwd(), "data", "skills");
|
||||
const skillCategories: SkillCategory[] = [];
|
||||
|
||||
try {
|
||||
// Read all JSON files in the skills directory
|
||||
const files = fs
|
||||
.readdirSync(dataDir)
|
||||
.filter((file) => file.endsWith(".json"));
|
||||
console.log(`📁 Found ${files.length} JSON files: ${files.join(", ")}`);
|
||||
|
||||
// Load all JSON files
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dataDir, file);
|
||||
const categoryName = path.basename(file, ".json");
|
||||
|
||||
try {
|
||||
console.log(`📖 Loading ${file}...`);
|
||||
const fileContent = fs.readFileSync(filePath, "utf-8");
|
||||
const data = JSON.parse(fileContent);
|
||||
|
||||
// Validate that it's a proper SkillCategory
|
||||
if (data.category && data.icon && Array.isArray(data.skills)) {
|
||||
skillCategories.push(data);
|
||||
} else {
|
||||
console.warn(`⚠️ Invalid skill category format in ${file}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ Error loading ${file}:`, error);
|
||||
// Continue with other files instead of failing completely
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`📊 Successfully loaded ${skillCategories.length} categories`);
|
||||
return skillCategories;
|
||||
} catch (error) {
|
||||
console.error("❌ Error reading skills directory:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of available skill category files
|
||||
*/
|
||||
export function getSkillCategoryFiles(): string[] {
|
||||
try {
|
||||
const dataDir = path.join(process.cwd(), "data", "skills");
|
||||
return fs
|
||||
.readdirSync(dataDir)
|
||||
.filter((file) => file.endsWith(".json"))
|
||||
.map((file) => path.basename(file, ".json"));
|
||||
} catch (error) {
|
||||
console.error("❌ Error reading skills directory:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a specific skill category by filename
|
||||
*/
|
||||
export function loadSkillCategoryFromFile(
|
||||
categoryName: string
|
||||
): SkillCategory | null {
|
||||
try {
|
||||
const dataDir = path.join(process.cwd(), "data", "skills");
|
||||
const filePath = path.join(dataDir, `${categoryName}.json`);
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.warn(`⚠️ Skill category file not found: ${categoryName}.json`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const fileContent = fs.readFileSync(filePath, "utf-8");
|
||||
const data = JSON.parse(fileContent);
|
||||
|
||||
// Validate that it's a proper SkillCategory
|
||||
if (data.category && data.icon && Array.isArray(data.skills)) {
|
||||
return data;
|
||||
} else {
|
||||
console.warn(`⚠️ Invalid skill category format in ${categoryName}.json`);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ Error loading skill category ${categoryName}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user