11import type { Server } from "node:http" ;
22import express from "express" ;
3- import type { AppConfig } from "../config/types" ;
43import { loadAppConfig , resolveConfigPath } from "../config/loadConfig" ;
54import { configureLogger , getLogger } from "../utils/logger" ;
65import { createLLMClient } from "../llm/factory" ;
7- import type { LLMClientBundle } from "../llm/types" ;
8- import { createSupabaseStore , type SupabaseVectorStore } from "../supabase/client" ;
6+ import { createSupabaseStore } from "../supabase/client" ;
97import { createApiKeyMiddleware } from "./middleware/apiKey" ;
10- import { handleMcpAskRequest } from "./routes/mcpAsk " ;
11- import { handleMcpMatchRequest } from "./routes/mcpMatch " ;
12- import { handleHealthRequest } from "./routes/health " ;
13- import { handleIngestRequest } from "./routes/ingest " ;
14- import { handleGithubWebhookRequest , type RequestWithRawBody } from "./routes/githubWebhook " ;
15- import { handleChatCompletions } from "./routes/chatCompletions " ;
8+ import { type RequestWithRawBody } from "./routes/githubWebhook " ;
9+ import { createApiRouter } from "./routers/api " ;
10+ import { createMcpRouter } from "./routers/mcp " ;
11+ import { createWebhookRouter } from "./routers/webhook " ;
12+ import { applyCors } from "./utils/cors " ;
13+ import { type ServerContext , createRouterContext } from "./utils/context " ;
1614
1715export interface ServerOptions {
1816 configPath ?: string ;
1917 port ?: number ;
2018}
2119
22- interface ServerContext {
23- config : AppConfig ;
24- llm : LLMClientBundle ;
25- store : SupabaseVectorStore ;
26- ingestionBusy : boolean ;
27- }
28-
2920type ExpressApp = ReturnType < typeof express > ;
3021
3122export interface RunningServer {
@@ -54,17 +45,6 @@ async function createContext(configPath?: string): Promise<ServerContext> {
5445 } ;
5546}
5647
57- function applyCors ( req : any , res : any , next : any ) : void {
58- res . setHeader ( "Access-Control-Allow-Origin" , "*" ) ;
59- res . setHeader ( "Access-Control-Allow-Methods" , "GET,POST,OPTIONS" ) ;
60- res . setHeader ( "Access-Control-Allow-Headers" , "Content-Type" ) ;
61- if ( req . method === "OPTIONS" ) {
62- res . sendStatus ( 204 ) ;
63- return ;
64- }
65- next ( ) ;
66- }
67-
6848export async function createServer ( options : ServerOptions = { } ) : Promise < { app : ExpressApp ; context : ServerContext } > {
6949 const context = await createContext ( options . configPath ) ;
7050 const logger = getLogger ( ) ;
@@ -79,82 +59,27 @@ export async function createServer(options: ServerOptions = {}): Promise<{ app:
7959 ) ;
8060 app . use ( applyCors ) ;
8161
82- // Apply API key middleware to all routes except /mcp/* endpoints
62+ // Apply API key middleware to all routes except /mcp/* and /webhook/* endpoints
8363 const apiKeyMiddleware = createApiKeyMiddleware ( context . config . server . apiKey ) ;
8464 app . use ( ( req : any , res : any , next : any ) => {
85- if ( req . path . startsWith ( '/mcp/' ) ) {
65+ if ( req . path . startsWith ( '/mcp/' ) || req . path . startsWith ( '/webhook/' ) ) {
8666 next ( ) ;
8767 } else {
8868 apiKeyMiddleware ( req , res , next ) ;
8969 }
9070 } ) ;
9171
92- app . get ( "/health" , ( req : any , res : any ) => {
93- handleHealthRequest ( req , res , { ingestionBusy : context . ingestionBusy } ) ;
94- } ) ;
72+ // Prepare router context
73+ const routerContext = createRouterContext ( context ) ;
9574
96- app . post ( "/ingest" , async ( req : any , res : any ) => {
97- await handleIngestRequest ( req , res , {
98- config : context . config ,
99- llm : context . llm ,
100- store : context . store ,
101- ingestionBusy : context . ingestionBusy ,
102- setIngestionBusy : ( busy : boolean ) => {
103- context . ingestionBusy = busy ;
104- } ,
105- } , logger ) ;
106- } ) ;
75+ // API routes (require API key)
76+ app . use ( createApiRouter ( routerContext , logger ) ) ;
10777
108- app . post ( "/v1/chat/completions" , async ( req : any , res : any ) => {
109- await handleChatCompletions (
110- req ,
111- res ,
112- {
113- config : context . config ,
114- llm : context . llm ,
115- store : context . store ,
116- } ,
117- logger
118- ) ;
119- } ) ;
78+ // MCP routes (no API key required)
79+ app . use ( '/mcp' , createMcpRouter ( routerContext , logger ) ) ;
12080
121- app . post ( "/mcp/ask" , async ( req : any , res : any ) => {
122- await handleMcpAskRequest (
123- req ,
124- res ,
125- {
126- config : context . config ,
127- store : context . store ,
128- } ,
129- logger
130- ) ;
131- } ) ;
132-
133- app . post ( "/mcp/match" , async ( req : any , res : any ) => {
134- await handleMcpMatchRequest (
135- req ,
136- res ,
137- {
138- config : context . config ,
139- llm : context . llm ,
140- store : context . store ,
141- } ,
142- logger
143- ) ;
144- } ) ;
145-
146- app . post ( "/webhook/github" , async ( req : RequestWithRawBody , res : any ) => {
147- await handleGithubWebhookRequest ( req , res , {
148- config : context . config ,
149- llm : context . llm ,
150- store : context . store ,
151- ingestionBusy : context . ingestionBusy ,
152- setIngestionBusy : ( busy : boolean ) => {
153- context . ingestionBusy = busy ;
154- } ,
155- githubWebhookSecret : context . config . server . githubWebhookSecret ,
156- } , logger ) ;
157- } ) ;
81+ // Webhook routes (no API key required)
82+ app . use ( '/webhook' , createWebhookRouter ( routerContext , logger ) ) ;
15883
15984 return { app, context } ;
16085}
0 commit comments