mcp-quiz-server
Version:
🧠AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.
256 lines (255 loc) • 10.2 kB
JavaScript
"use strict";
/**
* @fileoverview Route Registry - Central registry for all HTTP routes following clean architecture
* @version 1.0.0
* @since 2025-07-31
* @lastUpdated 2025-07-31
* @module RouteRegistry
* @description Central registry for organizing and configuring all HTTP routes in the application.
* Follows clean architecture principles with dependency injection and proper separation of concerns.
* @contributors Claude Code Agent
* @dependencies express, all route modules, ControllerFactory, DatabaseInitializer
* @requirementsTraceability
* @requirementsTraceability {@link Requirements.REQ_ARCH_002} (Service Boundary Enforcement)
* @requirementsTraceability {@link Requirements.REQ_API_001} (Health Check and Monitoring Endpoints)
* @requirementsTraceability Requirements.REQ_ROUTES_001} (User-Facing Quiz URL System)
* @requirementsTraceability {@link Requirements.REQ_ROUTES_004} (API Route Coexistence)
* @testType integration
* @testCoverage Route registry integration tests
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RouteRegistry = void 0;
const error_handler_1 = require("../../../shared/error-handler");
// Route module imports
const AdminRoutes_1 = require("./AdminRoutes");
const HealthRoutes_1 = require("./HealthRoutes");
const QuizRoutes_1 = require("./QuizRoutes");
const ResultsRoutes_1 = require("./ResultsRoutes");
const StatsRoutes_1 = require("./StatsRoutes");
/**
* Central route registry for organizing and configuring all HTTP routes.
*
* @description Manages the registration of all route modules with proper dependency
* injection and configuration. Supports both clean architecture controllers
* and legacy service fallbacks.
*
* @since 2025-07-31
* @author Claude Code Agent
* @requirements REQ_ARCH_002 (Service Boundary Enforcement)
* @accessibility Centralized route management for maintainability
*/
class RouteRegistry {
constructor(config) {
this.registeredRoutes = [];
this.registrationComplete = false;
this.config = config;
}
/**
* Registers all application routes with their respective configurations.
*
* @description Sets up all route modules with proper dependency injection,
* middleware configuration, and error handling.
*
* @throws {Error} If route registration fails
*
* @example
* ```typescript
* const registry = new RouteRegistry({
* app,
* controllerFactory,
* dbInitializer,
* auditLogger,
* legacyService
* });
* await registry.registerAllRoutes();
* ```
*
* @since 2025-07-31
* @author Claude Code Agent
* @requirements REQ_ARCH_002 (Service Boundary Enforcement)
*/
async registerAllRoutes() {
try {
error_handler_1.Logger.info('Starting route registration process');
const { app, controllerFactory, dbInitializer, auditLogger, environment } = this.config;
// Health routes (public endpoints)
this.registerHealthRoutes();
// Authentication routes (if auth is enabled)
this.registerAuthRoutes();
// Dashboard routes (user interface)
this.registerDashboardRoutes();
// Quiz routes (main API endpoints)
this.registerQuizRoutes();
// Results routes (quiz submission and results)
this.registerResultsRoutes();
// Statistics routes (analytics and metrics)
this.registerStatsRoutes();
// Admin routes (administrative operations)
this.registerAdminRoutes();
this.registrationComplete = true;
const status = {
routesRegistered: [...this.registeredRoutes],
controllersAvailable: !!(controllerFactory && controllerFactory.hasCleanArchitecture()),
cleanArchitectureMode: !!(controllerFactory === null || controllerFactory === void 0 ? void 0 : controllerFactory.hasCleanArchitecture()),
registrationTimestamp: new Date().toISOString(),
};
error_handler_1.Logger.info('Route registration completed successfully', {
routeCount: this.registeredRoutes.length,
cleanArchitecture: status.cleanArchitectureMode,
});
return status;
}
catch (error) {
error_handler_1.Logger.error('Route registration failed:', error instanceof Error ? error : new Error(String(error)));
throw new Error(`Failed to register routes: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Registers health check routes.
* @private
*/
registerHealthRoutes() {
const healthConfig = {
dbInitializer: this.config.dbInitializer,
environment: this.config.environment,
authService: this.config.authService,
};
const healthRouter = (0, HealthRoutes_1.createHealthRoutes)(healthConfig);
// Register both /health and root health check
this.config.app.use('/health', healthRouter);
this.config.app.get('/health', healthRouter); // Direct health endpoint
this.registeredRoutes.push('/health/*');
error_handler_1.Logger.info('Health routes registered');
}
/**
* Registers authentication routes.
* @private
*/
registerAuthRoutes() {
// Authentication routes disabled in OSS version
error_handler_1.Logger.info('Authentication routes disabled in OSS version');
return;
}
/**
* Registers dashboard routes for authenticated users.
* @private
*/
registerDashboardRoutes() {
// Dashboard routes disabled in OSS version
error_handler_1.Logger.info('Dashboard routes disabled in OSS version');
return;
}
/**
* Registers quiz-related routes.
* @private
*/
registerQuizRoutes() {
// Clean Architecture only - no legacy fallback
if (!this.config.controllerFactory) {
error_handler_1.Logger.warn('Quiz routes registration skipped - Clean Architecture controllers not available');
return;
}
const quizConfig = {
controllerFactory: this.config.controllerFactory,
auditLogger: this.config.auditLogger,
authMiddleware: this.config.authMiddleware,
};
const quizRouter = (0, QuizRoutes_1.createQuizRoutes)(quizConfig);
this.config.app.use('/api/quiz', quizRouter);
this.registeredRoutes.push('/api/quiz/*');
error_handler_1.Logger.info('Quiz routes registered (Clean Architecture only)');
}
/**
* Registers results-related routes.
* @private
*/
registerResultsRoutes() {
if (!this.config.controllerFactory) {
error_handler_1.Logger.warn('Results routes registration skipped - Clean Architecture controllers not available');
return;
}
const resultsConfig = {
auditLogger: this.config.auditLogger,
};
const resultsRouter = (0, ResultsRoutes_1.createResultsRoutes)(resultsConfig);
this.config.app.use('/api/results', resultsRouter);
this.registeredRoutes.push('/api/results/*');
error_handler_1.Logger.info('Results routes registered (Clean Architecture only)');
}
/**
* Registers statistics-related routes.
* @private
*/
registerStatsRoutes() {
if (!this.config.controllerFactory) {
error_handler_1.Logger.warn('Stats routes registration skipped - Clean Architecture controllers not available');
return;
}
const statsConfig = {
auditLogger: this.config.auditLogger,
authMiddleware: this.config.authMiddleware,
};
const statsRouter = (0, StatsRoutes_1.createStatsRoutes)(statsConfig);
this.config.app.use('/api/stats', statsRouter);
this.registeredRoutes.push('/api/stats/*');
error_handler_1.Logger.info('Statistics routes registered (Clean Architecture only)');
}
/**
* Registers administrative routes.
* @private
*/
registerAdminRoutes() {
if (!this.config.controllerFactory) {
error_handler_1.Logger.warn('Admin routes registration skipped - Clean Architecture controllers not available');
return;
}
const adminConfig = {
auditLogger: this.config.auditLogger,
// authMiddleware removed for OSS version
};
const adminRouter = (0, AdminRoutes_1.createAdminRoutes)(adminConfig);
this.config.app.use('/api/admin', adminRouter);
this.registeredRoutes.push('/api/admin/*');
error_handler_1.Logger.info('Admin routes registered (Clean Architecture only)');
}
/**
* Gets the current status of route registration.
*
* @returns Current route registry status
*
* @since 2025-07-31
* @author Claude Code Agent
*/
getStatus() {
var _a, _b;
return {
routesRegistered: [...this.registeredRoutes],
controllersAvailable: !!((_a = this.config.controllerFactory) === null || _a === void 0 ? void 0 : _a.hasCleanArchitecture()),
cleanArchitectureMode: !!((_b = this.config.controllerFactory) === null || _b === void 0 ? void 0 : _b.hasCleanArchitecture()),
registrationTimestamp: new Date().toISOString(),
};
}
/**
* Checks if route registration is complete.
*
* @returns True if all routes have been registered
*
* @since 2025-07-31
* @author Claude Code Agent
*/
isRegistrationComplete() {
return this.registrationComplete;
}
/**
* Gets the list of registered route patterns.
*
* @returns Array of registered route patterns
*
* @since 2025-07-31
* @author Claude Code Agent
*/
getRegisteredRoutes() {
return [...this.registeredRoutes];
}
}
exports.RouteRegistry = RouteRegistry;