diff --git a/db/migrations/000048_seed_default_courses.up.sql b/db/migrations/000048_seed_default_courses.up.sql index 2c00019..7401fc0 100644 --- a/db/migrations/000048_seed_default_courses.up.sql +++ b/db/migrations/000048_seed_default_courses.up.sql @@ -1,5 +1,5 @@ --- Default CEFR-style course names per program (custom courses can still be created via the API with any name). --- Matches hierarchy note on courses: CEFR labels A1..C2, plus ad-hoc names allowed. +-- Default CEFR-style courses per seeded program: Beginner→A1,A2; Intermediate→B1,B2; Advanced→C1,C2. +-- Custom courses can still be created via the API with any name. INSERT INTO courses (program_id, name, description, thumbnail) SELECT p.id, @@ -7,12 +7,13 @@ SELECT 'Default CEFR level course (system seed).', NULL FROM programs AS p -CROSS JOIN ( +INNER JOIN ( VALUES - ('A1'), - ('A2'), - ('B1'), - ('B2'), - ('C1'), - ('C2') -) AS v (name); + ('Beginner', 'A1'), + ('Beginner', 'A2'), + ('Intermediate', 'B1'), + ('Intermediate', 'B2'), + ('Advanced', 'C1'), + ('Advanced', 'C2') +) AS v (program_name, name) + ON p.name = v.program_name; diff --git a/db/migrations/000050_default_courses_per_program.down.sql b/db/migrations/000050_default_courses_per_program.down.sql new file mode 100644 index 0000000..648abe7 --- /dev/null +++ b/db/migrations/000050_default_courses_per_program.down.sql @@ -0,0 +1 @@ +-- Data cleanup is not reversed; restoring the old cross-product seed would be ambiguous. diff --git a/db/migrations/000050_default_courses_per_program.up.sql b/db/migrations/000050_default_courses_per_program.up.sql new file mode 100644 index 0000000..bcae0ad --- /dev/null +++ b/db/migrations/000050_default_courses_per_program.up.sql @@ -0,0 +1,45 @@ +-- Align default seeded courses with program: Beginner→A1,A2; Intermediate→B1,B2; Advanced→C1,C2. +-- Only touches rows with the system seed description; custom courses are unchanged. +-- Removing a course cascades to modules, lessons, and related LMS progress (see FKs on those tables). + +DELETE FROM courses AS c + USING programs AS p +WHERE c.program_id = p.id + AND c.description = 'Default CEFR level course (system seed).' + AND ( + ( + p.name = 'Beginner' + AND c.name IN ('B1', 'B2', 'C1', 'C2') + ) + OR ( + p.name = 'Intermediate' + AND c.name IN ('A1', 'A2', 'C1', 'C2') + ) + OR ( + p.name = 'Advanced' + AND c.name IN ('A1', 'A2', 'B1', 'B2') + ) + ); + +INSERT INTO courses (program_id, name, description, thumbnail) +SELECT + p.id, + v.name, + 'Default CEFR level course (system seed).', + NULL +FROM programs AS p +INNER JOIN ( + VALUES + ('Beginner', 'A1'), + ('Beginner', 'A2'), + ('Intermediate', 'B1'), + ('Intermediate', 'B2'), + ('Advanced', 'C1'), + ('Advanced', 'C2') +) AS v (program_name, name) + ON p.name = v.program_name +WHERE + NOT EXISTS ( + SELECT 1 FROM courses AS e + WHERE e.program_id = p.id AND e.name = v.name + ); diff --git a/internal/domain/course.go b/internal/domain/course.go index 2344fa1..22b7543 100644 --- a/internal/domain/course.go +++ b/internal/domain/course.go @@ -2,8 +2,15 @@ package domain import "time" -// DefaultCEFRCourseNames are the standard course names seeded for each program (migration 000048). -// Creating a course via the API may use any of these or a custom name. +// DefaultCEFRCoursesByProgramName maps seeded program names to default course names +// (migrations 000048 and 000050). The API may still create courses with any name. +var DefaultCEFRCoursesByProgramName = map[string][]string{ + "Beginner": {"A1", "A2"}, + "Intermediate": {"B1", "B2"}, + "Advanced": {"C1", "C2"}, +} + +// DefaultCEFRCourseNames is every CEFR label used in DefaultCEFRCoursesByProgramName. var DefaultCEFRCourseNames = []string{"A1", "A2", "B1", "B2", "C1", "C2"} // Course belongs to a Program.