feat(db): add phase1 device role, links, and commands schema

This commit is contained in:
2025-12-21 15:50:00 +00:00
parent cdaab7f0c1
commit 4fa525d8db
4 changed files with 107 additions and 17 deletions

View File

@@ -1,4 +1,4 @@
import { pgTable, timestamp, uuid, varchar, text, boolean } from 'drizzle-orm/pg-core';
import { pgTable, timestamp, uuid, varchar, text, boolean, integer, jsonb, unique } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').defaultRandom().primaryKey(),
@@ -15,11 +15,49 @@ export const devices = pgTable('devices', {
id: uuid('id').defaultRandom().primaryKey(),
userId: uuid('user_id').notNull().references(() => users.id),
name: varchar('name', { length: 255 }),
role: varchar('role', { length: 32 }).default('client').notNull(),
platform: varchar('platform', { length: 32 }),
appVersion: varchar('app_version', { length: 64 }),
pushToken: text('push_token'),
status: varchar('status', { length: 32 }).default('offline').notNull(),
isCamera: boolean('is_camera').default(false).notNull(),
lastSeenAt: timestamp('last_seen_at', { withTimezone: true }),
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
});
export const deviceLinks = pgTable(
'device_links',
{
id: uuid('id').defaultRandom().primaryKey(),
ownerUserId: uuid('owner_user_id').notNull().references(() => users.id),
cameraDeviceId: uuid('camera_device_id').notNull().references(() => devices.id),
clientDeviceId: uuid('client_device_id').notNull().references(() => devices.id),
status: varchar('status', { length: 32 }).default('active').notNull(),
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
},
(table) => ({
uniqueDevicePair: unique('device_links_camera_client_unique').on(table.cameraDeviceId, table.clientDeviceId),
}),
);
export const deviceCommands = pgTable('device_commands', {
id: uuid('id').defaultRandom().primaryKey(),
ownerUserId: uuid('owner_user_id').notNull().references(() => users.id),
sourceDeviceId: uuid('source_device_id').notNull().references(() => devices.id),
targetDeviceId: uuid('target_device_id').notNull().references(() => devices.id),
commandType: varchar('command_type', { length: 64 }).notNull(),
payload: jsonb('payload').$type<Record<string, unknown> | null>().default(null),
status: varchar('status', { length: 32 }).default('queued').notNull(),
retryCount: integer('retry_count').default(0).notNull(),
lastDispatchedAt: timestamp('last_dispatched_at', { withTimezone: true }),
acknowledgedAt: timestamp('acknowledged_at', { withTimezone: true }),
error: text('error'),
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
});
export const events = pgTable('events', {
id: uuid('id').defaultRandom().primaryKey(),
userId: uuid('user_id').notNull().references(() => users.id),
@@ -99,6 +137,8 @@ export const verifications = pgTable('verification', {
export const schema = {
users,
devices,
deviceLinks,
deviceCommands,
events,
videos,
notifications,