adding new schema for words, senses and translations incl. relations
This commit is contained in:
parent
0770ff9ec6
commit
de3ebf66a9
1 changed files with 106 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ import {
|
|||
CEFR_LEVELS,
|
||||
DIFFICULTY_LEVELS,
|
||||
LOBBY_STATUSES,
|
||||
NOUN_GENDERS,
|
||||
} from "@lila/shared";
|
||||
|
||||
// ── Vocabulary ────────────────────────────────────────────────────────────────
|
||||
|
|
@ -112,6 +113,95 @@ export const entry_translations = pgTable(
|
|||
],
|
||||
);
|
||||
|
||||
export const words = pgTable(
|
||||
"words",
|
||||
{
|
||||
id: uuid().primaryKey().defaultRandom(),
|
||||
headword: text().notNull(),
|
||||
language_code: varchar({ length: 10 }).notNull(),
|
||||
pos: varchar({ length: 20 }).notNull(),
|
||||
created_at: timestamp({ withTimezone: true }).defaultNow().notNull(),
|
||||
},
|
||||
(table) => [
|
||||
unique("unique_word_per_language_and_pos").on(
|
||||
table.headword,
|
||||
table.language_code,
|
||||
table.pos,
|
||||
),
|
||||
check(
|
||||
"words_language_code_check",
|
||||
sql`${table.language_code} IN (${sql.raw(SUPPORTED_LANGUAGE_CODES.map((code) => `'${code}'`).join(", "))})`,
|
||||
),
|
||||
check(
|
||||
"words_pos_check",
|
||||
sql`${table.pos} IN (${sql.raw(SUPPORTED_POS.map((pos) => `'${pos}'`).join(", "))})`,
|
||||
),
|
||||
index("idx_language_code_pos").on(table.language_code, table.pos),
|
||||
],
|
||||
);
|
||||
|
||||
export const senses = pgTable(
|
||||
"senses",
|
||||
{
|
||||
id: uuid().primaryKey().defaultRandom(),
|
||||
word_id: uuid()
|
||||
.notNull()
|
||||
.references(() => words.id, { onDelete: "cascade" }),
|
||||
sense_index: smallint().default(0).notNull(),
|
||||
difficulty: varchar({ length: 20 }).notNull(),
|
||||
definitions: text().array().notNull().default([]),
|
||||
examples: text().array().notNull().default([]),
|
||||
created_at: timestamp({ withTimezone: true }).defaultNow().notNull(),
|
||||
},
|
||||
(table) => [
|
||||
unique("unique_sense_per_word").on(table.word_id, table.sense_index),
|
||||
check(
|
||||
"senses_difficulty_check",
|
||||
sql`${table.difficulty} IN (${sql.raw(DIFFICULTY_LEVELS.map((lvl) => `'${lvl}'`).join(", "))})`,
|
||||
),
|
||||
index("idx_word_sense_difficulty").on(table.word_id, table.difficulty),
|
||||
],
|
||||
);
|
||||
|
||||
export const translations = pgTable(
|
||||
"translations",
|
||||
{
|
||||
id: uuid().primaryKey().defaultRandom(),
|
||||
sense_id: uuid()
|
||||
.notNull()
|
||||
.references(() => senses.id, { onDelete: "cascade" }),
|
||||
target_language_code: varchar({ length: 10 }).notNull(),
|
||||
translation: text().notNull(),
|
||||
gender: varchar({ length: 20 }),
|
||||
difficulty: varchar({ length: 20 }).notNull(),
|
||||
created_at: timestamp({ withTimezone: true }).defaultNow().notNull(),
|
||||
},
|
||||
(table) => [
|
||||
unique("unique_translation_per_sense").on(
|
||||
table.sense_id,
|
||||
table.target_language_code,
|
||||
table.translation,
|
||||
),
|
||||
check(
|
||||
"translations_language_code_check",
|
||||
sql`${table.target_language_code} IN (${sql.raw(SUPPORTED_LANGUAGE_CODES.map((code) => `'${code}'`).join(", "))})`,
|
||||
),
|
||||
check(
|
||||
"translations_difficulty_check",
|
||||
sql`${table.difficulty} IN (${sql.raw(DIFFICULTY_LEVELS.map((lvl) => `'${lvl}'`).join(", "))})`,
|
||||
),
|
||||
check(
|
||||
"translations_gender_check",
|
||||
sql`${table.gender} IS NULL OR ${table.gender} IN (${sql.raw(NOUN_GENDERS.map((gender) => `'${gender}'`).join(", "))})`,
|
||||
),
|
||||
index("idx_translations_sense_language_difficulty").on(
|
||||
table.sense_id,
|
||||
table.target_language_code,
|
||||
table.difficulty,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
// ── Auth (managed by Better Auth) ─────────────────────────────────────────────
|
||||
|
||||
export const user = pgTable("user", {
|
||||
|
|
@ -243,6 +333,22 @@ export const entryTranslationRelations = relations(
|
|||
}),
|
||||
);
|
||||
|
||||
export const wordRelations = relations(words, ({ many }) => ({
|
||||
senses: many(senses),
|
||||
}));
|
||||
|
||||
export const senseRelations = relations(senses, ({ one, many }) => ({
|
||||
word: one(words, { fields: [senses.word_id], references: [words.id] }),
|
||||
translations: many(translations),
|
||||
}));
|
||||
|
||||
export const translationRelations = relations(translations, ({ one }) => ({
|
||||
sense: one(senses, {
|
||||
fields: [translations.sense_id],
|
||||
references: [senses.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const userRelations = relations(user, ({ many }) => ({
|
||||
sessions: many(session),
|
||||
accounts: many(account),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue