feat(db): ownership columns and lesson_subscriptions table
This commit is contained in:
@@ -1,16 +1,28 @@
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { integer, sqliteTable, text, index } from 'drizzle-orm/sqlite-core';
|
||||
import type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core';
|
||||
import { integer, sqliteTable, text, index, uniqueIndex } from 'drizzle-orm/sqlite-core';
|
||||
|
||||
export const lessons = sqliteTable('lessons', {
|
||||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||||
parentId: integer('parent_id'),
|
||||
name: text('name').notNull(),
|
||||
description: text('description'),
|
||||
position: integer('position').notNull().default(0),
|
||||
bidirectional: integer('bidirectional', { mode: 'boolean' }).notNull().default(false),
|
||||
createdAt: integer('created_at').notNull().default(sql`(unixepoch())`),
|
||||
updatedAt: integer('updated_at').notNull().default(sql`(unixepoch())`),
|
||||
});
|
||||
export const lessons = sqliteTable(
|
||||
'lessons',
|
||||
{
|
||||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||||
parentId: integer('parent_id'),
|
||||
name: text('name').notNull(),
|
||||
description: text('description'),
|
||||
position: integer('position').notNull().default(0),
|
||||
bidirectional: integer('bidirectional', { mode: 'boolean' }).notNull().default(false),
|
||||
ownerId: integer('owner_id').references(() => users.id, { onDelete: 'cascade' }),
|
||||
visibility: text('visibility', { enum: ['private', 'shared'] }).notNull().default('private'),
|
||||
isCurated: integer('is_curated', { mode: 'boolean' }).notNull().default(false),
|
||||
sourceLessonId: integer('source_lesson_id').references((): AnySQLiteColumn => lessons.id, { onDelete: 'set null' }),
|
||||
createdAt: integer('created_at').notNull().default(sql`(unixepoch())`),
|
||||
updatedAt: integer('updated_at').notNull().default(sql`(unixepoch())`),
|
||||
},
|
||||
(t) => ({
|
||||
ownerIdx: index('lessons_owner_idx').on(t.ownerId),
|
||||
visibilityIdx: index('lessons_visibility_idx').on(t.visibility, t.isCurated),
|
||||
})
|
||||
);
|
||||
|
||||
export const cards = sqliteTable(
|
||||
'cards',
|
||||
@@ -37,10 +49,12 @@ export const cardProgress = sqliteTable(
|
||||
incorrectCount: integer('incorrect_count').notNull().default(0),
|
||||
lastShownAt: integer('last_shown_at'),
|
||||
nextDueAt: integer('next_due_at').notNull().default(0),
|
||||
userId: integer('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
||||
},
|
||||
(t) => ({
|
||||
pk: index('card_progress_pk').on(t.cardId, t.direction),
|
||||
dueIdx: index('card_progress_due_idx').on(t.nextDueAt),
|
||||
userIdx: index('card_progress_user_idx').on(t.userId, t.nextDueAt),
|
||||
})
|
||||
);
|
||||
|
||||
@@ -57,8 +71,12 @@ export const sessions = sqliteTable(
|
||||
cardsIncorrect: integer('cards_incorrect').notNull().default(0),
|
||||
status: text('status', { enum: ['active', 'completed', 'abandoned'] }).notNull().default('active'),
|
||||
queueSnapshot: text('queue_snapshot'),
|
||||
userId: integer('user_id').references(() => users.id, { onDelete: 'cascade' }),
|
||||
},
|
||||
(t) => ({ statusIdx: index('sessions_status_idx').on(t.status) })
|
||||
(t) => ({
|
||||
statusIdx: index('sessions_status_idx').on(t.status),
|
||||
userIdx: index('sessions_user_idx').on(t.userId, t.status),
|
||||
})
|
||||
);
|
||||
|
||||
export const attempts = sqliteTable(
|
||||
@@ -130,6 +148,23 @@ export const authTokens = sqliteTable(
|
||||
})
|
||||
);
|
||||
|
||||
export const lessonSubscriptions = sqliteTable(
|
||||
'lesson_subscriptions',
|
||||
{
|
||||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||||
userId: integer('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
|
||||
lessonId: integer('lesson_id').notNull().references(() => lessons.id, { onDelete: 'cascade' }),
|
||||
createdAt: integer('created_at').notNull().default(sql`(unixepoch())`),
|
||||
},
|
||||
(t) => ({
|
||||
userIdx: index('lesson_subscriptions_user_idx').on(t.userId),
|
||||
lessonIdx: index('lesson_subscriptions_lesson_idx').on(t.lessonId),
|
||||
userLessonUnique: uniqueIndex('lesson_subscriptions_user_lesson_unique').on(t.userId, t.lessonId),
|
||||
})
|
||||
);
|
||||
|
||||
export type LessonSubscriptionRow = typeof lessonSubscriptions.$inferSelect;
|
||||
|
||||
export type LessonRow = typeof lessons.$inferSelect;
|
||||
export type CardRow = typeof cards.$inferSelect;
|
||||
export type CardProgressRow = typeof cardProgress.$inferSelect;
|
||||
|
||||
Reference in New Issue
Block a user