@iota-big3/sdk-education-teacher-api
Version:
Teacher Tools API for Education Platform - Classroom management, grading, and insights
240 lines • 10.6 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TeacherAPI = void 0;
const express_1 = __importDefault(require("express"));
const http_1 = require("http");
const multer_1 = __importDefault(require("multer"));
const sdk_auth_1 = require("@iota-big3/sdk-auth");
const sdk_middleware_1 = require("@iota-big3/sdk-middleware");
const sdk_observability_1 = require("@iota-big3/sdk-observability");
const sdk_realtime_1 = require("@iota-big3/sdk-realtime");
const class_access_1 = require("./middleware/class-access");
const validate_teacher_1 = require("./middleware/validate-teacher");
const analytics_service_1 = require("./services/analytics-service");
const assignment_service_1 = require("./services/assignment-service");
const attendance_service_1 = require("./services/attendance-service");
const classroom_service_1 = require("./services/classroom-service");
const communication_service_1 = require("./services/communication-service");
const grading_service_1 = require("./services/grading-service");
const insights_service_1 = require("./services/insights-service");
const analytics_1 = require("./routes/analytics");
const assignments_1 = require("./routes/assignments");
const attendance_1 = require("./routes/attendance");
const classroom_1 = require("./routes/classroom");
const communication_1 = require("./routes/communication");
const dashboard_1 = require("./routes/dashboard");
const grading_1 = require("./routes/grading");
const insights_1 = require("./routes/insights");
const logger = new sdk_observability_1.CentralizedLogger({
level: 'info',
appName: 'teacher-api',
enableConsole: true,
enableFile: false
});
const upload = (0, multer_1.default)({
dest: 'uploads/',
limits: {
fileSize: 10 * 1024 * 1024,
},
});
class TeacherAPI {
constructor(config) {
this.upload = upload;
this.app = (0, express_1.default)();
this.server = (0, http_1.createServer)(this.app);
const sdkIntegrations = {
auth: new sdk_auth_1.SDKAuth({
jwtSecret: process.env.JWT_SECRET || 'teacher-api-secret-key',
jwtExpiry: 28800,
refreshTokenExpiry: 604800,
}),
logger: logger,
};
this.middlewareManager = (0, sdk_middleware_1.createMiddlewareManager)(sdkIntegrations);
this.services = {
classroom: new classroom_service_1.ClassroomService(),
grading: new grading_service_1.GradingService(),
assignment: new assignment_service_1.AssignmentService(),
attendance: new attendance_service_1.AttendanceService(),
insights: new insights_service_1.InsightsService(),
communication: new communication_service_1.CommunicationService(),
analytics: new analytics_service_1.AnalyticsService(),
};
this.setupMiddleware(config);
this.setupRoutes();
this.setupWebSocket(config?.corsOrigins);
this.services.grading.setSocketIO(this.io);
this.services.communication.setSocketIO(this.io);
}
setupMiddleware(config) {
this.middlewareManager.register('cors', this.middlewareManager.createCorsMiddleware({
origin: config?.corsOrigins || ['http://localhost:3000'],
credentials: true,
}));
this.middlewareManager.register('rateLimit', this.middlewareManager.createRateLimitMiddleware({
windowMs: config?.rateLimits?.windowMs || 15 * 60 * 1000,
max: config?.rateLimits?.max || 100,
}));
this.middlewareManager.register('auth', this.middlewareManager.createAuthMiddleware({
requireAuth: true,
tokenLocation: 'header'
}));
this.app.use(this.middlewareManager.apply());
this.app.use(express_1.default.json({ limit: '10mb' }));
this.app.use(express_1.default.urlencoded({ extended: true, limit: '10mb' }));
this.app.use('/api', validate_teacher_1.validateTeacher);
this.app.use('/api', class_access_1.classAccessMiddleware);
}
setupRoutes() {
this.app.get('/health', (req, res) => {
res.json({
success: true,
data: {
status: 'healthy',
timestamp: new Date().toISOString(),
service: 'teacher-api',
},
});
});
this.app.use('/api/dashboard', (0, dashboard_1.dashboardRoutes)(this.services));
this.app.use('/api/classroom', class_access_1.classAccessMiddleware, (0, classroom_1.classroomRoutes)(this.services, this.upload));
this.app.use('/api/grading', class_access_1.classAccessMiddleware, (0, grading_1.gradingRoutes)(this.services, this.upload));
this.app.use('/api/assignments', class_access_1.classAccessMiddleware, (0, assignments_1.assignmentRoutes)(this.services, this.upload));
this.app.use('/api/attendance', class_access_1.classAccessMiddleware, (0, attendance_1.attendanceRoutes)(this.services));
this.app.use('/api/insights', class_access_1.classAccessMiddleware, (0, insights_1.insightsRoutes)(this.services));
this.app.use('/api/communication', (0, communication_1.communicationRoutes)(this.services));
this.app.use('/api/analytics', class_access_1.classAccessMiddleware, (0, analytics_1.analyticsRoutes)(this.services));
this.app.use('*', (req, res) => {
res.status(404).json({
success: false,
error: {
code: 'NOT_FOUND',
message: 'Endpoint not found',
},
});
});
}
setupWebSocket(corsOrigins) {
const realtimeService = new sdk_realtime_1.RealtimeService({
cors: {
origin: corsOrigins || ['http://localhost:3000'],
methods: ['GET', 'POST'],
credentials: true,
},
});
this.io = realtimeService.attach(this.server);
this.io.use(async (socket, next) => {
try {
const token = socket.handshake.auth.token;
if (!token) {
return next(new Error('Authentication error'));
}
const authService = new sdk_auth_1.SDKAuth({
jwtSecret: process.env.JWT_SECRET || 'teacher-api-secret-key',
jwtExpiry: 28800,
refreshTokenExpiry: 604800,
sessionConfig: { maxAge: 28800, renewable: true, secureCookie: false, sameSite: 'strict' },
passwordPolicy: { minLength: 8, requireUppercase: true, requireLowercase: true, requireNumbers: true, requireSpecialChars: false },
enableMFA: false,
enableAudit: false
});
const result = await authService.validateToken(token);
if (!result.success) {
return next(new Error('Invalid token'));
}
socket.data.teacher = result.data;
next();
}
catch (error) {
next(new Error('Authentication error'));
}
});
this.io.on('connection', (socket) => {
logger.info(`Teacher connected: ${socket.data.teacher.id}`);
socket.join(`teacher:${socket.data.teacher.id}`);
if (socket.data.teacher.classIds) {
socket.data.teacher.classIds.forEach((classId) => {
socket.join(`class:${classId}`);
});
}
socket.on('grade:update', (data) => {
this.emitGradeUpdate(data.classId, data.studentId, data.gradeData);
});
socket.on('attendance:update', (data) => {
this.emitAttendanceUpdate(data.classId, data.attendanceData);
});
socket.on('announcement:create', (data) => {
this.emitAnnouncement(data.classIds, data.announcement);
});
socket.on('disconnect', () => {
logger.info(`Teacher disconnected: ${socket.data.teacher.id}`);
});
});
}
start(port = 3003) {
this.server.listen(port, () => {
logger.info(`Teacher API running on port ${port}`);
});
}
stop() {
this.server.close();
}
emitClassUpdate(classId, eventType, data) {
this.io.to(`class:${classId}`).emit('class:update', {
type: eventType,
classId,
data,
timestamp: new Date(),
});
}
emitGradeUpdate(classId, studentId, gradeData) {
this.io.to(`class:${classId}`).emit('grade:updated', {
studentId,
gradeData,
classId,
timestamp: new Date(),
});
this.io.to(`student:${studentId}:parents`).emit('grade:updated', {
studentId,
gradeData,
timestamp: new Date(),
});
}
emitAttendanceUpdate(classId, attendanceData) {
this.io.to(`class:${classId}`).emit('attendance:updated', {
classId,
attendanceData,
timestamp: new Date(),
});
}
emitAnnouncement(classIds, announcement) {
classIds.forEach(classId => {
this.io.to(`class:${classId}`).emit('announcement:new', announcement);
});
}
emit(event, data) {
logger.debug(`Emitting ${event}:`, data);
this.io.emit(event, data);
}
}
exports.TeacherAPI = TeacherAPI;
exports.default = TeacherAPI;
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map