feat: add apiKey plugin and new schema tables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7
web/src/lib/auth-client.ts
Normal file
7
web/src/lib/auth-client.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createAuthClient } from 'better-auth/svelte';
|
||||
import { apiKeyClient } from 'better-auth/client/plugins';
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: 'http://localhost:5173',
|
||||
plugins: [apiKeyClient()]
|
||||
});
|
||||
16
web/src/lib/server/auth.ts
Normal file
16
web/src/lib/server/auth.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { betterAuth } from 'better-auth';
|
||||
import { sveltekitCookies } from 'better-auth/svelte-kit';
|
||||
import { apiKey } from 'better-auth/plugins';
|
||||
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
|
||||
import { db } from './db';
|
||||
import { getRequestEvent } from '$app/server';
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: drizzleAdapter(db, {
|
||||
provider: 'pg'
|
||||
}),
|
||||
plugins: [sveltekitCookies(getRequestEvent), apiKey()],
|
||||
emailAndPassword: {
|
||||
enabled: true
|
||||
}
|
||||
});
|
||||
116
web/src/lib/server/db/schema.ts
Normal file
116
web/src/lib/server/db/schema.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { pgTable, text, timestamp, boolean, integer, jsonb } from 'drizzle-orm/pg-core';
|
||||
|
||||
export const user = pgTable('user', {
|
||||
id: text('id').primaryKey(),
|
||||
name: text('name').notNull(),
|
||||
email: text('email').notNull().unique(),
|
||||
emailVerified: boolean('email_verified').default(false).notNull(),
|
||||
image: text('image'),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at')
|
||||
.defaultNow()
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date())
|
||||
.notNull()
|
||||
});
|
||||
|
||||
export const session = pgTable('session', {
|
||||
id: text('id').primaryKey(),
|
||||
expiresAt: timestamp('expires_at').notNull(),
|
||||
token: text('token').notNull().unique(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at')
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date())
|
||||
.notNull(),
|
||||
ipAddress: text('ip_address'),
|
||||
userAgent: text('user_agent'),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' })
|
||||
});
|
||||
|
||||
export const account = pgTable('account', {
|
||||
id: text('id').primaryKey(),
|
||||
accountId: text('account_id').notNull(),
|
||||
providerId: text('provider_id').notNull(),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
accessToken: text('access_token'),
|
||||
refreshToken: text('refresh_token'),
|
||||
idToken: text('id_token'),
|
||||
accessTokenExpiresAt: timestamp('access_token_expires_at'),
|
||||
refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
|
||||
scope: text('scope'),
|
||||
password: text('password'),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at')
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date())
|
||||
.notNull()
|
||||
});
|
||||
|
||||
export const verification = pgTable('verification', {
|
||||
id: text('id').primaryKey(),
|
||||
identifier: text('identifier').notNull(),
|
||||
value: text('value').notNull(),
|
||||
expiresAt: timestamp('expires_at').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at')
|
||||
.defaultNow()
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date())
|
||||
.notNull()
|
||||
});
|
||||
|
||||
export const llmConfig = pgTable('llm_config', {
|
||||
id: text('id').primaryKey(),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
provider: text('provider').notNull(),
|
||||
apiKey: text('api_key').notNull(),
|
||||
model: text('model'),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at')
|
||||
.defaultNow()
|
||||
.$onUpdate(() => new Date())
|
||||
.notNull()
|
||||
});
|
||||
|
||||
export const device = pgTable('device', {
|
||||
id: text('id').primaryKey(),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
name: text('name').notNull(),
|
||||
lastSeen: timestamp('last_seen'),
|
||||
status: text('status').notNull().default('offline'),
|
||||
deviceInfo: jsonb('device_info'),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const agentSession = pgTable('agent_session', {
|
||||
id: text('id').primaryKey(),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
deviceId: text('device_id')
|
||||
.notNull()
|
||||
.references(() => device.id, { onDelete: 'cascade' }),
|
||||
goal: text('goal').notNull(),
|
||||
status: text('status').notNull().default('running'),
|
||||
stepsUsed: integer('steps_used').default(0),
|
||||
startedAt: timestamp('started_at').defaultNow().notNull(),
|
||||
completedAt: timestamp('completed_at')
|
||||
});
|
||||
|
||||
export const agentStep = pgTable('agent_step', {
|
||||
id: text('id').primaryKey(),
|
||||
sessionId: text('session_id')
|
||||
.notNull()
|
||||
.references(() => agentSession.id, { onDelete: 'cascade' }),
|
||||
stepNumber: integer('step_number').notNull(),
|
||||
screenHash: text('screen_hash'),
|
||||
action: jsonb('action'),
|
||||
reasoning: text('reasoning'),
|
||||
result: text('result'),
|
||||
timestamp: timestamp('timestamp').defaultNow().notNull()
|
||||
});
|
||||
Reference in New Issue
Block a user