import { boolean, check, integer, pgTable, text, timestamp, uuid, } from 'drizzle-orm/pg-core'; import { sql } from 'drizzle-orm'; import { users } from './identity'; /** Workspace-wide controls. The check keeps this deliberately single-tenant. */ export const platformSettings = pgTable( 'platform_settings', { id: text('id').primaryKey().default('default'), piggyModel: text('piggy_model').notNull().default('nvidia/nemotron-3-nano-30b-a3b'), piggyInferenceBase: text('piggy_inference_base') .notNull() .default('https://api.pinference.ai/api/v1'), piggyEnabled: boolean('piggy_enabled').notNull().default(false), /** AES-256-GCM envelope. Its key lives outside the database. */ primeApiKeyEncrypted: text('prime_api_key_encrypted'), primeApiKeyUpdatedAt: timestamp('prime_api_key_updated_at', { withTimezone: true }), primeSyncEnabled: boolean('prime_sync_enabled').notNull().default(false), primeSyncIntervalMinutes: integer('prime_sync_interval_minutes').notNull().default(30), /** * The Learn share code, in the database because it is rotatable. * * Not an env var and not a constant: rotating it must be something an * administrator does at 11pm when it has been forwarded outside the * company, without a redeploy. Stored in clear rather than hashed because * it is a passphrase a human reads aloud and an admin has to be able to * see it to share it — and because it grants nothing but the platform * track, which is marketing material. It is compared in constant time all * the same; the timing of a wrong answer should not narrow the guess. * * The initial value is a column default so the row is never without one. */ learnAccessCode: text('learn_access_code').notNull().default('carlthefog'), learnAccessCodeUpdatedAt: timestamp('learn_access_code_updated_at', { withTimezone: true }), updatedByUserId: uuid('updated_by_user_id').references(() => users.id, { onDelete: 'set null', }), updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), }, (t) => [ check('platform_settings_singleton_check', sql`${t.id} = 'default'`), check( 'platform_settings_sync_interval_check', sql`${t.primeSyncIntervalMinutes} BETWEEN 1 AND 1440`, ), ], ); export type PlatformSettings = typeof platformSettings.$inferSelect;