fix: fast node creation, first-run modal, simplified docs

- Skip AI calls when no valid OpenAI key (fixes 9-13s timeout)
- Add first-run modal prompting for API key
- Rewrite README for first-time users
- Add /api/health endpoint
- Remove all Anthropic references (not used in OS)
- Fix bootstrap script (dev:local → dev)
- Fix next.config.js devIndicators warning
- Add Node 18+ version check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
“BeeRad”
2026-02-02 15:10:46 +11:00
co-authored by Claude Opus 4.5
parent 38386afea4
commit 7beba57f63
13 changed files with 616 additions and 389 deletions
+38
View File
@@ -0,0 +1,38 @@
/**
* Main health check endpoint
* Returns overall system health status for quick verification
*/
import { NextResponse } from 'next/server';
import { checkDatabaseHealth } from '@/services/database';
import { hasValidOpenAiKey } from '@/services/database/descriptionService';
export const runtime = 'nodejs';
export async function GET() {
try {
const dbHealth = await checkDatabaseHealth();
const response = {
status: dbHealth.connected ? 'ok' : 'degraded',
database: dbHealth.connected ? 'connected' : 'disconnected',
vectorSearch: dbHealth.vectorExtension ? 'enabled' : 'disabled',
aiFeatures: hasValidOpenAiKey() ? 'enabled' : 'disabled (no API key)',
timestamp: new Date().toISOString(),
};
return NextResponse.json(response, {
status: dbHealth.connected ? 200 : 503,
});
} catch (error) {
return NextResponse.json(
{
status: 'error',
database: 'error',
error: error instanceof Error ? error.message : 'Unknown error',
timestamp: new Date().toISOString(),
},
{ status: 500 }
);
}
}
-47
View File
@@ -1,47 +0,0 @@
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
const { apiKey } = await request.json();
if (typeof apiKey !== 'string' || apiKey.trim().length === 0) {
return NextResponse.json(
{ ok: false, error: 'API key is required.' },
{ status: 400 }
);
}
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': apiKey.trim(),
'content-type': 'application/json',
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: 'claude-3-haiku-20240307',
max_tokens: 1,
messages: [{ role: 'user', content: 'test' }],
}),
});
if (!response.ok) {
const errorBody = await response.text();
return NextResponse.json(
{
ok: false,
status: response.status,
error: errorBody || 'Anthropic returned an error.',
},
{ status: 200 }
);
}
return NextResponse.json({ ok: true });
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
return NextResponse.json(
{ ok: false, error: message },
{ status: 500 }
);
}
}
+7 -1
View File
@@ -1,5 +1,11 @@
import ThreePanelLayout from '@/components/layout/ThreePanelLayout';
import FirstRunModal from '@/components/onboarding/FirstRunModal';
export default function Home() {
return <ThreePanelLayout />;
return (
<>
<ThreePanelLayout />
<FirstRunModal />
</>
);
}