- Added new course management functionalities in VocabController, including creating, updating, and deleting courses and lessons. - Implemented enrollment and progress tracking for courses, along with grammar exercise creation and management. - Updated database schema to include tables for courses, lessons, enrollments, and grammar exercises. - Enhanced frontend with new routes and views for course listing and details, including internationalization support for course-related texts. - Improved user experience by adding navigation to courses from the main vocab trainer view.
133 lines
5.1 KiB
JavaScript
133 lines
5.1 KiB
JavaScript
/* eslint-disable */
|
|
'use strict';
|
|
|
|
module.exports = {
|
|
async up(queryInterface) {
|
|
// Kurs-Tabelle
|
|
await queryInterface.sequelize.query(`
|
|
CREATE TABLE IF NOT EXISTS community.vocab_course (
|
|
id SERIAL PRIMARY KEY,
|
|
owner_user_id INTEGER NOT NULL,
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
language_id INTEGER NOT NULL,
|
|
difficulty_level INTEGER DEFAULT 1,
|
|
is_public BOOLEAN DEFAULT false,
|
|
share_code TEXT,
|
|
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT vocab_course_owner_fk
|
|
FOREIGN KEY (owner_user_id)
|
|
REFERENCES community."user"(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_language_fk
|
|
FOREIGN KEY (language_id)
|
|
REFERENCES community.vocab_language(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_share_code_uniq UNIQUE (share_code)
|
|
);
|
|
`);
|
|
|
|
// Lektionen innerhalb eines Kurses
|
|
await queryInterface.sequelize.query(`
|
|
CREATE TABLE IF NOT EXISTS community.vocab_course_lesson (
|
|
id SERIAL PRIMARY KEY,
|
|
course_id INTEGER NOT NULL,
|
|
chapter_id INTEGER NOT NULL,
|
|
lesson_number INTEGER NOT NULL,
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT vocab_course_lesson_course_fk
|
|
FOREIGN KEY (course_id)
|
|
REFERENCES community.vocab_course(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_lesson_chapter_fk
|
|
FOREIGN KEY (chapter_id)
|
|
REFERENCES community.vocab_chapter(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_lesson_unique UNIQUE (course_id, lesson_number)
|
|
);
|
|
`);
|
|
|
|
// Einschreibungen in Kurse
|
|
await queryInterface.sequelize.query(`
|
|
CREATE TABLE IF NOT EXISTS community.vocab_course_enrollment (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL,
|
|
course_id INTEGER NOT NULL,
|
|
enrolled_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT vocab_course_enrollment_user_fk
|
|
FOREIGN KEY (user_id)
|
|
REFERENCES community."user"(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_enrollment_course_fk
|
|
FOREIGN KEY (course_id)
|
|
REFERENCES community.vocab_course(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_enrollment_unique UNIQUE (user_id, course_id)
|
|
);
|
|
`);
|
|
|
|
// Fortschritt pro User und Lektion
|
|
await queryInterface.sequelize.query(`
|
|
CREATE TABLE IF NOT EXISTS community.vocab_course_progress (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL,
|
|
course_id INTEGER NOT NULL,
|
|
lesson_id INTEGER NOT NULL,
|
|
completed BOOLEAN DEFAULT false,
|
|
score INTEGER DEFAULT 0,
|
|
last_accessed_at TIMESTAMP WITHOUT TIME ZONE,
|
|
completed_at TIMESTAMP WITHOUT TIME ZONE,
|
|
CONSTRAINT vocab_course_progress_user_fk
|
|
FOREIGN KEY (user_id)
|
|
REFERENCES community."user"(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_progress_course_fk
|
|
FOREIGN KEY (course_id)
|
|
REFERENCES community.vocab_course(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_progress_lesson_fk
|
|
FOREIGN KEY (lesson_id)
|
|
REFERENCES community.vocab_course_lesson(id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT vocab_course_progress_unique UNIQUE (user_id, lesson_id)
|
|
);
|
|
`);
|
|
|
|
// Indizes
|
|
await queryInterface.sequelize.query(`
|
|
CREATE INDEX IF NOT EXISTS vocab_course_owner_idx
|
|
ON community.vocab_course(owner_user_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_language_idx
|
|
ON community.vocab_course(language_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_public_idx
|
|
ON community.vocab_course(is_public);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_lesson_course_idx
|
|
ON community.vocab_course_lesson(course_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_lesson_chapter_idx
|
|
ON community.vocab_course_lesson(chapter_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_enrollment_user_idx
|
|
ON community.vocab_course_enrollment(user_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_enrollment_course_idx
|
|
ON community.vocab_course_enrollment(course_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_progress_user_idx
|
|
ON community.vocab_course_progress(user_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_progress_course_idx
|
|
ON community.vocab_course_progress(course_id);
|
|
CREATE INDEX IF NOT EXISTS vocab_course_progress_lesson_idx
|
|
ON community.vocab_course_progress(lesson_id);
|
|
`);
|
|
},
|
|
|
|
async down(queryInterface) {
|
|
await queryInterface.sequelize.query(`
|
|
DROP TABLE IF EXISTS community.vocab_course_progress CASCADE;
|
|
DROP TABLE IF EXISTS community.vocab_course_enrollment CASCADE;
|
|
DROP TABLE IF EXISTS community.vocab_course_lesson CASCADE;
|
|
DROP TABLE IF EXISTS community.vocab_course CASCADE;
|
|
`);
|
|
}
|
|
};
|