diff --git a/apps/api/src/activity-logs/types/index.ts b/apps/api/src/activity-logs/types/index.ts
index 7030de822e..64344b3aad 100644
--- a/apps/api/src/activity-logs/types/index.ts
+++ b/apps/api/src/activity-logs/types/index.ts
@@ -99,10 +99,8 @@ export type LessonActivityLogSnapshot = {
lessonResources?: LessonActivityLogResource[];
questions?: LessonActivityLogQuestion[];
aiMentor?: {
- aiMentorInstructions?: string | null;
name?: string | null;
avatarReference?: string | null;
- type?: string | null;
voiceMode?: string | null;
ttsPreset?: string | null;
customTtsReference?: string | null;
diff --git a/apps/api/src/ai/__tests__/ai.controller.e2e-spec.ts b/apps/api/src/ai/__tests__/ai.controller.e2e-spec.ts
index 2f23218224..399dc31873 100644
--- a/apps/api/src/ai/__tests__/ai.controller.e2e-spec.ts
+++ b/apps/api/src/ai/__tests__/ai.controller.e2e-spec.ts
@@ -11,6 +11,7 @@ import { DB, DB_ADMIN } from "src/storage/db/db.providers";
import {
aiJudgeConfigurations,
aiJudgeCriteria,
+ aiMentorConfigurations,
aiMentorLessons,
chapters,
courses,
@@ -79,13 +80,18 @@ describe("AiController (e2e)", () => {
const addPolishAiMentorScenario = async (aiMentorLessonId: UUIDType) => {
await db
- .update(aiMentorLessons)
+ .update(aiMentorConfigurations)
.set({
- aiMentorInstructions: setJsonbField(
- aiMentorLessons.aiMentorInstructions,
+ additionalInstructions: setJsonbField(
+ aiMentorConfigurations.additionalInstructions,
SUPPORTED_LANGUAGES.PL,
"Polish mentor instructions",
),
+ })
+ .where(eq(aiMentorConfigurations.aiMentorLessonId, aiMentorLessonId));
+ await db
+ .update(aiMentorLessons)
+ .set({
name: setJsonbField(aiMentorLessons.name, SUPPORTED_LANGUAGES.PL, "Polish mentor"),
})
.where(eq(aiMentorLessons.id, aiMentorLessonId));
@@ -97,7 +103,7 @@ describe("AiController (e2e)", () => {
.withUserSettings(db)
.create({ role: SYSTEM_ROLE_SLUGS.STUDENT });
const aiMentorLesson = await aiMentorLessonFactory.create({
- aiMentorInstructions: "English mentor instructions",
+ additionalInstructions: "English mentor instructions",
taskGoal: "English task goal",
});
const courseId = await getCourseIdForAiMentorLesson(aiMentorLesson.lessonId);
@@ -131,9 +137,9 @@ describe("AiController (e2e)", () => {
SUPPORTED_LANGUAGES.DE,
);
- expect(polishLesson.instructions).toBe("Polish mentor instructions");
+ expect(polishLesson.additionalInstructions).toBe("Polish mentor instructions");
expect(polishLesson.name).toBe("Polish mentor");
- expect(fallbackLesson.instructions).toBe("English mentor instructions");
+ expect(fallbackLesson.additionalInstructions).toBe("English mentor instructions");
expect(polishLesson.learnerFirstName).toBe(threadOwner.firstName);
});
});
diff --git a/apps/api/src/ai/__tests__/createAiMentorLesson.ts b/apps/api/src/ai/__tests__/createAiMentorLesson.ts
index e1ada1b8a0..daeb1a598a 100644
--- a/apps/api/src/ai/__tests__/createAiMentorLesson.ts
+++ b/apps/api/src/ai/__tests__/createAiMentorLesson.ts
@@ -1,10 +1,22 @@
import { faker } from "@faker-js/faker";
-import { AI_MENTOR_TTS_PRESET, AI_MENTOR_VOICE_MODE, DEFAULT_AI_MENTOR_TYPE } from "@repo/shared";
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TTS_PRESET,
+ AI_MENTOR_TYPE,
+ AI_MENTOR_VOICE_MODE,
+ SUPPORTED_LANGUAGES,
+} from "@repo/shared";
import { Factory } from "fishery";
import { buildJsonbField } from "src/common/helpers/sqlHelpers";
import { LESSON_TYPES } from "src/lesson/lesson.type";
-import { aiJudgeConfigurations, aiMentorLessons, lessons } from "src/storage/schema";
+import {
+ aiJudgeConfigurations,
+ aiMentorConfigurations,
+ aiMentorLessons,
+ aiMentorRoleplayConfigurations,
+ lessons,
+} from "src/storage/schema";
import { createChapterFactory } from "../../../test/factory/chapter.factory";
@@ -13,9 +25,9 @@ import type { DatabasePg, UUIDType } from "src/common";
export type AiMentorLessonTest = Omit<
InferSelectModel,
- "tenantId" | "aiMentorInstructions" | "name"
+ "tenantId" | "name"
> & {
- aiMentorInstructions: string;
+ additionalInstructions: string;
taskGoal: string;
name: string;
};
@@ -39,7 +51,7 @@ export const createAiMentorLessonFactory = (db: DatabasePg) => {
.values({
chapterId,
type: LESSON_TYPES.AI_MENTOR,
- title: buildJsonbField("en", faker.commerce.productName()),
+ title: buildJsonbField(SUPPORTED_LANGUAGES.EN, faker.commerce.productName()),
isExternal: true,
})
.returning();
@@ -48,24 +60,39 @@ export const createAiMentorLessonFactory = (db: DatabasePg) => {
.insert(aiMentorLessons)
.values({
lessonId: lesson.id,
- aiMentorInstructions: buildJsonbField("en", aiMentorLesson.aiMentorInstructions),
- name: buildJsonbField("en", aiMentorLesson.name),
- type: aiMentorLesson.type,
+ name: buildJsonbField(SUPPORTED_LANGUAGES.EN, aiMentorLesson.name),
voiceMode: aiMentorLesson.voiceMode,
ttsPreset: aiMentorLesson.ttsPreset,
customTtsReference: aiMentorLesson.customTtsReference,
})
.returning();
+ const [mentorConfiguration] = await db
+ .insert(aiMentorConfigurations)
+ .values({
+ aiMentorLessonId: createdAiMentorLesson.id,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ additionalInstructions: buildJsonbField(
+ SUPPORTED_LANGUAGES.EN,
+ aiMentorLesson.additionalInstructions,
+ ),
+ })
+ .returning();
+
+ await db.insert(aiMentorRoleplayConfigurations).values({
+ configurationId: mentorConfiguration.id,
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ });
+
await db.insert(aiJudgeConfigurations).values({
aiMentorLessonId: createdAiMentorLesson.id,
- taskGoal: buildJsonbField("en", aiMentorLesson.taskGoal),
+ taskGoal: buildJsonbField(SUPPORTED_LANGUAGES.EN, aiMentorLesson.taskGoal),
passingThresholdPercent: 0,
});
return {
...createdAiMentorLesson,
- aiMentorInstructions: aiMentorLesson.aiMentorInstructions,
+ additionalInstructions: aiMentorLesson.additionalInstructions,
taskGoal: aiMentorLesson.taskGoal,
name: aiMentorLesson.name,
};
@@ -76,9 +103,8 @@ export const createAiMentorLessonFactory = (db: DatabasePg) => {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
lessonId: faker.string.uuid(),
- aiMentorInstructions: faker.commerce.productDescription(),
+ additionalInstructions: faker.commerce.productDescription(),
taskGoal: faker.commerce.productDescription(),
- type: DEFAULT_AI_MENTOR_TYPE,
name: "AI Mentor",
avatarReference: null,
voiceMode: AI_MENTOR_VOICE_MODE.PRESET,
diff --git a/apps/api/src/ai/ai-prompt.types.ts b/apps/api/src/ai/ai-prompt.types.ts
deleted file mode 100644
index e262b01d81..0000000000
--- a/apps/api/src/ai/ai-prompt.types.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { AiMentorType } from "@repo/shared";
-
-export type AiMentorPromptContext = {
- title: string;
- instructions: string;
- type: AiMentorType;
- name: string;
- learnerFirstName: string;
-};
diff --git a/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.spec.ts b/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.spec.ts
index bc9f33c0f6..e32380e610 100644
--- a/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.spec.ts
+++ b/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.spec.ts
@@ -1,3 +1,9 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+ SUPPORTED_LANGUAGES,
+} from "@repo/shared";
import { Value } from "@sinclair/typebox/value";
import {
@@ -19,8 +25,15 @@ const courseId = "baeb297a-b7d0-498a-bd4d-d70afcc428f1";
const lessonContext = {
title: "Handle a difficult sales objection",
taskDescription: "Reach an agreed next step.",
- aiMentorInstructions: "Act as a skeptical buyer.",
- aiMentorType: "roleplay",
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A buyer challenges the price of the proposed solution.",
+ aiRole: "Skeptical buyer",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the proposal justifies its price.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ additionalInstructions: "Raise a credible budget objection.",
+ },
} as const;
const configuration = {
@@ -85,11 +98,58 @@ describe("AI Judge configuration generation schemas", () => {
lessonContext,
mode: "create",
brief: "Assess objection handling.",
- language: "pl",
+ language: SUPPORTED_LANGUAGES.PL,
+ }),
+ ).toBe(false);
+ });
+
+ it("accepts both structured variants and rejects the legacy flat mentor context", () => {
+ expect(
+ Value.Check(generateAiJudgeConfigurationInputSchema, {
+ courseId,
+ lessonContext: {
+ title: "Explain safe password storage",
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Teach the learner to distinguish hashing from encryption.",
+ expertise: "Application security instructor",
+ contentScope: "Password storage, salts, and adaptive password hashing.",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+ },
+ },
+ mode: "create",
+ brief: "Assess whether the learner can select a safe password-storage approach.",
+ }),
+ ).toBe(true);
+
+ expect(
+ Value.Check(generateAiJudgeConfigurationInputSchema, {
+ courseId,
+ lessonContext: {
+ title: "Handle a difficult sales objection",
+ aiMentorInstructions: "Act as a skeptical buyer.",
+ aiMentorType: AI_MENTOR_TYPE.ROLEPLAY,
+ },
+ mode: "create",
+ brief: "Assess objection handling.",
}),
).toBe(false);
});
+ it("accepts lesson context before Mentor behavior is configured", () => {
+ expect(
+ Value.Check(generateAiJudgeConfigurationInputSchema, {
+ courseId,
+ lessonContext: {
+ title: "Handle a difficult sales objection",
+ taskDescription: "Respond to the customer's concern and agree on a next step.",
+ },
+ mode: "create",
+ brief: "Assess objection handling.",
+ }),
+ ).toBe(true);
+ });
+
it("requires complete configuration context for improve requests", () => {
expect(
Value.Check(generateAiJudgeConfigurationInputSchema, {
diff --git a/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.ts b/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.ts
index d46b9f95c5..1a4a0e7c4e 100644
--- a/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.ts
+++ b/apps/api/src/ai/judge-configuration-generation/schemas/ai-judge-configuration-generation.schema.ts
@@ -1,4 +1,3 @@
-import { AI_MENTOR_TYPE } from "@repo/shared";
import { Type } from "@sinclair/typebox";
import { UUIDSchema } from "src/common";
@@ -9,6 +8,7 @@ import {
aiJudgeCriterionContentSchema,
aiJudgeScoreGuidanceContentSchema,
} from "src/lesson/ai-judge-configuration/ai-judge-configuration.schema";
+import { aiMentorConfigurationContentSchema } from "src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema";
import {
AI_JUDGE_BLOCKING_ERROR_REF_PATTERN,
@@ -26,6 +26,7 @@ import {
} from "../ai-judge-configuration-generation.types";
import type { Static } from "@sinclair/typebox";
+import type { AiMentorConfigurationContent } from "src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema";
const nonEmptyTextSchema = Type.String({ minLength: 1 });
const generatedTaskGoalSchema = Type.String({ minLength: 1 });
@@ -115,8 +116,7 @@ export const aiJudgeGenerationLessonContextSchema = Type.Object(
{
title: Type.Optional(Type.String()),
taskDescription: Type.Optional(Type.String()),
- aiMentorInstructions: Type.Optional(Type.String()),
- aiMentorType: Type.Enum(AI_MENTOR_TYPE),
+ aiMentorConfiguration: Type.Optional(aiMentorConfigurationContentSchema),
},
{ additionalProperties: false },
);
@@ -545,7 +545,11 @@ export const cancelAiJudgeGenerationResponseSchema = Type.Object(
export type ReferencedAiJudgeConfiguration = Static;
export type GeneratedAiJudgeConfiguration = Static;
-export type AiJudgeGenerationLessonContext = Static;
+export type AiJudgeGenerationLessonContext = {
+ title?: string;
+ taskDescription?: string;
+ aiMentorConfiguration?: AiMentorConfigurationContent;
+};
export type AiJudgeValidationIssue = Static;
export type AiJudgeConfigurationValidatorModelResult = Static<
typeof aiJudgeConfigurationValidatorModelResultSchema
diff --git a/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generation-workflow.service.spec.ts b/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generation-workflow.service.spec.ts
index 6914293301..6f365b104b 100644
--- a/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generation-workflow.service.spec.ts
+++ b/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generation-workflow.service.spec.ts
@@ -1,4 +1,4 @@
-import { SUPPORTED_LANGUAGES } from "@repo/shared";
+import { AI_MENTOR_ROLEPLAY_DIFFICULTY, AI_MENTOR_TYPE, SUPPORTED_LANGUAGES } from "@repo/shared";
import { AI_JUDGE_GENERATION_FAILURE_MESSAGE } from "../ai-judge-configuration-generation.constants";
@@ -19,7 +19,14 @@ jest.mock("@langfuse/tracing", () => ({
const lessonContext = {
title: "Handle a price objection",
- aiMentorType: "roleplay",
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A buyer challenges the price of the proposed solution.",
+ aiRole: "Skeptical buyer",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the proposal justifies its price.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ },
} as const;
const draft: ReferencedAiJudgeConfiguration = {
diff --git a/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generator.service.spec.ts b/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generator.service.spec.ts
index b31d08584c..286a3dc7ea 100644
--- a/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generator.service.spec.ts
+++ b/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-generator.service.spec.ts
@@ -1,4 +1,4 @@
-import { SUPPORTED_LANGUAGES } from "@repo/shared";
+import { AI_MENTOR_ROLEPLAY_DIFFICULTY, AI_MENTOR_TYPE, SUPPORTED_LANGUAGES } from "@repo/shared";
import { loadAiSdk } from "src/ai/utils/ai-esm";
@@ -17,8 +17,15 @@ jest.mock("src/ai/utils/ai-esm", () => ({ loadAiSdk: jest.fn() }));
const lessonContext = {
title: "Handle a price objection",
taskDescription: "Reach an agreed next step.",
- aiMentorInstructions: "Act as a skeptical buyer.",
- aiMentorType: "roleplay",
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A buyer challenges the price of the proposed solution.",
+ aiRole: "Skeptical buyer",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the proposal justifies its price.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ additionalInstructions: "Raise a credible budget objection.",
+ },
} as const;
const configuration: ReferencedAiJudgeConfiguration = {
diff --git a/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-validator.service.spec.ts b/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-validator.service.spec.ts
index a13949ab03..e61f69c8a8 100644
--- a/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-validator.service.spec.ts
+++ b/apps/api/src/ai/judge-configuration-generation/services/ai-judge-configuration-validator.service.spec.ts
@@ -1,4 +1,4 @@
-import { SUPPORTED_LANGUAGES } from "@repo/shared";
+import { AI_MENTOR_ROLEPLAY_DIFFICULTY, AI_MENTOR_TYPE, SUPPORTED_LANGUAGES } from "@repo/shared";
import { loadAiSdk } from "src/ai/utils/ai-esm";
@@ -19,7 +19,14 @@ jest.mock("src/ai/utils/ai-esm", () => ({ loadAiSdk: jest.fn() }));
const lessonContext = {
title: "Handle a price objection",
- aiMentorType: "roleplay",
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A buyer challenges the price of the proposed solution.",
+ aiRole: "Skeptical buyer",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the proposal justifies its price.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ },
} as const;
const configuration: ReferencedAiJudgeConfiguration = {
diff --git a/apps/api/src/ai/repositories/ai.repository.ts b/apps/api/src/ai/repositories/ai.repository.ts
index 5dda1603bc..9b69993eed 100644
--- a/apps/api/src/ai/repositories/ai.repository.ts
+++ b/apps/api/src/ai/repositories/ai.repository.ts
@@ -20,7 +20,10 @@ import {
aiMentorJudgementBlockingErrors,
aiMentorJudgementCriteria,
aiMentorJudgements,
+ aiMentorConfigurations,
aiMentorLessons,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
aiMentorThreadMessages,
aiMentorThreads,
chapters,
@@ -33,15 +36,9 @@ import {
users,
} from "src/storage/schema";
-import type {
- AiMentorTTSPreset,
- AiMentorType,
- AiMentorVoiceMode,
- SupportedLanguages,
-} from "@repo/shared";
+import type { AiMentorTTSPreset, AiMentorVoiceMode, SupportedLanguages } from "@repo/shared";
import type { SQL } from "drizzle-orm";
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
-import type { AiMentorPromptContext } from "src/ai/ai-prompt.types";
import type {
AiJudgeBlockingErrorJudgementWrite,
AiJudgeCriterionJudgementWrite,
@@ -230,23 +227,74 @@ export class AiRepository {
.returning();
}
- async findMentorLessonByThreadId(
- threadId: UUIDType,
- language: SupportedLanguages,
- ): Promise {
+ async findMentorLessonByThreadId(threadId: UUIDType, language: SupportedLanguages) {
const [lesson] = await this.db
.select({
title: this.localizationService.getLocalizedSqlField(lessons.title, language),
- instructions: this.localizationService.getLocalizedSqlField(
- aiMentorLessons.aiMentorInstructions,
+ type: aiMentorConfigurations.type,
+ openingInstruction: this.localizationService.getLocalizedSqlField(
+ aiMentorConfigurations.openingInstruction,
+ language,
+ ),
+ additionalInstructions: this.localizationService.getLocalizedSqlField(
+ aiMentorConfigurations.additionalInstructions,
+ language,
+ ),
+ taskGoal: this.localizationService.getLocalizedSqlField(
+ aiMentorTeacherConfigurations.taskGoal,
+ language,
+ ),
+ expertise: this.localizationService.getLocalizedSqlField(
+ aiMentorTeacherConfigurations.expertise,
+ language,
+ ),
+ contentScope: this.localizationService.getLocalizedSqlField(
+ aiMentorTeacherConfigurations.contentScope,
+ language,
+ ),
+ teachingStyle: aiMentorTeacherConfigurations.teachingStyle,
+ feedbackGuidance: this.localizationService.getLocalizedSqlField(
+ aiMentorTeacherConfigurations.feedbackGuidance,
+ language,
+ ),
+ scenario: this.localizationService.getLocalizedSqlField(
+ aiMentorRoleplayConfigurations.scenario,
+ language,
+ ),
+ aiRole: this.localizationService.getLocalizedSqlField(
+ aiMentorRoleplayConfigurations.aiRole,
+ language,
+ ),
+ learnerRole: this.localizationService.getLocalizedSqlField(
+ aiMentorRoleplayConfigurations.learnerRole,
+ language,
+ ),
+ characterGoal: this.localizationService.getLocalizedSqlField(
+ aiMentorRoleplayConfigurations.characterGoal,
+ language,
+ ),
+ difficulty: aiMentorRoleplayConfigurations.difficulty,
+ factsAndConstraints: this.localizationService.getLocalizedSqlField(
+ aiMentorRoleplayConfigurations.factsAndConstraints,
language,
),
- type: sql`${aiMentorLessons.type}`,
name: this.localizationService.getLocalizedSqlField(aiMentorLessons.name, language),
learnerFirstName: users.firstName,
})
.from(aiMentorThreads)
.innerJoin(aiMentorLessons, eq(aiMentorThreads.aiMentorLessonId, aiMentorLessons.id))
+ .innerJoin(
+ aiMentorConfigurations,
+ eq(aiMentorConfigurations.aiMentorLessonId, aiMentorLessons.id),
+ )
+ .leftJoin(
+ aiMentorTeacherConfigurations,
+ eq(aiMentorTeacherConfigurations.configurationId, aiMentorConfigurations.id),
+ )
+ .leftJoin(
+ aiMentorRoleplayConfigurations,
+ eq(aiMentorRoleplayConfigurations.configurationId, aiMentorConfigurations.id),
+ )
.innerJoin(users, eq(users.id, aiMentorThreads.userId))
.innerJoin(lessons, eq(lessons.id, aiMentorLessons.lessonId))
.innerJoin(chapters, eq(chapters.id, lessons.chapterId))
diff --git a/apps/api/src/ai/services/prompt.service.spec.ts b/apps/api/src/ai/services/prompt.service.spec.ts
index dfc1c24744..605ef542b1 100644
--- a/apps/api/src/ai/services/prompt.service.spec.ts
+++ b/apps/api/src/ai/services/prompt.service.spec.ts
@@ -17,10 +17,22 @@ describe("PromptService learner-name personalization", () => {
findThread: jest.fn().mockResolvedValue({ userLanguage: SUPPORTED_LANGUAGES.PL }),
findMentorLessonByThreadId: jest.fn().mockResolvedValue({
title: "Negocjacje",
- instructions: "Odegraj wymagającego klienta.",
type: AI_MENTOR_TYPE.ROLEPLAY,
name: "Klient",
learnerFirstName: "Maciej",
+ openingInstruction: null,
+ additionalInstructions: null,
+ taskGoal: null,
+ expertise: null,
+ contentScope: null,
+ teachingStyle: null,
+ feedbackGuidance: null,
+ scenario: "Rozmowa z wymagającym klientem.",
+ aiRole: "Klient",
+ learnerRole: "Sprzedawca",
+ characterGoal: "Uzyskaj lepsze warunki.",
+ difficulty: "realistic",
+ factsAndConstraints: null,
}),
findGroupsByThreadId: jest.fn().mockResolvedValue([]),
insertMessage: jest.fn().mockResolvedValue([]),
@@ -62,7 +74,9 @@ describe("PromptService learner-name personalization", () => {
expect.objectContaining({
lessonTitle: "Negocjacje",
name: "Klient",
- lessonInstructions: "Odegraj wymagającego klienta.",
+ scenario: "Rozmowa z wymagającym klientem.",
+ aiRole: "Klient",
+ learnerRole: "Sprzedawca",
}),
);
expect(prompt).toBe("ROLEPLAY_PROMPT\n\nLEARNER_NAME_RULES");
diff --git a/apps/api/src/ai/services/prompt.service.ts b/apps/api/src/ai/services/prompt.service.ts
index 951d1e68c8..b33ac3ab33 100644
--- a/apps/api/src/ai/services/prompt.service.ts
+++ b/apps/api/src/ai/services/prompt.service.ts
@@ -2,7 +2,7 @@ import { LangfuseClient } from "@langfuse/client";
import { observe } from "@langfuse/tracing";
import { BadRequestException, Injectable } from "@nestjs/common";
import { PROMPT_MAP, promptTemplates } from "@repo/prompts";
-import { DEFAULT_AI_MENTOR_TYPE } from "@repo/shared";
+import { AI_MENTOR_TYPE } from "@repo/shared";
import { Value } from "@sinclair/typebox/value";
import { eq } from "drizzle-orm";
import Handlebars from "handlebars";
@@ -144,9 +144,11 @@ export class PromptService implements OnModuleInit {
const lesson = await this.aiRepository.findMentorLessonByThreadId(data.threadId, userLanguage);
- const groups = await this.aiRepository.findGroupsByThreadId(data.threadId, userLanguage);
+ if (!lesson) {
+ throw new BadRequestException("common.error.aiMentorConfigurationIncomplete");
+ }
- const mode = (lesson.type ?? DEFAULT_AI_MENTOR_TYPE).toLowerCase();
+ const groups = await this.aiRepository.findGroupsByThreadId(data.threadId, userLanguage);
const securityAndRagBlock = await this.loadPrompt("securityAndRagBlock", {
language: userLanguage,
@@ -157,27 +159,39 @@ export class PromptService implements OnModuleInit {
language: userLanguage,
});
- let promptChoice;
-
- switch (mode) {
- case "teacher":
- promptChoice = promptTemplates.teacherPrompt.id;
- break;
- case "roleplay":
- promptChoice = promptTemplates.roleplayPrompt.id;
- break;
- case "mentor":
- default:
- promptChoice = promptTemplates.mentorPrompt.id;
- }
-
- const mentorPrompt = await this.loadPrompt(promptChoice, {
+ const commonPromptVariables = {
lessonTitle: lesson.title,
name: lesson.name,
- lessonInstructions: lesson.instructions,
+ openingInstruction: lesson.openingInstruction ?? "",
+ additionalInstructions: lesson.additionalInstructions ?? "",
groups: groups.map((group) => `${group.name}: ${group.characteristic}\n`),
- securityAndRagBlock: securityAndRagBlock,
- });
+ securityAndRagBlock,
+ };
+
+ let mentorPrompt: string;
+
+ if (lesson.type === AI_MENTOR_TYPE.TEACHER && lesson.teachingStyle) {
+ mentorPrompt = await this.loadPrompt("teacherPrompt", {
+ ...commonPromptVariables,
+ taskGoal: lesson.taskGoal,
+ expertise: lesson.expertise,
+ contentScope: lesson.contentScope,
+ teachingStyle: lesson.teachingStyle,
+ feedbackGuidance: lesson.feedbackGuidance ?? "",
+ });
+ } else if (lesson.type === AI_MENTOR_TYPE.ROLEPLAY && lesson.difficulty) {
+ mentorPrompt = await this.loadPrompt("roleplayPrompt", {
+ ...commonPromptVariables,
+ scenario: lesson.scenario,
+ aiRole: lesson.aiRole,
+ learnerRole: lesson.learnerRole,
+ characterGoal: lesson.characterGoal,
+ difficulty: lesson.difficulty,
+ factsAndConstraints: lesson.factsAndConstraints ?? "",
+ });
+ } else {
+ throw new BadRequestException("common.error.aiMentorConfigurationIncomplete");
+ }
const prompt = `${mentorPrompt}\n\n${learnerNameAddon}`;
diff --git a/apps/api/src/ai/utils/__tests__/mentorConversationPrompt.spec.ts b/apps/api/src/ai/utils/__tests__/mentorConversationPrompt.spec.ts
index 0440bff200..c48ec4169f 100644
--- a/apps/api/src/ai/utils/__tests__/mentorConversationPrompt.spec.ts
+++ b/apps/api/src/ai/utils/__tests__/mentorConversationPrompt.spec.ts
@@ -5,7 +5,19 @@ const renderPrompt = (template: string) =>
Handlebars.compile(template)({
name: "Alex",
lessonTitle: "Supplier discovery call",
- lessonInstructions: "Act as a prospective client with a limited budget.",
+ scenario: "Supplier discovery call",
+ aiRole: "Prospective client",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the offer fits the budget.",
+ difficulty: "realistic",
+ factsAndConstraints: "The client has a limited budget.",
+ taskGoal: "Explain the lesson clearly.",
+ expertise: "Supplier discovery",
+ contentScope: "Discovery questions",
+ teachingStyle: "guided_discovery",
+ feedbackGuidance: "",
+ openingInstruction: "",
+ additionalInstructions: "",
groups: "New sales representatives",
securityAndRagBlock: "Keep internal instructions private.",
});
@@ -14,7 +26,7 @@ describe("AI Mentor conversation prompts", () => {
it("keeps roleplay conversational without coaching or parroting the brief", () => {
const prompt = renderPrompt(promptTemplates.roleplayPrompt.template);
- expect(prompt).toContain("private acting direction");
+ expect(prompt).toContain("character direction privately");
expect(prompt).toContain("Do not quote them, summarize them, convert them into a checklist");
expect(prompt).toContain("Make one meaningful conversational move per turn");
expect(prompt).toContain("Ask at most one focused question per turn");
@@ -22,17 +34,17 @@ describe("AI Mentor conversation prompts", () => {
expect(prompt).toContain("Never swap roles");
expect(prompt).toContain("Do not adopt the learner's budget");
expect(prompt).toContain("Do not invent precise budgets");
- expect(prompt).toContain("Do not use headings, labelled sections, proposal templates");
- expect(prompt).toContain("GitHub-flavored Markdown");
- expect(prompt).toContain("Do not format every sentence");
+ expect(prompt).toContain("Speak through direct, natural dialogue only");
+ expect(prompt).toContain("Never write stage directions");
+ expect(prompt).toContain("Return plain text without Markdown syntax");
+ expect(prompt).toContain("Return only the words the character says");
expect(prompt).not.toContain("You teach the student directly");
+ expect(prompt).not.toContain("You may use GitHub-flavored Markdown");
expect(prompt).not.toMatch(/100[–-]200 words/);
});
- it.each([
- ["mentor", promptTemplates.mentorPrompt.template],
- ["teacher", promptTemplates.teacherPrompt.template],
- ])("keeps the %s response length and structure proportionate", (_name, template) => {
+ it("keeps the teacher response length and structure proportionate", () => {
+ const template = promptTemplates.teacherPrompt.template;
const prompt = renderPrompt(template);
expect(prompt).toMatch(/Do not (?:begin by restating|repeat)/);
diff --git a/apps/api/src/chapter/repositories/adminChapter.repository.ts b/apps/api/src/chapter/repositories/adminChapter.repository.ts
index 60087d8f2d..e9d3244e6c 100644
--- a/apps/api/src/chapter/repositories/adminChapter.repository.ts
+++ b/apps/api/src/chapter/repositories/adminChapter.repository.ts
@@ -190,11 +190,6 @@ export class AdminChapterRepository {
SELECT json_build_object(
'id', ${aiMentorLessons.id},
'lessonId', ${aiMentorLessons.lessonId},
- 'aiMentorInstructions', ${this.localizationService.getFieldByLanguage(
- aiMentorLessons.aiMentorInstructions,
- language,
- )},
- 'type', ${aiMentorLessons.type},
'name', ${this.localizationService.getFieldByLanguage(aiMentorLessons.name, language)},
'avatarReference', ${aiMentorLessons.avatarReference},
'voiceMode', ${aiMentorLessons.voiceMode},
diff --git a/apps/api/src/courses/__tests__/master-course.e2e-spec.ts b/apps/api/src/courses/__tests__/master-course.e2e-spec.ts
index b42284cee3..5541d6da29 100644
--- a/apps/api/src/courses/__tests__/master-course.e2e-spec.ts
+++ b/apps/api/src/courses/__tests__/master-course.e2e-spec.ts
@@ -1,7 +1,12 @@
import { Readable } from "stream";
import { faker } from "@faker-js/faker";
-import { LESSON_TYPES, SYSTEM_ROLE_SLUGS } from "@repo/shared";
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TYPE,
+ LESSON_TYPES,
+ SYSTEM_ROLE_SLUGS,
+} from "@repo/shared";
import { and, asc, eq, inArray } from "drizzle-orm";
import request from "supertest";
@@ -18,7 +23,9 @@ import {
aiJudgeConfigurations,
aiJudgeCriteria,
aiJudgeScoreGuidance,
+ aiMentorConfigurations,
aiMentorLessons,
+ aiMentorRoleplayConfigurations,
categories,
chapters,
courses,
@@ -914,12 +921,25 @@ describe("Master course export and sync (e2e)", () => {
.insert(aiMentorLessons)
.values({
lessonId: sourceLessonId,
- aiMentorInstructions: buildJsonbFieldWithMultipleEntries({
+ })
+ .returning({ id: aiMentorLessons.id });
+
+ const [sourceMentorConfiguration] = await db
+ .insert(aiMentorConfigurations)
+ .values({
+ aiMentorLessonId: sourceAiMentor.id,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ additionalInstructions: buildJsonbFieldWithMultipleEntries({
en: "Run a discovery conversation",
pl: "Przeprowadz rozmowe discovery",
}),
})
- .returning({ id: aiMentorLessons.id });
+ .returning({ id: aiMentorConfigurations.id });
+
+ await db.insert(aiMentorRoleplayConfigurations).values({
+ configurationId: sourceMentorConfiguration.id,
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ });
const [sourceConfiguration] = await db
.insert(aiJudgeConfigurations)
diff --git a/apps/api/src/courses/course.service.ts b/apps/api/src/courses/course.service.ts
index 2258c8062c..b338a5bb72 100644
--- a/apps/api/src/courses/course.service.ts
+++ b/apps/api/src/courses/course.service.ts
@@ -79,11 +79,11 @@ import { SEARCH_ENTITY_TYPES } from "src/global-search/global-search.constants";
import { SearchIndexService } from "src/global-search/search-index.service";
import { LearningTimeRepository } from "src/learning-time";
import { AiJudgeConfigurationTranslationService } from "src/lesson/ai-judge-configuration/ai-judge-configuration-translation.service";
+import { AiMentorLessonTranslationService } from "src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service";
import { createLessonResourceIdRegex } from "src/lesson/lesson-resource-references";
import { LESSON_TYPES } from "src/lesson/lesson.type";
import { LessonRepository } from "src/lesson/repositories/lesson.repository";
import { AdminLessonService } from "src/lesson/services/adminLesson.service";
-import { AiMentorLessonTranslationService } from "src/lesson/services/aiMentorLessonTranslation.service";
import { LocalizationService } from "src/localization/localization.service";
import { ENTITY_TYPE } from "src/localization/localization.types";
import { LumaService } from "src/luma/luma.service";
@@ -101,7 +101,10 @@ import {
coursesSummaryStats,
groups,
groupUsers,
+ aiMentorConfigurations,
aiMentorLessons,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
lessonLearningTime,
lessons,
questionAnswerOptions,
@@ -1578,14 +1581,20 @@ export class CourseService {
if (hasMissingCourseFields) return true;
- const missingJudgeFields =
- await this.aiJudgeConfigurationTranslationService.getMissingTranslations(
+ const [missingMentorFields, missingJudgeFields] = await Promise.all([
+ this.aiMentorLessonTranslationService.getMissingTranslations(
id,
language,
courseInRequestedLanguage.baseLanguage,
- );
+ ),
+ this.aiJudgeConfigurationTranslationService.getMissingTranslations(
+ id,
+ language,
+ courseInRequestedLanguage.baseLanguage,
+ ),
+ ]);
- return missingJudgeFields.length > 0;
+ return missingMentorFields.length > 0 || missingJudgeFields.length > 0;
}
async getContentCreatorCourses({
@@ -4631,9 +4640,58 @@ export class CourseService {
.update(aiMentorLessons)
.set({
name: deleteJsonbField(aiMentorLessons.name, language),
- aiMentorInstructions: deleteJsonbField(aiMentorLessons.aiMentorInstructions, language),
})
.where(inArray(aiMentorLessons.lessonId, lessonIds));
+
+ const aiMentorConfigurationIds = trx
+ .select({ id: aiMentorConfigurations.id })
+ .from(aiMentorConfigurations)
+ .innerJoin(
+ aiMentorLessons,
+ eq(aiMentorLessons.id, aiMentorConfigurations.aiMentorLessonId),
+ )
+ .where(inArray(aiMentorLessons.lessonId, lessonIds));
+
+ await trx
+ .update(aiMentorConfigurations)
+ .set({
+ openingInstruction: deleteJsonbField(
+ aiMentorConfigurations.openingInstruction,
+ language,
+ ),
+ additionalInstructions: deleteJsonbField(
+ aiMentorConfigurations.additionalInstructions,
+ language,
+ ),
+ })
+ .where(inArray(aiMentorConfigurations.id, aiMentorConfigurationIds));
+
+ await trx
+ .update(aiMentorTeacherConfigurations)
+ .set({
+ taskGoal: deleteJsonbField(aiMentorTeacherConfigurations.taskGoal, language),
+ expertise: deleteJsonbField(aiMentorTeacherConfigurations.expertise, language),
+ contentScope: deleteJsonbField(aiMentorTeacherConfigurations.contentScope, language),
+ feedbackGuidance: deleteJsonbField(
+ aiMentorTeacherConfigurations.feedbackGuidance,
+ language,
+ ),
+ })
+ .where(inArray(aiMentorTeacherConfigurations.configurationId, aiMentorConfigurationIds));
+
+ await trx
+ .update(aiMentorRoleplayConfigurations)
+ .set({
+ scenario: deleteJsonbField(aiMentorRoleplayConfigurations.scenario, language),
+ aiRole: deleteJsonbField(aiMentorRoleplayConfigurations.aiRole, language),
+ learnerRole: deleteJsonbField(aiMentorRoleplayConfigurations.learnerRole, language),
+ characterGoal: deleteJsonbField(aiMentorRoleplayConfigurations.characterGoal, language),
+ factsAndConstraints: deleteJsonbField(
+ aiMentorRoleplayConfigurations.factsAndConstraints,
+ language,
+ ),
+ })
+ .where(inArray(aiMentorRoleplayConfigurations.configurationId, aiMentorConfigurationIds));
}
if (questionIds.length) {
@@ -5213,14 +5271,6 @@ export class CourseService {
field: aiMentorLessons.name,
idColumn: aiMentorLessons.lessonId,
};
-
- yield {
- id: lesson.id,
- hasValue: Boolean(lesson.aiMentor?.aiMentorInstructions?.length),
- baseValue: baseLesson?.aiMentor?.aiMentorInstructions,
- field: aiMentorLessons.aiMentorInstructions,
- idColumn: aiMentorLessons.lessonId,
- };
}
if (lesson.type !== LESSON_TYPES.QUIZ || !lesson.questions?.length) continue;
diff --git a/apps/api/src/courses/master-course-snapshot.service.ts b/apps/api/src/courses/master-course-snapshot.service.ts
index 12a8ab35ef..f409bb213d 100644
--- a/apps/api/src/courses/master-course-snapshot.service.ts
+++ b/apps/api/src/courses/master-course-snapshot.service.ts
@@ -29,6 +29,20 @@ export class MasterCourseSnapshotService {
const optionRows = await this.masterCourseRepository.getSourceOptions(questionIds);
const aiMentorRows = await this.masterCourseRepository.getSourceAiMentors(lessonIds);
const aiMentorIds = aiMentorRows.map((row) => row.id);
+ const aiMentorConfigurationRows =
+ await this.masterCourseRepository.getSourceAiMentorConfigurations(aiMentorIds);
+ const aiMentorConfigurationIds = aiMentorConfigurationRows.map((row) => row.id);
+ const [aiMentorTeacherConfigurationRows, aiMentorRoleplayConfigurationRows] =
+ aiMentorConfigurationIds.length
+ ? await Promise.all([
+ this.masterCourseRepository.getSourceAiMentorTeacherConfigurations(
+ aiMentorConfigurationIds,
+ ),
+ this.masterCourseRepository.getSourceAiMentorRoleplayConfigurations(
+ aiMentorConfigurationIds,
+ ),
+ ])
+ : [[], []];
let aiJudgeConfigurationRows: SourceSnapshot["aiJudgeConfigurations"] = [];
if (aiMentorIds.length)
aiJudgeConfigurationRows =
@@ -83,6 +97,9 @@ export class MasterCourseSnapshotService {
questions: questionRows,
options: optionRows,
aiMentors: aiMentorRows,
+ aiMentorConfigurations: aiMentorConfigurationRows,
+ aiMentorTeacherConfigurations: aiMentorTeacherConfigurationRows,
+ aiMentorRoleplayConfigurations: aiMentorRoleplayConfigurationRows,
aiJudgeConfigurations: aiJudgeConfigurationRows,
aiJudgeCriteria: aiJudgeCriterionRows,
aiJudgeScoreGuidance: aiJudgeScoreGuidanceRows,
diff --git a/apps/api/src/courses/master-course.repository.ts b/apps/api/src/courses/master-course.repository.ts
index d557ade8bc..3c2ff0ea12 100644
--- a/apps/api/src/courses/master-course.repository.ts
+++ b/apps/api/src/courses/master-course.repository.ts
@@ -19,7 +19,10 @@ import {
aiJudgeConfigurations,
aiJudgeCriteria,
aiJudgeScoreGuidance,
+ aiMentorConfigurations,
aiMentorLessons,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
categories,
chapters,
courses,
@@ -41,6 +44,9 @@ import {
} from "src/storage/schema";
import type {
+ AiMentorConfigurationInsert,
+ AiMentorRoleplayConfigurationInsert,
+ AiMentorTeacherConfigurationInsert,
AiJudgeBlockingErrorJsonbInsert,
AiJudgeConfigurationJsonbInsert,
AiJudgeConfigurationJsonbUpdate,
@@ -384,6 +390,29 @@ export class MasterCourseRepository {
.where(inArray(aiMentorLessons.lessonId, lessonIds));
}
+ async getSourceAiMentorConfigurations(aiMentorLessonIds: UUIDType[]) {
+ if (!aiMentorLessonIds.length) return [];
+
+ return this.db
+ .select()
+ .from(aiMentorConfigurations)
+ .where(inArray(aiMentorConfigurations.aiMentorLessonId, aiMentorLessonIds));
+ }
+
+ async getSourceAiMentorTeacherConfigurations(configurationIds: UUIDType[]) {
+ return this.db
+ .select()
+ .from(aiMentorTeacherConfigurations)
+ .where(inArray(aiMentorTeacherConfigurations.configurationId, configurationIds));
+ }
+
+ async getSourceAiMentorRoleplayConfigurations(configurationIds: UUIDType[]) {
+ return this.db
+ .select()
+ .from(aiMentorRoleplayConfigurations)
+ .where(inArray(aiMentorRoleplayConfigurations.configurationId, configurationIds));
+ }
+
async getSourceAiJudgeConfigurations(aiMentorLessonIds: UUIDType[]) {
return this.db
.select()
@@ -675,6 +704,65 @@ export class MasterCourseRepository {
await this.db.update(aiMentorLessons).set(values).where(eq(aiMentorLessons.id, aiMentorId));
}
+ async findAiMentorConfigurationByAiMentorLessonId(
+ aiMentorLessonId: UUIDType,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .select({ id: aiMentorConfigurations.id })
+ .from(aiMentorConfigurations)
+ .where(eq(aiMentorConfigurations.aiMentorLessonId, aiMentorLessonId))
+ .limit(1);
+
+ return configuration;
+ }
+
+ async createAiMentorConfiguration(
+ values: AiMentorConfigurationInsert,
+ dbInstance: DatabasePg,
+ ): Promise {
+ const [configuration] = await dbInstance
+ .insert(aiMentorConfigurations)
+ .values(values)
+ .returning({ id: aiMentorConfigurations.id });
+
+ return configuration.id;
+ }
+
+ async updateAiMentorConfiguration(
+ configurationId: UUIDType,
+ values: Partial,
+ dbInstance: DatabasePg,
+ ) {
+ await dbInstance
+ .update(aiMentorConfigurations)
+ .set(values)
+ .where(eq(aiMentorConfigurations.id, configurationId));
+ }
+
+ async replaceAiMentorConfigurationSubtype(
+ configurationId: UUIDType,
+ teacher: Omit | null,
+ roleplay: Omit | null,
+ dbInstance: DatabasePg,
+ ) {
+ await dbInstance
+ .delete(aiMentorTeacherConfigurations)
+ .where(eq(aiMentorTeacherConfigurations.configurationId, configurationId));
+ await dbInstance
+ .delete(aiMentorRoleplayConfigurations)
+ .where(eq(aiMentorRoleplayConfigurations.configurationId, configurationId));
+
+ if (teacher)
+ await dbInstance
+ .insert(aiMentorTeacherConfigurations)
+ .values({ ...teacher, configurationId });
+ if (roleplay)
+ await dbInstance
+ .insert(aiMentorRoleplayConfigurations)
+ .values({ ...roleplay, configurationId });
+ }
+
async findAiJudgeConfigurationByAiMentorLessonId(
aiMentorLessonId: UUIDType,
dbInstance: DatabasePg,
diff --git a/apps/api/src/courses/master-course.service.ts b/apps/api/src/courses/master-course.service.ts
index 6e7f515864..fc07797224 100644
--- a/apps/api/src/courses/master-course.service.ts
+++ b/apps/api/src/courses/master-course.service.ts
@@ -10,6 +10,7 @@ import {
NotFoundException,
} from "@nestjs/common";
import {
+ AI_MENTOR_TYPE,
COURSE_ORIGIN_TYPES,
ENTITY_TYPES,
LESSON_TYPES,
@@ -326,6 +327,7 @@ export class MasterCourseService {
});
await this.syncAiJudgeConfigurations(sourceSnapshot, aiMentorMap);
+ await this.syncAiMentorConfigurations(sourceSnapshot, aiMentorMap);
await this.syncAiMentorContexts(sourceSnapshot, aiMentorMap, params.tenantId);
await this.syncScormPackages({
exportId: params.targetCourseId,
@@ -637,6 +639,7 @@ export class MasterCourseService {
resourceCollection,
});
await this.syncAiJudgeConfigurations(sourceSnapshot, aiMentorMap);
+ await this.syncAiMentorConfigurations(sourceSnapshot, aiMentorMap);
await this.syncAiMentorContexts(sourceSnapshot, aiMentorMap, exportLink.targetTenantId);
await this.syncScormPackages({
exportId: exportLink.id,
@@ -1218,10 +1221,8 @@ export class MasterCourseService {
if (!existingAiMentor) {
const targetAiMentorId = await this.masterCourseRepository.createAiMentor({
lessonId: mappedLessonId,
- aiMentorInstructions: sourceAiMentor.aiMentorInstructions,
name: sourceAiMentor.name,
avatarReference,
- type: sourceAiMentor.type,
voiceMode: sourceAiMentor.voiceMode,
ttsPreset: sourceAiMentor.ttsPreset,
customTtsReference,
@@ -1231,10 +1232,8 @@ export class MasterCourseService {
}
await this.masterCourseRepository.updateAiMentor(existingAiMentor.id, {
- aiMentorInstructions: sourceAiMentor.aiMentorInstructions,
name: sourceAiMentor.name,
avatarReference,
- type: sourceAiMentor.type,
voiceMode: sourceAiMentor.voiceMode,
ttsPreset: sourceAiMentor.ttsPreset,
customTtsReference,
@@ -1245,6 +1244,87 @@ export class MasterCourseService {
return aiMentorMap;
}
+ private async syncAiMentorConfigurations(
+ sourceSnapshot: SourceSnapshot,
+ aiMentorMap: Map,
+ ) {
+ const teacherByConfigurationId = new Map(
+ sourceSnapshot.aiMentorTeacherConfigurations.map((configuration) => [
+ configuration.configurationId,
+ configuration,
+ ]),
+ );
+ const roleplayByConfigurationId = new Map(
+ sourceSnapshot.aiMentorRoleplayConfigurations.map((configuration) => [
+ configuration.configurationId,
+ configuration,
+ ]),
+ );
+
+ for (const sourceConfiguration of sourceSnapshot.aiMentorConfigurations) {
+ const targetAiMentorLessonId = aiMentorMap.get(sourceConfiguration.aiMentorLessonId);
+ if (!targetAiMentorLessonId) continue;
+
+ await this.db.transaction(async (transaction) => {
+ const existingConfiguration =
+ await this.masterCourseRepository.findAiMentorConfigurationByAiMentorLessonId(
+ targetAiMentorLessonId,
+ transaction,
+ );
+ const rootValues = this.omitCopiedRowFields(sourceConfiguration, [
+ "id",
+ "createdAt",
+ "updatedAt",
+ "tenantId",
+ "aiMentorLessonId",
+ ] as const);
+ const targetConfigurationId = existingConfiguration
+ ? existingConfiguration.id
+ : await this.masterCourseRepository.createAiMentorConfiguration(
+ { ...rootValues, aiMentorLessonId: targetAiMentorLessonId },
+ transaction,
+ );
+
+ if (existingConfiguration)
+ await this.masterCourseRepository.updateAiMentorConfiguration(
+ targetConfigurationId,
+ rootValues,
+ transaction,
+ );
+
+ const sourceTeacher = teacherByConfigurationId.get(sourceConfiguration.id);
+ const sourceRoleplay = roleplayByConfigurationId.get(sourceConfiguration.id);
+ const teacher =
+ sourceConfiguration.type === AI_MENTOR_TYPE.TEACHER && sourceTeacher
+ ? this.omitCopiedRowFields(sourceTeacher, [
+ "id",
+ "createdAt",
+ "updatedAt",
+ "tenantId",
+ "configurationId",
+ ] as const)
+ : null;
+ const roleplay =
+ sourceConfiguration.type === AI_MENTOR_TYPE.ROLEPLAY && sourceRoleplay
+ ? this.omitCopiedRowFields(sourceRoleplay, [
+ "id",
+ "createdAt",
+ "updatedAt",
+ "tenantId",
+ "configurationId",
+ ] as const)
+ : null;
+
+ await this.masterCourseRepository.replaceAiMentorConfigurationSubtype(
+ targetConfigurationId,
+ teacher,
+ roleplay,
+ transaction,
+ );
+ });
+ }
+ }
+
private async syncAiJudgeConfigurations(
sourceSnapshot: SourceSnapshot,
aiMentorMap: Map,
diff --git a/apps/api/src/courses/types/master-course.types.ts b/apps/api/src/courses/types/master-course.types.ts
index df4e5acd23..6ac59b6ce4 100644
--- a/apps/api/src/courses/types/master-course.types.ts
+++ b/apps/api/src/courses/types/master-course.types.ts
@@ -8,7 +8,10 @@ import type {
aiJudgeConfigurations,
aiJudgeCriteria,
aiJudgeScoreGuidance,
+ aiMentorConfigurations,
aiMentorLessons,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
categories,
chapters,
courses,
@@ -183,6 +186,20 @@ export type QuestionAnswerOptionJsonbUpdate = Partial<
export type AiMentorLessonSelect = InferSelectModel;
export type AiMentorLessonInsert = InferInsertModel;
+export type AiMentorConfigurationSelect = InferSelectModel;
+export type AiMentorConfigurationInsert = InferInsertModel;
+export type AiMentorTeacherConfigurationSelect = InferSelectModel<
+ typeof aiMentorTeacherConfigurations
+>;
+export type AiMentorTeacherConfigurationInsert = InferInsertModel<
+ typeof aiMentorTeacherConfigurations
+>;
+export type AiMentorRoleplayConfigurationSelect = InferSelectModel<
+ typeof aiMentorRoleplayConfigurations
+>;
+export type AiMentorRoleplayConfigurationInsert = InferInsertModel<
+ typeof aiMentorRoleplayConfigurations
+>;
export type AiJudgeConfigurationSelect = InferSelectModel;
export type AiJudgeConfigurationInsert = InferInsertModel;
@@ -250,6 +267,9 @@ export type SourceSnapshot = {
questions: Array;
options: Array;
aiMentors: Array;
+ aiMentorConfigurations: Array;
+ aiMentorTeacherConfigurations: Array;
+ aiMentorRoleplayConfigurations: Array;
aiJudgeConfigurations: Array;
aiJudgeCriteria: Array;
aiJudgeScoreGuidance: Array;
diff --git a/apps/api/src/lesson/__tests__/lesson.controller.e2e-spec.ts b/apps/api/src/lesson/__tests__/lesson.controller.e2e-spec.ts
index 53da49d878..a5575ce36f 100644
--- a/apps/api/src/lesson/__tests__/lesson.controller.e2e-spec.ts
+++ b/apps/api/src/lesson/__tests__/lesson.controller.e2e-spec.ts
@@ -1,6 +1,7 @@
import { Readable } from "stream";
import {
+ AI_MENTOR_TEACHING_STYLE,
AI_MENTOR_TYPE,
COURSE_ENROLLMENT,
ENTITY_TYPES,
@@ -23,6 +24,7 @@ import { QUESTION_TYPE } from "src/questions/schema/question.types";
import { DB, DB_ADMIN } from "src/storage/db/db.providers";
import {
aiJudgeConfigurations,
+ aiMentorConfigurations,
aiMentorLessons,
chapters,
courses,
@@ -327,6 +329,35 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
});
describe("AI mentor lesson translations", () => {
+ const teacherConfiguration = (additionalInstructions: string) => ({
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Guide the learner through the practice",
+ expertise: "Sales negotiation",
+ contentScope: "Discovery and objection handling",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+ additionalInstructions,
+ });
+
+ const translateTeacherConfiguration = async (
+ lessonId: UUIDType,
+ cookies: Awaited>,
+ additionalInstructions: string,
+ ) => {
+ await request(app.getHttpServer())
+ .patch(
+ `/api/lesson/${lessonId}/ai-mentor-configuration/translations/${SUPPORTED_LANGUAGES.PL}`,
+ )
+ .set("Cookie", cookies)
+ .send({
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Przeprowadź ucznia przez ćwiczenie",
+ expertise: "Negocjacje sprzedażowe",
+ contentScope: "Badanie potrzeb i obiekcje",
+ additionalInstructions,
+ })
+ .expect(200);
+ };
+
const createAiMentorLessonSetup = async (
availableLocales: SupportedLanguages[] = [SUPPORTED_LANGUAGES.EN, SUPPORTED_LANGUAGES.PL],
) => {
@@ -352,14 +383,15 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
title: "Negotiation practice",
description: "Practice a sales call.
",
chapterId: chapter.id,
- aiMentorInstructions: "Lead the learner through an English scenario.
",
+ aiMentorConfiguration: teacherConfiguration(
+ "Lead the learner through an English scenario.
",
+ ),
aiJudgeConfiguration: {
taskGoal: "Complete the negotiation practice",
passingThresholdPercent: 0,
criteria: [],
blockingErrors: [],
},
- type: AI_MENTOR_TYPE.MENTOR,
name: "AI Mentor",
})
.expect(201);
@@ -411,8 +443,9 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
title: "Negotiation practice",
description: "Practice a sales call.
",
chapterId: chapter.id,
- aiMentorInstructions: "Lead the learner through the scenario.
",
- type: AI_MENTOR_TYPE.MENTOR,
+ aiMentorConfiguration: teacherConfiguration(
+ "Lead the learner through the scenario.
",
+ ),
aiJudgeConfiguration: {
taskGoal: "Handle a sales objection and agree a next step",
passingThresholdPercent: 70,
@@ -487,8 +520,9 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
title: "Negotiation practice",
description: "Practice a sales call.
",
chapterId: chapter.id,
- aiMentorInstructions: "Lead the learner through the scenario.
",
- type: AI_MENTOR_TYPE.ROLEPLAY,
+ aiMentorConfiguration: teacherConfiguration(
+ "Lead the learner through the scenario.
",
+ ),
})
.expect(400);
});
@@ -663,13 +697,17 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
.send({
title: "Polish negotiation practice",
description: "Practice a Polish sales call.
",
- aiMentorInstructions: "Lead the learner through a Polish scenario.
",
- type: AI_MENTOR_TYPE.MENTOR,
name: "Mentor PL",
language: SUPPORTED_LANGUAGES.PL,
})
.expect(200);
+ await translateTeacherConfiguration(
+ lessonId,
+ adminCookies,
+ "Lead the learner through a Polish scenario.
",
+ );
+
const englishAiMentor = await getAiMentorFromCourse(
courseId,
lessonId,
@@ -685,12 +723,19 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
expect(englishAiMentor).toMatchObject({
name: "AI Mentor",
- aiMentorInstructions: "Lead the learner through an English scenario.
",
});
expect(polishAiMentor).toMatchObject({
name: "Mentor PL",
- aiMentorInstructions: "Lead the learner through a Polish scenario.
",
});
+
+ const polishConfiguration = await request(app.getHttpServer())
+ .get(`/api/lesson/${lessonId}/ai-mentor-configuration`)
+ .query({ language: SUPPORTED_LANGUAGES.PL })
+ .set("Cookie", adminCookies)
+ .expect(200);
+ expect(polishConfiguration.body.data.additionalInstructions).toBe(
+ "Lead the learner through a Polish scenario.
",
+ );
});
it("falls back to base-language AI mentor scenario fields on the learner endpoint", async () => {
@@ -719,7 +764,6 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
expect(response.body.data).toMatchObject({
aiMentor: { name: "AI Mentor" },
- aiMentorInstructions: "Lead the learner through an English scenario.
",
});
});
@@ -765,12 +809,16 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
.send({
title: "Polish negotiation practice",
description: "Practice a Polish sales call.
",
- aiMentorInstructions: "Lead the learner through a Polish scenario.
",
- type: AI_MENTOR_TYPE.MENTOR,
language: SUPPORTED_LANGUAGES.PL,
})
.expect(200);
+ await translateTeacherConfiguration(
+ lessonId,
+ adminCookies,
+ "Lead the learner through a Polish scenario.
",
+ );
+
const missingResponse = await request(app.getHttpServer())
.get("/api/course/beta-course-missing-translations")
.query({ id: courseId, language: SUPPORTED_LANGUAGES.PL })
@@ -805,13 +853,17 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
.send({
title: "Polish negotiation practice",
description: "Practice a Polish sales call.
",
- aiMentorInstructions: "Lead the learner through a Polish scenario.
",
- type: AI_MENTOR_TYPE.MENTOR,
name: "Mentor PL",
language: SUPPORTED_LANGUAGES.PL,
})
.expect(200);
+ await translateTeacherConfiguration(
+ lessonId,
+ adminCookies,
+ "Lead the learner through a Polish scenario.
",
+ );
+
await request(app.getHttpServer())
.delete(`/api/course/language/${courseId}`)
.query({ language: SUPPORTED_LANGUAGES.PL })
@@ -821,13 +873,17 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
const [aiMentorLesson] = await db
.select({
name: aiMentorLessons.name,
- aiMentorInstructions: aiMentorLessons.aiMentorInstructions,
})
.from(aiMentorLessons)
.where(eq(aiMentorLessons.lessonId, lessonId));
expect(aiMentorLesson.name).toEqual({ en: "AI Mentor" });
- expect(aiMentorLesson.aiMentorInstructions).toEqual({
+ const [configuration] = await db
+ .select({ additionalInstructions: aiMentorConfigurations.additionalInstructions })
+ .from(aiMentorConfigurations)
+ .innerJoin(aiMentorLessons, eq(aiMentorLessons.id, aiMentorConfigurations.aiMentorLessonId))
+ .where(eq(aiMentorLessons.lessonId, lessonId));
+ expect(configuration.additionalInstructions).toEqual({
en: "Lead the learner through an English scenario.
",
});
});
@@ -842,8 +898,6 @@ describe("LessonController (e2e) - quiz feedback redaction", () => {
.send({
title: "German negotiation practice",
description: "Practice a German sales call.
",
- aiMentorInstructions: "Lead the learner through a German scenario.
",
- type: AI_MENTOR_TYPE.MENTOR,
name: "AI Mentor",
language: SUPPORTED_LANGUAGES.DE,
})
diff --git a/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation-queue.service.spec.ts b/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation-queue.service.spec.ts
index f34950b172..d2bda6510c 100644
--- a/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation-queue.service.spec.ts
+++ b/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation-queue.service.spec.ts
@@ -1,5 +1,10 @@
import { NotFoundException } from "@nestjs/common";
-import { AI_JUDGE_CONFIGURATION_GENERATION_SOCKET_EVENTS } from "@repo/shared";
+import {
+ AI_JUDGE_CONFIGURATION_GENERATION_SOCKET_EVENTS,
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TYPE,
+ SUPPORTED_LANGUAGES,
+} from "@repo/shared";
import { v5 as uuidv5 } from "uuid";
import { AI_JUDGE_GENERATION_STATUS } from "src/ai/judge-configuration-generation/ai-judge-configuration-generation.types";
@@ -28,11 +33,21 @@ const currentUser = {
permissions: [],
roleSlugs: [],
};
+const lessonContext = {
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A buyer challenges the price of the proposed solution.",
+ aiRole: "Skeptical buyer",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the proposal justifies its price.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ },
+} as const;
const prepared = {
workflowInput: {
mode: "create",
- language: "en",
- lessonContext: { aiMentorType: "roleplay" },
+ language: SUPPORTED_LANGUAGES.EN,
+ lessonContext,
brief: "Assess discovery skills.",
},
identities: { criteria: [], blockingErrors: [] },
@@ -42,7 +57,7 @@ const prepared = {
const input = {
courseId: "00000000-0000-4000-8000-000000000004",
mode: "create",
- lessonContext: { aiMentorType: "roleplay" },
+ lessonContext,
brief: "Assess discovery skills.",
} as const;
const generatedConfiguration = {
diff --git a/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation.service.spec.ts b/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation.service.spec.ts
index 1e10d01b21..4eac3feb93 100644
--- a/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation.service.spec.ts
+++ b/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-generation.service.spec.ts
@@ -1,4 +1,4 @@
-import { AI_MENTOR_TYPE, SUPPORTED_LANGUAGES } from "@repo/shared";
+import { AI_MENTOR_ROLEPLAY_DIFFICULTY, AI_MENTOR_TYPE, SUPPORTED_LANGUAGES } from "@repo/shared";
import { AI_JUDGE_GENERATION_STATUS } from "src/ai/judge-configuration-generation/ai-judge-configuration-generation.types";
@@ -24,7 +24,14 @@ const blockingErrorId = "00000000-0000-4000-8000-000000000006" as UUIDType;
const currentUser = {} as CurrentUserType;
const lessonContext = {
title: "Handle a price objection",
- aiMentorType: AI_MENTOR_TYPE.ROLEPLAY,
+ aiMentorConfiguration: {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A buyer challenges the price of the proposed solution.",
+ aiRole: "Skeptical buyer",
+ learnerRole: "Sales representative",
+ characterGoal: "Understand whether the proposal justifies its price.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ },
};
const passedValidation: AiJudgeConfigurationValidationResult = {
passed: true,
diff --git a/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-translation.service.ts b/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-translation.service.ts
index 3bd1a210a3..92ee5d157a 100644
--- a/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-translation.service.ts
+++ b/apps/api/src/lesson/ai-judge-configuration/ai-judge-configuration-translation.service.ts
@@ -1,5 +1,6 @@
import { Injectable } from "@nestjs/common";
+import { getExactLocalizedText } from "src/localization/localization.utils";
import {
aiJudgeBlockingErrors,
aiJudgeConfigurations,
@@ -39,8 +40,8 @@ export class AiJudgeConfigurationTranslationService {
];
return localizedValues.some((value) => {
- const base = this.getLanguageValue(value, baseLanguage);
- const translated = this.getLanguageValue(value, language);
+ const base = getExactLocalizedText(value, baseLanguage);
+ const translated = getExactLocalizedText(value, language);
return Boolean(base?.length && !translated?.length);
});
@@ -76,9 +77,9 @@ export class AiJudgeConfigurationTranslationService {
...criteria.flatMap((criterion) => {
const context = {
...this.getContext(criterion, baseLanguage),
- aiJudgeTaskGoal: this.getLanguageValue(criterion.taskGoal, baseLanguage),
- aiJudgeCriterionTitle: this.getLanguageValue(criterion.title, baseLanguage),
- aiJudgeExpectedBehavior: this.getLanguageValue(criterion.expectedBehavior, baseLanguage),
+ aiJudgeTaskGoal: getExactLocalizedText(criterion.taskGoal, baseLanguage),
+ aiJudgeCriterionTitle: getExactLocalizedText(criterion.title, baseLanguage),
+ aiJudgeExpectedBehavior: getExactLocalizedText(criterion.expectedBehavior, baseLanguage),
};
return [
@@ -111,9 +112,9 @@ export class AiJudgeConfigurationTranslationService {
...scoreGuidance.flatMap((guidance) => {
const context = {
...this.getContext(guidance, baseLanguage),
- aiJudgeTaskGoal: this.getLanguageValue(guidance.taskGoal, baseLanguage),
- aiJudgeCriterionTitle: this.getLanguageValue(guidance.criterionTitle, baseLanguage),
- aiJudgeExpectedBehavior: this.getLanguageValue(
+ aiJudgeTaskGoal: getExactLocalizedText(guidance.taskGoal, baseLanguage),
+ aiJudgeCriterionTitle: getExactLocalizedText(guidance.criterionTitle, baseLanguage),
+ aiJudgeExpectedBehavior: getExactLocalizedText(
guidance.criterionExpectedBehavior,
baseLanguage,
),
@@ -157,7 +158,7 @@ export class AiJudgeConfigurationTranslationService {
metadata: "AI Judge blocking error",
context: {
...this.getContext(blockingError, baseLanguage),
- aiJudgeTaskGoal: this.getLanguageValue(blockingError.taskGoal, baseLanguage),
+ aiJudgeTaskGoal: getExactLocalizedText(blockingError.taskGoal, baseLanguage),
},
},
language,
@@ -172,8 +173,8 @@ export class AiJudgeConfigurationTranslationService {
language: SupportedLanguages,
baseLanguage: SupportedLanguages,
): ContextualCourseTranslationType[] {
- const base = this.getLanguageValue(input.source, baseLanguage);
- const translated = this.getLanguageValue(input.source, language);
+ const base = getExactLocalizedText(input.source, baseLanguage);
+ const translated = getExactLocalizedText(input.source, language);
if (!base?.length || translated?.length) return [];
@@ -200,13 +201,9 @@ export class AiJudgeConfigurationTranslationService {
baseLanguage: SupportedLanguages,
): CourseTranslationContext {
return {
- courseTitle: this.getLanguageValue(value.courseTitle, baseLanguage),
- lessonTitle: this.getLanguageValue(value.lessonTitle, baseLanguage),
- lessonDescription: this.getLanguageValue(value.lessonDescription, baseLanguage),
+ courseTitle: getExactLocalizedText(value.courseTitle, baseLanguage),
+ lessonTitle: getExactLocalizedText(value.lessonTitle, baseLanguage),
+ lessonDescription: getExactLocalizedText(value.lessonDescription, baseLanguage),
};
}
-
- private getLanguageValue(value: LocalizedText | null, language: SupportedLanguages) {
- return value?.[language];
- }
}
diff --git a/apps/api/src/lesson/ai-mentor-configuration/controllers/ai-mentor-configuration.controller.ts b/apps/api/src/lesson/ai-mentor-configuration/controllers/ai-mentor-configuration.controller.ts
new file mode 100644
index 0000000000..b7c7bac22f
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/controllers/ai-mentor-configuration.controller.ts
@@ -0,0 +1,92 @@
+import { Body, Controller, Get, Param, Patch, Put, Query } from "@nestjs/common";
+import { PERMISSIONS, SupportedLanguages } from "@repo/shared";
+import { Type } from "@sinclair/typebox";
+import { Validate } from "nestjs-typebox";
+
+import { BaseResponse, UUIDSchema, UUIDType, baseResponse } from "src/common";
+import { RequirePermission } from "src/common/decorators/require-permission.decorator";
+import { CurrentUser } from "src/common/decorators/user.decorator";
+import { CurrentUserType } from "src/common/types/current-user.type";
+import { supportedLanguagesSchema } from "src/courses/schemas/course.schema";
+
+import {
+ AiMentorConfigurationContent,
+ UpdateAiMentorConfigurationTranslationBody,
+ aiMentorConfigurationContentSchema,
+ aiMentorConfigurationResponseSchema,
+ updateAiMentorConfigurationTranslationSchema,
+} from "../schemas/ai-mentor-configuration.schema";
+import { AiMentorConfigurationService } from "../services/ai-mentor-configuration.service";
+
+import type { AiMentorConfigurationResponse } from "../schemas/ai-mentor-configuration.schema";
+
+@Controller("lesson/:lessonId/ai-mentor-configuration")
+@RequirePermission(PERMISSIONS.COURSE_UPDATE, PERMISSIONS.COURSE_UPDATE_OWN)
+export class AiMentorConfigurationController {
+ constructor(private readonly aiMentorConfigurationService: AiMentorConfigurationService) {}
+
+ @Get()
+ @Validate({
+ request: [
+ { type: "param", name: "lessonId", schema: UUIDSchema },
+ {
+ type: "query",
+ name: "language",
+ schema: Type.Optional(supportedLanguagesSchema),
+ },
+ ],
+ response: baseResponse(aiMentorConfigurationResponseSchema),
+ })
+ async getAiMentorConfiguration(
+ @Param("lessonId") lessonId: UUIDType,
+ @Query("language") language: SupportedLanguages | undefined,
+ @CurrentUser() currentUser: CurrentUserType,
+ ): Promise> {
+ return new BaseResponse(
+ await this.aiMentorConfigurationService.getConfiguration(lessonId, currentUser, language),
+ );
+ }
+
+ @Put()
+ @Validate({
+ request: [
+ { type: "param", name: "lessonId", schema: UUIDSchema },
+ { type: "body", schema: aiMentorConfigurationContentSchema },
+ ],
+ response: baseResponse(aiMentorConfigurationResponseSchema),
+ })
+ async replaceAiMentorConfiguration(
+ @Param("lessonId") lessonId: UUIDType,
+ @Body() body: AiMentorConfigurationContent,
+ @CurrentUser() currentUser: CurrentUserType,
+ ): Promise> {
+ return new BaseResponse(
+ await this.aiMentorConfigurationService.replaceConfiguration(lessonId, body, currentUser),
+ );
+ }
+
+ @Patch("translations/:language")
+ @Validate({
+ request: [
+ { type: "param", name: "lessonId", schema: UUIDSchema },
+ { type: "param", name: "language", schema: supportedLanguagesSchema },
+ { type: "body", schema: updateAiMentorConfigurationTranslationSchema },
+ ],
+ response: baseResponse(aiMentorConfigurationResponseSchema),
+ })
+ async updateAiMentorConfigurationTranslations(
+ @Param("lessonId") lessonId: UUIDType,
+ @Param("language") language: SupportedLanguages,
+ @Body() body: UpdateAiMentorConfigurationTranslationBody,
+ @CurrentUser() currentUser: CurrentUserType,
+ ): Promise> {
+ return new BaseResponse(
+ await this.aiMentorConfigurationService.updateTranslations(
+ lessonId,
+ language,
+ body,
+ currentUser,
+ ),
+ );
+ }
+}
diff --git a/apps/api/src/lesson/ai-mentor-configuration/repositories/ai-mentor-configuration.repository.ts b/apps/api/src/lesson/ai-mentor-configuration/repositories/ai-mentor-configuration.repository.ts
new file mode 100644
index 0000000000..ed60f06495
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/repositories/ai-mentor-configuration.repository.ts
@@ -0,0 +1,408 @@
+import { Inject, Injectable } from "@nestjs/common";
+import { eq } from "drizzle-orm";
+
+import { DatabasePg, type UUIDType } from "src/common";
+import { buildJsonbField, deleteJsonbField, setJsonbField } from "src/common/helpers/sqlHelpers";
+import { DB } from "src/storage/db/db.providers";
+import {
+ aiMentorConfigurations,
+ aiMentorLessons,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
+ chapters,
+ courses,
+ lessons,
+} from "src/storage/schema";
+
+import type {
+ AiMentorConfigurationContent,
+ AiMentorRoleplayConfigurationContent,
+ AiMentorTeacherConfigurationContent,
+ UpdateAiMentorConfigurationTranslationBody,
+ UpdateAiMentorRoleplayConfigurationTranslationBody,
+ UpdateAiMentorTeacherConfigurationTranslationBody,
+} from "../schemas/ai-mentor-configuration.schema";
+import type { AiMentorConfigurationLessonContext } from "../types/ai-mentor-configuration.types";
+import type { SupportedLanguages } from "@repo/shared";
+
+@Injectable()
+export class AiMentorConfigurationRepository {
+ constructor(@Inject(DB) private readonly db: DatabasePg) {}
+
+ async findLessonContext(
+ lessonId: UUIDType,
+ dbInstance: DatabasePg = this.db,
+ ): Promise {
+ const [context] = await dbInstance
+ .select({
+ courseId: courses.id,
+ lessonId: lessons.id,
+ lessonType: lessons.type,
+ aiMentorLessonId: aiMentorLessons.id,
+ configurationId: aiMentorConfigurations.id,
+ configurationType: aiMentorConfigurations.type,
+ baseLanguage: courses.baseLanguage,
+ availableLocales: courses.availableLocales,
+ })
+ .from(lessons)
+ .innerJoin(chapters, eq(chapters.id, lessons.chapterId))
+ .innerJoin(courses, eq(courses.id, chapters.courseId))
+ .leftJoin(aiMentorLessons, eq(aiMentorLessons.lessonId, lessons.id))
+ .leftJoin(
+ aiMentorConfigurations,
+ eq(aiMentorConfigurations.aiMentorLessonId, aiMentorLessons.id),
+ )
+ .where(eq(lessons.id, lessonId));
+
+ return context;
+ }
+
+ async findConfigurationRoot(configurationId: UUIDType, dbInstance: DatabasePg = this.db) {
+ const [configuration] = await dbInstance
+ .select()
+ .from(aiMentorConfigurations)
+ .where(eq(aiMentorConfigurations.id, configurationId));
+
+ return configuration;
+ }
+
+ async findTeacherConfiguration(configurationId: UUIDType, dbInstance: DatabasePg = this.db) {
+ const [configuration] = await dbInstance
+ .select()
+ .from(aiMentorTeacherConfigurations)
+ .where(eq(aiMentorTeacherConfigurations.configurationId, configurationId));
+
+ return configuration;
+ }
+
+ async findRoleplayConfiguration(configurationId: UUIDType, dbInstance: DatabasePg = this.db) {
+ const [configuration] = await dbInstance
+ .select()
+ .from(aiMentorRoleplayConfigurations)
+ .where(eq(aiMentorRoleplayConfigurations.configurationId, configurationId));
+
+ return configuration;
+ }
+
+ async getConfigurationsForCourse(courseId: UUIDType) {
+ return this.db
+ .select({
+ configurationId: aiMentorConfigurations.id,
+ type: aiMentorConfigurations.type,
+ openingInstruction: aiMentorConfigurations.openingInstruction,
+ additionalInstructions: aiMentorConfigurations.additionalInstructions,
+ teacherConfigurationId: aiMentorTeacherConfigurations.id,
+ taskGoal: aiMentorTeacherConfigurations.taskGoal,
+ expertise: aiMentorTeacherConfigurations.expertise,
+ contentScope: aiMentorTeacherConfigurations.contentScope,
+ feedbackGuidance: aiMentorTeacherConfigurations.feedbackGuidance,
+ roleplayConfigurationId: aiMentorRoleplayConfigurations.id,
+ scenario: aiMentorRoleplayConfigurations.scenario,
+ aiRole: aiMentorRoleplayConfigurations.aiRole,
+ learnerRole: aiMentorRoleplayConfigurations.learnerRole,
+ characterGoal: aiMentorRoleplayConfigurations.characterGoal,
+ factsAndConstraints: aiMentorRoleplayConfigurations.factsAndConstraints,
+ courseTitle: courses.title,
+ lessonTitle: lessons.title,
+ lessonDescription: lessons.description,
+ })
+ .from(aiMentorConfigurations)
+ .innerJoin(aiMentorLessons, eq(aiMentorLessons.id, aiMentorConfigurations.aiMentorLessonId))
+ .innerJoin(lessons, eq(lessons.id, aiMentorLessons.lessonId))
+ .innerJoin(chapters, eq(chapters.id, lessons.chapterId))
+ .innerJoin(courses, eq(courses.id, chapters.courseId))
+ .leftJoin(
+ aiMentorTeacherConfigurations,
+ eq(aiMentorTeacherConfigurations.configurationId, aiMentorConfigurations.id),
+ )
+ .leftJoin(
+ aiMentorRoleplayConfigurations,
+ eq(aiMentorRoleplayConfigurations.configurationId, aiMentorConfigurations.id),
+ )
+ .where(eq(courses.id, courseId));
+ }
+
+ async createConfigurationRoot(
+ aiMentorLessonId: UUIDType,
+ data: AiMentorConfigurationContent,
+ language: SupportedLanguages,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .insert(aiMentorConfigurations)
+ .values({
+ aiMentorLessonId,
+ type: data.type,
+ openingInstruction: buildJsonbField(language, data.openingInstruction),
+ additionalInstructions: buildJsonbField(language, data.additionalInstructions),
+ })
+ .returning();
+
+ return configuration;
+ }
+
+ async createTeacherConfiguration(
+ configurationId: UUIDType,
+ data: AiMentorTeacherConfigurationContent,
+ language: SupportedLanguages,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .insert(aiMentorTeacherConfigurations)
+ .values({
+ configurationId,
+ taskGoal: buildJsonbField(language, data.taskGoal),
+ expertise: buildJsonbField(language, data.expertise),
+ contentScope: buildJsonbField(language, data.contentScope),
+ teachingStyle: data.teachingStyle,
+ feedbackGuidance: buildJsonbField(language, data.feedbackGuidance),
+ })
+ .returning();
+
+ return configuration;
+ }
+
+ async createRoleplayConfiguration(
+ configurationId: UUIDType,
+ data: AiMentorRoleplayConfigurationContent,
+ language: SupportedLanguages,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .insert(aiMentorRoleplayConfigurations)
+ .values({
+ configurationId,
+ scenario: buildJsonbField(language, data.scenario),
+ aiRole: buildJsonbField(language, data.aiRole),
+ learnerRole: buildJsonbField(language, data.learnerRole),
+ characterGoal: buildJsonbField(language, data.characterGoal),
+ difficulty: data.difficulty,
+ factsAndConstraints: buildJsonbField(language, data.factsAndConstraints),
+ })
+ .returning();
+
+ return configuration;
+ }
+
+ async updateConfigurationRoot(
+ configurationId: UUIDType,
+ data: AiMentorConfigurationContent,
+ language: SupportedLanguages,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .update(aiMentorConfigurations)
+ .set({
+ type: data.type,
+ openingInstruction: this.replaceLocalizedValue(
+ aiMentorConfigurations.openingInstruction,
+ language,
+ data.openingInstruction,
+ ),
+ additionalInstructions: this.replaceLocalizedValue(
+ aiMentorConfigurations.additionalInstructions,
+ language,
+ data.additionalInstructions,
+ ),
+ })
+ .where(eq(aiMentorConfigurations.id, configurationId))
+ .returning();
+
+ return configuration;
+ }
+
+ async updateTeacherConfiguration(
+ configurationId: UUIDType,
+ data: AiMentorTeacherConfigurationContent,
+ language: SupportedLanguages,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .update(aiMentorTeacherConfigurations)
+ .set({
+ taskGoal: setJsonbField(aiMentorTeacherConfigurations.taskGoal, language, data.taskGoal),
+ expertise: setJsonbField(aiMentorTeacherConfigurations.expertise, language, data.expertise),
+ contentScope: setJsonbField(
+ aiMentorTeacherConfigurations.contentScope,
+ language,
+ data.contentScope,
+ ),
+ teachingStyle: data.teachingStyle,
+ feedbackGuidance: this.replaceLocalizedValue(
+ aiMentorTeacherConfigurations.feedbackGuidance,
+ language,
+ data.feedbackGuidance,
+ ),
+ })
+ .where(eq(aiMentorTeacherConfigurations.configurationId, configurationId))
+ .returning();
+
+ return configuration;
+ }
+
+ async updateRoleplayConfiguration(
+ configurationId: UUIDType,
+ data: AiMentorRoleplayConfigurationContent,
+ language: SupportedLanguages,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .update(aiMentorRoleplayConfigurations)
+ .set({
+ scenario: setJsonbField(aiMentorRoleplayConfigurations.scenario, language, data.scenario),
+ aiRole: setJsonbField(aiMentorRoleplayConfigurations.aiRole, language, data.aiRole),
+ learnerRole: setJsonbField(
+ aiMentorRoleplayConfigurations.learnerRole,
+ language,
+ data.learnerRole,
+ ),
+ characterGoal: setJsonbField(
+ aiMentorRoleplayConfigurations.characterGoal,
+ language,
+ data.characterGoal,
+ ),
+ difficulty: data.difficulty,
+ factsAndConstraints: this.replaceLocalizedValue(
+ aiMentorRoleplayConfigurations.factsAndConstraints,
+ language,
+ data.factsAndConstraints,
+ ),
+ })
+ .where(eq(aiMentorRoleplayConfigurations.configurationId, configurationId))
+ .returning();
+
+ return configuration;
+ }
+
+ async updateConfigurationRootTranslations(
+ configurationId: UUIDType,
+ language: SupportedLanguages,
+ data: UpdateAiMentorConfigurationTranslationBody,
+ dbInstance: DatabasePg,
+ ) {
+ await dbInstance
+ .update(aiMentorConfigurations)
+ .set({
+ openingInstruction: this.patchLocalizedValue(
+ aiMentorConfigurations.openingInstruction,
+ language,
+ data.openingInstruction,
+ ),
+ additionalInstructions: this.patchLocalizedValue(
+ aiMentorConfigurations.additionalInstructions,
+ language,
+ data.additionalInstructions,
+ ),
+ })
+ .where(eq(aiMentorConfigurations.id, configurationId));
+ }
+
+ async updateTeacherConfigurationTranslations(
+ configurationId: UUIDType,
+ language: SupportedLanguages,
+ data: UpdateAiMentorTeacherConfigurationTranslationBody,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .update(aiMentorTeacherConfigurations)
+ .set({
+ taskGoal: this.patchLocalizedValue(
+ aiMentorTeacherConfigurations.taskGoal,
+ language,
+ data.taskGoal,
+ ),
+ expertise: this.patchLocalizedValue(
+ aiMentorTeacherConfigurations.expertise,
+ language,
+ data.expertise,
+ ),
+ contentScope: this.patchLocalizedValue(
+ aiMentorTeacherConfigurations.contentScope,
+ language,
+ data.contentScope,
+ ),
+ feedbackGuidance: this.patchLocalizedValue(
+ aiMentorTeacherConfigurations.feedbackGuidance,
+ language,
+ data.feedbackGuidance,
+ ),
+ })
+ .where(eq(aiMentorTeacherConfigurations.configurationId, configurationId))
+ .returning();
+
+ return configuration;
+ }
+
+ async updateRoleplayConfigurationTranslations(
+ configurationId: UUIDType,
+ language: SupportedLanguages,
+ data: UpdateAiMentorRoleplayConfigurationTranslationBody,
+ dbInstance: DatabasePg,
+ ) {
+ const [configuration] = await dbInstance
+ .update(aiMentorRoleplayConfigurations)
+ .set({
+ scenario: this.patchLocalizedValue(
+ aiMentorRoleplayConfigurations.scenario,
+ language,
+ data.scenario,
+ ),
+ aiRole: this.patchLocalizedValue(
+ aiMentorRoleplayConfigurations.aiRole,
+ language,
+ data.aiRole,
+ ),
+ learnerRole: this.patchLocalizedValue(
+ aiMentorRoleplayConfigurations.learnerRole,
+ language,
+ data.learnerRole,
+ ),
+ characterGoal: this.patchLocalizedValue(
+ aiMentorRoleplayConfigurations.characterGoal,
+ language,
+ data.characterGoal,
+ ),
+ factsAndConstraints: this.patchLocalizedValue(
+ aiMentorRoleplayConfigurations.factsAndConstraints,
+ language,
+ data.factsAndConstraints,
+ ),
+ })
+ .where(eq(aiMentorRoleplayConfigurations.configurationId, configurationId))
+ .returning();
+
+ return configuration;
+ }
+
+ async deleteTeacherConfiguration(configurationId: UUIDType, dbInstance: DatabasePg) {
+ await dbInstance
+ .delete(aiMentorTeacherConfigurations)
+ .where(eq(aiMentorTeacherConfigurations.configurationId, configurationId));
+ }
+
+ async deleteRoleplayConfiguration(configurationId: UUIDType, dbInstance: DatabasePg) {
+ await dbInstance
+ .delete(aiMentorRoleplayConfigurations)
+ .where(eq(aiMentorRoleplayConfigurations.configurationId, configurationId));
+ }
+
+ private replaceLocalizedValue(
+ field: Parameters[0],
+ language: SupportedLanguages,
+ value: string | null | undefined,
+ ) {
+ return value ? setJsonbField(field, language, value) : deleteJsonbField(field, language);
+ }
+
+ private patchLocalizedValue(
+ field: Parameters[0],
+ language: SupportedLanguages,
+ value: string | null | undefined,
+ ) {
+ if (value === undefined) return undefined;
+
+ return value === null
+ ? deleteJsonbField(field, language)
+ : setJsonbField(field, language, value);
+ }
+}
diff --git a/apps/api/src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema.spec.ts b/apps/api/src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema.spec.ts
new file mode 100644
index 0000000000..349e7226b8
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema.spec.ts
@@ -0,0 +1,92 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+import { Value } from "@sinclair/typebox/value";
+
+import {
+ aiMentorConfigurationContentSchema,
+ updateAiMentorConfigurationTranslationSchema,
+} from "./ai-mentor-configuration.schema";
+
+const teacherConfiguration = {
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Help the learner explain the policy.",
+ expertise: "Compliance trainer",
+ contentScope: "Use the attached policy and avoid legal advice.",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+};
+
+const roleplayConfiguration = {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "The learner responds to a customer complaint.",
+ aiRole: "An unhappy customer",
+ learnerRole: "Customer support specialist",
+ characterGoal: "Receive a credible resolution and next step.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+};
+
+describe("AI Mentor configuration schemas", () => {
+ it("accepts complete Teacher and Roleplay configurations", () => {
+ expect(Value.Check(aiMentorConfigurationContentSchema, teacherConfiguration)).toBe(true);
+ expect(Value.Check(aiMentorConfigurationContentSchema, roleplayConfiguration)).toBe(true);
+ });
+
+ it("rejects mixed and legacy Mentor configurations", () => {
+ expect(
+ Value.Check(aiMentorConfigurationContentSchema, {
+ ...teacherConfiguration,
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.CHALLENGING,
+ }),
+ ).toBe(false);
+ expect(
+ Value.Check(aiMentorConfigurationContentSchema, {
+ ...roleplayConfiguration,
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.SOCRATIC,
+ }),
+ ).toBe(false);
+ expect(
+ Value.Check(aiMentorConfigurationContentSchema, {
+ ...teacherConfiguration,
+ type: "mentor",
+ }),
+ ).toBe(false);
+ });
+
+ it("requires non-empty core fields", () => {
+ expect(
+ Value.Check(aiMentorConfigurationContentSchema, {
+ ...teacherConfiguration,
+ taskGoal: "",
+ }),
+ ).toBe(false);
+ expect(
+ Value.Check(aiMentorConfigurationContentSchema, {
+ ...roleplayConfiguration,
+ learnerRole: "",
+ }),
+ ).toBe(false);
+ });
+
+ it("accepts only text fields matching the translation subtype", () => {
+ expect(
+ Value.Check(updateAiMentorConfigurationTranslationSchema, {
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Wyjaśnij zasady.",
+ feedbackGuidance: null,
+ }),
+ ).toBe(true);
+ expect(
+ Value.Check(updateAiMentorConfigurationTranslationSchema, {
+ type: AI_MENTOR_TYPE.TEACHER,
+ scenario: "Rozmowa z klientem.",
+ }),
+ ).toBe(false);
+ expect(
+ Value.Check(updateAiMentorConfigurationTranslationSchema, {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ }),
+ ).toBe(false);
+ });
+});
diff --git a/apps/api/src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema.ts b/apps/api/src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema.ts
new file mode 100644
index 0000000000..64d95c0693
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/schemas/ai-mentor-configuration.schema.ts
@@ -0,0 +1,228 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+import { Type } from "@sinclair/typebox";
+
+import { UUIDSchema } from "src/common";
+import { supportedLanguagesSchema } from "src/courses/schemas/course.schema";
+
+import type {
+ AiMentorRoleplayDifficulty,
+ AiMentorTeachingStyle,
+ SupportedLanguages,
+} from "@repo/shared";
+import type { UUIDType } from "src/common";
+
+const nonEmptyTextSchema = Type.String({ minLength: 1 });
+const optionalTextSchema = Type.Optional(Type.Union([nonEmptyTextSchema, Type.Null()]));
+
+const commonContentProperties = {
+ openingInstruction: optionalTextSchema,
+ additionalInstructions: optionalTextSchema,
+};
+
+export const aiMentorTeacherConfigurationContentSchema = Type.Object(
+ {
+ type: Type.Literal(AI_MENTOR_TYPE.TEACHER),
+ taskGoal: nonEmptyTextSchema,
+ expertise: nonEmptyTextSchema,
+ contentScope: nonEmptyTextSchema,
+ teachingStyle: Type.Enum(AI_MENTOR_TEACHING_STYLE),
+ feedbackGuidance: optionalTextSchema,
+ ...commonContentProperties,
+ },
+ { additionalProperties: false },
+);
+
+export const aiMentorRoleplayConfigurationContentSchema = Type.Object(
+ {
+ type: Type.Literal(AI_MENTOR_TYPE.ROLEPLAY),
+ scenario: nonEmptyTextSchema,
+ aiRole: nonEmptyTextSchema,
+ learnerRole: nonEmptyTextSchema,
+ characterGoal: nonEmptyTextSchema,
+ difficulty: Type.Enum(AI_MENTOR_ROLEPLAY_DIFFICULTY),
+ factsAndConstraints: optionalTextSchema,
+ ...commonContentProperties,
+ },
+ { additionalProperties: false },
+);
+
+export const aiMentorConfigurationContentSchema = Type.Union([
+ aiMentorTeacherConfigurationContentSchema,
+ aiMentorRoleplayConfigurationContentSchema,
+]);
+
+const responseMetadataProperties = {
+ id: UUIDSchema,
+ aiMentorLessonId: UUIDSchema,
+ needsConfiguration: Type.Boolean(),
+ hasMissingTranslations: Type.Boolean(),
+ language: supportedLanguagesSchema,
+ baseLanguage: supportedLanguagesSchema,
+ availableLocales: Type.Array(supportedLanguagesSchema),
+};
+
+export const aiMentorTeacherConfigurationResponseSchema = Type.Object(
+ {
+ ...responseMetadataProperties,
+ type: Type.Literal(AI_MENTOR_TYPE.TEACHER),
+ taskGoal: Type.String(),
+ expertise: Type.String(),
+ contentScope: Type.String(),
+ teachingStyle: Type.Enum(AI_MENTOR_TEACHING_STYLE),
+ feedbackGuidance: Type.Union([Type.String(), Type.Null()]),
+ openingInstruction: Type.Union([Type.String(), Type.Null()]),
+ additionalInstructions: Type.Union([Type.String(), Type.Null()]),
+ },
+ { additionalProperties: false },
+);
+
+export const aiMentorRoleplayConfigurationResponseSchema = Type.Object(
+ {
+ ...responseMetadataProperties,
+ type: Type.Literal(AI_MENTOR_TYPE.ROLEPLAY),
+ scenario: Type.String(),
+ aiRole: Type.String(),
+ learnerRole: Type.String(),
+ characterGoal: Type.String(),
+ difficulty: Type.Enum(AI_MENTOR_ROLEPLAY_DIFFICULTY),
+ factsAndConstraints: Type.Union([Type.String(), Type.Null()]),
+ openingInstruction: Type.Union([Type.String(), Type.Null()]),
+ additionalInstructions: Type.Union([Type.String(), Type.Null()]),
+ },
+ { additionalProperties: false },
+);
+
+export const aiMentorConfigurationResponseSchema = Type.Union([
+ aiMentorTeacherConfigurationResponseSchema,
+ aiMentorRoleplayConfigurationResponseSchema,
+]);
+
+const teacherTranslationProperties = {
+ taskGoal: Type.Optional(nonEmptyTextSchema),
+ expertise: Type.Optional(nonEmptyTextSchema),
+ contentScope: Type.Optional(nonEmptyTextSchema),
+ feedbackGuidance: optionalTextSchema,
+ openingInstruction: optionalTextSchema,
+ additionalInstructions: optionalTextSchema,
+};
+
+const roleplayTranslationProperties = {
+ scenario: Type.Optional(nonEmptyTextSchema),
+ aiRole: Type.Optional(nonEmptyTextSchema),
+ learnerRole: Type.Optional(nonEmptyTextSchema),
+ characterGoal: Type.Optional(nonEmptyTextSchema),
+ factsAndConstraints: optionalTextSchema,
+ openingInstruction: optionalTextSchema,
+ additionalInstructions: optionalTextSchema,
+};
+
+export const updateAiMentorTeacherConfigurationTranslationSchema = Type.Object(
+ {
+ type: Type.Literal(AI_MENTOR_TYPE.TEACHER),
+ ...teacherTranslationProperties,
+ },
+ { additionalProperties: false, minProperties: 2 },
+);
+
+export const updateAiMentorRoleplayConfigurationTranslationSchema = Type.Object(
+ {
+ type: Type.Literal(AI_MENTOR_TYPE.ROLEPLAY),
+ ...roleplayTranslationProperties,
+ },
+ { additionalProperties: false, minProperties: 2 },
+);
+
+export const updateAiMentorConfigurationTranslationSchema = Type.Union([
+ updateAiMentorTeacherConfigurationTranslationSchema,
+ updateAiMentorRoleplayConfigurationTranslationSchema,
+]);
+
+type AiMentorCommonConfigurationContent = {
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+};
+
+export type AiMentorTeacherConfigurationContent = AiMentorCommonConfigurationContent & {
+ type: typeof AI_MENTOR_TYPE.TEACHER;
+ taskGoal: string;
+ expertise: string;
+ contentScope: string;
+ teachingStyle: AiMentorTeachingStyle;
+ feedbackGuidance?: string | null;
+};
+
+export type AiMentorRoleplayConfigurationContent = AiMentorCommonConfigurationContent & {
+ type: typeof AI_MENTOR_TYPE.ROLEPLAY;
+ scenario: string;
+ aiRole: string;
+ learnerRole: string;
+ characterGoal: string;
+ difficulty: AiMentorRoleplayDifficulty;
+ factsAndConstraints?: string | null;
+};
+
+export type AiMentorConfigurationContent =
+ | AiMentorTeacherConfigurationContent
+ | AiMentorRoleplayConfigurationContent;
+
+type AiMentorConfigurationResponseMetadata = {
+ id: UUIDType;
+ aiMentorLessonId: UUIDType;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ language: SupportedLanguages;
+ baseLanguage: SupportedLanguages;
+ availableLocales: SupportedLanguages[];
+};
+
+export type AiMentorConfigurationResponse = AiMentorConfigurationResponseMetadata &
+ (
+ | {
+ type: typeof AI_MENTOR_TYPE.TEACHER;
+ taskGoal: string;
+ expertise: string;
+ contentScope: string;
+ teachingStyle: AiMentorTeachingStyle;
+ feedbackGuidance: string | null;
+ }
+ | {
+ type: typeof AI_MENTOR_TYPE.ROLEPLAY;
+ scenario: string;
+ aiRole: string;
+ learnerRole: string;
+ characterGoal: string;
+ difficulty: AiMentorRoleplayDifficulty;
+ factsAndConstraints: string | null;
+ }
+ );
+
+export type UpdateAiMentorTeacherConfigurationTranslationBody = {
+ type: typeof AI_MENTOR_TYPE.TEACHER;
+ taskGoal?: string;
+ expertise?: string;
+ contentScope?: string;
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+};
+
+export type UpdateAiMentorRoleplayConfigurationTranslationBody = {
+ type: typeof AI_MENTOR_TYPE.ROLEPLAY;
+ scenario?: string;
+ aiRole?: string;
+ learnerRole?: string;
+ characterGoal?: string;
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+};
+
+export type UpdateAiMentorConfigurationTranslationBody =
+ | UpdateAiMentorTeacherConfigurationTranslationBody
+ | UpdateAiMentorRoleplayConfigurationTranslationBody;
diff --git a/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service.spec.ts b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service.spec.ts
new file mode 100644
index 0000000000..6521815afa
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service.spec.ts
@@ -0,0 +1,68 @@
+import { BadRequestException } from "@nestjs/common";
+import { AI_MENTOR_TYPE } from "@repo/shared";
+
+import { AiMentorConfigurationGraphService } from "./ai-mentor-configuration-graph.service";
+
+import type { AiMentorConfigurationRepository } from "../repositories/ai-mentor-configuration.repository";
+import type { DatabasePg, UUIDType } from "src/common";
+
+describe("AiMentorConfigurationGraphService", () => {
+ const configurationId = "00000000-0000-4000-8000-000000000001" as UUIDType;
+ const aiMentorConfigurationRepository = {
+ findConfigurationRoot: jest.fn(),
+ findTeacherConfiguration: jest.fn(),
+ findRoleplayConfiguration: jest.fn(),
+ };
+ const service = new AiMentorConfigurationGraphService(
+ {} as DatabasePg,
+ aiMentorConfigurationRepository as unknown as AiMentorConfigurationRepository,
+ );
+
+ beforeEach(() => {
+ jest.resetAllMocks();
+ });
+
+ it("loads only the Teacher subtype selected by the root", async () => {
+ const configuration = { id: configurationId, type: AI_MENTOR_TYPE.TEACHER };
+ const teacherConfiguration = { configurationId };
+ aiMentorConfigurationRepository.findConfigurationRoot.mockResolvedValue(configuration);
+ aiMentorConfigurationRepository.findTeacherConfiguration.mockResolvedValue(
+ teacherConfiguration,
+ );
+
+ await expect(service.getValidatedGraph(configurationId)).resolves.toEqual({
+ configuration,
+ teacherConfiguration,
+ roleplayConfiguration: null,
+ });
+ expect(aiMentorConfigurationRepository.findRoleplayConfiguration).not.toHaveBeenCalled();
+ });
+
+ it("loads only the Roleplay subtype selected by the root", async () => {
+ const configuration = { id: configurationId, type: AI_MENTOR_TYPE.ROLEPLAY };
+ const roleplayConfiguration = { configurationId };
+ aiMentorConfigurationRepository.findConfigurationRoot.mockResolvedValue(configuration);
+ aiMentorConfigurationRepository.findRoleplayConfiguration.mockResolvedValue(
+ roleplayConfiguration,
+ );
+
+ await expect(service.getValidatedGraph(configurationId)).resolves.toEqual({
+ configuration,
+ teacherConfiguration: null,
+ roleplayConfiguration,
+ });
+ expect(aiMentorConfigurationRepository.findTeacherConfiguration).not.toHaveBeenCalled();
+ });
+
+ it("rejects a root without its selected subtype", async () => {
+ aiMentorConfigurationRepository.findConfigurationRoot.mockResolvedValue({
+ id: configurationId,
+ type: AI_MENTOR_TYPE.TEACHER,
+ });
+ aiMentorConfigurationRepository.findTeacherConfiguration.mockResolvedValue(undefined);
+
+ await expect(service.getValidatedGraph(configurationId)).rejects.toEqual(
+ new BadRequestException("aiMentorConfiguration.errors.invalidGraph"),
+ );
+ });
+});
diff --git a/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service.ts b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service.ts
new file mode 100644
index 0000000000..0fe4bb77f8
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service.ts
@@ -0,0 +1,224 @@
+import { BadRequestException, Inject, Injectable, NotFoundException } from "@nestjs/common";
+import { AI_MENTOR_TYPE } from "@repo/shared";
+
+import { DatabasePg, type UUIDType } from "src/common";
+import { DB } from "src/storage/db/db.providers";
+
+import { AiMentorConfigurationRepository } from "../repositories/ai-mentor-configuration.repository";
+
+import type {
+ AiMentorConfigurationContent,
+ UpdateAiMentorConfigurationTranslationBody,
+} from "../schemas/ai-mentor-configuration.schema";
+import type { AiMentorConfigurationGraph } from "../types/ai-mentor-configuration.types";
+import type { SupportedLanguages } from "@repo/shared";
+
+@Injectable()
+export class AiMentorConfigurationGraphService {
+ constructor(
+ @Inject(DB) private readonly db: DatabasePg,
+ private readonly aiMentorConfigurationRepository: AiMentorConfigurationRepository,
+ ) {}
+
+ async createConfiguration(
+ aiMentorLessonId: UUIDType,
+ data: AiMentorConfigurationContent,
+ baseLanguage: SupportedLanguages,
+ ): Promise {
+ return this.db.transaction((transaction) =>
+ this.createConfigurationInTransaction(aiMentorLessonId, data, baseLanguage, transaction),
+ );
+ }
+
+ async createConfigurationInTransaction(
+ aiMentorLessonId: UUIDType,
+ data: AiMentorConfigurationContent,
+ baseLanguage: SupportedLanguages,
+ transaction: DatabasePg,
+ ): Promise {
+ const root = await this.aiMentorConfigurationRepository.createConfigurationRoot(
+ aiMentorLessonId,
+ data,
+ baseLanguage,
+ transaction,
+ );
+
+ await this.createSubtype(root.id, data, baseLanguage, transaction);
+
+ return root.id;
+ }
+
+ async replaceConfiguration(
+ configurationId: UUIDType,
+ data: AiMentorConfigurationContent,
+ baseLanguage: SupportedLanguages,
+ ): Promise {
+ return this.db.transaction(async (transaction) => {
+ const existingGraph = await this.getValidatedGraph(configurationId, transaction);
+
+ await this.aiMentorConfigurationRepository.updateConfigurationRoot(
+ configurationId,
+ data,
+ baseLanguage,
+ transaction,
+ );
+
+ if (existingGraph.configuration.type === data.type)
+ await this.updateMatchingSubtype(configurationId, data, baseLanguage, transaction);
+ else {
+ await this.aiMentorConfigurationRepository.deleteTeacherConfiguration(
+ configurationId,
+ transaction,
+ );
+ await this.aiMentorConfigurationRepository.deleteRoleplayConfiguration(
+ configurationId,
+ transaction,
+ );
+ await this.createSubtype(configurationId, data, baseLanguage, transaction);
+ }
+
+ await this.getValidatedGraph(configurationId, transaction);
+
+ return configurationId;
+ });
+ }
+
+ async updateTranslations(
+ configurationId: UUIDType,
+ language: SupportedLanguages,
+ data: UpdateAiMentorConfigurationTranslationBody,
+ ) {
+ return this.db.transaction(async (transaction) => {
+ const graph = await this.getValidatedGraph(configurationId, transaction);
+
+ if (graph.configuration.type !== data.type)
+ throw new BadRequestException("aiMentorConfiguration.errors.typeMismatch");
+
+ await this.aiMentorConfigurationRepository.updateConfigurationRootTranslations(
+ configurationId,
+ language,
+ data,
+ transaction,
+ );
+
+ const subtype =
+ data.type === AI_MENTOR_TYPE.TEACHER
+ ? await this.aiMentorConfigurationRepository.updateTeacherConfigurationTranslations(
+ configurationId,
+ language,
+ data,
+ transaction,
+ )
+ : await this.aiMentorConfigurationRepository.updateRoleplayConfigurationTranslations(
+ configurationId,
+ language,
+ data,
+ transaction,
+ );
+
+ if (!subtype)
+ throw new NotFoundException("aiMentorConfiguration.errors.configurationNotFound");
+
+ await this.getValidatedGraph(configurationId, transaction);
+ });
+ }
+
+ async getValidatedGraph(
+ configurationId: UUIDType,
+ dbInstance: DatabasePg = this.db,
+ ): Promise {
+ const configuration = await this.aiMentorConfigurationRepository.findConfigurationRoot(
+ configurationId,
+ dbInstance,
+ );
+
+ if (!configuration)
+ throw new NotFoundException("aiMentorConfiguration.errors.configurationNotFound");
+
+ const graph: AiMentorConfigurationGraph =
+ configuration.type === AI_MENTOR_TYPE.TEACHER
+ ? {
+ configuration,
+ teacherConfiguration:
+ (await this.aiMentorConfigurationRepository.findTeacherConfiguration(
+ configurationId,
+ dbInstance,
+ )) ?? null,
+ roleplayConfiguration: null,
+ }
+ : {
+ configuration,
+ teacherConfiguration: null,
+ roleplayConfiguration:
+ (await this.aiMentorConfigurationRepository.findRoleplayConfiguration(
+ configurationId,
+ dbInstance,
+ )) ?? null,
+ };
+
+ this.assertGraphIntegrity(graph);
+
+ return graph;
+ }
+
+ private async createSubtype(
+ configurationId: UUIDType,
+ data: AiMentorConfigurationContent,
+ baseLanguage: SupportedLanguages,
+ transaction: DatabasePg,
+ ) {
+ if (data.type === AI_MENTOR_TYPE.TEACHER) {
+ await this.aiMentorConfigurationRepository.createTeacherConfiguration(
+ configurationId,
+ data,
+ baseLanguage,
+ transaction,
+ );
+ return;
+ }
+
+ await this.aiMentorConfigurationRepository.createRoleplayConfiguration(
+ configurationId,
+ data,
+ baseLanguage,
+ transaction,
+ );
+ }
+
+ private async updateMatchingSubtype(
+ configurationId: UUIDType,
+ data: AiMentorConfigurationContent,
+ baseLanguage: SupportedLanguages,
+ transaction: DatabasePg,
+ ) {
+ if (data.type === AI_MENTOR_TYPE.TEACHER) {
+ const updated = await this.aiMentorConfigurationRepository.updateTeacherConfiguration(
+ configurationId,
+ data,
+ baseLanguage,
+ transaction,
+ );
+ if (!updated)
+ throw new NotFoundException("aiMentorConfiguration.errors.configurationNotFound");
+ return;
+ }
+
+ const updated = await this.aiMentorConfigurationRepository.updateRoleplayConfiguration(
+ configurationId,
+ data,
+ baseLanguage,
+ transaction,
+ );
+ if (!updated) throw new NotFoundException("aiMentorConfiguration.errors.configurationNotFound");
+ }
+
+ private assertGraphIntegrity(graph: AiMentorConfigurationGraph) {
+ const matchingSubtype =
+ graph.configuration.type === AI_MENTOR_TYPE.TEACHER
+ ? graph.teacherConfiguration
+ : graph.roleplayConfiguration;
+
+ if (!matchingSubtype)
+ throw new BadRequestException("aiMentorConfiguration.errors.invalidGraph");
+ }
+}
diff --git a/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration.service.ts b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration.service.ts
new file mode 100644
index 0000000000..8b38b76119
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-configuration.service.ts
@@ -0,0 +1,195 @@
+import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
+import { AI_MENTOR_TYPE, COURSE_FEATURE, ENTITY_TYPES, LESSON_TYPES } from "@repo/shared";
+
+import { CourseFeaturePolicyService } from "src/courses/course-feature-policy.service";
+import { MasterCourseService } from "src/courses/master-course.service";
+import { AdminLessonService } from "src/lesson/services/adminLesson.service";
+import { getExactLocalizedText } from "src/localization/localization.utils";
+
+import { AiMentorConfigurationRepository } from "../repositories/ai-mentor-configuration.repository";
+import {
+ hasMissingAiMentorConfigurationTranslations,
+ needsAiMentorConfiguration,
+} from "../utils/ai-mentor-configuration.helpers";
+
+import { AiMentorConfigurationGraphService } from "./ai-mentor-configuration-graph.service";
+
+import type {
+ AiMentorConfigurationContent,
+ AiMentorConfigurationResponse,
+ UpdateAiMentorConfigurationTranslationBody,
+} from "../schemas/ai-mentor-configuration.schema";
+import type {
+ AiMentorConfigurationGraph,
+ ConfiguredAiMentorLessonContext,
+} from "../types/ai-mentor-configuration.types";
+import type { SupportedLanguages } from "@repo/shared";
+import type { UUIDType } from "src/common";
+import type { CurrentUserType } from "src/common/types/current-user.type";
+
+@Injectable()
+export class AiMentorConfigurationService {
+ constructor(
+ private readonly aiMentorConfigurationRepository: AiMentorConfigurationRepository,
+ private readonly aiMentorConfigurationGraphService: AiMentorConfigurationGraphService,
+ private readonly adminLessonService: AdminLessonService,
+ private readonly masterCourseService: MasterCourseService,
+ private readonly courseFeaturePolicyService: CourseFeaturePolicyService,
+ ) {}
+
+ async getConfiguration(
+ lessonId: UUIDType,
+ currentUser: CurrentUserType,
+ requestedLanguage?: SupportedLanguages,
+ ): Promise {
+ await this.adminLessonService.validateAccess(ENTITY_TYPES.LESSON, currentUser, lessonId);
+ const context = await this.getConfiguredContext(lessonId);
+
+ return this.buildResponse(context, requestedLanguage);
+ }
+
+ async replaceConfiguration(
+ lessonId: UUIDType,
+ data: AiMentorConfigurationContent,
+ currentUser: CurrentUserType,
+ ): Promise {
+ const context = await this.prepareStructuralWrite(lessonId, currentUser);
+
+ await this.aiMentorConfigurationGraphService.replaceConfiguration(
+ context.configurationId,
+ data,
+ context.baseLanguage,
+ );
+
+ return this.buildResponse({ ...context, configurationType: data.type }, context.baseLanguage);
+ }
+
+ async updateTranslations(
+ lessonId: UUIDType,
+ language: SupportedLanguages,
+ data: UpdateAiMentorConfigurationTranslationBody,
+ currentUser: CurrentUserType,
+ ): Promise {
+ const context = await this.prepareStructuralWrite(lessonId, currentUser);
+
+ if (!context.availableLocales.includes(language))
+ throw new BadRequestException("adminCourseView.toast.languageNotSupported");
+ if (language === context.baseLanguage)
+ throw new BadRequestException(
+ "aiMentorConfiguration.errors.translationRequiresNonBaseLanguage",
+ );
+
+ await this.aiMentorConfigurationGraphService.updateTranslations(
+ context.configurationId,
+ language,
+ data,
+ );
+
+ return this.buildResponse(context, language);
+ }
+
+ private async prepareStructuralWrite(
+ lessonId: UUIDType,
+ currentUser: CurrentUserType,
+ ): Promise {
+ await this.masterCourseService.assertCourseContentEditableByLessonId(lessonId);
+ await this.courseFeaturePolicyService.assertCourseFeatureEnabledByLessonId(
+ lessonId,
+ COURSE_FEATURE.CURRICULUM_EDITING,
+ );
+ await this.adminLessonService.validateAccess(ENTITY_TYPES.LESSON, currentUser, lessonId);
+
+ return this.getConfiguredContext(lessonId);
+ }
+
+ private async getConfiguredContext(lessonId: UUIDType): Promise {
+ const context = await this.aiMentorConfigurationRepository.findLessonContext(lessonId);
+
+ if (!context) throw new NotFoundException("adminCourseView.errors.notFound.lesson");
+ if (context.lessonType !== LESSON_TYPES.AI_MENTOR || !context.aiMentorLessonId)
+ throw new BadRequestException("aiMentorConfiguration.errors.invalidLessonType");
+ if (!context.configurationId || !context.configurationType)
+ throw new NotFoundException("aiMentorConfiguration.errors.configurationNotFound");
+
+ return {
+ ...context,
+ aiMentorLessonId: context.aiMentorLessonId,
+ configurationId: context.configurationId,
+ configurationType: context.configurationType,
+ };
+ }
+
+ private async buildResponse(
+ context: ConfiguredAiMentorLessonContext,
+ requestedLanguage?: SupportedLanguages,
+ ): Promise {
+ const language = this.resolveLanguage(context, requestedLanguage);
+ const graph = await this.aiMentorConfigurationGraphService.getValidatedGraph(
+ context.configurationId,
+ );
+ const metadata = this.buildResponseMetadata(context, graph, language);
+
+ if (graph.configuration.type === AI_MENTOR_TYPE.TEACHER) {
+ const teacher = graph.teacherConfiguration;
+ if (!teacher) throw new BadRequestException("aiMentorConfiguration.errors.invalidGraph");
+
+ return {
+ ...metadata,
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: getExactLocalizedText(teacher.taskGoal, language) ?? "",
+ expertise: getExactLocalizedText(teacher.expertise, language) ?? "",
+ contentScope: getExactLocalizedText(teacher.contentScope, language) ?? "",
+ teachingStyle: teacher.teachingStyle,
+ feedbackGuidance: getExactLocalizedText(teacher.feedbackGuidance, language) ?? null,
+ };
+ }
+
+ const roleplay = graph.roleplayConfiguration;
+ if (!roleplay) throw new BadRequestException("aiMentorConfiguration.errors.invalidGraph");
+
+ return {
+ ...metadata,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: getExactLocalizedText(roleplay.scenario, language) ?? "",
+ aiRole: getExactLocalizedText(roleplay.aiRole, language) ?? "",
+ learnerRole: getExactLocalizedText(roleplay.learnerRole, language) ?? "",
+ characterGoal: getExactLocalizedText(roleplay.characterGoal, language) ?? "",
+ difficulty: roleplay.difficulty,
+ factsAndConstraints: getExactLocalizedText(roleplay.factsAndConstraints, language) ?? null,
+ };
+ }
+
+ private buildResponseMetadata(
+ context: ConfiguredAiMentorLessonContext,
+ graph: AiMentorConfigurationGraph,
+ language: SupportedLanguages,
+ ) {
+ return {
+ id: graph.configuration.id,
+ aiMentorLessonId: graph.configuration.aiMentorLessonId,
+ needsConfiguration: needsAiMentorConfiguration(graph, context.baseLanguage),
+ hasMissingTranslations: hasMissingAiMentorConfigurationTranslations(
+ graph,
+ language,
+ context.baseLanguage,
+ ),
+ openingInstruction:
+ getExactLocalizedText(graph.configuration.openingInstruction, language) ?? null,
+ additionalInstructions:
+ getExactLocalizedText(graph.configuration.additionalInstructions, language) ?? null,
+ language,
+ baseLanguage: context.baseLanguage,
+ availableLocales: context.availableLocales,
+ };
+ }
+
+ private resolveLanguage(
+ context: ConfiguredAiMentorLessonContext,
+ requestedLanguage?: SupportedLanguages,
+ ) {
+ if (!requestedLanguage || !context.availableLocales.includes(requestedLanguage))
+ return context.baseLanguage;
+
+ return requestedLanguage;
+ }
+}
diff --git a/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service.spec.ts b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service.spec.ts
new file mode 100644
index 0000000000..db67931012
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service.spec.ts
@@ -0,0 +1,103 @@
+import { AI_MENTOR_TYPE, SUPPORTED_LANGUAGES } from "@repo/shared";
+
+import { aiMentorConfigurations } from "src/storage/schema";
+
+import { AiMentorLessonTranslationService } from "./ai-mentor-lesson-translation.service";
+
+import type { AiMentorConfigurationRepository } from "../repositories/ai-mentor-configuration.repository";
+
+describe("AiMentorLessonTranslationService", () => {
+ const courseId = "00000000-0000-4000-8000-000000000001";
+ const configurationId = "00000000-0000-4000-8000-000000000002";
+ const repository = {
+ getConfigurationsForCourse: jest.fn(),
+ };
+ const service = new AiMentorLessonTranslationService(
+ repository as unknown as AiMentorConfigurationRepository,
+ );
+
+ beforeEach(() => {
+ jest.resetAllMocks();
+ repository.getConfigurationsForCourse.mockResolvedValue([]);
+ });
+
+ it("collects missing structured AI Mentor fields with lesson context", async () => {
+ repository.getConfigurationsForCourse.mockResolvedValue([
+ {
+ configurationId,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ openingInstruction: null,
+ additionalInstructions: { en: "Act as a customer and ask clarifying questions." },
+ teacherConfigurationId: null,
+ taskGoal: null,
+ expertise: null,
+ contentScope: null,
+ feedbackGuidance: null,
+ roleplayConfigurationId: null,
+ scenario: null,
+ aiRole: null,
+ learnerRole: null,
+ characterGoal: null,
+ factsAndConstraints: null,
+ courseTitle: { en: "Sales course" },
+ lessonTitle: { en: "Discovery call" },
+ lessonDescription: { en: "Practice a customer conversation" },
+ },
+ ]);
+
+ const result = await service.getMissingTranslations(
+ courseId,
+ SUPPORTED_LANGUAGES.PL,
+ SUPPORTED_LANGUAGES.EN,
+ );
+
+ expect(result).toEqual([
+ {
+ data: {
+ id: configurationId,
+ base: "Act as a customer and ask clarifying questions.",
+ field: aiMentorConfigurations.additionalInstructions,
+ idColumn: aiMentorConfigurations.id,
+ },
+ metadata: "AI Mentor additional instructions",
+ context: {
+ courseTitle: "Sales course",
+ lessonTitle: "Discovery call",
+ lessonDescription: "Practice a customer conversation",
+ },
+ },
+ ]);
+ });
+
+ it("does not collect a field that already has the requested translation", async () => {
+ repository.getConfigurationsForCourse.mockResolvedValue([
+ {
+ configurationId,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ openingInstruction: null,
+ additionalInstructions: {
+ en: "Act as a customer.",
+ pl: "Odegraj rolę klienta.",
+ },
+ teacherConfigurationId: null,
+ taskGoal: null,
+ expertise: null,
+ contentScope: null,
+ feedbackGuidance: null,
+ roleplayConfigurationId: null,
+ scenario: null,
+ aiRole: null,
+ learnerRole: null,
+ characterGoal: null,
+ factsAndConstraints: null,
+ courseTitle: { en: "Sales course" },
+ lessonTitle: { en: "Discovery call" },
+ lessonDescription: {},
+ },
+ ]);
+
+ await expect(
+ service.getMissingTranslations(courseId, SUPPORTED_LANGUAGES.PL, SUPPORTED_LANGUAGES.EN),
+ ).resolves.toEqual([]);
+ });
+});
diff --git a/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service.ts b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service.ts
new file mode 100644
index 0000000000..5f3e4e86b7
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/services/ai-mentor-lesson-translation.service.ts
@@ -0,0 +1,174 @@
+import { Injectable } from "@nestjs/common";
+import { AI_MENTOR_TYPE } from "@repo/shared";
+
+import { getExactLocalizedText } from "src/localization/localization.utils";
+import {
+ aiMentorConfigurations,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
+} from "src/storage/schema";
+
+import { AiMentorConfigurationRepository } from "../repositories/ai-mentor-configuration.repository";
+
+import type {
+ AiMentorConfigurationCourseTranslationSource,
+ AiMentorTranslationCandidate,
+} from "../types/ai-mentor-lesson-translation.types";
+import type { SupportedLanguages } from "@repo/shared";
+import type { UUIDType } from "src/common";
+import type {
+ ContextualCourseTranslationType,
+ CourseTranslationContext,
+} from "src/courses/types/course.types";
+
+@Injectable()
+export class AiMentorLessonTranslationService {
+ constructor(private readonly aiMentorConfigurationRepository: AiMentorConfigurationRepository) {}
+
+ async getMissingTranslations(
+ courseId: UUIDType,
+ language: SupportedLanguages,
+ baseLanguage: SupportedLanguages,
+ ): Promise {
+ const configurations =
+ await this.aiMentorConfigurationRepository.getConfigurationsForCourse(courseId);
+
+ return configurations.flatMap((configuration) => {
+ const context: CourseTranslationContext = {
+ courseTitle: getExactLocalizedText(configuration.courseTitle, baseLanguage),
+ lessonTitle: getExactLocalizedText(configuration.lessonTitle, baseLanguage),
+ lessonDescription: getExactLocalizedText(configuration.lessonDescription, baseLanguage),
+ };
+ const commonCandidates: AiMentorTranslationCandidate[] = [
+ {
+ id: configuration.configurationId,
+ source: configuration.openingInstruction,
+ field: aiMentorConfigurations.openingInstruction,
+ idColumn: aiMentorConfigurations.id,
+ metadata: "AI Mentor opening instruction",
+ },
+ {
+ id: configuration.configurationId,
+ source: configuration.additionalInstructions,
+ field: aiMentorConfigurations.additionalInstructions,
+ idColumn: aiMentorConfigurations.id,
+ metadata: "AI Mentor additional instructions",
+ },
+ ];
+ const subtypeCandidates =
+ configuration.type === AI_MENTOR_TYPE.TEACHER
+ ? this.getTeacherCandidates(configuration)
+ : this.getRoleplayCandidates(configuration);
+
+ return [...commonCandidates, ...subtypeCandidates].flatMap((candidate) =>
+ this.toMissingTranslation(candidate, context, language, baseLanguage),
+ );
+ });
+ }
+
+ private getTeacherCandidates(
+ configuration: AiMentorConfigurationCourseTranslationSource,
+ ): AiMentorTranslationCandidate[] {
+ if (!configuration.teacherConfigurationId) return [];
+
+ return [
+ {
+ id: configuration.teacherConfigurationId,
+ source: configuration.taskGoal,
+ field: aiMentorTeacherConfigurations.taskGoal,
+ idColumn: aiMentorTeacherConfigurations.id,
+ metadata: "AI Mentor teaching task goal",
+ },
+ {
+ id: configuration.teacherConfigurationId,
+ source: configuration.expertise,
+ field: aiMentorTeacherConfigurations.expertise,
+ idColumn: aiMentorTeacherConfigurations.id,
+ metadata: "AI Mentor expertise",
+ },
+ {
+ id: configuration.teacherConfigurationId,
+ source: configuration.contentScope,
+ field: aiMentorTeacherConfigurations.contentScope,
+ idColumn: aiMentorTeacherConfigurations.id,
+ metadata: "AI Mentor content scope",
+ },
+ {
+ id: configuration.teacherConfigurationId,
+ source: configuration.feedbackGuidance,
+ field: aiMentorTeacherConfigurations.feedbackGuidance,
+ idColumn: aiMentorTeacherConfigurations.id,
+ metadata: "AI Mentor feedback guidance",
+ },
+ ];
+ }
+
+ private getRoleplayCandidates(
+ configuration: AiMentorConfigurationCourseTranslationSource,
+ ): AiMentorTranslationCandidate[] {
+ if (!configuration.roleplayConfigurationId) return [];
+
+ return [
+ {
+ id: configuration.roleplayConfigurationId,
+ source: configuration.scenario,
+ field: aiMentorRoleplayConfigurations.scenario,
+ idColumn: aiMentorRoleplayConfigurations.id,
+ metadata: "AI Mentor scenario",
+ },
+ {
+ id: configuration.roleplayConfigurationId,
+ source: configuration.aiRole,
+ field: aiMentorRoleplayConfigurations.aiRole,
+ idColumn: aiMentorRoleplayConfigurations.id,
+ metadata: "AI Mentor AI role",
+ },
+ {
+ id: configuration.roleplayConfigurationId,
+ source: configuration.learnerRole,
+ field: aiMentorRoleplayConfigurations.learnerRole,
+ idColumn: aiMentorRoleplayConfigurations.id,
+ metadata: "AI Mentor learner role",
+ },
+ {
+ id: configuration.roleplayConfigurationId,
+ source: configuration.characterGoal,
+ field: aiMentorRoleplayConfigurations.characterGoal,
+ idColumn: aiMentorRoleplayConfigurations.id,
+ metadata: "AI Mentor character goal",
+ },
+ {
+ id: configuration.roleplayConfigurationId,
+ source: configuration.factsAndConstraints,
+ field: aiMentorRoleplayConfigurations.factsAndConstraints,
+ idColumn: aiMentorRoleplayConfigurations.id,
+ metadata: "AI Mentor facts and constraints",
+ },
+ ];
+ }
+
+ private toMissingTranslation(
+ candidate: AiMentorTranslationCandidate,
+ context: CourseTranslationContext,
+ language: SupportedLanguages,
+ baseLanguage: SupportedLanguages,
+ ): ContextualCourseTranslationType[] {
+ const base = getExactLocalizedText(candidate.source, baseLanguage);
+ const translated = getExactLocalizedText(candidate.source, language);
+
+ if (!base?.length || translated?.length) return [];
+
+ return [
+ {
+ data: {
+ id: candidate.id,
+ base,
+ field: candidate.field,
+ idColumn: candidate.idColumn,
+ },
+ metadata: candidate.metadata,
+ context,
+ },
+ ];
+ }
+}
diff --git a/apps/api/src/lesson/ai-mentor-configuration/types/ai-mentor-configuration.types.ts b/apps/api/src/lesson/ai-mentor-configuration/types/ai-mentor-configuration.types.ts
new file mode 100644
index 0000000000..f811f8d1f1
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/types/ai-mentor-configuration.types.ts
@@ -0,0 +1,33 @@
+import type { AiMentorType, SupportedLanguages } from "@repo/shared";
+import type { UUIDType } from "src/common";
+import type {
+ aiMentorConfigurations,
+ aiMentorRoleplayConfigurations,
+ aiMentorTeacherConfigurations,
+} from "src/storage/schema";
+
+export type AiMentorConfigurationGraph = {
+ configuration: typeof aiMentorConfigurations.$inferSelect;
+ teacherConfiguration: typeof aiMentorTeacherConfigurations.$inferSelect | null;
+ roleplayConfiguration: typeof aiMentorRoleplayConfigurations.$inferSelect | null;
+};
+
+export type AiMentorConfigurationLessonContext = {
+ courseId: UUIDType;
+ lessonId: UUIDType;
+ lessonType: string;
+ aiMentorLessonId: UUIDType | null;
+ configurationId: UUIDType | null;
+ configurationType: AiMentorType | null;
+ baseLanguage: SupportedLanguages;
+ availableLocales: SupportedLanguages[];
+};
+
+export type ConfiguredAiMentorLessonContext = Omit<
+ AiMentorConfigurationLessonContext,
+ "aiMentorLessonId" | "configurationId" | "configurationType"
+> & {
+ aiMentorLessonId: UUIDType;
+ configurationId: UUIDType;
+ configurationType: AiMentorType;
+};
diff --git a/apps/api/src/lesson/ai-mentor-configuration/types/ai-mentor-lesson-translation.types.ts b/apps/api/src/lesson/ai-mentor-configuration/types/ai-mentor-lesson-translation.types.ts
new file mode 100644
index 0000000000..d25e32ba9f
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/types/ai-mentor-lesson-translation.types.ts
@@ -0,0 +1,16 @@
+import type { AiMentorConfigurationRepository } from "../repositories/ai-mentor-configuration.repository";
+import type { LocalizedText } from "@repo/shared";
+import type { AnyPgColumn } from "drizzle-orm/pg-core";
+import type { UUIDType } from "src/common";
+
+export type AiMentorConfigurationCourseTranslationSource = Awaited<
+ ReturnType
+>[number];
+
+export type AiMentorTranslationCandidate = {
+ id: UUIDType;
+ source: LocalizedText | null;
+ field: AnyPgColumn;
+ idColumn: AnyPgColumn;
+ metadata: string;
+};
diff --git a/apps/api/src/lesson/ai-mentor-configuration/utils/ai-mentor-configuration.helpers.ts b/apps/api/src/lesson/ai-mentor-configuration/utils/ai-mentor-configuration.helpers.ts
new file mode 100644
index 0000000000..35e5f2b055
--- /dev/null
+++ b/apps/api/src/lesson/ai-mentor-configuration/utils/ai-mentor-configuration.helpers.ts
@@ -0,0 +1,61 @@
+import { getExactLocalizedText } from "src/localization/localization.utils";
+
+import type { AiMentorConfigurationGraph } from "../types/ai-mentor-configuration.types";
+import type { SupportedLanguages } from "@repo/shared";
+
+export const needsAiMentorConfiguration = (
+ graph: AiMentorConfigurationGraph,
+ baseLanguage: SupportedLanguages,
+): boolean => {
+ const requiredValues = graph.teacherConfiguration
+ ? [
+ graph.teacherConfiguration.taskGoal,
+ graph.teacherConfiguration.expertise,
+ graph.teacherConfiguration.contentScope,
+ ]
+ : [
+ graph.roleplayConfiguration?.scenario,
+ graph.roleplayConfiguration?.aiRole,
+ graph.roleplayConfiguration?.learnerRole,
+ graph.roleplayConfiguration?.characterGoal,
+ ];
+
+ return requiredValues.some((value) => !getExactLocalizedText(value, baseLanguage)?.trim().length);
+};
+
+export const hasMissingAiMentorConfigurationTranslations = (
+ graph: AiMentorConfigurationGraph,
+ language: SupportedLanguages,
+ baseLanguage: SupportedLanguages,
+): boolean => {
+ if (language === baseLanguage) return false;
+
+ const localizedValues = [
+ graph.configuration.openingInstruction,
+ graph.configuration.additionalInstructions,
+ ...(graph.teacherConfiguration
+ ? [
+ graph.teacherConfiguration.taskGoal,
+ graph.teacherConfiguration.expertise,
+ graph.teacherConfiguration.contentScope,
+ graph.teacherConfiguration.feedbackGuidance,
+ ]
+ : []),
+ ...(graph.roleplayConfiguration
+ ? [
+ graph.roleplayConfiguration.scenario,
+ graph.roleplayConfiguration.aiRole,
+ graph.roleplayConfiguration.learnerRole,
+ graph.roleplayConfiguration.characterGoal,
+ graph.roleplayConfiguration.factsAndConstraints,
+ ]
+ : []),
+ ];
+
+ return localizedValues.some((value) => {
+ const base = getExactLocalizedText(value, baseLanguage);
+ const translated = getExactLocalizedText(value, language);
+
+ return Boolean(base?.length && !translated?.length);
+ });
+};
diff --git a/apps/api/src/lesson/lesson.module.ts b/apps/api/src/lesson/lesson.module.ts
index d0f37c289d..7c7446bf57 100644
--- a/apps/api/src/lesson/lesson.module.ts
+++ b/apps/api/src/lesson/lesson.module.ts
@@ -24,11 +24,15 @@ import { AiJudgeConfigurationTranslationService } from "./ai-judge-configuration
import { AiJudgeConfigurationController } from "./ai-judge-configuration/ai-judge-configuration.controller";
import { AiJudgeConfigurationRepository } from "./ai-judge-configuration/ai-judge-configuration.repository";
import { AiJudgeConfigurationService } from "./ai-judge-configuration/ai-judge-configuration.service";
+import { AiMentorConfigurationController } from "./ai-mentor-configuration/controllers/ai-mentor-configuration.controller";
+import { AiMentorConfigurationRepository } from "./ai-mentor-configuration/repositories/ai-mentor-configuration.repository";
+import { AiMentorConfigurationGraphService } from "./ai-mentor-configuration/services/ai-mentor-configuration-graph.service";
+import { AiMentorConfigurationService } from "./ai-mentor-configuration/services/ai-mentor-configuration.service";
+import { AiMentorLessonTranslationService } from "./ai-mentor-configuration/services/ai-mentor-lesson-translation.service";
import { LessonController } from "./lesson.controller";
import { AdminLessonRepository } from "./repositories/adminLesson.repository";
import { LessonRepository } from "./repositories/lesson.repository";
import { AdminLessonService } from "./services/adminLesson.service";
-import { AiMentorLessonTranslationService } from "./services/aiMentorLessonTranslation.service";
import { LessonService } from "./services/lesson.service";
@Module({
@@ -51,6 +55,7 @@ import { LessonService } from "./services/lesson.service";
LessonController,
AiJudgeConfigurationController,
AiJudgeConfigurationGenerationController,
+ AiMentorConfigurationController,
],
providers: [
AiJudgeConfigurationRepository,
@@ -60,6 +65,9 @@ import { LessonService } from "./services/lesson.service";
AiJudgeConfigurationGraphService,
AiJudgeConfigurationService,
AiJudgeConfigurationTranslationService,
+ AiMentorConfigurationRepository,
+ AiMentorConfigurationGraphService,
+ AiMentorConfigurationService,
AiMentorLessonTranslationService,
LessonRepository,
AdminLessonService,
@@ -70,6 +78,7 @@ import { LessonService } from "./services/lesson.service";
exports: [
AiJudgeConfigurationGraphService,
AiJudgeConfigurationTranslationService,
+ AiMentorConfigurationGraphService,
AiMentorLessonTranslationService,
AdminLessonService,
AdminLessonRepository,
diff --git a/apps/api/src/lesson/lesson.schema.ts b/apps/api/src/lesson/lesson.schema.ts
index b01bba9be6..1961eb1f3b 100644
--- a/apps/api/src/lesson/lesson.schema.ts
+++ b/apps/api/src/lesson/lesson.schema.ts
@@ -1,9 +1,4 @@
-import {
- AI_MENTOR_TTS_PRESET,
- AI_MENTOR_TYPE,
- AI_MENTOR_VOICE_MODE,
- SUPPORTED_LANGUAGES,
-} from "@repo/shared";
+import { AI_MENTOR_TTS_PRESET, AI_MENTOR_VOICE_MODE, SUPPORTED_LANGUAGES } from "@repo/shared";
import { Type } from "@sinclair/typebox";
import { AI_JUDGE_CRITERION_STATUS } from "src/ai/judge-configuration/judge-configuration.types";
@@ -17,6 +12,7 @@ import { QUESTION_TYPE } from "src/questions/schema/question.types";
import { PROGRESS_STATUSES } from "src/utils/types/progress.type";
import { aiJudgeConfigurationInputSchema } from "./ai-judge-configuration/ai-judge-configuration.schema";
+import { aiMentorConfigurationContentSchema } from "./ai-mentor-configuration/schemas/ai-mentor-configuration.schema";
import { LESSON_TYPES } from "./lesson.type";
import type { Static } from "@sinclair/typebox";
@@ -81,8 +77,6 @@ const lessonQuizSchema = Type.Object({
export const aiMentorLessonSchema = Type.Object({
id: UUIDSchema,
lessonId: UUIDSchema,
- aiMentorInstructions: Type.String(),
- type: Type.Enum(AI_MENTOR_TYPE),
name: Type.String(),
avatarReference: Type.Union([Type.String(), Type.Null()]),
voiceMode: Type.Enum(AI_MENTOR_VOICE_MODE),
@@ -140,9 +134,8 @@ export const createAiMentorLessonSchema = Type.Intersect([
Type.Object({
chapterId: UUIDSchema,
displayOrder: Type.Optional(Type.Number()),
- aiMentorInstructions: Type.String(),
+ aiMentorConfiguration: aiMentorConfigurationContentSchema,
aiJudgeConfiguration: aiJudgeConfigurationInputSchema,
- type: Type.Enum(AI_MENTOR_TYPE),
name: Type.Optional(Type.String()),
voiceMode: Type.Optional(Type.Enum(AI_MENTOR_VOICE_MODE)),
ttsPreset: Type.Optional(Type.Enum(AI_MENTOR_TTS_PRESET)),
@@ -150,7 +143,12 @@ export const createAiMentorLessonSchema = Type.Intersect([
}),
]);
export const updateAiMentorLessonSchema = Type.Intersect([
- Type.Omit(createAiMentorLessonSchema, ["chapterId", "displayOrder", "aiJudgeConfiguration"]),
+ Type.Omit(createAiMentorLessonSchema, [
+ "chapterId",
+ "displayOrder",
+ "aiMentorConfiguration",
+ "aiJudgeConfiguration",
+ ]),
Type.Object({
language: supportedLanguagesSchema,
}),
diff --git a/apps/api/src/lesson/repositories/adminLesson.repository.ts b/apps/api/src/lesson/repositories/adminLesson.repository.ts
index 31d924fb83..85520fca41 100644
--- a/apps/api/src/lesson/repositories/adminLesson.repository.ts
+++ b/apps/api/src/lesson/repositories/adminLesson.repository.ts
@@ -30,12 +30,7 @@ import type {
UpdateQuizLessonBody,
} from "../lesson.schema";
import type { CreateLiveLessonInput } from "../lesson.type";
-import type {
- AiMentorType,
- AiMentorTTSPreset,
- AiMentorVoiceMode,
- SupportedLanguages,
-} from "@repo/shared";
+import type { AiMentorTTSPreset, AiMentorVoiceMode, SupportedLanguages } from "@repo/shared";
import type { LessonActivityLogOption, LessonActivityLogQuestion } from "src/activity-logs/types";
import type { QuestionType } from "src/questions/schema/question.types";
@@ -53,15 +48,8 @@ export class AdminLessonRepository {
courseId: chapters.courseId,
title: this.localizationService.getLocalizedSqlField(lessons.title, language),
description: this.localizationService.getLocalizedSqlField(lessons.description, language),
- aiMentorInstructions: language
- ? this.localizationService.getFieldByLanguage(
- aiMentorLessons.aiMentorInstructions,
- language,
- )
- : this.localizationService.getLocalizedSqlField(aiMentorLessons.aiMentorInstructions),
aiMentorName: this.localizationService.getLocalizedSqlField(aiMentorLessons.name, language),
aiMentorAvatarReference: aiMentorLessons.avatarReference,
- aiMentorType: aiMentorLessons.type,
aiMentorVoiceMode: aiMentorLessons.voiceMode,
aiMentorTTSPreset: aiMentorLessons.ttsPreset,
aiMentorCustomTtsReference: this.localizationService.getLocalizedSqlField(
@@ -76,22 +64,6 @@ export class AdminLessonRepository {
.where(eq(lessons.id, id));
}
- async getAiMentorInstructionsForCourse(courseId: UUIDType) {
- return this.db
- .select({
- id: aiMentorLessons.id,
- aiMentorInstructions: aiMentorLessons.aiMentorInstructions,
- courseTitle: courses.title,
- lessonTitle: lessons.title,
- lessonDescription: lessons.description,
- })
- .from(aiMentorLessons)
- .innerJoin(lessons, eq(lessons.id, aiMentorLessons.lessonId))
- .innerJoin(chapters, eq(chapters.id, lessons.chapterId))
- .innerJoin(courses, eq(courses.id, chapters.courseId))
- .where(eq(courses.id, courseId));
- }
-
async getContentLessonsByIds(lessonIds: UUIDType[], language?: SupportedLanguages) {
if (!lessonIds.length) return [];
@@ -324,8 +296,6 @@ export class AdminLessonRepository {
async updateAiMentorLessonData(
lessonId: UUIDType,
data: {
- aiMentorInstructions: string;
- type: AiMentorType;
name?: string;
voiceMode: AiMentorVoiceMode;
ttsPreset: AiMentorTTSPreset;
@@ -348,12 +318,6 @@ export class AdminLessonRepository {
return dbInstance
.update(aiMentorLessons)
.set({
- aiMentorInstructions: setJsonbField(
- aiMentorLessons.aiMentorInstructions,
- data.language,
- data.aiMentorInstructions,
- ),
- type: data.type,
name: setJsonbField(aiMentorLessons.name, data.language, data.name),
voiceMode: data.voiceMode,
ttsPreset: data.ttsPreset,
@@ -365,8 +329,6 @@ export class AdminLessonRepository {
async createAiMentorLessonData(
data: {
lessonId: UUIDType;
- aiMentorInstructions: string;
- type: AiMentorType;
name?: string;
voiceMode: AiMentorVoiceMode;
ttsPreset: AiMentorTTSPreset;
@@ -380,14 +342,12 @@ export class AdminLessonRepository {
? undefined
: buildJsonbField(data.language, data.customTtsReference, true);
- const { language, aiMentorInstructions } = data;
+ const { language } = data;
return dbInstance
.insert(aiMentorLessons)
.values({
lessonId: data.lessonId,
- aiMentorInstructions: buildJsonbField(language, aiMentorInstructions),
- type: data.type,
name: buildJsonbField(language, data.name ?? "AI Mentor"),
voiceMode: data.voiceMode,
ttsPreset: data.ttsPreset,
diff --git a/apps/api/src/lesson/repositories/lesson.repository.ts b/apps/api/src/lesson/repositories/lesson.repository.ts
index 76b9eedd6d..3eca647714 100644
--- a/apps/api/src/lesson/repositories/lesson.repository.ts
+++ b/apps/api/src/lesson/repositories/lesson.repository.ts
@@ -242,10 +242,6 @@ export class LessonRepository {
ELSE NULL
END
`,
- aiMentorInstructions: this.localizationService.getLocalizedSqlField(
- aiMentorLessons.aiMentorInstructions,
- language,
- ),
isExternal: sql`${lessons.isExternal}`,
liveTrainingId: sql`
(
diff --git a/apps/api/src/lesson/services/adminLesson.service.ts b/apps/api/src/lesson/services/adminLesson.service.ts
index 3a3d6be16f..a640856fbd 100644
--- a/apps/api/src/lesson/services/adminLesson.service.ts
+++ b/apps/api/src/lesson/services/adminLesson.service.ts
@@ -42,9 +42,9 @@ import { OutboxPublisher } from "src/outbox/outbox.publisher";
import { ResourceLibraryService } from "src/resource-library/resource-library.service";
import { questionAnswerOptions, questions } from "src/storage/schema";
import { StudentLessonProgressService } from "src/studentLessonProgress/studentLessonProgress.service";
-import { isRichTextEmpty } from "src/utils/isRichTextEmpty";
import { AiJudgeConfigurationGraphService } from "../ai-judge-configuration/ai-judge-configuration-graph.service";
+import { AiMentorConfigurationGraphService } from "../ai-mentor-configuration/services/ai-mentor-configuration-graph.service";
import { LESSON_TYPES } from "../lesson.type";
import { AdminLessonRepository } from "../repositories/adminLesson.repository";
import { LessonRepository } from "../repositories/lesson.repository";
@@ -94,6 +94,7 @@ export class AdminLessonService {
private readonly liveTrainingService: LiveTrainingService,
private readonly searchIndexService: SearchIndexService,
private readonly aiJudgeConfigurationGraphService: AiJudgeConfigurationGraphService,
+ private readonly aiMentorConfigurationGraphService: AiMentorConfigurationGraphService,
@Inject("CACHE_MANAGER") private readonly cache: CacheManagerStore,
) {}
@@ -456,9 +457,6 @@ export class AdminLessonService {
});
}
- if (isRichTextEmpty(data.aiMentorInstructions))
- throw new BadRequestException("adminCourseView.errors.lesson.aiMentorRequiredContent");
-
if (!data.name?.trim().length) data.name = "AI Mentor";
const voiceMode = data.voiceMode ?? AI_MENTOR_VOICE_MODE.PRESET;
const customTtsReference = data.customTtsReference?.trim() || null;
@@ -576,9 +574,6 @@ export class AdminLessonService {
if (!lesson) throw new NotFoundException("adminCourseView.errors.notFound.lesson");
- if (isRichTextEmpty(data.aiMentorInstructions))
- throw new BadRequestException("adminCourseView.errors.lesson.aiMentorRequiredContent");
-
const previousLessonSnapshot = await this.buildLessonActivitySnapshot(id, data.language);
const updatedLesson = await this.updateAiMentorLessonWithTransaction(
@@ -842,8 +837,6 @@ export class AdminLessonService {
const [aiMentorLesson] = await this.adminLessonRepository.createAiMentorLessonData(
{
lessonId: lesson.id,
- aiMentorInstructions: data.aiMentorInstructions,
- type: data.type,
name: data?.name,
voiceMode: data.voiceMode ?? AI_MENTOR_VOICE_MODE.PRESET,
ttsPreset: data.ttsPreset ?? AI_MENTOR_TTS_PRESET.MALE,
@@ -853,6 +846,13 @@ export class AdminLessonService {
trx,
);
+ await this.aiMentorConfigurationGraphService.createConfigurationInTransaction(
+ aiMentorLesson.id,
+ data.aiMentorConfiguration,
+ language,
+ trx,
+ );
+
await this.aiJudgeConfigurationGraphService.createConfigurationInTransaction(
aiMentorLesson.id,
data.aiJudgeConfiguration,
@@ -872,7 +872,7 @@ export class AdminLessonService {
userId: UUIDType,
) {
return await this.db.transaction(async (trx) => {
- const { aiMentorInstructions, type: _type, name, ...lessonData } = data;
+ const { name, ...lessonData } = data;
const { availableLocales } = await this.localizationService.getBaseLanguage(
ENTITY_TYPE.LESSON,
@@ -893,9 +893,6 @@ export class AdminLessonService {
trx,
);
- if (isRichTextEmpty(data.aiMentorInstructions))
- throw new BadRequestException("adminCourseView.errors.lesson.aiMentorRequiredContent");
-
if (data.name?.trim().length === 0) {
data.name = "AI Mentor";
}
@@ -910,8 +907,6 @@ export class AdminLessonService {
await this.adminLessonRepository.updateAiMentorLessonData(
id,
{
- aiMentorInstructions,
- type: data.type,
name,
voiceMode,
ttsPreset: data.ttsPreset ?? AI_MENTOR_TTS_PRESET.MALE,
@@ -1592,10 +1587,8 @@ export class AdminLessonService {
aiMentor:
lesson.type === LESSON_TYPES.AI_MENTOR
? {
- aiMentorInstructions: lesson.aiMentorInstructions,
name: lesson.aiMentorName,
avatarReference: lesson.aiMentorAvatarReference,
- type: lesson.aiMentorType,
voiceMode: lesson.aiMentorVoiceMode,
ttsPreset: lesson.aiMentorTTSPreset,
customTtsReference: lesson.aiMentorCustomTtsReference,
diff --git a/apps/api/src/lesson/services/aiMentorLessonTranslation.service.spec.ts b/apps/api/src/lesson/services/aiMentorLessonTranslation.service.spec.ts
deleted file mode 100644
index f08d7714aa..0000000000
--- a/apps/api/src/lesson/services/aiMentorLessonTranslation.service.spec.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { aiMentorLessons } from "src/storage/schema";
-
-import { AiMentorLessonTranslationService } from "./aiMentorLessonTranslation.service";
-
-import type { AdminLessonRepository } from "../repositories/adminLesson.repository";
-
-describe("AiMentorLessonTranslationService", () => {
- const courseId = "00000000-0000-4000-8000-000000000001";
- const aiMentorLessonId = "00000000-0000-4000-8000-000000000002";
- const repository = {
- getAiMentorInstructionsForCourse: jest.fn(),
- };
- const service = new AiMentorLessonTranslationService(
- repository as unknown as AdminLessonRepository,
- );
-
- beforeEach(() => {
- jest.resetAllMocks();
- repository.getAiMentorInstructionsForCourse.mockResolvedValue([]);
- });
-
- it("collects missing AI Mentor instructions with lesson context", async () => {
- repository.getAiMentorInstructionsForCourse.mockResolvedValue([
- {
- id: aiMentorLessonId,
- aiMentorInstructions: { en: "Act as a customer and ask clarifying questions." },
- courseTitle: { en: "Sales course" },
- lessonTitle: { en: "Discovery call" },
- lessonDescription: { en: "Practice a customer conversation" },
- },
- ]);
-
- const result = await service.getMissingTranslations(courseId, "pl", "en");
-
- expect(result).toEqual([
- {
- data: {
- id: aiMentorLessonId,
- base: "Act as a customer and ask clarifying questions.",
- field: aiMentorLessons.aiMentorInstructions,
- idColumn: aiMentorLessons.id,
- },
- metadata: "AI Mentor instructions",
- context: {
- courseTitle: "Sales course",
- lessonTitle: "Discovery call",
- lessonDescription: "Practice a customer conversation",
- },
- },
- ]);
- });
-
- it("does not collect instructions that already have the requested translation", async () => {
- repository.getAiMentorInstructionsForCourse.mockResolvedValue([
- {
- id: aiMentorLessonId,
- aiMentorInstructions: {
- en: "Act as a customer.",
- pl: "Odegraj rolę klienta.",
- },
- courseTitle: { en: "Sales course" },
- lessonTitle: { en: "Discovery call" },
- lessonDescription: {},
- },
- ]);
-
- await expect(service.getMissingTranslations(courseId, "pl", "en")).resolves.toEqual([]);
- });
-});
diff --git a/apps/api/src/lesson/services/aiMentorLessonTranslation.service.ts b/apps/api/src/lesson/services/aiMentorLessonTranslation.service.ts
deleted file mode 100644
index c90e0b0128..0000000000
--- a/apps/api/src/lesson/services/aiMentorLessonTranslation.service.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Injectable } from "@nestjs/common";
-
-import { aiMentorLessons } from "src/storage/schema";
-
-import { AdminLessonRepository } from "../repositories/adminLesson.repository";
-
-import type { LocalizedText, SupportedLanguages } from "@repo/shared";
-import type { UUIDType } from "src/common";
-import type { ContextualCourseTranslationType } from "src/courses/types/course.types";
-
-@Injectable()
-export class AiMentorLessonTranslationService {
- constructor(private readonly adminLessonRepository: AdminLessonRepository) {}
-
- async getMissingTranslations(
- courseId: UUIDType,
- language: SupportedLanguages,
- baseLanguage: SupportedLanguages,
- ): Promise {
- const aiMentorLessonsForCourse =
- await this.adminLessonRepository.getAiMentorInstructionsForCourse(courseId);
-
- return aiMentorLessonsForCourse.flatMap((aiMentorLesson) => {
- const base = this.getLanguageValue(aiMentorLesson.aiMentorInstructions, baseLanguage);
- const translated = this.getLanguageValue(aiMentorLesson.aiMentorInstructions, language);
-
- if (!base?.length || translated?.length) return [];
-
- return [
- {
- data: {
- id: aiMentorLesson.id,
- base,
- field: aiMentorLessons.aiMentorInstructions,
- idColumn: aiMentorLessons.id,
- },
- metadata: "AI Mentor instructions",
- context: {
- courseTitle: this.getLanguageValue(aiMentorLesson.courseTitle, baseLanguage),
- lessonTitle: this.getLanguageValue(aiMentorLesson.lessonTitle, baseLanguage),
- lessonDescription: this.getLanguageValue(
- aiMentorLesson.lessonDescription,
- baseLanguage,
- ),
- },
- },
- ];
- });
- }
-
- private getLanguageValue(value: LocalizedText | null, language: SupportedLanguages) {
- return value?.[language];
- }
-}
diff --git a/apps/api/src/localization/localization.utils.ts b/apps/api/src/localization/localization.utils.ts
new file mode 100644
index 0000000000..8c2b86b5a6
--- /dev/null
+++ b/apps/api/src/localization/localization.utils.ts
@@ -0,0 +1,6 @@
+import type { LocalizedText, SupportedLanguages } from "@repo/shared";
+
+export const getExactLocalizedText = (
+ value: LocalizedText | null | undefined,
+ language: SupportedLanguages,
+) => value?.[language];
diff --git a/apps/api/src/luma/luma-generated-course-import.service.spec.ts b/apps/api/src/luma/luma-generated-course-import.service.spec.ts
index 7eda796c44..39317b0fd7 100644
--- a/apps/api/src/luma/luma-generated-course-import.service.spec.ts
+++ b/apps/api/src/luma/luma-generated-course-import.service.spec.ts
@@ -14,6 +14,7 @@ describe("LumaGeneratedCourseImportService", () => {
undefined as never,
undefined as never,
undefined as never,
+ undefined as never,
);
it("accepts a generated AI Mentor lesson with a structured Judge configuration", () => {
diff --git a/apps/api/src/luma/luma-generated-course-import.service.ts b/apps/api/src/luma/luma-generated-course-import.service.ts
index 5a1743c2a9..7652c603ea 100644
--- a/apps/api/src/luma/luma-generated-course-import.service.ts
+++ b/apps/api/src/luma/luma-generated-course-import.service.ts
@@ -5,6 +5,8 @@ import {
AI_MENTOR_TTS_PRESET,
AI_MENTOR_TYPE,
AI_MENTOR_VOICE_MODE,
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
DEFAULT_AI_MENTOR_TYPE,
} from "@repo/shared";
import { Value } from "@sinclair/typebox/value";
@@ -21,6 +23,7 @@ import { FileService } from "src/file/file.service";
import { IngestionService } from "src/ingestion/services/ingestion.service";
import { AiJudgeConfigurationGraphService } from "src/lesson/ai-judge-configuration/ai-judge-configuration-graph.service";
import { aiJudgeConfigurationInputSchema } from "src/lesson/ai-judge-configuration/ai-judge-configuration.schema";
+import { AiMentorConfigurationGraphService } from "src/lesson/ai-mentor-configuration/services/ai-mentor-configuration-graph.service";
import { LESSON_TYPES } from "src/lesson/lesson.type";
import { AdminLessonRepository } from "src/lesson/repositories/adminLesson.repository";
import {
@@ -78,6 +81,7 @@ export class LumaGeneratedCourseImportService {
private readonly adminChapterRepository: AdminChapterRepository,
private readonly adminLessonRepository: AdminLessonRepository,
private readonly aiJudgeConfigurationGraphService: AiJudgeConfigurationGraphService,
+ private readonly aiMentorConfigurationGraphService: AiMentorConfigurationGraphService,
private readonly ingestionService: IngestionService,
private readonly lumaCourseGenerationSyncRepository: LumaCourseGenerationSyncRepository,
) {}
@@ -230,17 +234,19 @@ export class LumaGeneratedCourseImportService {
.insert(aiMentorLessons)
.values({
lessonId: lesson.id,
- aiMentorInstructions: buildJsonbField(
- data.language,
- this.sanitizeText(aiMentor.aiMentorInstructions),
- ),
- type: this.mapAiMentorType(aiMentor.type),
name: buildJsonbField(data.language, this.sanitizeText(aiMentor?.name ?? "AI Mentor")),
voiceMode: AI_MENTOR_VOICE_MODE.PRESET,
ttsPreset: this.mapAiMentorTtsPreset(aiMentor.ttsPreset),
})
.returning({ id: aiMentorLessons.id });
+ await this.aiMentorConfigurationGraphService.createConfigurationInTransaction(
+ aiMentorLesson.id,
+ this.buildImportedAiMentorConfiguration(aiMentor),
+ data.language,
+ data.trx,
+ );
+
await this.aiJudgeConfigurationGraphService.createConfigurationInTransaction(
aiMentorLesson.id,
aiMentor.aiJudgeConfiguration,
@@ -725,6 +731,32 @@ export class LumaGeneratedCourseImportService {
return DEFAULT_AI_MENTOR_TYPE;
}
+ private buildImportedAiMentorConfiguration(aiMentor: LumaGeneratedCourseAiMentor) {
+ const type = this.mapAiMentorType(aiMentor.type);
+ const additionalInstructions = this.sanitizeText(aiMentor.aiMentorInstructions);
+
+ if (type === AI_MENTOR_TYPE.TEACHER) {
+ return {
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "",
+ expertise: "",
+ contentScope: "",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.EXPLAIN_AND_PRACTICE,
+ additionalInstructions,
+ };
+ }
+
+ return {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "",
+ aiRole: "",
+ learnerRole: "",
+ characterGoal: "",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ additionalInstructions,
+ };
+ }
+
private mapAiMentorTtsPreset(preset: "male" | "female" | undefined): AiMentorTTSPreset {
if (preset === AI_MENTOR_TTS_PRESET.FEMALE) return AI_MENTOR_TTS_PRESET.FEMALE;
return AI_MENTOR_TTS_PRESET.MALE;
diff --git a/apps/api/src/seed/nice-data-seeds.ts b/apps/api/src/seed/nice-data-seeds.ts
index 3480fbf345..8d49d034cd 100644
--- a/apps/api/src/seed/nice-data-seeds.ts
+++ b/apps/api/src/seed/nice-data-seeds.ts
@@ -104,7 +104,7 @@ export const niceCourses: NiceCourseData[] = [
{
type: LESSON_TYPES.AI_MENTOR,
title: "HTML Basics",
- aiMentorInstructions:
+ additionalInstructions:
"Guide the learner through the basics of HTML structure, including elements, tags, and their roles in building a web page. Encourage questions and provide examples for each concept.",
aiJudgeConfiguration: {
taskGoal:
diff --git a/apps/api/src/seed/seed-helpers.ts b/apps/api/src/seed/seed-helpers.ts
index 70ef095b14..94a9ce4109 100644
--- a/apps/api/src/seed/seed-helpers.ts
+++ b/apps/api/src/seed/seed-helpers.ts
@@ -1,6 +1,8 @@
import { faker } from "@faker-js/faker";
import { ConfigService } from "@nestjs/config";
import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TYPE,
SYSTEM_ROLE_PERMISSIONS,
SYSTEM_ROLE_SLUGS,
SYSTEM_RULE_SET_SLUGS,
@@ -21,7 +23,9 @@ import {
aiJudgeConfigurations,
aiJudgeCriteria,
aiJudgeScoreGuidance,
+ aiMentorConfigurations,
aiMentorLessons,
+ aiMentorRoleplayConfigurations,
articles,
categories,
chapters,
@@ -220,23 +224,44 @@ export async function createNiceCourses(
.returning();
if (
lessonData.type === LESSON_TYPES.AI_MENTOR &&
- lessonData.aiMentorInstructions &&
+ lessonData.additionalInstructions &&
lessonData.aiJudgeConfiguration
) {
const [aiMentorLesson] = await db
.insert(aiMentorLessons)
.values({
lessonId: lesson.id,
- aiMentorInstructions: buildJsonbField("en", lessonData.aiMentorInstructions),
tenantId,
})
.returning();
+ const [aiMentorConfiguration] = await db
+ .insert(aiMentorConfigurations)
+ .values({
+ aiMentorLessonId: aiMentorLesson.id,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ additionalInstructions: buildJsonbField(
+ SUPPORTED_LANGUAGES.EN,
+ lessonData.additionalInstructions,
+ ),
+ tenantId,
+ })
+ .returning();
+
+ await db.insert(aiMentorRoleplayConfigurations).values({
+ configurationId: aiMentorConfiguration.id,
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ tenantId,
+ });
+
const [configuration] = await db
.insert(aiJudgeConfigurations)
.values({
aiMentorLessonId: aiMentorLesson.id,
- taskGoal: buildJsonbField("en", lessonData.aiJudgeConfiguration.taskGoal),
+ taskGoal: buildJsonbField(
+ SUPPORTED_LANGUAGES.EN,
+ lessonData.aiJudgeConfiguration.taskGoal,
+ ),
passingThresholdPercent: lessonData.aiJudgeConfiguration.passingThresholdPercent,
tenantId,
})
@@ -247,8 +272,11 @@ export async function createNiceCourses(
.insert(aiJudgeCriteria)
.values({
configurationId: configuration.id,
- title: buildJsonbField("en", criterionData.title),
- expectedBehavior: buildJsonbField("en", criterionData.expectedBehavior),
+ title: buildJsonbField(SUPPORTED_LANGUAGES.EN, criterionData.title),
+ expectedBehavior: buildJsonbField(
+ SUPPORTED_LANGUAGES.EN,
+ criterionData.expectedBehavior,
+ ),
maxScore: criterionData.maxScore,
tenantId,
})
@@ -258,8 +286,10 @@ export async function createNiceCourses(
criterionData.scoreGuidance.map((guidance) => ({
criterionId: criterion.id,
score: guidance.score,
- description: buildJsonbField("en", guidance.description),
- example: guidance.example ? buildJsonbField("en", guidance.example) : undefined,
+ description: buildJsonbField(SUPPORTED_LANGUAGES.EN, guidance.description),
+ example: guidance.example
+ ? buildJsonbField(SUPPORTED_LANGUAGES.EN, guidance.example)
+ : undefined,
tenantId,
})),
);
@@ -269,7 +299,7 @@ export async function createNiceCourses(
await db.insert(aiJudgeBlockingErrors).values(
lessonData.aiJudgeConfiguration.blockingErrors.map((blockingError) => ({
configurationId: configuration.id,
- description: buildJsonbField("en", blockingError.description),
+ description: buildJsonbField(SUPPORTED_LANGUAGES.EN, blockingError.description),
tenantId,
})),
);
diff --git a/apps/api/src/storage/migrations/0179_add_ai_mentor_configuration_tables.sql b/apps/api/src/storage/migrations/0179_add_ai_mentor_configuration_tables.sql
new file mode 100644
index 0000000000..9b401dddb5
--- /dev/null
+++ b/apps/api/src/storage/migrations/0179_add_ai_mentor_configuration_tables.sql
@@ -0,0 +1,98 @@
+DO $$ BEGIN
+ CREATE TYPE "public"."ai_mentor_roleplay_difficulty" AS ENUM('cooperative', 'realistic', 'challenging');
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ CREATE TYPE "public"."ai_mentor_teaching_style" AS ENUM('explain_and_practice', 'guided_discovery', 'socratic');
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ CREATE TYPE "public"."structured_ai_mentor_type" AS ENUM('teacher', 'roleplay');
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "ai_mentor_configurations" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "created_at" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ "updated_at" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ "ai_mentor_lesson_id" uuid NOT NULL,
+ "type" "structured_ai_mentor_type" NOT NULL,
+ "opening_instruction" jsonb,
+ "additional_instructions" jsonb,
+ "tenant_id" uuid DEFAULT current_setting('app.tenant_id', true)::uuid NOT NULL,
+ CONSTRAINT "ai_mentor_configurations_ai_mentor_lesson_id_unique" UNIQUE("ai_mentor_lesson_id")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "ai_mentor_roleplay_configurations" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "created_at" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ "updated_at" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ "configuration_id" uuid NOT NULL,
+ "scenario" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "ai_role" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "learner_role" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "character_goal" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "difficulty" "ai_mentor_roleplay_difficulty" NOT NULL,
+ "facts_and_constraints" jsonb,
+ "tenant_id" uuid DEFAULT current_setting('app.tenant_id', true)::uuid NOT NULL,
+ CONSTRAINT "ai_mentor_roleplay_configurations_configuration_id_unique" UNIQUE("configuration_id")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "ai_mentor_teacher_configurations" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "created_at" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ "updated_at" timestamp(3) with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ "configuration_id" uuid NOT NULL,
+ "task_goal" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "expertise" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "content_scope" jsonb DEFAULT '{}'::jsonb NOT NULL,
+ "teaching_style" "ai_mentor_teaching_style" NOT NULL,
+ "feedback_guidance" jsonb,
+ "tenant_id" uuid DEFAULT current_setting('app.tenant_id', true)::uuid NOT NULL,
+ CONSTRAINT "ai_mentor_teacher_configurations_configuration_id_unique" UNIQUE("configuration_id")
+);
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "ai_mentor_configurations" ADD CONSTRAINT "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk" FOREIGN KEY ("ai_mentor_lesson_id") REFERENCES "public"."ai_mentor_lessons"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "ai_mentor_configurations" ADD CONSTRAINT "ai_mentor_configurations_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "ai_mentor_roleplay_configurations" ADD CONSTRAINT "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk" FOREIGN KEY ("configuration_id") REFERENCES "public"."ai_mentor_configurations"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "ai_mentor_roleplay_configurations" ADD CONSTRAINT "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "ai_mentor_teacher_configurations" ADD CONSTRAINT "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk" FOREIGN KEY ("configuration_id") REFERENCES "public"."ai_mentor_configurations"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "ai_mentor_teacher_configurations" ADD CONSTRAINT "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "ai_mentor_configurations_tenant_id_idx" ON "ai_mentor_configurations" USING btree ("tenant_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "ai_mentor_roleplay_configurations_tenant_id_idx" ON "ai_mentor_roleplay_configurations" USING btree ("tenant_id");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "ai_mentor_teacher_configurations_tenant_id_idx" ON "ai_mentor_teacher_configurations" USING btree ("tenant_id");
\ No newline at end of file
diff --git a/apps/api/src/storage/migrations/0180_enable_ai_mentor_configuration_rls.sql b/apps/api/src/storage/migrations/0180_enable_ai_mentor_configuration_rls.sql
new file mode 100644
index 0000000000..3bc2efd203
--- /dev/null
+++ b/apps/api/src/storage/migrations/0180_enable_ai_mentor_configuration_rls.sql
@@ -0,0 +1,24 @@
+ALTER TABLE "ai_mentor_configurations" ENABLE ROW LEVEL SECURITY;
+ALTER TABLE "ai_mentor_teacher_configurations" ENABLE ROW LEVEL SECURITY;
+ALTER TABLE "ai_mentor_roleplay_configurations" ENABLE ROW LEVEL SECURITY;
+
+DROP POLICY IF EXISTS "ai_mentor_configurations_tenant_isolation"
+ ON "ai_mentor_configurations";
+DROP POLICY IF EXISTS "ai_mentor_teacher_configurations_tenant_isolation"
+ ON "ai_mentor_teacher_configurations";
+DROP POLICY IF EXISTS "ai_mentor_roleplay_configurations_tenant_isolation"
+ ON "ai_mentor_roleplay_configurations";
+--> statement-breakpoint
+CREATE POLICY "ai_mentor_configurations_tenant_isolation" ON "ai_mentor_configurations"
+ USING ("tenant_id" = current_setting('app.tenant_id', true)::uuid)
+ WITH CHECK ("tenant_id" = current_setting('app.tenant_id', true)::uuid);
+--> statement-breakpoint
+CREATE POLICY "ai_mentor_teacher_configurations_tenant_isolation"
+ ON "ai_mentor_teacher_configurations"
+ USING ("tenant_id" = current_setting('app.tenant_id', true)::uuid)
+ WITH CHECK ("tenant_id" = current_setting('app.tenant_id', true)::uuid);
+--> statement-breakpoint
+CREATE POLICY "ai_mentor_roleplay_configurations_tenant_isolation"
+ ON "ai_mentor_roleplay_configurations"
+ USING ("tenant_id" = current_setting('app.tenant_id', true)::uuid)
+ WITH CHECK ("tenant_id" = current_setting('app.tenant_id', true)::uuid);
diff --git a/apps/api/src/storage/migrations/0181_backfill_ai_mentor_configurations.sql b/apps/api/src/storage/migrations/0181_backfill_ai_mentor_configurations.sql
new file mode 100644
index 0000000000..065bc3a458
--- /dev/null
+++ b/apps/api/src/storage/migrations/0181_backfill_ai_mentor_configurations.sql
@@ -0,0 +1,42 @@
+INSERT INTO "ai_mentor_configurations" (
+ "ai_mentor_lesson_id",
+ "type",
+ "additional_instructions",
+ "tenant_id"
+)
+SELECT
+ "id",
+ CASE
+ WHEN "type" = 'roleplay' THEN 'roleplay'::"structured_ai_mentor_type"
+ ELSE 'teacher'::"structured_ai_mentor_type"
+ END,
+ "ai_mentor_instructions",
+ "tenant_id"
+FROM "ai_mentor_lessons"
+ON CONFLICT ("ai_mentor_lesson_id") DO NOTHING;
+--> statement-breakpoint
+INSERT INTO "ai_mentor_teacher_configurations" (
+ "configuration_id",
+ "teaching_style",
+ "tenant_id"
+)
+SELECT
+ "id",
+ 'explain_and_practice'::"ai_mentor_teaching_style",
+ "tenant_id"
+FROM "ai_mentor_configurations"
+WHERE "type" = 'teacher'
+ON CONFLICT ("configuration_id") DO NOTHING;
+--> statement-breakpoint
+INSERT INTO "ai_mentor_roleplay_configurations" (
+ "configuration_id",
+ "difficulty",
+ "tenant_id"
+)
+SELECT
+ "id",
+ 'realistic'::"ai_mentor_roleplay_difficulty",
+ "tenant_id"
+FROM "ai_mentor_configurations"
+WHERE "type" = 'roleplay'
+ON CONFLICT ("configuration_id") DO NOTHING;
diff --git a/apps/api/src/storage/migrations/0182_drop_legacy_ai_mentor_configuration_columns.sql b/apps/api/src/storage/migrations/0182_drop_legacy_ai_mentor_configuration_columns.sql
new file mode 100644
index 0000000000..8980cf374d
--- /dev/null
+++ b/apps/api/src/storage/migrations/0182_drop_legacy_ai_mentor_configuration_columns.sql
@@ -0,0 +1,2 @@
+ALTER TABLE "ai_mentor_lessons" DROP COLUMN IF EXISTS "ai_mentor_instructions";--> statement-breakpoint
+ALTER TABLE "ai_mentor_lessons" DROP COLUMN IF EXISTS "type";
\ No newline at end of file
diff --git a/apps/api/src/storage/migrations/meta/0179_snapshot.json b/apps/api/src/storage/migrations/meta/0179_snapshot.json
new file mode 100644
index 0000000000..2b04230bc9
--- /dev/null
+++ b/apps/api/src/storage/migrations/meta/0179_snapshot.json
@@ -0,0 +1,15683 @@
+{
+ "id": "c0fcfff7-62ac-47ce-8ba9-f73039c39f9b",
+ "prevId": "60de642a-1902-46db-97ed-4758e7d35563",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.activity_logs": {
+ "name": "activity_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_email": {
+ "name": "actor_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_role": {
+ "name": "actor_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action_type": {
+ "name": "action_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "activity_logs_tenant_id_idx": {
+ "name": "activity_logs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_tenant_timeframe_idx": {
+ "name": "activity_logs_tenant_timeframe_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_actor_idx": {
+ "name": "activity_logs_actor_idx",
+ "columns": [
+ {
+ "expression": "actor_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_action_idx": {
+ "name": "activity_logs_action_idx",
+ "columns": [
+ {
+ "expression": "action_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_timeframe_idx": {
+ "name": "activity_logs_timeframe_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_resource_idx": {
+ "name": "activity_logs_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "activity_logs_actor_id_users_id_fk": {
+ "name": "activity_logs_actor_id_users_id_fk",
+ "tableFrom": "activity_logs",
+ "tableTo": "users",
+ "columnsFrom": [
+ "actor_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ },
+ "activity_logs_tenant_id_tenants_id_fk": {
+ "name": "activity_logs_tenant_id_tenants_id_fk",
+ "tableFrom": "activity_logs",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_blocking_errors": {
+ "name": "ai_judge_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_blocking_errors_tenant_id_idx": {
+ "name": "ai_judge_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_judge_blocking_errors_configuration_id_created_at_idx": {
+ "name": "ai_judge_blocking_errors_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "tableTo": "ai_judge_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_configurations": {
+ "name": "ai_judge_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "passing_threshold_percent": {
+ "name": "passing_threshold_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_configurations_tenant_id_idx": {
+ "name": "ai_judge_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_judge_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "ai_mentor_lesson_id"
+ ]
+ }
+ }
+ },
+ "public.ai_judge_criteria": {
+ "name": "ai_judge_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expected_behavior": {
+ "name": "expected_behavior",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_criteria_tenant_id_idx": {
+ "name": "ai_judge_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_judge_criteria_configuration_id_created_at_idx": {
+ "name": "ai_judge_criteria_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "tableTo": "ai_judge_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_score_guidance": {
+ "name": "ai_judge_score_guidance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "example": {
+ "name": "example",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_score_guidance_tenant_id_idx": {
+ "name": "ai_judge_score_guidance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_judge_score_guidance_criterion_id_score_unique": {
+ "name": "ai_judge_score_guidance_criterion_id_score_unique",
+ "columns": [
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "score",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "tableTo": "ai_judge_criteria",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_score_guidance_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_score_guidance_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_blocking_errors": {
+ "name": "ai_mentor_judgement_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blocking_error_id": {
+ "name": "blocking_error_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "blocking_error_description": {
+ "name": "blocking_error_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_blocking_errors_tenant_id_idx": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "blocking_error_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "tableTo": "ai_mentor_judgements",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "tableTo": "ai_judge_blocking_errors",
+ "columnsFrom": [
+ "blocking_error_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_criteria": {
+ "name": "ai_mentor_judgement_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "criterion_title": {
+ "name": "criterion_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "awarded_points": {
+ "name": "awarded_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score_at_judgement": {
+ "name": "max_score_at_judgement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_criteria_tenant_id_idx": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "tableTo": "ai_mentor_judgements",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "tableTo": "ai_judge_criteria",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgements": {
+ "name": "ai_mentor_judgements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "earned_points": {
+ "name": "earned_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgements_tenant_id_idx": {
+ "name": "ai_mentor_judgements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "tableTo": "ai_mentor_threads",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "tableTo": "ai_judge_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgements_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgements_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_judgements_thread_id_unique": {
+ "name": "ai_mentor_judgements_thread_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "thread_id"
+ ]
+ }
+ }
+ },
+ "public.ai_mentor_lessons": {
+ "name": "ai_mentor_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_instructions": {
+ "name": "ai_mentor_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'roleplay'"
+ },
+ "voice_mode": {
+ "name": "voice_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'preset'"
+ },
+ "tts_preset": {
+ "name": "tts_preset",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'male'"
+ },
+ "custom_tts_reference": {
+ "name": "custom_tts_reference",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_lessons_tenant_id_idx": {
+ "name": "ai_mentor_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_lessons_lesson_id_lessons_id_fk": {
+ "name": "ai_mentor_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_lessons_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_student_lesson_progress": {
+ "name": "ai_mentor_student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_lesson_progress_id": {
+ "name": "student_lesson_progress_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_score": {
+ "name": "min_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_student_lesson_progress_tenant_id_idx": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "tableTo": "student_lesson_progress",
+ "columnsFrom": [
+ "student_lesson_progress_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_thread_messages": {
+ "name": "ai_mentor_thread_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_thread_messages_tenant_id_idx": {
+ "name": "ai_mentor_thread_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "tableTo": "ai_mentor_threads",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_thread_messages_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_thread_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_threads": {
+ "name": "ai_mentor_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "user_language": {
+ "name": "user_language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_threads_tenant_id_idx": {
+ "name": "ai_mentor_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_threads_user_id_users_id_fk": {
+ "name": "ai_mentor_threads_user_id_users_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_threads_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.announcements": {
+ "name": "announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "audience": {
+ "name": "audience",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all_users'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'published'"
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "send_email": {
+ "name": "send_email",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "email_template": {
+ "name": "email_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "announcements_tenant_id_idx": {
+ "name": "announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "announcements_author_id_users_id_fk": {
+ "name": "announcements_author_id_users_id_fk",
+ "tableFrom": "announcements",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "announcements_tenant_id_tenants_id_fk": {
+ "name": "announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "announcements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.article_sections": {
+ "name": "article_sections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "article_sections_tenant_id_idx": {
+ "name": "article_sections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "article_sections_tenant_id_tenants_id_fk": {
+ "name": "article_sections_tenant_id_tenants_id_fk",
+ "tableFrom": "article_sections",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.articles": {
+ "name": "articles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "article_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "article_section_id": {
+ "name": "article_section_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by_id": {
+ "name": "updated_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "articles_tenant_id_idx": {
+ "name": "articles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "article_section_idx": {
+ "name": "article_section_idx",
+ "columns": [
+ {
+ "expression": "article_section_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "articles_article_section_id_article_sections_id_fk": {
+ "name": "articles_article_section_id_article_sections_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "article_sections",
+ "columnsFrom": [
+ "article_section_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "articles_author_id_users_id_fk": {
+ "name": "articles_author_id_users_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "articles_updated_by_id_users_id_fk": {
+ "name": "articles_updated_by_id_users_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "updated_by_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "articles_tenant_id_tenants_id_fk": {
+ "name": "articles_tenant_id_tenants_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_events": {
+ "name": "calendar_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "uid": {
+ "name": "uid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "all_day": {
+ "name": "all_day",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizer_user_id": {
+ "name": "organizer_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rrule": {
+ "name": "rrule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exdates": {
+ "name": "exdates",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_events_tenant_id_idx": {
+ "name": "calendar_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_events_tenant_starts_ends_idx": {
+ "name": "calendar_events_tenant_starts_ends_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starts_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "ends_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_events_tenant_uid_unique_idx": {
+ "name": "calendar_events_tenant_uid_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "uid",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_events_organizer_user_id_users_id_fk": {
+ "name": "calendar_events_organizer_user_id_users_id_fk",
+ "tableFrom": "calendar_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "organizer_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "calendar_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.categories": {
+ "name": "categories",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "categories_tenant_id_idx": {
+ "name": "categories_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "categories_tenant_id_base_title_unique": {
+ "name": "categories_tenant_id_base_title_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"title\"->>\"base_language\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "categories_tenant_id_tenants_id_fk": {
+ "name": "categories_tenant_id_tenants_id_fk",
+ "tableFrom": "categories",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.certificates": {
+ "name": "certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archive_reason": {
+ "name": "archive_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiration_warning_sent_at": {
+ "name": "expiration_warning_sent_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "certificates_tenant_id_idx": {
+ "name": "certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "certificates_active_expiry_idx": {
+ "name": "certificates_active_expiry_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "certificates_user_course_idx": {
+ "name": "certificates_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "certificates_user_id_users_id_fk": {
+ "name": "certificates_user_id_users_id_fk",
+ "tableFrom": "certificates",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "certificates_course_id_courses_id_fk": {
+ "name": "certificates_course_id_courses_id_fk",
+ "tableFrom": "certificates",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "certificates_tenant_id_tenants_id_fk": {
+ "name": "certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "certificates",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.chapters": {
+ "name": "chapters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_freemium": {
+ "name": "is_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_count": {
+ "name": "lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "chapters_tenant_id_idx": {
+ "name": "chapters_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "chapters_tenant_id_course_id_idx": {
+ "name": "chapters_tenant_id_course_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "chapters_course_id_courses_id_fk": {
+ "name": "chapters_course_id_courses_id_fk",
+ "tableFrom": "chapters",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "chapters_author_id_users_id_fk": {
+ "name": "chapters_author_id_users_id_fk",
+ "tableFrom": "chapters",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "chapters_tenant_id_tenants_id_fk": {
+ "name": "chapters_tenant_id_tenants_id_fk",
+ "tableFrom": "chapters",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_message_reactions": {
+ "name": "course_chat_message_reactions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reaction": {
+ "name": "reaction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_message_reactions_tenant_id_idx": {
+ "name": "course_chat_message_reactions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_message_reactions_message_id_reaction_idx": {
+ "name": "course_chat_message_reactions_message_id_reaction_idx",
+ "columns": [
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_message_reactions_user_message_reaction_unique_idx": {
+ "name": "course_chat_message_reactions_user_message_reaction_unique_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_chat_message_reactions_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_message_reactions_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "course_chat_messages",
+ "columnsFrom": [
+ "message_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_message_reactions_course_id_courses_id_fk": {
+ "name": "course_chat_message_reactions_course_id_courses_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_message_reactions_user_id_users_id_fk": {
+ "name": "course_chat_message_reactions_user_id_users_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_message_reactions_tenant_id_tenants_id_fk": {
+ "name": "course_chat_message_reactions_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_messages": {
+ "name": "course_chat_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_message_id": {
+ "name": "parent_message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_messages_tenant_id_idx": {
+ "name": "course_chat_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_messages_course_id_created_at_idx": {
+ "name": "course_chat_messages_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_messages_thread_id_created_at_idx": {
+ "name": "course_chat_messages_thread_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_messages_parent_message_id_created_at_idx": {
+ "name": "course_chat_messages_parent_message_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "parent_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_chat_messages_thread_id_course_chat_threads_id_fk": {
+ "name": "course_chat_messages_thread_id_course_chat_threads_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "course_chat_threads",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_course_id_courses_id_fk": {
+ "name": "course_chat_messages_course_id_courses_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_user_id_users_id_fk": {
+ "name": "course_chat_messages_user_id_users_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_parent_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_messages_parent_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "course_chat_messages",
+ "columnsFrom": [
+ "parent_message_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_tenant_id_tenants_id_fk": {
+ "name": "course_chat_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_threads": {
+ "name": "course_chat_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_threads_tenant_id_idx": {
+ "name": "course_chat_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_threads_course_id_created_at_idx": {
+ "name": "course_chat_threads_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_threads_course_id_updated_at_idx": {
+ "name": "course_chat_threads_course_id_updated_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_chat_threads_course_id_courses_id_fk": {
+ "name": "course_chat_threads_course_id_courses_id_fk",
+ "tableFrom": "course_chat_threads",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_threads_created_by_user_id_users_id_fk": {
+ "name": "course_chat_threads_created_by_user_id_users_id_fk",
+ "tableFrom": "course_chat_threads",
+ "tableTo": "users",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_threads_tenant_id_tenants_id_fk": {
+ "name": "course_chat_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_threads",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_slugs": {
+ "name": "course_slugs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_short_id": {
+ "name": "course_short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lang": {
+ "name": "lang",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_slugs_tenant_id_idx": {
+ "name": "course_slugs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_slug_course_short_id_lang_unique_idx": {
+ "name": "course_slug_course_short_id_lang_unique_idx",
+ "columns": [
+ {
+ "expression": "course_short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lang",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_slugs_course_short_id_courses_short_id_fk": {
+ "name": "course_slugs_course_short_id_courses_short_id_fk",
+ "tableFrom": "course_slugs",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_short_id"
+ ],
+ "columnsTo": [
+ "short_id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "cascade"
+ },
+ "course_slugs_tenant_id_tenants_id_fk": {
+ "name": "course_slugs_tenant_id_tenants_id_fk",
+ "tableFrom": "course_slugs",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_student_mode": {
+ "name": "course_student_mode",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_student_mode_tenant_id_idx": {
+ "name": "course_student_mode_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_student_mode_user_id_users_id_fk": {
+ "name": "course_student_mode_user_id_users_id_fk",
+ "tableFrom": "course_student_mode",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_student_mode_course_id_courses_id_fk": {
+ "name": "course_student_mode_course_id_courses_id_fk",
+ "tableFrom": "course_student_mode",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_student_mode_tenant_id_tenants_id_fk": {
+ "name": "course_student_mode_tenant_id_tenants_id_fk",
+ "tableFrom": "course_student_mode",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_student_mode_user_id_course_id_unique": {
+ "name": "course_student_mode_user_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.course_students_stats": {
+ "name": "course_students_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "month": {
+ "name": "month",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "new_students_count": {
+ "name": "new_students_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_students_stats_tenant_id_idx": {
+ "name": "course_students_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_students_stats_course_id_courses_id_fk": {
+ "name": "course_students_stats_course_id_courses_id_fk",
+ "tableFrom": "course_students_stats",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_students_stats_author_id_users_id_fk": {
+ "name": "course_students_stats_author_id_users_id_fk",
+ "tableFrom": "course_students_stats",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_students_stats_tenant_id_tenants_id_fk": {
+ "name": "course_students_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "course_students_stats",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_students_stats_course_id_month_year_unique": {
+ "name": "course_students_stats_course_id_month_year_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "course_id",
+ "month",
+ "year"
+ ]
+ }
+ }
+ },
+ "public.courses": {
+ "name": "courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "short_id": {
+ "name": "short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_s3_key": {
+ "name": "thumbnail_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "has_certificate": {
+ "name": "has_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "price_in_cents": {
+ "name": "price_in_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "currency": {
+ "name": "currency",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'usd'"
+ },
+ "chapter_count": {
+ "name": "chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "course_type": {
+ "name": "course_type",
+ "type": "course_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category_id": {
+ "name": "category_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stripe_product_id": {
+ "name": "stripe_product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripe_price_id": {
+ "name": "stripe_price_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"lessonSequenceEnabled\":false,\"quizFeedbackEnabled\":true,\"certificateSignature\":null,\"certificateFontColor\":null,\"certificateValidity\":null,\"videoCompletionTrackingEnabled\":true}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_tenant_id_idx": {
+ "name": "courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "courses_short_id_unique_idx": {
+ "name": "courses_short_id_unique_idx",
+ "columns": [
+ {
+ "expression": "short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "courses_author_id_users_id_fk": {
+ "name": "courses_author_id_users_id_fk",
+ "tableFrom": "courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "courses_category_id_categories_id_fk": {
+ "name": "courses_category_id_categories_id_fk",
+ "tableFrom": "courses",
+ "tableTo": "categories",
+ "columnsFrom": [
+ "category_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "courses_tenant_id_tenants_id_fk": {
+ "name": "courses_tenant_id_tenants_id_fk",
+ "tableFrom": "courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.courses_summary_stats": {
+ "name": "courses_summary_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "free_purchased_count": {
+ "name": "free_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_count": {
+ "name": "paid_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_after_freemium_count": {
+ "name": "paid_purchased_after_freemium_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_freemium_student_count": {
+ "name": "completed_freemium_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_course_student_count": {
+ "name": "completed_course_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_summary_stats_tenant_id_idx": {
+ "name": "courses_summary_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "courses_summary_stats_course_id_courses_id_fk": {
+ "name": "courses_summary_stats_course_id_courses_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "courses_summary_stats_author_id_users_id_fk": {
+ "name": "courses_summary_stats_author_id_users_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "courses_summary_stats_tenant_id_tenants_id_fk": {
+ "name": "courses_summary_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "courses_summary_stats_course_id_unique": {
+ "name": "courses_summary_stats_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.create_tokens": {
+ "name": "create_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reminder_count": {
+ "name": "reminder_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "create_tokens_tenant_id_idx": {
+ "name": "create_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "create_tokens_token_hash_idx": {
+ "name": "create_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "create_tokens_user_id_users_id_fk": {
+ "name": "create_tokens_user_id_users_id_fk",
+ "tableFrom": "create_tokens",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "create_tokens_tenant_id_tenants_id_fk": {
+ "name": "create_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "create_tokens",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.credentials": {
+ "name": "credentials",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requires_password_change": {
+ "name": "requires_password_change",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "credentials_tenant_id_idx": {
+ "name": "credentials_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "credentials_user_id_users_id_fk": {
+ "name": "credentials_user_id_users_id_fk",
+ "tableFrom": "credentials",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credentials_tenant_id_tenants_id_fk": {
+ "name": "credentials_tenant_id_tenants_id_fk",
+ "tableFrom": "credentials",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.doc_chunks": {
+ "name": "doc_chunks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_index": {
+ "name": "chunk_index",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding": {
+ "name": "embedding",
+ "type": "vector(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "doc_chunks_tenant_id_idx": {
+ "name": "doc_chunks_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "doc_chunks_document_id_documents_id_fk": {
+ "name": "doc_chunks_document_id_documents_id_fk",
+ "tableFrom": "doc_chunks",
+ "tableTo": "documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "doc_chunks_tenant_id_tenants_id_fk": {
+ "name": "doc_chunks_tenant_id_tenants_id_fk",
+ "tableFrom": "doc_chunks",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.document_to_ai_mentor_lesson": {
+ "name": "document_to_ai_mentor_lesson",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "document_to_ai_mentor_lesson_tenant_id_idx": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "document_to_ai_mentor_lesson_document_id_documents_id_fk": {
+ "name": "document_to_ai_mentor_lesson_document_id_documents_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "tableTo": "documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique": {
+ "name": "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "document_id",
+ "ai_mentor_lesson_id"
+ ]
+ }
+ }
+ },
+ "public.documents": {
+ "name": "documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "check_sum": {
+ "name": "check_sum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "documents_tenant_id_idx": {
+ "name": "documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "documents_tenant_id_tenants_id_fk": {
+ "name": "documents_tenant_id_tenants_id_fk",
+ "tableFrom": "documents",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "documents_check_sum_unique": {
+ "name": "documents_check_sum_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "check_sum"
+ ]
+ }
+ }
+ },
+ "public.form_field_answers": {
+ "name": "form_field_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_field_id": {
+ "name": "form_field_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label_snapshot": {
+ "name": "label_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "answered_language": {
+ "name": "answered_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_field_answers_tenant_id_idx": {
+ "name": "form_field_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "form_field_answers_user_id_form_field_id_unique": {
+ "name": "form_field_answers_user_id_form_field_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "form_field_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "form_field_answers_user_id_idx": {
+ "name": "form_field_answers_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "form_field_answers_form_field_id_form_fields_id_fk": {
+ "name": "form_field_answers_form_field_id_form_fields_id_fk",
+ "tableFrom": "form_field_answers",
+ "tableTo": "form_fields",
+ "columnsFrom": [
+ "form_field_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ },
+ "form_field_answers_user_id_users_id_fk": {
+ "name": "form_field_answers_user_id_users_id_fk",
+ "tableFrom": "form_field_answers",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "form_field_answers_tenant_id_tenants_id_fk": {
+ "name": "form_field_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "form_field_answers",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.form_fields": {
+ "name": "form_fields",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_id": {
+ "name": "form_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "required": {
+ "name": "required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_fields_tenant_id_idx": {
+ "name": "form_fields_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "form_fields_form_id_display_order_idx": {
+ "name": "form_fields_form_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "form_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "form_fields_form_id_forms_id_fk": {
+ "name": "form_fields_form_id_forms_id_fk",
+ "tableFrom": "form_fields",
+ "tableTo": "forms",
+ "columnsFrom": [
+ "form_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "form_fields_tenant_id_tenants_id_fk": {
+ "name": "form_fields_tenant_id_tenants_id_fk",
+ "tableFrom": "form_fields",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.forms": {
+ "name": "forms",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "forms_tenant_id_idx": {
+ "name": "forms_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "forms_tenant_id_type_unique_idx": {
+ "name": "forms_tenant_id_type_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "forms_tenant_id_tenants_id_fk": {
+ "name": "forms_tenant_id_tenants_id_fk",
+ "tableFrom": "forms",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.group_announcements": {
+ "name": "group_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_announcements_tenant_id_idx": {
+ "name": "group_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_announcements_group_id_groups_id_fk": {
+ "name": "group_announcements_group_id_groups_id_fk",
+ "tableFrom": "group_announcements",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_announcements_announcement_id_announcements_id_fk": {
+ "name": "group_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "group_announcements",
+ "tableTo": "announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_announcements_tenant_id_tenants_id_fk": {
+ "name": "group_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "group_announcements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_announcements_group_id_announcement_id_unique": {
+ "name": "group_announcements_group_id_announcement_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "group_id",
+ "announcement_id"
+ ]
+ }
+ }
+ },
+ "public.group_courses": {
+ "name": "group_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enrolled_by": {
+ "name": "enrolled_by",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_mandatory": {
+ "name": "is_mandatory",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "due_date": {
+ "name": "due_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_courses_tenant_id_idx": {
+ "name": "group_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_courses_group_id_groups_id_fk": {
+ "name": "group_courses_group_id_groups_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_courses_course_id_courses_id_fk": {
+ "name": "group_courses_course_id_courses_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_courses_enrolled_by_users_id_fk": {
+ "name": "group_courses_enrolled_by_users_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "enrolled_by"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "group_courses_calendar_event_id_calendar_events_id_fk": {
+ "name": "group_courses_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "group_courses_tenant_id_tenants_id_fk": {
+ "name": "group_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_courses_calendar_event_id_unique": {
+ "name": "group_courses_calendar_event_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "calendar_event_id"
+ ]
+ },
+ "group_courses_group_id_course_id_unique": {
+ "name": "group_courses_group_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "group_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.group_learning_paths": {
+ "name": "group_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_learning_paths_tenant_id_idx": {
+ "name": "group_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "group_learning_paths_learning_path_idx": {
+ "name": "group_learning_paths_learning_path_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_learning_paths_group_id_groups_id_fk": {
+ "name": "group_learning_paths_group_id_groups_id_fk",
+ "tableFrom": "group_learning_paths",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "group_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "group_learning_paths",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "group_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "group_learning_paths",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_learning_paths_group_id_learning_path_id_unique": {
+ "name": "group_learning_paths_group_id_learning_path_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "group_id",
+ "learning_path_id"
+ ]
+ }
+ }
+ },
+ "public.group_users": {
+ "name": "group_users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_users_tenant_id_idx": {
+ "name": "group_users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_users_user_id_users_id_fk": {
+ "name": "group_users_user_id_users_id_fk",
+ "tableFrom": "group_users",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_users_group_id_groups_id_fk": {
+ "name": "group_users_group_id_groups_id_fk",
+ "tableFrom": "group_users",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_users_tenant_id_tenants_id_fk": {
+ "name": "group_users_tenant_id_tenants_id_fk",
+ "tableFrom": "group_users",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_users_user_id_group_id_unique": {
+ "name": "group_users_user_id_group_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "group_id"
+ ]
+ }
+ }
+ },
+ "public.groups": {
+ "name": "groups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "characteristic": {
+ "name": "characteristic",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "groups_tenant_id_idx": {
+ "name": "groups_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "groups_tenant_id_tenants_id_fk": {
+ "name": "groups_tenant_id_tenants_id_fk",
+ "tableFrom": "groups",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.integration_api_keys": {
+ "name": "integration_api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "key_prefix": {
+ "name": "key_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "integration_api_keys_tenant_id_idx": {
+ "name": "integration_api_keys_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "integration_api_keys_key_prefix_idx": {
+ "name": "integration_api_keys_key_prefix_idx",
+ "columns": [
+ {
+ "expression": "key_prefix",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "integration_api_keys_created_by_idx": {
+ "name": "integration_api_keys_created_by_idx",
+ "columns": [
+ {
+ "expression": "created_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "integration_api_keys_created_by_user_id_users_id_fk": {
+ "name": "integration_api_keys_created_by_user_id_users_id_fk",
+ "tableFrom": "integration_api_keys",
+ "tableTo": "users",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "integration_api_keys_tenant_id_tenants_id_fk": {
+ "name": "integration_api_keys_tenant_id_tenants_id_fk",
+ "tableFrom": "integration_api_keys",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_certificates": {
+ "name": "learning_path_certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_certificates_tenant_id_idx": {
+ "name": "learning_path_certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_certificates_user_id_users_id_fk": {
+ "name": "learning_path_certificates_user_id_users_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_certificates_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_certificates_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_certificates_tenant_id_tenants_id_fk": {
+ "name": "learning_path_certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_courses": {
+ "name": "learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_courses_tenant_id_idx": {
+ "name": "learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_courses_path_id_course_id_unique_idx": {
+ "name": "learning_path_courses_path_id_course_id_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_courses_path_id_display_order_unique_idx": {
+ "name": "learning_path_courses_path_id_display_order_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_courses_path_id_display_order_idx": {
+ "name": "learning_path_courses_path_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_courses",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_courses_course_id_courses_id_fk": {
+ "name": "learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "learning_path_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_entity_map": {
+ "name": "learning_path_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "learning_path_entity_map_export_idx": {
+ "name": "learning_path_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_entity_map_source_entity_idx": {
+ "name": "learning_path_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_entity_map_source_unique_idx": {
+ "name": "learning_path_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_entity_map_export_id_learning_path_exports_id_fk": {
+ "name": "learning_path_entity_map_export_id_learning_path_exports_id_fk",
+ "tableFrom": "learning_path_entity_map",
+ "tableTo": "learning_path_exports",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_exports": {
+ "name": "learning_path_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_learning_path_id": {
+ "name": "target_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "learning_path_exports_source_learning_path_idx": {
+ "name": "learning_path_exports_source_learning_path_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_exports_target_learning_path_idx": {
+ "name": "learning_path_exports_target_learning_path_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_exports_source_target_unique_idx": {
+ "name": "learning_path_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_exports_source_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_exports_target_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_exports_target_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_exports_target_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_exports",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "target_learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_paths": {
+ "name": "learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_reference": {
+ "name": "thumbnail_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "includes_certificate": {
+ "name": "includes_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"certificateSignature\":null,\"certificateFontColor\":null}'::jsonb"
+ },
+ "sequence_enabled": {
+ "name": "sequence_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_paths_tenant_id_idx": {
+ "name": "learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_paths_author_id_users_id_fk": {
+ "name": "learning_paths_author_id_users_id_fk",
+ "tableFrom": "learning_paths",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "learning_paths_tenant_id_tenants_id_fk": {
+ "name": "learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_paths",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.lesson_learning_time": {
+ "name": "lesson_learning_time",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_learning_time_tenant_id_idx": {
+ "name": "lesson_learning_time_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lesson_learning_time_user_course_idx": {
+ "name": "lesson_learning_time_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "lesson_learning_time_user_id_users_id_fk": {
+ "name": "lesson_learning_time_user_id_users_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_learning_time_lesson_id_lessons_id_fk": {
+ "name": "lesson_learning_time_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_learning_time_course_id_courses_id_fk": {
+ "name": "lesson_learning_time_course_id_courses_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_learning_time_tenant_id_tenants_id_fk": {
+ "name": "lesson_learning_time_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_learning_time_user_id_lesson_id_unique": {
+ "name": "lesson_learning_time_user_id_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "lesson_id"
+ ]
+ }
+ }
+ },
+ "public.lesson_video_progress": {
+ "name": "lesson_video_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_entity_id": {
+ "name": "resource_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "duration_seconds": {
+ "name": "duration_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bucket_size_seconds": {
+ "name": "bucket_size_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "watched_ranges": {
+ "name": "watched_ranges",
+ "type": "int4multirange",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::int4multirange"
+ },
+ "covered_bucket_count": {
+ "name": "covered_bucket_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "coverage_percent": {
+ "name": "coverage_percent",
+ "type": "numeric(5, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "active_watch_seconds": {
+ "name": "active_watch_seconds",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "is_watched": {
+ "name": "is_watched",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "watched_at": {
+ "name": "watched_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_video_progress_tenant_id_idx": {
+ "name": "lesson_video_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lesson_video_progress_lesson_idx": {
+ "name": "lesson_video_progress_lesson_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lesson_video_progress_resource_entity_idx": {
+ "name": "lesson_video_progress_resource_entity_idx",
+ "columns": [
+ {
+ "expression": "resource_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "lesson_video_progress_student_id_users_id_fk": {
+ "name": "lesson_video_progress_student_id_users_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_video_progress_lesson_id_lessons_id_fk": {
+ "name": "lesson_video_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_video_progress_resource_entity_id_resource_entity_id_fk": {
+ "name": "lesson_video_progress_resource_entity_id_resource_entity_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "resource_entity",
+ "columnsFrom": [
+ "resource_entity_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_video_progress_tenant_id_tenants_id_fk": {
+ "name": "lesson_video_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique": {
+ "name": "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "resource_entity_id"
+ ]
+ }
+ }
+ },
+ "public.lessons": {
+ "name": "lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "threshold_score": {
+ "name": "threshold_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts_limit": {
+ "name": "attempts_limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quiz_cooldown_in_hours": {
+ "name": "quiz_cooldown_in_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_s3_key": {
+ "name": "file_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_external": {
+ "name": "is_external",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lessons_tenant_id_idx": {
+ "name": "lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lessons_tenant_id_chapter_id_type_idx": {
+ "name": "lessons_tenant_id_chapter_id_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chapter_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "lessons_chapter_id_chapters_id_fk": {
+ "name": "lessons_chapter_id_chapters_id_fk",
+ "tableFrom": "lessons",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lessons_tenant_id_tenants_id_fk": {
+ "name": "lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "lessons",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_lessons": {
+ "name": "live_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_link_id": {
+ "name": "live_training_link_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_lessons_tenant_id_idx": {
+ "name": "live_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_lessons_lesson_language_unique_idx": {
+ "name": "live_lessons_lesson_language_unique_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_lessons_training_link_idx": {
+ "name": "live_lessons_training_link_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_link_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_lessons_training_idx": {
+ "name": "live_lessons_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_lessons_live_training_id_live_trainings_id_fk": {
+ "name": "live_lessons_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_lessons_live_training_link_id_live_training_links_id_fk": {
+ "name": "live_lessons_live_training_link_id_live_training_links_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "live_training_links",
+ "columnsFrom": [
+ "live_training_link_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_lessons_lesson_id_lessons_id_fk": {
+ "name": "live_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_lessons_tenant_id_tenants_id_fk": {
+ "name": "live_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_attendance": {
+ "name": "live_training_attendance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_participant_id": {
+ "name": "live_training_session_participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "joined_at": {
+ "name": "joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "left_at": {
+ "name": "left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_participant_sid": {
+ "name": "livekit_participant_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disconnect_reason": {
+ "name": "disconnect_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_attendance_tenant_id_idx": {
+ "name": "live_training_attendance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_attendance_session_user_idx": {
+ "name": "live_training_attendance_session_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_attendance_training_user_idx": {
+ "name": "live_training_attendance_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_attendance_joined_at_idx": {
+ "name": "live_training_attendance_joined_at_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "joined_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk": {
+ "name": "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "live_training_session_participants",
+ "columnsFrom": [
+ "live_training_session_participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_attendance_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "live_training_sessions",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_attendance_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_user_id_users_id_fk": {
+ "name": "live_training_attendance_user_id_users_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_tenant_id_tenants_id_fk": {
+ "name": "live_training_attendance_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_links": {
+ "name": "live_training_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'course'"
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_links_tenant_id_idx": {
+ "name": "live_training_links_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_links_training_entity_unique_idx": {
+ "name": "live_training_links_training_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_links_training_idx": {
+ "name": "live_training_links_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_links_entity_idx": {
+ "name": "live_training_links_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_links_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_links_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_links",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_links_tenant_id_tenants_id_fk": {
+ "name": "live_training_links_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_links",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_members": {
+ "name": "live_training_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'host'"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_members_tenant_id_idx": {
+ "name": "live_training_members_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_training_user_unique_idx": {
+ "name": "live_training_members_training_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_training_idx": {
+ "name": "live_training_members_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_user_idx": {
+ "name": "live_training_members_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_role_idx": {
+ "name": "live_training_members_role_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_members_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_members_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_members",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_members_user_id_users_id_fk": {
+ "name": "live_training_members_user_id_users_id_fk",
+ "tableFrom": "live_training_members",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_members_tenant_id_tenants_id_fk": {
+ "name": "live_training_members_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_members",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_session_participants": {
+ "name": "live_training_session_participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_joined_at": {
+ "name": "first_joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_left_at": {
+ "name": "last_left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "join_count": {
+ "name": "join_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "livekit_identity": {
+ "name": "livekit_identity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_session_participants_tenant_id_idx": {
+ "name": "live_training_session_participants_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_session_user_unique_idx": {
+ "name": "live_training_session_participants_session_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_session_idx": {
+ "name": "live_training_session_participants_session_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_training_user_idx": {
+ "name": "live_training_session_participants_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_user_idx": {
+ "name": "live_training_session_participants_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "live_training_sessions",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_session_participants_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_session_participants_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_session_participants_user_id_users_id_fk": {
+ "name": "live_training_session_participants_user_id_users_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_session_participants_tenant_id_tenants_id_fk": {
+ "name": "live_training_session_participants_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_sessions": {
+ "name": "live_training_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'waiting'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_by_user_id": {
+ "name": "started_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_by_user_id": {
+ "name": "ended_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "end_reason": {
+ "name": "end_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_name": {
+ "name": "livekit_room_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_sid": {
+ "name": "livekit_room_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "peak_participant_count": {
+ "name": "peak_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "unique_participant_count": {
+ "name": "unique_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_sessions_tenant_id_idx": {
+ "name": "live_training_sessions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_sessions_training_idx": {
+ "name": "live_training_sessions_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_sessions_status_idx": {
+ "name": "live_training_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_sessions_livekit_room_name_idx": {
+ "name": "live_training_sessions_livekit_room_name_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "livekit_room_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_sessions_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_sessions_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_sessions_started_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_started_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "started_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_sessions_ended_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_ended_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "ended_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_sessions_tenant_id_tenants_id_fk": {
+ "name": "live_training_sessions_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_trainings": {
+ "name": "live_trainings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "delivery_type": {
+ "name": "delivery_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'online'"
+ },
+ "visibility_scope": {
+ "name": "visibility_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'linked_courses'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "max_participants": {
+ "name": "max_participants",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"viewerPermissions\":{\"microphoneEnabled\":false,\"cameraEnabled\":false}}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_trainings_tenant_id_idx": {
+ "name": "live_trainings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_trainings_tenant_status_idx": {
+ "name": "live_trainings_tenant_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_trainings_author_idx": {
+ "name": "live_trainings_author_idx",
+ "columns": [
+ {
+ "expression": "author_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_trainings_calendar_event_id_calendar_events_id_fk": {
+ "name": "live_trainings_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "live_trainings",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_trainings_author_id_users_id_fk": {
+ "name": "live_trainings_author_id_users_id_fk",
+ "tableFrom": "live_trainings",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_trainings_tenant_id_tenants_id_fk": {
+ "name": "live_trainings_tenant_id_tenants_id_fk",
+ "tableFrom": "live_trainings",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "live_trainings_calendar_event_id_unique": {
+ "name": "live_trainings_calendar_event_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "calendar_event_id"
+ ]
+ }
+ }
+ },
+ "public.luma_course_generation_syncs": {
+ "name": "luma_course_generation_syncs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_id": {
+ "name": "draft_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failed_at": {
+ "name": "failed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dismissed_at": {
+ "name": "dismissed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "luma_course_generation_syncs_tenant_id_idx": {
+ "name": "luma_course_generation_syncs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "luma_course_generation_syncs_course_id_idx": {
+ "name": "luma_course_generation_syncs_course_id_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "luma_course_generation_syncs_status_idx": {
+ "name": "luma_course_generation_syncs_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "luma_course_generation_syncs_course_id_courses_id_fk": {
+ "name": "luma_course_generation_syncs_course_id_courses_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "luma_course_generation_syncs_tenant_id_tenants_id_fk": {
+ "name": "luma_course_generation_syncs_tenant_id_tenants_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "luma_course_generation_syncs_course_id_unique": {
+ "name": "luma_course_generation_syncs_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.magic_link_tokens": {
+ "name": "magic_link_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "magic_link_tokens_tenant_id_idx": {
+ "name": "magic_link_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "magic_link_tokens_token_hash_idx": {
+ "name": "magic_link_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "magic_link_tokens_user_id_users_id_fk": {
+ "name": "magic_link_tokens_user_id_users_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "magic_link_tokens_tenant_id_tenants_id_fk": {
+ "name": "magic_link_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_entity_map": {
+ "name": "master_course_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "master_course_entity_map_export_idx": {
+ "name": "master_course_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_entity_map_source_entity_idx": {
+ "name": "master_course_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_entity_map_source_unique_idx": {
+ "name": "master_course_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "master_course_entity_map_export_id_master_course_exports_id_fk": {
+ "name": "master_course_entity_map_export_id_master_course_exports_id_fk",
+ "tableFrom": "master_course_entity_map",
+ "tableTo": "master_course_exports",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_exports": {
+ "name": "master_course_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_course_id": {
+ "name": "target_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "master_course_exports_source_course_idx": {
+ "name": "master_course_exports_source_course_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_exports_target_course_idx": {
+ "name": "master_course_exports_target_course_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_exports_source_target_unique_idx": {
+ "name": "master_course_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "master_course_exports_source_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "master_course_exports_source_course_id_courses_id_fk": {
+ "name": "master_course_exports_source_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "source_course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "master_course_exports_target_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "master_course_exports_target_course_id_courses_id_fk": {
+ "name": "master_course_exports_target_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "target_course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.news": {
+ "name": "news",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "news_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "news_tenant_id_idx": {
+ "name": "news_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "news_author_id_users_id_fk": {
+ "name": "news_author_id_users_id_fk",
+ "tableFrom": "news",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "news_tenant_id_tenants_id_fk": {
+ "name": "news_tenant_id_tenants_id_fk",
+ "tableFrom": "news",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.outbox_events": {
+ "name": "outbox_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "outbox_events_tenant_id_idx": {
+ "name": "outbox_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "outbox_events_poll_idx": {
+ "name": "outbox_events_poll_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "outbox_events_tenant_id_tenants_id_fk": {
+ "name": "outbox_events_tenant_id_tenants_id_fk",
+ "tableFrom": "outbox_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_role_rule_sets": {
+ "name": "permission_role_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_role_rule_sets_tenant_id_idx": {
+ "name": "permission_role_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_role_rule_sets_role_id_rule_set_id_unique": {
+ "name": "permission_role_rule_sets_role_id_rule_set_id_unique",
+ "columns": [
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_role_rule_sets_role_id_permission_roles_id_fk": {
+ "name": "permission_role_rule_sets_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "tableTo": "permission_roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "tableTo": "permission_rule_sets",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_role_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_role_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_roles": {
+ "name": "permission_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_roles_tenant_id_idx": {
+ "name": "permission_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_roles_tenant_id_slug_unique": {
+ "name": "permission_roles_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_roles",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_set_permissions": {
+ "name": "permission_rule_set_permissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission": {
+ "name": "permission",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_set_permissions_tenant_id_idx": {
+ "name": "permission_rule_set_permissions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_rule_set_permissions_rule_set_id_permission_unique": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_unique",
+ "columns": [
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "tableTo": "permission_rule_sets",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_rule_set_permissions_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_set_permissions_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_sets": {
+ "name": "permission_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_sets_tenant_id_idx": {
+ "name": "permission_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_rule_sets_tenant_id_slug_unique": {
+ "name": "permission_rule_sets_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_sets",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_user_roles": {
+ "name": "permission_user_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_user_roles_tenant_id_idx": {
+ "name": "permission_user_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_user_roles_user_id_role_id_unique": {
+ "name": "permission_user_roles_user_id_role_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_user_roles_user_id_users_id_fk": {
+ "name": "permission_user_roles_user_id_users_id_fk",
+ "tableFrom": "permission_user_roles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_user_roles_role_id_permission_roles_id_fk": {
+ "name": "permission_user_roles_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_user_roles",
+ "tableTo": "permission_roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_user_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_user_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_user_roles",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.question_answer_options": {
+ "name": "question_answer_options",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "option_text": {
+ "name": "option_text",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_word": {
+ "name": "matched_word",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scale_answer": {
+ "name": "scale_answer",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "question_answer_options_tenant_id_idx": {
+ "name": "question_answer_options_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "question_answer_options_question_id_questions_id_fk": {
+ "name": "question_answer_options_question_id_questions_id_fk",
+ "tableFrom": "question_answer_options",
+ "tableTo": "questions",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "question_answer_options_tenant_id_tenants_id_fk": {
+ "name": "question_answer_options_tenant_id_tenants_id_fk",
+ "tableFrom": "question_answer_options",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions": {
+ "name": "questions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "photo_s3_key": {
+ "name": "photo_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "solution_explanation": {
+ "name": "solution_explanation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_tenant_id_idx": {
+ "name": "questions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "questions_lesson_id_lessons_id_fk": {
+ "name": "questions_lesson_id_lessons_id_fk",
+ "tableFrom": "questions",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "questions_author_id_users_id_fk": {
+ "name": "questions_author_id_users_id_fk",
+ "tableFrom": "questions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "questions_tenant_id_tenants_id_fk": {
+ "name": "questions_tenant_id_tenants_id_fk",
+ "tableFrom": "questions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions_and_answers": {
+ "name": "questions_and_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_and_answers_tenant_id_idx": {
+ "name": "questions_and_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "questions_and_answers_tenant_id_tenants_id_fk": {
+ "name": "questions_and_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "questions_and_answers",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.quiz_attempts": {
+ "name": "quiz_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "correct_answers": {
+ "name": "correct_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wrong_answers": {
+ "name": "wrong_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "quiz_attempts_tenant_id_idx": {
+ "name": "quiz_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "quiz_attempts_user_id_users_id_fk": {
+ "name": "quiz_attempts_user_id_users_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "quiz_attempts_course_id_courses_id_fk": {
+ "name": "quiz_attempts_course_id_courses_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "quiz_attempts_lesson_id_lessons_id_fk": {
+ "name": "quiz_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "quiz_attempts_tenant_id_tenants_id_fk": {
+ "name": "quiz_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.reset_tokens": {
+ "name": "reset_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "reset_tokens_tenant_id_idx": {
+ "name": "reset_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "reset_tokens_token_hash_idx": {
+ "name": "reset_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "reset_tokens_user_id_users_id_fk": {
+ "name": "reset_tokens_user_id_users_id_fk",
+ "tableFrom": "reset_tokens",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "reset_tokens_tenant_id_tenants_id_fk": {
+ "name": "reset_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "reset_tokens",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.resource_entity": {
+ "name": "resource_entity",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "relationship_type": {
+ "name": "relationship_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'attachment'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resource_entity_tenant_id_idx": {
+ "name": "resource_entity_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_entity_resource_idx": {
+ "name": "resource_entity_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_entity_entity_idx": {
+ "name": "resource_entity_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_entity_relationship_idx": {
+ "name": "resource_entity_relationship_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "relationship_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "resource_entity_resource_id_resources_id_fk": {
+ "name": "resource_entity_resource_id_resources_id_fk",
+ "tableFrom": "resource_entity",
+ "tableTo": "resources",
+ "columnsFrom": [
+ "resource_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "resource_entity_tenant_id_tenants_id_fk": {
+ "name": "resource_entity_tenant_id_tenants_id_fk",
+ "tableFrom": "resource_entity",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique": {
+ "name": "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "resource_id",
+ "entity_id",
+ "entity_type",
+ "relationship_type"
+ ]
+ }
+ }
+ },
+ "public.resources": {
+ "name": "resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reference": {
+ "name": "reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "uploaded_by_id": {
+ "name": "uploaded_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resources_tenant_id_idx": {
+ "name": "resources_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "resources_uploaded_by_id_users_id_fk": {
+ "name": "resources_uploaded_by_id_users_id_fk",
+ "tableFrom": "resources",
+ "tableTo": "users",
+ "columnsFrom": [
+ "uploaded_by_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "resources_tenant_id_tenants_id_fk": {
+ "name": "resources_tenant_id_tenants_id_fk",
+ "tableFrom": "resources",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_attempts": {
+ "name": "scorm_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sco_id": {
+ "name": "sco_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attempt_number": {
+ "name": "attempt_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_attempts_tenant_id_idx": {
+ "name": "scorm_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_student_lesson_idx": {
+ "name": "scorm_attempts_student_lesson_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_student_package_idx": {
+ "name": "scorm_attempts_student_package_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_sco_id_idx": {
+ "name": "scorm_attempts_sco_id_idx",
+ "columns": [
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_student_package_sco_attempt_unique_idx": {
+ "name": "scorm_attempts_student_package_sco_attempt_unique_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "attempt_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_attempts_student_id_users_id_fk": {
+ "name": "scorm_attempts_student_id_users_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_course_id_courses_id_fk": {
+ "name": "scorm_attempts_course_id_courses_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_lesson_id_lessons_id_fk": {
+ "name": "scorm_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_package_id_scorm_packages_id_fk": {
+ "name": "scorm_attempts_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "scorm_packages",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_sco_id_scorm_scos_id_fk": {
+ "name": "scorm_attempts_sco_id_scorm_scos_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "scorm_scos",
+ "columnsFrom": [
+ "sco_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_tenant_id_tenants_id_fk": {
+ "name": "scorm_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_packages": {
+ "name": "scorm_packages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "scorm_package_entity_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "standard": {
+ "name": "standard",
+ "type": "scorm_standard",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_file_reference": {
+ "name": "original_file_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "extracted_files_reference": {
+ "name": "extracted_files_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_entry_point": {
+ "name": "manifest_entry_point",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_json": {
+ "name": "manifest_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "scorm_package_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_packages_tenant_id_idx": {
+ "name": "scorm_packages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_packages_entity_idx": {
+ "name": "scorm_packages_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_packages_entity_unique_idx": {
+ "name": "scorm_packages_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_packages_tenant_id_tenants_id_fk": {
+ "name": "scorm_packages_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_packages",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_runtime_state": {
+ "name": "scorm_runtime_state",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "attempt_id": {
+ "name": "attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completion_status": {
+ "name": "completion_status",
+ "type": "scorm_completion_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "success_status": {
+ "name": "success_status",
+ "type": "scorm_success_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "score_raw": {
+ "name": "score_raw",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_min": {
+ "name": "score_min",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_max": {
+ "name": "score_max",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_scaled": {
+ "name": "score_scaled",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_location": {
+ "name": "lesson_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspend_data": {
+ "name": "suspend_data",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_time": {
+ "name": "session_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_time": {
+ "name": "total_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "progress_measure": {
+ "name": "progress_measure",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "entry": {
+ "name": "entry",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exit": {
+ "name": "exit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_cmi_json": {
+ "name": "raw_cmi_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_runtime_state_tenant_id_idx": {
+ "name": "scorm_runtime_state_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_runtime_state_attempt_id_unique_idx": {
+ "name": "scorm_runtime_state_attempt_id_unique_idx",
+ "columns": [
+ {
+ "expression": "attempt_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_runtime_state_attempt_id_scorm_attempts_id_fk": {
+ "name": "scorm_runtime_state_attempt_id_scorm_attempts_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "tableTo": "scorm_attempts",
+ "columnsFrom": [
+ "attempt_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_runtime_state_tenant_id_tenants_id_fk": {
+ "name": "scorm_runtime_state_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_scos": {
+ "name": "scorm_scos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_identifier": {
+ "name": "organization_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "identifier_ref": {
+ "name": "identifier_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_identifier": {
+ "name": "resource_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scorm_type": {
+ "name": "scorm_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "href": {
+ "name": "href",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "launch_path": {
+ "name": "launch_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parameters": {
+ "name": "parameters",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_identifier": {
+ "name": "parent_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_visible": {
+ "name": "is_visible",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "item_metadata_json": {
+ "name": "item_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_metadata_json": {
+ "name": "resource_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_scos_tenant_id_idx": {
+ "name": "scorm_scos_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_scos_package_id_idx": {
+ "name": "scorm_scos_package_id_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_scos_lesson_id_idx": {
+ "name": "scorm_scos_lesson_id_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_scos_package_identifier_unique_idx": {
+ "name": "scorm_scos_package_identifier_unique_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_scos_package_id_scorm_packages_id_fk": {
+ "name": "scorm_scos_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_scos",
+ "tableTo": "scorm_packages",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_scos_lesson_id_lessons_id_fk": {
+ "name": "scorm_scos_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_scos",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_scos_tenant_id_tenants_id_fk": {
+ "name": "scorm_scos_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_scos",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.search_documents": {
+ "name": "search_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "search_vector": {
+ "name": "search_vector",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "search_documents_tenant_id_idx": {
+ "name": "search_documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "search_documents_vector_idx": {
+ "name": "search_documents_vector_idx",
+ "columns": [
+ {
+ "expression": "search_vector",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ },
+ "search_documents_language_entity_type_idx": {
+ "name": "search_documents_language_entity_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "search_documents_entity_idx": {
+ "name": "search_documents_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "search_documents_document_unique_idx": {
+ "name": "search_documents_document_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "search_documents_tenant_id_tenants_id_fk": {
+ "name": "search_documents_tenant_id_tenants_id_fk",
+ "tableFrom": "search_documents",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.secrets": {
+ "name": "secrets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "secret_name": {
+ "name": "secret_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "ciphertext": {
+ "name": "ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "iv": {
+ "name": "iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tag": {
+ "name": "tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek": {
+ "name": "encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_iv": {
+ "name": "encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_tag": {
+ "name": "encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "alg": {
+ "name": "alg",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'AES-256-GCM'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "secrets_tenant_id_idx": {
+ "name": "secrets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "secrets_tenant_secret_name_uq": {
+ "name": "secrets_tenant_secret_name_uq",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "secrets_name_idx": {
+ "name": "secrets_name_idx",
+ "columns": [
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "secrets_tenant_id_tenants_id_fk": {
+ "name": "secrets_tenant_id_tenants_id_fk",
+ "tableFrom": "secrets",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.settings": {
+ "name": "settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "settings_tenant_id_idx": {
+ "name": "settings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "settings_user_id_users_id_fk": {
+ "name": "settings_user_id_users_id_fk",
+ "tableFrom": "settings",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "settings_tenant_id_tenants_id_fk": {
+ "name": "settings_tenant_id_tenants_id_fk",
+ "tableFrom": "settings",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.student_chapter_progress": {
+ "name": "student_chapter_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_lesson_count": {
+ "name": "completed_lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_as_freemium": {
+ "name": "completed_as_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_chapter_progress_tenant_id_idx": {
+ "name": "student_chapter_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_chapter_progress_student_id_users_id_fk": {
+ "name": "student_chapter_progress_student_id_users_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_course_id_courses_id_fk": {
+ "name": "student_chapter_progress_course_id_courses_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_chapter_id_chapters_id_fk": {
+ "name": "student_chapter_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_tenant_id_tenants_id_fk": {
+ "name": "student_chapter_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_chapter_progress_student_id_course_id_chapter_id_unique": {
+ "name": "student_chapter_progress_student_id_course_id_chapter_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "course_id",
+ "chapter_id"
+ ]
+ }
+ }
+ },
+ "public.student_courses": {
+ "name": "student_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "finished_chapter_count": {
+ "name": "finished_chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "course_completion_metadata": {
+ "name": "course_completion_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'enrolled'"
+ },
+ "payment_id": {
+ "name": "payment_id",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_by_group_id": {
+ "name": "enrolled_by_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_courses_tenant_id_idx": {
+ "name": "student_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_courses_tenant_id_course_status_student_idx": {
+ "name": "student_courses_tenant_id_course_status_student_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_courses_student_id_users_id_fk": {
+ "name": "student_courses_student_id_users_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_courses_course_id_courses_id_fk": {
+ "name": "student_courses_course_id_courses_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_courses_enrolled_by_group_id_groups_id_fk": {
+ "name": "student_courses_enrolled_by_group_id_groups_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "enrolled_by_group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_courses_tenant_id_tenants_id_fk": {
+ "name": "student_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_courses_student_id_course_id_unique": {
+ "name": "student_courses_student_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.student_learning_path_courses": {
+ "name": "student_learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_path_courses_tenant_id_idx": {
+ "name": "student_learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_learning_path_courses_student_path_idx": {
+ "name": "student_learning_path_courses_student_path_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_learning_path_courses_course_idx": {
+ "name": "student_learning_path_courses_course_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_learning_path_courses_student_id_users_id_fk": {
+ "name": "student_learning_path_courses_student_id_users_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_path_courses_course_id_courses_id_fk": {
+ "name": "student_learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "student_learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_path_courses_student_id_learning_path_id_course_id_unique": {
+ "name": "student_learning_path_courses_student_id_learning_path_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "learning_path_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.student_learning_paths": {
+ "name": "student_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "enrollment_type": {
+ "name": "enrollment_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'direct'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_paths_tenant_id_idx": {
+ "name": "student_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_learning_paths_student_id_users_id_fk": {
+ "name": "student_learning_paths_student_id_users_id_fk",
+ "tableFrom": "student_learning_paths",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_paths",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "student_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_paths",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_paths_student_id_learning_path_id_unique": {
+ "name": "student_learning_paths_student_id_learning_path_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "learning_path_id"
+ ]
+ }
+ }
+ },
+ "public.student_lesson_progress": {
+ "name": "student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_question_count": {
+ "name": "completed_question_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "quiz_score": {
+ "name": "quiz_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_quiz_passed": {
+ "name": "is_quiz_passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_started": {
+ "name": "is_started",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "language_answered": {
+ "name": "language_answered",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_lesson_progress_tenant_id_idx": {
+ "name": "student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_lesson_progress_completed_quiz_score_idx": {
+ "name": "student_lesson_progress_completed_quiz_score_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"student_lesson_progress\".\"completed_at\" IS NOT NULL AND \"student_lesson_progress\".\"quiz_score\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_lesson_progress_student_id_users_id_fk": {
+ "name": "student_lesson_progress_student_id_users_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "student_lesson_progress_chapter_id_chapters_id_fk": {
+ "name": "student_lesson_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_lesson_progress_lesson_id_lessons_id_fk": {
+ "name": "student_lesson_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_lesson_progress_student_id_lesson_id_chapter_id_unique": {
+ "name": "student_lesson_progress_student_id_lesson_id_chapter_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "chapter_id"
+ ]
+ }
+ }
+ },
+ "public.student_question_answers": {
+ "name": "student_question_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "answer": {
+ "name": "answer",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_question_answers_tenant_id_idx": {
+ "name": "student_question_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_question_answers_question_id_questions_id_fk": {
+ "name": "student_question_answers_question_id_questions_id_fk",
+ "tableFrom": "student_question_answers",
+ "tableTo": "questions",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_question_answers_student_id_users_id_fk": {
+ "name": "student_question_answers_student_id_users_id_fk",
+ "tableFrom": "student_question_answers",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_question_answers_tenant_id_tenants_id_fk": {
+ "name": "student_question_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "student_question_answers",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_question_answers_question_id_student_id_unique": {
+ "name": "student_question_answers_question_id_student_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "question_id",
+ "student_id"
+ ]
+ }
+ }
+ },
+ "public.support_sessions": {
+ "name": "support_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "original_user_id": {
+ "name": "original_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_tenant_id": {
+ "name": "original_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_user_id": {
+ "name": "target_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hashed_grant_token": {
+ "name": "hashed_grant_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_expires_at": {
+ "name": "grant_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "activated_at": {
+ "name": "activated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "return_url": {
+ "name": "return_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ }
+ },
+ "indexes": {
+ "support_sessions_hashed_grant_token_unique": {
+ "name": "support_sessions_hashed_grant_token_unique",
+ "columns": [
+ {
+ "expression": "hashed_grant_token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_status_idx": {
+ "name": "support_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_original_user_idx": {
+ "name": "support_sessions_original_user_idx",
+ "columns": [
+ {
+ "expression": "original_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_target_tenant_idx": {
+ "name": "support_sessions_target_tenant_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_target_user_idx": {
+ "name": "support_sessions_target_user_idx",
+ "columns": [
+ {
+ "expression": "target_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "support_sessions_original_user_id_users_id_fk": {
+ "name": "support_sessions_original_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "original_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "support_sessions_original_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_original_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "original_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "support_sessions_target_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_target_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "support_sessions_target_user_id_users_id_fk": {
+ "name": "support_sessions_target_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "target_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.tenants": {
+ "name": "tenants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "host": {
+ "name": "host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "is_managing": {
+ "name": "is_managing",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ }
+ },
+ "indexes": {
+ "unique_host_idx": {
+ "name": "unique_host_idx",
+ "columns": [
+ {
+ "expression": "host",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user_announcements": {
+ "name": "user_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_read": {
+ "name": "is_read",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "read_at": {
+ "name": "read_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_announcements_tenant_id_idx": {
+ "name": "user_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_announcements_user_id_users_id_fk": {
+ "name": "user_announcements_user_id_users_id_fk",
+ "tableFrom": "user_announcements",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_announcements_announcement_id_announcements_id_fk": {
+ "name": "user_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "user_announcements",
+ "tableTo": "announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_announcements_tenant_id_tenants_id_fk": {
+ "name": "user_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "user_announcements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_announcements_user_id_announcement_id_unique": {
+ "name": "user_announcements_user_id_announcement_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "announcement_id"
+ ]
+ }
+ }
+ },
+ "public.user_details": {
+ "name": "user_details",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_phone_number": {
+ "name": "contact_phone_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contact_email": {
+ "name": "contact_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "job_title": {
+ "name": "job_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_details_tenant_id_idx": {
+ "name": "user_details_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_details_user_id_users_id_fk": {
+ "name": "user_details_user_id_users_id_fk",
+ "tableFrom": "user_details",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_details_tenant_id_tenants_id_fk": {
+ "name": "user_details_tenant_id_tenants_id_fk",
+ "tableFrom": "user_details",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_details_user_id_unique": {
+ "name": "user_details_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ }
+ },
+ "public.user_onboarding": {
+ "name": "user_onboarding",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dashboard": {
+ "name": "dashboard",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "courses": {
+ "name": "courses",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "announcements": {
+ "name": "announcements",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "profile": {
+ "name": "profile",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "provider_information": {
+ "name": "provider_information",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_onboarding_tenant_id_idx": {
+ "name": "user_onboarding_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_onboarding_user_id_users_id_fk": {
+ "name": "user_onboarding_user_id_users_id_fk",
+ "tableFrom": "user_onboarding",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_onboarding_tenant_id_tenants_id_fk": {
+ "name": "user_onboarding_tenant_id_tenants_id_fk",
+ "tableFrom": "user_onboarding",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_onboarding_user_id_unique": {
+ "name": "user_onboarding_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ }
+ },
+ "public.user_statistics": {
+ "name": "user_statistics",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_streak": {
+ "name": "current_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "longest_streak": {
+ "name": "longest_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_activity_date": {
+ "name": "last_activity_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activity_history": {
+ "name": "activity_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_statistics_tenant_id_idx": {
+ "name": "user_statistics_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_statistics_user_id_users_id_fk": {
+ "name": "user_statistics_user_id_users_id_fk",
+ "tableFrom": "user_statistics",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_statistics_tenant_id_tenants_id_fk": {
+ "name": "user_statistics_tenant_id_tenants_id_fk",
+ "tableFrom": "user_statistics",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_statistics_user_id_unique": {
+ "name": "user_statistics_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ }
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_name": {
+ "name": "first_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_name": {
+ "name": "last_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "users_tenant_id_idx": {
+ "name": "users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "users_tenant_id_email_unique_idx": {
+ "name": "users_tenant_id_email_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "users_tenant_id_tenants_id_fk": {
+ "name": "users_tenant_id_tenants_id_fk",
+ "tableFrom": "users",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_connections": {
+ "name": "calendar_connections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_email": {
+ "name": "account_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_ciphertext": {
+ "name": "refresh_token_ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_iv": {
+ "name": "refresh_token_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_tag": {
+ "name": "refresh_token_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek": {
+ "name": "refresh_token_encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_iv": {
+ "name": "refresh_token_encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_tag": {
+ "name": "refresh_token_encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'syncing'"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_cursor": {
+ "name": "sync_cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_start": {
+ "name": "sync_window_start",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_end": {
+ "name": "sync_window_end",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "window_built_at": {
+ "name": "window_built_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_successful_sync_at": {
+ "name": "last_successful_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_completed_at": {
+ "name": "last_sync_completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_client_state": {
+ "name": "subscription_client_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_expires_at": {
+ "name": "subscription_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_sync_enabled": {
+ "name": "outbound_sync_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "outbound_status": {
+ "name": "outbound_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'disabled'"
+ },
+ "outbound_calendar_id": {
+ "name": "outbound_calendar_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_error_code": {
+ "name": "outbound_error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_outbound_sync_at": {
+ "name": "last_outbound_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_connections_tenant_id_idx": {
+ "name": "calendar_connections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_tenant_user_provider_unique_idx": {
+ "name": "calendar_connections_tenant_user_provider_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_subscription_idx": {
+ "name": "calendar_connections_subscription_idx",
+ "columns": [
+ {
+ "expression": "subscription_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_connections_user_id_users_id_fk": {
+ "name": "calendar_connections_user_id_users_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_connections_tenant_id_tenants_id_fk": {
+ "name": "calendar_connections_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_external_events": {
+ "name": "calendar_external_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "web_link": {
+ "name": "web_link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensitivity": {
+ "name": "sensitivity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "availability": {
+ "name": "availability",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_cancelled": {
+ "name": "is_cancelled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_external_events_tenant_id_idx": {
+ "name": "calendar_external_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_calendar_event_unique_idx": {
+ "name": "calendar_external_events_calendar_event_unique_idx",
+ "columns": [
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_connection_event_unique_idx": {
+ "name": "calendar_external_events_tenant_connection_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_user_idx": {
+ "name": "calendar_external_events_tenant_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_external_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_external_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_external_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_user_id_users_id_fk": {
+ "name": "calendar_external_events_user_id_users_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_external_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_outbound_events": {
+ "name": "calendar_outbound_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_outbound_events_tenant_id_idx": {
+ "name": "calendar_outbound_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_event_user_unique_idx": {
+ "name": "calendar_outbound_events_connection_event_user_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_external_event_unique_idx": {
+ "name": "calendar_outbound_events_connection_external_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_calendar_event_idx": {
+ "name": "calendar_outbound_events_calendar_event_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_outbound_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_outbound_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_outbound_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_user_id_users_id_fk": {
+ "name": "calendar_outbound_events_user_id_users_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_outbound_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_configurations": {
+ "name": "ai_mentor_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "structured_ai_mentor_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opening_instruction": {
+ "name": "opening_instruction",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "additional_instructions": {
+ "name": "additional_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_configurations_tenant_id_idx": {
+ "name": "ai_mentor_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "ai_mentor_lesson_id"
+ ]
+ }
+ }
+ },
+ "public.ai_mentor_roleplay_configurations": {
+ "name": "ai_mentor_roleplay_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario": {
+ "name": "scenario",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "ai_role": {
+ "name": "ai_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "learner_role": {
+ "name": "learner_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "character_goal": {
+ "name": "character_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "difficulty": {
+ "name": "difficulty",
+ "type": "ai_mentor_roleplay_difficulty",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "facts_and_constraints": {
+ "name": "facts_and_constraints",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_roleplay_configurations_tenant_id_idx": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "tableTo": "ai_mentor_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_roleplay_configurations_configuration_id_unique": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "configuration_id"
+ ]
+ }
+ }
+ },
+ "public.ai_mentor_teacher_configurations": {
+ "name": "ai_mentor_teacher_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expertise": {
+ "name": "expertise",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content_scope": {
+ "name": "content_scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "teaching_style": {
+ "name": "teaching_style",
+ "type": "ai_mentor_teaching_style",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback_guidance": {
+ "name": "feedback_guidance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_teacher_configurations_tenant_id_idx": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "tableTo": "ai_mentor_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_teacher_configurations_configuration_id_unique": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "configuration_id"
+ ]
+ }
+ }
+ }
+ },
+ "enums": {
+ "public.ai_mentor_roleplay_difficulty": {
+ "name": "ai_mentor_roleplay_difficulty",
+ "schema": "public",
+ "values": [
+ "cooperative",
+ "realistic",
+ "challenging"
+ ]
+ },
+ "public.ai_mentor_teaching_style": {
+ "name": "ai_mentor_teaching_style",
+ "schema": "public",
+ "values": [
+ "explain_and_practice",
+ "guided_discovery",
+ "socratic"
+ ]
+ },
+ "public.article_status": {
+ "name": "article_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.course_type": {
+ "name": "course_type",
+ "schema": "public",
+ "values": [
+ "default",
+ "scorm"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published",
+ "private"
+ ]
+ },
+ "public.news_status": {
+ "name": "news_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.scorm_completion_status": {
+ "name": "scorm_completion_status",
+ "schema": "public",
+ "values": [
+ "completed",
+ "incomplete",
+ "not_attempted",
+ "unknown"
+ ]
+ },
+ "public.scorm_package_entity_type": {
+ "name": "scorm_package_entity_type",
+ "schema": "public",
+ "values": [
+ "course",
+ "lesson"
+ ]
+ },
+ "public.scorm_package_status": {
+ "name": "scorm_package_status",
+ "schema": "public",
+ "values": [
+ "processing",
+ "ready",
+ "failed"
+ ]
+ },
+ "public.scorm_standard": {
+ "name": "scorm_standard",
+ "schema": "public",
+ "values": [
+ "scorm_1_2",
+ "scorm_2004"
+ ]
+ },
+ "public.scorm_success_status": {
+ "name": "scorm_success_status",
+ "schema": "public",
+ "values": [
+ "passed",
+ "failed",
+ "unknown"
+ ]
+ },
+ "public.structured_ai_mentor_type": {
+ "name": "structured_ai_mentor_type",
+ "schema": "public",
+ "values": [
+ "teacher",
+ "roleplay"
+ ]
+ }
+ },
+ "schemas": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/apps/api/src/storage/migrations/meta/0180_snapshot.json b/apps/api/src/storage/migrations/meta/0180_snapshot.json
new file mode 100644
index 0000000000..cde8d7b236
--- /dev/null
+++ b/apps/api/src/storage/migrations/meta/0180_snapshot.json
@@ -0,0 +1,15683 @@
+{
+ "id": "fce3e758-9163-4b71-b763-0ef6a51fd56b",
+ "prevId": "c0fcfff7-62ac-47ce-8ba9-f73039c39f9b",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.activity_logs": {
+ "name": "activity_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_email": {
+ "name": "actor_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_role": {
+ "name": "actor_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action_type": {
+ "name": "action_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "activity_logs_tenant_id_idx": {
+ "name": "activity_logs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_tenant_timeframe_idx": {
+ "name": "activity_logs_tenant_timeframe_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_actor_idx": {
+ "name": "activity_logs_actor_idx",
+ "columns": [
+ {
+ "expression": "actor_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_action_idx": {
+ "name": "activity_logs_action_idx",
+ "columns": [
+ {
+ "expression": "action_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_timeframe_idx": {
+ "name": "activity_logs_timeframe_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_resource_idx": {
+ "name": "activity_logs_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "activity_logs_actor_id_users_id_fk": {
+ "name": "activity_logs_actor_id_users_id_fk",
+ "tableFrom": "activity_logs",
+ "columnsFrom": [
+ "actor_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "activity_logs_tenant_id_tenants_id_fk": {
+ "name": "activity_logs_tenant_id_tenants_id_fk",
+ "tableFrom": "activity_logs",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_blocking_errors": {
+ "name": "ai_judge_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_blocking_errors_tenant_id_idx": {
+ "name": "ai_judge_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_judge_blocking_errors_configuration_id_created_at_idx": {
+ "name": "ai_judge_blocking_errors_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_judge_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_configurations": {
+ "name": "ai_judge_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "passing_threshold_percent": {
+ "name": "passing_threshold_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_configurations_tenant_id_idx": {
+ "name": "ai_judge_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_judge_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_unique",
+ "columns": [
+ "ai_mentor_lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_judge_criteria": {
+ "name": "ai_judge_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expected_behavior": {
+ "name": "expected_behavior",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_criteria_tenant_id_idx": {
+ "name": "ai_judge_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_judge_criteria_configuration_id_created_at_idx": {
+ "name": "ai_judge_criteria_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_judge_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_score_guidance": {
+ "name": "ai_judge_score_guidance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "example": {
+ "name": "example",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_score_guidance_tenant_id_idx": {
+ "name": "ai_judge_score_guidance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_judge_score_guidance_criterion_id_score_unique": {
+ "name": "ai_judge_score_guidance_criterion_id_score_unique",
+ "columns": [
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "score",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "tableTo": "ai_judge_criteria",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_score_guidance_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_score_guidance_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_blocking_errors": {
+ "name": "ai_mentor_judgement_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blocking_error_id": {
+ "name": "blocking_error_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "blocking_error_description": {
+ "name": "blocking_error_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_blocking_errors_tenant_id_idx": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "blocking_error_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "tableTo": "ai_mentor_judgements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "columnsFrom": [
+ "blocking_error_id"
+ ],
+ "tableTo": "ai_judge_blocking_errors",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_criteria": {
+ "name": "ai_mentor_judgement_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "criterion_title": {
+ "name": "criterion_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "awarded_points": {
+ "name": "awarded_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score_at_judgement": {
+ "name": "max_score_at_judgement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_criteria_tenant_id_idx": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "tableTo": "ai_mentor_judgements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "tableTo": "ai_judge_criteria",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgements": {
+ "name": "ai_mentor_judgements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "earned_points": {
+ "name": "earned_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgements_tenant_id_idx": {
+ "name": "ai_mentor_judgements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "ai_mentor_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_judge_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "ai_mentor_judgements_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgements_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_judgements_thread_id_unique": {
+ "name": "ai_mentor_judgements_thread_id_unique",
+ "columns": [
+ "thread_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_mentor_lessons": {
+ "name": "ai_mentor_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_instructions": {
+ "name": "ai_mentor_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'roleplay'"
+ },
+ "voice_mode": {
+ "name": "voice_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'preset'"
+ },
+ "tts_preset": {
+ "name": "tts_preset",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'male'"
+ },
+ "custom_tts_reference": {
+ "name": "custom_tts_reference",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_lessons_tenant_id_idx": {
+ "name": "ai_mentor_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_lessons_lesson_id_lessons_id_fk": {
+ "name": "ai_mentor_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_lessons_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_student_lesson_progress": {
+ "name": "ai_mentor_student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_lesson_progress_id": {
+ "name": "student_lesson_progress_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_score": {
+ "name": "min_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_student_lesson_progress_tenant_id_idx": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "columnsFrom": [
+ "student_lesson_progress_id"
+ ],
+ "tableTo": "student_lesson_progress",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_thread_messages": {
+ "name": "ai_mentor_thread_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_thread_messages_tenant_id_idx": {
+ "name": "ai_mentor_thread_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "ai_mentor_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_thread_messages_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_thread_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_threads": {
+ "name": "ai_mentor_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "user_language": {
+ "name": "user_language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_threads_tenant_id_idx": {
+ "name": "ai_mentor_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_threads_user_id_users_id_fk": {
+ "name": "ai_mentor_threads_user_id_users_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_threads_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.announcements": {
+ "name": "announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "audience": {
+ "name": "audience",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all_users'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'published'"
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "send_email": {
+ "name": "send_email",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "email_template": {
+ "name": "email_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "announcements_tenant_id_idx": {
+ "name": "announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "announcements_author_id_users_id_fk": {
+ "name": "announcements_author_id_users_id_fk",
+ "tableFrom": "announcements",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "announcements_tenant_id_tenants_id_fk": {
+ "name": "announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "announcements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.article_sections": {
+ "name": "article_sections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "article_sections_tenant_id_idx": {
+ "name": "article_sections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "article_sections_tenant_id_tenants_id_fk": {
+ "name": "article_sections_tenant_id_tenants_id_fk",
+ "tableFrom": "article_sections",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.articles": {
+ "name": "articles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "article_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "article_section_id": {
+ "name": "article_section_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by_id": {
+ "name": "updated_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "articles_tenant_id_idx": {
+ "name": "articles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "article_section_idx": {
+ "name": "article_section_idx",
+ "columns": [
+ {
+ "expression": "article_section_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "articles_article_section_id_article_sections_id_fk": {
+ "name": "articles_article_section_id_article_sections_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "article_section_id"
+ ],
+ "tableTo": "article_sections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "articles_author_id_users_id_fk": {
+ "name": "articles_author_id_users_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "articles_updated_by_id_users_id_fk": {
+ "name": "articles_updated_by_id_users_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "updated_by_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "articles_tenant_id_tenants_id_fk": {
+ "name": "articles_tenant_id_tenants_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_events": {
+ "name": "calendar_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "uid": {
+ "name": "uid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "all_day": {
+ "name": "all_day",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizer_user_id": {
+ "name": "organizer_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rrule": {
+ "name": "rrule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exdates": {
+ "name": "exdates",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_events_tenant_id_idx": {
+ "name": "calendar_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "calendar_events_tenant_starts_ends_idx": {
+ "name": "calendar_events_tenant_starts_ends_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starts_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "ends_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "calendar_events_tenant_uid_unique_idx": {
+ "name": "calendar_events_tenant_uid_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "uid",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "calendar_events_organizer_user_id_users_id_fk": {
+ "name": "calendar_events_organizer_user_id_users_id_fk",
+ "tableFrom": "calendar_events",
+ "columnsFrom": [
+ "organizer_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "calendar_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_events",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.categories": {
+ "name": "categories",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "categories_tenant_id_idx": {
+ "name": "categories_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "categories_tenant_id_base_title_unique": {
+ "name": "categories_tenant_id_base_title_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"title\"->>\"base_language\")",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "categories_tenant_id_tenants_id_fk": {
+ "name": "categories_tenant_id_tenants_id_fk",
+ "tableFrom": "categories",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.certificates": {
+ "name": "certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archive_reason": {
+ "name": "archive_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiration_warning_sent_at": {
+ "name": "expiration_warning_sent_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "certificates_tenant_id_idx": {
+ "name": "certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "certificates_active_expiry_idx": {
+ "name": "certificates_active_expiry_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "certificates_user_course_idx": {
+ "name": "certificates_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "certificates_user_id_users_id_fk": {
+ "name": "certificates_user_id_users_id_fk",
+ "tableFrom": "certificates",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "certificates_course_id_courses_id_fk": {
+ "name": "certificates_course_id_courses_id_fk",
+ "tableFrom": "certificates",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "certificates_tenant_id_tenants_id_fk": {
+ "name": "certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "certificates",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.chapters": {
+ "name": "chapters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_freemium": {
+ "name": "is_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_count": {
+ "name": "lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "chapters_tenant_id_idx": {
+ "name": "chapters_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chapters_tenant_id_course_id_idx": {
+ "name": "chapters_tenant_id_course_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chapters_course_id_courses_id_fk": {
+ "name": "chapters_course_id_courses_id_fk",
+ "tableFrom": "chapters",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chapters_author_id_users_id_fk": {
+ "name": "chapters_author_id_users_id_fk",
+ "tableFrom": "chapters",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chapters_tenant_id_tenants_id_fk": {
+ "name": "chapters_tenant_id_tenants_id_fk",
+ "tableFrom": "chapters",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_message_reactions": {
+ "name": "course_chat_message_reactions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reaction": {
+ "name": "reaction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_message_reactions_tenant_id_idx": {
+ "name": "course_chat_message_reactions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_message_reactions_message_id_reaction_idx": {
+ "name": "course_chat_message_reactions_message_id_reaction_idx",
+ "columns": [
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_message_reactions_user_message_reaction_unique_idx": {
+ "name": "course_chat_message_reactions_user_message_reaction_unique_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_chat_message_reactions_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_message_reactions_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "message_id"
+ ],
+ "tableTo": "course_chat_messages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_message_reactions_course_id_courses_id_fk": {
+ "name": "course_chat_message_reactions_course_id_courses_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_message_reactions_user_id_users_id_fk": {
+ "name": "course_chat_message_reactions_user_id_users_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_message_reactions_tenant_id_tenants_id_fk": {
+ "name": "course_chat_message_reactions_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_messages": {
+ "name": "course_chat_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_message_id": {
+ "name": "parent_message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_messages_tenant_id_idx": {
+ "name": "course_chat_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_messages_course_id_created_at_idx": {
+ "name": "course_chat_messages_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_messages_thread_id_created_at_idx": {
+ "name": "course_chat_messages_thread_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_messages_parent_message_id_created_at_idx": {
+ "name": "course_chat_messages_parent_message_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "parent_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_chat_messages_thread_id_course_chat_threads_id_fk": {
+ "name": "course_chat_messages_thread_id_course_chat_threads_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "course_chat_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_messages_course_id_courses_id_fk": {
+ "name": "course_chat_messages_course_id_courses_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_messages_user_id_users_id_fk": {
+ "name": "course_chat_messages_user_id_users_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_messages_parent_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_messages_parent_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "parent_message_id"
+ ],
+ "tableTo": "course_chat_messages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "course_chat_messages_tenant_id_tenants_id_fk": {
+ "name": "course_chat_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_threads": {
+ "name": "course_chat_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_threads_tenant_id_idx": {
+ "name": "course_chat_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_threads_course_id_created_at_idx": {
+ "name": "course_chat_threads_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_threads_course_id_updated_at_idx": {
+ "name": "course_chat_threads_course_id_updated_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_chat_threads_course_id_courses_id_fk": {
+ "name": "course_chat_threads_course_id_courses_id_fk",
+ "tableFrom": "course_chat_threads",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_threads_created_by_user_id_users_id_fk": {
+ "name": "course_chat_threads_created_by_user_id_users_id_fk",
+ "tableFrom": "course_chat_threads",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_threads_tenant_id_tenants_id_fk": {
+ "name": "course_chat_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_threads",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_slugs": {
+ "name": "course_slugs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_short_id": {
+ "name": "course_short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lang": {
+ "name": "lang",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_slugs_tenant_id_idx": {
+ "name": "course_slugs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_slug_course_short_id_lang_unique_idx": {
+ "name": "course_slug_course_short_id_lang_unique_idx",
+ "columns": [
+ {
+ "expression": "course_short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lang",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_slugs_course_short_id_courses_short_id_fk": {
+ "name": "course_slugs_course_short_id_courses_short_id_fk",
+ "tableFrom": "course_slugs",
+ "columnsFrom": [
+ "course_short_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "short_id"
+ ],
+ "onUpdate": "cascade",
+ "onDelete": "cascade"
+ },
+ "course_slugs_tenant_id_tenants_id_fk": {
+ "name": "course_slugs_tenant_id_tenants_id_fk",
+ "tableFrom": "course_slugs",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_student_mode": {
+ "name": "course_student_mode",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_student_mode_tenant_id_idx": {
+ "name": "course_student_mode_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_student_mode_user_id_users_id_fk": {
+ "name": "course_student_mode_user_id_users_id_fk",
+ "tableFrom": "course_student_mode",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_student_mode_course_id_courses_id_fk": {
+ "name": "course_student_mode_course_id_courses_id_fk",
+ "tableFrom": "course_student_mode",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_student_mode_tenant_id_tenants_id_fk": {
+ "name": "course_student_mode_tenant_id_tenants_id_fk",
+ "tableFrom": "course_student_mode",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_student_mode_user_id_course_id_unique": {
+ "name": "course_student_mode_user_id_course_id_unique",
+ "columns": [
+ "user_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.course_students_stats": {
+ "name": "course_students_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "month": {
+ "name": "month",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "new_students_count": {
+ "name": "new_students_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_students_stats_tenant_id_idx": {
+ "name": "course_students_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_students_stats_course_id_courses_id_fk": {
+ "name": "course_students_stats_course_id_courses_id_fk",
+ "tableFrom": "course_students_stats",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_students_stats_author_id_users_id_fk": {
+ "name": "course_students_stats_author_id_users_id_fk",
+ "tableFrom": "course_students_stats",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_students_stats_tenant_id_tenants_id_fk": {
+ "name": "course_students_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "course_students_stats",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_students_stats_course_id_month_year_unique": {
+ "name": "course_students_stats_course_id_month_year_unique",
+ "columns": [
+ "course_id",
+ "month",
+ "year"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.courses": {
+ "name": "courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "short_id": {
+ "name": "short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_s3_key": {
+ "name": "thumbnail_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "has_certificate": {
+ "name": "has_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "price_in_cents": {
+ "name": "price_in_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "currency": {
+ "name": "currency",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'usd'"
+ },
+ "chapter_count": {
+ "name": "chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "course_type": {
+ "name": "course_type",
+ "type": "course_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category_id": {
+ "name": "category_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stripe_product_id": {
+ "name": "stripe_product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripe_price_id": {
+ "name": "stripe_price_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"lessonSequenceEnabled\":false,\"quizFeedbackEnabled\":true,\"certificateSignature\":null,\"certificateFontColor\":null,\"certificateValidity\":null,\"videoCompletionTrackingEnabled\":true}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_tenant_id_idx": {
+ "name": "courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "courses_short_id_unique_idx": {
+ "name": "courses_short_id_unique_idx",
+ "columns": [
+ {
+ "expression": "short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "courses_author_id_users_id_fk": {
+ "name": "courses_author_id_users_id_fk",
+ "tableFrom": "courses",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "courses_category_id_categories_id_fk": {
+ "name": "courses_category_id_categories_id_fk",
+ "tableFrom": "courses",
+ "columnsFrom": [
+ "category_id"
+ ],
+ "tableTo": "categories",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "courses_tenant_id_tenants_id_fk": {
+ "name": "courses_tenant_id_tenants_id_fk",
+ "tableFrom": "courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.courses_summary_stats": {
+ "name": "courses_summary_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "free_purchased_count": {
+ "name": "free_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_count": {
+ "name": "paid_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_after_freemium_count": {
+ "name": "paid_purchased_after_freemium_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_freemium_student_count": {
+ "name": "completed_freemium_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_course_student_count": {
+ "name": "completed_course_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_summary_stats_tenant_id_idx": {
+ "name": "courses_summary_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "courses_summary_stats_course_id_courses_id_fk": {
+ "name": "courses_summary_stats_course_id_courses_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "courses_summary_stats_author_id_users_id_fk": {
+ "name": "courses_summary_stats_author_id_users_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "courses_summary_stats_tenant_id_tenants_id_fk": {
+ "name": "courses_summary_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "courses_summary_stats_course_id_unique": {
+ "name": "courses_summary_stats_course_id_unique",
+ "columns": [
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.create_tokens": {
+ "name": "create_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reminder_count": {
+ "name": "reminder_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "create_tokens_tenant_id_idx": {
+ "name": "create_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "create_tokens_token_hash_idx": {
+ "name": "create_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "create_tokens_user_id_users_id_fk": {
+ "name": "create_tokens_user_id_users_id_fk",
+ "tableFrom": "create_tokens",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "create_tokens_tenant_id_tenants_id_fk": {
+ "name": "create_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "create_tokens",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.credentials": {
+ "name": "credentials",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requires_password_change": {
+ "name": "requires_password_change",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "credentials_tenant_id_idx": {
+ "name": "credentials_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "credentials_user_id_users_id_fk": {
+ "name": "credentials_user_id_users_id_fk",
+ "tableFrom": "credentials",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "credentials_tenant_id_tenants_id_fk": {
+ "name": "credentials_tenant_id_tenants_id_fk",
+ "tableFrom": "credentials",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.doc_chunks": {
+ "name": "doc_chunks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_index": {
+ "name": "chunk_index",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding": {
+ "name": "embedding",
+ "type": "vector(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "doc_chunks_tenant_id_idx": {
+ "name": "doc_chunks_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "doc_chunks_document_id_documents_id_fk": {
+ "name": "doc_chunks_document_id_documents_id_fk",
+ "tableFrom": "doc_chunks",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "doc_chunks_tenant_id_tenants_id_fk": {
+ "name": "doc_chunks_tenant_id_tenants_id_fk",
+ "tableFrom": "doc_chunks",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.document_to_ai_mentor_lesson": {
+ "name": "document_to_ai_mentor_lesson",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "document_to_ai_mentor_lesson_tenant_id_idx": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_to_ai_mentor_lesson_document_id_documents_id_fk": {
+ "name": "document_to_ai_mentor_lesson_document_id_documents_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique": {
+ "name": "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique",
+ "columns": [
+ "document_id",
+ "ai_mentor_lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.documents": {
+ "name": "documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "check_sum": {
+ "name": "check_sum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "documents_tenant_id_idx": {
+ "name": "documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "documents_tenant_id_tenants_id_fk": {
+ "name": "documents_tenant_id_tenants_id_fk",
+ "tableFrom": "documents",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "documents_check_sum_unique": {
+ "name": "documents_check_sum_unique",
+ "columns": [
+ "check_sum"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.form_field_answers": {
+ "name": "form_field_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_field_id": {
+ "name": "form_field_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label_snapshot": {
+ "name": "label_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "answered_language": {
+ "name": "answered_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_field_answers_tenant_id_idx": {
+ "name": "form_field_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "form_field_answers_user_id_form_field_id_unique": {
+ "name": "form_field_answers_user_id_form_field_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "form_field_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "form_field_answers_user_id_idx": {
+ "name": "form_field_answers_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "form_field_answers_form_field_id_form_fields_id_fk": {
+ "name": "form_field_answers_form_field_id_form_fields_id_fk",
+ "tableFrom": "form_field_answers",
+ "columnsFrom": [
+ "form_field_id"
+ ],
+ "tableTo": "form_fields",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "form_field_answers_user_id_users_id_fk": {
+ "name": "form_field_answers_user_id_users_id_fk",
+ "tableFrom": "form_field_answers",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "form_field_answers_tenant_id_tenants_id_fk": {
+ "name": "form_field_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "form_field_answers",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.form_fields": {
+ "name": "form_fields",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_id": {
+ "name": "form_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "required": {
+ "name": "required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_fields_tenant_id_idx": {
+ "name": "form_fields_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "form_fields_form_id_display_order_idx": {
+ "name": "form_fields_form_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "form_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "form_fields_form_id_forms_id_fk": {
+ "name": "form_fields_form_id_forms_id_fk",
+ "tableFrom": "form_fields",
+ "columnsFrom": [
+ "form_id"
+ ],
+ "tableTo": "forms",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "form_fields_tenant_id_tenants_id_fk": {
+ "name": "form_fields_tenant_id_tenants_id_fk",
+ "tableFrom": "form_fields",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.forms": {
+ "name": "forms",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "forms_tenant_id_idx": {
+ "name": "forms_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "forms_tenant_id_type_unique_idx": {
+ "name": "forms_tenant_id_type_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "forms_tenant_id_tenants_id_fk": {
+ "name": "forms_tenant_id_tenants_id_fk",
+ "tableFrom": "forms",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.group_announcements": {
+ "name": "group_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_announcements_tenant_id_idx": {
+ "name": "group_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_announcements_group_id_groups_id_fk": {
+ "name": "group_announcements_group_id_groups_id_fk",
+ "tableFrom": "group_announcements",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_announcements_announcement_id_announcements_id_fk": {
+ "name": "group_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "group_announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "tableTo": "announcements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_announcements_tenant_id_tenants_id_fk": {
+ "name": "group_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "group_announcements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_announcements_group_id_announcement_id_unique": {
+ "name": "group_announcements_group_id_announcement_id_unique",
+ "columns": [
+ "group_id",
+ "announcement_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.group_courses": {
+ "name": "group_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enrolled_by": {
+ "name": "enrolled_by",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_mandatory": {
+ "name": "is_mandatory",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "due_date": {
+ "name": "due_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_courses_tenant_id_idx": {
+ "name": "group_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_courses_group_id_groups_id_fk": {
+ "name": "group_courses_group_id_groups_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_courses_course_id_courses_id_fk": {
+ "name": "group_courses_course_id_courses_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_courses_enrolled_by_users_id_fk": {
+ "name": "group_courses_enrolled_by_users_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "enrolled_by"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "group_courses_calendar_event_id_calendar_events_id_fk": {
+ "name": "group_courses_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "tableTo": "calendar_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "group_courses_tenant_id_tenants_id_fk": {
+ "name": "group_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_courses_calendar_event_id_unique": {
+ "name": "group_courses_calendar_event_id_unique",
+ "columns": [
+ "calendar_event_id"
+ ],
+ "nullsNotDistinct": false
+ },
+ "group_courses_group_id_course_id_unique": {
+ "name": "group_courses_group_id_course_id_unique",
+ "columns": [
+ "group_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.group_learning_paths": {
+ "name": "group_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_learning_paths_tenant_id_idx": {
+ "name": "group_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "group_learning_paths_learning_path_idx": {
+ "name": "group_learning_paths_learning_path_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_learning_paths_group_id_groups_id_fk": {
+ "name": "group_learning_paths_group_id_groups_id_fk",
+ "tableFrom": "group_learning_paths",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "group_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "group_learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "group_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "group_learning_paths",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_learning_paths_group_id_learning_path_id_unique": {
+ "name": "group_learning_paths_group_id_learning_path_id_unique",
+ "columns": [
+ "group_id",
+ "learning_path_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.group_users": {
+ "name": "group_users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_users_tenant_id_idx": {
+ "name": "group_users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_users_user_id_users_id_fk": {
+ "name": "group_users_user_id_users_id_fk",
+ "tableFrom": "group_users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_users_group_id_groups_id_fk": {
+ "name": "group_users_group_id_groups_id_fk",
+ "tableFrom": "group_users",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_users_tenant_id_tenants_id_fk": {
+ "name": "group_users_tenant_id_tenants_id_fk",
+ "tableFrom": "group_users",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_users_user_id_group_id_unique": {
+ "name": "group_users_user_id_group_id_unique",
+ "columns": [
+ "user_id",
+ "group_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.groups": {
+ "name": "groups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "characteristic": {
+ "name": "characteristic",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "groups_tenant_id_idx": {
+ "name": "groups_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "groups_tenant_id_tenants_id_fk": {
+ "name": "groups_tenant_id_tenants_id_fk",
+ "tableFrom": "groups",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.integration_api_keys": {
+ "name": "integration_api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "key_prefix": {
+ "name": "key_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "integration_api_keys_tenant_id_idx": {
+ "name": "integration_api_keys_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "integration_api_keys_key_prefix_idx": {
+ "name": "integration_api_keys_key_prefix_idx",
+ "columns": [
+ {
+ "expression": "key_prefix",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "integration_api_keys_created_by_idx": {
+ "name": "integration_api_keys_created_by_idx",
+ "columns": [
+ {
+ "expression": "created_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "integration_api_keys_created_by_user_id_users_id_fk": {
+ "name": "integration_api_keys_created_by_user_id_users_id_fk",
+ "tableFrom": "integration_api_keys",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "integration_api_keys_tenant_id_tenants_id_fk": {
+ "name": "integration_api_keys_tenant_id_tenants_id_fk",
+ "tableFrom": "integration_api_keys",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_certificates": {
+ "name": "learning_path_certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_certificates_tenant_id_idx": {
+ "name": "learning_path_certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_certificates_user_id_users_id_fk": {
+ "name": "learning_path_certificates_user_id_users_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_certificates_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_certificates_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_certificates_tenant_id_tenants_id_fk": {
+ "name": "learning_path_certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_courses": {
+ "name": "learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_courses_tenant_id_idx": {
+ "name": "learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_courses_path_id_course_id_unique_idx": {
+ "name": "learning_path_courses_path_id_course_id_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_courses_path_id_display_order_unique_idx": {
+ "name": "learning_path_courses_path_id_display_order_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_courses_path_id_display_order_idx": {
+ "name": "learning_path_courses_path_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_courses",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_courses_course_id_courses_id_fk": {
+ "name": "learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "learning_path_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_entity_map": {
+ "name": "learning_path_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "learning_path_entity_map_export_idx": {
+ "name": "learning_path_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_entity_map_source_entity_idx": {
+ "name": "learning_path_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_entity_map_source_unique_idx": {
+ "name": "learning_path_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_entity_map_export_id_learning_path_exports_id_fk": {
+ "name": "learning_path_entity_map_export_id_learning_path_exports_id_fk",
+ "tableFrom": "learning_path_entity_map",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "tableTo": "learning_path_exports",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_exports": {
+ "name": "learning_path_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_learning_path_id": {
+ "name": "target_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "learning_path_exports_source_learning_path_idx": {
+ "name": "learning_path_exports_source_learning_path_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_exports_target_learning_path_idx": {
+ "name": "learning_path_exports_target_learning_path_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_exports_source_target_unique_idx": {
+ "name": "learning_path_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_exports_source_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_exports_target_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_exports_target_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_exports_target_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_exports",
+ "columnsFrom": [
+ "target_learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_paths": {
+ "name": "learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_reference": {
+ "name": "thumbnail_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "includes_certificate": {
+ "name": "includes_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"certificateSignature\":null,\"certificateFontColor\":null}'::jsonb"
+ },
+ "sequence_enabled": {
+ "name": "sequence_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_paths_tenant_id_idx": {
+ "name": "learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_paths_author_id_users_id_fk": {
+ "name": "learning_paths_author_id_users_id_fk",
+ "tableFrom": "learning_paths",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "learning_paths_tenant_id_tenants_id_fk": {
+ "name": "learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_paths",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.lesson_learning_time": {
+ "name": "lesson_learning_time",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_learning_time_tenant_id_idx": {
+ "name": "lesson_learning_time_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lesson_learning_time_user_course_idx": {
+ "name": "lesson_learning_time_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "lesson_learning_time_user_id_users_id_fk": {
+ "name": "lesson_learning_time_user_id_users_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_learning_time_lesson_id_lessons_id_fk": {
+ "name": "lesson_learning_time_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_learning_time_course_id_courses_id_fk": {
+ "name": "lesson_learning_time_course_id_courses_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_learning_time_tenant_id_tenants_id_fk": {
+ "name": "lesson_learning_time_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_learning_time_user_id_lesson_id_unique": {
+ "name": "lesson_learning_time_user_id_lesson_id_unique",
+ "columns": [
+ "user_id",
+ "lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.lesson_video_progress": {
+ "name": "lesson_video_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_entity_id": {
+ "name": "resource_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "duration_seconds": {
+ "name": "duration_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bucket_size_seconds": {
+ "name": "bucket_size_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "watched_ranges": {
+ "name": "watched_ranges",
+ "type": "int4multirange",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::int4multirange"
+ },
+ "covered_bucket_count": {
+ "name": "covered_bucket_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "coverage_percent": {
+ "name": "coverage_percent",
+ "type": "numeric(5, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "active_watch_seconds": {
+ "name": "active_watch_seconds",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "is_watched": {
+ "name": "is_watched",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "watched_at": {
+ "name": "watched_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_video_progress_tenant_id_idx": {
+ "name": "lesson_video_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lesson_video_progress_lesson_idx": {
+ "name": "lesson_video_progress_lesson_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lesson_video_progress_resource_entity_idx": {
+ "name": "lesson_video_progress_resource_entity_idx",
+ "columns": [
+ {
+ "expression": "resource_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "lesson_video_progress_student_id_users_id_fk": {
+ "name": "lesson_video_progress_student_id_users_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_video_progress_lesson_id_lessons_id_fk": {
+ "name": "lesson_video_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_video_progress_resource_entity_id_resource_entity_id_fk": {
+ "name": "lesson_video_progress_resource_entity_id_resource_entity_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "resource_entity_id"
+ ],
+ "tableTo": "resource_entity",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_video_progress_tenant_id_tenants_id_fk": {
+ "name": "lesson_video_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique": {
+ "name": "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique",
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "resource_entity_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.lessons": {
+ "name": "lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "threshold_score": {
+ "name": "threshold_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts_limit": {
+ "name": "attempts_limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quiz_cooldown_in_hours": {
+ "name": "quiz_cooldown_in_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_s3_key": {
+ "name": "file_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_external": {
+ "name": "is_external",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lessons_tenant_id_idx": {
+ "name": "lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lessons_tenant_id_chapter_id_type_idx": {
+ "name": "lessons_tenant_id_chapter_id_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chapter_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "lessons_chapter_id_chapters_id_fk": {
+ "name": "lessons_chapter_id_chapters_id_fk",
+ "tableFrom": "lessons",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "tableTo": "chapters",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lessons_tenant_id_tenants_id_fk": {
+ "name": "lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "lessons",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_lessons": {
+ "name": "live_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_link_id": {
+ "name": "live_training_link_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_lessons_tenant_id_idx": {
+ "name": "live_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_lessons_lesson_language_unique_idx": {
+ "name": "live_lessons_lesson_language_unique_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_lessons_training_link_idx": {
+ "name": "live_lessons_training_link_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_link_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_lessons_training_idx": {
+ "name": "live_lessons_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_lessons_live_training_id_live_trainings_id_fk": {
+ "name": "live_lessons_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_lessons_live_training_link_id_live_training_links_id_fk": {
+ "name": "live_lessons_live_training_link_id_live_training_links_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "live_training_link_id"
+ ],
+ "tableTo": "live_training_links",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_lessons_lesson_id_lessons_id_fk": {
+ "name": "live_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_lessons_tenant_id_tenants_id_fk": {
+ "name": "live_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_attendance": {
+ "name": "live_training_attendance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_participant_id": {
+ "name": "live_training_session_participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "joined_at": {
+ "name": "joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "left_at": {
+ "name": "left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_participant_sid": {
+ "name": "livekit_participant_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disconnect_reason": {
+ "name": "disconnect_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_attendance_tenant_id_idx": {
+ "name": "live_training_attendance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_attendance_session_user_idx": {
+ "name": "live_training_attendance_session_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_attendance_training_user_idx": {
+ "name": "live_training_attendance_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_attendance_joined_at_idx": {
+ "name": "live_training_attendance_joined_at_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "joined_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk": {
+ "name": "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "live_training_session_participant_id"
+ ],
+ "tableTo": "live_training_session_participants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_attendance_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_attendance_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "tableTo": "live_training_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_attendance_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_attendance_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_attendance_user_id_users_id_fk": {
+ "name": "live_training_attendance_user_id_users_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_attendance_tenant_id_tenants_id_fk": {
+ "name": "live_training_attendance_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_links": {
+ "name": "live_training_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'course'"
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_links_tenant_id_idx": {
+ "name": "live_training_links_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_links_training_entity_unique_idx": {
+ "name": "live_training_links_training_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_links_training_idx": {
+ "name": "live_training_links_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_links_entity_idx": {
+ "name": "live_training_links_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_links_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_links_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_links",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_links_tenant_id_tenants_id_fk": {
+ "name": "live_training_links_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_links",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_members": {
+ "name": "live_training_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'host'"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_members_tenant_id_idx": {
+ "name": "live_training_members_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_training_user_unique_idx": {
+ "name": "live_training_members_training_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_training_idx": {
+ "name": "live_training_members_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_user_idx": {
+ "name": "live_training_members_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_role_idx": {
+ "name": "live_training_members_role_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_members_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_members_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_members",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_members_user_id_users_id_fk": {
+ "name": "live_training_members_user_id_users_id_fk",
+ "tableFrom": "live_training_members",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_members_tenant_id_tenants_id_fk": {
+ "name": "live_training_members_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_members",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_session_participants": {
+ "name": "live_training_session_participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_joined_at": {
+ "name": "first_joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_left_at": {
+ "name": "last_left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "join_count": {
+ "name": "join_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "livekit_identity": {
+ "name": "livekit_identity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_session_participants_tenant_id_idx": {
+ "name": "live_training_session_participants_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_session_user_unique_idx": {
+ "name": "live_training_session_participants_session_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_session_idx": {
+ "name": "live_training_session_participants_session_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_training_user_idx": {
+ "name": "live_training_session_participants_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_user_idx": {
+ "name": "live_training_session_participants_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "tableTo": "live_training_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_session_participants_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_session_participants_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_session_participants_user_id_users_id_fk": {
+ "name": "live_training_session_participants_user_id_users_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_session_participants_tenant_id_tenants_id_fk": {
+ "name": "live_training_session_participants_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_sessions": {
+ "name": "live_training_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'waiting'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_by_user_id": {
+ "name": "started_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_by_user_id": {
+ "name": "ended_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "end_reason": {
+ "name": "end_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_name": {
+ "name": "livekit_room_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_sid": {
+ "name": "livekit_room_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "peak_participant_count": {
+ "name": "peak_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "unique_participant_count": {
+ "name": "unique_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_sessions_tenant_id_idx": {
+ "name": "live_training_sessions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_sessions_training_idx": {
+ "name": "live_training_sessions_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_sessions_status_idx": {
+ "name": "live_training_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_sessions_livekit_room_name_idx": {
+ "name": "live_training_sessions_livekit_room_name_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "livekit_room_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_sessions_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_sessions_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_sessions_started_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_started_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "started_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_sessions_ended_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_ended_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "ended_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_sessions_tenant_id_tenants_id_fk": {
+ "name": "live_training_sessions_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_trainings": {
+ "name": "live_trainings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "delivery_type": {
+ "name": "delivery_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'online'"
+ },
+ "visibility_scope": {
+ "name": "visibility_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'linked_courses'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "max_participants": {
+ "name": "max_participants",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"viewerPermissions\":{\"microphoneEnabled\":false,\"cameraEnabled\":false}}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_trainings_tenant_id_idx": {
+ "name": "live_trainings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_trainings_tenant_status_idx": {
+ "name": "live_trainings_tenant_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_trainings_author_idx": {
+ "name": "live_trainings_author_idx",
+ "columns": [
+ {
+ "expression": "author_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_trainings_calendar_event_id_calendar_events_id_fk": {
+ "name": "live_trainings_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "live_trainings",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "tableTo": "calendar_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_trainings_author_id_users_id_fk": {
+ "name": "live_trainings_author_id_users_id_fk",
+ "tableFrom": "live_trainings",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_trainings_tenant_id_tenants_id_fk": {
+ "name": "live_trainings_tenant_id_tenants_id_fk",
+ "tableFrom": "live_trainings",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "live_trainings_calendar_event_id_unique": {
+ "name": "live_trainings_calendar_event_id_unique",
+ "columns": [
+ "calendar_event_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.luma_course_generation_syncs": {
+ "name": "luma_course_generation_syncs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_id": {
+ "name": "draft_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failed_at": {
+ "name": "failed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dismissed_at": {
+ "name": "dismissed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "luma_course_generation_syncs_tenant_id_idx": {
+ "name": "luma_course_generation_syncs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "luma_course_generation_syncs_course_id_idx": {
+ "name": "luma_course_generation_syncs_course_id_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "luma_course_generation_syncs_status_idx": {
+ "name": "luma_course_generation_syncs_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "luma_course_generation_syncs_course_id_courses_id_fk": {
+ "name": "luma_course_generation_syncs_course_id_courses_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "luma_course_generation_syncs_tenant_id_tenants_id_fk": {
+ "name": "luma_course_generation_syncs_tenant_id_tenants_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "luma_course_generation_syncs_course_id_unique": {
+ "name": "luma_course_generation_syncs_course_id_unique",
+ "columns": [
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.magic_link_tokens": {
+ "name": "magic_link_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "magic_link_tokens_tenant_id_idx": {
+ "name": "magic_link_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "magic_link_tokens_token_hash_idx": {
+ "name": "magic_link_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "magic_link_tokens_user_id_users_id_fk": {
+ "name": "magic_link_tokens_user_id_users_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "magic_link_tokens_tenant_id_tenants_id_fk": {
+ "name": "magic_link_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_entity_map": {
+ "name": "master_course_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "master_course_entity_map_export_idx": {
+ "name": "master_course_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_entity_map_source_entity_idx": {
+ "name": "master_course_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_entity_map_source_unique_idx": {
+ "name": "master_course_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "master_course_entity_map_export_id_master_course_exports_id_fk": {
+ "name": "master_course_entity_map_export_id_master_course_exports_id_fk",
+ "tableFrom": "master_course_entity_map",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "tableTo": "master_course_exports",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_exports": {
+ "name": "master_course_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_course_id": {
+ "name": "target_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "master_course_exports_source_course_idx": {
+ "name": "master_course_exports_source_course_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_exports_target_course_idx": {
+ "name": "master_course_exports_target_course_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_exports_source_target_unique_idx": {
+ "name": "master_course_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "master_course_exports_source_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "master_course_exports_source_course_id_courses_id_fk": {
+ "name": "master_course_exports_source_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "source_course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "master_course_exports_target_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "master_course_exports_target_course_id_courses_id_fk": {
+ "name": "master_course_exports_target_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "target_course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.news": {
+ "name": "news",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "news_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "news_tenant_id_idx": {
+ "name": "news_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "news_author_id_users_id_fk": {
+ "name": "news_author_id_users_id_fk",
+ "tableFrom": "news",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "news_tenant_id_tenants_id_fk": {
+ "name": "news_tenant_id_tenants_id_fk",
+ "tableFrom": "news",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.outbox_events": {
+ "name": "outbox_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "outbox_events_tenant_id_idx": {
+ "name": "outbox_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "outbox_events_poll_idx": {
+ "name": "outbox_events_poll_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "outbox_events_tenant_id_tenants_id_fk": {
+ "name": "outbox_events_tenant_id_tenants_id_fk",
+ "tableFrom": "outbox_events",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_role_rule_sets": {
+ "name": "permission_role_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_role_rule_sets_tenant_id_idx": {
+ "name": "permission_role_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_role_rule_sets_role_id_rule_set_id_unique": {
+ "name": "permission_role_rule_sets_role_id_rule_set_id_unique",
+ "columns": [
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_role_rule_sets_role_id_permission_roles_id_fk": {
+ "name": "permission_role_rule_sets_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "tableTo": "permission_roles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "tableTo": "permission_rule_sets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_role_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_role_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_roles": {
+ "name": "permission_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_roles_tenant_id_idx": {
+ "name": "permission_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_roles_tenant_id_slug_unique": {
+ "name": "permission_roles_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_roles",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_set_permissions": {
+ "name": "permission_rule_set_permissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission": {
+ "name": "permission",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_set_permissions_tenant_id_idx": {
+ "name": "permission_rule_set_permissions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_rule_set_permissions_rule_set_id_permission_unique": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_unique",
+ "columns": [
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "tableTo": "permission_rule_sets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_rule_set_permissions_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_set_permissions_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_sets": {
+ "name": "permission_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_sets_tenant_id_idx": {
+ "name": "permission_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_rule_sets_tenant_id_slug_unique": {
+ "name": "permission_rule_sets_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_sets",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_user_roles": {
+ "name": "permission_user_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_user_roles_tenant_id_idx": {
+ "name": "permission_user_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_user_roles_user_id_role_id_unique": {
+ "name": "permission_user_roles_user_id_role_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_user_roles_user_id_users_id_fk": {
+ "name": "permission_user_roles_user_id_users_id_fk",
+ "tableFrom": "permission_user_roles",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_user_roles_role_id_permission_roles_id_fk": {
+ "name": "permission_user_roles_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_user_roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "tableTo": "permission_roles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_user_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_user_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_user_roles",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.question_answer_options": {
+ "name": "question_answer_options",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "option_text": {
+ "name": "option_text",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_word": {
+ "name": "matched_word",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scale_answer": {
+ "name": "scale_answer",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "question_answer_options_tenant_id_idx": {
+ "name": "question_answer_options_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "question_answer_options_question_id_questions_id_fk": {
+ "name": "question_answer_options_question_id_questions_id_fk",
+ "tableFrom": "question_answer_options",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "tableTo": "questions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "question_answer_options_tenant_id_tenants_id_fk": {
+ "name": "question_answer_options_tenant_id_tenants_id_fk",
+ "tableFrom": "question_answer_options",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions": {
+ "name": "questions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "photo_s3_key": {
+ "name": "photo_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "solution_explanation": {
+ "name": "solution_explanation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_tenant_id_idx": {
+ "name": "questions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "questions_lesson_id_lessons_id_fk": {
+ "name": "questions_lesson_id_lessons_id_fk",
+ "tableFrom": "questions",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "questions_author_id_users_id_fk": {
+ "name": "questions_author_id_users_id_fk",
+ "tableFrom": "questions",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "questions_tenant_id_tenants_id_fk": {
+ "name": "questions_tenant_id_tenants_id_fk",
+ "tableFrom": "questions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions_and_answers": {
+ "name": "questions_and_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_and_answers_tenant_id_idx": {
+ "name": "questions_and_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "questions_and_answers_tenant_id_tenants_id_fk": {
+ "name": "questions_and_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "questions_and_answers",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.quiz_attempts": {
+ "name": "quiz_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "correct_answers": {
+ "name": "correct_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wrong_answers": {
+ "name": "wrong_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "quiz_attempts_tenant_id_idx": {
+ "name": "quiz_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "quiz_attempts_user_id_users_id_fk": {
+ "name": "quiz_attempts_user_id_users_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "quiz_attempts_course_id_courses_id_fk": {
+ "name": "quiz_attempts_course_id_courses_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "quiz_attempts_lesson_id_lessons_id_fk": {
+ "name": "quiz_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "quiz_attempts_tenant_id_tenants_id_fk": {
+ "name": "quiz_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.reset_tokens": {
+ "name": "reset_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "reset_tokens_tenant_id_idx": {
+ "name": "reset_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "reset_tokens_token_hash_idx": {
+ "name": "reset_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "reset_tokens_user_id_users_id_fk": {
+ "name": "reset_tokens_user_id_users_id_fk",
+ "tableFrom": "reset_tokens",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "reset_tokens_tenant_id_tenants_id_fk": {
+ "name": "reset_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "reset_tokens",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.resource_entity": {
+ "name": "resource_entity",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "relationship_type": {
+ "name": "relationship_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'attachment'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resource_entity_tenant_id_idx": {
+ "name": "resource_entity_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_entity_resource_idx": {
+ "name": "resource_entity_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_entity_entity_idx": {
+ "name": "resource_entity_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_entity_relationship_idx": {
+ "name": "resource_entity_relationship_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "relationship_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "resource_entity_resource_id_resources_id_fk": {
+ "name": "resource_entity_resource_id_resources_id_fk",
+ "tableFrom": "resource_entity",
+ "columnsFrom": [
+ "resource_id"
+ ],
+ "tableTo": "resources",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "resource_entity_tenant_id_tenants_id_fk": {
+ "name": "resource_entity_tenant_id_tenants_id_fk",
+ "tableFrom": "resource_entity",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique": {
+ "name": "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique",
+ "columns": [
+ "resource_id",
+ "entity_id",
+ "entity_type",
+ "relationship_type"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.resources": {
+ "name": "resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reference": {
+ "name": "reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "uploaded_by_id": {
+ "name": "uploaded_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resources_tenant_id_idx": {
+ "name": "resources_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "resources_uploaded_by_id_users_id_fk": {
+ "name": "resources_uploaded_by_id_users_id_fk",
+ "tableFrom": "resources",
+ "columnsFrom": [
+ "uploaded_by_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "resources_tenant_id_tenants_id_fk": {
+ "name": "resources_tenant_id_tenants_id_fk",
+ "tableFrom": "resources",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_attempts": {
+ "name": "scorm_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sco_id": {
+ "name": "sco_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attempt_number": {
+ "name": "attempt_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_attempts_tenant_id_idx": {
+ "name": "scorm_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_student_lesson_idx": {
+ "name": "scorm_attempts_student_lesson_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_student_package_idx": {
+ "name": "scorm_attempts_student_package_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_sco_id_idx": {
+ "name": "scorm_attempts_sco_id_idx",
+ "columns": [
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_student_package_sco_attempt_unique_idx": {
+ "name": "scorm_attempts_student_package_sco_attempt_unique_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "attempt_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_attempts_student_id_users_id_fk": {
+ "name": "scorm_attempts_student_id_users_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_course_id_courses_id_fk": {
+ "name": "scorm_attempts_course_id_courses_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_lesson_id_lessons_id_fk": {
+ "name": "scorm_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_package_id_scorm_packages_id_fk": {
+ "name": "scorm_attempts_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "tableTo": "scorm_packages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_sco_id_scorm_scos_id_fk": {
+ "name": "scorm_attempts_sco_id_scorm_scos_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "sco_id"
+ ],
+ "tableTo": "scorm_scos",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_tenant_id_tenants_id_fk": {
+ "name": "scorm_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_packages": {
+ "name": "scorm_packages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "scorm_package_entity_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "standard": {
+ "name": "standard",
+ "type": "scorm_standard",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_file_reference": {
+ "name": "original_file_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "extracted_files_reference": {
+ "name": "extracted_files_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_entry_point": {
+ "name": "manifest_entry_point",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_json": {
+ "name": "manifest_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "scorm_package_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_packages_tenant_id_idx": {
+ "name": "scorm_packages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_packages_entity_idx": {
+ "name": "scorm_packages_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_packages_entity_unique_idx": {
+ "name": "scorm_packages_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_packages_tenant_id_tenants_id_fk": {
+ "name": "scorm_packages_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_packages",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_runtime_state": {
+ "name": "scorm_runtime_state",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "attempt_id": {
+ "name": "attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completion_status": {
+ "name": "completion_status",
+ "type": "scorm_completion_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "success_status": {
+ "name": "success_status",
+ "type": "scorm_success_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "score_raw": {
+ "name": "score_raw",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_min": {
+ "name": "score_min",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_max": {
+ "name": "score_max",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_scaled": {
+ "name": "score_scaled",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_location": {
+ "name": "lesson_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspend_data": {
+ "name": "suspend_data",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_time": {
+ "name": "session_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_time": {
+ "name": "total_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "progress_measure": {
+ "name": "progress_measure",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "entry": {
+ "name": "entry",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exit": {
+ "name": "exit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_cmi_json": {
+ "name": "raw_cmi_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_runtime_state_tenant_id_idx": {
+ "name": "scorm_runtime_state_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_runtime_state_attempt_id_unique_idx": {
+ "name": "scorm_runtime_state_attempt_id_unique_idx",
+ "columns": [
+ {
+ "expression": "attempt_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_runtime_state_attempt_id_scorm_attempts_id_fk": {
+ "name": "scorm_runtime_state_attempt_id_scorm_attempts_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "columnsFrom": [
+ "attempt_id"
+ ],
+ "tableTo": "scorm_attempts",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_runtime_state_tenant_id_tenants_id_fk": {
+ "name": "scorm_runtime_state_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_scos": {
+ "name": "scorm_scos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_identifier": {
+ "name": "organization_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "identifier_ref": {
+ "name": "identifier_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_identifier": {
+ "name": "resource_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scorm_type": {
+ "name": "scorm_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "href": {
+ "name": "href",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "launch_path": {
+ "name": "launch_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parameters": {
+ "name": "parameters",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_identifier": {
+ "name": "parent_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_visible": {
+ "name": "is_visible",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "item_metadata_json": {
+ "name": "item_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_metadata_json": {
+ "name": "resource_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_scos_tenant_id_idx": {
+ "name": "scorm_scos_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_scos_package_id_idx": {
+ "name": "scorm_scos_package_id_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_scos_lesson_id_idx": {
+ "name": "scorm_scos_lesson_id_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_scos_package_identifier_unique_idx": {
+ "name": "scorm_scos_package_identifier_unique_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_scos_package_id_scorm_packages_id_fk": {
+ "name": "scorm_scos_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_scos",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "tableTo": "scorm_packages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_scos_lesson_id_lessons_id_fk": {
+ "name": "scorm_scos_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_scos",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_scos_tenant_id_tenants_id_fk": {
+ "name": "scorm_scos_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_scos",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.search_documents": {
+ "name": "search_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "search_vector": {
+ "name": "search_vector",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "search_documents_tenant_id_idx": {
+ "name": "search_documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "search_documents_vector_idx": {
+ "name": "search_documents_vector_idx",
+ "columns": [
+ {
+ "expression": "search_vector",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "search_documents_language_entity_type_idx": {
+ "name": "search_documents_language_entity_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "search_documents_entity_idx": {
+ "name": "search_documents_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "search_documents_document_unique_idx": {
+ "name": "search_documents_document_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "search_documents_tenant_id_tenants_id_fk": {
+ "name": "search_documents_tenant_id_tenants_id_fk",
+ "tableFrom": "search_documents",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.secrets": {
+ "name": "secrets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "secret_name": {
+ "name": "secret_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "ciphertext": {
+ "name": "ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "iv": {
+ "name": "iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tag": {
+ "name": "tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek": {
+ "name": "encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_iv": {
+ "name": "encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_tag": {
+ "name": "encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "alg": {
+ "name": "alg",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'AES-256-GCM'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "secrets_tenant_id_idx": {
+ "name": "secrets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secrets_tenant_secret_name_uq": {
+ "name": "secrets_tenant_secret_name_uq",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secrets_name_idx": {
+ "name": "secrets_name_idx",
+ "columns": [
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "secrets_tenant_id_tenants_id_fk": {
+ "name": "secrets_tenant_id_tenants_id_fk",
+ "tableFrom": "secrets",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.settings": {
+ "name": "settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "settings_tenant_id_idx": {
+ "name": "settings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "settings_user_id_users_id_fk": {
+ "name": "settings_user_id_users_id_fk",
+ "tableFrom": "settings",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "settings_tenant_id_tenants_id_fk": {
+ "name": "settings_tenant_id_tenants_id_fk",
+ "tableFrom": "settings",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.student_chapter_progress": {
+ "name": "student_chapter_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_lesson_count": {
+ "name": "completed_lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_as_freemium": {
+ "name": "completed_as_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_chapter_progress_tenant_id_idx": {
+ "name": "student_chapter_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_chapter_progress_student_id_users_id_fk": {
+ "name": "student_chapter_progress_student_id_users_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_chapter_progress_course_id_courses_id_fk": {
+ "name": "student_chapter_progress_course_id_courses_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_chapter_progress_chapter_id_chapters_id_fk": {
+ "name": "student_chapter_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_tenant_id_tenants_id_fk": {
+ "name": "student_chapter_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_chapter_progress_student_id_course_id_chapter_id_unique": {
+ "name": "student_chapter_progress_student_id_course_id_chapter_id_unique",
+ "columns": [
+ "student_id",
+ "course_id",
+ "chapter_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_courses": {
+ "name": "student_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "finished_chapter_count": {
+ "name": "finished_chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "course_completion_metadata": {
+ "name": "course_completion_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'enrolled'"
+ },
+ "payment_id": {
+ "name": "payment_id",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_by_group_id": {
+ "name": "enrolled_by_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_courses_tenant_id_idx": {
+ "name": "student_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_courses_tenant_id_course_status_student_idx": {
+ "name": "student_courses_tenant_id_course_status_student_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_courses_student_id_users_id_fk": {
+ "name": "student_courses_student_id_users_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_courses_course_id_courses_id_fk": {
+ "name": "student_courses_course_id_courses_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_courses_enrolled_by_group_id_groups_id_fk": {
+ "name": "student_courses_enrolled_by_group_id_groups_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "enrolled_by_group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_courses_tenant_id_tenants_id_fk": {
+ "name": "student_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_courses_student_id_course_id_unique": {
+ "name": "student_courses_student_id_course_id_unique",
+ "columns": [
+ "student_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_learning_path_courses": {
+ "name": "student_learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_path_courses_tenant_id_idx": {
+ "name": "student_learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_learning_path_courses_student_path_idx": {
+ "name": "student_learning_path_courses_student_path_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_learning_path_courses_course_idx": {
+ "name": "student_learning_path_courses_course_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_learning_path_courses_student_id_users_id_fk": {
+ "name": "student_learning_path_courses_student_id_users_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_path_courses_course_id_courses_id_fk": {
+ "name": "student_learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "student_learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_path_courses_student_id_learning_path_id_course_id_unique": {
+ "name": "student_learning_path_courses_student_id_learning_path_id_course_id_unique",
+ "columns": [
+ "student_id",
+ "learning_path_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_learning_paths": {
+ "name": "student_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "enrollment_type": {
+ "name": "enrollment_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'direct'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_paths_tenant_id_idx": {
+ "name": "student_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_learning_paths_student_id_users_id_fk": {
+ "name": "student_learning_paths_student_id_users_id_fk",
+ "tableFrom": "student_learning_paths",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "student_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_paths",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_paths_student_id_learning_path_id_unique": {
+ "name": "student_learning_paths_student_id_learning_path_id_unique",
+ "columns": [
+ "student_id",
+ "learning_path_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_lesson_progress": {
+ "name": "student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_question_count": {
+ "name": "completed_question_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "quiz_score": {
+ "name": "quiz_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_quiz_passed": {
+ "name": "is_quiz_passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_started": {
+ "name": "is_started",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "language_answered": {
+ "name": "language_answered",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_lesson_progress_tenant_id_idx": {
+ "name": "student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_lesson_progress_completed_quiz_score_idx": {
+ "name": "student_lesson_progress_completed_quiz_score_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"student_lesson_progress\".\"completed_at\" IS NOT NULL AND \"student_lesson_progress\".\"quiz_score\" IS NOT NULL",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_lesson_progress_student_id_users_id_fk": {
+ "name": "student_lesson_progress_student_id_users_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "student_lesson_progress_chapter_id_chapters_id_fk": {
+ "name": "student_lesson_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "tableTo": "chapters",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_lesson_progress_lesson_id_lessons_id_fk": {
+ "name": "student_lesson_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_lesson_progress_student_id_lesson_id_chapter_id_unique": {
+ "name": "student_lesson_progress_student_id_lesson_id_chapter_id_unique",
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "chapter_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_question_answers": {
+ "name": "student_question_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "answer": {
+ "name": "answer",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_question_answers_tenant_id_idx": {
+ "name": "student_question_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_question_answers_question_id_questions_id_fk": {
+ "name": "student_question_answers_question_id_questions_id_fk",
+ "tableFrom": "student_question_answers",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "tableTo": "questions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_question_answers_student_id_users_id_fk": {
+ "name": "student_question_answers_student_id_users_id_fk",
+ "tableFrom": "student_question_answers",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_question_answers_tenant_id_tenants_id_fk": {
+ "name": "student_question_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "student_question_answers",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_question_answers_question_id_student_id_unique": {
+ "name": "student_question_answers_question_id_student_id_unique",
+ "columns": [
+ "question_id",
+ "student_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.support_sessions": {
+ "name": "support_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "original_user_id": {
+ "name": "original_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_tenant_id": {
+ "name": "original_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_user_id": {
+ "name": "target_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hashed_grant_token": {
+ "name": "hashed_grant_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_expires_at": {
+ "name": "grant_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "activated_at": {
+ "name": "activated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "return_url": {
+ "name": "return_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ }
+ },
+ "indexes": {
+ "support_sessions_hashed_grant_token_unique": {
+ "name": "support_sessions_hashed_grant_token_unique",
+ "columns": [
+ {
+ "expression": "hashed_grant_token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_status_idx": {
+ "name": "support_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_original_user_idx": {
+ "name": "support_sessions_original_user_idx",
+ "columns": [
+ {
+ "expression": "original_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_target_tenant_idx": {
+ "name": "support_sessions_target_tenant_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_target_user_idx": {
+ "name": "support_sessions_target_user_idx",
+ "columns": [
+ {
+ "expression": "target_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "support_sessions_original_user_id_users_id_fk": {
+ "name": "support_sessions_original_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "original_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "support_sessions_original_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_original_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "original_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "support_sessions_target_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_target_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "support_sessions_target_user_id_users_id_fk": {
+ "name": "support_sessions_target_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "target_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.tenants": {
+ "name": "tenants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "host": {
+ "name": "host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "is_managing": {
+ "name": "is_managing",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ }
+ },
+ "indexes": {
+ "unique_host_idx": {
+ "name": "unique_host_idx",
+ "columns": [
+ {
+ "expression": "host",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user_announcements": {
+ "name": "user_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_read": {
+ "name": "is_read",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "read_at": {
+ "name": "read_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_announcements_tenant_id_idx": {
+ "name": "user_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_announcements_user_id_users_id_fk": {
+ "name": "user_announcements_user_id_users_id_fk",
+ "tableFrom": "user_announcements",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_announcements_announcement_id_announcements_id_fk": {
+ "name": "user_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "user_announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "tableTo": "announcements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_announcements_tenant_id_tenants_id_fk": {
+ "name": "user_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "user_announcements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_announcements_user_id_announcement_id_unique": {
+ "name": "user_announcements_user_id_announcement_id_unique",
+ "columns": [
+ "user_id",
+ "announcement_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.user_details": {
+ "name": "user_details",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_phone_number": {
+ "name": "contact_phone_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contact_email": {
+ "name": "contact_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "job_title": {
+ "name": "job_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_details_tenant_id_idx": {
+ "name": "user_details_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_details_user_id_users_id_fk": {
+ "name": "user_details_user_id_users_id_fk",
+ "tableFrom": "user_details",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_details_tenant_id_tenants_id_fk": {
+ "name": "user_details_tenant_id_tenants_id_fk",
+ "tableFrom": "user_details",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_details_user_id_unique": {
+ "name": "user_details_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.user_onboarding": {
+ "name": "user_onboarding",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dashboard": {
+ "name": "dashboard",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "courses": {
+ "name": "courses",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "announcements": {
+ "name": "announcements",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "profile": {
+ "name": "profile",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "provider_information": {
+ "name": "provider_information",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_onboarding_tenant_id_idx": {
+ "name": "user_onboarding_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_onboarding_user_id_users_id_fk": {
+ "name": "user_onboarding_user_id_users_id_fk",
+ "tableFrom": "user_onboarding",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_onboarding_tenant_id_tenants_id_fk": {
+ "name": "user_onboarding_tenant_id_tenants_id_fk",
+ "tableFrom": "user_onboarding",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_onboarding_user_id_unique": {
+ "name": "user_onboarding_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.user_statistics": {
+ "name": "user_statistics",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_streak": {
+ "name": "current_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "longest_streak": {
+ "name": "longest_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_activity_date": {
+ "name": "last_activity_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activity_history": {
+ "name": "activity_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_statistics_tenant_id_idx": {
+ "name": "user_statistics_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_statistics_user_id_users_id_fk": {
+ "name": "user_statistics_user_id_users_id_fk",
+ "tableFrom": "user_statistics",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_statistics_tenant_id_tenants_id_fk": {
+ "name": "user_statistics_tenant_id_tenants_id_fk",
+ "tableFrom": "user_statistics",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_statistics_user_id_unique": {
+ "name": "user_statistics_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_name": {
+ "name": "first_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_name": {
+ "name": "last_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "users_tenant_id_idx": {
+ "name": "users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "users_tenant_id_email_unique_idx": {
+ "name": "users_tenant_id_email_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "users_tenant_id_tenants_id_fk": {
+ "name": "users_tenant_id_tenants_id_fk",
+ "tableFrom": "users",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_connections": {
+ "name": "calendar_connections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_email": {
+ "name": "account_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_ciphertext": {
+ "name": "refresh_token_ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_iv": {
+ "name": "refresh_token_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_tag": {
+ "name": "refresh_token_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek": {
+ "name": "refresh_token_encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_iv": {
+ "name": "refresh_token_encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_tag": {
+ "name": "refresh_token_encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'syncing'"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_cursor": {
+ "name": "sync_cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_start": {
+ "name": "sync_window_start",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_end": {
+ "name": "sync_window_end",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "window_built_at": {
+ "name": "window_built_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_successful_sync_at": {
+ "name": "last_successful_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_completed_at": {
+ "name": "last_sync_completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_client_state": {
+ "name": "subscription_client_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_expires_at": {
+ "name": "subscription_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_sync_enabled": {
+ "name": "outbound_sync_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "outbound_status": {
+ "name": "outbound_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'disabled'"
+ },
+ "outbound_calendar_id": {
+ "name": "outbound_calendar_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_error_code": {
+ "name": "outbound_error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_outbound_sync_at": {
+ "name": "last_outbound_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_connections_tenant_id_idx": {
+ "name": "calendar_connections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_tenant_user_provider_unique_idx": {
+ "name": "calendar_connections_tenant_user_provider_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_subscription_idx": {
+ "name": "calendar_connections_subscription_idx",
+ "columns": [
+ {
+ "expression": "subscription_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_connections_user_id_users_id_fk": {
+ "name": "calendar_connections_user_id_users_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_connections_tenant_id_tenants_id_fk": {
+ "name": "calendar_connections_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_external_events": {
+ "name": "calendar_external_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "web_link": {
+ "name": "web_link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensitivity": {
+ "name": "sensitivity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "availability": {
+ "name": "availability",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_cancelled": {
+ "name": "is_cancelled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_external_events_tenant_id_idx": {
+ "name": "calendar_external_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_calendar_event_unique_idx": {
+ "name": "calendar_external_events_calendar_event_unique_idx",
+ "columns": [
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_connection_event_unique_idx": {
+ "name": "calendar_external_events_tenant_connection_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_user_idx": {
+ "name": "calendar_external_events_tenant_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_external_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_external_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_external_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_user_id_users_id_fk": {
+ "name": "calendar_external_events_user_id_users_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_external_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_outbound_events": {
+ "name": "calendar_outbound_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_outbound_events_tenant_id_idx": {
+ "name": "calendar_outbound_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_event_user_unique_idx": {
+ "name": "calendar_outbound_events_connection_event_user_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_external_event_unique_idx": {
+ "name": "calendar_outbound_events_connection_external_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_calendar_event_idx": {
+ "name": "calendar_outbound_events_calendar_event_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_outbound_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_outbound_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_outbound_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_user_id_users_id_fk": {
+ "name": "calendar_outbound_events_user_id_users_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_outbound_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_configurations": {
+ "name": "ai_mentor_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "structured_ai_mentor_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opening_instruction": {
+ "name": "opening_instruction",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "additional_instructions": {
+ "name": "additional_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_configurations_tenant_id_idx": {
+ "name": "ai_mentor_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_unique",
+ "columns": [
+ "ai_mentor_lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_mentor_roleplay_configurations": {
+ "name": "ai_mentor_roleplay_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario": {
+ "name": "scenario",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "ai_role": {
+ "name": "ai_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "learner_role": {
+ "name": "learner_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "character_goal": {
+ "name": "character_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "difficulty": {
+ "name": "difficulty",
+ "type": "ai_mentor_roleplay_difficulty",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "facts_and_constraints": {
+ "name": "facts_and_constraints",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_roleplay_configurations_tenant_id_idx": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_mentor_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_roleplay_configurations_configuration_id_unique": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_unique",
+ "columns": [
+ "configuration_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_mentor_teacher_configurations": {
+ "name": "ai_mentor_teacher_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expertise": {
+ "name": "expertise",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content_scope": {
+ "name": "content_scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "teaching_style": {
+ "name": "teaching_style",
+ "type": "ai_mentor_teaching_style",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback_guidance": {
+ "name": "feedback_guidance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_teacher_configurations_tenant_id_idx": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_mentor_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_teacher_configurations_configuration_id_unique": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_unique",
+ "columns": [
+ "configuration_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ }
+ },
+ "enums": {
+ "public.ai_mentor_roleplay_difficulty": {
+ "name": "ai_mentor_roleplay_difficulty",
+ "schema": "public",
+ "values": [
+ "cooperative",
+ "realistic",
+ "challenging"
+ ]
+ },
+ "public.ai_mentor_teaching_style": {
+ "name": "ai_mentor_teaching_style",
+ "schema": "public",
+ "values": [
+ "explain_and_practice",
+ "guided_discovery",
+ "socratic"
+ ]
+ },
+ "public.article_status": {
+ "name": "article_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.course_type": {
+ "name": "course_type",
+ "schema": "public",
+ "values": [
+ "default",
+ "scorm"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published",
+ "private"
+ ]
+ },
+ "public.news_status": {
+ "name": "news_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.scorm_completion_status": {
+ "name": "scorm_completion_status",
+ "schema": "public",
+ "values": [
+ "completed",
+ "incomplete",
+ "not_attempted",
+ "unknown"
+ ]
+ },
+ "public.scorm_package_entity_type": {
+ "name": "scorm_package_entity_type",
+ "schema": "public",
+ "values": [
+ "course",
+ "lesson"
+ ]
+ },
+ "public.scorm_package_status": {
+ "name": "scorm_package_status",
+ "schema": "public",
+ "values": [
+ "processing",
+ "ready",
+ "failed"
+ ]
+ },
+ "public.scorm_standard": {
+ "name": "scorm_standard",
+ "schema": "public",
+ "values": [
+ "scorm_1_2",
+ "scorm_2004"
+ ]
+ },
+ "public.scorm_success_status": {
+ "name": "scorm_success_status",
+ "schema": "public",
+ "values": [
+ "passed",
+ "failed",
+ "unknown"
+ ]
+ },
+ "public.structured_ai_mentor_type": {
+ "name": "structured_ai_mentor_type",
+ "schema": "public",
+ "values": [
+ "teacher",
+ "roleplay"
+ ]
+ }
+ },
+ "schemas": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/apps/api/src/storage/migrations/meta/0181_snapshot.json b/apps/api/src/storage/migrations/meta/0181_snapshot.json
new file mode 100644
index 0000000000..da7886350e
--- /dev/null
+++ b/apps/api/src/storage/migrations/meta/0181_snapshot.json
@@ -0,0 +1,15683 @@
+{
+ "id": "ac657bae-4111-4460-a898-69f50191e6c9",
+ "prevId": "fce3e758-9163-4b71-b763-0ef6a51fd56b",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.activity_logs": {
+ "name": "activity_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_email": {
+ "name": "actor_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_role": {
+ "name": "actor_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action_type": {
+ "name": "action_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "activity_logs_tenant_id_idx": {
+ "name": "activity_logs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_tenant_timeframe_idx": {
+ "name": "activity_logs_tenant_timeframe_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_actor_idx": {
+ "name": "activity_logs_actor_idx",
+ "columns": [
+ {
+ "expression": "actor_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_action_idx": {
+ "name": "activity_logs_action_idx",
+ "columns": [
+ {
+ "expression": "action_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_timeframe_idx": {
+ "name": "activity_logs_timeframe_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "activity_logs_resource_idx": {
+ "name": "activity_logs_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "activity_logs_actor_id_users_id_fk": {
+ "name": "activity_logs_actor_id_users_id_fk",
+ "tableFrom": "activity_logs",
+ "columnsFrom": [
+ "actor_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "activity_logs_tenant_id_tenants_id_fk": {
+ "name": "activity_logs_tenant_id_tenants_id_fk",
+ "tableFrom": "activity_logs",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_blocking_errors": {
+ "name": "ai_judge_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_blocking_errors_tenant_id_idx": {
+ "name": "ai_judge_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_judge_blocking_errors_configuration_id_created_at_idx": {
+ "name": "ai_judge_blocking_errors_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_judge_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_configurations": {
+ "name": "ai_judge_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "passing_threshold_percent": {
+ "name": "passing_threshold_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_configurations_tenant_id_idx": {
+ "name": "ai_judge_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_judge_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_unique",
+ "columns": [
+ "ai_mentor_lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_judge_criteria": {
+ "name": "ai_judge_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expected_behavior": {
+ "name": "expected_behavior",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_criteria_tenant_id_idx": {
+ "name": "ai_judge_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_judge_criteria_configuration_id_created_at_idx": {
+ "name": "ai_judge_criteria_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_judge_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_score_guidance": {
+ "name": "ai_judge_score_guidance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "example": {
+ "name": "example",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_score_guidance_tenant_id_idx": {
+ "name": "ai_judge_score_guidance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_judge_score_guidance_criterion_id_score_unique": {
+ "name": "ai_judge_score_guidance_criterion_id_score_unique",
+ "columns": [
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "score",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "tableTo": "ai_judge_criteria",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_judge_score_guidance_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_score_guidance_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_blocking_errors": {
+ "name": "ai_mentor_judgement_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blocking_error_id": {
+ "name": "blocking_error_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "blocking_error_description": {
+ "name": "blocking_error_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_blocking_errors_tenant_id_idx": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "blocking_error_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "tableTo": "ai_mentor_judgements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "columnsFrom": [
+ "blocking_error_id"
+ ],
+ "tableTo": "ai_judge_blocking_errors",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_criteria": {
+ "name": "ai_mentor_judgement_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "criterion_title": {
+ "name": "criterion_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "awarded_points": {
+ "name": "awarded_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score_at_judgement": {
+ "name": "max_score_at_judgement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_criteria_tenant_id_idx": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "tableTo": "ai_mentor_judgements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "tableTo": "ai_judge_criteria",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgements": {
+ "name": "ai_mentor_judgements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "earned_points": {
+ "name": "earned_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgements_tenant_id_idx": {
+ "name": "ai_mentor_judgements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "ai_mentor_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_judge_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "ai_mentor_judgements_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgements_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_judgements_thread_id_unique": {
+ "name": "ai_mentor_judgements_thread_id_unique",
+ "columns": [
+ "thread_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_mentor_lessons": {
+ "name": "ai_mentor_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_instructions": {
+ "name": "ai_mentor_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'roleplay'"
+ },
+ "voice_mode": {
+ "name": "voice_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'preset'"
+ },
+ "tts_preset": {
+ "name": "tts_preset",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'male'"
+ },
+ "custom_tts_reference": {
+ "name": "custom_tts_reference",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_lessons_tenant_id_idx": {
+ "name": "ai_mentor_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_lessons_lesson_id_lessons_id_fk": {
+ "name": "ai_mentor_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_lessons_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_student_lesson_progress": {
+ "name": "ai_mentor_student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_lesson_progress_id": {
+ "name": "student_lesson_progress_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_score": {
+ "name": "min_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_student_lesson_progress_tenant_id_idx": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "columnsFrom": [
+ "student_lesson_progress_id"
+ ],
+ "tableTo": "student_lesson_progress",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_thread_messages": {
+ "name": "ai_mentor_thread_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_thread_messages_tenant_id_idx": {
+ "name": "ai_mentor_thread_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "ai_mentor_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_thread_messages_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_thread_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_threads": {
+ "name": "ai_mentor_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "user_language": {
+ "name": "user_language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_threads_tenant_id_idx": {
+ "name": "ai_mentor_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_threads_user_id_users_id_fk": {
+ "name": "ai_mentor_threads_user_id_users_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_threads_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.announcements": {
+ "name": "announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "audience": {
+ "name": "audience",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all_users'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'published'"
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "send_email": {
+ "name": "send_email",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "email_template": {
+ "name": "email_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "announcements_tenant_id_idx": {
+ "name": "announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "announcements_author_id_users_id_fk": {
+ "name": "announcements_author_id_users_id_fk",
+ "tableFrom": "announcements",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "announcements_tenant_id_tenants_id_fk": {
+ "name": "announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "announcements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.article_sections": {
+ "name": "article_sections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "article_sections_tenant_id_idx": {
+ "name": "article_sections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "article_sections_tenant_id_tenants_id_fk": {
+ "name": "article_sections_tenant_id_tenants_id_fk",
+ "tableFrom": "article_sections",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.articles": {
+ "name": "articles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "article_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "article_section_id": {
+ "name": "article_section_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by_id": {
+ "name": "updated_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "articles_tenant_id_idx": {
+ "name": "articles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "article_section_idx": {
+ "name": "article_section_idx",
+ "columns": [
+ {
+ "expression": "article_section_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "articles_article_section_id_article_sections_id_fk": {
+ "name": "articles_article_section_id_article_sections_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "article_section_id"
+ ],
+ "tableTo": "article_sections",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "articles_author_id_users_id_fk": {
+ "name": "articles_author_id_users_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "articles_updated_by_id_users_id_fk": {
+ "name": "articles_updated_by_id_users_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "updated_by_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "articles_tenant_id_tenants_id_fk": {
+ "name": "articles_tenant_id_tenants_id_fk",
+ "tableFrom": "articles",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_events": {
+ "name": "calendar_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "uid": {
+ "name": "uid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "all_day": {
+ "name": "all_day",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizer_user_id": {
+ "name": "organizer_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rrule": {
+ "name": "rrule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exdates": {
+ "name": "exdates",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_events_tenant_id_idx": {
+ "name": "calendar_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "calendar_events_tenant_starts_ends_idx": {
+ "name": "calendar_events_tenant_starts_ends_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starts_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "ends_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "calendar_events_tenant_uid_unique_idx": {
+ "name": "calendar_events_tenant_uid_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "uid",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "calendar_events_organizer_user_id_users_id_fk": {
+ "name": "calendar_events_organizer_user_id_users_id_fk",
+ "tableFrom": "calendar_events",
+ "columnsFrom": [
+ "organizer_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "calendar_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_events",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.categories": {
+ "name": "categories",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "categories_tenant_id_idx": {
+ "name": "categories_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "categories_tenant_id_base_title_unique": {
+ "name": "categories_tenant_id_base_title_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"title\"->>\"base_language\")",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "categories_tenant_id_tenants_id_fk": {
+ "name": "categories_tenant_id_tenants_id_fk",
+ "tableFrom": "categories",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.certificates": {
+ "name": "certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archive_reason": {
+ "name": "archive_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiration_warning_sent_at": {
+ "name": "expiration_warning_sent_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "certificates_tenant_id_idx": {
+ "name": "certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "certificates_active_expiry_idx": {
+ "name": "certificates_active_expiry_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "certificates_user_course_idx": {
+ "name": "certificates_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "certificates_user_id_users_id_fk": {
+ "name": "certificates_user_id_users_id_fk",
+ "tableFrom": "certificates",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "certificates_course_id_courses_id_fk": {
+ "name": "certificates_course_id_courses_id_fk",
+ "tableFrom": "certificates",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "certificates_tenant_id_tenants_id_fk": {
+ "name": "certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "certificates",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.chapters": {
+ "name": "chapters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_freemium": {
+ "name": "is_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_count": {
+ "name": "lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "chapters_tenant_id_idx": {
+ "name": "chapters_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "chapters_tenant_id_course_id_idx": {
+ "name": "chapters_tenant_id_course_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "chapters_course_id_courses_id_fk": {
+ "name": "chapters_course_id_courses_id_fk",
+ "tableFrom": "chapters",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "chapters_author_id_users_id_fk": {
+ "name": "chapters_author_id_users_id_fk",
+ "tableFrom": "chapters",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "chapters_tenant_id_tenants_id_fk": {
+ "name": "chapters_tenant_id_tenants_id_fk",
+ "tableFrom": "chapters",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_message_reactions": {
+ "name": "course_chat_message_reactions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reaction": {
+ "name": "reaction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_message_reactions_tenant_id_idx": {
+ "name": "course_chat_message_reactions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_message_reactions_message_id_reaction_idx": {
+ "name": "course_chat_message_reactions_message_id_reaction_idx",
+ "columns": [
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_message_reactions_user_message_reaction_unique_idx": {
+ "name": "course_chat_message_reactions_user_message_reaction_unique_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_chat_message_reactions_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_message_reactions_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "message_id"
+ ],
+ "tableTo": "course_chat_messages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_message_reactions_course_id_courses_id_fk": {
+ "name": "course_chat_message_reactions_course_id_courses_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_message_reactions_user_id_users_id_fk": {
+ "name": "course_chat_message_reactions_user_id_users_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_message_reactions_tenant_id_tenants_id_fk": {
+ "name": "course_chat_message_reactions_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_messages": {
+ "name": "course_chat_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_message_id": {
+ "name": "parent_message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_messages_tenant_id_idx": {
+ "name": "course_chat_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_messages_course_id_created_at_idx": {
+ "name": "course_chat_messages_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_messages_thread_id_created_at_idx": {
+ "name": "course_chat_messages_thread_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_messages_parent_message_id_created_at_idx": {
+ "name": "course_chat_messages_parent_message_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "parent_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_chat_messages_thread_id_course_chat_threads_id_fk": {
+ "name": "course_chat_messages_thread_id_course_chat_threads_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "tableTo": "course_chat_threads",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_messages_course_id_courses_id_fk": {
+ "name": "course_chat_messages_course_id_courses_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_messages_user_id_users_id_fk": {
+ "name": "course_chat_messages_user_id_users_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_messages_parent_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_messages_parent_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "parent_message_id"
+ ],
+ "tableTo": "course_chat_messages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "course_chat_messages_tenant_id_tenants_id_fk": {
+ "name": "course_chat_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_messages",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_threads": {
+ "name": "course_chat_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_threads_tenant_id_idx": {
+ "name": "course_chat_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_threads_course_id_created_at_idx": {
+ "name": "course_chat_threads_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_chat_threads_course_id_updated_at_idx": {
+ "name": "course_chat_threads_course_id_updated_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_chat_threads_course_id_courses_id_fk": {
+ "name": "course_chat_threads_course_id_courses_id_fk",
+ "tableFrom": "course_chat_threads",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_threads_created_by_user_id_users_id_fk": {
+ "name": "course_chat_threads_created_by_user_id_users_id_fk",
+ "tableFrom": "course_chat_threads",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_chat_threads_tenant_id_tenants_id_fk": {
+ "name": "course_chat_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_threads",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_slugs": {
+ "name": "course_slugs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_short_id": {
+ "name": "course_short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lang": {
+ "name": "lang",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_slugs_tenant_id_idx": {
+ "name": "course_slugs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "course_slug_course_short_id_lang_unique_idx": {
+ "name": "course_slug_course_short_id_lang_unique_idx",
+ "columns": [
+ {
+ "expression": "course_short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lang",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_slugs_course_short_id_courses_short_id_fk": {
+ "name": "course_slugs_course_short_id_courses_short_id_fk",
+ "tableFrom": "course_slugs",
+ "columnsFrom": [
+ "course_short_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "short_id"
+ ],
+ "onUpdate": "cascade",
+ "onDelete": "cascade"
+ },
+ "course_slugs_tenant_id_tenants_id_fk": {
+ "name": "course_slugs_tenant_id_tenants_id_fk",
+ "tableFrom": "course_slugs",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_student_mode": {
+ "name": "course_student_mode",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_student_mode_tenant_id_idx": {
+ "name": "course_student_mode_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_student_mode_user_id_users_id_fk": {
+ "name": "course_student_mode_user_id_users_id_fk",
+ "tableFrom": "course_student_mode",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_student_mode_course_id_courses_id_fk": {
+ "name": "course_student_mode_course_id_courses_id_fk",
+ "tableFrom": "course_student_mode",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_student_mode_tenant_id_tenants_id_fk": {
+ "name": "course_student_mode_tenant_id_tenants_id_fk",
+ "tableFrom": "course_student_mode",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_student_mode_user_id_course_id_unique": {
+ "name": "course_student_mode_user_id_course_id_unique",
+ "columns": [
+ "user_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.course_students_stats": {
+ "name": "course_students_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "month": {
+ "name": "month",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "new_students_count": {
+ "name": "new_students_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_students_stats_tenant_id_idx": {
+ "name": "course_students_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "course_students_stats_course_id_courses_id_fk": {
+ "name": "course_students_stats_course_id_courses_id_fk",
+ "tableFrom": "course_students_stats",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_students_stats_author_id_users_id_fk": {
+ "name": "course_students_stats_author_id_users_id_fk",
+ "tableFrom": "course_students_stats",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "course_students_stats_tenant_id_tenants_id_fk": {
+ "name": "course_students_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "course_students_stats",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_students_stats_course_id_month_year_unique": {
+ "name": "course_students_stats_course_id_month_year_unique",
+ "columns": [
+ "course_id",
+ "month",
+ "year"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.courses": {
+ "name": "courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "short_id": {
+ "name": "short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_s3_key": {
+ "name": "thumbnail_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "has_certificate": {
+ "name": "has_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "price_in_cents": {
+ "name": "price_in_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "currency": {
+ "name": "currency",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'usd'"
+ },
+ "chapter_count": {
+ "name": "chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "course_type": {
+ "name": "course_type",
+ "type": "course_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category_id": {
+ "name": "category_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stripe_product_id": {
+ "name": "stripe_product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripe_price_id": {
+ "name": "stripe_price_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"lessonSequenceEnabled\":false,\"quizFeedbackEnabled\":true,\"certificateSignature\":null,\"certificateFontColor\":null,\"certificateValidity\":null,\"videoCompletionTrackingEnabled\":true}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_tenant_id_idx": {
+ "name": "courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "courses_short_id_unique_idx": {
+ "name": "courses_short_id_unique_idx",
+ "columns": [
+ {
+ "expression": "short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "courses_author_id_users_id_fk": {
+ "name": "courses_author_id_users_id_fk",
+ "tableFrom": "courses",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "courses_category_id_categories_id_fk": {
+ "name": "courses_category_id_categories_id_fk",
+ "tableFrom": "courses",
+ "columnsFrom": [
+ "category_id"
+ ],
+ "tableTo": "categories",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "courses_tenant_id_tenants_id_fk": {
+ "name": "courses_tenant_id_tenants_id_fk",
+ "tableFrom": "courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.courses_summary_stats": {
+ "name": "courses_summary_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "free_purchased_count": {
+ "name": "free_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_count": {
+ "name": "paid_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_after_freemium_count": {
+ "name": "paid_purchased_after_freemium_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_freemium_student_count": {
+ "name": "completed_freemium_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_course_student_count": {
+ "name": "completed_course_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_summary_stats_tenant_id_idx": {
+ "name": "courses_summary_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "courses_summary_stats_course_id_courses_id_fk": {
+ "name": "courses_summary_stats_course_id_courses_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "courses_summary_stats_author_id_users_id_fk": {
+ "name": "courses_summary_stats_author_id_users_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "courses_summary_stats_tenant_id_tenants_id_fk": {
+ "name": "courses_summary_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "courses_summary_stats_course_id_unique": {
+ "name": "courses_summary_stats_course_id_unique",
+ "columns": [
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.create_tokens": {
+ "name": "create_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reminder_count": {
+ "name": "reminder_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "create_tokens_tenant_id_idx": {
+ "name": "create_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "create_tokens_token_hash_idx": {
+ "name": "create_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "create_tokens_user_id_users_id_fk": {
+ "name": "create_tokens_user_id_users_id_fk",
+ "tableFrom": "create_tokens",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "create_tokens_tenant_id_tenants_id_fk": {
+ "name": "create_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "create_tokens",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.credentials": {
+ "name": "credentials",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requires_password_change": {
+ "name": "requires_password_change",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "credentials_tenant_id_idx": {
+ "name": "credentials_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "credentials_user_id_users_id_fk": {
+ "name": "credentials_user_id_users_id_fk",
+ "tableFrom": "credentials",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "credentials_tenant_id_tenants_id_fk": {
+ "name": "credentials_tenant_id_tenants_id_fk",
+ "tableFrom": "credentials",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.doc_chunks": {
+ "name": "doc_chunks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_index": {
+ "name": "chunk_index",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding": {
+ "name": "embedding",
+ "type": "vector(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "doc_chunks_tenant_id_idx": {
+ "name": "doc_chunks_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "doc_chunks_document_id_documents_id_fk": {
+ "name": "doc_chunks_document_id_documents_id_fk",
+ "tableFrom": "doc_chunks",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "doc_chunks_tenant_id_tenants_id_fk": {
+ "name": "doc_chunks_tenant_id_tenants_id_fk",
+ "tableFrom": "doc_chunks",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.document_to_ai_mentor_lesson": {
+ "name": "document_to_ai_mentor_lesson",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "document_to_ai_mentor_lesson_tenant_id_idx": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "document_to_ai_mentor_lesson_document_id_documents_id_fk": {
+ "name": "document_to_ai_mentor_lesson_document_id_documents_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "tableTo": "documents",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique": {
+ "name": "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique",
+ "columns": [
+ "document_id",
+ "ai_mentor_lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.documents": {
+ "name": "documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "check_sum": {
+ "name": "check_sum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "documents_tenant_id_idx": {
+ "name": "documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "documents_tenant_id_tenants_id_fk": {
+ "name": "documents_tenant_id_tenants_id_fk",
+ "tableFrom": "documents",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "documents_check_sum_unique": {
+ "name": "documents_check_sum_unique",
+ "columns": [
+ "check_sum"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.form_field_answers": {
+ "name": "form_field_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_field_id": {
+ "name": "form_field_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label_snapshot": {
+ "name": "label_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "answered_language": {
+ "name": "answered_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_field_answers_tenant_id_idx": {
+ "name": "form_field_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "form_field_answers_user_id_form_field_id_unique": {
+ "name": "form_field_answers_user_id_form_field_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "form_field_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "form_field_answers_user_id_idx": {
+ "name": "form_field_answers_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "form_field_answers_form_field_id_form_fields_id_fk": {
+ "name": "form_field_answers_form_field_id_form_fields_id_fk",
+ "tableFrom": "form_field_answers",
+ "columnsFrom": [
+ "form_field_id"
+ ],
+ "tableTo": "form_fields",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "restrict"
+ },
+ "form_field_answers_user_id_users_id_fk": {
+ "name": "form_field_answers_user_id_users_id_fk",
+ "tableFrom": "form_field_answers",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "form_field_answers_tenant_id_tenants_id_fk": {
+ "name": "form_field_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "form_field_answers",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.form_fields": {
+ "name": "form_fields",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_id": {
+ "name": "form_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "required": {
+ "name": "required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_fields_tenant_id_idx": {
+ "name": "form_fields_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "form_fields_form_id_display_order_idx": {
+ "name": "form_fields_form_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "form_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "form_fields_form_id_forms_id_fk": {
+ "name": "form_fields_form_id_forms_id_fk",
+ "tableFrom": "form_fields",
+ "columnsFrom": [
+ "form_id"
+ ],
+ "tableTo": "forms",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "form_fields_tenant_id_tenants_id_fk": {
+ "name": "form_fields_tenant_id_tenants_id_fk",
+ "tableFrom": "form_fields",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.forms": {
+ "name": "forms",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "forms_tenant_id_idx": {
+ "name": "forms_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "forms_tenant_id_type_unique_idx": {
+ "name": "forms_tenant_id_type_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "forms_tenant_id_tenants_id_fk": {
+ "name": "forms_tenant_id_tenants_id_fk",
+ "tableFrom": "forms",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.group_announcements": {
+ "name": "group_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_announcements_tenant_id_idx": {
+ "name": "group_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_announcements_group_id_groups_id_fk": {
+ "name": "group_announcements_group_id_groups_id_fk",
+ "tableFrom": "group_announcements",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_announcements_announcement_id_announcements_id_fk": {
+ "name": "group_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "group_announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "tableTo": "announcements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_announcements_tenant_id_tenants_id_fk": {
+ "name": "group_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "group_announcements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_announcements_group_id_announcement_id_unique": {
+ "name": "group_announcements_group_id_announcement_id_unique",
+ "columns": [
+ "group_id",
+ "announcement_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.group_courses": {
+ "name": "group_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enrolled_by": {
+ "name": "enrolled_by",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_mandatory": {
+ "name": "is_mandatory",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "due_date": {
+ "name": "due_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_courses_tenant_id_idx": {
+ "name": "group_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_courses_group_id_groups_id_fk": {
+ "name": "group_courses_group_id_groups_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_courses_course_id_courses_id_fk": {
+ "name": "group_courses_course_id_courses_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_courses_enrolled_by_users_id_fk": {
+ "name": "group_courses_enrolled_by_users_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "enrolled_by"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "group_courses_calendar_event_id_calendar_events_id_fk": {
+ "name": "group_courses_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "tableTo": "calendar_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "group_courses_tenant_id_tenants_id_fk": {
+ "name": "group_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "group_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_courses_calendar_event_id_unique": {
+ "name": "group_courses_calendar_event_id_unique",
+ "columns": [
+ "calendar_event_id"
+ ],
+ "nullsNotDistinct": false
+ },
+ "group_courses_group_id_course_id_unique": {
+ "name": "group_courses_group_id_course_id_unique",
+ "columns": [
+ "group_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.group_learning_paths": {
+ "name": "group_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_learning_paths_tenant_id_idx": {
+ "name": "group_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "group_learning_paths_learning_path_idx": {
+ "name": "group_learning_paths_learning_path_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_learning_paths_group_id_groups_id_fk": {
+ "name": "group_learning_paths_group_id_groups_id_fk",
+ "tableFrom": "group_learning_paths",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "group_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "group_learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "group_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "group_learning_paths",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_learning_paths_group_id_learning_path_id_unique": {
+ "name": "group_learning_paths_group_id_learning_path_id_unique",
+ "columns": [
+ "group_id",
+ "learning_path_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.group_users": {
+ "name": "group_users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_users_tenant_id_idx": {
+ "name": "group_users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "group_users_user_id_users_id_fk": {
+ "name": "group_users_user_id_users_id_fk",
+ "tableFrom": "group_users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_users_group_id_groups_id_fk": {
+ "name": "group_users_group_id_groups_id_fk",
+ "tableFrom": "group_users",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "group_users_tenant_id_tenants_id_fk": {
+ "name": "group_users_tenant_id_tenants_id_fk",
+ "tableFrom": "group_users",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_users_user_id_group_id_unique": {
+ "name": "group_users_user_id_group_id_unique",
+ "columns": [
+ "user_id",
+ "group_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.groups": {
+ "name": "groups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "characteristic": {
+ "name": "characteristic",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "groups_tenant_id_idx": {
+ "name": "groups_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "groups_tenant_id_tenants_id_fk": {
+ "name": "groups_tenant_id_tenants_id_fk",
+ "tableFrom": "groups",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.integration_api_keys": {
+ "name": "integration_api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "key_prefix": {
+ "name": "key_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "integration_api_keys_tenant_id_idx": {
+ "name": "integration_api_keys_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "integration_api_keys_key_prefix_idx": {
+ "name": "integration_api_keys_key_prefix_idx",
+ "columns": [
+ {
+ "expression": "key_prefix",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "integration_api_keys_created_by_idx": {
+ "name": "integration_api_keys_created_by_idx",
+ "columns": [
+ {
+ "expression": "created_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "integration_api_keys_created_by_user_id_users_id_fk": {
+ "name": "integration_api_keys_created_by_user_id_users_id_fk",
+ "tableFrom": "integration_api_keys",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "integration_api_keys_tenant_id_tenants_id_fk": {
+ "name": "integration_api_keys_tenant_id_tenants_id_fk",
+ "tableFrom": "integration_api_keys",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_certificates": {
+ "name": "learning_path_certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_certificates_tenant_id_idx": {
+ "name": "learning_path_certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_certificates_user_id_users_id_fk": {
+ "name": "learning_path_certificates_user_id_users_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_certificates_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_certificates_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_certificates_tenant_id_tenants_id_fk": {
+ "name": "learning_path_certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_courses": {
+ "name": "learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_courses_tenant_id_idx": {
+ "name": "learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_courses_path_id_course_id_unique_idx": {
+ "name": "learning_path_courses_path_id_course_id_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_courses_path_id_display_order_unique_idx": {
+ "name": "learning_path_courses_path_id_display_order_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_courses_path_id_display_order_idx": {
+ "name": "learning_path_courses_path_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_courses",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_courses_course_id_courses_id_fk": {
+ "name": "learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "learning_path_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_entity_map": {
+ "name": "learning_path_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "learning_path_entity_map_export_idx": {
+ "name": "learning_path_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_entity_map_source_entity_idx": {
+ "name": "learning_path_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_entity_map_source_unique_idx": {
+ "name": "learning_path_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_entity_map_export_id_learning_path_exports_id_fk": {
+ "name": "learning_path_entity_map_export_id_learning_path_exports_id_fk",
+ "tableFrom": "learning_path_entity_map",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "tableTo": "learning_path_exports",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_exports": {
+ "name": "learning_path_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_learning_path_id": {
+ "name": "target_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "learning_path_exports_source_learning_path_idx": {
+ "name": "learning_path_exports_source_learning_path_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_exports_target_learning_path_idx": {
+ "name": "learning_path_exports_target_learning_path_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "learning_path_exports_source_target_unique_idx": {
+ "name": "learning_path_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_path_exports_source_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_exports_target_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "learning_path_exports_target_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_exports_target_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_exports",
+ "columnsFrom": [
+ "target_learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_paths": {
+ "name": "learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_reference": {
+ "name": "thumbnail_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "includes_certificate": {
+ "name": "includes_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"certificateSignature\":null,\"certificateFontColor\":null}'::jsonb"
+ },
+ "sequence_enabled": {
+ "name": "sequence_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_paths_tenant_id_idx": {
+ "name": "learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "learning_paths_author_id_users_id_fk": {
+ "name": "learning_paths_author_id_users_id_fk",
+ "tableFrom": "learning_paths",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "learning_paths_tenant_id_tenants_id_fk": {
+ "name": "learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_paths",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.lesson_learning_time": {
+ "name": "lesson_learning_time",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_learning_time_tenant_id_idx": {
+ "name": "lesson_learning_time_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lesson_learning_time_user_course_idx": {
+ "name": "lesson_learning_time_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "lesson_learning_time_user_id_users_id_fk": {
+ "name": "lesson_learning_time_user_id_users_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_learning_time_lesson_id_lessons_id_fk": {
+ "name": "lesson_learning_time_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_learning_time_course_id_courses_id_fk": {
+ "name": "lesson_learning_time_course_id_courses_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_learning_time_tenant_id_tenants_id_fk": {
+ "name": "lesson_learning_time_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_learning_time_user_id_lesson_id_unique": {
+ "name": "lesson_learning_time_user_id_lesson_id_unique",
+ "columns": [
+ "user_id",
+ "lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.lesson_video_progress": {
+ "name": "lesson_video_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_entity_id": {
+ "name": "resource_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "duration_seconds": {
+ "name": "duration_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bucket_size_seconds": {
+ "name": "bucket_size_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "watched_ranges": {
+ "name": "watched_ranges",
+ "type": "int4multirange",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::int4multirange"
+ },
+ "covered_bucket_count": {
+ "name": "covered_bucket_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "coverage_percent": {
+ "name": "coverage_percent",
+ "type": "numeric(5, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "active_watch_seconds": {
+ "name": "active_watch_seconds",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "is_watched": {
+ "name": "is_watched",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "watched_at": {
+ "name": "watched_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_video_progress_tenant_id_idx": {
+ "name": "lesson_video_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lesson_video_progress_lesson_idx": {
+ "name": "lesson_video_progress_lesson_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lesson_video_progress_resource_entity_idx": {
+ "name": "lesson_video_progress_resource_entity_idx",
+ "columns": [
+ {
+ "expression": "resource_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "lesson_video_progress_student_id_users_id_fk": {
+ "name": "lesson_video_progress_student_id_users_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_video_progress_lesson_id_lessons_id_fk": {
+ "name": "lesson_video_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_video_progress_resource_entity_id_resource_entity_id_fk": {
+ "name": "lesson_video_progress_resource_entity_id_resource_entity_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "resource_entity_id"
+ ],
+ "tableTo": "resource_entity",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lesson_video_progress_tenant_id_tenants_id_fk": {
+ "name": "lesson_video_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique": {
+ "name": "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique",
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "resource_entity_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.lessons": {
+ "name": "lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "threshold_score": {
+ "name": "threshold_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts_limit": {
+ "name": "attempts_limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quiz_cooldown_in_hours": {
+ "name": "quiz_cooldown_in_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_s3_key": {
+ "name": "file_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_external": {
+ "name": "is_external",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lessons_tenant_id_idx": {
+ "name": "lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "lessons_tenant_id_chapter_id_type_idx": {
+ "name": "lessons_tenant_id_chapter_id_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chapter_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "lessons_chapter_id_chapters_id_fk": {
+ "name": "lessons_chapter_id_chapters_id_fk",
+ "tableFrom": "lessons",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "tableTo": "chapters",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "lessons_tenant_id_tenants_id_fk": {
+ "name": "lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "lessons",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_lessons": {
+ "name": "live_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_link_id": {
+ "name": "live_training_link_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_lessons_tenant_id_idx": {
+ "name": "live_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_lessons_lesson_language_unique_idx": {
+ "name": "live_lessons_lesson_language_unique_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_lessons_training_link_idx": {
+ "name": "live_lessons_training_link_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_link_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_lessons_training_idx": {
+ "name": "live_lessons_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_lessons_live_training_id_live_trainings_id_fk": {
+ "name": "live_lessons_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_lessons_live_training_link_id_live_training_links_id_fk": {
+ "name": "live_lessons_live_training_link_id_live_training_links_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "live_training_link_id"
+ ],
+ "tableTo": "live_training_links",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_lessons_lesson_id_lessons_id_fk": {
+ "name": "live_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_lessons_tenant_id_tenants_id_fk": {
+ "name": "live_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "live_lessons",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_attendance": {
+ "name": "live_training_attendance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_participant_id": {
+ "name": "live_training_session_participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "joined_at": {
+ "name": "joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "left_at": {
+ "name": "left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_participant_sid": {
+ "name": "livekit_participant_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disconnect_reason": {
+ "name": "disconnect_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_attendance_tenant_id_idx": {
+ "name": "live_training_attendance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_attendance_session_user_idx": {
+ "name": "live_training_attendance_session_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_attendance_training_user_idx": {
+ "name": "live_training_attendance_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_attendance_joined_at_idx": {
+ "name": "live_training_attendance_joined_at_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "joined_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk": {
+ "name": "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "live_training_session_participant_id"
+ ],
+ "tableTo": "live_training_session_participants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_attendance_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_attendance_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "tableTo": "live_training_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_attendance_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_attendance_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_attendance_user_id_users_id_fk": {
+ "name": "live_training_attendance_user_id_users_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_attendance_tenant_id_tenants_id_fk": {
+ "name": "live_training_attendance_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_links": {
+ "name": "live_training_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'course'"
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_links_tenant_id_idx": {
+ "name": "live_training_links_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_links_training_entity_unique_idx": {
+ "name": "live_training_links_training_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_links_training_idx": {
+ "name": "live_training_links_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_links_entity_idx": {
+ "name": "live_training_links_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_links_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_links_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_links",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_links_tenant_id_tenants_id_fk": {
+ "name": "live_training_links_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_links",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_members": {
+ "name": "live_training_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'host'"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_members_tenant_id_idx": {
+ "name": "live_training_members_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_training_user_unique_idx": {
+ "name": "live_training_members_training_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_training_idx": {
+ "name": "live_training_members_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_user_idx": {
+ "name": "live_training_members_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_members_role_idx": {
+ "name": "live_training_members_role_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_members_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_members_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_members",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_members_user_id_users_id_fk": {
+ "name": "live_training_members_user_id_users_id_fk",
+ "tableFrom": "live_training_members",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_members_tenant_id_tenants_id_fk": {
+ "name": "live_training_members_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_members",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_session_participants": {
+ "name": "live_training_session_participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_joined_at": {
+ "name": "first_joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_left_at": {
+ "name": "last_left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "join_count": {
+ "name": "join_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "livekit_identity": {
+ "name": "livekit_identity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_session_participants_tenant_id_idx": {
+ "name": "live_training_session_participants_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_session_user_unique_idx": {
+ "name": "live_training_session_participants_session_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_session_idx": {
+ "name": "live_training_session_participants_session_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_training_user_idx": {
+ "name": "live_training_session_participants_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_session_participants_user_idx": {
+ "name": "live_training_session_participants_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "tableTo": "live_training_sessions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_session_participants_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_session_participants_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_session_participants_user_id_users_id_fk": {
+ "name": "live_training_session_participants_user_id_users_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_session_participants_tenant_id_tenants_id_fk": {
+ "name": "live_training_session_participants_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_sessions": {
+ "name": "live_training_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'waiting'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_by_user_id": {
+ "name": "started_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_by_user_id": {
+ "name": "ended_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "end_reason": {
+ "name": "end_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_name": {
+ "name": "livekit_room_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_sid": {
+ "name": "livekit_room_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "peak_participant_count": {
+ "name": "peak_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "unique_participant_count": {
+ "name": "unique_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_sessions_tenant_id_idx": {
+ "name": "live_training_sessions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_sessions_training_idx": {
+ "name": "live_training_sessions_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_sessions_status_idx": {
+ "name": "live_training_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_training_sessions_livekit_room_name_idx": {
+ "name": "live_training_sessions_livekit_room_name_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "livekit_room_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_training_sessions_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_sessions_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "tableTo": "live_trainings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_training_sessions_started_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_started_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "started_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_sessions_ended_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_ended_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "ended_by_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_training_sessions_tenant_id_tenants_id_fk": {
+ "name": "live_training_sessions_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_sessions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_trainings": {
+ "name": "live_trainings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "delivery_type": {
+ "name": "delivery_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'online'"
+ },
+ "visibility_scope": {
+ "name": "visibility_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'linked_courses'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "max_participants": {
+ "name": "max_participants",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"viewerPermissions\":{\"microphoneEnabled\":false,\"cameraEnabled\":false}}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_trainings_tenant_id_idx": {
+ "name": "live_trainings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_trainings_tenant_status_idx": {
+ "name": "live_trainings_tenant_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "live_trainings_author_idx": {
+ "name": "live_trainings_author_idx",
+ "columns": [
+ {
+ "expression": "author_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "live_trainings_calendar_event_id_calendar_events_id_fk": {
+ "name": "live_trainings_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "live_trainings",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "tableTo": "calendar_events",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "live_trainings_author_id_users_id_fk": {
+ "name": "live_trainings_author_id_users_id_fk",
+ "tableFrom": "live_trainings",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "live_trainings_tenant_id_tenants_id_fk": {
+ "name": "live_trainings_tenant_id_tenants_id_fk",
+ "tableFrom": "live_trainings",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "live_trainings_calendar_event_id_unique": {
+ "name": "live_trainings_calendar_event_id_unique",
+ "columns": [
+ "calendar_event_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.luma_course_generation_syncs": {
+ "name": "luma_course_generation_syncs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_id": {
+ "name": "draft_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failed_at": {
+ "name": "failed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dismissed_at": {
+ "name": "dismissed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "luma_course_generation_syncs_tenant_id_idx": {
+ "name": "luma_course_generation_syncs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "luma_course_generation_syncs_course_id_idx": {
+ "name": "luma_course_generation_syncs_course_id_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "luma_course_generation_syncs_status_idx": {
+ "name": "luma_course_generation_syncs_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "luma_course_generation_syncs_course_id_courses_id_fk": {
+ "name": "luma_course_generation_syncs_course_id_courses_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "luma_course_generation_syncs_tenant_id_tenants_id_fk": {
+ "name": "luma_course_generation_syncs_tenant_id_tenants_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "luma_course_generation_syncs_course_id_unique": {
+ "name": "luma_course_generation_syncs_course_id_unique",
+ "columns": [
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.magic_link_tokens": {
+ "name": "magic_link_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "magic_link_tokens_tenant_id_idx": {
+ "name": "magic_link_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "magic_link_tokens_token_hash_idx": {
+ "name": "magic_link_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "magic_link_tokens_user_id_users_id_fk": {
+ "name": "magic_link_tokens_user_id_users_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "magic_link_tokens_tenant_id_tenants_id_fk": {
+ "name": "magic_link_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_entity_map": {
+ "name": "master_course_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "master_course_entity_map_export_idx": {
+ "name": "master_course_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_entity_map_source_entity_idx": {
+ "name": "master_course_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_entity_map_source_unique_idx": {
+ "name": "master_course_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "master_course_entity_map_export_id_master_course_exports_id_fk": {
+ "name": "master_course_entity_map_export_id_master_course_exports_id_fk",
+ "tableFrom": "master_course_entity_map",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "tableTo": "master_course_exports",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_exports": {
+ "name": "master_course_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_course_id": {
+ "name": "target_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "master_course_exports_source_course_idx": {
+ "name": "master_course_exports_source_course_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_exports_target_course_idx": {
+ "name": "master_course_exports_target_course_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "master_course_exports_source_target_unique_idx": {
+ "name": "master_course_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "master_course_exports_source_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "master_course_exports_source_course_id_courses_id_fk": {
+ "name": "master_course_exports_source_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "source_course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "master_course_exports_target_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "master_course_exports_target_course_id_courses_id_fk": {
+ "name": "master_course_exports_target_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "columnsFrom": [
+ "target_course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.news": {
+ "name": "news",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "news_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "news_tenant_id_idx": {
+ "name": "news_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "news_author_id_users_id_fk": {
+ "name": "news_author_id_users_id_fk",
+ "tableFrom": "news",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "news_tenant_id_tenants_id_fk": {
+ "name": "news_tenant_id_tenants_id_fk",
+ "tableFrom": "news",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.outbox_events": {
+ "name": "outbox_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "outbox_events_tenant_id_idx": {
+ "name": "outbox_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "outbox_events_poll_idx": {
+ "name": "outbox_events_poll_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "outbox_events_tenant_id_tenants_id_fk": {
+ "name": "outbox_events_tenant_id_tenants_id_fk",
+ "tableFrom": "outbox_events",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_role_rule_sets": {
+ "name": "permission_role_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_role_rule_sets_tenant_id_idx": {
+ "name": "permission_role_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_role_rule_sets_role_id_rule_set_id_unique": {
+ "name": "permission_role_rule_sets_role_id_rule_set_id_unique",
+ "columns": [
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_role_rule_sets_role_id_permission_roles_id_fk": {
+ "name": "permission_role_rule_sets_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "tableTo": "permission_roles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "tableTo": "permission_rule_sets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_role_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_role_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_roles": {
+ "name": "permission_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_roles_tenant_id_idx": {
+ "name": "permission_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_roles_tenant_id_slug_unique": {
+ "name": "permission_roles_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_roles",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_set_permissions": {
+ "name": "permission_rule_set_permissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission": {
+ "name": "permission",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_set_permissions_tenant_id_idx": {
+ "name": "permission_rule_set_permissions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_rule_set_permissions_rule_set_id_permission_unique": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_unique",
+ "columns": [
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "tableTo": "permission_rule_sets",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_rule_set_permissions_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_set_permissions_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_sets": {
+ "name": "permission_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_sets_tenant_id_idx": {
+ "name": "permission_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_rule_sets_tenant_id_slug_unique": {
+ "name": "permission_rule_sets_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_sets",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_user_roles": {
+ "name": "permission_user_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_user_roles_tenant_id_idx": {
+ "name": "permission_user_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "permission_user_roles_user_id_role_id_unique": {
+ "name": "permission_user_roles_user_id_role_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "permission_user_roles_user_id_users_id_fk": {
+ "name": "permission_user_roles_user_id_users_id_fk",
+ "tableFrom": "permission_user_roles",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_user_roles_role_id_permission_roles_id_fk": {
+ "name": "permission_user_roles_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_user_roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "tableTo": "permission_roles",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "permission_user_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_user_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_user_roles",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.question_answer_options": {
+ "name": "question_answer_options",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "option_text": {
+ "name": "option_text",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_word": {
+ "name": "matched_word",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scale_answer": {
+ "name": "scale_answer",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "question_answer_options_tenant_id_idx": {
+ "name": "question_answer_options_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "question_answer_options_question_id_questions_id_fk": {
+ "name": "question_answer_options_question_id_questions_id_fk",
+ "tableFrom": "question_answer_options",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "tableTo": "questions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "question_answer_options_tenant_id_tenants_id_fk": {
+ "name": "question_answer_options_tenant_id_tenants_id_fk",
+ "tableFrom": "question_answer_options",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions": {
+ "name": "questions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "photo_s3_key": {
+ "name": "photo_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "solution_explanation": {
+ "name": "solution_explanation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_tenant_id_idx": {
+ "name": "questions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "questions_lesson_id_lessons_id_fk": {
+ "name": "questions_lesson_id_lessons_id_fk",
+ "tableFrom": "questions",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "questions_author_id_users_id_fk": {
+ "name": "questions_author_id_users_id_fk",
+ "tableFrom": "questions",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "questions_tenant_id_tenants_id_fk": {
+ "name": "questions_tenant_id_tenants_id_fk",
+ "tableFrom": "questions",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions_and_answers": {
+ "name": "questions_and_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_and_answers_tenant_id_idx": {
+ "name": "questions_and_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "questions_and_answers_tenant_id_tenants_id_fk": {
+ "name": "questions_and_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "questions_and_answers",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.quiz_attempts": {
+ "name": "quiz_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "correct_answers": {
+ "name": "correct_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wrong_answers": {
+ "name": "wrong_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "quiz_attempts_tenant_id_idx": {
+ "name": "quiz_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "quiz_attempts_user_id_users_id_fk": {
+ "name": "quiz_attempts_user_id_users_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "quiz_attempts_course_id_courses_id_fk": {
+ "name": "quiz_attempts_course_id_courses_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "quiz_attempts_lesson_id_lessons_id_fk": {
+ "name": "quiz_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "quiz_attempts_tenant_id_tenants_id_fk": {
+ "name": "quiz_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "quiz_attempts",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.reset_tokens": {
+ "name": "reset_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "reset_tokens_tenant_id_idx": {
+ "name": "reset_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "reset_tokens_token_hash_idx": {
+ "name": "reset_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "reset_tokens_user_id_users_id_fk": {
+ "name": "reset_tokens_user_id_users_id_fk",
+ "tableFrom": "reset_tokens",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "reset_tokens_tenant_id_tenants_id_fk": {
+ "name": "reset_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "reset_tokens",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.resource_entity": {
+ "name": "resource_entity",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "relationship_type": {
+ "name": "relationship_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'attachment'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resource_entity_tenant_id_idx": {
+ "name": "resource_entity_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_entity_resource_idx": {
+ "name": "resource_entity_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_entity_entity_idx": {
+ "name": "resource_entity_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "resource_entity_relationship_idx": {
+ "name": "resource_entity_relationship_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "relationship_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "resource_entity_resource_id_resources_id_fk": {
+ "name": "resource_entity_resource_id_resources_id_fk",
+ "tableFrom": "resource_entity",
+ "columnsFrom": [
+ "resource_id"
+ ],
+ "tableTo": "resources",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "resource_entity_tenant_id_tenants_id_fk": {
+ "name": "resource_entity_tenant_id_tenants_id_fk",
+ "tableFrom": "resource_entity",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique": {
+ "name": "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique",
+ "columns": [
+ "resource_id",
+ "entity_id",
+ "entity_type",
+ "relationship_type"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.resources": {
+ "name": "resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reference": {
+ "name": "reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "uploaded_by_id": {
+ "name": "uploaded_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resources_tenant_id_idx": {
+ "name": "resources_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "resources_uploaded_by_id_users_id_fk": {
+ "name": "resources_uploaded_by_id_users_id_fk",
+ "tableFrom": "resources",
+ "columnsFrom": [
+ "uploaded_by_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "resources_tenant_id_tenants_id_fk": {
+ "name": "resources_tenant_id_tenants_id_fk",
+ "tableFrom": "resources",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_attempts": {
+ "name": "scorm_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sco_id": {
+ "name": "sco_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attempt_number": {
+ "name": "attempt_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_attempts_tenant_id_idx": {
+ "name": "scorm_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_student_lesson_idx": {
+ "name": "scorm_attempts_student_lesson_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_student_package_idx": {
+ "name": "scorm_attempts_student_package_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_sco_id_idx": {
+ "name": "scorm_attempts_sco_id_idx",
+ "columns": [
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_attempts_student_package_sco_attempt_unique_idx": {
+ "name": "scorm_attempts_student_package_sco_attempt_unique_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "attempt_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_attempts_student_id_users_id_fk": {
+ "name": "scorm_attempts_student_id_users_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_course_id_courses_id_fk": {
+ "name": "scorm_attempts_course_id_courses_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_lesson_id_lessons_id_fk": {
+ "name": "scorm_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_package_id_scorm_packages_id_fk": {
+ "name": "scorm_attempts_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "tableTo": "scorm_packages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_sco_id_scorm_scos_id_fk": {
+ "name": "scorm_attempts_sco_id_scorm_scos_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "sco_id"
+ ],
+ "tableTo": "scorm_scos",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_attempts_tenant_id_tenants_id_fk": {
+ "name": "scorm_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_attempts",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_packages": {
+ "name": "scorm_packages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "scorm_package_entity_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "standard": {
+ "name": "standard",
+ "type": "scorm_standard",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_file_reference": {
+ "name": "original_file_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "extracted_files_reference": {
+ "name": "extracted_files_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_entry_point": {
+ "name": "manifest_entry_point",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_json": {
+ "name": "manifest_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "scorm_package_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_packages_tenant_id_idx": {
+ "name": "scorm_packages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_packages_entity_idx": {
+ "name": "scorm_packages_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_packages_entity_unique_idx": {
+ "name": "scorm_packages_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_packages_tenant_id_tenants_id_fk": {
+ "name": "scorm_packages_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_packages",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_runtime_state": {
+ "name": "scorm_runtime_state",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "attempt_id": {
+ "name": "attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completion_status": {
+ "name": "completion_status",
+ "type": "scorm_completion_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "success_status": {
+ "name": "success_status",
+ "type": "scorm_success_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "score_raw": {
+ "name": "score_raw",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_min": {
+ "name": "score_min",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_max": {
+ "name": "score_max",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_scaled": {
+ "name": "score_scaled",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_location": {
+ "name": "lesson_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspend_data": {
+ "name": "suspend_data",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_time": {
+ "name": "session_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_time": {
+ "name": "total_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "progress_measure": {
+ "name": "progress_measure",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "entry": {
+ "name": "entry",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exit": {
+ "name": "exit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_cmi_json": {
+ "name": "raw_cmi_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_runtime_state_tenant_id_idx": {
+ "name": "scorm_runtime_state_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_runtime_state_attempt_id_unique_idx": {
+ "name": "scorm_runtime_state_attempt_id_unique_idx",
+ "columns": [
+ {
+ "expression": "attempt_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_runtime_state_attempt_id_scorm_attempts_id_fk": {
+ "name": "scorm_runtime_state_attempt_id_scorm_attempts_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "columnsFrom": [
+ "attempt_id"
+ ],
+ "tableTo": "scorm_attempts",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_runtime_state_tenant_id_tenants_id_fk": {
+ "name": "scorm_runtime_state_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_scos": {
+ "name": "scorm_scos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_identifier": {
+ "name": "organization_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "identifier_ref": {
+ "name": "identifier_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_identifier": {
+ "name": "resource_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scorm_type": {
+ "name": "scorm_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "href": {
+ "name": "href",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "launch_path": {
+ "name": "launch_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parameters": {
+ "name": "parameters",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_identifier": {
+ "name": "parent_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_visible": {
+ "name": "is_visible",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "item_metadata_json": {
+ "name": "item_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_metadata_json": {
+ "name": "resource_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_scos_tenant_id_idx": {
+ "name": "scorm_scos_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_scos_package_id_idx": {
+ "name": "scorm_scos_package_id_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_scos_lesson_id_idx": {
+ "name": "scorm_scos_lesson_id_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "scorm_scos_package_identifier_unique_idx": {
+ "name": "scorm_scos_package_identifier_unique_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "scorm_scos_package_id_scorm_packages_id_fk": {
+ "name": "scorm_scos_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_scos",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "tableTo": "scorm_packages",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_scos_lesson_id_lessons_id_fk": {
+ "name": "scorm_scos_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_scos",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "scorm_scos_tenant_id_tenants_id_fk": {
+ "name": "scorm_scos_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_scos",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.search_documents": {
+ "name": "search_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "search_vector": {
+ "name": "search_vector",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "search_documents_tenant_id_idx": {
+ "name": "search_documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "search_documents_vector_idx": {
+ "name": "search_documents_vector_idx",
+ "columns": [
+ {
+ "expression": "search_vector",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ },
+ "search_documents_language_entity_type_idx": {
+ "name": "search_documents_language_entity_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "search_documents_entity_idx": {
+ "name": "search_documents_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "search_documents_document_unique_idx": {
+ "name": "search_documents_document_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "search_documents_tenant_id_tenants_id_fk": {
+ "name": "search_documents_tenant_id_tenants_id_fk",
+ "tableFrom": "search_documents",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.secrets": {
+ "name": "secrets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "secret_name": {
+ "name": "secret_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "ciphertext": {
+ "name": "ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "iv": {
+ "name": "iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tag": {
+ "name": "tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek": {
+ "name": "encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_iv": {
+ "name": "encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_tag": {
+ "name": "encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "alg": {
+ "name": "alg",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'AES-256-GCM'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "secrets_tenant_id_idx": {
+ "name": "secrets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secrets_tenant_secret_name_uq": {
+ "name": "secrets_tenant_secret_name_uq",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "secrets_name_idx": {
+ "name": "secrets_name_idx",
+ "columns": [
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "secrets_tenant_id_tenants_id_fk": {
+ "name": "secrets_tenant_id_tenants_id_fk",
+ "tableFrom": "secrets",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.settings": {
+ "name": "settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "settings_tenant_id_idx": {
+ "name": "settings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "settings_user_id_users_id_fk": {
+ "name": "settings_user_id_users_id_fk",
+ "tableFrom": "settings",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "settings_tenant_id_tenants_id_fk": {
+ "name": "settings_tenant_id_tenants_id_fk",
+ "tableFrom": "settings",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.student_chapter_progress": {
+ "name": "student_chapter_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_lesson_count": {
+ "name": "completed_lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_as_freemium": {
+ "name": "completed_as_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_chapter_progress_tenant_id_idx": {
+ "name": "student_chapter_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_chapter_progress_student_id_users_id_fk": {
+ "name": "student_chapter_progress_student_id_users_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_chapter_progress_course_id_courses_id_fk": {
+ "name": "student_chapter_progress_course_id_courses_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_chapter_progress_chapter_id_chapters_id_fk": {
+ "name": "student_chapter_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_tenant_id_tenants_id_fk": {
+ "name": "student_chapter_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_chapter_progress_student_id_course_id_chapter_id_unique": {
+ "name": "student_chapter_progress_student_id_course_id_chapter_id_unique",
+ "columns": [
+ "student_id",
+ "course_id",
+ "chapter_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_courses": {
+ "name": "student_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "finished_chapter_count": {
+ "name": "finished_chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "course_completion_metadata": {
+ "name": "course_completion_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'enrolled'"
+ },
+ "payment_id": {
+ "name": "payment_id",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_by_group_id": {
+ "name": "enrolled_by_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_courses_tenant_id_idx": {
+ "name": "student_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_courses_tenant_id_course_status_student_idx": {
+ "name": "student_courses_tenant_id_course_status_student_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_courses_student_id_users_id_fk": {
+ "name": "student_courses_student_id_users_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_courses_course_id_courses_id_fk": {
+ "name": "student_courses_course_id_courses_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_courses_enrolled_by_group_id_groups_id_fk": {
+ "name": "student_courses_enrolled_by_group_id_groups_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "enrolled_by_group_id"
+ ],
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "student_courses_tenant_id_tenants_id_fk": {
+ "name": "student_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_courses_student_id_course_id_unique": {
+ "name": "student_courses_student_id_course_id_unique",
+ "columns": [
+ "student_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_learning_path_courses": {
+ "name": "student_learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_path_courses_tenant_id_idx": {
+ "name": "student_learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_learning_path_courses_student_path_idx": {
+ "name": "student_learning_path_courses_student_path_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_learning_path_courses_course_idx": {
+ "name": "student_learning_path_courses_course_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_learning_path_courses_student_id_users_id_fk": {
+ "name": "student_learning_path_courses_student_id_users_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_path_courses_course_id_courses_id_fk": {
+ "name": "student_learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "tableTo": "courses",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "student_learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_path_courses_student_id_learning_path_id_course_id_unique": {
+ "name": "student_learning_path_courses_student_id_learning_path_id_course_id_unique",
+ "columns": [
+ "student_id",
+ "learning_path_id",
+ "course_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_learning_paths": {
+ "name": "student_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "enrollment_type": {
+ "name": "enrollment_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'direct'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_paths_tenant_id_idx": {
+ "name": "student_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_learning_paths_student_id_users_id_fk": {
+ "name": "student_learning_paths_student_id_users_id_fk",
+ "tableFrom": "student_learning_paths",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "tableTo": "learning_paths",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "student_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_paths",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_paths_student_id_learning_path_id_unique": {
+ "name": "student_learning_paths_student_id_learning_path_id_unique",
+ "columns": [
+ "student_id",
+ "learning_path_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_lesson_progress": {
+ "name": "student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_question_count": {
+ "name": "completed_question_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "quiz_score": {
+ "name": "quiz_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_quiz_passed": {
+ "name": "is_quiz_passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_started": {
+ "name": "is_started",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "language_answered": {
+ "name": "language_answered",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_lesson_progress_tenant_id_idx": {
+ "name": "student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "student_lesson_progress_completed_quiz_score_idx": {
+ "name": "student_lesson_progress_completed_quiz_score_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "where": "\"student_lesson_progress\".\"completed_at\" IS NOT NULL AND \"student_lesson_progress\".\"quiz_score\" IS NOT NULL",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_lesson_progress_student_id_users_id_fk": {
+ "name": "student_lesson_progress_student_id_users_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "set null"
+ },
+ "student_lesson_progress_chapter_id_chapters_id_fk": {
+ "name": "student_lesson_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "tableTo": "chapters",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_lesson_progress_lesson_id_lessons_id_fk": {
+ "name": "student_lesson_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "tableTo": "lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_lesson_progress_student_id_lesson_id_chapter_id_unique": {
+ "name": "student_lesson_progress_student_id_lesson_id_chapter_id_unique",
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "chapter_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.student_question_answers": {
+ "name": "student_question_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "answer": {
+ "name": "answer",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_question_answers_tenant_id_idx": {
+ "name": "student_question_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "student_question_answers_question_id_questions_id_fk": {
+ "name": "student_question_answers_question_id_questions_id_fk",
+ "tableFrom": "student_question_answers",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "tableTo": "questions",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_question_answers_student_id_users_id_fk": {
+ "name": "student_question_answers_student_id_users_id_fk",
+ "tableFrom": "student_question_answers",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "student_question_answers_tenant_id_tenants_id_fk": {
+ "name": "student_question_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "student_question_answers",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_question_answers_question_id_student_id_unique": {
+ "name": "student_question_answers_question_id_student_id_unique",
+ "columns": [
+ "question_id",
+ "student_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.support_sessions": {
+ "name": "support_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "original_user_id": {
+ "name": "original_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_tenant_id": {
+ "name": "original_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_user_id": {
+ "name": "target_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hashed_grant_token": {
+ "name": "hashed_grant_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_expires_at": {
+ "name": "grant_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "activated_at": {
+ "name": "activated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "return_url": {
+ "name": "return_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ }
+ },
+ "indexes": {
+ "support_sessions_hashed_grant_token_unique": {
+ "name": "support_sessions_hashed_grant_token_unique",
+ "columns": [
+ {
+ "expression": "hashed_grant_token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_status_idx": {
+ "name": "support_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_original_user_idx": {
+ "name": "support_sessions_original_user_idx",
+ "columns": [
+ {
+ "expression": "original_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_target_tenant_idx": {
+ "name": "support_sessions_target_tenant_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "support_sessions_target_user_idx": {
+ "name": "support_sessions_target_user_idx",
+ "columns": [
+ {
+ "expression": "target_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "support_sessions_original_user_id_users_id_fk": {
+ "name": "support_sessions_original_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "original_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "support_sessions_original_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_original_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "original_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "support_sessions_target_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_target_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "support_sessions_target_user_id_users_id_fk": {
+ "name": "support_sessions_target_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "columnsFrom": [
+ "target_user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.tenants": {
+ "name": "tenants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "host": {
+ "name": "host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "is_managing": {
+ "name": "is_managing",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ }
+ },
+ "indexes": {
+ "unique_host_idx": {
+ "name": "unique_host_idx",
+ "columns": [
+ {
+ "expression": "host",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user_announcements": {
+ "name": "user_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_read": {
+ "name": "is_read",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "read_at": {
+ "name": "read_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_announcements_tenant_id_idx": {
+ "name": "user_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_announcements_user_id_users_id_fk": {
+ "name": "user_announcements_user_id_users_id_fk",
+ "tableFrom": "user_announcements",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_announcements_announcement_id_announcements_id_fk": {
+ "name": "user_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "user_announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "tableTo": "announcements",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_announcements_tenant_id_tenants_id_fk": {
+ "name": "user_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "user_announcements",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_announcements_user_id_announcement_id_unique": {
+ "name": "user_announcements_user_id_announcement_id_unique",
+ "columns": [
+ "user_id",
+ "announcement_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.user_details": {
+ "name": "user_details",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_phone_number": {
+ "name": "contact_phone_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contact_email": {
+ "name": "contact_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "job_title": {
+ "name": "job_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_details_tenant_id_idx": {
+ "name": "user_details_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_details_user_id_users_id_fk": {
+ "name": "user_details_user_id_users_id_fk",
+ "tableFrom": "user_details",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_details_tenant_id_tenants_id_fk": {
+ "name": "user_details_tenant_id_tenants_id_fk",
+ "tableFrom": "user_details",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_details_user_id_unique": {
+ "name": "user_details_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.user_onboarding": {
+ "name": "user_onboarding",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dashboard": {
+ "name": "dashboard",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "courses": {
+ "name": "courses",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "announcements": {
+ "name": "announcements",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "profile": {
+ "name": "profile",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "provider_information": {
+ "name": "provider_information",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_onboarding_tenant_id_idx": {
+ "name": "user_onboarding_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_onboarding_user_id_users_id_fk": {
+ "name": "user_onboarding_user_id_users_id_fk",
+ "tableFrom": "user_onboarding",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_onboarding_tenant_id_tenants_id_fk": {
+ "name": "user_onboarding_tenant_id_tenants_id_fk",
+ "tableFrom": "user_onboarding",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_onboarding_user_id_unique": {
+ "name": "user_onboarding_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.user_statistics": {
+ "name": "user_statistics",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_streak": {
+ "name": "current_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "longest_streak": {
+ "name": "longest_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_activity_date": {
+ "name": "last_activity_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activity_history": {
+ "name": "activity_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_statistics_tenant_id_idx": {
+ "name": "user_statistics_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_statistics_user_id_users_id_fk": {
+ "name": "user_statistics_user_id_users_id_fk",
+ "tableFrom": "user_statistics",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "users",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "user_statistics_tenant_id_tenants_id_fk": {
+ "name": "user_statistics_tenant_id_tenants_id_fk",
+ "tableFrom": "user_statistics",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_statistics_user_id_unique": {
+ "name": "user_statistics_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_name": {
+ "name": "first_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_name": {
+ "name": "last_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "users_tenant_id_idx": {
+ "name": "users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ },
+ "users_tenant_id_email_unique_idx": {
+ "name": "users_tenant_id_email_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "users_tenant_id_tenants_id_fk": {
+ "name": "users_tenant_id_tenants_id_fk",
+ "tableFrom": "users",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_connections": {
+ "name": "calendar_connections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_email": {
+ "name": "account_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_ciphertext": {
+ "name": "refresh_token_ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_iv": {
+ "name": "refresh_token_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_tag": {
+ "name": "refresh_token_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek": {
+ "name": "refresh_token_encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_iv": {
+ "name": "refresh_token_encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_tag": {
+ "name": "refresh_token_encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'syncing'"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_cursor": {
+ "name": "sync_cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_start": {
+ "name": "sync_window_start",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_end": {
+ "name": "sync_window_end",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "window_built_at": {
+ "name": "window_built_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_successful_sync_at": {
+ "name": "last_successful_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_completed_at": {
+ "name": "last_sync_completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_client_state": {
+ "name": "subscription_client_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_expires_at": {
+ "name": "subscription_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_sync_enabled": {
+ "name": "outbound_sync_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "outbound_status": {
+ "name": "outbound_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'disabled'"
+ },
+ "outbound_calendar_id": {
+ "name": "outbound_calendar_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_error_code": {
+ "name": "outbound_error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_outbound_sync_at": {
+ "name": "last_outbound_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_connections_tenant_id_idx": {
+ "name": "calendar_connections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_tenant_user_provider_unique_idx": {
+ "name": "calendar_connections_tenant_user_provider_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_subscription_idx": {
+ "name": "calendar_connections_subscription_idx",
+ "columns": [
+ {
+ "expression": "subscription_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_connections_user_id_users_id_fk": {
+ "name": "calendar_connections_user_id_users_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_connections_tenant_id_tenants_id_fk": {
+ "name": "calendar_connections_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_external_events": {
+ "name": "calendar_external_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "web_link": {
+ "name": "web_link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensitivity": {
+ "name": "sensitivity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "availability": {
+ "name": "availability",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_cancelled": {
+ "name": "is_cancelled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_external_events_tenant_id_idx": {
+ "name": "calendar_external_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_calendar_event_unique_idx": {
+ "name": "calendar_external_events_calendar_event_unique_idx",
+ "columns": [
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_connection_event_unique_idx": {
+ "name": "calendar_external_events_tenant_connection_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_user_idx": {
+ "name": "calendar_external_events_tenant_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_external_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_external_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_external_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_user_id_users_id_fk": {
+ "name": "calendar_external_events_user_id_users_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_external_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_outbound_events": {
+ "name": "calendar_outbound_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_outbound_events_tenant_id_idx": {
+ "name": "calendar_outbound_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_event_user_unique_idx": {
+ "name": "calendar_outbound_events_connection_event_user_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_external_event_unique_idx": {
+ "name": "calendar_outbound_events_connection_external_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_calendar_event_idx": {
+ "name": "calendar_outbound_events_calendar_event_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_outbound_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_outbound_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_outbound_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_user_id_users_id_fk": {
+ "name": "calendar_outbound_events_user_id_users_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_outbound_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_configurations": {
+ "name": "ai_mentor_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "structured_ai_mentor_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opening_instruction": {
+ "name": "opening_instruction",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "additional_instructions": {
+ "name": "additional_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_configurations_tenant_id_idx": {
+ "name": "ai_mentor_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "tableTo": "ai_mentor_lessons",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_unique",
+ "columns": [
+ "ai_mentor_lesson_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_mentor_roleplay_configurations": {
+ "name": "ai_mentor_roleplay_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario": {
+ "name": "scenario",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "ai_role": {
+ "name": "ai_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "learner_role": {
+ "name": "learner_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "character_goal": {
+ "name": "character_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "difficulty": {
+ "name": "difficulty",
+ "type": "ai_mentor_roleplay_difficulty",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "facts_and_constraints": {
+ "name": "facts_and_constraints",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_roleplay_configurations_tenant_id_idx": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_mentor_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_roleplay_configurations_configuration_id_unique": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_unique",
+ "columns": [
+ "configuration_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.ai_mentor_teacher_configurations": {
+ "name": "ai_mentor_teacher_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expertise": {
+ "name": "expertise",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content_scope": {
+ "name": "content_scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "teaching_style": {
+ "name": "teaching_style",
+ "type": "ai_mentor_teaching_style",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback_guidance": {
+ "name": "feedback_guidance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_teacher_configurations_tenant_id_idx": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "tableTo": "ai_mentor_configurations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "tableTo": "tenants",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_teacher_configurations_configuration_id_unique": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_unique",
+ "columns": [
+ "configuration_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ }
+ },
+ "enums": {
+ "public.ai_mentor_roleplay_difficulty": {
+ "name": "ai_mentor_roleplay_difficulty",
+ "schema": "public",
+ "values": [
+ "cooperative",
+ "realistic",
+ "challenging"
+ ]
+ },
+ "public.ai_mentor_teaching_style": {
+ "name": "ai_mentor_teaching_style",
+ "schema": "public",
+ "values": [
+ "explain_and_practice",
+ "guided_discovery",
+ "socratic"
+ ]
+ },
+ "public.article_status": {
+ "name": "article_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.course_type": {
+ "name": "course_type",
+ "schema": "public",
+ "values": [
+ "default",
+ "scorm"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published",
+ "private"
+ ]
+ },
+ "public.news_status": {
+ "name": "news_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.scorm_completion_status": {
+ "name": "scorm_completion_status",
+ "schema": "public",
+ "values": [
+ "completed",
+ "incomplete",
+ "not_attempted",
+ "unknown"
+ ]
+ },
+ "public.scorm_package_entity_type": {
+ "name": "scorm_package_entity_type",
+ "schema": "public",
+ "values": [
+ "course",
+ "lesson"
+ ]
+ },
+ "public.scorm_package_status": {
+ "name": "scorm_package_status",
+ "schema": "public",
+ "values": [
+ "processing",
+ "ready",
+ "failed"
+ ]
+ },
+ "public.scorm_standard": {
+ "name": "scorm_standard",
+ "schema": "public",
+ "values": [
+ "scorm_1_2",
+ "scorm_2004"
+ ]
+ },
+ "public.scorm_success_status": {
+ "name": "scorm_success_status",
+ "schema": "public",
+ "values": [
+ "passed",
+ "failed",
+ "unknown"
+ ]
+ },
+ "public.structured_ai_mentor_type": {
+ "name": "structured_ai_mentor_type",
+ "schema": "public",
+ "values": [
+ "teacher",
+ "roleplay"
+ ]
+ }
+ },
+ "schemas": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/apps/api/src/storage/migrations/meta/0182_snapshot.json b/apps/api/src/storage/migrations/meta/0182_snapshot.json
new file mode 100644
index 0000000000..8d0b5a8bce
--- /dev/null
+++ b/apps/api/src/storage/migrations/meta/0182_snapshot.json
@@ -0,0 +1,15669 @@
+{
+ "id": "1f25d967-7fff-48a6-83d5-cc61903d60d7",
+ "prevId": "ac657bae-4111-4460-a898-69f50191e6c9",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.activity_logs": {
+ "name": "activity_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_email": {
+ "name": "actor_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_role": {
+ "name": "actor_role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "action_type": {
+ "name": "action_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "activity_logs_tenant_id_idx": {
+ "name": "activity_logs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_tenant_timeframe_idx": {
+ "name": "activity_logs_tenant_timeframe_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_actor_idx": {
+ "name": "activity_logs_actor_idx",
+ "columns": [
+ {
+ "expression": "actor_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_action_idx": {
+ "name": "activity_logs_action_idx",
+ "columns": [
+ {
+ "expression": "action_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_timeframe_idx": {
+ "name": "activity_logs_timeframe_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "activity_logs_resource_idx": {
+ "name": "activity_logs_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "activity_logs_actor_id_users_id_fk": {
+ "name": "activity_logs_actor_id_users_id_fk",
+ "tableFrom": "activity_logs",
+ "tableTo": "users",
+ "columnsFrom": [
+ "actor_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ },
+ "activity_logs_tenant_id_tenants_id_fk": {
+ "name": "activity_logs_tenant_id_tenants_id_fk",
+ "tableFrom": "activity_logs",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_blocking_errors": {
+ "name": "ai_judge_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_blocking_errors_tenant_id_idx": {
+ "name": "ai_judge_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_judge_blocking_errors_configuration_id_created_at_idx": {
+ "name": "ai_judge_blocking_errors_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_blocking_errors_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "tableTo": "ai_judge_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_blocking_errors",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_configurations": {
+ "name": "ai_judge_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "passing_threshold_percent": {
+ "name": "passing_threshold_percent",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_configurations_tenant_id_idx": {
+ "name": "ai_judge_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_judge_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_judge_configurations_ai_mentor_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "ai_mentor_lesson_id"
+ ]
+ }
+ }
+ },
+ "public.ai_judge_criteria": {
+ "name": "ai_judge_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expected_behavior": {
+ "name": "expected_behavior",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_criteria_tenant_id_idx": {
+ "name": "ai_judge_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_judge_criteria_configuration_id_created_at_idx": {
+ "name": "ai_judge_criteria_configuration_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "configuration_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_judge_criteria_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "tableTo": "ai_judge_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_criteria",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_judge_score_guidance": {
+ "name": "ai_judge_score_guidance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "example": {
+ "name": "example",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_judge_score_guidance_tenant_id_idx": {
+ "name": "ai_judge_score_guidance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_judge_score_guidance_criterion_id_score_unique": {
+ "name": "ai_judge_score_guidance_criterion_id_score_unique",
+ "columns": [
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "score",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_judge_score_guidance_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "tableTo": "ai_judge_criteria",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_judge_score_guidance_tenant_id_tenants_id_fk": {
+ "name": "ai_judge_score_guidance_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_judge_score_guidance",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_blocking_errors": {
+ "name": "ai_mentor_judgement_blocking_errors",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blocking_error_id": {
+ "name": "blocking_error_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "blocking_error_description": {
+ "name": "blocking_error_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_blocking_errors_tenant_id_idx": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_blocking_error_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "blocking_error_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "tableTo": "ai_mentor_judgements",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_blocking_error_id_ai_judge_blocking_errors_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "tableTo": "ai_judge_blocking_errors",
+ "columnsFrom": [
+ "blocking_error_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_blocking_errors_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_blocking_errors",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgement_criteria": {
+ "name": "ai_mentor_judgement_criteria",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "judgement_id": {
+ "name": "judgement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "criterion_id": {
+ "name": "criterion_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "criterion_title": {
+ "name": "criterion_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "awarded_points": {
+ "name": "awarded_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score_at_judgement": {
+ "name": "max_score_at_judgement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learner_safe_feedback": {
+ "name": "learner_safe_feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgement_criteria_tenant_id_idx": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_criterion_id_unique",
+ "columns": [
+ {
+ "expression": "judgement_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "criterion_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk": {
+ "name": "ai_mentor_judgement_criteria_judgement_id_ai_mentor_judgements_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "tableTo": "ai_mentor_judgements",
+ "columnsFrom": [
+ "judgement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk": {
+ "name": "ai_mentor_judgement_criteria_criterion_id_ai_judge_criteria_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "tableTo": "ai_judge_criteria",
+ "columnsFrom": [
+ "criterion_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgement_criteria_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgement_criteria",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_judgements": {
+ "name": "ai_mentor_judgements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "earned_points": {
+ "name": "earned_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_judgements_tenant_id_idx": {
+ "name": "ai_mentor_judgements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_judgements_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "tableTo": "ai_mentor_threads",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk": {
+ "name": "ai_mentor_judgements_configuration_id_ai_judge_configurations_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "tableTo": "ai_judge_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_judgements_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_judgements_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_judgements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_judgements_thread_id_unique": {
+ "name": "ai_mentor_judgements_thread_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "thread_id"
+ ]
+ }
+ }
+ },
+ "public.ai_mentor_lessons": {
+ "name": "ai_mentor_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "voice_mode": {
+ "name": "voice_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'preset'"
+ },
+ "tts_preset": {
+ "name": "tts_preset",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'male'"
+ },
+ "custom_tts_reference": {
+ "name": "custom_tts_reference",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_lessons_tenant_id_idx": {
+ "name": "ai_mentor_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_lessons_lesson_id_lessons_id_fk": {
+ "name": "ai_mentor_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_lessons_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_lessons",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_student_lesson_progress": {
+ "name": "ai_mentor_student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_lesson_progress_id": {
+ "name": "student_lesson_progress_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_score": {
+ "name": "min_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_score": {
+ "name": "max_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "percentage": {
+ "name": "percentage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "passed": {
+ "name": "passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_student_lesson_progress_tenant_id_idx": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_student_lesson_progress_id_student_lesson_progress_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "tableTo": "student_lesson_progress",
+ "columnsFrom": [
+ "student_lesson_progress_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_student_lesson_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_thread_messages": {
+ "name": "ai_mentor_thread_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_thread_messages_tenant_id_idx": {
+ "name": "ai_mentor_thread_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk": {
+ "name": "ai_mentor_thread_messages_thread_id_ai_mentor_threads_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "tableTo": "ai_mentor_threads",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_thread_messages_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_thread_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_thread_messages",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_threads": {
+ "name": "ai_mentor_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "user_language": {
+ "name": "user_language",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_threads_tenant_id_idx": {
+ "name": "ai_mentor_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_threads_user_id_users_id_fk": {
+ "name": "ai_mentor_threads_user_id_users_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_threads_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_threads_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_threads",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.announcements": {
+ "name": "announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "audience": {
+ "name": "audience",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all_users'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'published'"
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "send_email": {
+ "name": "send_email",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "email_template": {
+ "name": "email_template",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "source_id": {
+ "name": "source_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "announcements_tenant_id_idx": {
+ "name": "announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "announcements_author_id_users_id_fk": {
+ "name": "announcements_author_id_users_id_fk",
+ "tableFrom": "announcements",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "announcements_tenant_id_tenants_id_fk": {
+ "name": "announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "announcements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.article_sections": {
+ "name": "article_sections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "article_sections_tenant_id_idx": {
+ "name": "article_sections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "article_sections_tenant_id_tenants_id_fk": {
+ "name": "article_sections_tenant_id_tenants_id_fk",
+ "tableFrom": "article_sections",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.articles": {
+ "name": "articles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "article_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "article_section_id": {
+ "name": "article_section_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_by_id": {
+ "name": "updated_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "articles_tenant_id_idx": {
+ "name": "articles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "article_section_idx": {
+ "name": "article_section_idx",
+ "columns": [
+ {
+ "expression": "article_section_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "articles_article_section_id_article_sections_id_fk": {
+ "name": "articles_article_section_id_article_sections_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "article_sections",
+ "columnsFrom": [
+ "article_section_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "articles_author_id_users_id_fk": {
+ "name": "articles_author_id_users_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "articles_updated_by_id_users_id_fk": {
+ "name": "articles_updated_by_id_users_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "updated_by_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "articles_tenant_id_tenants_id_fk": {
+ "name": "articles_tenant_id_tenants_id_fk",
+ "tableFrom": "articles",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_events": {
+ "name": "calendar_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "uid": {
+ "name": "uid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sequence": {
+ "name": "sequence",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "all_day": {
+ "name": "all_day",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organizer_user_id": {
+ "name": "organizer_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rrule": {
+ "name": "rrule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exdates": {
+ "name": "exdates",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_events_tenant_id_idx": {
+ "name": "calendar_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_events_tenant_starts_ends_idx": {
+ "name": "calendar_events_tenant_starts_ends_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "starts_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "ends_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_events_tenant_uid_unique_idx": {
+ "name": "calendar_events_tenant_uid_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "uid",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_events_organizer_user_id_users_id_fk": {
+ "name": "calendar_events_organizer_user_id_users_id_fk",
+ "tableFrom": "calendar_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "organizer_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "calendar_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.categories": {
+ "name": "categories",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "categories_tenant_id_idx": {
+ "name": "categories_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "categories_tenant_id_base_title_unique": {
+ "name": "categories_tenant_id_base_title_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "(\"title\"->>\"base_language\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "categories_tenant_id_tenants_id_fk": {
+ "name": "categories_tenant_id_tenants_id_fk",
+ "tableFrom": "categories",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.certificates": {
+ "name": "certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archive_reason": {
+ "name": "archive_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expiration_warning_sent_at": {
+ "name": "expiration_warning_sent_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "certificates_tenant_id_idx": {
+ "name": "certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "certificates_active_expiry_idx": {
+ "name": "certificates_active_expiry_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "certificates_user_course_idx": {
+ "name": "certificates_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "certificates_user_id_users_id_fk": {
+ "name": "certificates_user_id_users_id_fk",
+ "tableFrom": "certificates",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "certificates_course_id_courses_id_fk": {
+ "name": "certificates_course_id_courses_id_fk",
+ "tableFrom": "certificates",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "certificates_tenant_id_tenants_id_fk": {
+ "name": "certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "certificates",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.chapters": {
+ "name": "chapters",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_freemium": {
+ "name": "is_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_count": {
+ "name": "lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "chapters_tenant_id_idx": {
+ "name": "chapters_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "chapters_tenant_id_course_id_idx": {
+ "name": "chapters_tenant_id_course_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "chapters_course_id_courses_id_fk": {
+ "name": "chapters_course_id_courses_id_fk",
+ "tableFrom": "chapters",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "chapters_author_id_users_id_fk": {
+ "name": "chapters_author_id_users_id_fk",
+ "tableFrom": "chapters",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "chapters_tenant_id_tenants_id_fk": {
+ "name": "chapters_tenant_id_tenants_id_fk",
+ "tableFrom": "chapters",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_message_reactions": {
+ "name": "course_chat_message_reactions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reaction": {
+ "name": "reaction",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_message_reactions_tenant_id_idx": {
+ "name": "course_chat_message_reactions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_message_reactions_message_id_reaction_idx": {
+ "name": "course_chat_message_reactions_message_id_reaction_idx",
+ "columns": [
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_message_reactions_user_message_reaction_unique_idx": {
+ "name": "course_chat_message_reactions_user_message_reaction_unique_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "reaction",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_chat_message_reactions_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_message_reactions_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "course_chat_messages",
+ "columnsFrom": [
+ "message_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_message_reactions_course_id_courses_id_fk": {
+ "name": "course_chat_message_reactions_course_id_courses_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_message_reactions_user_id_users_id_fk": {
+ "name": "course_chat_message_reactions_user_id_users_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_message_reactions_tenant_id_tenants_id_fk": {
+ "name": "course_chat_message_reactions_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_message_reactions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_messages": {
+ "name": "course_chat_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "thread_id": {
+ "name": "thread_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_message_id": {
+ "name": "parent_message_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_messages_tenant_id_idx": {
+ "name": "course_chat_messages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_messages_course_id_created_at_idx": {
+ "name": "course_chat_messages_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_messages_thread_id_created_at_idx": {
+ "name": "course_chat_messages_thread_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "thread_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_messages_parent_message_id_created_at_idx": {
+ "name": "course_chat_messages_parent_message_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "parent_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_chat_messages_thread_id_course_chat_threads_id_fk": {
+ "name": "course_chat_messages_thread_id_course_chat_threads_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "course_chat_threads",
+ "columnsFrom": [
+ "thread_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_course_id_courses_id_fk": {
+ "name": "course_chat_messages_course_id_courses_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_user_id_users_id_fk": {
+ "name": "course_chat_messages_user_id_users_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_parent_message_id_course_chat_messages_id_fk": {
+ "name": "course_chat_messages_parent_message_id_course_chat_messages_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "course_chat_messages",
+ "columnsFrom": [
+ "parent_message_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "course_chat_messages_tenant_id_tenants_id_fk": {
+ "name": "course_chat_messages_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_messages",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_chat_threads": {
+ "name": "course_chat_threads",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_chat_threads_tenant_id_idx": {
+ "name": "course_chat_threads_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_threads_course_id_created_at_idx": {
+ "name": "course_chat_threads_course_id_created_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_chat_threads_course_id_updated_at_idx": {
+ "name": "course_chat_threads_course_id_updated_at_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_chat_threads_course_id_courses_id_fk": {
+ "name": "course_chat_threads_course_id_courses_id_fk",
+ "tableFrom": "course_chat_threads",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_threads_created_by_user_id_users_id_fk": {
+ "name": "course_chat_threads_created_by_user_id_users_id_fk",
+ "tableFrom": "course_chat_threads",
+ "tableTo": "users",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_chat_threads_tenant_id_tenants_id_fk": {
+ "name": "course_chat_threads_tenant_id_tenants_id_fk",
+ "tableFrom": "course_chat_threads",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_slugs": {
+ "name": "course_slugs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_short_id": {
+ "name": "course_short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lang": {
+ "name": "lang",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_slugs_tenant_id_idx": {
+ "name": "course_slugs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "course_slug_course_short_id_lang_unique_idx": {
+ "name": "course_slug_course_short_id_lang_unique_idx",
+ "columns": [
+ {
+ "expression": "course_short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lang",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_slugs_course_short_id_courses_short_id_fk": {
+ "name": "course_slugs_course_short_id_courses_short_id_fk",
+ "tableFrom": "course_slugs",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_short_id"
+ ],
+ "columnsTo": [
+ "short_id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "cascade"
+ },
+ "course_slugs_tenant_id_tenants_id_fk": {
+ "name": "course_slugs_tenant_id_tenants_id_fk",
+ "tableFrom": "course_slugs",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.course_student_mode": {
+ "name": "course_student_mode",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_student_mode_tenant_id_idx": {
+ "name": "course_student_mode_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_student_mode_user_id_users_id_fk": {
+ "name": "course_student_mode_user_id_users_id_fk",
+ "tableFrom": "course_student_mode",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_student_mode_course_id_courses_id_fk": {
+ "name": "course_student_mode_course_id_courses_id_fk",
+ "tableFrom": "course_student_mode",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_student_mode_tenant_id_tenants_id_fk": {
+ "name": "course_student_mode_tenant_id_tenants_id_fk",
+ "tableFrom": "course_student_mode",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_student_mode_user_id_course_id_unique": {
+ "name": "course_student_mode_user_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.course_students_stats": {
+ "name": "course_students_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "month": {
+ "name": "month",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "new_students_count": {
+ "name": "new_students_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "course_students_stats_tenant_id_idx": {
+ "name": "course_students_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "course_students_stats_course_id_courses_id_fk": {
+ "name": "course_students_stats_course_id_courses_id_fk",
+ "tableFrom": "course_students_stats",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_students_stats_author_id_users_id_fk": {
+ "name": "course_students_stats_author_id_users_id_fk",
+ "tableFrom": "course_students_stats",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "course_students_stats_tenant_id_tenants_id_fk": {
+ "name": "course_students_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "course_students_stats",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "course_students_stats_course_id_month_year_unique": {
+ "name": "course_students_stats_course_id_month_year_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "course_id",
+ "month",
+ "year"
+ ]
+ }
+ }
+ },
+ "public.courses": {
+ "name": "courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "short_id": {
+ "name": "short_id",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_s3_key": {
+ "name": "thumbnail_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "has_certificate": {
+ "name": "has_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "price_in_cents": {
+ "name": "price_in_cents",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "currency": {
+ "name": "currency",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'usd'"
+ },
+ "chapter_count": {
+ "name": "chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "course_type": {
+ "name": "course_type",
+ "type": "course_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category_id": {
+ "name": "category_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stripe_product_id": {
+ "name": "stripe_product_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripe_price_id": {
+ "name": "stripe_price_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"lessonSequenceEnabled\":false,\"quizFeedbackEnabled\":true,\"certificateSignature\":null,\"certificateFontColor\":null,\"certificateValidity\":null,\"videoCompletionTrackingEnabled\":true}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_tenant_id_idx": {
+ "name": "courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "courses_short_id_unique_idx": {
+ "name": "courses_short_id_unique_idx",
+ "columns": [
+ {
+ "expression": "short_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "courses_author_id_users_id_fk": {
+ "name": "courses_author_id_users_id_fk",
+ "tableFrom": "courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "courses_category_id_categories_id_fk": {
+ "name": "courses_category_id_categories_id_fk",
+ "tableFrom": "courses",
+ "tableTo": "categories",
+ "columnsFrom": [
+ "category_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "courses_tenant_id_tenants_id_fk": {
+ "name": "courses_tenant_id_tenants_id_fk",
+ "tableFrom": "courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.courses_summary_stats": {
+ "name": "courses_summary_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "free_purchased_count": {
+ "name": "free_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_count": {
+ "name": "paid_purchased_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "paid_purchased_after_freemium_count": {
+ "name": "paid_purchased_after_freemium_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_freemium_student_count": {
+ "name": "completed_freemium_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_course_student_count": {
+ "name": "completed_course_student_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "courses_summary_stats_tenant_id_idx": {
+ "name": "courses_summary_stats_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "courses_summary_stats_course_id_courses_id_fk": {
+ "name": "courses_summary_stats_course_id_courses_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "courses_summary_stats_author_id_users_id_fk": {
+ "name": "courses_summary_stats_author_id_users_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "courses_summary_stats_tenant_id_tenants_id_fk": {
+ "name": "courses_summary_stats_tenant_id_tenants_id_fk",
+ "tableFrom": "courses_summary_stats",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "courses_summary_stats_course_id_unique": {
+ "name": "courses_summary_stats_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.create_tokens": {
+ "name": "create_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reminder_count": {
+ "name": "reminder_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "create_tokens_tenant_id_idx": {
+ "name": "create_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "create_tokens_token_hash_idx": {
+ "name": "create_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "create_tokens_user_id_users_id_fk": {
+ "name": "create_tokens_user_id_users_id_fk",
+ "tableFrom": "create_tokens",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "create_tokens_tenant_id_tenants_id_fk": {
+ "name": "create_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "create_tokens",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.credentials": {
+ "name": "credentials",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requires_password_change": {
+ "name": "requires_password_change",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "credentials_tenant_id_idx": {
+ "name": "credentials_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "credentials_user_id_users_id_fk": {
+ "name": "credentials_user_id_users_id_fk",
+ "tableFrom": "credentials",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credentials_tenant_id_tenants_id_fk": {
+ "name": "credentials_tenant_id_tenants_id_fk",
+ "tableFrom": "credentials",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.doc_chunks": {
+ "name": "doc_chunks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_index": {
+ "name": "chunk_index",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding": {
+ "name": "embedding",
+ "type": "vector(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "doc_chunks_tenant_id_idx": {
+ "name": "doc_chunks_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "doc_chunks_document_id_documents_id_fk": {
+ "name": "doc_chunks_document_id_documents_id_fk",
+ "tableFrom": "doc_chunks",
+ "tableTo": "documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "doc_chunks_tenant_id_tenants_id_fk": {
+ "name": "doc_chunks_tenant_id_tenants_id_fk",
+ "tableFrom": "doc_chunks",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.document_to_ai_mentor_lesson": {
+ "name": "document_to_ai_mentor_lesson",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "document_to_ai_mentor_lesson_tenant_id_idx": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "document_to_ai_mentor_lesson_document_id_documents_id_fk": {
+ "name": "document_to_ai_mentor_lesson_document_id_documents_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "tableTo": "documents",
+ "columnsFrom": [
+ "document_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "document_to_ai_mentor_lesson_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk": {
+ "name": "document_to_ai_mentor_lesson_tenant_id_tenants_id_fk",
+ "tableFrom": "document_to_ai_mentor_lesson",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique": {
+ "name": "document_to_ai_mentor_lesson_document_id_ai_mentor_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "document_id",
+ "ai_mentor_lesson_id"
+ ]
+ }
+ }
+ },
+ "public.documents": {
+ "name": "documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "byte_size": {
+ "name": "byte_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "check_sum": {
+ "name": "check_sum",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "documents_tenant_id_idx": {
+ "name": "documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "documents_tenant_id_tenants_id_fk": {
+ "name": "documents_tenant_id_tenants_id_fk",
+ "tableFrom": "documents",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "documents_check_sum_unique": {
+ "name": "documents_check_sum_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "check_sum"
+ ]
+ }
+ }
+ },
+ "public.form_field_answers": {
+ "name": "form_field_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_field_id": {
+ "name": "form_field_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label_snapshot": {
+ "name": "label_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "answered_language": {
+ "name": "answered_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_field_answers_tenant_id_idx": {
+ "name": "form_field_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "form_field_answers_user_id_form_field_id_unique": {
+ "name": "form_field_answers_user_id_form_field_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "form_field_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "form_field_answers_user_id_idx": {
+ "name": "form_field_answers_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "form_field_answers_form_field_id_form_fields_id_fk": {
+ "name": "form_field_answers_form_field_id_form_fields_id_fk",
+ "tableFrom": "form_field_answers",
+ "tableTo": "form_fields",
+ "columnsFrom": [
+ "form_field_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ },
+ "form_field_answers_user_id_users_id_fk": {
+ "name": "form_field_answers_user_id_users_id_fk",
+ "tableFrom": "form_field_answers",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "form_field_answers_tenant_id_tenants_id_fk": {
+ "name": "form_field_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "form_field_answers",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.form_fields": {
+ "name": "form_fields",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "form_id": {
+ "name": "form_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "required": {
+ "name": "required",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "form_fields_tenant_id_idx": {
+ "name": "form_fields_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "form_fields_form_id_display_order_idx": {
+ "name": "form_fields_form_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "form_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "form_fields_form_id_forms_id_fk": {
+ "name": "form_fields_form_id_forms_id_fk",
+ "tableFrom": "form_fields",
+ "tableTo": "forms",
+ "columnsFrom": [
+ "form_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "form_fields_tenant_id_tenants_id_fk": {
+ "name": "form_fields_tenant_id_tenants_id_fk",
+ "tableFrom": "form_fields",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.forms": {
+ "name": "forms",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "forms_tenant_id_idx": {
+ "name": "forms_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "forms_tenant_id_type_unique_idx": {
+ "name": "forms_tenant_id_type_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "forms_tenant_id_tenants_id_fk": {
+ "name": "forms_tenant_id_tenants_id_fk",
+ "tableFrom": "forms",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.group_announcements": {
+ "name": "group_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_announcements_tenant_id_idx": {
+ "name": "group_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_announcements_group_id_groups_id_fk": {
+ "name": "group_announcements_group_id_groups_id_fk",
+ "tableFrom": "group_announcements",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_announcements_announcement_id_announcements_id_fk": {
+ "name": "group_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "group_announcements",
+ "tableTo": "announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_announcements_tenant_id_tenants_id_fk": {
+ "name": "group_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "group_announcements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_announcements_group_id_announcement_id_unique": {
+ "name": "group_announcements_group_id_announcement_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "group_id",
+ "announcement_id"
+ ]
+ }
+ }
+ },
+ "public.group_courses": {
+ "name": "group_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enrolled_by": {
+ "name": "enrolled_by",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_mandatory": {
+ "name": "is_mandatory",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "due_date": {
+ "name": "due_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_courses_tenant_id_idx": {
+ "name": "group_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_courses_group_id_groups_id_fk": {
+ "name": "group_courses_group_id_groups_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_courses_course_id_courses_id_fk": {
+ "name": "group_courses_course_id_courses_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_courses_enrolled_by_users_id_fk": {
+ "name": "group_courses_enrolled_by_users_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "enrolled_by"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "group_courses_calendar_event_id_calendar_events_id_fk": {
+ "name": "group_courses_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "group_courses_tenant_id_tenants_id_fk": {
+ "name": "group_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "group_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_courses_calendar_event_id_unique": {
+ "name": "group_courses_calendar_event_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "calendar_event_id"
+ ]
+ },
+ "group_courses_group_id_course_id_unique": {
+ "name": "group_courses_group_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "group_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.group_learning_paths": {
+ "name": "group_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_learning_paths_tenant_id_idx": {
+ "name": "group_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "group_learning_paths_learning_path_idx": {
+ "name": "group_learning_paths_learning_path_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_learning_paths_group_id_groups_id_fk": {
+ "name": "group_learning_paths_group_id_groups_id_fk",
+ "tableFrom": "group_learning_paths",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "group_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "group_learning_paths",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "group_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "group_learning_paths",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_learning_paths_group_id_learning_path_id_unique": {
+ "name": "group_learning_paths_group_id_learning_path_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "group_id",
+ "learning_path_id"
+ ]
+ }
+ }
+ },
+ "public.group_users": {
+ "name": "group_users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "group_users_tenant_id_idx": {
+ "name": "group_users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_users_user_id_users_id_fk": {
+ "name": "group_users_user_id_users_id_fk",
+ "tableFrom": "group_users",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_users_group_id_groups_id_fk": {
+ "name": "group_users_group_id_groups_id_fk",
+ "tableFrom": "group_users",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_users_tenant_id_tenants_id_fk": {
+ "name": "group_users_tenant_id_tenants_id_fk",
+ "tableFrom": "group_users",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "group_users_user_id_group_id_unique": {
+ "name": "group_users_user_id_group_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "group_id"
+ ]
+ }
+ }
+ },
+ "public.groups": {
+ "name": "groups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "characteristic": {
+ "name": "characteristic",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "groups_tenant_id_idx": {
+ "name": "groups_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "groups_tenant_id_tenants_id_fk": {
+ "name": "groups_tenant_id_tenants_id_fk",
+ "tableFrom": "groups",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.integration_api_keys": {
+ "name": "integration_api_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "key_prefix": {
+ "name": "key_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by_user_id": {
+ "name": "created_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "integration_api_keys_tenant_id_idx": {
+ "name": "integration_api_keys_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "integration_api_keys_key_prefix_idx": {
+ "name": "integration_api_keys_key_prefix_idx",
+ "columns": [
+ {
+ "expression": "key_prefix",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "integration_api_keys_created_by_idx": {
+ "name": "integration_api_keys_created_by_idx",
+ "columns": [
+ {
+ "expression": "created_by_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "integration_api_keys_created_by_user_id_users_id_fk": {
+ "name": "integration_api_keys_created_by_user_id_users_id_fk",
+ "tableFrom": "integration_api_keys",
+ "tableTo": "users",
+ "columnsFrom": [
+ "created_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "integration_api_keys_tenant_id_tenants_id_fk": {
+ "name": "integration_api_keys_tenant_id_tenants_id_fk",
+ "tableFrom": "integration_api_keys",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_certificates": {
+ "name": "learning_path_certificates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_certificates_tenant_id_idx": {
+ "name": "learning_path_certificates_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_certificates_user_id_users_id_fk": {
+ "name": "learning_path_certificates_user_id_users_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_certificates_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_certificates_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_certificates_tenant_id_tenants_id_fk": {
+ "name": "learning_path_certificates_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_certificates",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_courses": {
+ "name": "learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_path_courses_tenant_id_idx": {
+ "name": "learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_courses_path_id_course_id_unique_idx": {
+ "name": "learning_path_courses_path_id_course_id_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_courses_path_id_display_order_unique_idx": {
+ "name": "learning_path_courses_path_id_display_order_unique_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_courses_path_id_display_order_idx": {
+ "name": "learning_path_courses_path_id_display_order_idx",
+ "columns": [
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_courses",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_courses_course_id_courses_id_fk": {
+ "name": "learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "learning_path_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_entity_map": {
+ "name": "learning_path_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "learning_path_entity_map_export_idx": {
+ "name": "learning_path_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_entity_map_source_entity_idx": {
+ "name": "learning_path_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_entity_map_source_unique_idx": {
+ "name": "learning_path_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_entity_map_export_id_learning_path_exports_id_fk": {
+ "name": "learning_path_entity_map_export_id_learning_path_exports_id_fk",
+ "tableFrom": "learning_path_entity_map",
+ "tableTo": "learning_path_exports",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_path_exports": {
+ "name": "learning_path_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_learning_path_id": {
+ "name": "target_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "learning_path_exports_source_learning_path_idx": {
+ "name": "learning_path_exports_source_learning_path_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_exports_target_learning_path_idx": {
+ "name": "learning_path_exports_target_learning_path_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "learning_path_exports_source_target_unique_idx": {
+ "name": "learning_path_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_path_exports_source_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_exports_target_tenant_id_tenants_id_fk": {
+ "name": "learning_path_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_path_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "learning_path_exports_target_learning_path_id_learning_paths_id_fk": {
+ "name": "learning_path_exports_target_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "learning_path_exports",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "target_learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.learning_paths": {
+ "name": "learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "thumbnail_reference": {
+ "name": "thumbnail_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "includes_certificate": {
+ "name": "includes_certificate",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"certificateSignature\":null,\"certificateFontColor\":null}'::jsonb"
+ },
+ "sequence_enabled": {
+ "name": "sequence_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "origin_type": {
+ "name": "origin_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'regular'"
+ },
+ "source_learning_path_id": {
+ "name": "source_learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "learning_paths_tenant_id_idx": {
+ "name": "learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "learning_paths_author_id_users_id_fk": {
+ "name": "learning_paths_author_id_users_id_fk",
+ "tableFrom": "learning_paths",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "learning_paths_tenant_id_tenants_id_fk": {
+ "name": "learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "learning_paths",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.lesson_learning_time": {
+ "name": "lesson_learning_time",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_learning_time_tenant_id_idx": {
+ "name": "lesson_learning_time_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lesson_learning_time_user_course_idx": {
+ "name": "lesson_learning_time_user_course_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "lesson_learning_time_user_id_users_id_fk": {
+ "name": "lesson_learning_time_user_id_users_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_learning_time_lesson_id_lessons_id_fk": {
+ "name": "lesson_learning_time_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_learning_time_course_id_courses_id_fk": {
+ "name": "lesson_learning_time_course_id_courses_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_learning_time_tenant_id_tenants_id_fk": {
+ "name": "lesson_learning_time_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_learning_time",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_learning_time_user_id_lesson_id_unique": {
+ "name": "lesson_learning_time_user_id_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "lesson_id"
+ ]
+ }
+ }
+ },
+ "public.lesson_video_progress": {
+ "name": "lesson_video_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_entity_id": {
+ "name": "resource_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "duration_seconds": {
+ "name": "duration_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bucket_size_seconds": {
+ "name": "bucket_size_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "watched_ranges": {
+ "name": "watched_ranges",
+ "type": "int4multirange",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::int4multirange"
+ },
+ "covered_bucket_count": {
+ "name": "covered_bucket_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "coverage_percent": {
+ "name": "coverage_percent",
+ "type": "numeric(5, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "active_watch_seconds": {
+ "name": "active_watch_seconds",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "is_watched": {
+ "name": "is_watched",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "watched_at": {
+ "name": "watched_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lesson_video_progress_tenant_id_idx": {
+ "name": "lesson_video_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lesson_video_progress_lesson_idx": {
+ "name": "lesson_video_progress_lesson_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lesson_video_progress_resource_entity_idx": {
+ "name": "lesson_video_progress_resource_entity_idx",
+ "columns": [
+ {
+ "expression": "resource_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "lesson_video_progress_student_id_users_id_fk": {
+ "name": "lesson_video_progress_student_id_users_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_video_progress_lesson_id_lessons_id_fk": {
+ "name": "lesson_video_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_video_progress_resource_entity_id_resource_entity_id_fk": {
+ "name": "lesson_video_progress_resource_entity_id_resource_entity_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "resource_entity",
+ "columnsFrom": [
+ "resource_entity_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lesson_video_progress_tenant_id_tenants_id_fk": {
+ "name": "lesson_video_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "lesson_video_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique": {
+ "name": "lesson_video_progress_student_id_lesson_id_resource_entity_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "resource_entity_id"
+ ]
+ }
+ }
+ },
+ "public.lessons": {
+ "name": "lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "threshold_score": {
+ "name": "threshold_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts_limit": {
+ "name": "attempts_limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quiz_cooldown_in_hours": {
+ "name": "quiz_cooldown_in_hours",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_s3_key": {
+ "name": "file_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_type": {
+ "name": "file_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_external": {
+ "name": "is_external",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "lessons_tenant_id_idx": {
+ "name": "lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "lessons_tenant_id_chapter_id_type_idx": {
+ "name": "lessons_tenant_id_chapter_id_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chapter_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "lessons_chapter_id_chapters_id_fk": {
+ "name": "lessons_chapter_id_chapters_id_fk",
+ "tableFrom": "lessons",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "lessons_tenant_id_tenants_id_fk": {
+ "name": "lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "lessons",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_lessons": {
+ "name": "live_lessons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_link_id": {
+ "name": "live_training_link_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_lessons_tenant_id_idx": {
+ "name": "live_lessons_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_lessons_lesson_language_unique_idx": {
+ "name": "live_lessons_lesson_language_unique_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_lessons_training_link_idx": {
+ "name": "live_lessons_training_link_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_link_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_lessons_training_idx": {
+ "name": "live_lessons_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_lessons_live_training_id_live_trainings_id_fk": {
+ "name": "live_lessons_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_lessons_live_training_link_id_live_training_links_id_fk": {
+ "name": "live_lessons_live_training_link_id_live_training_links_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "live_training_links",
+ "columnsFrom": [
+ "live_training_link_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_lessons_lesson_id_lessons_id_fk": {
+ "name": "live_lessons_lesson_id_lessons_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_lessons_tenant_id_tenants_id_fk": {
+ "name": "live_lessons_tenant_id_tenants_id_fk",
+ "tableFrom": "live_lessons",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_attendance": {
+ "name": "live_training_attendance",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_participant_id": {
+ "name": "live_training_session_participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "joined_at": {
+ "name": "joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "left_at": {
+ "name": "left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_participant_sid": {
+ "name": "livekit_participant_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disconnect_reason": {
+ "name": "disconnect_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_attendance_tenant_id_idx": {
+ "name": "live_training_attendance_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_attendance_session_user_idx": {
+ "name": "live_training_attendance_session_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_attendance_training_user_idx": {
+ "name": "live_training_attendance_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_attendance_joined_at_idx": {
+ "name": "live_training_attendance_joined_at_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "joined_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk": {
+ "name": "live_training_attendance_live_training_session_participant_id_live_training_session_participants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "live_training_session_participants",
+ "columnsFrom": [
+ "live_training_session_participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_attendance_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "live_training_sessions",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_attendance_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_user_id_users_id_fk": {
+ "name": "live_training_attendance_user_id_users_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_attendance_tenant_id_tenants_id_fk": {
+ "name": "live_training_attendance_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_attendance",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_links": {
+ "name": "live_training_links",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'course'"
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_links_tenant_id_idx": {
+ "name": "live_training_links_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_links_training_entity_unique_idx": {
+ "name": "live_training_links_training_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_links_training_idx": {
+ "name": "live_training_links_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_links_entity_idx": {
+ "name": "live_training_links_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_links_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_links_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_links",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_links_tenant_id_tenants_id_fk": {
+ "name": "live_training_links_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_links",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_members": {
+ "name": "live_training_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'host'"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_members_tenant_id_idx": {
+ "name": "live_training_members_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_training_user_unique_idx": {
+ "name": "live_training_members_training_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_training_idx": {
+ "name": "live_training_members_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_user_idx": {
+ "name": "live_training_members_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_members_role_idx": {
+ "name": "live_training_members_role_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_members_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_members_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_members",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_members_user_id_users_id_fk": {
+ "name": "live_training_members_user_id_users_id_fk",
+ "tableFrom": "live_training_members",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_members_tenant_id_tenants_id_fk": {
+ "name": "live_training_members_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_members",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_session_participants": {
+ "name": "live_training_session_participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_session_id": {
+ "name": "live_training_session_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_joined_at": {
+ "name": "first_joined_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_left_at": {
+ "name": "last_left_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_seconds": {
+ "name": "total_seconds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "join_count": {
+ "name": "join_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "livekit_identity": {
+ "name": "livekit_identity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_session_participants_tenant_id_idx": {
+ "name": "live_training_session_participants_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_session_user_unique_idx": {
+ "name": "live_training_session_participants_session_user_unique_idx",
+ "columns": [
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_session_idx": {
+ "name": "live_training_session_participants_session_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_training_user_idx": {
+ "name": "live_training_session_participants_training_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_session_participants_user_idx": {
+ "name": "live_training_session_participants_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk": {
+ "name": "live_training_session_participants_live_training_session_id_live_training_sessions_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "live_training_sessions",
+ "columnsFrom": [
+ "live_training_session_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_session_participants_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_session_participants_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_session_participants_user_id_users_id_fk": {
+ "name": "live_training_session_participants_user_id_users_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_session_participants_tenant_id_tenants_id_fk": {
+ "name": "live_training_session_participants_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_session_participants",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_training_sessions": {
+ "name": "live_training_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "live_training_id": {
+ "name": "live_training_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'waiting'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_by_user_id": {
+ "name": "started_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_by_user_id": {
+ "name": "ended_by_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "end_reason": {
+ "name": "end_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_name": {
+ "name": "livekit_room_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "livekit_room_sid": {
+ "name": "livekit_room_sid",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "peak_participant_count": {
+ "name": "peak_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "unique_participant_count": {
+ "name": "unique_participant_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_training_sessions_tenant_id_idx": {
+ "name": "live_training_sessions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_sessions_training_idx": {
+ "name": "live_training_sessions_training_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "live_training_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_sessions_status_idx": {
+ "name": "live_training_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_training_sessions_livekit_room_name_idx": {
+ "name": "live_training_sessions_livekit_room_name_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "livekit_room_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_training_sessions_live_training_id_live_trainings_id_fk": {
+ "name": "live_training_sessions_live_training_id_live_trainings_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "live_trainings",
+ "columnsFrom": [
+ "live_training_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_training_sessions_started_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_started_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "started_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_sessions_ended_by_user_id_users_id_fk": {
+ "name": "live_training_sessions_ended_by_user_id_users_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "ended_by_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_training_sessions_tenant_id_tenants_id_fk": {
+ "name": "live_training_sessions_tenant_id_tenants_id_fk",
+ "tableFrom": "live_training_sessions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.live_trainings": {
+ "name": "live_trainings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "delivery_type": {
+ "name": "delivery_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'online'"
+ },
+ "visibility_scope": {
+ "name": "visibility_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'linked_courses'"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "max_participants": {
+ "name": "max_participants",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"viewerPermissions\":{\"microphoneEnabled\":false,\"cameraEnabled\":false}}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "live_trainings_tenant_id_idx": {
+ "name": "live_trainings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_trainings_tenant_status_idx": {
+ "name": "live_trainings_tenant_status_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "live_trainings_author_idx": {
+ "name": "live_trainings_author_idx",
+ "columns": [
+ {
+ "expression": "author_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "live_trainings_calendar_event_id_calendar_events_id_fk": {
+ "name": "live_trainings_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "live_trainings",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "live_trainings_author_id_users_id_fk": {
+ "name": "live_trainings_author_id_users_id_fk",
+ "tableFrom": "live_trainings",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "live_trainings_tenant_id_tenants_id_fk": {
+ "name": "live_trainings_tenant_id_tenants_id_fk",
+ "tableFrom": "live_trainings",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "live_trainings_calendar_event_id_unique": {
+ "name": "live_trainings_calendar_event_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "calendar_event_id"
+ ]
+ }
+ }
+ },
+ "public.luma_course_generation_syncs": {
+ "name": "luma_course_generation_syncs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_id": {
+ "name": "draft_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failed_at": {
+ "name": "failed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dismissed_at": {
+ "name": "dismissed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "luma_course_generation_syncs_tenant_id_idx": {
+ "name": "luma_course_generation_syncs_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "luma_course_generation_syncs_course_id_idx": {
+ "name": "luma_course_generation_syncs_course_id_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "luma_course_generation_syncs_status_idx": {
+ "name": "luma_course_generation_syncs_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "luma_course_generation_syncs_course_id_courses_id_fk": {
+ "name": "luma_course_generation_syncs_course_id_courses_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "luma_course_generation_syncs_tenant_id_tenants_id_fk": {
+ "name": "luma_course_generation_syncs_tenant_id_tenants_id_fk",
+ "tableFrom": "luma_course_generation_syncs",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "luma_course_generation_syncs_course_id_unique": {
+ "name": "luma_course_generation_syncs_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.magic_link_tokens": {
+ "name": "magic_link_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "magic_link_tokens_tenant_id_idx": {
+ "name": "magic_link_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "magic_link_tokens_token_hash_idx": {
+ "name": "magic_link_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "magic_link_tokens_user_id_users_id_fk": {
+ "name": "magic_link_tokens_user_id_users_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "magic_link_tokens_tenant_id_tenants_id_fk": {
+ "name": "magic_link_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "magic_link_tokens",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_entity_map": {
+ "name": "master_course_entity_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "export_id": {
+ "name": "export_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_entity_id": {
+ "name": "source_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_entity_id": {
+ "name": "target_entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "master_course_entity_map_export_idx": {
+ "name": "master_course_entity_map_export_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_entity_map_source_entity_idx": {
+ "name": "master_course_entity_map_source_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_entity_map_source_unique_idx": {
+ "name": "master_course_entity_map_source_unique_idx",
+ "columns": [
+ {
+ "expression": "export_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "master_course_entity_map_export_id_master_course_exports_id_fk": {
+ "name": "master_course_entity_map_export_id_master_course_exports_id_fk",
+ "tableFrom": "master_course_entity_map",
+ "tableTo": "master_course_exports",
+ "columnsFrom": [
+ "export_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.master_course_exports": {
+ "name": "master_course_exports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "source_tenant_id": {
+ "name": "source_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_course_id": {
+ "name": "source_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_course_id": {
+ "name": "target_course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_status": {
+ "name": "sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "master_course_exports_source_course_idx": {
+ "name": "master_course_exports_source_course_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_exports_target_course_idx": {
+ "name": "master_course_exports_target_course_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "master_course_exports_source_target_unique_idx": {
+ "name": "master_course_exports_source_target_unique_idx",
+ "columns": [
+ {
+ "expression": "source_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "master_course_exports_source_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_source_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "source_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "master_course_exports_source_course_id_courses_id_fk": {
+ "name": "master_course_exports_source_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "source_course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "master_course_exports_target_tenant_id_tenants_id_fk": {
+ "name": "master_course_exports_target_tenant_id_tenants_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "master_course_exports_target_course_id_courses_id_fk": {
+ "name": "master_course_exports_target_course_id_courses_id_fk",
+ "tableFrom": "master_course_exports",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "target_course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.news": {
+ "name": "news",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "summary": {
+ "name": "summary",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "news_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "news_tenant_id_idx": {
+ "name": "news_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "news_author_id_users_id_fk": {
+ "name": "news_author_id_users_id_fk",
+ "tableFrom": "news",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "news_tenant_id_tenants_id_fk": {
+ "name": "news_tenant_id_tenants_id_fk",
+ "tableFrom": "news",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.outbox_events": {
+ "name": "outbox_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempt_count": {
+ "name": "attempt_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "published_at": {
+ "name": "published_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "outbox_events_tenant_id_idx": {
+ "name": "outbox_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "outbox_events_poll_idx": {
+ "name": "outbox_events_poll_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "outbox_events_tenant_id_tenants_id_fk": {
+ "name": "outbox_events_tenant_id_tenants_id_fk",
+ "tableFrom": "outbox_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_role_rule_sets": {
+ "name": "permission_role_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_role_rule_sets_tenant_id_idx": {
+ "name": "permission_role_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_role_rule_sets_role_id_rule_set_id_unique": {
+ "name": "permission_role_rule_sets_role_id_rule_set_id_unique",
+ "columns": [
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_role_rule_sets_role_id_permission_roles_id_fk": {
+ "name": "permission_role_rule_sets_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "tableTo": "permission_roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_role_rule_sets_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "tableTo": "permission_rule_sets",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_role_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_role_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_role_rule_sets",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_roles": {
+ "name": "permission_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_roles_tenant_id_idx": {
+ "name": "permission_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_roles_tenant_id_slug_unique": {
+ "name": "permission_roles_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_roles",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_set_permissions": {
+ "name": "permission_rule_set_permissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "rule_set_id": {
+ "name": "rule_set_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission": {
+ "name": "permission",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_set_permissions_tenant_id_idx": {
+ "name": "permission_rule_set_permissions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_rule_set_permissions_rule_set_id_permission_unique": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_unique",
+ "columns": [
+ {
+ "expression": "rule_set_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk": {
+ "name": "permission_rule_set_permissions_rule_set_id_permission_rule_sets_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "tableTo": "permission_rule_sets",
+ "columnsFrom": [
+ "rule_set_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_rule_set_permissions_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_set_permissions_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_set_permissions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_rule_sets": {
+ "name": "permission_rule_sets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_system": {
+ "name": "is_system",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_rule_sets_tenant_id_idx": {
+ "name": "permission_rule_sets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_rule_sets_tenant_id_slug_unique": {
+ "name": "permission_rule_sets_tenant_id_slug_unique",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_rule_sets_tenant_id_tenants_id_fk": {
+ "name": "permission_rule_sets_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_rule_sets",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.permission_user_roles": {
+ "name": "permission_user_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "permission_user_roles_tenant_id_idx": {
+ "name": "permission_user_roles_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_user_roles_user_id_role_id_unique": {
+ "name": "permission_user_roles_user_id_role_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "role_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_user_roles_user_id_users_id_fk": {
+ "name": "permission_user_roles_user_id_users_id_fk",
+ "tableFrom": "permission_user_roles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_user_roles_role_id_permission_roles_id_fk": {
+ "name": "permission_user_roles_role_id_permission_roles_id_fk",
+ "tableFrom": "permission_user_roles",
+ "tableTo": "permission_roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_user_roles_tenant_id_tenants_id_fk": {
+ "name": "permission_user_roles_tenant_id_tenants_id_fk",
+ "tableFrom": "permission_user_roles",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.question_answer_options": {
+ "name": "question_answer_options",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "option_text": {
+ "name": "option_text",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matched_word": {
+ "name": "matched_word",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scale_answer": {
+ "name": "scale_answer",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "question_answer_options_tenant_id_idx": {
+ "name": "question_answer_options_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "question_answer_options_question_id_questions_id_fk": {
+ "name": "question_answer_options_question_id_questions_id_fk",
+ "tableFrom": "question_answer_options",
+ "tableTo": "questions",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "question_answer_options_tenant_id_tenants_id_fk": {
+ "name": "question_answer_options_tenant_id_tenants_id_fk",
+ "tableFrom": "question_answer_options",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions": {
+ "name": "questions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "author_id": {
+ "name": "author_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "photo_s3_key": {
+ "name": "photo_s3_key",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "solution_explanation": {
+ "name": "solution_explanation",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_tenant_id_idx": {
+ "name": "questions_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "questions_lesson_id_lessons_id_fk": {
+ "name": "questions_lesson_id_lessons_id_fk",
+ "tableFrom": "questions",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "questions_author_id_users_id_fk": {
+ "name": "questions_author_id_users_id_fk",
+ "tableFrom": "questions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "author_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "questions_tenant_id_tenants_id_fk": {
+ "name": "questions_tenant_id_tenants_id_fk",
+ "tableFrom": "questions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.questions_and_answers": {
+ "name": "questions_and_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "base_language": {
+ "name": "base_language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "available_locales": {
+ "name": "available_locales",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "ARRAY['en']::text[]"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "questions_and_answers_tenant_id_idx": {
+ "name": "questions_and_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "questions_and_answers_tenant_id_tenants_id_fk": {
+ "name": "questions_and_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "questions_and_answers",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.quiz_attempts": {
+ "name": "quiz_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "correct_answers": {
+ "name": "correct_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wrong_answers": {
+ "name": "wrong_answers",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "score": {
+ "name": "score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "quiz_attempts_tenant_id_idx": {
+ "name": "quiz_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "quiz_attempts_user_id_users_id_fk": {
+ "name": "quiz_attempts_user_id_users_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "quiz_attempts_course_id_courses_id_fk": {
+ "name": "quiz_attempts_course_id_courses_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "quiz_attempts_lesson_id_lessons_id_fk": {
+ "name": "quiz_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "quiz_attempts_tenant_id_tenants_id_fk": {
+ "name": "quiz_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "quiz_attempts",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.reset_tokens": {
+ "name": "reset_tokens",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expiry_date": {
+ "name": "expiry_date",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "reset_tokens_tenant_id_idx": {
+ "name": "reset_tokens_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "reset_tokens_token_hash_idx": {
+ "name": "reset_tokens_token_hash_idx",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "reset_tokens_user_id_users_id_fk": {
+ "name": "reset_tokens_user_id_users_id_fk",
+ "tableFrom": "reset_tokens",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "reset_tokens_tenant_id_tenants_id_fk": {
+ "name": "reset_tokens_tenant_id_tenants_id_fk",
+ "tableFrom": "reset_tokens",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.resource_entity": {
+ "name": "resource_entity",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "relationship_type": {
+ "name": "relationship_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'attachment'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resource_entity_tenant_id_idx": {
+ "name": "resource_entity_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_entity_resource_idx": {
+ "name": "resource_entity_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_entity_entity_idx": {
+ "name": "resource_entity_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_entity_relationship_idx": {
+ "name": "resource_entity_relationship_idx",
+ "columns": [
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "relationship_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "resource_entity_resource_id_resources_id_fk": {
+ "name": "resource_entity_resource_id_resources_id_fk",
+ "tableFrom": "resource_entity",
+ "tableTo": "resources",
+ "columnsFrom": [
+ "resource_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "resource_entity_tenant_id_tenants_id_fk": {
+ "name": "resource_entity_tenant_id_tenants_id_fk",
+ "tableFrom": "resource_entity",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique": {
+ "name": "resource_entity_resource_id_entity_id_entity_type_relationship_type_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "resource_id",
+ "entity_id",
+ "entity_type",
+ "relationship_type"
+ ]
+ }
+ }
+ },
+ "public.resources": {
+ "name": "resources",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "title": {
+ "name": "title",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "description": {
+ "name": "description",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "reference": {
+ "name": "reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "uploaded_by_id": {
+ "name": "uploaded_by_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "resources_tenant_id_idx": {
+ "name": "resources_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "resources_uploaded_by_id_users_id_fk": {
+ "name": "resources_uploaded_by_id_users_id_fk",
+ "tableFrom": "resources",
+ "tableTo": "users",
+ "columnsFrom": [
+ "uploaded_by_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "resources_tenant_id_tenants_id_fk": {
+ "name": "resources_tenant_id_tenants_id_fk",
+ "tableFrom": "resources",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_attempts": {
+ "name": "scorm_attempts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sco_id": {
+ "name": "sco_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "attempt_number": {
+ "name": "attempt_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_attempts_tenant_id_idx": {
+ "name": "scorm_attempts_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_student_lesson_idx": {
+ "name": "scorm_attempts_student_lesson_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_student_package_idx": {
+ "name": "scorm_attempts_student_package_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_sco_id_idx": {
+ "name": "scorm_attempts_sco_id_idx",
+ "columns": [
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_attempts_student_package_sco_attempt_unique_idx": {
+ "name": "scorm_attempts_student_package_sco_attempt_unique_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sco_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "attempt_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_attempts_student_id_users_id_fk": {
+ "name": "scorm_attempts_student_id_users_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_course_id_courses_id_fk": {
+ "name": "scorm_attempts_course_id_courses_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_lesson_id_lessons_id_fk": {
+ "name": "scorm_attempts_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_package_id_scorm_packages_id_fk": {
+ "name": "scorm_attempts_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "scorm_packages",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_sco_id_scorm_scos_id_fk": {
+ "name": "scorm_attempts_sco_id_scorm_scos_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "scorm_scos",
+ "columnsFrom": [
+ "sco_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_attempts_tenant_id_tenants_id_fk": {
+ "name": "scorm_attempts_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_attempts",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_packages": {
+ "name": "scorm_packages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "scorm_package_entity_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'en'"
+ },
+ "standard": {
+ "name": "standard",
+ "type": "scorm_standard",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_file_reference": {
+ "name": "original_file_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "extracted_files_reference": {
+ "name": "extracted_files_reference",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_entry_point": {
+ "name": "manifest_entry_point",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "manifest_json": {
+ "name": "manifest_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "status": {
+ "name": "status",
+ "type": "scorm_package_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'processing'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_packages_tenant_id_idx": {
+ "name": "scorm_packages_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_packages_entity_idx": {
+ "name": "scorm_packages_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_packages_entity_unique_idx": {
+ "name": "scorm_packages_entity_unique_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_packages_tenant_id_tenants_id_fk": {
+ "name": "scorm_packages_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_packages",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_runtime_state": {
+ "name": "scorm_runtime_state",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "attempt_id": {
+ "name": "attempt_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completion_status": {
+ "name": "completion_status",
+ "type": "scorm_completion_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "success_status": {
+ "name": "success_status",
+ "type": "scorm_success_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'unknown'"
+ },
+ "score_raw": {
+ "name": "score_raw",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_min": {
+ "name": "score_min",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_max": {
+ "name": "score_max",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "score_scaled": {
+ "name": "score_scaled",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lesson_location": {
+ "name": "lesson_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspend_data": {
+ "name": "suspend_data",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_time": {
+ "name": "session_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_time": {
+ "name": "total_time",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "progress_measure": {
+ "name": "progress_measure",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "entry": {
+ "name": "entry",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exit": {
+ "name": "exit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_cmi_json": {
+ "name": "raw_cmi_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_runtime_state_tenant_id_idx": {
+ "name": "scorm_runtime_state_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_runtime_state_attempt_id_unique_idx": {
+ "name": "scorm_runtime_state_attempt_id_unique_idx",
+ "columns": [
+ {
+ "expression": "attempt_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_runtime_state_attempt_id_scorm_attempts_id_fk": {
+ "name": "scorm_runtime_state_attempt_id_scorm_attempts_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "tableTo": "scorm_attempts",
+ "columnsFrom": [
+ "attempt_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_runtime_state_tenant_id_tenants_id_fk": {
+ "name": "scorm_runtime_state_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_runtime_state",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.scorm_scos": {
+ "name": "scorm_scos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "package_id": {
+ "name": "package_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_identifier": {
+ "name": "organization_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "identifier_ref": {
+ "name": "identifier_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_identifier": {
+ "name": "resource_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scorm_type": {
+ "name": "scorm_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "href": {
+ "name": "href",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "launch_path": {
+ "name": "launch_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parameters": {
+ "name": "parameters",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_order": {
+ "name": "display_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_identifier": {
+ "name": "parent_identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_visible": {
+ "name": "is_visible",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "item_metadata_json": {
+ "name": "item_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_metadata_json": {
+ "name": "resource_metadata_json",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "scorm_scos_tenant_id_idx": {
+ "name": "scorm_scos_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_scos_package_id_idx": {
+ "name": "scorm_scos_package_id_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_scos_lesson_id_idx": {
+ "name": "scorm_scos_lesson_id_idx",
+ "columns": [
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scorm_scos_package_identifier_unique_idx": {
+ "name": "scorm_scos_package_identifier_unique_idx",
+ "columns": [
+ {
+ "expression": "package_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scorm_scos_package_id_scorm_packages_id_fk": {
+ "name": "scorm_scos_package_id_scorm_packages_id_fk",
+ "tableFrom": "scorm_scos",
+ "tableTo": "scorm_packages",
+ "columnsFrom": [
+ "package_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_scos_lesson_id_lessons_id_fk": {
+ "name": "scorm_scos_lesson_id_lessons_id_fk",
+ "tableFrom": "scorm_scos",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scorm_scos_tenant_id_tenants_id_fk": {
+ "name": "scorm_scos_tenant_id_tenants_id_fk",
+ "tableFrom": "scorm_scos",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.search_documents": {
+ "name": "search_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "search_vector": {
+ "name": "search_vector",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "search_documents_tenant_id_idx": {
+ "name": "search_documents_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "search_documents_vector_idx": {
+ "name": "search_documents_vector_idx",
+ "columns": [
+ {
+ "expression": "search_vector",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ },
+ "search_documents_language_entity_type_idx": {
+ "name": "search_documents_language_entity_type_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "search_documents_entity_idx": {
+ "name": "search_documents_entity_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "search_documents_document_unique_idx": {
+ "name": "search_documents_document_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "document_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "language",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "search_documents_tenant_id_tenants_id_fk": {
+ "name": "search_documents_tenant_id_tenants_id_fk",
+ "tableFrom": "search_documents",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.secrets": {
+ "name": "secrets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "secret_name": {
+ "name": "secret_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "ciphertext": {
+ "name": "ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "iv": {
+ "name": "iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tag": {
+ "name": "tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek": {
+ "name": "encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_iv": {
+ "name": "encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_dek_tag": {
+ "name": "encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "alg": {
+ "name": "alg",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'AES-256-GCM'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "secrets_tenant_id_idx": {
+ "name": "secrets_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "secrets_tenant_secret_name_uq": {
+ "name": "secrets_tenant_secret_name_uq",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "secrets_name_idx": {
+ "name": "secrets_name_idx",
+ "columns": [
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "secrets_tenant_id_tenants_id_fk": {
+ "name": "secrets_tenant_id_tenants_id_fk",
+ "tableFrom": "secrets",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.settings": {
+ "name": "settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "settings_tenant_id_idx": {
+ "name": "settings_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "settings_user_id_users_id_fk": {
+ "name": "settings_user_id_users_id_fk",
+ "tableFrom": "settings",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "settings_tenant_id_tenants_id_fk": {
+ "name": "settings_tenant_id_tenants_id_fk",
+ "tableFrom": "settings",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.student_chapter_progress": {
+ "name": "student_chapter_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_lesson_count": {
+ "name": "completed_lesson_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_as_freemium": {
+ "name": "completed_as_freemium",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_chapter_progress_tenant_id_idx": {
+ "name": "student_chapter_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_chapter_progress_student_id_users_id_fk": {
+ "name": "student_chapter_progress_student_id_users_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_course_id_courses_id_fk": {
+ "name": "student_chapter_progress_course_id_courses_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_chapter_id_chapters_id_fk": {
+ "name": "student_chapter_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_chapter_progress_tenant_id_tenants_id_fk": {
+ "name": "student_chapter_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_chapter_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_chapter_progress_student_id_course_id_chapter_id_unique": {
+ "name": "student_chapter_progress_student_id_course_id_chapter_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "course_id",
+ "chapter_id"
+ ]
+ }
+ }
+ },
+ "public.student_courses": {
+ "name": "student_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "finished_chapter_count": {
+ "name": "finished_chapter_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "course_completion_metadata": {
+ "name": "course_completion_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "status": {
+ "name": "status",
+ "type": "varchar",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'enrolled'"
+ },
+ "payment_id": {
+ "name": "payment_id",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_by_group_id": {
+ "name": "enrolled_by_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_courses_tenant_id_idx": {
+ "name": "student_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_courses_tenant_id_course_status_student_idx": {
+ "name": "student_courses_tenant_id_course_status_student_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_courses_student_id_users_id_fk": {
+ "name": "student_courses_student_id_users_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_courses_course_id_courses_id_fk": {
+ "name": "student_courses_course_id_courses_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_courses_enrolled_by_group_id_groups_id_fk": {
+ "name": "student_courses_enrolled_by_group_id_groups_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "groups",
+ "columnsFrom": [
+ "enrolled_by_group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "student_courses_tenant_id_tenants_id_fk": {
+ "name": "student_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_courses_student_id_course_id_unique": {
+ "name": "student_courses_student_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.student_learning_path_courses": {
+ "name": "student_learning_path_courses",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_path_courses_tenant_id_idx": {
+ "name": "student_learning_path_courses_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_learning_path_courses_student_path_idx": {
+ "name": "student_learning_path_courses_student_path_idx",
+ "columns": [
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "learning_path_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_learning_path_courses_course_idx": {
+ "name": "student_learning_path_courses_course_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_learning_path_courses_student_id_users_id_fk": {
+ "name": "student_learning_path_courses_student_id_users_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_path_courses_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_path_courses_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_path_courses_course_id_courses_id_fk": {
+ "name": "student_learning_path_courses_course_id_courses_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "courses",
+ "columnsFrom": [
+ "course_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_path_courses_tenant_id_tenants_id_fk": {
+ "name": "student_learning_path_courses_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_path_courses",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_path_courses_student_id_learning_path_id_course_id_unique": {
+ "name": "student_learning_path_courses_student_id_learning_path_id_course_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "learning_path_id",
+ "course_id"
+ ]
+ }
+ }
+ },
+ "public.student_learning_paths": {
+ "name": "student_learning_paths",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "learning_path_id": {
+ "name": "learning_path_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "progress": {
+ "name": "progress",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'not_started'"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrolled_at": {
+ "name": "enrolled_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "enrollment_type": {
+ "name": "enrollment_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'direct'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_learning_paths_tenant_id_idx": {
+ "name": "student_learning_paths_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_learning_paths_student_id_users_id_fk": {
+ "name": "student_learning_paths_student_id_users_id_fk",
+ "tableFrom": "student_learning_paths",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_paths_learning_path_id_learning_paths_id_fk": {
+ "name": "student_learning_paths_learning_path_id_learning_paths_id_fk",
+ "tableFrom": "student_learning_paths",
+ "tableTo": "learning_paths",
+ "columnsFrom": [
+ "learning_path_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_learning_paths_tenant_id_tenants_id_fk": {
+ "name": "student_learning_paths_tenant_id_tenants_id_fk",
+ "tableFrom": "student_learning_paths",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_learning_paths_student_id_learning_path_id_unique": {
+ "name": "student_learning_paths_student_id_learning_path_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "learning_path_id"
+ ]
+ }
+ }
+ },
+ "public.student_lesson_progress": {
+ "name": "student_lesson_progress",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chapter_id": {
+ "name": "chapter_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lesson_id": {
+ "name": "lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_question_count": {
+ "name": "completed_question_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "quiz_score": {
+ "name": "quiz_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_quiz_passed": {
+ "name": "is_quiz_passed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_started": {
+ "name": "is_started",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "language_answered": {
+ "name": "language_answered",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'en'"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_lesson_progress_tenant_id_idx": {
+ "name": "student_lesson_progress_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "student_lesson_progress_completed_quiz_score_idx": {
+ "name": "student_lesson_progress_completed_quiz_score_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lesson_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "student_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"student_lesson_progress\".\"completed_at\" IS NOT NULL AND \"student_lesson_progress\".\"quiz_score\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_lesson_progress_student_id_users_id_fk": {
+ "name": "student_lesson_progress_student_id_users_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "student_lesson_progress_chapter_id_chapters_id_fk": {
+ "name": "student_lesson_progress_chapter_id_chapters_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "chapters",
+ "columnsFrom": [
+ "chapter_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_lesson_progress_lesson_id_lessons_id_fk": {
+ "name": "student_lesson_progress_lesson_id_lessons_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "lessons",
+ "columnsFrom": [
+ "lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_lesson_progress_tenant_id_tenants_id_fk": {
+ "name": "student_lesson_progress_tenant_id_tenants_id_fk",
+ "tableFrom": "student_lesson_progress",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_lesson_progress_student_id_lesson_id_chapter_id_unique": {
+ "name": "student_lesson_progress_student_id_lesson_id_chapter_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "student_id",
+ "lesson_id",
+ "chapter_id"
+ ]
+ }
+ }
+ },
+ "public.student_question_answers": {
+ "name": "student_question_answers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "question_id": {
+ "name": "question_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "student_id": {
+ "name": "student_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "answer": {
+ "name": "answer",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "is_correct": {
+ "name": "is_correct",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "student_question_answers_tenant_id_idx": {
+ "name": "student_question_answers_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "student_question_answers_question_id_questions_id_fk": {
+ "name": "student_question_answers_question_id_questions_id_fk",
+ "tableFrom": "student_question_answers",
+ "tableTo": "questions",
+ "columnsFrom": [
+ "question_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_question_answers_student_id_users_id_fk": {
+ "name": "student_question_answers_student_id_users_id_fk",
+ "tableFrom": "student_question_answers",
+ "tableTo": "users",
+ "columnsFrom": [
+ "student_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "student_question_answers_tenant_id_tenants_id_fk": {
+ "name": "student_question_answers_tenant_id_tenants_id_fk",
+ "tableFrom": "student_question_answers",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "student_question_answers_question_id_student_id_unique": {
+ "name": "student_question_answers_question_id_student_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "question_id",
+ "student_id"
+ ]
+ }
+ }
+ },
+ "public.support_sessions": {
+ "name": "support_sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "original_user_id": {
+ "name": "original_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "original_tenant_id": {
+ "name": "original_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_tenant_id": {
+ "name": "target_tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_user_id": {
+ "name": "target_user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hashed_grant_token": {
+ "name": "hashed_grant_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "grant_expires_at": {
+ "name": "grant_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "activated_at": {
+ "name": "activated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "return_url": {
+ "name": "return_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ }
+ },
+ "indexes": {
+ "support_sessions_hashed_grant_token_unique": {
+ "name": "support_sessions_hashed_grant_token_unique",
+ "columns": [
+ {
+ "expression": "hashed_grant_token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_status_idx": {
+ "name": "support_sessions_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_original_user_idx": {
+ "name": "support_sessions_original_user_idx",
+ "columns": [
+ {
+ "expression": "original_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_target_tenant_idx": {
+ "name": "support_sessions_target_tenant_idx",
+ "columns": [
+ {
+ "expression": "target_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "support_sessions_target_user_idx": {
+ "name": "support_sessions_target_user_idx",
+ "columns": [
+ {
+ "expression": "target_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "support_sessions_original_user_id_users_id_fk": {
+ "name": "support_sessions_original_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "original_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "support_sessions_original_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_original_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "original_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "support_sessions_target_tenant_id_tenants_id_fk": {
+ "name": "support_sessions_target_tenant_id_tenants_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "target_tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "support_sessions_target_user_id_users_id_fk": {
+ "name": "support_sessions_target_user_id_users_id_fk",
+ "tableFrom": "support_sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "target_user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.tenants": {
+ "name": "tenants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "host": {
+ "name": "host",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "is_managing": {
+ "name": "is_managing",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ }
+ },
+ "indexes": {
+ "unique_host_idx": {
+ "name": "unique_host_idx",
+ "columns": [
+ {
+ "expression": "host",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user_announcements": {
+ "name": "user_announcements",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "announcement_id": {
+ "name": "announcement_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_read": {
+ "name": "is_read",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "read_at": {
+ "name": "read_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_announcements_tenant_id_idx": {
+ "name": "user_announcements_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_announcements_user_id_users_id_fk": {
+ "name": "user_announcements_user_id_users_id_fk",
+ "tableFrom": "user_announcements",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_announcements_announcement_id_announcements_id_fk": {
+ "name": "user_announcements_announcement_id_announcements_id_fk",
+ "tableFrom": "user_announcements",
+ "tableTo": "announcements",
+ "columnsFrom": [
+ "announcement_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_announcements_tenant_id_tenants_id_fk": {
+ "name": "user_announcements_tenant_id_tenants_id_fk",
+ "tableFrom": "user_announcements",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_announcements_user_id_announcement_id_unique": {
+ "name": "user_announcements_user_id_announcement_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id",
+ "announcement_id"
+ ]
+ }
+ }
+ },
+ "public.user_details": {
+ "name": "user_details",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "contact_phone_number": {
+ "name": "contact_phone_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contact_email": {
+ "name": "contact_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "job_title": {
+ "name": "job_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_details_tenant_id_idx": {
+ "name": "user_details_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_details_user_id_users_id_fk": {
+ "name": "user_details_user_id_users_id_fk",
+ "tableFrom": "user_details",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_details_tenant_id_tenants_id_fk": {
+ "name": "user_details_tenant_id_tenants_id_fk",
+ "tableFrom": "user_details",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_details_user_id_unique": {
+ "name": "user_details_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ }
+ },
+ "public.user_onboarding": {
+ "name": "user_onboarding",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dashboard": {
+ "name": "dashboard",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "courses": {
+ "name": "courses",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "announcements": {
+ "name": "announcements",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "profile": {
+ "name": "profile",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "settings": {
+ "name": "settings",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "provider_information": {
+ "name": "provider_information",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_onboarding_tenant_id_idx": {
+ "name": "user_onboarding_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_onboarding_user_id_users_id_fk": {
+ "name": "user_onboarding_user_id_users_id_fk",
+ "tableFrom": "user_onboarding",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_onboarding_tenant_id_tenants_id_fk": {
+ "name": "user_onboarding_tenant_id_tenants_id_fk",
+ "tableFrom": "user_onboarding",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_onboarding_user_id_unique": {
+ "name": "user_onboarding_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ }
+ },
+ "public.user_statistics": {
+ "name": "user_statistics",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_streak": {
+ "name": "current_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "longest_streak": {
+ "name": "longest_streak",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_activity_date": {
+ "name": "last_activity_date",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "activity_history": {
+ "name": "activity_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'::jsonb"
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "user_statistics_tenant_id_idx": {
+ "name": "user_statistics_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_statistics_user_id_users_id_fk": {
+ "name": "user_statistics_user_id_users_id_fk",
+ "tableFrom": "user_statistics",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_statistics_tenant_id_tenants_id_fk": {
+ "name": "user_statistics_tenant_id_tenants_id_fk",
+ "tableFrom": "user_statistics",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_statistics_user_id_unique": {
+ "name": "user_statistics_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ }
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_name": {
+ "name": "first_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_name": {
+ "name": "last_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "avatar_reference": {
+ "name": "avatar_reference",
+ "type": "varchar(500)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived": {
+ "name": "archived",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "users_tenant_id_idx": {
+ "name": "users_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "users_tenant_id_email_unique_idx": {
+ "name": "users_tenant_id_email_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "users_tenant_id_tenants_id_fk": {
+ "name": "users_tenant_id_tenants_id_fk",
+ "tableFrom": "users",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_connections": {
+ "name": "calendar_connections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "account_email": {
+ "name": "account_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_ciphertext": {
+ "name": "refresh_token_ciphertext",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_iv": {
+ "name": "refresh_token_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_tag": {
+ "name": "refresh_token_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek": {
+ "name": "refresh_token_encrypted_dek",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_iv": {
+ "name": "refresh_token_encrypted_dek_iv",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token_encrypted_dek_tag": {
+ "name": "refresh_token_encrypted_dek_tag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'syncing'"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_cursor": {
+ "name": "sync_cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_start": {
+ "name": "sync_window_start",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_window_end": {
+ "name": "sync_window_end",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "window_built_at": {
+ "name": "window_built_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_successful_sync_at": {
+ "name": "last_successful_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_completed_at": {
+ "name": "last_sync_completed_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_id": {
+ "name": "subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_client_state": {
+ "name": "subscription_client_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subscription_expires_at": {
+ "name": "subscription_expires_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_sync_enabled": {
+ "name": "outbound_sync_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "outbound_status": {
+ "name": "outbound_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'disabled'"
+ },
+ "outbound_calendar_id": {
+ "name": "outbound_calendar_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outbound_error_code": {
+ "name": "outbound_error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_outbound_sync_at": {
+ "name": "last_outbound_sync_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_connections_tenant_id_idx": {
+ "name": "calendar_connections_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_tenant_user_provider_unique_idx": {
+ "name": "calendar_connections_tenant_user_provider_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_connections_subscription_idx": {
+ "name": "calendar_connections_subscription_idx",
+ "columns": [
+ {
+ "expression": "subscription_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_connections_user_id_users_id_fk": {
+ "name": "calendar_connections_user_id_users_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_connections_tenant_id_tenants_id_fk": {
+ "name": "calendar_connections_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_connections",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_external_events": {
+ "name": "calendar_external_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "web_link": {
+ "name": "web_link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensitivity": {
+ "name": "sensitivity",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "availability": {
+ "name": "availability",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_cancelled": {
+ "name": "is_cancelled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_external_events_tenant_id_idx": {
+ "name": "calendar_external_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_calendar_event_unique_idx": {
+ "name": "calendar_external_events_calendar_event_unique_idx",
+ "columns": [
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_connection_event_unique_idx": {
+ "name": "calendar_external_events_tenant_connection_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_external_events_tenant_user_idx": {
+ "name": "calendar_external_events_tenant_user_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_external_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_external_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_external_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_user_id_users_id_fk": {
+ "name": "calendar_external_events_user_id_users_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_external_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_external_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_external_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.calendar_outbound_events": {
+ "name": "calendar_outbound_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "calendar_event_id": {
+ "name": "calendar_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_event_id": {
+ "name": "external_event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "calendar_outbound_events_tenant_id_idx": {
+ "name": "calendar_outbound_events_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_event_user_unique_idx": {
+ "name": "calendar_outbound_events_connection_event_user_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_connection_external_event_unique_idx": {
+ "name": "calendar_outbound_events_connection_external_event_unique_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "calendar_outbound_events_calendar_event_idx": {
+ "name": "calendar_outbound_events_calendar_event_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "calendar_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "calendar_outbound_events_connection_id_calendar_connections_id_fk": {
+ "name": "calendar_outbound_events_connection_id_calendar_connections_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_connections",
+ "columnsFrom": [
+ "connection_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_calendar_event_id_calendar_events_id_fk": {
+ "name": "calendar_outbound_events_calendar_event_id_calendar_events_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "calendar_events",
+ "columnsFrom": [
+ "calendar_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_user_id_users_id_fk": {
+ "name": "calendar_outbound_events_user_id_users_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "calendar_outbound_events_tenant_id_tenants_id_fk": {
+ "name": "calendar_outbound_events_tenant_id_tenants_id_fk",
+ "tableFrom": "calendar_outbound_events",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.ai_mentor_configurations": {
+ "name": "ai_mentor_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "ai_mentor_lesson_id": {
+ "name": "ai_mentor_lesson_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "structured_ai_mentor_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "opening_instruction": {
+ "name": "opening_instruction",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "additional_instructions": {
+ "name": "additional_instructions",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_configurations_tenant_id_idx": {
+ "name": "ai_mentor_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_ai_mentor_lessons_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "tableTo": "ai_mentor_lessons",
+ "columnsFrom": [
+ "ai_mentor_lesson_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_configurations_ai_mentor_lesson_id_unique": {
+ "name": "ai_mentor_configurations_ai_mentor_lesson_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "ai_mentor_lesson_id"
+ ]
+ }
+ }
+ },
+ "public.ai_mentor_roleplay_configurations": {
+ "name": "ai_mentor_roleplay_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario": {
+ "name": "scenario",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "ai_role": {
+ "name": "ai_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "learner_role": {
+ "name": "learner_role",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "character_goal": {
+ "name": "character_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "difficulty": {
+ "name": "difficulty",
+ "type": "ai_mentor_roleplay_difficulty",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "facts_and_constraints": {
+ "name": "facts_and_constraints",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_roleplay_configurations_tenant_id_idx": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "tableTo": "ai_mentor_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_roleplay_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_roleplay_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_roleplay_configurations_configuration_id_unique": {
+ "name": "ai_mentor_roleplay_configurations_configuration_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "configuration_id"
+ ]
+ }
+ }
+ },
+ "public.ai_mentor_teacher_configurations": {
+ "name": "ai_mentor_teacher_configurations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp(3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "CURRENT_TIMESTAMP"
+ },
+ "configuration_id": {
+ "name": "configuration_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "task_goal": {
+ "name": "task_goal",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "expertise": {
+ "name": "expertise",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "content_scope": {
+ "name": "content_scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "teaching_style": {
+ "name": "teaching_style",
+ "type": "ai_mentor_teaching_style",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback_guidance": {
+ "name": "feedback_guidance",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "current_setting('app.tenant_id', true)::uuid"
+ }
+ },
+ "indexes": {
+ "ai_mentor_teacher_configurations_tenant_id_idx": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_idx",
+ "columns": [
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_ai_mentor_configurations_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "tableTo": "ai_mentor_configurations",
+ "columnsFrom": [
+ "configuration_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk": {
+ "name": "ai_mentor_teacher_configurations_tenant_id_tenants_id_fk",
+ "tableFrom": "ai_mentor_teacher_configurations",
+ "tableTo": "tenants",
+ "columnsFrom": [
+ "tenant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "ai_mentor_teacher_configurations_configuration_id_unique": {
+ "name": "ai_mentor_teacher_configurations_configuration_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "configuration_id"
+ ]
+ }
+ }
+ }
+ },
+ "enums": {
+ "public.ai_mentor_roleplay_difficulty": {
+ "name": "ai_mentor_roleplay_difficulty",
+ "schema": "public",
+ "values": [
+ "cooperative",
+ "realistic",
+ "challenging"
+ ]
+ },
+ "public.ai_mentor_teaching_style": {
+ "name": "ai_mentor_teaching_style",
+ "schema": "public",
+ "values": [
+ "explain_and_practice",
+ "guided_discovery",
+ "socratic"
+ ]
+ },
+ "public.article_status": {
+ "name": "article_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.course_type": {
+ "name": "course_type",
+ "schema": "public",
+ "values": [
+ "default",
+ "scorm"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published",
+ "private"
+ ]
+ },
+ "public.news_status": {
+ "name": "news_status",
+ "schema": "public",
+ "values": [
+ "draft",
+ "published"
+ ]
+ },
+ "public.scorm_completion_status": {
+ "name": "scorm_completion_status",
+ "schema": "public",
+ "values": [
+ "completed",
+ "incomplete",
+ "not_attempted",
+ "unknown"
+ ]
+ },
+ "public.scorm_package_entity_type": {
+ "name": "scorm_package_entity_type",
+ "schema": "public",
+ "values": [
+ "course",
+ "lesson"
+ ]
+ },
+ "public.scorm_package_status": {
+ "name": "scorm_package_status",
+ "schema": "public",
+ "values": [
+ "processing",
+ "ready",
+ "failed"
+ ]
+ },
+ "public.scorm_standard": {
+ "name": "scorm_standard",
+ "schema": "public",
+ "values": [
+ "scorm_1_2",
+ "scorm_2004"
+ ]
+ },
+ "public.scorm_success_status": {
+ "name": "scorm_success_status",
+ "schema": "public",
+ "values": [
+ "passed",
+ "failed",
+ "unknown"
+ ]
+ },
+ "public.structured_ai_mentor_type": {
+ "name": "structured_ai_mentor_type",
+ "schema": "public",
+ "values": [
+ "teacher",
+ "roleplay"
+ ]
+ }
+ },
+ "schemas": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/apps/api/src/storage/migrations/meta/_journal.json b/apps/api/src/storage/migrations/meta/_journal.json
index 48c03231df..998c10d7ba 100644
--- a/apps/api/src/storage/migrations/meta/_journal.json
+++ b/apps/api/src/storage/migrations/meta/_journal.json
@@ -1254,6 +1254,34 @@
"when": 1785309941472,
"tag": "0178_remove_category_archiving",
"breakpoints": true
+ },
+ {
+ "idx": 179,
+ "version": "7",
+ "when": 1785153121334,
+ "tag": "0179_add_ai_mentor_configuration_tables",
+ "breakpoints": true
+ },
+ {
+ "idx": 180,
+ "version": "7",
+ "when": 1785153140729,
+ "tag": "0180_enable_ai_mentor_configuration_rls",
+ "breakpoints": true
+ },
+ {
+ "idx": 181,
+ "version": "7",
+ "when": 1785153988477,
+ "tag": "0181_backfill_ai_mentor_configurations",
+ "breakpoints": true
+ },
+ {
+ "idx": 182,
+ "version": "7",
+ "when": 1785155002370,
+ "tag": "0182_drop_legacy_ai_mentor_configuration_columns",
+ "breakpoints": true
}
]
-}
\ No newline at end of file
+}
diff --git a/apps/api/src/storage/schema/index.ts b/apps/api/src/storage/schema/index.ts
index e9b19e04d4..05e1379db1 100644
--- a/apps/api/src/storage/schema/index.ts
+++ b/apps/api/src/storage/schema/index.ts
@@ -29,6 +29,9 @@ import {
MICROSOFT_CALENDAR_CONNECTION_STATUSES,
MICROSOFT_CALENDAR_OUTBOUND_STATUSES,
ANNOUNCEMENT_AUDIENCES,
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
} from "@repo/shared";
import { sql } from "drizzle-orm";
import {
@@ -113,6 +116,9 @@ import type {
OutlookEventAvailability,
OutlookEventSensitivity,
AnnouncementAudience,
+ AiMentorRoleplayDifficulty,
+ AiMentorTeachingStyle,
+ AiMentorType,
} from "@repo/shared";
import type { ActivityLogActionType, ActivityLogMetadata } from "src/activity-logs/types";
import type { AiJudgeCriterionStatus } from "src/ai/judge-configuration/judge-configuration.types";
@@ -916,13 +922,8 @@ export const aiMentorLessons = pgTable(
lessonId: uuid("lesson_id")
.references(() => lessons.id, { onDelete: "cascade" })
.notNull(),
- aiMentorInstructions: jsonb("ai_mentor_instructions")
- .$type()
- .default({})
- .notNull(),
name: jsonb("name").$type().default({}).notNull(),
avatarReference: varchar("avatar_reference", { length: 500 }),
- type: text("type").notNull().default("roleplay"),
voiceMode: text("voice_mode").notNull().default("preset"),
ttsPreset: text("tts_preset").notNull().default("male"),
customTtsReference: jsonb("custom_tts_reference"),
@@ -931,6 +932,79 @@ export const aiMentorLessons = pgTable(
withTenantIdIndex("ai_mentor_lessons"),
);
+export const structuredAiMentorTypeEnum = pgEnum(
+ "structured_ai_mentor_type",
+ Object.values(AI_MENTOR_TYPE) as [string, ...string[]],
+);
+export const aiMentorTeachingStyleEnum = pgEnum(
+ "ai_mentor_teaching_style",
+ Object.values(AI_MENTOR_TEACHING_STYLE) as [string, ...string[]],
+);
+export const aiMentorRoleplayDifficultyEnum = pgEnum(
+ "ai_mentor_roleplay_difficulty",
+ Object.values(AI_MENTOR_ROLEPLAY_DIFFICULTY) as [string, ...string[]],
+);
+
+export const aiMentorConfigurations = pgTable(
+ "ai_mentor_configurations",
+ {
+ ...id,
+ ...timestamps,
+ aiMentorLessonId: uuid("ai_mentor_lesson_id")
+ .references(() => aiMentorLessons.id, { onDelete: "cascade" })
+ .notNull()
+ .unique(),
+ type: structuredAiMentorTypeEnum("type").$type().notNull(),
+ openingInstruction: jsonb("opening_instruction").$type(),
+ additionalInstructions: jsonb("additional_instructions").$type(),
+ tenantId,
+ },
+ withTenantIdIndex("ai_mentor_configurations"),
+);
+
+export const aiMentorTeacherConfigurations = pgTable(
+ "ai_mentor_teacher_configurations",
+ {
+ ...id,
+ ...timestamps,
+ configurationId: uuid("configuration_id")
+ .references(() => aiMentorConfigurations.id, { onDelete: "cascade" })
+ .notNull()
+ .unique(),
+ taskGoal: jsonb("task_goal").$type().default({}).notNull(),
+ expertise: jsonb("expertise").$type().default({}).notNull(),
+ contentScope: jsonb("content_scope").$type().default({}).notNull(),
+ teachingStyle: aiMentorTeachingStyleEnum("teaching_style")
+ .$type()
+ .notNull(),
+ feedbackGuidance: jsonb("feedback_guidance").$type(),
+ tenantId,
+ },
+ withTenantIdIndex("ai_mentor_teacher_configurations"),
+);
+
+export const aiMentorRoleplayConfigurations = pgTable(
+ "ai_mentor_roleplay_configurations",
+ {
+ ...id,
+ ...timestamps,
+ configurationId: uuid("configuration_id")
+ .references(() => aiMentorConfigurations.id, { onDelete: "cascade" })
+ .notNull()
+ .unique(),
+ scenario: jsonb("scenario").$type().default({}).notNull(),
+ aiRole: jsonb("ai_role").$type().default({}).notNull(),
+ learnerRole: jsonb("learner_role").$type().default({}).notNull(),
+ characterGoal: jsonb("character_goal").$type().default({}).notNull(),
+ difficulty: aiMentorRoleplayDifficultyEnum("difficulty")
+ .$type()
+ .notNull(),
+ factsAndConstraints: jsonb("facts_and_constraints").$type(),
+ tenantId,
+ },
+ withTenantIdIndex("ai_mentor_roleplay_configurations"),
+);
+
export const aiMentorThreads = pgTable(
"ai_mentor_threads",
{
diff --git a/apps/api/src/swagger/api-schema.json b/apps/api/src/swagger/api-schema.json
index ddfe278cbe..9361be241c 100644
--- a/apps/api/src/swagger/api-schema.json
+++ b/apps/api/src/swagger/api-schema.json
@@ -703,6 +703,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -1591,6 +1595,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -1643,6 +1651,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -1840,6 +1852,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -2413,6 +2429,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -2473,6 +2493,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -2624,6 +2648,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -2736,6 +2764,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -2794,6 +2826,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -2928,6 +2964,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3118,6 +3158,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3292,6 +3336,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3421,6 +3469,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3621,6 +3673,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3804,6 +3860,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3872,6 +3932,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -3979,6 +4043,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -4039,6 +4107,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -4124,6 +4196,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -4185,6 +4261,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -4246,6 +4326,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5009,6 +5093,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5079,6 +5167,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5222,6 +5314,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5373,6 +5469,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5524,6 +5624,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5576,6 +5680,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5640,6 +5748,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5686,6 +5798,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -5750,6 +5866,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -6026,6 +6146,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -6219,6 +6343,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -6446,6 +6574,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -6507,6 +6639,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -7211,6 +7347,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -7306,6 +7446,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -7469,14 +7613,14 @@
}
}
},
- "/api/studentLessonProgress": {
- "post": {
- "operationId": "StudentLessonProgressController_markLessonAsCompleted",
+ "/api/lesson/{lessonId}/ai-mentor-configuration": {
+ "get": {
+ "operationId": "AiMentorConfigurationController_getAiMentorConfiguration",
"parameters": [
{
- "name": "id",
+ "name": "lessonId",
"required": true,
- "in": "query",
+ "in": "path",
"schema": {
"format": "uuid",
"type": "string"
@@ -7512,6 +7656,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -7522,7 +7670,42 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/MarkLessonAsCompletedResponse"
+ "$ref": "#/components/schemas/GetAiMentorConfigurationResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "put": {
+ "operationId": "AiMentorConfigurationController_replaceAiMentorConfiguration",
+ "parameters": [
+ {
+ "name": "lessonId",
+ "required": true,
+ "in": "path",
+ "schema": {
+ "format": "uuid",
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ReplaceAiMentorConfigurationBody"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ReplaceAiMentorConfigurationResponse"
}
}
}
@@ -7530,14 +7713,14 @@
}
}
},
- "/api/certificates/all": {
- "get": {
- "operationId": "CertificatesController_getAllCertificates",
+ "/api/lesson/{lessonId}/ai-mentor-configuration/translations/{language}": {
+ "patch": {
+ "operationId": "AiMentorConfigurationController_updateAiMentorConfigurationTranslations",
"parameters": [
{
- "name": "userId",
- "required": false,
- "in": "query",
+ "name": "lessonId",
+ "required": true,
+ "in": "path",
"schema": {
"format": "uuid",
"type": "string"
@@ -7545,8 +7728,8 @@
},
{
"name": "language",
- "required": false,
- "in": "query",
+ "required": true,
+ "in": "path",
"schema": {
"default": "en",
"anyOf": [
@@ -7573,33 +7756,87 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
- },
- {
- "name": "page",
- "required": false,
- "in": "query",
- "schema": {
- "minimum": 1,
- "type": "number"
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateAiMentorConfigurationTranslationsBody"
+ }
}
- },
+ }
+ },
+ "responses": {
+ "200": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateAiMentorConfigurationTranslationsResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/studentLessonProgress": {
+ "post": {
+ "operationId": "StudentLessonProgressController_markLessonAsCompleted",
+ "parameters": [
{
- "name": "perPage",
- "required": false,
+ "name": "id",
+ "required": true,
"in": "query",
"schema": {
- "type": "number"
+ "format": "uuid",
+ "type": "string"
}
},
{
- "name": "sort",
+ "name": "language",
"required": false,
"in": "query",
"schema": {
- "type": "string"
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
}
}
],
@@ -7608,7 +7845,7 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/GetAllCertificatesResponse"
+ "$ref": "#/components/schemas/MarkLessonAsCompletedResponse"
}
}
}
@@ -7616,9 +7853,9 @@
}
}
},
- "/api/certificates/certificate": {
+ "/api/certificates/all": {
"get": {
- "operationId": "CertificatesController_getCertificate",
+ "operationId": "CertificatesController_getAllCertificates",
"parameters": [
{
"name": "userId",
@@ -7629,15 +7866,6 @@
"type": "string"
}
},
- {
- "name": "courseId",
- "required": false,
- "in": "query",
- "schema": {
- "format": "uuid",
- "type": "string"
- }
- },
{
"name": "language",
"required": false,
@@ -7668,6 +7896,109 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ {
+ "name": "page",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "minimum": 1,
+ "type": "number"
+ }
+ },
+ {
+ "name": "perPage",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "number"
+ }
+ },
+ {
+ "name": "sort",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetAllCertificatesResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/certificates/certificate": {
+ "get": {
+ "operationId": "CertificatesController_getCertificate",
+ "parameters": [
+ {
+ "name": "userId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "format": "uuid",
+ "type": "string"
+ }
+ },
+ {
+ "name": "courseId",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "format": "uuid",
+ "type": "string"
+ }
+ },
+ {
+ "name": "language",
+ "required": false,
+ "in": "query",
+ "schema": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -7814,6 +8145,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -7901,6 +8236,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -8314,6 +8653,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -8375,6 +8718,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -8646,6 +8993,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -8726,6 +9077,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -8973,6 +9328,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9043,6 +9402,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9103,6 +9466,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9163,6 +9530,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9223,6 +9594,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9283,6 +9658,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9352,6 +9731,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9421,6 +9804,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9483,6 +9870,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -9664,6 +10055,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -10454,6 +10849,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -10539,6 +10938,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -10633,6 +11036,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -10691,6 +11098,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -11066,6 +11477,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -11159,6 +11574,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -11279,6 +11698,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -11857,6 +12280,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -12021,6 +12448,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -12073,6 +12504,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -12429,6 +12864,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -13321,6 +13760,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14429,6 +14872,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14488,6 +14935,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14563,6 +15014,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14649,6 +15104,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14704,6 +15163,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14750,6 +15213,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -14877,6 +15344,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15025,6 +15496,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15120,6 +15595,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15274,6 +15753,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15425,6 +15908,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15471,6 +15958,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15523,6 +16014,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15622,6 +16117,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15736,6 +16235,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -15862,6 +16365,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -16001,6 +16508,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -16071,6 +16582,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -16669,6 +17184,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -17563,6 +18082,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -18319,6 +18842,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18349,6 +18876,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -18426,6 +18957,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18479,6 +19014,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18553,6 +19092,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18601,6 +19144,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18665,6 +19212,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18718,6 +19269,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -18793,6 +19348,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -20894,6 +21453,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -20967,6 +21530,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -21352,6 +21919,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -21382,6 +21953,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -21497,6 +22072,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -21527,6 +22106,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -21629,6 +22212,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -21659,6 +22246,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -21947,6 +22538,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -23344,6 +23939,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -23592,6 +24191,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -23621,6 +24224,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -23781,6 +24388,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -23810,6 +24421,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -23945,6 +24560,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -23974,6 +24593,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -24118,6 +24741,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -24185,6 +24812,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -24240,6 +24871,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -24269,6 +24904,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -24413,212 +25052,12 @@
{
"const": "es",
"type": "string"
- }
- ]
- },
- "availableLocales": {
- "type": "array",
- "items": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- }
- },
- "createdAt": {
- "type": "string"
- },
- "updatedAt": {
- "type": "string"
- }
- },
- "required": [
- "id",
- "title",
- "description",
- "thumbnailReference",
- "status",
- "includesCertificate",
- "settings",
- "sequenceEnabled",
- "authorId",
- "baseLanguage",
- "availableLocales",
- "createdAt",
- "updatedAt"
- ]
- }
- },
- "required": [
- "data"
- ]
- },
- "DeleteLanguageResponse": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "title": {
- "type": "string"
- },
- "availableLocales": {
- "type": "array",
- "items": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- }
- },
- "baseLanguage": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
},
{
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- },
- "createdAt": {
- "anyOf": [
- {
+ "const": "fr",
"type": "string"
- },
- {
- "type": "null"
}
]
- }
- },
- "required": [
- "id",
- "title",
- "availableLocales",
- "baseLanguage",
- "createdAt"
- ]
- }
- },
- "required": [
- "data"
- ]
- },
- "UpdateBaseLanguageBody": {
- "type": "object",
- "properties": {
- "baseLanguage": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- }
- },
- "required": [
- "baseLanguage"
- ]
- },
- "UpdateBaseLanguageResponse": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "title": {
- "type": "string"
},
"availableLocales": {
"type": "array",
@@ -24647,6 +25086,86 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "title",
+ "description",
+ "thumbnailReference",
+ "status",
+ "includesCertificate",
+ "settings",
+ "sequenceEnabled",
+ "authorId",
+ "baseLanguage",
+ "availableLocales",
+ "createdAt",
+ "updatedAt"
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "DeleteLanguageResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -24676,6 +25195,154 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "createdAt": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "title",
+ "availableLocales",
+ "baseLanguage",
+ "createdAt"
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "UpdateBaseLanguageBody": {
+ "type": "object",
+ "properties": {
+ "baseLanguage": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "required": [
+ "baseLanguage"
+ ]
+ },
+ "UpdateBaseLanguageResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "baseLanguage": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -24826,6 +25493,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -24855,6 +25526,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -25703,6 +26378,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -25732,6 +26411,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -26550,6 +27233,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -26579,6 +27266,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -26933,6 +27624,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -26970,6 +27665,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -26993,25 +27692,6 @@
"format": "uuid",
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -27063,8 +27743,6 @@
"required": [
"id",
"lessonId",
- "aiMentorInstructions",
- "type",
"name",
"avatarReference",
"voiceMode",
@@ -27284,6 +27962,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -27313,6 +27995,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -27453,6 +28139,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -27732,6 +28422,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -30107,6 +30801,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -30144,6 +30842,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -30167,25 +30869,6 @@
"format": "uuid",
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -30237,8 +30920,6 @@
"required": [
"id",
"lessonId",
- "aiMentorInstructions",
- "type",
"name",
"avatarReference",
"voiceMode",
@@ -30614,6 +31295,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -30651,6 +31336,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -30674,25 +31363,6 @@
"format": "uuid",
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -30744,8 +31414,6 @@
"required": [
"id",
"lessonId",
- "aiMentorInstructions",
- "type",
"name",
"avatarReference",
"voiceMode",
@@ -30861,6 +31529,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -31351,6 +32023,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -31521,6 +32197,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -32658,6 +33338,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -32695,6 +33379,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -32718,25 +33406,6 @@
"format": "uuid",
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -32788,8 +33457,6 @@
"required": [
"id",
"lessonId",
- "aiMentorInstructions",
- "type",
"name",
"avatarReference",
"voiceMode",
@@ -32914,6 +33581,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -33105,6 +33776,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -33489,6 +34164,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -33526,6 +34205,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -33565,8 +34248,170 @@
"displayOrder": {
"type": "number"
},
- "aiMentorInstructions": {
- "type": "string"
+ "aiMentorConfiguration": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expertise": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "contentScope": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "aiRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "learnerRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "characterGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty"
+ ]
+ }
+ ]
},
"aiJudgeConfiguration": {
"additionalProperties": false,
@@ -33678,22 +34523,6 @@
"blockingErrors"
]
},
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -33734,9 +34563,8 @@
},
"required": [
"chapterId",
- "aiMentorInstructions",
- "aiJudgeConfiguration",
- "type"
+ "aiMentorConfiguration",
+ "aiJudgeConfiguration"
]
}
]
@@ -33981,6 +34809,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34018,6 +34850,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34050,25 +34886,6 @@
{
"type": "object",
"properties": {
- "aiMentorInstructions": {
- "type": "string"
- },
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -34106,11 +34923,7 @@
}
]
}
- },
- "required": [
- "aiMentorInstructions",
- "type"
- ]
+ }
}
]
},
@@ -34143,6 +34956,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34391,6 +35208,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34428,6 +35249,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34709,6 +35534,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34746,6 +35575,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -34801,6 +35634,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -35074,6 +35911,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -35111,6 +35952,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -35134,25 +35979,6 @@
"format": "uuid",
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "type": {
- "anyOf": [
- {
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
- },
- {
- "const": "roleplay",
- "type": "string"
- }
- ]
- },
"name": {
"type": "string"
},
@@ -35204,8 +36030,6 @@
"required": [
"id",
"lessonId",
- "aiMentorInstructions",
- "type",
"name",
"avatarReference",
"voiceMode",
@@ -35280,6 +36104,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -35422,6 +36250,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -35665,6 +36497,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -35871,6 +36707,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -35899,6 +36739,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -35929,6 +36773,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -36206,291 +37054,14 @@
{
"const": "es",
"type": "string"
- }
- ]
- },
- "baseLanguage": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
},
{
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
+ "const": "fr",
"type": "string"
}
]
},
- "availableLocales": {
- "type": "array",
- "items": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- }
- }
- },
- "required": [
- "id",
- "aiMentorLessonId",
- "hasMissingTranslations",
- "taskGoal",
- "passingThresholdPercent",
- "totalMaxScore",
- "criteria",
- "blockingErrors",
- "language",
- "baseLanguage",
- "availableLocales"
- ]
- }
- },
- "required": [
- "data"
- ]
- },
- "UpdateTranslationsBody": {
- "additionalProperties": false,
- "minProperties": 1,
- "type": "object",
- "properties": {
- "taskGoal": {
- "minLength": 1,
- "type": "string"
- },
- "criteria": {
- "type": "array",
- "items": {
- "additionalProperties": false,
- "minProperties": 2,
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "title": {
- "minLength": 1,
- "type": "string"
- },
- "expectedBehavior": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "id"
- ]
- }
- },
- "scoreGuidance": {
- "type": "array",
- "items": {
- "additionalProperties": false,
- "minProperties": 2,
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "description": {
- "minLength": 1,
- "type": "string"
- },
- "example": {
- "anyOf": [
- {
- "minLength": 1,
- "type": "string"
- },
- {
- "type": "null"
- }
- ]
- }
- },
- "required": [
- "id"
- ]
- }
- },
- "blockingErrors": {
- "type": "array",
- "items": {
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "description": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "id",
- "description"
- ]
- }
- }
- }
- },
- "UpdateTranslationsResponse": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "aiMentorLessonId": {
- "format": "uuid",
- "type": "string"
- },
- "hasMissingTranslations": {
- "type": "boolean"
- },
- "taskGoal": {
- "type": "string"
- },
- "passingThresholdPercent": {
- "minimum": 0,
- "maximum": 100,
- "type": "integer"
- },
- "totalMaxScore": {
- "minimum": 0,
- "type": "integer"
- },
- "criteria": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "title": {
- "type": "string"
- },
- "expectedBehavior": {
- "type": "string"
- },
- "maxScore": {
- "minimum": 1,
- "maximum": 5,
- "type": "integer"
- },
- "scoreGuidance": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "score": {
- "minimum": 0,
- "type": "integer"
- },
- "description": {
- "type": "string"
- },
- "example": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ]
- }
- },
- "required": [
- "id",
- "score",
- "description",
- "example"
- ]
- }
- }
- },
- "required": [
- "id",
- "title",
- "expectedBehavior",
- "maxScore",
- "scoreGuidance"
- ]
- }
- },
- "blockingErrors": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- },
- "required": [
- "id",
- "description"
- ]
- }
- },
- "language": {
+ "baseLanguage": {
"anyOf": [
{
"const": "en",
@@ -36515,6 +37086,299 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "hasMissingTranslations",
+ "taskGoal",
+ "passingThresholdPercent",
+ "totalMaxScore",
+ "criteria",
+ "blockingErrors",
+ "language",
+ "baseLanguage",
+ "availableLocales"
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "UpdateTranslationsBody": {
+ "additionalProperties": false,
+ "minProperties": 1,
+ "type": "object",
+ "properties": {
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "criteria": {
+ "type": "array",
+ "items": {
+ "additionalProperties": false,
+ "minProperties": 2,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "title": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expectedBehavior": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "id"
+ ]
+ }
+ },
+ "scoreGuidance": {
+ "type": "array",
+ "items": {
+ "additionalProperties": false,
+ "minProperties": 2,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "example": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id"
+ ]
+ }
+ },
+ "blockingErrors": {
+ "type": "array",
+ "items": {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "description"
+ ]
+ }
+ }
+ }
+ },
+ "UpdateTranslationsResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "taskGoal": {
+ "type": "string"
+ },
+ "passingThresholdPercent": {
+ "minimum": 0,
+ "maximum": 100,
+ "type": "integer"
+ },
+ "totalMaxScore": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "criteria": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "title": {
+ "type": "string"
+ },
+ "expectedBehavior": {
+ "type": "string"
+ },
+ "maxScore": {
+ "minimum": 1,
+ "maximum": 5,
+ "type": "integer"
+ },
+ "scoreGuidance": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "score": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "description": {
+ "type": "string"
+ },
+ "example": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "score",
+ "description",
+ "example"
+ ]
+ }
+ }
+ },
+ "required": [
+ "id",
+ "title",
+ "expectedBehavior",
+ "maxScore",
+ "scoreGuidance"
+ ]
+ }
+ },
+ "blockingErrors": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "description"
+ ]
+ }
+ },
+ "language": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -36543,6 +37407,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -36573,6 +37441,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -36621,29 +37493,172 @@
"taskDescription": {
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "aiMentorType": {
+ "aiMentorConfiguration": {
"anyOf": [
{
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expertise": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "contentScope": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle"
+ ]
},
{
- "const": "roleplay",
- "type": "string"
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "aiRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "learnerRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "characterGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty"
+ ]
}
]
}
- },
- "required": [
- "aiMentorType"
- ]
+ }
},
"mode": {
"const": "create",
@@ -36683,29 +37698,172 @@
"taskDescription": {
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "aiMentorType": {
+ "aiMentorConfiguration": {
"anyOf": [
{
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expertise": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "contentScope": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle"
+ ]
},
{
- "const": "roleplay",
- "type": "string"
- }
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "aiRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "learnerRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "characterGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty"
+ ]
+ }
]
}
- },
- "required": [
- "aiMentorType"
- ]
+ }
},
"mode": {
"const": "improve",
@@ -41587,29 +42745,172 @@
"taskDescription": {
"type": "string"
},
- "aiMentorInstructions": {
- "type": "string"
- },
- "aiMentorType": {
+ "aiMentorConfiguration": {
"anyOf": [
{
- "const": "mentor",
- "type": "string"
- },
- {
- "const": "teacher",
- "type": "string"
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expertise": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "contentScope": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle"
+ ]
},
{
- "const": "roleplay",
- "type": "string"
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "aiRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "learnerRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "characterGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty"
+ ]
}
]
}
- },
- "required": [
- "aiMentorType"
- ]
+ }
},
"brief": {
"minLength": 1,
@@ -41687,204 +42988,1731 @@
"description"
]
}
- }
+ }
+ },
+ "required": [
+ "title",
+ "expectedBehavior",
+ "maxScore",
+ "scoreGuidance"
+ ]
+ }
+ },
+ "blockingErrors": {
+ "type": "array",
+ "items": {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "description": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "description"
+ ]
+ }
+ }
+ },
+ "required": [
+ "taskGoal",
+ "passingThresholdPercent",
+ "criteria",
+ "blockingErrors"
+ ]
+ }
+ },
+ "required": [
+ "courseId",
+ "lessonContext",
+ "configuration"
+ ]
+ },
+ "ValidateConfigurationResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "passed": {
+ "type": "boolean"
+ },
+ "summary": {
+ "minLength": 1,
+ "maxLength": 180,
+ "type": "string"
+ },
+ "issues": {
+ "maxItems": 3,
+ "type": "array",
+ "items": {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "code": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "severity": {
+ "anyOf": [
+ {
+ "const": "error",
+ "type": "string"
+ },
+ {
+ "const": "warning",
+ "type": "string"
+ }
+ ]
+ },
+ "target": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "configuration",
+ "type": "string"
+ },
+ "field": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "type"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "criterion",
+ "type": "string"
+ },
+ "ref": {
+ "pattern": "^C[1-9][0-9]*$",
+ "type": "string"
+ },
+ "field": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "ref"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "scoreGuidance",
+ "type": "string"
+ },
+ "ref": {
+ "pattern": "^C[1-9][0-9]*$",
+ "type": "string"
+ },
+ "score": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "field": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "ref",
+ "score"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "blockingError",
+ "type": "string"
+ },
+ "ref": {
+ "pattern": "^B[1-9][0-9]*$",
+ "type": "string"
+ },
+ "field": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "ref"
+ ]
+ }
+ ]
+ },
+ "message": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "correction": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "code",
+ "severity",
+ "target",
+ "message",
+ "correction"
+ ]
+ }
+ }
+ },
+ "required": [
+ "passed",
+ "summary",
+ "issues"
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "GetAiMentorConfigurationResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "needsConfiguration": {
+ "type": "boolean"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "language": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "baseLanguage": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "type": "string"
+ },
+ "expertise": {
+ "type": "string"
+ },
+ "contentScope": {
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "needsConfiguration",
+ "hasMissingTranslations",
+ "language",
+ "baseLanguage",
+ "availableLocales",
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle",
+ "feedbackGuidance",
+ "openingInstruction",
+ "additionalInstructions"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "needsConfiguration": {
+ "type": "boolean"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "language": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "baseLanguage": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "type": "string"
+ },
+ "aiRole": {
+ "type": "string"
+ },
+ "learnerRole": {
+ "type": "string"
+ },
+ "characterGoal": {
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "needsConfiguration",
+ "hasMissingTranslations",
+ "language",
+ "baseLanguage",
+ "availableLocales",
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty",
+ "factsAndConstraints",
+ "openingInstruction",
+ "additionalInstructions"
+ ]
+ }
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "ReplaceAiMentorConfigurationBody": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expertise": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "contentScope": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "aiRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "learnerRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "characterGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty"
+ ]
+ }
+ ]
+ },
+ "ReplaceAiMentorConfigurationResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "needsConfiguration": {
+ "type": "boolean"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "language": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "baseLanguage": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "type": "string"
+ },
+ "expertise": {
+ "type": "string"
+ },
+ "contentScope": {
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "needsConfiguration",
+ "hasMissingTranslations",
+ "language",
+ "baseLanguage",
+ "availableLocales",
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle",
+ "feedbackGuidance",
+ "openingInstruction",
+ "additionalInstructions"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "needsConfiguration": {
+ "type": "boolean"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "language": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "baseLanguage": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "type": "string"
+ },
+ "aiRole": {
+ "type": "string"
+ },
+ "learnerRole": {
+ "type": "string"
+ },
+ "characterGoal": {
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "needsConfiguration",
+ "hasMissingTranslations",
+ "language",
+ "baseLanguage",
+ "availableLocales",
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty",
+ "factsAndConstraints",
+ "openingInstruction",
+ "additionalInstructions"
+ ]
+ }
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "UpdateAiMentorConfigurationTranslationsBody": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "minProperties": 2,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "expertise": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "contentScope": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "minProperties": 2,
+ "type": "object",
+ "properties": {
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "aiRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "learnerRole": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "characterGoal": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "type"
+ ]
+ }
+ ]
+ },
+ "UpdateAiMentorConfigurationTranslationsResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "needsConfiguration": {
+ "type": "boolean"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "language": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "baseLanguage": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "type": {
+ "const": "teacher",
+ "type": "string"
+ },
+ "taskGoal": {
+ "type": "string"
+ },
+ "expertise": {
+ "type": "string"
+ },
+ "contentScope": {
+ "type": "string"
+ },
+ "teachingStyle": {
+ "anyOf": [
+ {
+ "const": "explain_and_practice",
+ "type": "string"
+ },
+ {
+ "const": "guided_discovery",
+ "type": "string"
+ },
+ {
+ "const": "socratic",
+ "type": "string"
+ }
+ ]
+ },
+ "feedbackGuidance": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "needsConfiguration",
+ "hasMissingTranslations",
+ "language",
+ "baseLanguage",
+ "availableLocales",
+ "type",
+ "taskGoal",
+ "expertise",
+ "contentScope",
+ "teachingStyle",
+ "feedbackGuidance",
+ "openingInstruction",
+ "additionalInstructions"
+ ]
+ },
+ {
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "id": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "aiMentorLessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "needsConfiguration": {
+ "type": "boolean"
+ },
+ "hasMissingTranslations": {
+ "type": "boolean"
+ },
+ "language": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
},
- "required": [
- "title",
- "expectedBehavior",
- "maxScore",
- "scoreGuidance"
- ]
- }
- },
- "blockingErrors": {
- "type": "array",
- "items": {
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "id": {
- "format": "uuid",
- "type": "string"
- },
- "description": {
- "minLength": 1,
- "type": "string"
- }
+ "baseLanguage": {
+ "default": "en",
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
},
- "required": [
- "description"
- ]
- }
- }
- },
- "required": [
- "taskGoal",
- "passingThresholdPercent",
- "criteria",
- "blockingErrors"
- ]
- }
- },
- "required": [
- "courseId",
- "lessonContext",
- "configuration"
- ]
- },
- "ValidateConfigurationResponse": {
- "type": "object",
- "properties": {
- "data": {
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "passed": {
- "type": "boolean"
- },
- "summary": {
- "minLength": 1,
- "maxLength": 180,
- "type": "string"
- },
- "issues": {
- "maxItems": 3,
- "type": "array",
- "items": {
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "code": {
- "minLength": 1,
- "type": "string"
- },
- "severity": {
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "default": "en",
"anyOf": [
{
- "const": "error",
+ "const": "en",
"type": "string"
},
{
- "const": "warning",
+ "const": "pl",
"type": "string"
- }
- ]
- },
- "target": {
- "anyOf": [
+ },
{
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "type": {
- "const": "configuration",
- "type": "string"
- },
- "field": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "type"
- ]
+ "const": "de",
+ "type": "string"
},
{
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "type": {
- "const": "criterion",
- "type": "string"
- },
- "ref": {
- "pattern": "^C[1-9][0-9]*$",
- "type": "string"
- },
- "field": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "type",
- "ref"
- ]
+ "const": "lt",
+ "type": "string"
},
{
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "type": {
- "const": "scoreGuidance",
- "type": "string"
- },
- "ref": {
- "pattern": "^C[1-9][0-9]*$",
- "type": "string"
- },
- "score": {
- "minimum": 0,
- "type": "integer"
- },
- "field": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "type",
- "ref",
- "score"
- ]
+ "const": "cs",
+ "type": "string"
},
{
- "additionalProperties": false,
- "type": "object",
- "properties": {
- "type": {
- "const": "blockingError",
- "type": "string"
- },
- "ref": {
- "pattern": "^B[1-9][0-9]*$",
- "type": "string"
- },
- "field": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "type",
- "ref"
- ]
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
- },
- "message": {
- "minLength": 1,
- "type": "string"
- },
- "correction": {
- "minLength": 1,
- "type": "string"
}
},
- "required": [
- "code",
- "severity",
- "target",
- "message",
- "correction"
- ]
- }
+ "type": {
+ "const": "roleplay",
+ "type": "string"
+ },
+ "scenario": {
+ "type": "string"
+ },
+ "aiRole": {
+ "type": "string"
+ },
+ "learnerRole": {
+ "type": "string"
+ },
+ "characterGoal": {
+ "type": "string"
+ },
+ "difficulty": {
+ "anyOf": [
+ {
+ "const": "cooperative",
+ "type": "string"
+ },
+ {
+ "const": "realistic",
+ "type": "string"
+ },
+ {
+ "const": "challenging",
+ "type": "string"
+ }
+ ]
+ },
+ "factsAndConstraints": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "openingInstruction": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "additionalInstructions": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ }
+ },
+ "required": [
+ "id",
+ "aiMentorLessonId",
+ "needsConfiguration",
+ "hasMissingTranslations",
+ "language",
+ "baseLanguage",
+ "availableLocales",
+ "type",
+ "scenario",
+ "aiRole",
+ "learnerRole",
+ "characterGoal",
+ "difficulty",
+ "factsAndConstraints",
+ "openingInstruction",
+ "additionalInstructions"
+ ]
}
- },
- "required": [
- "passed",
- "summary",
- "issues"
]
}
},
@@ -42153,6 +44981,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -42474,6 +45306,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -43171,6 +46007,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -44043,6 +46883,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -44278,6 +47122,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -46294,6 +49142,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -46324,6 +49176,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -46545,180 +49401,196 @@
{
"const": "es",
"type": "string"
- }
- ]
- },
- "availableLocales": {
- "type": "array",
- "items": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- }
- },
- "deletedAt": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ]
- },
- "isRead": {
- "type": "boolean"
- }
- },
- "required": [
- "id",
- "createdAt",
- "updatedAt",
- "authorId",
- "audience",
- "status",
- "scheduledAt",
- "publishedAt",
- "sendEmail",
- "emailTemplate",
- "sourceType",
- "sourceId",
- "title",
- "content",
- "baseLanguage",
- "availableLocales",
- "deletedAt",
- "isRead"
- ]
- }
- },
- "pagination": {
- "type": "object",
- "properties": {
- "totalItems": {
- "type": "number"
- },
- "page": {
- "type": "number"
- },
- "perPage": {
- "type": "number"
- }
- },
- "required": [
- "totalItems",
- "page",
- "perPage"
- ]
- },
- "appliedFilters": {
- "type": "object",
- "patternProperties": {
- "^(.*)$": {}
- }
- }
- },
- "required": [
- "data",
- "pagination"
- ]
- },
- "CreateAnnouncementBody": {
- "type": "object",
- "properties": {
- "groupId": {
- "default": null,
- "anyOf": [
- {
- "format": "uuid",
- "type": "string"
- },
- {
- "type": "null"
- }
- ]
- },
- "baseLanguage": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
- "type": "string"
- }
- ]
- },
- "translations": {
- "minItems": 1,
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "language": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
- },
- {
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
},
{
- "const": "es",
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "availableLocales": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "deletedAt": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "isRead": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "id",
+ "createdAt",
+ "updatedAt",
+ "authorId",
+ "audience",
+ "status",
+ "scheduledAt",
+ "publishedAt",
+ "sendEmail",
+ "emailTemplate",
+ "sourceType",
+ "sourceId",
+ "title",
+ "content",
+ "baseLanguage",
+ "availableLocales",
+ "deletedAt",
+ "isRead"
+ ]
+ }
+ },
+ "pagination": {
+ "type": "object",
+ "properties": {
+ "totalItems": {
+ "type": "number"
+ },
+ "page": {
+ "type": "number"
+ },
+ "perPage": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "totalItems",
+ "page",
+ "perPage"
+ ]
+ },
+ "appliedFilters": {
+ "type": "object",
+ "patternProperties": {
+ "^(.*)$": {}
+ }
+ }
+ },
+ "required": [
+ "data",
+ "pagination"
+ ]
+ },
+ "CreateAnnouncementBody": {
+ "type": "object",
+ "properties": {
+ "groupId": {
+ "default": null,
+ "anyOf": [
+ {
+ "format": "uuid",
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "baseLanguage": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ },
+ "translations": {
+ "minItems": 1,
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "language": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
"type": "string"
}
]
@@ -46884,6 +49756,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -46914,6 +49790,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -47417,164 +50297,172 @@
{
"const": "es",
"type": "string"
- }
- ]
- }
- },
- "required": [
- "lessonId",
- "resourceEntityId",
- "durationSeconds",
- "watchedRanges"
- ]
- },
- "UpsertProgressResponse": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "properties": {
- "lessonId": {
- "format": "uuid",
- "type": "string"
- },
- "resourceEntityId": {
- "format": "uuid",
- "type": "string"
- },
- "durationSeconds": {
- "type": "number"
- },
- "bucketSizeSeconds": {
- "type": "number"
- },
- "coveredBucketCount": {
- "type": "number"
- },
- "coveragePercent": {
- "type": "number"
- },
- "watchedRanges": {
- "type": "array",
- "items": {
- "type": "array",
- "items": [
- {
- "minimum": 0,
- "type": "number"
- },
- {
- "minimum": 0,
- "type": "number"
- }
- ],
- "additionalItems": false,
- "minItems": 2,
- "maxItems": 2
- }
- },
- "isWatched": {
- "type": "boolean"
- },
- "watchedAt": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ]
- },
- "lessonCompleted": {
- "type": "boolean"
- }
- },
- "required": [
- "lessonId",
- "resourceEntityId",
- "durationSeconds",
- "bucketSizeSeconds",
- "coveredBucketCount",
- "coveragePercent",
- "watchedRanges",
- "isWatched",
- "watchedAt",
- "lessonCompleted"
- ]
- }
- },
- "required": [
- "data"
- ]
- },
- "CreatePaymentIntentResponse": {
- "type": "object",
- "properties": {
- "data": {
- "type": "object",
- "properties": {
- "clientSecret": {
- "type": "string"
- }
- },
- "required": [
- "clientSecret"
- ]
- }
- },
- "required": [
- "data"
- ]
- },
- "CreateCheckoutSessionBody": {
- "type": "object",
- "properties": {
- "amountInCents": {
- "type": "number"
- },
- "allowPromotionCode": {
- "type": "boolean"
- },
- "quantity": {
- "type": "number"
- },
- "productName": {
- "type": "string"
- },
- "productDescription": {
- "type": "string"
- },
- "courseId": {
- "type": "string"
- },
- "customerId": {
- "type": "string"
- },
- "locale": {
- "anyOf": [
- {
- "const": "en",
- "type": "string"
},
{
- "const": "pl",
- "type": "string"
- },
- {
- "const": "de",
- "type": "string"
- },
- {
- "const": "lt",
- "type": "string"
- },
- {
- "const": "cs",
- "type": "string"
- },
- {
- "const": "es",
+ "const": "fr",
+ "type": "string"
+ }
+ ]
+ }
+ },
+ "required": [
+ "lessonId",
+ "resourceEntityId",
+ "durationSeconds",
+ "watchedRanges"
+ ]
+ },
+ "UpsertProgressResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "properties": {
+ "lessonId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "resourceEntityId": {
+ "format": "uuid",
+ "type": "string"
+ },
+ "durationSeconds": {
+ "type": "number"
+ },
+ "bucketSizeSeconds": {
+ "type": "number"
+ },
+ "coveredBucketCount": {
+ "type": "number"
+ },
+ "coveragePercent": {
+ "type": "number"
+ },
+ "watchedRanges": {
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ {
+ "minimum": 0,
+ "type": "number"
+ },
+ {
+ "minimum": 0,
+ "type": "number"
+ }
+ ],
+ "additionalItems": false,
+ "minItems": 2,
+ "maxItems": 2
+ }
+ },
+ "isWatched": {
+ "type": "boolean"
+ },
+ "watchedAt": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "lessonCompleted": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "lessonId",
+ "resourceEntityId",
+ "durationSeconds",
+ "bucketSizeSeconds",
+ "coveredBucketCount",
+ "coveragePercent",
+ "watchedRanges",
+ "isWatched",
+ "watchedAt",
+ "lessonCompleted"
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "CreatePaymentIntentResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "object",
+ "properties": {
+ "clientSecret": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "clientSecret"
+ ]
+ }
+ },
+ "required": [
+ "data"
+ ]
+ },
+ "CreateCheckoutSessionBody": {
+ "type": "object",
+ "properties": {
+ "amountInCents": {
+ "type": "number"
+ },
+ "allowPromotionCode": {
+ "type": "boolean"
+ },
+ "quantity": {
+ "type": "number"
+ },
+ "productName": {
+ "type": "string"
+ },
+ "productDescription": {
+ "type": "string"
+ },
+ "courseId": {
+ "type": "string"
+ },
+ "customerId": {
+ "type": "string"
+ },
+ "locale": {
+ "anyOf": [
+ {
+ "const": "en",
+ "type": "string"
+ },
+ {
+ "const": "pl",
+ "type": "string"
+ },
+ {
+ "const": "de",
+ "type": "string"
+ },
+ {
+ "const": "lt",
+ "type": "string"
+ },
+ {
+ "const": "cs",
+ "type": "string"
+ },
+ {
+ "const": "es",
+ "type": "string"
+ },
+ {
+ "const": "fr",
"type": "string"
}
]
@@ -48345,6 +51233,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -48396,6 +51288,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -48425,6 +51321,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -48519,6 +51419,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -48548,6 +51452,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -48606,6 +51514,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -48674,6 +51586,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -48719,6 +51635,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -48748,6 +51668,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -50013,6 +52937,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -50043,6 +52971,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -50364,6 +53296,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -50394,6 +53330,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -50655,6 +53595,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -50839,6 +53783,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -50869,6 +53817,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -50929,6 +53881,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -51108,6 +54064,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -51138,6 +54098,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -52155,6 +55119,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -52258,6 +55226,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -52332,6 +55304,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -52650,6 +55626,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -52776,6 +55756,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -52938,6 +55922,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -53474,6 +56462,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -53503,6 +56495,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -54695,6 +57691,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -54725,6 +57725,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -54792,6 +57796,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -54822,6 +57830,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -54870,6 +57882,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -54963,6 +57979,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -54994,6 +58014,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -55283,6 +58307,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -55368,6 +58396,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -55399,6 +58431,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -55681,6 +58717,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -55712,6 +58752,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -55997,6 +59041,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -56057,6 +59105,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -56158,6 +59210,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -56285,6 +59341,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -56355,6 +59415,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -56386,6 +59450,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -56436,6 +59504,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -56499,6 +59571,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -56889,6 +59965,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -56920,6 +60000,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
}
@@ -57447,6 +60531,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -57512,6 +60600,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -57626,6 +60718,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
@@ -57695,6 +60791,10 @@
{
"const": "es",
"type": "string"
+ },
+ {
+ "const": "fr",
+ "type": "string"
}
]
},
diff --git a/apps/api/src/utils/types/test-types.ts b/apps/api/src/utils/types/test-types.ts
index 97f37f7c17..1998313033 100644
--- a/apps/api/src/utils/types/test-types.ts
+++ b/apps/api/src/utils/types/test-types.ts
@@ -59,7 +59,7 @@ const niceCourseData = Type.Intersect([
),
Type.Partial(
Type.Object({
- aiMentorInstructions: Type.String(),
+ additionalInstructions: Type.String(),
aiJudgeConfiguration: aiJudgeConfigurationInputSchema,
}),
),
diff --git a/apps/web/app/api/generated-api.ts b/apps/web/app/api/generated-api.ts
index 434e1dbb99..a04c7fa841 100644
--- a/apps/web/app/api/generated-api.ts
+++ b/apps/web/app/api/generated-api.ts
@@ -110,7 +110,7 @@ export interface RegisterBody {
*/
lastName: string;
password: string;
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
formAnswers?: object;
}
@@ -329,7 +329,7 @@ export interface CreatePasswordBody {
password: string;
/** @minLength 1 */
createToken: string;
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreatePasswordResponse {
@@ -496,8 +496,8 @@ export interface GetPublicRegistrationFormResponse {
type: "checkbox";
/** @minLength 1 */
label: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
required: boolean;
displayOrder: number;
archived: boolean;
@@ -510,13 +510,13 @@ export interface GetPublicRegistrationFormResponse {
export interface GetUserSettingsResponse {
data:
| {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
}
| {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
@@ -528,13 +528,13 @@ export interface GetUserSettingsResponse {
export type UpdateUserSettingsBody =
| {
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled?: boolean;
MFASecret?: string | null;
}
| {
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled?: boolean;
MFASecret?: string | null;
@@ -546,13 +546,13 @@ export type UpdateUserSettingsBody =
export interface UpdateUserSettingsResponse {
data:
| {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
}
| {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
@@ -564,7 +564,7 @@ export interface UpdateUserSettingsResponse {
export interface UpdateAdminNewUserNotificationResponse {
data: {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
@@ -973,7 +973,7 @@ export interface UpdateLearningPathsEnabledResponse {
export interface UpdateAdminFinishedCourseNotificationResponse {
data: {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
@@ -985,7 +985,7 @@ export interface UpdateAdminFinishedCourseNotificationResponse {
export interface UpdateAdminOverdueCourseNotificationResponse {
data: {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
@@ -1071,8 +1071,8 @@ export interface GetAdminRegistrationFormResponse {
/** @minLength 1 */
es?: string;
};
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
required: boolean;
displayOrder: number;
archived: boolean;
@@ -1101,8 +1101,8 @@ export interface UpdateRegistrationFormBody {
/** @minLength 1 */
es?: string;
};
- baseLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales?: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales?: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
required: boolean;
displayOrder: number;
archived: boolean;
@@ -1129,8 +1129,8 @@ export interface UpdateRegistrationFormResponse {
/** @minLength 1 */
es?: string;
};
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
required: boolean;
displayOrder: number;
archived: boolean;
@@ -1204,7 +1204,7 @@ export interface UpdateConfigWarningDismissedBody {
export interface UpdateConfigWarningDismissedResponse {
data: {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @default false */
isMFAEnabled: boolean;
MFASecret: string | null;
@@ -1529,7 +1529,7 @@ export interface CreateUserBody {
*/
lastName: string;
roleSlugs: string[];
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateUserResponse {
@@ -1589,8 +1589,8 @@ export interface GetAllGroupsResponse {
id: string;
name: string;
characteristic: string | null;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
users?: {
id: string;
createdAt: string;
@@ -1619,8 +1619,8 @@ export interface GetGroupByIdResponse {
id: string;
name: string;
characteristic: string | null;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
users?: {
id: string;
createdAt: string;
@@ -1643,8 +1643,8 @@ export interface GetUserGroupsResponse {
id: string;
name: string;
characteristic: string | null;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
users?: {
id: string;
createdAt: string;
@@ -1670,7 +1670,7 @@ export interface GetUserGroupsResponse {
export interface CreateGroupBody {
name: string;
characteristic?: string;
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateGroupResponse {
@@ -1684,7 +1684,7 @@ export interface CreateGroupResponse {
export interface UpdateGroupBody {
name?: string;
characteristic?: string;
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface UpdateGroupResponse {
@@ -1693,8 +1693,8 @@ export interface UpdateGroupResponse {
id: string;
name: string;
characteristic?: string | null;
- availableLocales?: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales?: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string;
updatedAt: string;
isMandatory?: boolean;
@@ -1720,8 +1720,8 @@ export interface CreateLanguageResponse {
sequenceEnabled: boolean;
/** @format uuid */
authorId: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
createdAt: string;
updatedAt: string;
};
@@ -1732,14 +1732,14 @@ export interface DeleteLanguageResponse {
/** @format uuid */
id: string;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string | null;
};
}
export interface UpdateBaseLanguageBody {
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface UpdateBaseLanguageResponse {
@@ -1747,8 +1747,8 @@ export interface UpdateBaseLanguageResponse {
/** @format uuid */
id: string;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string | null;
};
}
@@ -1781,8 +1781,8 @@ export interface GetGroupsByCourseResponse {
id: string;
name: string;
characteristic?: string | null;
- availableLocales?: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales?: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string;
updatedAt: string;
isMandatory?: boolean;
@@ -1941,8 +1941,8 @@ export interface GetAvailableCourseCategoriesResponse {
/** @format uuid */
id: string;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string | null;
}[];
pagination: {
@@ -2088,8 +2088,8 @@ export interface GetCourseResponse {
slug: string;
stripeProductId: string | null;
stripePriceId: string | null;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
dueDate: string | null;
};
}
@@ -2157,18 +2157,16 @@ export interface GetBetaCourseByIdResponse {
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
aiMentor?: {
/** @format uuid */
id: string;
/** @format uuid */
lessonId: string;
- aiMentorInstructions: string;
- type: "mentor" | "teacher" | "roleplay";
name: string;
avatarReference: string | null;
voiceMode: "preset" | "custom";
@@ -2207,8 +2205,8 @@ export interface GetBetaCourseByIdResponse {
thumbnailS3SingedUrl?: string | null;
trailerUrl?: string | null;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
sourceCourseId?: string | null;
sourceTenantId?: string | null;
};
@@ -2232,7 +2230,7 @@ export type CreateCourseBody = {
isScorm?: boolean;
hasCertificate?: boolean;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
} & {
chapters?: string[];
};
@@ -2298,7 +2296,7 @@ export interface UpdateCourseBody {
chapters?: string[];
archived?: boolean;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface UpdateCourseResponse {
@@ -2841,18 +2839,16 @@ export type BetaCreateChapterBody = {
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
aiMentor?: {
/** @format uuid */
id: string;
/** @format uuid */
lessonId: string;
- aiMentorInstructions: string;
- type: "mentor" | "teacher" | "roleplay";
name: string;
avatarReference: string | null;
voiceMode: "preset" | "custom";
@@ -2927,18 +2923,16 @@ export type UpdateChapterBody = ({
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
aiMentor?: {
/** @format uuid */
id: string;
/** @format uuid */
lessonId: string;
- aiMentorInstructions: string;
- type: "mentor" | "teacher" | "roleplay";
name: string;
avatarReference: string | null;
voiceMode: "preset" | "custom";
@@ -2960,7 +2954,7 @@ export type UpdateChapterBody = ({
courseId?: string;
}) & {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
};
export interface UpdateChapterResponse {
@@ -3060,7 +3054,7 @@ export interface GetLessonByIdResponse {
questionId?: string;
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
passQuestion: boolean | null;
}[];
questionCount: number;
@@ -3078,7 +3072,7 @@ export interface GetLessonByIdResponse {
displayOrder: number;
isExternal?: boolean;
nextLessonId: string | null;
- userLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ userLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
status?: "active" | "completed" | "archived";
/** @format uuid */
threadId?: string;
@@ -3261,18 +3255,16 @@ export type BetaCreateLessonBody = {
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
aiMentor?: {
/** @format uuid */
id: string;
/** @format uuid */
lessonId: string;
- aiMentorInstructions: string;
- type: "mentor" | "teacher" | "roleplay";
name: string;
avatarReference: string | null;
voiceMode: "preset" | "custom";
@@ -3306,7 +3298,7 @@ export interface BetaCreateLiveTrainingLessonBody {
/** @format uuid */
chapterId: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
displayOrder?: number;
contextId?: string;
liveTraining?: {
@@ -3361,7 +3353,7 @@ export interface AttachLiveTrainingLessonBody {
*/
title: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
liveTraining?: {
/**
* @minLength 1
@@ -3453,10 +3445,10 @@ export type BetaCreateAiMentorLessonBody = {
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
liveTrainingId?: string | null;
updatedAt?: string;
@@ -3464,7 +3456,35 @@ export type BetaCreateAiMentorLessonBody = {
/** @format uuid */
chapterId: string;
displayOrder?: number;
- aiMentorInstructions: string;
+ aiMentorConfiguration:
+ | {
+ type: "teacher";
+ /** @minLength 1 */
+ taskGoal: string;
+ /** @minLength 1 */
+ expertise: string;
+ /** @minLength 1 */
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ }
+ | {
+ type: "roleplay";
+ /** @minLength 1 */
+ scenario: string;
+ /** @minLength 1 */
+ aiRole: string;
+ /** @minLength 1 */
+ learnerRole: string;
+ /** @minLength 1 */
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ };
aiJudgeConfiguration: {
/** @minLength 1 */
taskGoal: string;
@@ -3503,7 +3523,6 @@ export type BetaCreateAiMentorLessonBody = {
description: string;
}[];
};
- type: "mentor" | "teacher" | "roleplay";
name?: string;
voiceMode?: "preset" | "custom";
ttsPreset?: "male" | "female";
@@ -3557,23 +3576,21 @@ export type BetaUpdateAiMentorLessonBody = ({
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
liveTrainingId?: string | null;
updatedAt?: string;
} & {
- aiMentorInstructions: string;
- type: "mentor" | "teacher" | "roleplay";
name?: string;
voiceMode?: "preset" | "custom";
ttsPreset?: "male" | "female";
customTtsReference?: string | null;
}) & {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
};
export interface BetaUpdateAiMentorLessonResponse {
@@ -3625,10 +3642,10 @@ export type BetaCreateQuizLessonBody = {
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
} & {
/** @format uuid */
@@ -3687,10 +3704,10 @@ export type BetaUpdateQuizLessonBody = ({
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
} & {
/** @format uuid */
@@ -3698,7 +3715,7 @@ export type BetaUpdateQuizLessonBody = ({
displayOrder?: number;
}) & {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
};
export interface BetaUpdateQuizLessonResponse {
@@ -3747,18 +3764,16 @@ export type BetaUpdateLessonBody = ({
matchedWord?: string | null;
scaleAnswer?: number | null;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}[];
aiMentor?: {
/** @format uuid */
id: string;
/** @format uuid */
lessonId: string;
- aiMentorInstructions: string;
- type: "mentor" | "teacher" | "roleplay";
name: string;
avatarReference: string | null;
voiceMode: "preset" | "custom";
@@ -3774,7 +3789,7 @@ export type BetaUpdateLessonBody = ({
contextId?: string;
}) & {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
};
export interface BetaUpdateLessonResponse {
@@ -3810,7 +3825,7 @@ export interface EvaluationQuizBody {
}
)[];
}[];
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface EvaluationQuizResponse {
@@ -3862,7 +3877,7 @@ export interface UpdateEmbedLessonBody {
/** @format uuid */
lessonId: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface UpdateEmbedLessonResponse {
@@ -3922,9 +3937,9 @@ export interface GetConfigurationResponse {
id: string;
description: string;
}[];
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
} | null;
}
@@ -4006,9 +4021,9 @@ export interface ReplaceConfigurationResponse {
id: string;
description: string;
}[];
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
};
}
@@ -4077,9 +4092,9 @@ export interface UpdateTranslationsResponse {
id: string;
description: string;
}[];
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
};
}
@@ -4092,8 +4107,35 @@ export type GenerateBody =
lessonContext: {
title?: string;
taskDescription?: string;
- aiMentorInstructions?: string;
- aiMentorType: "mentor" | "teacher" | "roleplay";
+ aiMentorConfiguration?:
+ | {
+ type: "teacher";
+ /** @minLength 1 */
+ taskGoal: string;
+ /** @minLength 1 */
+ expertise: string;
+ /** @minLength 1 */
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ }
+ | {
+ type: "roleplay";
+ /** @minLength 1 */
+ scenario: string;
+ /** @minLength 1 */
+ aiRole: string;
+ /** @minLength 1 */
+ learnerRole: string;
+ /** @minLength 1 */
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ };
};
mode: "create";
/** @minLength 1 */
@@ -4107,8 +4149,35 @@ export type GenerateBody =
lessonContext: {
title?: string;
taskDescription?: string;
- aiMentorInstructions?: string;
- aiMentorType: "mentor" | "teacher" | "roleplay";
+ aiMentorConfiguration?:
+ | {
+ type: "teacher";
+ /** @minLength 1 */
+ taskGoal: string;
+ /** @minLength 1 */
+ expertise: string;
+ /** @minLength 1 */
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ }
+ | {
+ type: "roleplay";
+ /** @minLength 1 */
+ scenario: string;
+ /** @minLength 1 */
+ aiRole: string;
+ /** @minLength 1 */
+ learnerRole: string;
+ /** @minLength 1 */
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ };
};
mode: "improve";
/** @minLength 1 */
@@ -5435,8 +5504,35 @@ export interface ValidateConfigurationBody {
lessonContext: {
title?: string;
taskDescription?: string;
- aiMentorInstructions?: string;
- aiMentorType: "mentor" | "teacher" | "roleplay";
+ aiMentorConfiguration?:
+ | {
+ type: "teacher";
+ /** @minLength 1 */
+ taskGoal: string;
+ /** @minLength 1 */
+ expertise: string;
+ /** @minLength 1 */
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ }
+ | {
+ type: "roleplay";
+ /** @minLength 1 */
+ scenario: string;
+ /** @minLength 1 */
+ aiRole: string;
+ /** @minLength 1 */
+ learnerRole: string;
+ /** @minLength 1 */
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ };
};
/** @minLength 1 */
brief?: string;
@@ -5530,6 +5626,205 @@ export interface ValidateConfigurationResponse {
};
}
+export interface GetAiMentorConfigurationResponse {
+ data:
+ | {
+ /** @format uuid */
+ id: string;
+ /** @format uuid */
+ aiMentorLessonId: string;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ /** @default "en" */
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ /** @default "en" */
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ type: "teacher";
+ taskGoal: string;
+ expertise: string;
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance: string | null;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ }
+ | {
+ /** @format uuid */
+ id: string;
+ /** @format uuid */
+ aiMentorLessonId: string;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ /** @default "en" */
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ /** @default "en" */
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ type: "roleplay";
+ scenario: string;
+ aiRole: string;
+ learnerRole: string;
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints: string | null;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ };
+}
+
+export type ReplaceAiMentorConfigurationBody =
+ | {
+ type: "teacher";
+ /** @minLength 1 */
+ taskGoal: string;
+ /** @minLength 1 */
+ expertise: string;
+ /** @minLength 1 */
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ }
+ | {
+ type: "roleplay";
+ /** @minLength 1 */
+ scenario: string;
+ /** @minLength 1 */
+ aiRole: string;
+ /** @minLength 1 */
+ learnerRole: string;
+ /** @minLength 1 */
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ };
+
+export interface ReplaceAiMentorConfigurationResponse {
+ data:
+ | {
+ /** @format uuid */
+ id: string;
+ /** @format uuid */
+ aiMentorLessonId: string;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ /** @default "en" */
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ /** @default "en" */
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ type: "teacher";
+ taskGoal: string;
+ expertise: string;
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance: string | null;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ }
+ | {
+ /** @format uuid */
+ id: string;
+ /** @format uuid */
+ aiMentorLessonId: string;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ /** @default "en" */
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ /** @default "en" */
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ type: "roleplay";
+ scenario: string;
+ aiRole: string;
+ learnerRole: string;
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints: string | null;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ };
+}
+
+export type UpdateAiMentorConfigurationTranslationsBody =
+ | {
+ type: "teacher";
+ /** @minLength 1 */
+ taskGoal?: string;
+ /** @minLength 1 */
+ expertise?: string;
+ /** @minLength 1 */
+ contentScope?: string;
+ feedbackGuidance?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ }
+ | {
+ type: "roleplay";
+ /** @minLength 1 */
+ scenario?: string;
+ /** @minLength 1 */
+ aiRole?: string;
+ /** @minLength 1 */
+ learnerRole?: string;
+ /** @minLength 1 */
+ characterGoal?: string;
+ factsAndConstraints?: string | null;
+ openingInstruction?: string | null;
+ additionalInstructions?: string | null;
+ };
+
+export interface UpdateAiMentorConfigurationTranslationsResponse {
+ data:
+ | {
+ /** @format uuid */
+ id: string;
+ /** @format uuid */
+ aiMentorLessonId: string;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ /** @default "en" */
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ /** @default "en" */
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ type: "teacher";
+ taskGoal: string;
+ expertise: string;
+ contentScope: string;
+ teachingStyle: "explain_and_practice" | "guided_discovery" | "socratic";
+ feedbackGuidance: string | null;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ }
+ | {
+ /** @format uuid */
+ id: string;
+ /** @format uuid */
+ aiMentorLessonId: string;
+ needsConfiguration: boolean;
+ hasMissingTranslations: boolean;
+ /** @default "en" */
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ /** @default "en" */
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ type: "roleplay";
+ scenario: string;
+ aiRole: string;
+ learnerRole: string;
+ characterGoal: string;
+ difficulty: "cooperative" | "realistic" | "challenging";
+ factsAndConstraints: string | null;
+ openingInstruction: string | null;
+ additionalInstructions: string | null;
+ };
+}
+
export interface MarkLessonAsCompletedResponse {
data: {
message: string;
@@ -5579,7 +5874,7 @@ export type GetCertificateResponse = {
export interface DownloadCertificateBody {
/** @format uuid */
certificateId: string;
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateCertificateShareLinkBody {
@@ -5662,7 +5957,7 @@ export interface GetThreadResponse {
aiMentorLessonId: string;
/** @format uuid */
userId: string;
- userLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ userLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string;
updatedAt: string;
status: "active" | "completed" | "archived";
@@ -5807,7 +6102,7 @@ export interface UploadAssetBody {
/** @format uuid */
contextId?: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title: string;
description: string;
}
@@ -5955,7 +6250,7 @@ export interface GetLiveTrainingResponse {
export interface CreateLiveTrainingBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/**
* @minLength 1
* @maxLength 120
@@ -6007,7 +6302,7 @@ export interface GetHostCandidatesResponse {
export type UpdateLiveTrainingBody = {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
} & {
/**
* @minLength 1
@@ -6335,8 +6630,8 @@ export interface GetAllAnnouncementsResponse {
sourceId: string | null;
title: string;
content: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
deletedAt: string | null;
isRead: boolean | null;
}[];
@@ -6370,8 +6665,8 @@ export interface GetAnnouncementsForUserResponse {
sourceId: string | null;
title: string;
content: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
deletedAt: string | null;
isRead: boolean;
}[];
@@ -6386,10 +6681,10 @@ export interface GetAnnouncementsForUserResponse {
export interface CreateAnnouncementBody {
/** @default null */
groupId: string | null;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @minItems 1 */
translations: {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/**
* @minLength 1
* @maxLength 120
@@ -6419,8 +6714,8 @@ export interface CreateAnnouncementResponse {
sourceId: string | null;
title: string;
content: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
deletedAt: string | null;
};
}
@@ -6541,7 +6836,7 @@ export interface UpsertProgressBody {
*/
activeWatchSecondsDelta?: number;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface UpsertProgressResponse {
@@ -6575,7 +6870,7 @@ export interface CreateCheckoutSessionBody {
productDescription?: string;
courseId: string;
customerId: string;
- locale: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ locale: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
priceId: string;
}
@@ -6715,7 +7010,7 @@ export interface PrepareAiMentorStatisticsProgressBody {
/** @format uuid */
studentId: string;
/** @default "en" */
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface GetAllCategoriesResponse {
@@ -6723,8 +7018,8 @@ export interface GetAllCategoriesResponse {
/** @format uuid */
id: string;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string | null;
}[];
pagination: {
@@ -6740,15 +7035,15 @@ export interface GetCategoryByIdResponse {
/** @format uuid */
id: string;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string | null;
};
}
export interface CreateCategoryBody {
title: string;
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateCategoryResponse {
@@ -6763,7 +7058,7 @@ export interface UpdateCategoryBody {
/** @format uuid */
id?: string;
title?: string;
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface UpdateCategoryResponse {
@@ -6771,8 +7066,8 @@ export interface UpdateCategoryResponse {
/** @format uuid */
id: string;
title: string;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
createdAt: string | null;
};
}
@@ -7059,8 +7354,8 @@ export interface GetLearningPathsResponse {
sequenceEnabled: boolean;
/** @format uuid */
authorId: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
createdAt: string;
updatedAt: string;
} & {
@@ -7114,8 +7409,8 @@ export interface GetLearningPathByIdResponse {
sequenceEnabled: boolean;
/** @format uuid */
authorId: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
createdAt: string;
updatedAt: string;
} & {
@@ -7155,7 +7450,7 @@ export interface GetLearningPathByIdResponse {
}
export interface CreateLearningPathBody {
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title: string;
description: string;
thumbnailReference?: string | null;
@@ -7190,15 +7485,15 @@ export interface CreateLearningPathResponse {
sequenceEnabled: boolean;
/** @format uuid */
authorId: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
createdAt: string;
updatedAt: string;
};
}
export interface UpdateLearningPathBody {
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title?: string;
description?: string;
thumbnailReference?: string | null;
@@ -7233,8 +7528,8 @@ export interface UpdateLearningPathResponse {
sequenceEnabled: boolean;
/** @format uuid */
authorId: string;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
createdAt: string;
updatedAt: string;
};
@@ -7487,7 +7782,7 @@ export type InitScormImportBody =
/** @format uuid */
categoryId: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
status?: "draft" | "published" | "private";
thumbnailS3Key?: string;
priceInCents?: number;
@@ -7508,7 +7803,7 @@ export type InitScormImportBody =
chapterId: string;
title: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
};
}
| {
@@ -7524,7 +7819,7 @@ export type InitScormImportBody =
metadata: {
title: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
};
};
@@ -7611,7 +7906,7 @@ export interface CommitScormAttemptBody {
/** @format uuid */
courseId: string;
values: object;
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CommitScormAttemptResponse {
@@ -7636,7 +7931,7 @@ export interface FinishScormAttemptBody {
/** @format uuid */
courseId: string;
values: object;
- language?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface FinishScormAttemptResponse {
@@ -7670,7 +7965,7 @@ export interface CreateTenantBody {
adminFirstName: string;
/** @minLength 1 */
adminLastName: string;
- adminLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ adminLanguage?: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateTenantResponse {
@@ -7785,8 +8080,8 @@ export interface GetGroupsResponse {
id: string;
name: string;
characteristic: string | null;
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
users?: {
id: string;
createdAt: string;
@@ -8070,8 +8365,8 @@ export interface GetQAResponse {
id: string;
title: string | null;
description: string | null;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
}
export type GetAllQAResponse = {
@@ -8079,14 +8374,14 @@ export type GetAllQAResponse = {
id: string;
title: string | null;
description: string | null;
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
}[];
export interface CreateQABody {
title: string;
description: string;
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateQAResponse {
@@ -8110,8 +8405,8 @@ export interface GetDraftNewsListResponse {
status: string;
isPublic: boolean;
/** @default "en" */
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
publishedAt: string | null;
authorName: string;
resources?: {
@@ -8169,7 +8464,7 @@ export interface GenerateNewsPreviewBody {
/** @format uuid */
newsId: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
content: string;
}
@@ -8189,8 +8484,8 @@ export interface GetNewsResponse {
status: string;
isPublic: boolean;
/** @default "en" */
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
publishedAt: string | null;
authorName: string;
resources?: {
@@ -8247,8 +8542,8 @@ export interface GetNewsListResponse {
status: string;
isPublic: boolean;
/** @default "en" */
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
publishedAt: string | null;
authorName: string;
resources?: {
@@ -8304,7 +8599,7 @@ export interface GetNewsListResponse {
export interface CreateNewsBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateNewsResponse {
@@ -8316,7 +8611,7 @@ export interface CreateNewsResponse {
export interface UpdateNewsBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title?: string;
summary?: string;
content?: string;
@@ -8338,7 +8633,7 @@ export interface UpdateNewsResponse {
export interface AddNewLanguageBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface AddNewLanguageResponse {
@@ -8372,7 +8667,7 @@ export interface UploadFileToNewsResponse {
export interface CreateArticleSectionBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface CreateArticleSectionResponse {
@@ -8388,15 +8683,15 @@ export interface GetArticleSectionResponse {
id: string;
title: string;
/** @default "en" */
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
assignedArticlesCount: number;
};
}
export interface UpdateArticleSectionBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title?: string;
}
@@ -8409,7 +8704,7 @@ export interface UpdateArticleSectionResponse {
export interface AddNewLanguageToSectionBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
}
export interface AddNewLanguageToSectionResponse {
@@ -8501,8 +8796,8 @@ export interface GetArticleResponse {
status: string;
isPublic: boolean;
/** @default "en" */
- baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es";
- availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es")[];
+ baseLanguage: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
+ availableLocales: ("en" | "pl" | "de" | "lt" | "cs" | "es" | "fr")[];
publishedAt: string | null;
authorName: string;
/** @format uuid */
@@ -8615,7 +8910,7 @@ export type GetArticlesResponse = {
export interface CreateArticleBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
/** @format uuid */
sectionId: string;
}
@@ -8629,7 +8924,7 @@ export interface CreateArticleResponse {
export interface UpdateArticleBody {
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title?: string;
summary?: string;
content?: string;
@@ -8656,7 +8951,7 @@ export interface UploadFileToArticleBody {
*/
file?: File;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
title: string;
description: string;
}
@@ -8672,7 +8967,7 @@ export interface GenerateArticlePreviewBody {
/** @format uuid */
articleId: string;
/** @default "en" */
- language: "en" | "pl" | "de" | "lt" | "cs" | "es";
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr";
content: string;
}
@@ -9552,7 +9847,7 @@ export class API extends HttpClient
@@ -10224,7 +10519,7 @@ export class API extends HttpClient
@@ -10245,7 +10540,7 @@ export class API extends HttpClient
@@ -10319,7 +10614,7 @@ export class API extends HttpClient
@@ -10681,7 +10976,7 @@ export class API extends HttpClient
@@ -10702,7 +10997,7 @@ export class API extends HttpClient
@@ -10762,7 +11057,7 @@ export class API extends HttpClient
@@ -10815,7 +11110,7 @@ export class API extends HttpClient
@@ -10836,7 +11131,7 @@ export class API extends HttpClient
@@ -10901,7 +11196,7 @@ export class API extends HttpClient
@@ -10944,7 +11239,7 @@ export class API extends HttpClient
@@ -10987,7 +11282,7 @@ export class API extends HttpClient
@@ -11022,7 +11317,7 @@ export class API extends HttpClient extends HttpClient
@@ -11115,7 +11410,7 @@ export class API extends HttpClient
@@ -11138,7 +11433,7 @@ export class API extends HttpClient
@@ -11166,7 +11461,7 @@ export class API extends HttpClient
@@ -11188,7 +11483,7 @@ export class API extends HttpClient
@@ -11226,7 +11521,7 @@ export class API extends HttpClient
@@ -11249,7 +11544,7 @@ export class API extends HttpClient
@@ -11272,7 +11567,7 @@ export class API extends HttpClient
@@ -11665,7 +11960,7 @@ export class API extends HttpClient
@@ -11689,7 +11984,7 @@ export class API extends HttpClient
@@ -11727,7 +12022,7 @@ export class API extends HttpClient
@@ -11766,7 +12061,7 @@ export class API extends HttpClient
@@ -11805,7 +12100,7 @@ export class API extends HttpClient
@@ -11827,7 +12122,7 @@ export class API extends HttpClient
@@ -11848,7 +12143,7 @@ export class API extends HttpClient
@@ -11869,7 +12164,7 @@ export class API extends HttpClient
@@ -11890,7 +12185,7 @@ export class API extends HttpClient
@@ -12049,7 +12344,7 @@ export class API extends HttpClient
@@ -12159,7 +12454,7 @@ export class API extends HttpClient
@@ -12287,7 +12582,7 @@ export class API extends HttpClient
@@ -12309,7 +12604,7 @@ export class API extends HttpClient extends HttpClient
@@ -12764,7 +13059,7 @@ export class API extends HttpClient
@@ -12866,6 +13161,69 @@ export class API extends HttpClient
+ this.request({
+ path: `/api/lesson/${lessonId}/ai-mentor-configuration`,
+ method: "GET",
+ query: query,
+ format: "json",
+ ...params,
+ }),
+
+ /**
+ * No description
+ *
+ * @name AiMentorConfigurationControllerReplaceAiMentorConfiguration
+ * @request PUT:/api/lesson/{lessonId}/ai-mentor-configuration
+ */
+ aiMentorConfigurationControllerReplaceAiMentorConfiguration: (
+ lessonId: string,
+ data: ReplaceAiMentorConfigurationBody,
+ params: RequestParams = {},
+ ) =>
+ this.request({
+ path: `/api/lesson/${lessonId}/ai-mentor-configuration`,
+ method: "PUT",
+ body: data,
+ type: ContentType.Json,
+ format: "json",
+ ...params,
+ }),
+
+ /**
+ * No description
+ *
+ * @name AiMentorConfigurationControllerUpdateAiMentorConfigurationTranslations
+ * @request PATCH:/api/lesson/{lessonId}/ai-mentor-configuration/translations/{language}
+ */
+ aiMentorConfigurationControllerUpdateAiMentorConfigurationTranslations: (
+ lessonId: string,
+ language: "en" | "pl" | "de" | "lt" | "cs" | "es" | "fr",
+ data: UpdateAiMentorConfigurationTranslationsBody,
+ params: RequestParams = {},
+ ) =>
+ this.request({
+ path: `/api/lesson/${lessonId}/ai-mentor-configuration/translations/${language}`,
+ method: "PATCH",
+ body: data,
+ type: ContentType.Json,
+ format: "json",
+ ...params,
+ }),
+
/**
* No description
*
@@ -12877,7 +13235,7 @@ export class API extends HttpClient
@@ -12900,7 +13258,7 @@ export class API extends HttpClient extends HttpClient
@@ -13008,7 +13366,7 @@ export class API extends HttpClient
@@ -13035,7 +13393,7 @@ export class API extends HttpClient
@@ -13258,7 +13616,7 @@ export class API extends HttpClient
@@ -13280,7 +13638,7 @@ export class API extends HttpClient
@@ -13383,7 +13741,7 @@ export class API extends HttpClient
@@ -13423,7 +13781,7 @@ export class API extends HttpClient
@@ -13532,7 +13890,7 @@ export class API extends HttpClient
@@ -13555,7 +13913,7 @@ export class API extends HttpClient
@@ -13576,7 +13934,7 @@ export class API extends HttpClient
@@ -13597,7 +13955,7 @@ export class API extends HttpClient
@@ -13618,7 +13976,7 @@ export class API extends HttpClient
@@ -13639,7 +13997,7 @@ export class API extends HttpClient
@@ -13661,7 +14019,7 @@ export class API extends HttpClient
@@ -13683,7 +14041,7 @@ export class API extends HttpClient
@@ -13716,7 +14074,7 @@ export class API extends HttpClient extends HttpClient extends HttpClient
@@ -14270,7 +14628,7 @@ export class API extends HttpClient
@@ -14311,7 +14669,7 @@ export class API extends HttpClient
@@ -14332,7 +14690,7 @@ export class API extends HttpClient
@@ -14524,7 +14882,7 @@ export class API extends HttpClient extends HttpClient
@@ -14623,7 +14981,7 @@ export class API extends HttpClient
@@ -14910,7 +15268,7 @@ export class API extends HttpClient
@@ -15009,7 +15367,7 @@ export class API extends HttpClient
@@ -15030,7 +15388,7 @@ export class API extends HttpClient
@@ -15232,7 +15590,7 @@ export class API extends HttpClient extends HttpClient
@@ -15921,7 +16279,7 @@ export class API extends HttpClient
@@ -15944,7 +16302,7 @@ export class API extends HttpClient
@@ -15979,7 +16337,7 @@ export class API extends HttpClient
@@ -16017,7 +16375,7 @@ export class API extends HttpClient
@@ -16038,7 +16396,7 @@ export class API extends HttpClient
@@ -16058,7 +16416,7 @@ export class API extends HttpClient extends HttpClient
@@ -16193,7 +16551,7 @@ export class API extends HttpClient extends HttpClient
@@ -16300,7 +16658,7 @@ export class API extends HttpClient
@@ -16376,7 +16734,7 @@ export class API extends HttpClient
@@ -16396,7 +16754,7 @@ export class API extends HttpClient
@@ -16417,7 +16775,7 @@ export class API extends HttpClient extends HttpClient extends HttpClient
@@ -16574,7 +16932,7 @@ export class API extends HttpClient
@@ -16650,7 +17008,7 @@ export class API extends HttpClient extends HttpClient
diff --git a/apps/web/app/api/mutations/admin/useReplaceAiMentorConfiguration.ts b/apps/web/app/api/mutations/admin/useReplaceAiMentorConfiguration.ts
new file mode 100644
index 0000000000..16735604b0
--- /dev/null
+++ b/apps/web/app/api/mutations/admin/useReplaceAiMentorConfiguration.ts
@@ -0,0 +1,47 @@
+import { useMutation } from "@tanstack/react-query";
+import { useTranslation } from "react-i18next";
+
+import { ApiClient } from "~/api/api-client";
+import { AI_MENTOR_CONFIGURATION_QUERY_KEY } from "~/api/queries/admin/useAiMentorConfiguration";
+import { queryClient } from "~/api/queryClient";
+import { getTranslatedApiErrorMessage } from "~/api/utils/getTranslatedApiErrorMessage";
+import { useToast } from "~/components/ui/use-toast";
+
+import type { ReplaceAiMentorConfigurationBody } from "~/api/generated-api";
+
+type ReplaceAiMentorConfigurationOptions = {
+ lessonId: string;
+ data: ReplaceAiMentorConfigurationBody;
+};
+
+export const useReplaceAiMentorConfiguration = () => {
+ const { t } = useTranslation();
+ const { toast } = useToast();
+
+ return useMutation({
+ mutationFn: async ({ lessonId, data }: ReplaceAiMentorConfigurationOptions) => {
+ const response =
+ await ApiClient.api.aiMentorConfigurationControllerReplaceAiMentorConfiguration(
+ lessonId,
+ data,
+ );
+ return response.data.data;
+ },
+ onSuccess: async (_configuration, { lessonId }) => {
+ await queryClient.invalidateQueries({
+ queryKey: [...AI_MENTOR_CONFIGURATION_QUERY_KEY, lessonId],
+ });
+ toast({
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.configurationSaved",
+ ),
+ });
+ },
+ onError: (error) => {
+ toast({
+ description: getTranslatedApiErrorMessage(error, t, t("common.toast.somethingWentWrong")),
+ variant: "destructive",
+ });
+ },
+ });
+};
diff --git a/apps/web/app/api/mutations/admin/useUpdateAiMentorConfigurationTranslation.ts b/apps/web/app/api/mutations/admin/useUpdateAiMentorConfigurationTranslation.ts
new file mode 100644
index 0000000000..c1663e2437
--- /dev/null
+++ b/apps/web/app/api/mutations/admin/useUpdateAiMentorConfigurationTranslation.ts
@@ -0,0 +1,59 @@
+import { useMutation } from "@tanstack/react-query";
+import { useTranslation } from "react-i18next";
+
+import { ApiClient } from "~/api/api-client";
+import { AI_MENTOR_CONFIGURATION_QUERY_KEY } from "~/api/queries/admin/useAiMentorConfiguration";
+import { COURSE_TRANSLATIONS_QUERY_KEY } from "~/api/queries/admin/useHasMissingTranslations";
+import { queryClient } from "~/api/queryClient";
+import { getTranslatedApiErrorMessage } from "~/api/utils/getTranslatedApiErrorMessage";
+import { useToast } from "~/components/ui/use-toast";
+
+import type { SupportedLanguages } from "@repo/shared";
+import type { UpdateAiMentorConfigurationTranslationsBody } from "~/api/generated-api";
+
+type UpdateAiMentorConfigurationTranslationOptions = {
+ courseId: string;
+ lessonId: string;
+ language: SupportedLanguages;
+ data: UpdateAiMentorConfigurationTranslationsBody;
+};
+
+export const useUpdateAiMentorConfigurationTranslation = () => {
+ const { t } = useTranslation();
+ const { toast } = useToast();
+
+ return useMutation({
+ mutationFn: async ({
+ lessonId,
+ language,
+ data,
+ }: UpdateAiMentorConfigurationTranslationOptions) => {
+ const response =
+ await ApiClient.api.aiMentorConfigurationControllerUpdateAiMentorConfigurationTranslations(
+ lessonId,
+ language,
+ data,
+ );
+ return response.data.data;
+ },
+ onSuccess: async (_configuration, { courseId, language, lessonId }) => {
+ await Promise.all([
+ queryClient.invalidateQueries({
+ queryKey: [...AI_MENTOR_CONFIGURATION_QUERY_KEY, lessonId],
+ }),
+ queryClient.invalidateQueries({
+ queryKey: [COURSE_TRANSLATIONS_QUERY_KEY, { id: courseId, language }],
+ }),
+ ]);
+ toast({
+ description: t("adminCourseView.curriculum.lesson.aiMentorConfiguration.translationSaved"),
+ });
+ },
+ onError: (error) => {
+ toast({
+ description: getTranslatedApiErrorMessage(error, t, t("common.toast.somethingWentWrong")),
+ variant: "destructive",
+ });
+ },
+ });
+};
diff --git a/apps/web/app/api/queries/admin/useAiMentorConfiguration.ts b/apps/web/app/api/queries/admin/useAiMentorConfiguration.ts
new file mode 100644
index 0000000000..637e4f9b2b
--- /dev/null
+++ b/apps/web/app/api/queries/admin/useAiMentorConfiguration.ts
@@ -0,0 +1,27 @@
+import { queryOptions, useQuery } from "@tanstack/react-query";
+
+import { ApiClient } from "~/api/api-client";
+
+import type { SupportedLanguages } from "@repo/shared";
+import type { GetAiMentorConfigurationResponse } from "~/api/generated-api";
+
+export const AI_MENTOR_CONFIGURATION_QUERY_KEY = ["ai-mentor-configuration"] as const;
+
+export const aiMentorConfigurationQueryOptions = (lessonId: string, language: SupportedLanguages) =>
+ queryOptions({
+ enabled: Boolean(lessonId),
+ queryKey: [...AI_MENTOR_CONFIGURATION_QUERY_KEY, lessonId, language],
+ queryFn: async () => {
+ const response = await ApiClient.api.aiMentorConfigurationControllerGetAiMentorConfiguration(
+ lessonId,
+ {
+ language,
+ },
+ );
+ return response.data;
+ },
+ select: (response: GetAiMentorConfigurationResponse) => response.data,
+ });
+
+export const useAiMentorConfiguration = (lessonId: string, language: SupportedLanguages) =>
+ useQuery(aiMentorConfigurationQueryOptions(lessonId, language));
diff --git a/apps/web/app/components/ui/dialog.tsx b/apps/web/app/components/ui/dialog.tsx
index cc019b707f..e9bd490860 100644
--- a/apps/web/app/components/ui/dialog.tsx
+++ b/apps/web/app/components/ui/dialog.tsx
@@ -49,10 +49,11 @@ const DialogContent = React.forwardRef<
React.ComponentPropsWithoutRef &
VariantProps & {
noCloseButton?: boolean;
+ overlayClassName?: string;
}
->(({ className, children, noCloseButton = false, variant, ...props }, ref) => (
+>(({ className, children, noCloseButton = false, overlayClassName, variant, ...props }, ref) => (
-
+
language="en"
baseLanguage="en"
isPersisted={false}
+ isAiMentorConfigured
onConfigureWithAi={vi.fn()}
{...props}
/>
@@ -87,6 +88,22 @@ describe("AiJudgeConfigurationCard", () => {
expect(onConfigureWithAi).not.toHaveBeenCalled();
});
+ it("blocks AI creation until AI Mentor behavior is configured", async () => {
+ const user = userEvent.setup();
+ const onConfigureWithAi = vi.fn();
+ renderCard({ isAiMentorConfigured: false, onConfigureWithAi });
+
+ const aiAction = screen.getByRole("button", { name: "Create with AI" });
+ expect(aiAction).toBeDisabled();
+
+ await user.hover(aiAction.parentElement!);
+ const tooltipCopies = await screen.findAllByText(
+ "Configure AI Mentor behavior before creating completion conditions with AI.",
+ );
+ expect(tooltipCopies.some((element) => element.getAttribute("role") !== "tooltip")).toBe(true);
+ expect(onConfigureWithAi).not.toHaveBeenCalled();
+ });
+
it("keeps AI creation visible but disabled outside the base language", async () => {
const user = userEvent.setup();
renderCard({ language: "pl", baseLanguage: "en" });
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiJudge/AiJudgeConfigurationCard.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiJudge/AiJudgeConfigurationCard.tsx
index e279e56d7c..2220f94219 100644
--- a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiJudge/AiJudgeConfigurationCard.tsx
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiJudge/AiJudgeConfigurationCard.tsx
@@ -26,6 +26,7 @@ type AiJudgeConfigurationCardBaseProps = {
isPersisted: boolean;
isLoading?: boolean;
isSaving?: boolean;
+ isAiMentorConfigured: boolean;
onConfigureWithAi?: (mode: AiJudgeGenerationMode) => void;
onValidateConfiguration?: (value: AiJudgeConfigurationDraft) => Promise;
onImproveWithAi?: (
@@ -57,6 +58,7 @@ export const AiJudgeConfigurationCard = ({
isPersisted,
isLoading = false,
isSaving = false,
+ isAiMentorConfigured,
onConfigureWithAi,
editorOpen,
onEditorOpenChange,
@@ -79,7 +81,14 @@ export const AiJudgeConfigurationCard = ({
const editorButtonLabelKey = isConfigured
? "adminCourseView.curriculum.lesson.aiJudge.editAssessment"
: "adminCourseView.curriculum.lesson.aiJudge.configureManually";
- const isAiActionDisabled = language !== baseLanguage || isLoading;
+ const isAiActionDisabled = language !== baseLanguage || isLoading || !isAiMentorConfigured;
+ let aiActionTooltipKey: string | undefined;
+
+ if (language !== baseLanguage)
+ aiActionTooltipKey = "adminCourseView.curriculum.lesson.aiJudge.structureLockedTooltip";
+ else if (!isAiMentorConfigured)
+ aiActionTooltipKey =
+ "adminCourseView.curriculum.lesson.aiJudge.aiMentorConfigurationRequiredTooltip";
return (
<>
@@ -130,13 +139,13 @@ export const AiJudgeConfigurationCard = ({
- {language !== baseLanguage && (
+ {aiActionTooltipKey && (
- {t("adminCourseView.curriculum.lesson.aiJudge.structureLockedTooltip")}
+ {t(aiActionTooltipKey)}
)}
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationCard.test.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationCard.test.tsx
new file mode 100644
index 0000000000..99f6374d18
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationCard.test.tsx
@@ -0,0 +1,87 @@
+import { AI_MENTOR_ROLEPLAY_DIFFICULTY, AI_MENTOR_TYPE } from "@repo/shared";
+import { screen } from "@testing-library/react";
+import { userEvent } from "@testing-library/user-event";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+
+import { TooltipProvider } from "~/components/ui/tooltip";
+import i18next from "~/utils/mocks/i18next.mock";
+import { renderWith } from "~/utils/testUtils";
+
+import { AiMentorConfigurationCard } from "./AiMentorConfigurationCard";
+
+import type { AiMentorConfigurationDraft } from "./aiMentorConfiguration.types";
+
+const roleplayConfiguration: AiMentorConfigurationDraft = {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "An unexpected invoice",
+ aiRole: "Concerned customer",
+ learnerRole: "Support representative",
+ characterGoal: "Receive a clear next step",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+};
+
+const renderCard = (props: Partial> = {}) =>
+ renderWith().render(
+
+
+ ,
+ );
+
+describe("AiMentorConfigurationCard", () => {
+ beforeEach(async () => {
+ await i18next.changeLanguage("en");
+ });
+
+ it("opens the manual configuration dialog from the empty state", async () => {
+ const user = userEvent.setup();
+ renderCard();
+
+ const manualAction = screen.getByRole("button", { name: "Configure manually" });
+ expect(manualAction).toHaveClass("text-primary", "px-1.5");
+
+ await user.click(manualAction);
+
+ expect(screen.getByRole("dialog", { name: "Configure AI Mentor" })).toBeVisible();
+ expect(screen.getByText("Mentor mode")).toBeVisible();
+ });
+
+ it("summarizes a configured Roleplay", () => {
+ renderCard({ value: roleplayConfiguration, isPersisted: true });
+
+ expect(screen.getByText("Roleplay · Concerned customer · Realistic")).toBeVisible();
+ expect(screen.getByRole("button", { name: "Review configuration" })).toBeVisible();
+ });
+
+ it("requires the base configuration before opening a translation", () => {
+ renderCard({ language: "pl", baseLanguage: "en", isPersisted: true });
+
+ expect(screen.getByRole("button", { name: "Configure manually" })).toBeDisabled();
+ expect(
+ screen.getByText(
+ "Configure AI Mentor behavior in the course base language before translating it.",
+ ),
+ ).toBeVisible();
+ });
+
+ it("shows migrated incomplete configurations as an error state", () => {
+ const { container } = renderCard({
+ value: roleplayConfiguration,
+ isPersisted: true,
+ needsConfiguration: true,
+ });
+
+ expect(
+ screen.getByText(
+ "This configuration needs a few details before it can be edited or translated.",
+ ),
+ ).toBeVisible();
+ expect(container.querySelector(".border-error-500")).toBeInTheDocument();
+ });
+});
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationCard.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationCard.tsx
new file mode 100644
index 0000000000..1d280a71fc
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationCard.tsx
@@ -0,0 +1,161 @@
+import { AI_MENTOR_TYPE } from "@repo/shared";
+import { ChevronRight } from "lucide-react";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+
+import { Button } from "~/components/ui/button";
+import { Card, CardContent } from "~/components/ui/card";
+import { Tooltip, TooltipArrow, TooltipContent, TooltipTrigger } from "~/components/ui/tooltip";
+import { cn } from "~/lib/utils";
+
+import { AiMentorConfigurationDialog } from "./AiMentorConfigurationDialog";
+
+import type { AiMentorConfigurationDraft } from "./aiMentorConfiguration.types";
+import type { SupportedLanguages } from "@repo/shared";
+
+type AiMentorConfigurationCardProps = {
+ value?: AiMentorConfigurationDraft;
+ onSaveBaseConfiguration: (value: AiMentorConfigurationDraft) => Promise | void;
+ onSaveTranslation: (value: AiMentorConfigurationDraft) => Promise | void;
+ language: SupportedLanguages;
+ baseLanguage: SupportedLanguages;
+ isPersisted: boolean;
+ isLoading?: boolean;
+ isSaving?: boolean;
+ needsConfiguration?: boolean;
+ error?: string;
+};
+
+export const AiMentorConfigurationCard = ({
+ value,
+ onSaveBaseConfiguration,
+ onSaveTranslation,
+ language,
+ baseLanguage,
+ isPersisted,
+ isLoading = false,
+ isSaving = false,
+ needsConfiguration = false,
+ error,
+}: AiMentorConfigurationCardProps) => {
+ const { t } = useTranslation();
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const isConfigured = Boolean(value);
+ const canOpenDialog =
+ !isLoading &&
+ (language === baseLanguage || (isPersisted && isConfigured && !needsConfiguration));
+ const requiresBaseConfiguration =
+ language !== baseLanguage && (!isConfigured || needsConfiguration);
+ const hasError = Boolean(error) || needsConfiguration;
+
+ const summary = (() => {
+ if (!value) return null;
+
+ if (value.type === AI_MENTOR_TYPE.TEACHER) {
+ const expertise =
+ value.expertise.trim() ||
+ value.taskGoal.trim() ||
+ t("adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.teacher.label");
+ const teachingStyle = t(
+ `adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.${value.teachingStyle}.label`,
+ );
+ return t("adminCourseView.curriculum.lesson.aiMentorConfiguration.summary", {
+ type: t("adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.teacher.label"),
+ detail: expertise,
+ behavior: teachingStyle,
+ });
+ }
+
+ const aiRole =
+ value.aiRole.trim() ||
+ value.scenario.trim() ||
+ t("adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.roleplay.label");
+ const difficulty = t(
+ `adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.${value.difficulty}.label`,
+ );
+ return t("adminCourseView.curriculum.lesson.aiMentorConfiguration.summary", {
+ type: t("adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.roleplay.label"),
+ detail: aiRole,
+ behavior: difficulty,
+ });
+ })();
+ const description = (() => {
+ if (needsConfiguration)
+ return t("adminCourseView.curriculum.lesson.aiMentorConfiguration.incompleteDescription");
+ if (summary) return summary;
+ if (canOpenDialog)
+ return t("adminCourseView.curriculum.lesson.aiMentorConfiguration.emptyDescription");
+ return t("adminCourseView.curriculum.lesson.aiMentorConfiguration.baseLanguageRequired");
+ })();
+ const actionLabel = isConfigured
+ ? t("adminCourseView.curriculum.lesson.aiMentorConfiguration.reviewConfiguration")
+ : t("adminCourseView.curriculum.lesson.aiMentorConfiguration.configureManually");
+
+ return (
+ <>
+
+
+
+
+
+ {t("adminCourseView.curriculum.lesson.aiMentorConfiguration.cardTitle")}
+
+
{description}
+ {error &&
{error}
}
+
+
+
+
+
+
+
+
+ {requiresBaseConfiguration && (
+
+ {t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.structureLockedTooltip",
+ )}
+
+
+ )}
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationDialog.test.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationDialog.test.tsx
new file mode 100644
index 0000000000..67a003843b
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationDialog.test.tsx
@@ -0,0 +1,156 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+import { screen } from "@testing-library/react";
+import { userEvent } from "@testing-library/user-event";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+
+import i18next from "~/utils/mocks/i18next.mock";
+import { renderWith } from "~/utils/testUtils";
+
+import { AiMentorConfigurationDialog } from "./AiMentorConfigurationDialog";
+
+vi.mock("~/components/RichText/Editor", () => ({
+ BaseEditor: ({
+ content,
+ onChange,
+ ariaLabel,
+ }: {
+ content?: string;
+ onChange: (value: string) => void;
+ ariaLabel?: string;
+ }) => (
+
",
+ contentScope: "Old content scope
",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+ }}
+ onSaveBaseConfiguration={vi.fn()}
+ onSaveTranslation={vi.fn()}
+ language="en"
+ baseLanguage="en"
+ isPersisted
+ />,
+ );
+
+ await user.click(screen.getByRole("radio", { name: /Roleplay/ }));
+ await user.click(screen.getByRole("button", { name: "Continue" }));
+ await user.click(screen.getByRole("radio", { name: /Teacher/ }));
+
+ expect(screen.getByTestId("curriculum-ai-mentor-configuration-expertise-input")).toHaveValue(
+ "",
+ );
+ expect(screen.getByRole("textbox", { name: "Task goal" })).toHaveValue("");
+ expect(screen.getByRole("textbox", { name: "Content scope" })).toHaveValue("");
+ });
+});
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationDialog.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationDialog.tsx
new file mode 100644
index 0000000000..566949e055
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationDialog.tsx
@@ -0,0 +1,225 @@
+import { zodResolver } from "@hookform/resolvers/zod";
+import { AI_MENTOR_TYPE } from "@repo/shared";
+import { useEffect, useState } from "react";
+import { useForm } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+import { match } from "ts-pattern";
+
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from "~/components/ui/alert-dialog";
+import { Button } from "~/components/ui/button";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "~/components/ui/dialog";
+import { Form } from "~/components/ui/form";
+
+import {
+ createEmptyAiMentorConfiguration,
+ hasAiMentorModeSpecificContent,
+ switchAiMentorConfigurationType,
+} from "./aiMentorConfiguration.defaults";
+import { aiMentorConfigurationSchema } from "./aiMentorConfiguration.schema";
+import { AiMentorConfigurationFields } from "./AiMentorConfigurationFields";
+
+import type { AiMentorConfigurationDraft } from "./aiMentorConfiguration.types";
+import type { AiMentorType, SupportedLanguages } from "@repo/shared";
+
+type AiMentorConfigurationDialogProps = {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+ value?: AiMentorConfigurationDraft;
+ onSaveBaseConfiguration: (value: AiMentorConfigurationDraft) => Promise | void;
+ onSaveTranslation: (value: AiMentorConfigurationDraft) => Promise | void;
+ language: SupportedLanguages;
+ baseLanguage: SupportedLanguages;
+ isPersisted: boolean;
+ isSaving?: boolean;
+};
+
+export const AiMentorConfigurationDialog = ({
+ open,
+ onOpenChange,
+ value,
+ onSaveBaseConfiguration,
+ onSaveTranslation,
+ language,
+ baseLanguage,
+ isPersisted,
+ isSaving = false,
+}: AiMentorConfigurationDialogProps) => {
+ const { t } = useTranslation();
+ const [pendingType, setPendingType] = useState(null);
+ const canEditStructure = language === baseLanguage;
+ const form = useForm({
+ resolver: zodResolver(aiMentorConfigurationSchema(t)),
+ defaultValues: value ?? createEmptyAiMentorConfiguration(),
+ });
+ const submitLabelKey = match({ canEditStructure, isPersisted })
+ .with(
+ { canEditStructure: true, isPersisted: true },
+ () => "adminCourseView.curriculum.lesson.aiMentorConfiguration.saveConfiguration" as const,
+ )
+ .with(
+ { canEditStructure: true, isPersisted: false },
+ () => "adminCourseView.curriculum.lesson.aiMentorConfiguration.applyConfiguration" as const,
+ )
+ .otherwise(
+ () => "adminCourseView.curriculum.lesson.aiMentorConfiguration.saveTranslation" as const,
+ );
+
+ useEffect(() => {
+ if (!open) return;
+ setPendingType(null);
+ form.reset(value ?? createEmptyAiMentorConfiguration());
+ }, [form, open, value]);
+
+ const applyTypeChange = (type: AiMentorType) => {
+ const currentConfiguration = form.getValues();
+ const nextConfiguration = switchAiMentorConfigurationType(currentConfiguration, type);
+
+ if (currentConfiguration.type === AI_MENTOR_TYPE.TEACHER) {
+ form.resetField("taskGoal", { defaultValue: "" });
+ form.resetField("expertise", { defaultValue: "" });
+ form.resetField("contentScope", { defaultValue: "" });
+ form.resetField("feedbackGuidance", { defaultValue: "" });
+ } else {
+ form.resetField("scenario", { defaultValue: "" });
+ form.resetField("aiRole", { defaultValue: "" });
+ form.resetField("learnerRole", { defaultValue: "" });
+ form.resetField("characterGoal", { defaultValue: "" });
+ form.resetField("factsAndConstraints", { defaultValue: "" });
+ }
+
+ form.reset(nextConfiguration);
+ setPendingType(null);
+ };
+
+ const handleTypeChange = (type: AiMentorType) => {
+ const configuration = form.getValues();
+ if (configuration.type === type) return;
+
+ if (hasAiMentorModeSpecificContent(configuration)) {
+ setPendingType(type);
+ return;
+ }
+
+ applyTypeChange(type);
+ };
+
+ const handleSave = form.handleSubmit(async (configuration) => {
+ if (canEditStructure) await onSaveBaseConfiguration(configuration);
+ else await onSaveTranslation(configuration);
+ onOpenChange(false);
+ });
+
+ return (
+ <>
+
+
+ {
+ if (!confirmationOpen) setPendingType(null);
+ }}
+ >
+
+
+
+ {t("adminCourseView.curriculum.lesson.aiMentorConfiguration.typeChange.title")}
+
+
+ {t("adminCourseView.curriculum.lesson.aiMentorConfiguration.typeChange.description", {
+ type:
+ pendingType === AI_MENTOR_TYPE.TEACHER
+ ? t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.teacher.label",
+ )
+ : t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.roleplay.label",
+ ),
+ })}
+
+
+
+ setPendingType(null)}>
+ {t("common.button.cancel")}
+
+ {
+ if (pendingType) applyTypeChange(pendingType);
+ }}
+ >
+ {t("clientStatisticsView.button.continue")}
+
+
+
+
+ >
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationFields.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationFields.tsx
new file mode 100644
index 0000000000..70687daae1
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorConfigurationFields.tsx
@@ -0,0 +1,96 @@
+import { AI_MENTOR_TYPE, type AiMentorType } from "@repo/shared";
+import { Drama, GraduationCap } from "lucide-react";
+import { useEffect, useRef } from "react";
+import { useFormContext, useWatch } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+
+import { AiMentorFineTuneConfigurationFields } from "./AiMentorFineTuneConfigurationFields";
+import { AiMentorRoleplayConfigurationFields } from "./AiMentorRoleplayConfigurationFields";
+import { AiMentorTeacherConfigurationFields } from "./AiMentorTeacherConfigurationFields";
+import { ConfigurationChoiceCards } from "./fields/AiMentorConfigurationFieldInputs";
+
+import type { AiMentorConfigurationDraft } from "./aiMentorConfiguration.types";
+import type { Choice } from "./fields/AiMentorConfigurationFieldInputs";
+
+type AiMentorConfigurationFieldsProps = {
+ canEditStructure: boolean;
+ onTypeChange: (type: AiMentorType) => void;
+};
+
+export const AiMentorConfigurationFields = ({
+ canEditStructure,
+ onTypeChange,
+}: AiMentorConfigurationFieldsProps) => {
+ const { t } = useTranslation();
+ const form = useFormContext();
+ const optionalFieldsRef = useRef(null);
+ const type = useWatch({ control: form.control, name: "type" });
+ const errorKeys = Object.keys(form.formState.errors);
+ const hasOptionalError = [
+ "feedbackGuidance",
+ "factsAndConstraints",
+ "openingInstruction",
+ "additionalInstructions",
+ ].some((field) => errorKeys.includes(field));
+
+ useEffect(() => {
+ if (hasOptionalError && optionalFieldsRef.current) optionalFieldsRef.current.open = true;
+ }, [hasOptionalError]);
+
+ const modeChoices: Choice[] = [
+ {
+ value: AI_MENTOR_TYPE.ROLEPLAY,
+ label: t("adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.roleplay.label"),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.roleplay.description",
+ ),
+ icon: Drama,
+ },
+ {
+ value: AI_MENTOR_TYPE.TEACHER,
+ label: t("adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.teacher.label"),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.mode.teacher.description",
+ ),
+ icon: GraduationCap,
+ },
+ ];
+
+ return (
+
+ {!canEditStructure && (
+
+
+ {t("adminCourseView.curriculum.lesson.aiMentorConfiguration.translationModeTitle")}
+
+
+ {t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.translationModeDescription",
+ )}
+
+
+ )}
+
+
onTypeChange(value)}
+ />
+
+ {type === AI_MENTOR_TYPE.TEACHER ? (
+
+ ) : (
+
+ )}
+
+
+
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorFineTuneConfigurationFields.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorFineTuneConfigurationFields.tsx
new file mode 100644
index 0000000000..8366549b72
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorFineTuneConfigurationFields.tsx
@@ -0,0 +1,93 @@
+import { AI_MENTOR_TYPE } from "@repo/shared";
+import { ChevronDown, SlidersHorizontal } from "lucide-react";
+import { useTranslation } from "react-i18next";
+
+import { cn } from "~/lib/utils";
+
+import { ConfigurationTextField } from "./fields/AiMentorConfigurationFieldInputs";
+
+import type { AiMentorType } from "@repo/shared";
+import type { RefObject } from "react";
+
+type AiMentorFineTuneConfigurationFieldsProps = {
+ type: AiMentorType;
+ hasOptionalError: boolean;
+ optionalFieldsRef: RefObject;
+};
+
+export const AiMentorFineTuneConfigurationFields = ({
+ type,
+ hasOptionalError,
+ optionalFieldsRef,
+}: AiMentorFineTuneConfigurationFieldsProps) => {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+
+ {t("adminCourseView.curriculum.lesson.aiMentorConfiguration.fineTuneBehavior")}
+
+
+
+
+
+ {type === AI_MENTOR_TYPE.TEACHER ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorRoleplayConfigurationFields.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorRoleplayConfigurationFields.tsx
new file mode 100644
index 0000000000..cd5d8cf870
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorRoleplayConfigurationFields.tsx
@@ -0,0 +1,101 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TYPE,
+ type AiMentorRoleplayDifficulty,
+} from "@repo/shared";
+import { useTranslation } from "react-i18next";
+
+import {
+ ConfigurationChoiceCards,
+ ConfigurationTextField,
+} from "./fields/AiMentorConfigurationFieldInputs";
+
+import type { Choice } from "./fields/AiMentorConfigurationFieldInputs";
+
+type AiMentorRoleplayConfigurationFieldsProps = {
+ canEditStructure: boolean;
+};
+
+export const AiMentorRoleplayConfigurationFields = ({
+ canEditStructure,
+}: AiMentorRoleplayConfigurationFieldsProps) => {
+ const { t } = useTranslation();
+
+ const difficultyChoices: Choice[] = [
+ {
+ value: AI_MENTOR_ROLEPLAY_DIFFICULTY.COOPERATIVE,
+ label: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.cooperative.label",
+ ),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.cooperative.description",
+ ),
+ },
+ {
+ value: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ label: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.realistic.label",
+ ),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.realistic.description",
+ ),
+ },
+ {
+ value: AI_MENTOR_ROLEPLAY_DIFFICULTY.CHALLENGING,
+ label: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.challenging.label",
+ ),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.difficulty.challenging.description",
+ ),
+ },
+ ];
+
+ return (
+
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorTeacherConfigurationFields.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorTeacherConfigurationFields.tsx
new file mode 100644
index 0000000000..8a808648af
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/AiMentorTeacherConfigurationFields.tsx
@@ -0,0 +1,87 @@
+import { AI_MENTOR_TEACHING_STYLE, AI_MENTOR_TYPE, type AiMentorTeachingStyle } from "@repo/shared";
+import { useTranslation } from "react-i18next";
+
+import {
+ ConfigurationChoiceCards,
+ ConfigurationTextField,
+} from "./fields/AiMentorConfigurationFieldInputs";
+
+import type { Choice } from "./fields/AiMentorConfigurationFieldInputs";
+
+type AiMentorTeacherConfigurationFieldsProps = {
+ canEditStructure: boolean;
+};
+
+export const AiMentorTeacherConfigurationFields = ({
+ canEditStructure,
+}: AiMentorTeacherConfigurationFieldsProps) => {
+ const { t } = useTranslation();
+
+ const teachingStyleChoices: Choice[] = [
+ {
+ value: AI_MENTOR_TEACHING_STYLE.EXPLAIN_AND_PRACTICE,
+ label: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.explain_and_practice.label",
+ ),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.explain_and_practice.description",
+ ),
+ },
+ {
+ value: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+ label: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.guided_discovery.label",
+ ),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.guided_discovery.description",
+ ),
+ },
+ {
+ value: AI_MENTOR_TEACHING_STYLE.SOCRATIC,
+ label: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.socratic.label",
+ ),
+ description: t(
+ "adminCourseView.curriculum.lesson.aiMentorConfiguration.teachingStyle.socratic.description",
+ ),
+ },
+ ];
+
+ return (
+
+
+
+
+
+
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.defaults.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.defaults.ts
new file mode 100644
index 0000000000..a4032a3038
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.defaults.ts
@@ -0,0 +1,72 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+
+import { stripHtmlTags } from "~/utils/stripHtmlTags";
+
+import type { AiMentorConfigurationDraft } from "./aiMentorConfiguration.types";
+import type { AiMentorType } from "@repo/shared";
+
+export const createEmptyTeacherConfiguration = (): AiMentorConfigurationDraft => ({
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "",
+ expertise: "",
+ contentScope: "",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.EXPLAIN_AND_PRACTICE,
+ feedbackGuidance: "",
+ openingInstruction: "",
+ additionalInstructions: "",
+});
+
+export const createEmptyRoleplayConfiguration = (): AiMentorConfigurationDraft => ({
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "",
+ aiRole: "",
+ learnerRole: "",
+ characterGoal: "",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ factsAndConstraints: "",
+ openingInstruction: "",
+ additionalInstructions: "",
+});
+
+export const createEmptyAiMentorConfiguration = (
+ type: AiMentorType = AI_MENTOR_TYPE.ROLEPLAY,
+): AiMentorConfigurationDraft =>
+ type === AI_MENTOR_TYPE.TEACHER
+ ? createEmptyTeacherConfiguration()
+ : createEmptyRoleplayConfiguration();
+
+export const hasAiMentorModeSpecificContent = (
+ configuration: AiMentorConfigurationDraft,
+): boolean => {
+ const hasContent = (value: string | null | undefined) =>
+ Boolean(value && stripHtmlTags(value).trim());
+
+ if (configuration.type === AI_MENTOR_TYPE.TEACHER)
+ return [
+ configuration.taskGoal,
+ configuration.expertise,
+ configuration.contentScope,
+ configuration.feedbackGuidance,
+ ].some(hasContent);
+
+ return [
+ configuration.scenario,
+ configuration.aiRole,
+ configuration.learnerRole,
+ configuration.characterGoal,
+ configuration.factsAndConstraints,
+ ].some(hasContent);
+};
+
+export const switchAiMentorConfigurationType = (
+ configuration: AiMentorConfigurationDraft,
+ type: AiMentorType,
+): AiMentorConfigurationDraft => ({
+ ...createEmptyAiMentorConfiguration(type),
+ openingInstruction: configuration.openingInstruction,
+ additionalInstructions: configuration.additionalInstructions,
+});
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.mappers.test.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.mappers.test.ts
new file mode 100644
index 0000000000..af6862a7a5
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.mappers.test.ts
@@ -0,0 +1,94 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+import { describe, expect, it } from "vitest";
+
+import {
+ mapAiMentorConfigurationDraftToBaseInput,
+ mapAiMentorConfigurationDraftToTranslationInput,
+ mapAiMentorConfigurationResponseToDraft,
+} from "./aiMentorConfiguration.mappers";
+
+import type { AiMentorConfigurationResponse } from "./aiMentorConfiguration.types";
+const commonResponse = {
+ id: "00000000-0000-4000-8000-000000000001",
+ aiMentorLessonId: "00000000-0000-4000-8000-000000000002",
+ needsConfiguration: false,
+ hasMissingTranslations: false,
+ language: "en",
+ baseLanguage: "en",
+ availableLocales: ["en", "pl"],
+} satisfies Pick<
+ AiMentorConfigurationResponse,
+ | "id"
+ | "aiMentorLessonId"
+ | "needsConfiguration"
+ | "hasMissingTranslations"
+ | "language"
+ | "baseLanguage"
+ | "availableLocales"
+>;
+
+describe("AI Mentor configuration mappers", () => {
+ it("maps and normalizes a Teacher configuration", () => {
+ const response = {
+ ...commonResponse,
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Teach escalation",
+ expertise: "Support coach",
+ contentScope: "Escalation policy",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.EXPLAIN_AND_PRACTICE,
+ feedbackGuidance: null,
+ openingInstruction: null,
+ additionalInstructions: null,
+ } satisfies AiMentorConfigurationResponse;
+
+ const draft = mapAiMentorConfigurationResponseToDraft(response);
+ if (draft.type !== AI_MENTOR_TYPE.TEACHER) throw new Error("Expected Teacher draft");
+
+ expect(draft.feedbackGuidance).toBe("");
+ expect(
+ mapAiMentorConfigurationDraftToBaseInput({
+ ...draft,
+ taskGoal: " Teach escalation ",
+ openingInstruction: " ",
+ }),
+ ).toMatchObject({
+ taskGoal: "Teach escalation",
+ openingInstruction: null,
+ });
+ });
+
+ it("excludes structural Roleplay fields from a translation update", () => {
+ const response = {
+ ...commonResponse,
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "Invoice discussion",
+ aiRole: "Concerned customer",
+ learnerRole: "Support representative",
+ characterGoal: "Understand the charge",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.CHALLENGING,
+ factsAndConstraints: "The invoice is correct.",
+ openingInstruction: null,
+ additionalInstructions: null,
+ } satisfies AiMentorConfigurationResponse;
+
+ const translation = mapAiMentorConfigurationDraftToTranslationInput(
+ mapAiMentorConfigurationResponseToDraft(response),
+ );
+
+ expect(translation).toEqual({
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "Invoice discussion",
+ aiRole: "Concerned customer",
+ learnerRole: "Support representative",
+ characterGoal: "Understand the charge",
+ factsAndConstraints: "The invoice is correct.",
+ openingInstruction: null,
+ additionalInstructions: null,
+ });
+ expect(translation).not.toHaveProperty("difficulty");
+ });
+});
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.mappers.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.mappers.ts
new file mode 100644
index 0000000000..106300f46a
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.mappers.ts
@@ -0,0 +1,92 @@
+import { AI_MENTOR_TYPE } from "@repo/shared";
+
+import type {
+ AiMentorConfigurationDraft,
+ AiMentorConfigurationResponse,
+ AiMentorConfigurationTranslationInput,
+} from "./aiMentorConfiguration.types";
+
+const normalizeOptionalText = (value: string | null | undefined) => value?.trim() || null;
+
+export const mapAiMentorConfigurationResponseToDraft = (
+ response: AiMentorConfigurationResponse,
+): AiMentorConfigurationDraft => {
+ if (response.type === AI_MENTOR_TYPE.TEACHER) {
+ return {
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: response.taskGoal,
+ expertise: response.expertise,
+ contentScope: response.contentScope,
+ teachingStyle: response.teachingStyle,
+ feedbackGuidance: response.feedbackGuidance ?? "",
+ openingInstruction: response.openingInstruction ?? "",
+ additionalInstructions: response.additionalInstructions ?? "",
+ };
+ }
+
+ return {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: response.scenario,
+ aiRole: response.aiRole,
+ learnerRole: response.learnerRole,
+ characterGoal: response.characterGoal,
+ difficulty: response.difficulty,
+ factsAndConstraints: response.factsAndConstraints ?? "",
+ openingInstruction: response.openingInstruction ?? "",
+ additionalInstructions: response.additionalInstructions ?? "",
+ };
+};
+
+export const mapAiMentorConfigurationDraftToBaseInput = (
+ draft: AiMentorConfigurationDraft,
+): AiMentorConfigurationDraft => {
+ if (draft.type === AI_MENTOR_TYPE.TEACHER) {
+ return {
+ ...draft,
+ taskGoal: draft.taskGoal.trim(),
+ expertise: draft.expertise.trim(),
+ contentScope: draft.contentScope.trim(),
+ feedbackGuidance: normalizeOptionalText(draft.feedbackGuidance),
+ openingInstruction: normalizeOptionalText(draft.openingInstruction),
+ additionalInstructions: normalizeOptionalText(draft.additionalInstructions),
+ };
+ }
+
+ return {
+ ...draft,
+ scenario: draft.scenario.trim(),
+ aiRole: draft.aiRole.trim(),
+ learnerRole: draft.learnerRole.trim(),
+ characterGoal: draft.characterGoal.trim(),
+ factsAndConstraints: normalizeOptionalText(draft.factsAndConstraints),
+ openingInstruction: normalizeOptionalText(draft.openingInstruction),
+ additionalInstructions: normalizeOptionalText(draft.additionalInstructions),
+ };
+};
+
+export const mapAiMentorConfigurationDraftToTranslationInput = (
+ draft: AiMentorConfigurationDraft,
+): AiMentorConfigurationTranslationInput => {
+ if (draft.type === AI_MENTOR_TYPE.TEACHER) {
+ return {
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: draft.taskGoal.trim(),
+ expertise: draft.expertise.trim(),
+ contentScope: draft.contentScope.trim(),
+ feedbackGuidance: normalizeOptionalText(draft.feedbackGuidance),
+ openingInstruction: normalizeOptionalText(draft.openingInstruction),
+ additionalInstructions: normalizeOptionalText(draft.additionalInstructions),
+ };
+ }
+
+ return {
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: draft.scenario.trim(),
+ aiRole: draft.aiRole.trim(),
+ learnerRole: draft.learnerRole.trim(),
+ characterGoal: draft.characterGoal.trim(),
+ factsAndConstraints: normalizeOptionalText(draft.factsAndConstraints),
+ openingInstruction: normalizeOptionalText(draft.openingInstruction),
+ additionalInstructions: normalizeOptionalText(draft.additionalInstructions),
+ };
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.schema.test.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.schema.test.ts
new file mode 100644
index 0000000000..24e4e431cc
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.schema.test.ts
@@ -0,0 +1,64 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+import { describe, expect, it } from "vitest";
+
+import { aiMentorConfigurationSchema } from "./aiMentorConfiguration.schema";
+
+import type { TFunction } from "i18next";
+
+const t = ((key: string) => key) as TFunction;
+
+describe("aiMentorConfigurationSchema", () => {
+ it("accepts a complete Teacher configuration", () => {
+ const result = aiMentorConfigurationSchema(t).safeParse({
+ type: AI_MENTOR_TYPE.TEACHER,
+ taskGoal: "Help the learner explain the escalation process.",
+ expertise: "Customer support coach",
+ contentScope: "Use the company escalation policy.",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+ });
+
+ expect(result.success).toBe(true);
+ });
+
+ it("accepts a complete Roleplay configuration", () => {
+ const result = aiMentorConfigurationSchema(t).safeParse({
+ type: AI_MENTOR_TYPE.ROLEPLAY,
+ scenario: "A customer questions an unexpected invoice.",
+ aiRole: "Concerned customer",
+ learnerRole: "Support representative",
+ characterGoal: "Receive a clear explanation and next step.",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ });
+
+ expect(result.success).toBe(true);
+ });
+
+ it("rejects incomplete and mixed mode fields", () => {
+ const result = aiMentorConfigurationSchema(t).safeParse({
+ type: AI_MENTOR_TYPE.TEACHER,
+ scenario: "A roleplay scenario",
+ aiRole: "Customer",
+ learnerRole: "Representative",
+ characterGoal: "Resolve the issue",
+ difficulty: AI_MENTOR_ROLEPLAY_DIFFICULTY.REALISTIC,
+ });
+
+ expect(result.success).toBe(false);
+ });
+
+ it("rejects visually empty rich-text fields", () => {
+ const result = aiMentorConfigurationSchema(t).safeParse({
+ type: AI_MENTOR_TYPE.TEACHER,
+ expertise: "Customer support coach",
+ taskGoal: "
",
+ contentScope: "Use the company escalation policy.
",
+ teachingStyle: AI_MENTOR_TEACHING_STYLE.GUIDED_DISCOVERY,
+ });
+
+ expect(result.success).toBe(false);
+ });
+});
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.schema.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.schema.ts
new file mode 100644
index 0000000000..81094bbaa6
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.schema.ts
@@ -0,0 +1,45 @@
+import {
+ AI_MENTOR_ROLEPLAY_DIFFICULTY,
+ AI_MENTOR_TEACHING_STYLE,
+ AI_MENTOR_TYPE,
+} from "@repo/shared";
+import { z } from "zod";
+
+import { stripHtmlTags } from "~/utils/stripHtmlTags";
+
+import type { TFunction } from "i18next";
+
+const optionalText = z.string().nullable().optional();
+
+const requiredText = (t: TFunction) =>
+ z
+ .string()
+ .refine(
+ (value) => stripHtmlTags(value).trim().length > 0,
+ t("adminCourseView.curriculum.lesson.aiMentorConfiguration.validation.required"),
+ );
+
+export const aiMentorConfigurationSchema = (t: TFunction) =>
+ z.discriminatedUnion("type", [
+ z.object({
+ type: z.literal(AI_MENTOR_TYPE.TEACHER),
+ taskGoal: requiredText(t),
+ expertise: requiredText(t),
+ contentScope: requiredText(t),
+ teachingStyle: z.nativeEnum(AI_MENTOR_TEACHING_STYLE),
+ feedbackGuidance: optionalText,
+ openingInstruction: optionalText,
+ additionalInstructions: optionalText,
+ }),
+ z.object({
+ type: z.literal(AI_MENTOR_TYPE.ROLEPLAY),
+ scenario: requiredText(t),
+ aiRole: requiredText(t),
+ learnerRole: requiredText(t),
+ characterGoal: requiredText(t),
+ difficulty: z.nativeEnum(AI_MENTOR_ROLEPLAY_DIFFICULTY),
+ factsAndConstraints: optionalText,
+ openingInstruction: optionalText,
+ additionalInstructions: optionalText,
+ }),
+ ]);
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.types.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.types.ts
new file mode 100644
index 0000000000..9003397dd1
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/aiMentorConfiguration.types.ts
@@ -0,0 +1,9 @@
+import type {
+ GetAiMentorConfigurationResponse,
+ ReplaceAiMentorConfigurationBody,
+ UpdateAiMentorConfigurationTranslationsBody,
+} from "~/api/generated-api";
+
+export type AiMentorConfigurationDraft = ReplaceAiMentorConfigurationBody;
+export type AiMentorConfigurationResponse = GetAiMentorConfigurationResponse["data"];
+export type AiMentorConfigurationTranslationInput = UpdateAiMentorConfigurationTranslationsBody;
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/fields/AiMentorConfigurationFieldInputs.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/fields/AiMentorConfigurationFieldInputs.tsx
new file mode 100644
index 0000000000..28b9e4920d
--- /dev/null
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorConfiguration/fields/AiMentorConfigurationFieldInputs.tsx
@@ -0,0 +1,178 @@
+import { useFormContext } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+
+import { BaseEditor } from "~/components/RichText/Editor";
+import { FormControl, FormField, FormItem, FormLabel, FormMessage } from "~/components/ui/form";
+import { Input } from "~/components/ui/input";
+import { RadioGroup, RadioGroupItem } from "~/components/ui/radio-group";
+import { cn } from "~/lib/utils";
+
+import type { AiMentorConfigurationDraft } from "../aiMentorConfiguration.types";
+import type { LucideIcon } from "lucide-react";
+import type { FieldPath } from "react-hook-form";
+
+type ConfigurationTextFieldProps = {
+ name: FieldPath;
+ label: string;
+ placeholder: string;
+ richText?: boolean;
+ optional?: boolean;
+ className?: string;
+ testId?: string;
+};
+
+export const ConfigurationTextField = ({
+ name,
+ label,
+ placeholder,
+ richText = false,
+ optional = false,
+ className,
+ testId,
+}: ConfigurationTextFieldProps) => {
+ const { t } = useTranslation();
+ const form = useFormContext();
+
+ return (
+ (
+
+
+ {label}
+ {optional && (
+
+ {t("adminCourseView.curriculum.lesson.aiMentorConfiguration.optional")}
+
+ )}
+
+
+ {richText ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
+ )}
+ />
+ );
+};
+
+export type Choice = {
+ value: TValue;
+ label: string;
+ description: string;
+ icon?: LucideIcon;
+};
+
+type ConfigurationChoiceCardsProps = {
+ name: "type" | "teachingStyle" | "difficulty";
+ label: string;
+ choices: Choice[];
+ columns: 2 | 3;
+ disabled?: boolean;
+ onValueChange?: (value: TValue) => void;
+};
+
+export const ConfigurationChoiceCards = ({
+ name,
+ label,
+ choices,
+ columns,
+ disabled = false,
+ onValueChange,
+}: ConfigurationChoiceCardsProps) => {
+ const form = useFormContext();
+
+ return (
+ (
+
+ {label}
+
+
+ {choices.map((choice) => {
+ const selected = choice.value === field.value;
+ const choiceId = `ai-mentor-${name}-${choice.value}`;
+ const ChoiceIcon = choice.icon;
+
+ return (
+
+ );
+ })}
+
+
+
+
+ )}
+ />
+ );
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLesson.constants.ts b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLesson.constants.ts
index 3c1d04b13f..28332afb80 100644
--- a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLesson.constants.ts
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLesson.constants.ts
@@ -1,3 +1,9 @@
export const MAX_MB_PER_FILE = 10;
export const MAX_NUM_OF_FILES = 3;
export const MAX_AI_MENTOR_TEXT_LENGTH = 20_000;
+
+export const AI_MENTOR_FILE_TYPES_MAP: Record = {
+ "application/pdf": "PDF",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "DOCX",
+ "text/plain": "TXT",
+};
diff --git a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLessonForm.tsx b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLessonForm.tsx
index 45358ac131..8437b4e0b4 100644
--- a/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLessonForm.tsx
+++ b/apps/web/app/modules/Admin/EditCourse/CourseLessons/NewLesson/AiMentorLessonForm/AiMentorLessonForm.tsx
@@ -4,10 +4,13 @@ import { useEffect, useMemo, useReducer, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { useReplaceAiJudgeConfiguration } from "~/api/mutations/admin/useReplaceAiJudgeConfiguration";
+import { useReplaceAiMentorConfiguration } from "~/api/mutations/admin/useReplaceAiMentorConfiguration";
import { useUpdateAiJudgeConfigurationTranslation } from "~/api/mutations/admin/useUpdateAiJudgeConfigurationTranslation";
+import { useUpdateAiMentorConfigurationTranslation } from "~/api/mutations/admin/useUpdateAiMentorConfigurationTranslation";
import { useUploadAiMentorAvatar } from "~/api/mutations/admin/useUploadAiMentorAvatar";
import { useValidateAiJudgeConfiguration } from "~/api/mutations/admin/useValidateAiJudgeConfiguration";
import { useAiJudgeConfiguration } from "~/api/queries/admin/useAiJudgeConfiguration";
+import { useAiMentorConfiguration } from "~/api/queries/admin/useAiMentorConfiguration";
import { COURSE_QUERY_KEY } from "~/api/queries/admin/useBetaCourse";
import { useLumaConfigured } from "~/api/queries/useLumaConfigured";
import { queryClient } from "~/api/queryClient";
@@ -51,15 +54,23 @@ import {
import { AiJudgeConfigurationCard } from "./AiJudge/AiJudgeConfigurationCard";
import { AiJudgeGenerationDialog } from "./AiJudge/AiJudgeGenerationDialog";
import { useAiJudgeConfigurationGeneration } from "./AiJudge/useAiJudgeConfigurationGeneration";
-import { AiMentorIdentityFields } from "./components/AiMentorIdentityFields";
import {
- AiMentorInstructionsField,
- AiMentorSuggestionExamples,
-} from "./components/AiMentorInstructionsFields";
+ mapAiMentorConfigurationDraftToBaseInput,
+ mapAiMentorConfigurationDraftToTranslationInput,
+ mapAiMentorConfigurationResponseToDraft,
+} from "./AiMentorConfiguration/aiMentorConfiguration.mappers";
+import { AiMentorConfigurationCard } from "./AiMentorConfiguration/AiMentorConfigurationCard";
+import { AiMentorIdentityFields } from "./components/AiMentorIdentityFields";
import { AiMentorScenarioFields } from "./components/AiMentorScenarioFields";
+import { AiMentorScenarioTemplateSelect } from "./components/AiMentorScenarioTemplateSelect";
import { AiMentorVoiceConfigurationFields } from "./components/AiMentorVoiceConfigurationFields";
import { useAiMentorLessonForm } from "./hooks/useAiMentorLessonForm";
import UpdateAiAvatarModal from "./UpdateAiAvatarModal";
+import {
+ buildAiMentorScenarioTemplateDraft,
+ type AiMentorScenarioTemplate,
+} from "./utils/AiMentorScenarioTemplate.helpers";
+import { stripHtmlTags } from "./validators/useAiMentorLessonFormSchema";
import type {
AiJudgeConfigurationDraft,
@@ -67,6 +78,7 @@ import type {
AiJudgeGenerationRequest,
AiJudgeValidationResult,
} from "./AiJudge/aiJudgeConfiguration.types";
+import type { AiMentorConfigurationDraft } from "./AiMentorConfiguration/aiMentorConfiguration.types";
import type { Chapter, Lesson } from "../../../EditCourse.types";
import type { SupportedLanguages } from "@repo/shared";
@@ -89,6 +101,16 @@ const AiMentorLessonForm = ({
}: AiMentorLessonProps) => {
const { mutateAsync: replaceAiJudgeConfiguration, isPending: isReplacingAiJudgeConfiguration } =
useReplaceAiJudgeConfiguration();
+ const { mutateAsync: replaceAiMentorConfiguration, isPending: isReplacingAiMentorConfiguration } =
+ useReplaceAiMentorConfiguration();
+ const saveStagedAiMentorConfiguration = async (configuration: AiMentorConfigurationDraft) => {
+ if (!lessonToEdit) return;
+
+ await replaceAiMentorConfiguration({
+ lessonId: lessonToEdit.id,
+ data: mapAiMentorConfigurationDraftToBaseInput(configuration),
+ });
+ };
const saveStagedAiJudgeConfiguration = async (configuration: AiJudgeConfigurationDraft) => {
if (!lessonToEdit) return;
@@ -99,21 +121,13 @@ const AiMentorLessonForm = ({
});
};
- const {
- form,
- onSubmit,
- onDelete,
- handleSuggestionClick,
- isConfirmDialogOpen,
- setIsConfirmDialogOpen,
- onConfirmOverwrite,
- onCancelOverwrite,
- } = useAiMentorLessonForm({
+ const { form, onSubmit, onDelete } = useAiMentorLessonForm({
chapterToEdit,
lessonToEdit,
setContentTypeToDisplay,
language,
baseLanguage,
+ onSaveStagedAiMentorConfiguration: saveStagedAiMentorConfiguration,
onSaveStagedAiJudgeConfiguration: saveStagedAiJudgeConfiguration,
});
@@ -123,6 +137,8 @@ const AiMentorLessonForm = ({
const [isModalOpen, setIsModalOpen] = useState(false);
const [isAvatarDialogOpen, setIsAvatarDialogOpen] = useState(false);
+ const [pendingScenarioTemplate, setPendingScenarioTemplate] =
+ useState(null);
const [aiJudgeAuthoringState, dispatchAiJudgeAuthoring] = useReducer(
aiJudgeAuthoringReducer,
INITIAL_AI_JUDGE_AUTHORING_STATE,
@@ -149,9 +165,15 @@ const AiMentorLessonForm = ({
mutateAsync: updateAiJudgeConfigurationTranslation,
isPending: isUpdatingAiJudgeConfigurationTranslation,
} = useUpdateAiJudgeConfigurationTranslation();
+ const {
+ mutateAsync: updateAiMentorConfigurationTranslation,
+ isPending: isUpdatingAiMentorConfigurationTranslation,
+ } = useUpdateAiMentorConfigurationTranslation();
const lessonId = lessonToEdit?.id ?? "";
const { data: savedAiJudgeConfiguration, isLoading: isAiJudgeConfigurationLoading } =
useAiJudgeConfiguration(lessonId, language);
+ const { data: savedAiMentorConfiguration, isLoading: isAiMentorConfigurationLoading } =
+ useAiMentorConfiguration(lessonId, language);
const [avatarPreview, setAvatarPreview] = useState(
lessonToEdit?.avatarReferenceUrl ?? null,
@@ -166,8 +188,17 @@ const AiMentorLessonForm = ({
: "adminCourseView.curriculum.lesson.other.voiceConfigCartesiaTooltip";
const objectUrlRef = useRef(null);
+ const hasStagedAiMentorConfigurationRef = useRef(false);
const hasStagedAiJudgeConfigurationRef = useRef(false);
+ const stagedAiMentorConfiguration = form.watch("aiMentorConfiguration");
const stagedAiJudgeConfiguration = form.watch("aiJudgeConfiguration");
+ const persistedAiMentorConfiguration = useMemo(
+ () =>
+ savedAiMentorConfiguration
+ ? mapAiMentorConfigurationResponseToDraft(savedAiMentorConfiguration)
+ : undefined,
+ [savedAiMentorConfiguration],
+ );
const persistedAiJudgeConfiguration = useMemo(
() =>
savedAiJudgeConfiguration
@@ -175,13 +206,64 @@ const AiMentorLessonForm = ({
: undefined,
[savedAiJudgeConfiguration],
);
+ const aiMentorConfiguration = stagedAiMentorConfiguration ?? persistedAiMentorConfiguration;
const aiJudgeConfiguration = stagedAiJudgeConfiguration ?? persistedAiJudgeConfiguration;
+ const isAiMentorConfigurationDirty = Boolean(form.formState.dirtyFields.aiMentorConfiguration);
const isAiJudgeConfigurationDirty = Boolean(form.formState.dirtyFields.aiJudgeConfiguration);
+ const applyScenarioTemplate = (template: AiMentorScenarioTemplate) => {
+ const draft = buildAiMentorScenarioTemplateDraft(template, t);
+ hasStagedAiMentorConfigurationRef.current = true;
+ hasStagedAiJudgeConfigurationRef.current = true;
+ form.setValue("description", draft.taskDescription, {
+ shouldDirty: true,
+ shouldValidate: true,
+ });
+ form.setValue("aiMentorConfiguration", draft.aiMentorConfiguration, {
+ shouldDirty: true,
+ shouldValidate: true,
+ });
+ form.setValue("aiJudgeConfiguration", draft.aiJudgeConfiguration, {
+ shouldDirty: true,
+ shouldValidate: true,
+ });
+ setPendingScenarioTemplate(null);
+ };
+
+ const handleScenarioTemplateSelect = (template: AiMentorScenarioTemplate) => {
+ const hasExistingContent =
+ Boolean(stripHtmlTags(form.getValues("description") ?? "")) ||
+ Boolean(form.getValues("aiMentorConfiguration")) ||
+ Boolean(form.getValues("aiJudgeConfiguration"));
+
+ if (hasExistingContent) {
+ setPendingScenarioTemplate(template);
+ return;
+ }
+
+ applyScenarioTemplate(template);
+ };
+
useEffect(() => {
+ hasStagedAiMentorConfigurationRef.current = false;
hasStagedAiJudgeConfigurationRef.current = false;
}, [language, lessonToEdit?.id]);
+ useEffect(() => {
+ if (
+ !lessonToEdit ||
+ !persistedAiMentorConfiguration ||
+ isAiMentorConfigurationDirty ||
+ hasStagedAiMentorConfigurationRef.current
+ )
+ return;
+
+ form.setValue("aiMentorConfiguration", persistedAiMentorConfiguration, {
+ shouldDirty: false,
+ shouldValidate: false,
+ });
+ }, [form, isAiMentorConfigurationDirty, lessonToEdit, persistedAiMentorConfiguration]);
+
useEffect(() => {
if (
!lessonToEdit ||
@@ -201,10 +283,43 @@ const AiMentorLessonForm = ({
lessonToEdit &&
language !== baseLanguage &&
(!lessonToEdit.title.trim() ||
- !lessonToEdit.aiMentor?.aiMentorInstructions.trim() ||
+ savedAiMentorConfiguration?.hasMissingTranslations ||
savedAiJudgeConfiguration?.hasMissingTranslations),
);
+ const handleAiMentorBaseConfigurationSave = async (configuration: AiMentorConfigurationDraft) => {
+ const normalizedConfiguration = mapAiMentorConfigurationDraftToBaseInput(configuration);
+
+ if (lessonToEdit) {
+ await replaceAiMentorConfiguration({
+ lessonId: lessonToEdit.id,
+ data: normalizedConfiguration,
+ });
+ hasStagedAiMentorConfigurationRef.current = false;
+ form.resetField("aiMentorConfiguration", {
+ defaultValue: normalizedConfiguration,
+ });
+ return;
+ }
+
+ hasStagedAiMentorConfigurationRef.current = true;
+ form.setValue("aiMentorConfiguration", normalizedConfiguration, {
+ shouldDirty: true,
+ shouldValidate: true,
+ });
+ };
+
+ const handleAiMentorTranslationSave = async (configuration: AiMentorConfigurationDraft) => {
+ if (!lessonToEdit) return;
+
+ await updateAiMentorConfigurationTranslation({
+ courseId: id,
+ lessonId: lessonToEdit.id,
+ language,
+ data: mapAiMentorConfigurationDraftToTranslationInput(configuration),
+ });
+ };
+
const handleAiJudgeBaseConfigurationSave = async (
configuration: NonNullable,
) => {
@@ -255,21 +370,28 @@ const AiMentorLessonForm = ({
openAiJudgeGeneration(mode);
};
- const getAiJudgeLessonContext = () => ({
- title: form.getValues("title") || undefined,
- taskDescription: form.getValues("description") || undefined,
- aiMentorInstructions: form.getValues("aiMentorInstructions") || undefined,
- aiMentorType: form.getValues("type"),
- });
+ const getAiJudgeLessonContext = () => {
+ const configuration = form.getValues("aiMentorConfiguration");
+
+ return {
+ title: form.getValues("title") || undefined,
+ taskDescription: form.getValues("description") || undefined,
+ ...(configuration && {
+ aiMentorConfiguration: mapAiMentorConfigurationDraftToBaseInput(configuration),
+ }),
+ };
+ };
const handleGenerateAiJudgeConfiguration = async ({
mode,
instruction,
}: AiJudgeGenerationRequest) => {
+ const lessonContext = getAiJudgeLessonContext();
+
const commonInput = {
courseId: id,
lessonId: lessonToEdit?.id,
- lessonContext: getAiJudgeLessonContext(),
+ lessonContext,
};
if (mode === AI_JUDGE_GENERATION_MODE.CREATE) {
@@ -292,19 +414,22 @@ const AiMentorLessonForm = ({
});
};
- const handleValidateAiJudgeConfiguration = (
+ const handleValidateAiJudgeConfiguration = async (
configuration: AiJudgeConfigurationDraft,
signal?: AbortSignal,
- ) =>
- validateAiJudgeConfiguration({
+ ) => {
+ const lessonContext = getAiJudgeLessonContext();
+
+ return validateAiJudgeConfiguration({
data: {
courseId: id,
lessonId: lessonToEdit?.id,
- lessonContext: getAiJudgeLessonContext(),
+ lessonContext,
configuration: mapAiJudgeConfigurationDraftToBaseInput(configuration),
},
signal,
});
+ };
const stageGeneratedAiJudgeConfiguration = (configuration: AiJudgeConfigurationDraft) => {
hasStagedAiJudgeConfigurationRef.current = true;
@@ -318,6 +443,9 @@ const AiMentorLessonForm = ({
configuration: AiJudgeConfigurationDraft,
validation?: AiJudgeValidationResult,
) => {
+ const lessonContext = getAiJudgeLessonContext();
+ if (!lessonContext) return;
+
stageGeneratedAiJudgeConfiguration(configuration);
openAiJudgeGeneration(AI_JUDGE_GENERATION_MODE.IMPROVE, validation);
@@ -327,7 +455,7 @@ const AiMentorLessonForm = ({
void startAiJudgeConfigurationGeneration({
courseId: id,
lessonId: lessonToEdit?.id,
- lessonContext: getAiJudgeLessonContext(),
+ lessonContext,
mode: AI_JUDGE_GENERATION_MODE.IMPROVE,
instruction: instruction || validation.summary,
currentConfiguration: mapAiJudgeConfigurationDraftToBaseInput(configuration),
@@ -515,11 +643,34 @@ const AiMentorLessonForm = ({
+ {language === baseLanguage && (
+
+ )}
+
{canConfigureVoiceMentor && (
)}
-
+
-
{lessonToEdit && (
@@ -601,7 +752,12 @@ const AiMentorLessonForm = ({
contentType={DeleteContentType.AI_MENTOR}
/>
-