UNPKG

@sparring/tech-roles-library

Version:

Comprehensive tech roles and competencies library for 78 technical roles with 9 career levels each. Includes detailed competencies and career progression paths with complete bilingual support (EN/ES).

167 lines (150 loc) 4.43 kB
/** * Competency Database - In-memory database with optimized indexes * * Provides fast lookups through multiple indexes (by code, role, category, competency, level). * Uses Map data structures for O(1) lookups. * * @module core/database * @author 686f6c61 */ /** * In-memory database for competency entries with multiple indexes. * * @class CompetencyDatabase */ class CompetencyDatabase { /** * Creates a new database instance with empty indexes. */ constructor() { this.entries = []; this.indexes = { byCode: new Map(), // code -> entry byRole: new Map(), // roleName -> [entries] byCategory: new Map(), // category -> [entries] byCompetency: new Map(), // competency (lowercase) -> [entries] byLevelNumber: new Map() // levelNumber -> [entries] }; } /** * Load entries and build all indexes. * * @param {Object[]} entries - Array of parsed role entries */ load(entries) { this.entries = entries; this.buildIndexes(); } /** * Build all indexes from loaded entries. * Creates inverted indexes for fast lookups. * * @private */ buildIndexes() { this.entries.forEach(entry => { // Index by code this.indexes.byCode.set(entry.code, entry); // Index by role if (!this.indexes.byRole.has(entry.role)) { this.indexes.byRole.set(entry.role, []); } this.indexes.byRole.get(entry.role).push(entry); // Index by category if (!this.indexes.byCategory.has(entry.category)) { this.indexes.byCategory.set(entry.category, []); } this.indexes.byCategory.get(entry.category).push(entry); // Index by competency (inverted index) const allCompetencies = [ ...entry.coreCompetencies, ...entry.complementaryCompetencies ]; allCompetencies.forEach(comp => { const compLower = comp.toLowerCase(); if (!this.indexes.byCompetency.has(compLower)) { this.indexes.byCompetency.set(compLower, []); } this.indexes.byCompetency.get(compLower).push(entry); }); // Index by level number if (entry.levelNumber) { if (!this.indexes.byLevelNumber.has(entry.levelNumber)) { this.indexes.byLevelNumber.set(entry.levelNumber, []); } this.indexes.byLevelNumber.get(entry.levelNumber).push(entry); } }); // Sort role entries by level number this.indexes.byRole.forEach((entries, role) => { entries.sort((a, b) => (a.levelNumber || 0) - (b.levelNumber || 0)); }); } /** * Get entry by code. * * @param {string} code - Role code (e.g., 'BE-L3') * @returns {Object|undefined} Entry or undefined if not found */ getByCode(code) { return this.indexes.byCode.get(code); } /** * Get all entries for a role. * * @param {string} role - Role name * @returns {Object[]} Array of entries for this role */ getByRole(role) { return this.indexes.byRole.get(role) || []; } /** * Get all entries in a category. * * @param {string} category - Category name * @returns {Object[]} Array of entries in this category */ getByCategory(category) { return this.indexes.byCategory.get(category) || []; } /** * Search entries by competency. * * @param {string} competency - Competency to search for * @returns {Object[]} Array of entries containing this competency */ searchByCompetency(competency) { const compLower = competency.toLowerCase(); return this.indexes.byCompetency.get(compLower) || []; } /** * Get all unique role names. * * @returns {string[]} Array of role names */ getAllRoles() { return Array.from(this.indexes.byRole.keys()).sort(); } /** * Get all unique category names. * * @returns {string[]} Array of category names */ getAllCategories() { return Array.from(this.indexes.byCategory.keys()).sort(); } /** * Get database statistics. * * @returns {Object} Statistics object with counts and averages */ getStatistics() { return { totalRoles: this.getAllRoles().length, totalCategories: this.getAllCategories().length, totalEntries: this.entries.length, averageEntriesPerRole: Math.round(this.entries.length / this.getAllRoles().length) }; } } module.exports = CompetencyDatabase;