feat: remove supabase dependence during course cloning (#605)
* feat: Add .gitignore file and update package.json with pnpm version feat: Enhance course queries with error handling and new course retrieval feat: Implement exercise queries for creating and fetching exercises, questions, and options feat: Create group queries for managing groups and group members feat: Add lesson queries for creating lessons and fetching sections by course ID feat: Update seed script to include seeding for users, profiles, accounts, organizations, groups, courses, lessons, exercises, questions, and options * feat: Enhance course cloning functionality by refining course and lesson data handling * chore: remove console.log * feat: update role assignment in cloneCourse function and clean up unused types in database.ts
This commit is contained in:
@@ -3,6 +3,7 @@ import * as schema from '@db/schema';
|
||||
import { and, eq, sql } from 'drizzle-orm';
|
||||
|
||||
import { db } from '@db/drizzle';
|
||||
import { TNewCourse } from '@db/types';
|
||||
|
||||
/**
|
||||
* Gets courses by organization siteName
|
||||
@@ -10,41 +11,61 @@ import { db } from '@db/drizzle';
|
||||
* @returns Array of courses with lesson counts and organization info
|
||||
*/
|
||||
export const getCoursesBySiteName = async (siteName: string) => {
|
||||
const result = await db
|
||||
.select({
|
||||
course: schema.course,
|
||||
organization: {
|
||||
id: schema.organization.id,
|
||||
name: schema.organization.name,
|
||||
siteName: schema.organization.siteName,
|
||||
avatarUrl: schema.organization.avatarUrl
|
||||
},
|
||||
lessonCount: sql<number>`COUNT(${schema.lesson.id})`.as('lesson_count')
|
||||
})
|
||||
.from(schema.course)
|
||||
.innerJoin(schema.group, eq(schema.course.groupId, schema.group.id))
|
||||
.innerJoin(schema.organization, eq(schema.group.organizationId, schema.organization.id))
|
||||
.leftJoin(schema.lesson, eq(schema.course.id, schema.lesson.courseId))
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organization.siteName, siteName),
|
||||
eq(schema.course.status, 'ACTIVE'),
|
||||
eq(schema.course.isPublished, true)
|
||||
try {
|
||||
const result = await db
|
||||
.select({
|
||||
course: schema.course,
|
||||
organization: {
|
||||
id: schema.organization.id,
|
||||
name: schema.organization.name,
|
||||
siteName: schema.organization.siteName,
|
||||
avatarUrl: schema.organization.avatarUrl
|
||||
},
|
||||
lessonCount: sql<number>`COUNT(${schema.lesson.id})`.as('lesson_count')
|
||||
})
|
||||
.from(schema.course)
|
||||
.innerJoin(schema.group, eq(schema.course.groupId, schema.group.id))
|
||||
.innerJoin(schema.organization, eq(schema.group.organizationId, schema.organization.id))
|
||||
.leftJoin(schema.lesson, eq(schema.course.id, schema.lesson.courseId))
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organization.siteName, siteName),
|
||||
eq(schema.course.status, 'ACTIVE'),
|
||||
eq(schema.course.isPublished, true)
|
||||
)
|
||||
)
|
||||
)
|
||||
.groupBy(
|
||||
schema.course.id,
|
||||
schema.organization.id,
|
||||
schema.organization.name,
|
||||
schema.organization.siteName,
|
||||
schema.organization.avatarUrl
|
||||
);
|
||||
.groupBy(
|
||||
schema.course.id,
|
||||
schema.organization.id,
|
||||
schema.organization.name,
|
||||
schema.organization.siteName,
|
||||
schema.organization.avatarUrl
|
||||
);
|
||||
|
||||
return result.map((row) => ({
|
||||
...row.course,
|
||||
lessons: [{ count: Number(row.lessonCount) }],
|
||||
group: {
|
||||
organization: row.organization
|
||||
}
|
||||
}));
|
||||
return result.map((row) => ({
|
||||
...row.course,
|
||||
lessons: [{ count: Number(row.lessonCount) }],
|
||||
group: {
|
||||
organization: row.organization
|
||||
}
|
||||
}));
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get courses by site name "${siteName}": ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
export async function getCourseById(courseId: string) {
|
||||
try {
|
||||
return await db.select().from(schema.course).where(eq(schema.course.id, courseId)).limit(1);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get course by ID "${courseId}": ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createCourse(newCourse: TNewCourse) {
|
||||
try {
|
||||
return await db.insert(schema.course).values(newCourse).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create course: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import { db, eq, inArray } from '@db/drizzle';
|
||||
import { TNewExercise, TNewQuestion, TNewOption, TExercise } from '@db/types';
|
||||
import * as schema from '@db/schema';
|
||||
|
||||
export async function createExercises(values: TNewExercise[]) {
|
||||
try {
|
||||
return db.insert(schema.exercise).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create exercises: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getExercisesByLessonIds(lessonIds: string[]): Promise<TExercise[]> {
|
||||
if (lessonIds.length === 0) return [];
|
||||
try {
|
||||
return db.select().from(schema.exercise).where(inArray(schema.exercise.lessonId, lessonIds));
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to get exercises by lesson IDs: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createQuestions(values: TNewQuestion[]) {
|
||||
if (values.length === 0) return [];
|
||||
try {
|
||||
return db.insert(schema.question).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create questions: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getQuestionsByExerciseIds(exerciseIds: string[]): Promise<TNewQuestion[]> {
|
||||
if (exerciseIds.length === 0) return [];
|
||||
try {
|
||||
return db.select().from(schema.question).where(inArray(schema.question.exerciseId, exerciseIds));
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to get questions by exercise IDs: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createOptions(values: TNewOption[]) {
|
||||
if (values.length === 0) return [];
|
||||
try {
|
||||
return db.insert(schema.option).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create options: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getOptionsByQuestionIds(questionIds: number[]) {
|
||||
if (questionIds.length === 0) return [];
|
||||
try {
|
||||
return db.select().from(schema.option).where(inArray(schema.option.questionId, questionIds));
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to get options by question IDs: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './exercise';
|
||||
@@ -0,0 +1,19 @@
|
||||
import { db } from '@db/drizzle';
|
||||
import { TNewGroup, TNewGroupmember } from '@db/types';
|
||||
import * as schema from '@db/schema';
|
||||
|
||||
export async function createGroup(values: TNewGroup) {
|
||||
try {
|
||||
return db.insert(schema.group).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create group: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function addGroupMember(values: TNewGroupmember) {
|
||||
try {
|
||||
return db.insert(schema.groupmember).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to add group member: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './group';
|
||||
@@ -1,3 +1,6 @@
|
||||
export * from './organization';
|
||||
export * from './auth';
|
||||
export * from './course';
|
||||
export * from './group';
|
||||
export * from './lesson';
|
||||
export * from './exercise';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './lesson';
|
||||
@@ -0,0 +1,59 @@
|
||||
import { db, eq, inArray } from '@db/drizzle';
|
||||
import * as schema from '@db/schema';
|
||||
import { TNewLesson, TNewLessonSection, TNewLessonLanguage } from '@db/types';
|
||||
|
||||
export async function getSectionsByCourseId(courseId: string) {
|
||||
try {
|
||||
return db.select().from(schema.lessonSection).where(eq(schema.lessonSection.courseId, courseId));
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to get sections by course ID "${courseId}": ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createLessonSections(values: TNewLessonSection[]) {
|
||||
try {
|
||||
return db.insert(schema.lessonSection).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create lesson sections: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLessonsByCourseId(courseId: string) {
|
||||
try {
|
||||
return db.select().from(schema.lesson).where(eq(schema.lesson.courseId, courseId));
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to get lessons by course ID "${courseId}": ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createLessons(values: TNewLesson[]) {
|
||||
try {
|
||||
return db.insert(schema.lesson).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create lessons: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLessonLanguagesByLessonIds(lessonIds: string[]) {
|
||||
if (lessonIds.length === 0) return [];
|
||||
try {
|
||||
return db.select().from(schema.lessonLanguage).where(inArray(schema.lessonLanguage.lessonId, lessonIds));
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Failed to get lesson languages by lesson IDs: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createLessonLanguages(values: TNewLessonLanguage[]) {
|
||||
if (values.length === 0) return [];
|
||||
try {
|
||||
return db.insert(schema.lessonLanguage).values(values).returning();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create lesson languages: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user