feat: add user_stats, audit_logs and verification tokens schema
Made-with: Cursor
This commit is contained in:
18
src/db/schema/auditLogs.ts
Normal file
18
src/db/schema/auditLogs.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { pgTable, uuid, varchar, timestamp } from 'drizzle-orm/pg-core';
|
||||
import { jsonb } from 'drizzle-orm/pg-core';
|
||||
import { users } from './users.js';
|
||||
|
||||
export const auditLogs = pgTable('audit_logs', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
adminId: uuid('admin_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
action: varchar('action', { length: 100 }).notNull(),
|
||||
targetType: varchar('target_type', { length: 50 }).notNull(),
|
||||
targetId: uuid('target_id').notNull(),
|
||||
details: jsonb('details').$type<Record<string, unknown>>(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
|
||||
export type AuditLog = typeof auditLogs.$inferSelect;
|
||||
export type NewAuditLog = typeof auditLogs.$inferInsert;
|
||||
@@ -7,3 +7,7 @@ export * from './testQuestions.js';
|
||||
export * from './questionBank.js';
|
||||
export * from './questionCacheMeta.js';
|
||||
export * from './questionReports.js';
|
||||
export * from './userStats.js';
|
||||
export * from './auditLogs.js';
|
||||
export * from './userQuestionLog.js';
|
||||
export * from './verificationTokens.js';
|
||||
|
||||
17
src/db/schema/userQuestionLog.ts
Normal file
17
src/db/schema/userQuestionLog.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { pgTable, uuid, timestamp } from 'drizzle-orm/pg-core';
|
||||
import { users } from './users.js';
|
||||
import { questionBank } from './questionBank.js';
|
||||
|
||||
export const userQuestionLog = pgTable('user_question_log', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
userId: uuid('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
questionBankId: uuid('question_bank_id')
|
||||
.notNull()
|
||||
.references(() => questionBank.id, { onDelete: 'cascade' }),
|
||||
seenAt: timestamp('seen_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
|
||||
export type UserQuestionLog = typeof userQuestionLog.$inferSelect;
|
||||
export type NewUserQuestionLog = typeof userQuestionLog.$inferInsert;
|
||||
26
src/db/schema/userStats.ts
Normal file
26
src/db/schema/userStats.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { pgTable, uuid, integer, timestamp } from 'drizzle-orm/pg-core';
|
||||
import { unique } from 'drizzle-orm/pg-core';
|
||||
import { stackEnum, levelEnum } from './enums.js';
|
||||
import { users } from './users.js';
|
||||
|
||||
export const userStats = pgTable(
|
||||
'user_stats',
|
||||
{
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
userId: uuid('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
stack: stackEnum('stack').notNull(),
|
||||
level: levelEnum('level').notNull(),
|
||||
totalQuestions: integer('total_questions').notNull().default(0),
|
||||
correctAnswers: integer('correct_answers').notNull().default(0),
|
||||
testsTaken: integer('tests_taken').notNull().default(0),
|
||||
lastTestAt: timestamp('last_test_at', { withTimezone: true }),
|
||||
},
|
||||
(t) => ({
|
||||
userStackLevelUnique: unique().on(t.userId, t.stack, t.level),
|
||||
})
|
||||
);
|
||||
|
||||
export type UserStat = typeof userStats.$inferSelect;
|
||||
export type NewUserStat = typeof userStats.$inferInsert;
|
||||
22
src/db/schema/verificationTokens.ts
Normal file
22
src/db/schema/verificationTokens.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { pgTable, uuid, varchar, timestamp } from 'drizzle-orm/pg-core';
|
||||
import { users } from './users.js';
|
||||
|
||||
export const emailVerificationCodes = pgTable('email_verification_codes', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
userId: uuid('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
code: varchar('code', { length: 10 }).notNull(),
|
||||
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
|
||||
export const passwordResetTokens = pgTable('password_reset_tokens', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
userId: uuid('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
tokenHash: varchar('token_hash', { length: 255 }).notNull(),
|
||||
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
Reference in New Issue
Block a user