feat: add A2-B1 course expansion features including listening activities and conversation sessions
- Updated VocabCourseView.vue to display CEFR level for courses. - Enhanced VocabLessonView.vue with new sections for listening activities and conversation labs, including audio controls and transcript toggling. - Created migration to add new columns to vocab_course and new tables for conversation sessions and listening activities. - Implemented models for vocab_conversation_session and vocab_listening_activity. - Developed scripts to create new A2 and B1 bridge courses with structured lesson plans. - Documented the A2-B1 expansion plan detailing course structure, learning goals, and assessment criteria.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
async up(queryInterface) {
|
||||
await queryInterface.sequelize.transaction(async (transaction) => {
|
||||
await queryInterface.sequelize.query(`
|
||||
ALTER TABLE community.vocab_course
|
||||
ADD COLUMN IF NOT EXISTS cefr_level TEXT,
|
||||
ADD COLUMN IF NOT EXISTS course_kind TEXT NOT NULL DEFAULT 'core',
|
||||
ADD COLUMN IF NOT EXISTS prerequisite_course_id INTEGER NULL
|
||||
REFERENCES community.vocab_course(id) ON DELETE SET NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS community.vocab_conversation_session (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER NOT NULL REFERENCES community."user"(id) ON DELETE CASCADE,
|
||||
lesson_id INTEGER NOT NULL REFERENCES community.vocab_course_lesson(id) ON DELETE CASCADE,
|
||||
scenario JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
turns JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
summary JSONB NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS vocab_conversation_session_user_lesson_idx
|
||||
ON community.vocab_conversation_session(user_id, lesson_id, updated_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS community.vocab_listening_activity (
|
||||
id SERIAL PRIMARY KEY,
|
||||
lesson_id INTEGER NOT NULL REFERENCES community.vocab_course_lesson(id) ON DELETE CASCADE,
|
||||
audio_url TEXT NOT NULL,
|
||||
transcript TEXT NOT NULL,
|
||||
translation TEXT NULL,
|
||||
speaker_profile JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
speed TEXT NOT NULL DEFAULT 'natural',
|
||||
questions JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS vocab_listening_activity_lesson_idx
|
||||
ON community.vocab_listening_activity(lesson_id);
|
||||
`, { transaction });
|
||||
});
|
||||
},
|
||||
|
||||
async down(queryInterface) {
|
||||
await queryInterface.sequelize.query(`
|
||||
DROP TABLE IF EXISTS community.vocab_listening_activity;
|
||||
DROP TABLE IF EXISTS community.vocab_conversation_session;
|
||||
ALTER TABLE community.vocab_course
|
||||
DROP COLUMN IF EXISTS prerequisite_course_id,
|
||||
DROP COLUMN IF EXISTS course_kind,
|
||||
DROP COLUMN IF EXISTS cefr_level;
|
||||
`);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
/** Repairs the already generated exercise that rendered as a bare blank. */
|
||||
module.exports = {
|
||||
async up(queryInterface) {
|
||||
await queryInterface.sequelize.query(`
|
||||
UPDATE community.vocab_grammar_exercise AS exercise
|
||||
SET question_data = '{"type":"gap_fill","text":"{gap} ka padulong?","gaps":1}'::jsonb,
|
||||
answer_data = '{"type":"gap_fill","answers":["Asa"]}'::jsonb,
|
||||
explanation = 'Das Kernmuster lautet: "Asa ka padulong?"'
|
||||
FROM community.vocab_course_lesson AS lesson
|
||||
WHERE exercise.lesson_id = lesson.id
|
||||
AND lesson.lesson_number = 46
|
||||
AND lesson.title = 'Fragen im Alltag vertiefen'
|
||||
AND exercise.title = 'Fragen im Alltag vertiefen: Kernmuster ergänzen'
|
||||
AND exercise.question_data->>'text' = '{gap}';
|
||||
`);
|
||||
},
|
||||
async down() {
|
||||
// The old exercise has no useful learner-visible prompt and is not restored.
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user