kites/src/db/schema.ts
2025-11-20 18:49:32 -08:00

119 lines
4.1 KiB
TypeScript

import { sqliteTable, text, integer, index, primaryKey } from 'drizzle-orm/sqlite-core';
import { sql } from 'drizzle-orm';
import type { AdapterAccount } from "next-auth/adapters";
// --- Application Tables ---
export const pastes = sqliteTable('pastes', {
id: text('id').primaryKey(), // Nanoid
title: text('title'),
content: text('content').notNull(),
contentType: text('content_type').default('text/plain'),
syntax: text('syntax'),
visibility: text('visibility').default('public'), // 'public', 'unlisted', 'private'
authorId: text('author_id').references(() => users.id, { onDelete: 'set null' }), // Linked to User
sessionId: text('session_id'), // Linked to Agent Session (logical)
expiresAt: integer('expires_at', { mode: 'timestamp' }),
createdAt: integer('created_at', { mode: 'timestamp' }).default(sql`CURRENT_TIMESTAMP`),
updatedAt: integer('updated_at', { mode: 'timestamp' }).default(sql`CURRENT_TIMESTAMP`),
});
export const tags = sqliteTable('tags', {
id: text('id').primaryKey(),
name: text('name').notNull().unique(),
color: text('color'),
description: text('description'),
});
export const pastesToTags = sqliteTable('pastes_to_tags', {
pasteId: text('paste_id').references(() => pastes.id, { onDelete: 'cascade' }),
tagId: text('tag_id').references(() => tags.id, { onDelete: 'cascade' }),
}, (t) => ({
pk: index('pk').on(t.pasteId, t.tagId),
}));
// Renamed from 'sessions' to 'agent_sessions' to avoid conflict with Auth.js
export const agentSessions = sqliteTable('agent_sessions', {
id: text('id').primaryKey(),
title: text('title'),
agentName: text('agent_name'),
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }), // Optional owner
createdAt: integer('created_at', { mode: 'timestamp' }).default(sql`CURRENT_TIMESTAMP`),
});
// --- Auth.js Tables ---
export const users = sqliteTable("user", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
name: text("name"),
email: text("email").notNull(),
emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
image: text("image"),
});
export const accounts = sqliteTable(
"account",
{
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
type: text("type").$type<AdapterAccount["type"]>().notNull(),
provider: text("provider").notNull(),
providerAccountId: text("providerAccountId").notNull(),
refresh_token: text("refresh_token"),
access_token: text("access_token"),
expires_at: integer("expires_at"),
token_type: text("token_type"),
scope: text("scope"),
id_token: text("id_token"),
session_state: text("session_state"),
},
(account) => ({
compoundKey: primaryKey({
columns: [account.provider, account.providerAccountId],
}),
})
);
export const sessions = sqliteTable("session", {
sessionToken: text("sessionToken").primaryKey(),
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
});
export const verificationTokens = sqliteTable(
"verificationToken",
{
identifier: text("identifier").notNull(),
token: text("token").notNull(),
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
},
(verificationToken) => ({
compositePk: primaryKey({
columns: [verificationToken.identifier, verificationToken.token],
}),
})
);
export const authenticators = sqliteTable(
"authenticator",
{
credentialID: text("credentialID").notNull().unique(),
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
providerAccountId: text("providerAccountId").notNull(),
credentialPublicKey: text("credentialPublicKey").notNull(),
counter: integer("counter").notNull(),
credentialDeviceType: text("credentialDeviceType").notNull(),
credentialBackedUp: integer("credentialBackedUp").notNull(),
transports: text("transports"),
},
(authenticator) => ({
compositePK: primaryKey({
columns: [authenticator.userId, authenticator.credentialID],
}),
})
);