courseworx/backend/routes/userNotes.js
mmabdalla 5477297914 v2.0.2 - Complete Plugin Architecture System and Multi-Currency Implementation
Major Features Added:
- Complete Plugin Architecture System with financial plugin
- Multi-currency support with exchange rates
- Course type system (online, classroom, hybrid)
- Attendance tracking and QR code scanning
- Classroom sessions management
- Course sections and content management
- Professional video player with authentication
- Secure media serving system
- Shopping cart and checkout system
- Financial dashboard and earnings tracking
- Trainee progress tracking
- User notes and assignments system

Backend Infrastructure:
- Plugin loader and registry system
- Multi-currency database models
- Secure media middleware
- Course access middleware
- Financial plugin with payment processing
- Database migrations for new features
- API endpoints for all new functionality

Frontend Components:
- Course management interface
- Content creation and editing
- Section management with drag-and-drop
- Professional video player
- QR scanner for attendance
- Shopping cart and checkout flow
- Financial dashboard
- Plugin management interface
- Trainee details and progress views

This represents a major evolution of CourseWorx from a basic LMS to a comprehensive educational platform with plugin architecture.
2025-09-14 04:20:37 +03:00

166 lines
4.6 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { UserNotes, Course, CourseContent } = require('../models');
const { auth } = require('../middleware/auth');
const { requirePaidEnrollment } = require('../middleware/courseAccess');
// Get user notes for a course (requires paid enrollment)
router.get('/:courseId', auth, requirePaidEnrollment, async (req, res) => {
try {
const { courseId } = req.params;
const { userId } = req.query;
// Check if course exists
const course = await Course.findByPk(courseId);
if (!course) {
return res.status(404).json({ error: 'Course not found' });
}
// Get notes for the user and course
const notes = await UserNotes.findAll({
where: {
courseId,
userId: userId || req.user.id
},
include: [
{
model: CourseContent,
as: 'content',
attributes: ['id', 'title', 'type']
}
],
order: [['createdAt', 'DESC']]
});
res.json(notes);
} catch (error) {
console.error('Error fetching user notes:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Get user notes for specific content (requires paid enrollment)
router.get('/:courseId/content/:contentId', auth, requirePaidEnrollment, async (req, res) => {
try {
const { courseId, contentId } = req.params;
const { userId } = req.query;
// Check if course and content exist
const course = await Course.findByPk(courseId);
if (!course) {
return res.status(404).json({ error: 'Course not found' });
}
const content = await CourseContent.findOne({
where: { id: contentId, courseId }
});
if (!content) {
return res.status(404).json({ error: 'Content not found' });
}
// Get notes for the user, course, and content
const notes = await UserNotes.findAll({
where: {
courseId,
contentId,
userId: userId || req.user.id
},
order: [['createdAt', 'DESC']]
});
res.json(notes);
} catch (error) {
console.error('Error fetching content notes:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Create a new note (requires paid enrollment)
router.post('/:courseId', auth, requirePaidEnrollment, async (req, res) => {
try {
const { courseId } = req.params;
const { contentId, notes, tabType, isPublic } = req.body;
// Check if course exists
const course = await Course.findByPk(courseId);
if (!course) {
return res.status(404).json({ error: 'Course not found' });
}
// If contentId is provided, check if content exists
if (contentId) {
const content = await CourseContent.findOne({
where: { id: contentId, courseId }
});
if (!content) {
return res.status(404).json({ error: 'Content not found' });
}
}
// Create the note
const userNote = await UserNotes.create({
userId: req.user.id,
courseId,
contentId: contentId || null,
notes: notes || '',
tabType: tabType || 'notes',
isPublic: isPublic || false
});
res.status(201).json(userNote);
} catch (error) {
console.error('Error creating note:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Update a note
router.put('/:noteId', auth, async (req, res) => {
try {
const { noteId } = req.params;
const updateData = req.body;
// Find the note and check ownership
const note = await UserNotes.findByPk(noteId);
if (!note) {
return res.status(404).json({ error: 'Note not found' });
}
if (note.userId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized to update this note' });
}
// Update the note
await note.update(updateData);
res.json(note);
} catch (error) {
console.error('Error updating note:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Delete a note
router.delete('/:noteId', auth, async (req, res) => {
try {
const { noteId } = req.params;
// Find the note and check ownership
const note = await UserNotes.findByPk(noteId);
if (!note) {
return res.status(404).json({ error: 'Note not found' });
}
if (note.userId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized to delete this note' });
}
// Delete the note
await note.destroy();
res.json({ message: 'Note deleted successfully' });
} catch (error) {
console.error('Error deleting note:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
module.exports = router;