94 lines
3.5 KiB
JavaScript
94 lines
3.5 KiB
JavaScript
import { sqliteTable, integer, text, blob, real } from 'drizzle-orm/sqlite-core';
|
|
import { isNull } from 'drizzle-orm';
|
|
|
|
export const user = sqliteTable('user', {
|
|
id: text('id').primaryKey(),
|
|
age: integer('age'),
|
|
username: text('username').notNull().unique(),
|
|
passwordHash: text('password_hash').notNull()
|
|
});
|
|
|
|
export const session = sqliteTable('session', {
|
|
id: text('id').primaryKey(),
|
|
userId: text('user_id')
|
|
.notNull()
|
|
.references(() => user.id),
|
|
expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull()
|
|
});
|
|
|
|
export const audioFile = sqliteTable('audio_file', {
|
|
id: text('id').primaryKey(),
|
|
filename: text('filename').notNull(),
|
|
contentType: text('content_type').notNull(),
|
|
data: blob('data').default(null), // Temporarily keep for migration
|
|
s3Key: text('s3_key'), // Temporarily optional for migration
|
|
duration: real('duration'),
|
|
fileSize: integer('file_size'),
|
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
deletedAt: integer('deleted_at', { mode: 'timestamp' }) // Soft delete for audio files
|
|
});
|
|
|
|
export const inviteLink = sqliteTable('invite_link', {
|
|
id: text('id').primaryKey(),
|
|
token: text('token').notNull().unique(),
|
|
participantName: text('participant_name'),
|
|
isUsed: integer('is_used', { mode: 'boolean' }).notNull().default(false),
|
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
usedAt: integer('used_at', { mode: 'timestamp' }),
|
|
deletedAt: integer('deleted_at', { mode: 'timestamp' })
|
|
});
|
|
|
|
export const participant = sqliteTable('participant', {
|
|
id: text('id').primaryKey(),
|
|
inviteToken: text('invite_token')
|
|
.notNull()
|
|
.references(() => inviteLink.token),
|
|
sessionId: text('session_id'),
|
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
deletedAt: integer('deleted_at', { mode: 'timestamp' })
|
|
});
|
|
|
|
export const rating = sqliteTable('rating', {
|
|
id: text('id').primaryKey(),
|
|
participantId: text('participant_id')
|
|
.notNull()
|
|
.references(() => participant.id),
|
|
audioFileId: text('audio_file_id')
|
|
.notNull()
|
|
.references(() => audioFile.id),
|
|
timestamp: real('timestamp').notNull(),
|
|
value: real('value').notNull(),
|
|
isCompleted: integer('is_completed', { mode: 'boolean' }).notNull().default(false),
|
|
timeseriesData: text('timeseries_data'), // JSON string of all rating changes (for completed ratings)
|
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
deletedAt: integer('deleted_at', { mode: 'timestamp' }) // Soft delete for redos
|
|
});
|
|
|
|
export const participantProgress = sqliteTable('participant_progress', {
|
|
id: text('id').primaryKey(),
|
|
participantId: text('participant_id')
|
|
.notNull()
|
|
.references(() => participant.id),
|
|
audioFileId: text('audio_file_id')
|
|
.notNull()
|
|
.references(() => audioFile.id),
|
|
isCompleted: integer('is_completed', { mode: 'boolean' }).notNull().default(false),
|
|
lastPosition: real('last_position').default(0),
|
|
maxReachedTime: real('max_reached_time').default(0),
|
|
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull()
|
|
});
|
|
|
|
export const overallRating = sqliteTable('overall_rating', {
|
|
id: text('id').primaryKey(),
|
|
participantId: text('participant_id')
|
|
.notNull()
|
|
.references(() => participant.id),
|
|
audioFileId: text('audio_file_id')
|
|
.notNull()
|
|
.references(() => audioFile.id),
|
|
value: real('value').notNull(), // 0-100 rating value
|
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
|
|
deletedAt: integer('deleted_at', { mode: 'timestamp' }) // Soft delete for potential redos
|
|
});
|