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

View File

@@ -0,0 +1,84 @@
import { db } from '../db'
import { jsonResponse, errorResponse } from '../utils/cors'
export async function handleComponents(req: Request) {
if (req.method === 'GET') {
const rows = db.query('SELECT * FROM vue_components ORDER BY updated_at DESC').all()
return jsonResponse(rows)
}
if (req.method === 'POST') {
const body = await req.json()
const id = body.id || `comp-${Date.now()}`
const stmt = db.prepare(`
INSERT OR REPLACE INTO vue_components
(id, name, template, setup, style, props, imports, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
`)
stmt.run(
id,
body.name,
body.template,
body.setup || '',
body.style || '',
JSON.stringify(body.props || []),
JSON.stringify(body.imports || [])
)
return jsonResponse({ success: true, id })
}
if (req.method === 'DELETE') {
db.run('DELETE FROM vue_components')
return jsonResponse({ success: true })
}
return null
}
export async function handleComponentById(req: Request, id: string) {
if (req.method === 'GET') {
const row = db.query('SELECT * FROM vue_components WHERE id = ?').get(id)
if (!row) {
return errorResponse('Component not found', 404)
}
return jsonResponse(row)
}
if (req.method === 'DELETE') {
// Check if component is in use by any canvas
const usage = db.query(`
SELECT pc.id, pc.name
FROM canvas_components cc
JOIN project_canvas pc ON cc.canvas_id = pc.id
WHERE cc.component_id = ?
`).all(id) as { id: string; name: string }[]
if (usage.length > 0) {
return jsonResponse({
error: 'Component in use',
message: `Cannot delete component. It is used by: ${usage.map(u => u.name).join(', ')}`,
usedBy: usage
}, 409)
}
db.run('DELETE FROM vue_components WHERE id = ?', [id])
return jsonResponse({ success: true })
}
return null
}
export function handleComponentUsage(componentId: string) {
const usage = db.query(`
SELECT pc.id, pc.name, pc.type
FROM canvas_components cc
JOIN project_canvas pc ON cc.canvas_id = pc.id
WHERE cc.component_id = ?
`).all(componentId) as { id: string; name: string; type: string }[]
return jsonResponse({
componentId,
usedBy: usage,
canDelete: usage.length === 0
})
}