#pragma once #include "apikey.hpp" #include "auth.hpp" #include "collection_registry.hpp" #include "db_gateway.hpp" #include "key_store.hpp" #include "settings_store.hpp" #include #include #include namespace svapi { struct ServerDeps { DbGateway& db; SettingsStore& settings; KeyStore& keys; CollectionRegistry& registry; SessionStore& sessions; std::string webuiDir; // static SPA root ("" disables) std::string shareDir; // openapi.json + llms.txt dir }; class ApiServer { public: explicit ApiServer(ServerDeps deps); void registerRoutes(); int bindToAnyPort(const std::string& host); void listenAfterBind(); bool listen(const std::string& host, uint16_t port); void stop(); httplib::Server& raw() { return svr_; } ServerDeps& deps() { return d_; } private: ServerDeps d_; httplib::Server svr_; }; // Auth helpers (defined in server.cpp). std::optional resolveKey(ServerDeps& d, const httplib::Request& req); ApiKey requireKey(ServerDeps& d, const httplib::Request& req); // throws Unauthorized void requireAdmin(const ApiKey& k); // throws Forbidden void requireProjectAccess(const ApiKey& k, const std::string& project); // throws Forbidden // Like requireProjectAccess, but additionally denies capability-scoped keys — // collection/project management is not expressible in a key scope, so a scoped // (publishable) key must never reach these routes. void requireProjectManage(const ApiKey& k, const std::string& project); // throws Forbidden void requireCapability(ServerDeps& d, const ApiKey& k, const httplib::Request& req, const std::string& project, const std::string& collection, KeyOp op); // Route registration (handlers/*.cpp). void registerMetaRoutes(ApiServer&); void registerWebuiAuthRoutes(ApiServer&); void registerProjectRoutes(ApiServer&); void registerKeyRoutes(ApiServer&); void registerCollectionRoutes(ApiServer&); void registerDocumentRoutes(ApiServer&); void registerVectorRoutes(ApiServer&); void registerStatsRoutes(ApiServer&); void registerSettingsRoutes(ApiServer&); } // namespace svapi