Initial commit
This commit is contained in:
16
lib/db/index.ts
Normal file
16
lib/db/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { drizzle } from 'drizzle-orm/postgres-js'
|
||||
import postgres from 'postgres'
|
||||
import * as schema from './schema'
|
||||
|
||||
// In Next.js, avoid creating multiple connections in development due to hot reload
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var _pgClient: ReturnType<typeof postgres> | undefined
|
||||
}
|
||||
|
||||
const connectionString = process.env.DATABASE_URL!
|
||||
|
||||
const client = globalThis._pgClient ?? postgres(connectionString)
|
||||
if (process.env.NODE_ENV !== 'production') globalThis._pgClient = client
|
||||
|
||||
export const db = drizzle(client, { schema })
|
||||
79
lib/db/schema.ts
Normal file
79
lib/db/schema.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import {
|
||||
pgTable,
|
||||
uuid,
|
||||
text,
|
||||
boolean,
|
||||
timestamp,
|
||||
integer,
|
||||
} from 'drizzle-orm/pg-core'
|
||||
import { sql } from 'drizzle-orm'
|
||||
|
||||
export const users = pgTable('users', {
|
||||
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
|
||||
email: text('email').unique().notNull(),
|
||||
passwordHash: text('password_hash').notNull(),
|
||||
fullName: text('full_name'),
|
||||
company: text('company'),
|
||||
role: text('role').default('user').notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const machines = pgTable('machines', {
|
||||
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
|
||||
userId: uuid('user_id').references(() => users.id, { onDelete: 'cascade' }).notNull(),
|
||||
name: text('name').notNull(),
|
||||
hostname: text('hostname'),
|
||||
os: text('os'),
|
||||
osVersion: text('os_version'),
|
||||
agentVersion: text('agent_version'),
|
||||
ipAddress: text('ip_address'),
|
||||
accessKey: text('access_key').unique().notNull(),
|
||||
isOnline: boolean('is_online').default(false).notNull(),
|
||||
lastSeen: timestamp('last_seen', { withTimezone: true }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const sessionCodes = pgTable('session_codes', {
|
||||
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
|
||||
code: text('code').notNull(),
|
||||
machineId: uuid('machine_id').references(() => machines.id, { onDelete: 'cascade' }).notNull(),
|
||||
createdBy: uuid('created_by').references(() => users.id, { onDelete: 'set null' }),
|
||||
expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
|
||||
isActive: boolean('is_active').default(true).notNull(),
|
||||
usedAt: timestamp('used_at', { withTimezone: true }),
|
||||
usedBy: uuid('used_by').references(() => users.id, { onDelete: 'set null' }),
|
||||
})
|
||||
|
||||
export const sessions = pgTable('sessions', {
|
||||
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
|
||||
machineId: uuid('machine_id').references(() => machines.id, { onDelete: 'set null' }),
|
||||
machineName: text('machine_name'),
|
||||
viewerUserId: uuid('viewer_user_id').references(() => users.id, { onDelete: 'set null' }),
|
||||
connectionType: text('connection_type'),
|
||||
sessionCode: text('session_code'),
|
||||
startedAt: timestamp('started_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
endedAt: timestamp('ended_at', { withTimezone: true }),
|
||||
durationSeconds: integer('duration_seconds'),
|
||||
notes: text('notes'),
|
||||
})
|
||||
|
||||
export const invites = pgTable('invites', {
|
||||
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
|
||||
token: uuid('token').unique().notNull().default(sql`gen_random_uuid()`),
|
||||
email: text('email').notNull(),
|
||||
createdBy: uuid('created_by').references(() => users.id, { onDelete: 'set null' }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
expiresAt: timestamp('expires_at', { withTimezone: true })
|
||||
.notNull()
|
||||
.default(sql`now() + interval '7 days'`),
|
||||
usedAt: timestamp('used_at', { withTimezone: true }),
|
||||
usedBy: uuid('used_by').references(() => users.id, { onDelete: 'set null' }),
|
||||
})
|
||||
|
||||
export type User = typeof users.$inferSelect
|
||||
export type Machine = typeof machines.$inferSelect
|
||||
export type SessionCode = typeof sessionCodes.$inferSelect
|
||||
export type Session = typeof sessions.$inferSelect
|
||||
export type Invite = typeof invites.$inferSelect
|
||||
Reference in New Issue
Block a user