diff --git a/src/apps/officer-web/App.tsx b/src/apps/officer-web/App.tsx index b8d40a93..64da4fd0 100644 --- a/src/apps/officer-web/App.tsx +++ b/src/apps/officer-web/App.tsx @@ -8,7 +8,7 @@ import { useInitialData } from '@/state/useInitialData'; export function App() { const { isLoading, isAuthenticated } = useAuth(); - const { onboardingComplete, plugins, isLoading: isServerSettingsLoading } = useServerSettings(); + const { plugins, isLoading: isServerSettingsLoading } = useServerSettings(); useServerEnvironment(); useInitialData(); @@ -26,14 +26,7 @@ export function App() { )} - {/* {isAuthenticated && !onboardingComplete && ( */} - {/* */} - {/* } /> */} - {/* } /> */} - {/* } /> */} - {/* */} - {/* )} */} - {isAuthenticated && onboardingComplete && ( + {isAuthenticated && ( } /> diff --git a/src/apps/officer-web/Screens/Dashboard/Home/HomeScreen.tsx b/src/apps/officer-web/Screens/Dashboard/Home/HomeScreen.tsx index f0577676..10b849d9 100644 --- a/src/apps/officer-web/Screens/Dashboard/Home/HomeScreen.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Home/HomeScreen.tsx @@ -1,61 +1,14 @@ -import type { LayoutNode, PanelComponents, DefaultFileSort } from 'officerdev'; -import { WorkspaceView, useFileViewerPanels } from 'officerdev'; +import type { LayoutNode } from 'officerdev'; +import { WorkspaceView } from 'officerdev'; import { useDashboardState } from 'state/useDashboardState'; -import { useSettings } from 'state/useSettings'; -import { Button } from '@/components/ui/button'; import { defaultLayout } from './defaultLayout'; -const HomeHeader = () => { - const { settings, saveSettings } = useSettings(); - - const completeOnboarding = () => { - saveSettings({ ...settings, onboarding: { complete: true } }); - }; - - return ( -
-
-

Welcome to your Officer.dev platform

-

- Please follow the video instructions below in order to get familiar with all that is possible. -

- -
-
- ); -}; - -const components: PanelComponents = { - 'home-header': HomeHeader, -}; - -const defaultSort: DefaultFileSort = { field: 'type', direction: 'desc' }; - export const HomeScreen = () => { const workspace = useDashboardState('screens/home', defaultLayout); - const ephemeral = useFileViewerPanels(); - const { settings } = useSettings(); - - if (settings.onboarding.complete) { - return ( -
- -
- ); - } return (
- +
); }; diff --git a/src/apps/officer-web/Screens/Dashboard/Home/defaultLayout.tsx b/src/apps/officer-web/Screens/Dashboard/Home/defaultLayout.tsx index 7e2ef6e6..b7f274b5 100644 --- a/src/apps/officer-web/Screens/Dashboard/Home/defaultLayout.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Home/defaultLayout.tsx @@ -4,9 +4,5 @@ export const defaultLayout: LayoutNode = { type: 'group', id: 'home-root', direction: 'vertical', - children: [ - { node: { type: 'panel', id: 'home-header', appType: null }, size: 30 }, - { node: { type: 'panel', id: 'home-files', appType: 'officerdev/file-browser' }, size: 70 }, - ], + children: [{ node: { type: 'panel', id: 'home-files', appType: 'officerdev/file-browser' }, size: 100 }], }; - diff --git a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/AIHarnessesCard.tsx b/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/AIHarnessesCard.tsx deleted file mode 100644 index dd36461e..00000000 --- a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/AIHarnessesCard.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { useState } from 'react'; -import { Terminal, Copy, Check } from 'lucide-react'; -import { useQuery, useQueryClient } from '@tanstack/react-query'; -import { Button } from '@/components/ui/button'; -import { Card } from '@/components/Card'; -import { useClient } from 'hooks/useClient'; - -type AIHarnessesCardProps = { - onNext: () => void; - onBack: () => void; - saveSettings: (settings: Record) => Promise; -}; - -export const AIHarnessesCard = ({ onNext, onBack, saveSettings }: AIHarnessesCardProps) => { - const client = useClient(); - const queryClient = useQueryClient(); - const [installing, setInstalling] = useState(false); - - type VersionInfo = { version: string | null; path: string | null; globalPath: string | null }; - type ClaudeAuthInfo = { authenticated: boolean; loggedIn?: boolean; subscriptionType?: string }; - - const { data: claudeVersion, isLoading: claudeLoading } = useQuery({ - queryKey: ['CLAUDE_CODE_VERSION'], - queryFn: () => client.get('/server-settings/claude-code/version'), - refetchInterval: (query) => { - const data = query.state.data; - return data?.version && !data?.globalPath ? 1000 : false; - }, - }); - - const { data: claudeAuth } = useQuery({ - queryKey: ['CLAUDE_CODE_AUTH'], - queryFn: () => client.get('/server-settings/claude-code/auth'), - enabled: !!claudeVersion?.version, - refetchInterval: (query) => (!query.state.data?.authenticated ? 2000 : false), - }); - - const installClaude = async () => { - setInstalling(true); - try { - const result = await client.post('/server-settings/claude-code/install'); - queryClient.setQueryData(['CLAUDE_CODE_VERSION'], result); - } finally { - setInstalling(false); - } - }; - - const [copied, setCopied] = useState(null); - - const copyToClipboard = (text: string) => { - navigator.clipboard.writeText(text); - setCopied(text); - setTimeout(() => setCopied(null), 1500); - }; - - const CopyCommand = ({ command }: { command: string }) => ( -
- Not globally accessible. Run: -
- {command} - -
-
- ); - - const claudeReady = !!claudeVersion?.version && !!claudeVersion?.globalPath && !!claudeAuth?.authenticated; - - const handleNext = async () => { - await saveSettings({ aiHarnesses: { claudeCode: true }, onboardingComplete: true }); - onNext(); - }; - - return ( - -
- -

AI Harnesses

-
-

Set up Claude Code for AI-assisted development.

- -
-
- Claude Code -
- {claudeLoading ? ( - 'Checking version...' - ) : claudeVersion?.version ? ( - <> -
{claudeVersion.version}
-
{claudeVersion.path}
- {claudeAuth && ( -
- {claudeAuth.authenticated ? ( - `Logged in (${claudeAuth.subscriptionType ?? 'unknown plan'})` - ) : ( -
- Not logged in - -
- )} -
- )} - {!claudeVersion.globalPath && claudeVersion.path && ( - - )} - - ) : ( - - )} -
-
-
- -
- - -
-
- ); -}; diff --git a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/ServerTypeCard.tsx b/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/ServerTypeCard.tsx deleted file mode 100644 index fec70b80..00000000 --- a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/ServerTypeCard.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { useState } from 'react'; -import { Building2, UserRound } from 'lucide-react'; -import { Button } from '@/components/ui/button'; -import { Card } from '@/components/Card'; - -type AccountMode = 'organization' | 'single' | null; - -type ServerTypeCardProps = { - onNext: () => void; - saveSettings: (settings: Record) => Promise; -}; - -export const ServerTypeCard = ({ onNext, saveSettings }: ServerTypeCardProps) => { - const [accountMode, setAccountMode] = useState(null); - - const handleNext = async () => { - await saveSettings({ accountMode }); - onNext(); - }; - - return ( - -

Account Type

-

How will you be using Officer?

- -
- - - -
- -
- -
-
- ); -}; diff --git a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx b/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx deleted file mode 100644 index d586469a..00000000 --- a/src/apps/officer-web/Screens/Dashboard/OnboardingAdmin/index.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { useState, useEffect } from 'react'; -import { useServerSettings } from 'state/useServerSettings'; -import { ServerTypeCard } from './ServerTypeCard'; -import { AIHarnessesCard } from './AIHarnessesCard'; - -const STEPS = ['server-type', 'ai-harnesses'] as const; -type Step = (typeof STEPS)[number]; - -const getStepFromHash = (): Step => { - const hash = window.location.hash.slice(1); - if (STEPS.includes(hash as Step)) return hash as Step; - return STEPS[0]!; -}; - -const setHash = (step: Step) => { - window.location.hash = step; -}; - -export const OnboardingAdmin = () => { - const { saveSettings } = useServerSettings(); - const [step, setStep] = useState(getStepFromHash); - - useEffect(() => { - const onHashChange = () => setStep(getStepFromHash()); - window.addEventListener('hashchange', onHashChange); - return () => window.removeEventListener('hashchange', onHashChange); - }, []); - - useEffect(() => { - setHash(step); - }, [step]); - - const currentIndex = STEPS.indexOf(step); - - const nextStep = () => { - if (currentIndex < STEPS.length - 1) { - setStep(STEPS[currentIndex + 1]!); - } - }; - - const prevStep = () => { - if (currentIndex > 0) { - setStep(STEPS[currentIndex - 1]!); - } - }; - - return ( -
-
- {step === 'server-type' && } - {step === 'ai-harnesses' && ( - - )} -
-
- ); -}; diff --git a/src/apps/officer-web/Screens/Dashboard/index.tsx b/src/apps/officer-web/Screens/Dashboard/index.tsx index 249b71ee..044c62b1 100644 --- a/src/apps/officer-web/Screens/Dashboard/index.tsx +++ b/src/apps/officer-web/Screens/Dashboard/index.tsx @@ -1,6 +1,5 @@ export * from './Layout'; export * from './Home'; -export * from './OnboardingAdmin'; export * from './PasskeyGate'; export * from './Plans'; export * from './Processes'; diff --git a/src/databases/officer_db/migrations/0000_eager_sir_ram.sql b/src/databases/officer_db/migrations/0000_eager_sir_ram.sql new file mode 100644 index 00000000..c51fdde5 --- /dev/null +++ b/src/databases/officer_db/migrations/0000_eager_sir_ram.sql @@ -0,0 +1,228 @@ +CREATE TABLE "passkey_challenges" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "origin" text NOT NULL, + "challenge" text NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "expires_at" timestamp with time zone NOT NULL +); +--> statement-breakpoint +CREATE TABLE "passkeys" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "origin" text, + "credential_id" text, + "public_key" text, + "counter" integer DEFAULT 0 NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "token_blacklist" ( + "jti" text PRIMARY KEY NOT NULL, + "expires_at" timestamp with time zone NOT NULL +); +--> statement-breakpoint +CREATE TABLE "users" ( + "id" serial PRIMARY KEY NOT NULL, + "email" text NOT NULL, + "password" text, + "status" text DEFAULT 'Unverified' NOT NULL, + "name" text, + "username" text, + "avatar" text, + "password_changed_at" timestamp with time zone, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "users_email_unique" UNIQUE("email"), + CONSTRAINT "users_username_unique" UNIQUE("username") +); +--> statement-breakpoint +CREATE TABLE "dock_configs" ( + "user_id" integer PRIMARY KEY NOT NULL, + "paths" jsonb DEFAULT '[]'::jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "user_integrations" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "provider" text NOT NULL, + "server_integration_id" integer, + "config" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "uq_user_integrations_user_provider" UNIQUE("user_id","provider") +); +--> statement-breakpoint +CREATE TABLE "user_settings" ( + "user_id" integer PRIMARY KEY NOT NULL, + "settings" jsonb DEFAULT '{}'::jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "user_state" ( + "user_id" integer PRIMARY KEY NOT NULL, + "state" jsonb DEFAULT '{}'::jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "dashboard_defaults" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "terminals" jsonb DEFAULT '{}'::jsonb NOT NULL, + "host_terminals" jsonb DEFAULT '{}'::jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "dashboard_defaults_user_id_unique" UNIQUE("user_id") +); +--> statement-breakpoint +CREATE TABLE "dashboards" ( + "id" text PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "name" text NOT NULL, + "config" jsonb DEFAULT '{}'::jsonb NOT NULL, + "layout" jsonb DEFAULT '[]'::jsonb NOT NULL, + "terminals" jsonb DEFAULT '[]'::jsonb NOT NULL, + "host_terminals" jsonb DEFAULT '[]'::jsonb NOT NULL, + "sort_order" integer DEFAULT 0 NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "uq_dashboards_user_id" UNIQUE("user_id","id") +); +--> statement-breakpoint +CREATE TABLE "projects" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "slug" text NOT NULL, + "meta" jsonb DEFAULT '{}'::jsonb NOT NULL, + "layout" jsonb DEFAULT '[]'::jsonb NOT NULL, + "terminals" jsonb DEFAULT '[]'::jsonb NOT NULL, + "host_terminals" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "uq_projects_user_slug" UNIQUE("user_id","slug") +); +--> statement-breakpoint +CREATE TABLE "screens" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "name" text NOT NULL, + "layout" jsonb DEFAULT '[]'::jsonb NOT NULL, + "terminals" jsonb DEFAULT '{}'::jsonb NOT NULL, + "host_terminals" jsonb DEFAULT '{}'::jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "uq_screens_user_name" UNIQUE("user_id","name") +); +--> statement-breakpoint +CREATE TABLE "queue_jobs" ( + "id" text PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "lane" text NOT NULL, + "type" text NOT NULL, + "status" text DEFAULT 'queued' NOT NULL, + "current_step" integer DEFAULT 0 NOT NULL, + "steps" jsonb DEFAULT '[]'::jsonb NOT NULL, + "meta" jsonb, + "error" text, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "started_at" timestamp with time zone, + "completed_at" timestamp with time zone +); +--> statement-breakpoint +CREATE TABLE "task_logs" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "task_name" text NOT NULL, + "task_dir_name" text NOT NULL, + "entry_name" text NOT NULL, + "entry_type" text NOT NULL, + "provider" text NOT NULL, + "model" text NOT NULL, + "is_error" boolean DEFAULT false NOT NULL, + "messages" jsonb DEFAULT '[]'::jsonb NOT NULL, + "started_at" timestamp with time zone NOT NULL, + "completed_at" timestamp with time zone +); +--> statement-breakpoint +CREATE TABLE "terminal_containers" ( + "user_id" integer PRIMARY KEY NOT NULL, + "docker_id" text NOT NULL, + "port" integer NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "server_config" ( + "key" text PRIMARY KEY NOT NULL, + "value" jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint +CREATE TABLE "server_integrations" ( + "id" serial PRIMARY KEY NOT NULL, + "provider" text NOT NULL, + "enabled" boolean DEFAULT true NOT NULL, + "config" jsonb DEFAULT '{}'::jsonb NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "server_integrations_provider_unique" UNIQUE("provider") +); +--> statement-breakpoint +CREATE TABLE "email_accounts" ( + "id" serial PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "provider" text NOT NULL, + "email" text NOT NULL, + "display_name" text, + "imap_host" text NOT NULL, + "imap_port" integer NOT NULL, + "imap_secure" boolean DEFAULT true NOT NULL, + "auth_type" text NOT NULL, + "credentials" jsonb DEFAULT '{}'::jsonb NOT NULL, + "enabled" boolean DEFAULT true NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "status" text DEFAULT 'connected' NOT NULL, + "sync_meta" jsonb DEFAULT '{}'::jsonb NOT NULL, + "updated_at" timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT "uq_email_accounts_user_email" UNIQUE("user_id","email") +); +--> statement-breakpoint +CREATE TABLE "pipeline_jobs" ( + "id" text PRIMARY KEY NOT NULL, + "user_id" integer NOT NULL, + "task_dir_name" text NOT NULL, + "task_name" text NOT NULL, + "mode" text DEFAULT 'pipeline' NOT NULL, + "status" text DEFAULT 'pending' NOT NULL, + "inputs" jsonb DEFAULT '{}'::jsonb NOT NULL, + "cwd" text, + "config" jsonb NOT NULL, + "progress" jsonb, + "total_cost" jsonb, + "error" text, + "exit_code" integer, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "started_at" timestamp with time zone, + "completed_at" timestamp with time zone +); +--> statement-breakpoint +ALTER TABLE "passkey_challenges" ADD CONSTRAINT "passkey_challenges_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "passkeys" ADD CONSTRAINT "passkeys_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "dock_configs" ADD CONSTRAINT "dock_configs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "user_integrations" ADD CONSTRAINT "user_integrations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "user_integrations" ADD CONSTRAINT "user_integrations_server_integration_id_server_integrations_id_fk" FOREIGN KEY ("server_integration_id") REFERENCES "public"."server_integrations"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "user_settings" ADD CONSTRAINT "user_settings_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "user_state" ADD CONSTRAINT "user_state_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "dashboard_defaults" ADD CONSTRAINT "dashboard_defaults_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "dashboards" ADD CONSTRAINT "dashboards_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "projects" ADD CONSTRAINT "projects_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "screens" ADD CONSTRAINT "screens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "queue_jobs" ADD CONSTRAINT "queue_jobs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "task_logs" ADD CONSTRAINT "task_logs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "terminal_containers" ADD CONSTRAINT "terminal_containers_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "email_accounts" ADD CONSTRAINT "email_accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "pipeline_jobs" ADD CONSTRAINT "pipeline_jobs_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "idx_token_blacklist_expires" ON "token_blacklist" USING btree ("expires_at");--> statement-breakpoint +CREATE INDEX "idx_queue_jobs_status_lane" ON "queue_jobs" USING btree ("status","lane");--> statement-breakpoint +CREATE INDEX "idx_queue_jobs_user" ON "queue_jobs" USING btree ("user_id");--> statement-breakpoint +CREATE INDEX "idx_task_logs_user_started" ON "task_logs" USING btree ("user_id","started_at");--> statement-breakpoint +CREATE INDEX "idx_pipeline_jobs_user_created" ON "pipeline_jobs" USING btree ("user_id","created_at");--> statement-breakpoint +CREATE INDEX "idx_pipeline_jobs_status" ON "pipeline_jobs" USING btree ("status"); \ No newline at end of file diff --git a/src/databases/officer_db/migrations/meta/0000_snapshot.json b/src/databases/officer_db/migrations/meta/0000_snapshot.json new file mode 100644 index 00000000..0a15a38e --- /dev/null +++ b/src/databases/officer_db/migrations/meta/0000_snapshot.json @@ -0,0 +1,1575 @@ +{ + "id": "251f147c-5aeb-41e8-8f24-8a6e2892eaeb", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.passkey_challenges": { + "name": "passkey_challenges", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "challenge": { + "name": "challenge", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "passkey_challenges_user_id_users_id_fk": { + "name": "passkey_challenges_user_id_users_id_fk", + "tableFrom": "passkey_challenges", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.passkeys": { + "name": "passkeys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "counter": { + "name": "counter", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "passkeys_user_id_users_id_fk": { + "name": "passkeys_user_id_users_id_fk", + "tableFrom": "passkeys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.token_blacklist": { + "name": "token_blacklist", + "schema": "", + "columns": { + "jti": { + "name": "jti", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_token_blacklist_expires": { + "name": "idx_token_blacklist_expires", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Unverified'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar": { + "name": "avatar", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password_changed_at": { + "name": "password_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_unique": { + "name": "users_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + }, + "users_username_unique": { + "name": "users_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dock_configs": { + "name": "dock_configs", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "paths": { + "name": "paths", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "dock_configs_user_id_users_id_fk": { + "name": "dock_configs_user_id_users_id_fk", + "tableFrom": "dock_configs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_integrations": { + "name": "user_integrations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "server_integration_id": { + "name": "server_integration_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_integrations_user_id_users_id_fk": { + "name": "user_integrations_user_id_users_id_fk", + "tableFrom": "user_integrations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_integrations_server_integration_id_server_integrations_id_fk": { + "name": "user_integrations_server_integration_id_server_integrations_id_fk", + "tableFrom": "user_integrations", + "tableTo": "server_integrations", + "columnsFrom": [ + "server_integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_user_integrations_user_provider": { + "name": "uq_user_integrations_user_provider", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "provider" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_settings": { + "name": "user_settings", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_settings_user_id_users_id_fk": { + "name": "user_settings_user_id_users_id_fk", + "tableFrom": "user_settings", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_state": { + "name": "user_state", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "state": { + "name": "state", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_state_user_id_users_id_fk": { + "name": "user_state_user_id_users_id_fk", + "tableFrom": "user_state", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dashboard_defaults": { + "name": "dashboard_defaults", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "terminals": { + "name": "terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "host_terminals": { + "name": "host_terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "dashboard_defaults_user_id_users_id_fk": { + "name": "dashboard_defaults_user_id_users_id_fk", + "tableFrom": "dashboard_defaults", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dashboard_defaults_user_id_unique": { + "name": "dashboard_defaults_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dashboards": { + "name": "dashboards", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "layout": { + "name": "layout", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "terminals": { + "name": "terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "host_terminals": { + "name": "host_terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "dashboards_user_id_users_id_fk": { + "name": "dashboards_user_id_users_id_fk", + "tableFrom": "dashboards", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_dashboards_user_id": { + "name": "uq_dashboards_user_id", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "meta": { + "name": "meta", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "layout": { + "name": "layout", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "terminals": { + "name": "terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "host_terminals": { + "name": "host_terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "projects_user_id_users_id_fk": { + "name": "projects_user_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_projects_user_slug": { + "name": "uq_projects_user_slug", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.screens": { + "name": "screens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "layout": { + "name": "layout", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "terminals": { + "name": "terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "host_terminals": { + "name": "host_terminals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "screens_user_id_users_id_fk": { + "name": "screens_user_id_users_id_fk", + "tableFrom": "screens", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_screens_user_name": { + "name": "uq_screens_user_name", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.queue_jobs": { + "name": "queue_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "lane": { + "name": "lane", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "current_step": { + "name": "current_step", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "steps": { + "name": "steps", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "meta": { + "name": "meta", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_queue_jobs_status_lane": { + "name": "idx_queue_jobs_status_lane", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "lane", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_queue_jobs_user": { + "name": "idx_queue_jobs_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "queue_jobs_user_id_users_id_fk": { + "name": "queue_jobs_user_id_users_id_fk", + "tableFrom": "queue_jobs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.task_logs": { + "name": "task_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "task_name": { + "name": "task_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "task_dir_name": { + "name": "task_dir_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entry_name": { + "name": "entry_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entry_type": { + "name": "entry_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_error": { + "name": "is_error", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "messages": { + "name": "messages", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_task_logs_user_started": { + "name": "idx_task_logs_user_started", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "task_logs_user_id_users_id_fk": { + "name": "task_logs_user_id_users_id_fk", + "tableFrom": "task_logs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.terminal_containers": { + "name": "terminal_containers", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "docker_id": { + "name": "docker_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port": { + "name": "port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "terminal_containers_user_id_users_id_fk": { + "name": "terminal_containers_user_id_users_id_fk", + "tableFrom": "terminal_containers", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.server_config": { + "name": "server_config", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.server_integrations": { + "name": "server_integrations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "server_integrations_provider_unique": { + "name": "server_integrations_provider_unique", + "nullsNotDistinct": false, + "columns": [ + "provider" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_accounts": { + "name": "email_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "imap_host": { + "name": "imap_host", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "imap_port": { + "name": "imap_port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "imap_secure": { + "name": "imap_secure", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credentials": { + "name": "credentials", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'connected'" + }, + "sync_meta": { + "name": "sync_meta", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_accounts_user_id_users_id_fk": { + "name": "email_accounts_user_id_users_id_fk", + "tableFrom": "email_accounts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "uq_email_accounts_user_email": { + "name": "uq_email_accounts_user_email", + "nullsNotDistinct": false, + "columns": [ + "user_id", + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipeline_jobs": { + "name": "pipeline_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "task_dir_name": { + "name": "task_dir_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "task_name": { + "name": "task_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pipeline'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "inputs": { + "name": "inputs", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "cwd": { + "name": "cwd", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "progress": { + "name": "progress", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "total_cost": { + "name": "total_cost", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "exit_code": { + "name": "exit_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_pipeline_jobs_user_created": { + "name": "idx_pipeline_jobs_user_created", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_pipeline_jobs_status": { + "name": "idx_pipeline_jobs_status", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "pipeline_jobs_user_id_users_id_fk": { + "name": "pipeline_jobs_user_id_users_id_fk", + "tableFrom": "pipeline_jobs", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/src/databases/officer_db/migrations/meta/_journal.json b/src/databases/officer_db/migrations/meta/_journal.json new file mode 100644 index 00000000..0df3982b --- /dev/null +++ b/src/databases/officer_db/migrations/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1785018112373, + "tag": "0000_eager_sir_ram", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/src/servers/api/file-browser/router.ts b/src/servers/api/file-browser/router.ts index ab9e6dbb..ee8472e4 100644 --- a/src/servers/api/file-browser/router.ts +++ b/src/servers/api/file-browser/router.ts @@ -18,10 +18,8 @@ async function getUserTtsVoice(userId: number): Promise { return null; } -const DEFAULT_HOME_DIRS = ['Downloads', 'Documents', 'Music', 'Videos', 'Pictures', 'Onboarding']; +const DEFAULT_HOME_DIRS = ['Downloads', 'Documents', 'Music', 'Videos', 'Pictures']; const OLD_CACHE_DIRS = ['ocr', 'tts', 'transcriptions', 'audio', 'video']; -const ONBOARDING_SEED = join(DATA_PATH, 'Onboarding'); -const ONBOARDING_ADMIN_SEED = join(DATA_PATH, 'Onboarding_Admin'); async function cleanOldCacheDirs(userDataDir: string) { for (const dir of OLD_CACHE_DIRS) { @@ -30,28 +28,10 @@ async function cleanOldCacheDirs(userDataDir: string) { } } -async function syncSeedDir(seedDir: string, targetDir: string) { - if (!existsSync(seedDir)) return; - - await mkdir(targetDir, { recursive: true }); - - const seedEntries = await readdir(seedDir, { withFileTypes: true }); - for (const entry of seedEntries) { - const dest = join(targetDir, entry.name); - if (existsSync(dest)) continue; - await cp(join(seedDir, entry.name), dest, { recursive: true }); - } -} - async function seedHomeDir(homeDir: string) { for (const dir of DEFAULT_HOME_DIRS) { const target = join(homeDir, dir); - if (dir === 'Onboarding') { - await syncSeedDir(ONBOARDING_ADMIN_SEED, join(homeDir, 'Onboarding')); - await syncSeedDir(ONBOARDING_SEED, join(homeDir, 'Onboarding', 'User_Onboarding')); - } else if (!existsSync(target)) { - await mkdir(target, { recursive: true }); - } + if (!existsSync(target)) await mkdir(target, { recursive: true }); } } diff --git a/src/servers/api/server-settings/server-settings.ts b/src/servers/api/server-settings/server-settings.ts index 384164cd..173a39fb 100644 --- a/src/servers/api/server-settings/server-settings.ts +++ b/src/servers/api/server-settings/server-settings.ts @@ -26,11 +26,6 @@ serverSettingsRouter.get('/settings', async (ctx) => { return ctx.json(await readServerSettings()); }); -serverSettingsRouter.get('/onboarding-complete', async (ctx) => { - const settings = await readServerSettings(); - return ctx.json({ onboardingComplete: !!settings.onboardingComplete }); -}); - serverSettingsRouter.put('/', async (ctx) => { const body = await ctx.req.json(); const settings = await readServerSettings(); diff --git a/src/servers/hono.ts b/src/servers/hono.ts index 581b5dcc..92dab120 100644 --- a/src/servers/hono.ts +++ b/src/servers/hono.ts @@ -67,11 +67,6 @@ honoServer.post('/api/hooks/claude-done', async (ctx) => { } return ctx.json({ ok: true }); }); -honoServer.get('/api/server-settings/onboarding-complete', async (ctx) => { - const { readServerSettings } = await import('officerdb'); - const settings = await readServerSettings(); - return ctx.json({ onboardingComplete: !!settings.onboardingComplete }); -}); const protectedRouter = createRouter(); protectedRouter.use(bodyParser()); diff --git a/src/workspaces/state/src/useServerSettings.ts b/src/workspaces/state/src/useServerSettings.ts index 359b200c..0ee23aba 100644 --- a/src/workspaces/state/src/useServerSettings.ts +++ b/src/workspaces/state/src/useServerSettings.ts @@ -8,8 +8,6 @@ type AIHarnesses = { }; type ServerSettings = { - onboardingComplete?: boolean; - accountMode?: 'organization' | 'single'; aiHarnesses?: AIHarnesses; plugins?: Record; }; @@ -25,8 +23,6 @@ export const useServerSettings = () => { queryFn: () => client.get('/server-settings/settings'), }); - const onboardingComplete = settings?.onboardingComplete ?? true; - const accountMode = settings?.accountMode; const aiHarnesses = settings?.aiHarnesses; const plugins = settings?.plugins; const saveSettings = useCallback( @@ -37,5 +33,5 @@ export const useServerSettings = () => { [client, queryClient], ); - return { onboardingComplete, accountMode, aiHarnesses, plugins, isLoading, saveSettings }; + return { aiHarnesses, plugins, isLoading, saveSettings }; }; diff --git a/src/workspaces/state/src/useSettings.ts b/src/workspaces/state/src/useSettings.ts index b78d1dad..4ded21eb 100644 --- a/src/workspaces/state/src/useSettings.ts +++ b/src/workspaces/state/src/useSettings.ts @@ -16,7 +16,6 @@ const mergeWithDefaults = (saved: Partial): UserSettings => ({ appearance: { ...DEFAULT_SETTINGS.appearance, ...saved.appearance }, languages: { ...DEFAULT_SETTINGS.languages, ...saved.languages }, tts: { ...DEFAULT_SETTINGS.tts, ...saved.tts }, - onboarding: { ...DEFAULT_SETTINGS.onboarding, ...saved.onboarding }, }); export const useSettings = () => { @@ -77,9 +76,6 @@ export type UserSettings = { tts: { voice: string | null; }; - onboarding: { - complete: boolean; - }; }; export type UserState = Record; @@ -113,7 +109,4 @@ export const DEFAULT_SETTINGS: UserSettings = { tts: { voice: null, }, - onboarding: { - complete: false, - }, };