From 4323ae90f8284a6f42f4009edc316b67bef26ec7 Mon Sep 17 00:00:00 2001 From: Christomatt Date: Sun, 1 Feb 2026 03:26:03 +0100 Subject: [PATCH] chore: remove outdated install wizard --- src/app/api/install/status/route.ts | 54 ------ src/app/install/page.tsx | 273 ---------------------------- src/components/LayoutWrapper.tsx | 3 +- 3 files changed, 1 insertion(+), 329 deletions(-) delete mode 100644 src/app/api/install/status/route.ts delete mode 100644 src/app/install/page.tsx diff --git a/src/app/api/install/status/route.ts b/src/app/api/install/status/route.ts deleted file mode 100644 index 2f52407..0000000 --- a/src/app/api/install/status/route.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { NextResponse } from 'next/server'; -import { db, users } from '@/db'; -import { count, sql } from 'drizzle-orm'; - -const requiredEnv = [ - 'DATABASE_URL', - 'AUTH_SECRET', - 'NEXT_PUBLIC_NODE_DOMAIN', - 'NEXT_PUBLIC_NODE_NAME', - 'ADMIN_EMAILS', -]; - -const optionalEnv: string[] = []; - -export async function GET() { - try { - const envStatus = { - required: requiredEnv.reduce>((acc, key) => { - acc[key] = Boolean(process.env[key]); - return acc; - }, {}), - optional: optionalEnv.reduce>((acc, key) => { - acc[key] = Boolean(process.env[key]); - return acc; - }, {}), - }; - - if (!db) { - return NextResponse.json({ - env: envStatus, - db: { connected: false, schemaReady: false, usersCount: 0 }, - }); - } - - let schemaReady = true; - let usersCount = 0; - - try { - await db.execute(sql`select 1 from users limit 1`); - const [result] = await db.select({ count: count() }).from(users); - usersCount = Number(result?.count || 0); - } catch { - schemaReady = false; - } - - return NextResponse.json({ - env: envStatus, - db: { connected: true, schemaReady, usersCount }, - }); - } catch (error) { - console.error('Install status error:', error); - return NextResponse.json({ error: 'Failed to check status' }, { status: 500 }); - } -} diff --git a/src/app/install/page.tsx b/src/app/install/page.tsx deleted file mode 100644 index b1f0a2e..0000000 --- a/src/app/install/page.tsx +++ /dev/null @@ -1,273 +0,0 @@ -'use client'; - -import { useEffect, useState } from 'react'; -import Link from 'next/link'; -import { useSearchParams } from 'next/navigation'; - -export const dynamic = 'force-dynamic'; - -type EnvStatus = { - required: Record; - optional: Record; -}; - -type InstallStatus = { - env: EnvStatus; - db: { - connected: boolean; - schemaReady: boolean; - usersCount: number; - }; -}; - -const requiredLabels: Record = { - DATABASE_URL: 'Database connection string', - AUTH_SECRET: 'Auth cookie secret', - NEXT_PUBLIC_NODE_DOMAIN: 'Public node domain', - NEXT_PUBLIC_NODE_NAME: 'Node display name', - ADMIN_EMAILS: 'Admin emails list', -}; - -const optionalLabels: Record = {}; - -const StepCard = ({ - title, - description, - status, - children, -}: { - title: string; - description?: string; - status?: { label: string; tone: 'ok' | 'warn' }; - children: React.ReactNode; -}) => ( -
-
-
-
{title}
- {description &&
{description}
} -
- {status && ( -
- {status.label} -
- )} -
- {children} -
-); - -export default function InstallPage() { - const searchParams = useSearchParams(); - const force = searchParams.get('force') === '1'; - const [status, setStatus] = useState(null); - const [loading, setLoading] = useState(true); - - const loadStatus = async () => { - setLoading(true); - try { - const res = await fetch('/api/install/status'); - const data = await res.json(); - setStatus(data); - } catch { - setStatus(null); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - loadStatus(); - }, []); - - const isInstalled = status?.db.connected && status?.db.schemaReady && status?.db.usersCount > 0; - - if (loading) { - return ( -
-
Checking install status...
-
- ); - } - - if (!status) { - return ( -
-
-

Setup Wizard

-

We could not load the install status.

- -
-
- ); - } - - if (isInstalled && !force) { - return ( -
-
-

Synapsis is already set up

-

Your database is connected and at least one user exists.

- - Go to home - - - Re-run setup - -
-
- ); - } - - const missingRequired = Object.entries(status.env.required).filter(([, ok]) => !ok); - const missingOptional = Object.entries(status.env.optional).filter(([, ok]) => !ok); - const envComplete = missingRequired.length === 0; - const dbComplete = status.db.connected && status.db.schemaReady; - const adminComplete = status.db.usersCount > 0; - const completedSteps = [envComplete, dbComplete, adminComplete].filter(Boolean).length; - const progressPercent = Math.round((completedSteps / 3) * 100); - - return ( -
-
-
-
-

Synapsis Setup

-

Follow these steps to complete your installation.

-
- -
-
-
-
-
-
- {completedSteps} / 3 steps complete - {progressPercent}% -
-
-
-
-
Environment
-
{envComplete ? 'Ready' : 'Needs values'}
-
-
-
Database
-
{dbComplete ? 'Ready' : 'Not ready'}
-
-
-
Admin
-
{adminComplete ? 'Ready' : 'Not created'}
-
-
-
- - -
- {Object.entries(status.env.required).map(([key, ok]) => ( -
-
{key}
-
{requiredLabels[key]}
-
{ok ? 'Set' : 'Missing'}
-
- ))} -
- {missingRequired.length > 0 && ( -
- Missing required values: {missingRequired.map(([key]) => key).join(', ')} -
- )} - {missingRequired.some(([key]) => key === 'AUTH_SECRET') && ( -
- To generate an AUTH_SECRET, run: - - openssl rand -base64 33 - -
- )} -
Optional
-
- {Object.entries(status.env.optional).map(([key, ok]) => ( -
-
{key}
-
{optionalLabels[key]}
-
{ok ? 'Set' : 'Not set'}
-
- ))} -
- {missingOptional.length > 0 && ( -
- Optional values missing: {missingOptional.map(([key]) => key).join(', ')} -
- )} -
- - -
- Database connection - {status.db.connected ? 'Connected' : 'Not connected'} -
-
- Schema - {status.db.schemaReady ? 'Ready' : 'Missing tables'} -
- {!status.db.schemaReady && ( -
- Run npm run db:push to create tables. -
- )} -
- - -
- Existing users - {status.db.usersCount} -
-

- Register a user via the login page. Then add their email to - ADMIN_EMAILS and redeploy. -

- - Go to login / register - -
- - - - Go to home - - - Open moderation dashboard - - -
- ); -} diff --git a/src/components/LayoutWrapper.tsx b/src/components/LayoutWrapper.tsx index b4d1f85..a6ef64d 100644 --- a/src/components/LayoutWrapper.tsx +++ b/src/components/LayoutWrapper.tsx @@ -12,8 +12,7 @@ export function LayoutWrapper({ children }: { children: React.ReactNode }) { // Paths that should NOT have the app layout const isStandalone = pathname === '/login' || - pathname === '/register' || - pathname?.startsWith('/install'); + pathname === '/register'; // Hide right sidebar on chat page for more space const hideRightSidebar = false;