refactor: Modularize server into separate concerns

Split monolithic index.ts (~1400 lines) into modular structure:
- config.ts: Server configuration and constants
- db/: Database initialization, migrations, and seeds
- routes/: API handlers by domain (themes, canvas, components, etc.)
- services/: Terminal WebSocket server
- utils/: CORS helpers

Entry point now only coordinates initialization.
This commit is contained in:
2026-02-13 13:01:18 -06:00
parent 9681ce4198
commit 645f51a74e
16 changed files with 1503 additions and 1382 deletions

134
server/db/seeds.ts Normal file
View File

@@ -0,0 +1,134 @@
import type { Database } from 'bun:sqlite'
const darkTheme = {
id: 'theme-dark',
name: 'Dark',
description: 'Default dark theme',
is_default: 1,
is_system: 1,
variables: JSON.stringify({
colors: {
'bg-primary': '#0f0f14',
'bg-secondary': '#16161d',
'bg-hover': '#1e1e28',
'bg-tertiary': '#252530',
'border-color': '#2a2a3a',
'border-hover': '#3a3a4a'
},
text: {
'text-primary': '#e4e4e7',
'text-secondary': '#a1a1aa',
'text-muted': '#52525b',
'text-inverse': '#0f0f14'
},
accent: {
'accent': '#6366f1',
'accent-hover': '#818cf8',
'accent-muted': 'rgba(99, 102, 241, 0.2)',
'accent-text': '#ffffff'
},
semantic: {
'success': '#22c55e',
'success-bg': 'rgba(34, 197, 94, 0.1)',
'warning': '#eab308',
'warning-bg': 'rgba(234, 179, 8, 0.1)',
'error': '#ef4444',
'error-bg': 'rgba(239, 68, 68, 0.1)',
'info': '#3b82f6',
'info-bg': 'rgba(59, 130, 246, 0.1)'
},
spacing: {
'radius-sm': '4px',
'radius-md': '8px',
'radius-lg': '12px',
'radius-full': '9999px'
},
typography: {
'font-sans': "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
'font-mono': "'JetBrains Mono', 'Fira Code', Consolas, monospace"
},
effects: {
'shadow-sm': '0 1px 2px rgba(0,0,0,0.2)',
'shadow-md': '0 4px 6px rgba(0,0,0,0.3)',
'shadow-lg': '0 10px 15px rgba(0,0,0,0.4)',
'transition-fast': '0.15s ease',
'transition-normal': '0.2s ease'
}
}),
metadata: JSON.stringify({ author: 'system', version: '1.0.0', tags: ['dark', 'default'] })
}
const lightTheme = {
id: 'theme-light',
name: 'Light',
description: 'Clean light theme',
is_default: 0,
is_system: 1,
variables: JSON.stringify({
colors: {
'bg-primary': '#ffffff',
'bg-secondary': '#f4f4f5',
'bg-hover': '#e4e4e7',
'bg-tertiary': '#d4d4d8',
'border-color': '#d4d4d8',
'border-hover': '#a1a1aa'
},
text: {
'text-primary': '#18181b',
'text-secondary': '#52525b',
'text-muted': '#a1a1aa',
'text-inverse': '#ffffff'
},
accent: {
'accent': '#4f46e5',
'accent-hover': '#4338ca',
'accent-muted': 'rgba(79, 70, 229, 0.1)',
'accent-text': '#ffffff'
},
semantic: {
'success': '#16a34a',
'success-bg': 'rgba(22, 163, 74, 0.1)',
'warning': '#ca8a04',
'warning-bg': 'rgba(202, 138, 4, 0.1)',
'error': '#dc2626',
'error-bg': 'rgba(220, 38, 38, 0.1)',
'info': '#2563eb',
'info-bg': 'rgba(37, 99, 235, 0.1)'
},
spacing: {
'radius-sm': '4px',
'radius-md': '8px',
'radius-lg': '12px',
'radius-full': '9999px'
},
typography: {
'font-sans': "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
'font-mono': "'JetBrains Mono', 'Fira Code', Consolas, monospace"
},
effects: {
'shadow-sm': '0 1px 2px rgba(0,0,0,0.05)',
'shadow-md': '0 4px 6px rgba(0,0,0,0.07)',
'shadow-lg': '0 10px 15px rgba(0,0,0,0.1)',
'transition-fast': '0.15s ease',
'transition-normal': '0.2s ease'
}
}),
metadata: JSON.stringify({ author: 'system', version: '1.0.0', tags: ['light'] })
}
export function runSeeds(db: Database) {
// Check if system themes exist
const existingThemes = db.query('SELECT COUNT(*) as count FROM themes WHERE is_system = 1').get() as { count: number }
if (existingThemes.count === 0) {
const stmt = db.prepare(`
INSERT INTO themes (id, name, description, is_default, is_system, variables, metadata)
VALUES (?, ?, ?, ?, ?, ?, ?)
`)
stmt.run(darkTheme.id, darkTheme.name, darkTheme.description, darkTheme.is_default, darkTheme.is_system, darkTheme.variables, darkTheme.metadata)
stmt.run(lightTheme.id, lightTheme.name, lightTheme.description, lightTheme.is_default, lightTheme.is_system, lightTheme.variables, lightTheme.metadata)
console.log('[DB] System themes created')
}
}