Bläddra i källkod

feat(main): wire config, DB, settings+keys bootstrap, default project, serve

Fszontagh 2 månader sedan
förälder
incheckning
c646cc9c95
1 ändrade filer med 74 tillägg och 4 borttagningar
  1. 74 4
      src/main.cpp

+ 74 - 4
src/main.cpp

@@ -1,15 +1,85 @@
+#include "auth.hpp"
+#include "collection_registry.hpp"
+#include "config.hpp"
+#include "db_gateway.hpp"
+#include "key_store.hpp"
+#include "server.hpp"
+#include "settings_store.hpp"
 #include <svapi/version.hpp>
+#include <spdlog/spdlog.h>
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#else
+#define sd_notify(u, s) do {} while (0)
+#endif
+#include <atomic>
+#include <chrono>
+#include <csignal>
+#include <cstdlib>
 #include <cstring>
 #include <iostream>
+#include <thread>
+
+namespace {
+std::atomic<bool> g_running{true};
+void onSignal(int) { g_running = false; }
+std::string envOr(const char* k, const std::string& dflt = "") { const char* v = std::getenv(k); return v ? std::string(v) : dflt; }
+}
 
 int main(int argc, char** argv) {
+    std::string configPath = "/etc/smartbotic-vectorapi/config.json";
+    std::string webuiDirOverride;
+    std::string shareDir = "/usr/share/smartbotic-vectorapi";
     for (int i = 1; i < argc; ++i) {
-        if (std::strcmp(argv[i], "--version") == 0 || std::strcmp(argv[i], "-v") == 0) {
-            std::cout << "smartbotic-vectorapi " << svapi::VERSION
-                      << " (" << svapi::GIT_COMMIT << ")\n";
+        if (std::strcmp(argv[i], "--config") == 0 && i + 1 < argc) configPath = argv[++i];
+        else if (std::strcmp(argv[i], "--webui-dir") == 0 && i + 1 < argc) webuiDirOverride = argv[++i];
+        else if (std::strcmp(argv[i], "--share-dir") == 0 && i + 1 < argc) shareDir = argv[++i];
+        else if (std::strcmp(argv[i], "--version") == 0 || std::strcmp(argv[i], "-v") == 0) {
+            std::cout << "smartbotic-vectorapi " << svapi::VERSION << " (" << svapi::GIT_COMMIT << ")\n";
             return 0;
         }
     }
-    std::cout << "smartbotic-vectorapi " << svapi::VERSION << " — not yet wired (see plan)\n";
+
+    svapi::Config cfg;
+    try { cfg = svapi::Config::load(configPath); }
+    catch (const std::exception& e) { std::cerr << "config error: " << e.what() << "\n"; return 1; }
+    spdlog::set_level(spdlog::level::from_str(cfg.logLevel));
+    if (!webuiDirOverride.empty()) cfg.webuiDir = webuiDirOverride;
+
+    std::signal(SIGINT, onSignal); std::signal(SIGTERM, onSignal); std::signal(SIGPIPE, SIG_IGN);
+
+    svapi::DbGateway db(cfg.dbAddress);
+    spdlog::info("connecting to smartbotic-database at {}", cfg.dbAddress);
+    for (int i = 0; i < 30 && !db.connect(); ++i) std::this_thread::sleep_for(std::chrono::seconds(1));
+    if (!db.healthy()) { spdlog::error("database not reachable at {}", cfg.dbAddress); return 1; }
+
+    svapi::SettingsStore settings(db);
+    settings.bootstrap(envOr("OPENAI_API_KEY"));
+    settings.startWatch();
+
+    svapi::KeyStore keys(db);
+    keys.bootstrap(envOr("SMARTBOTIC_VECTORAPI_KEY"));
+    keys.startWatch();
+
+    svapi::CollectionRegistry registry(db);
+    const std::string defProj = settings.snapshot()->defaultProject;
+    db.ensureProject(defProj);
+    registry.ensure(defProj);
+
+    svapi::SessionStore sessions(std::chrono::minutes(settings.snapshot()->sessionTtlMinutes));
+
+    svapi::ServerDeps deps{db, settings, keys, registry, sessions, cfg.webuiDir, shareDir};
+    svapi::ApiServer server(std::move(deps));
+    server.registerRoutes();
+
+    std::thread http([&] {
+        spdlog::info("listening on {}:{}", cfg.httpBind, cfg.httpPort);
+        if (!server.listen(cfg.httpBind, cfg.httpPort)) { spdlog::error("bind failed"); g_running = false; }
+    });
+    sd_notify(0, "READY=1");
+    while (g_running) { sd_notify(0, "WATCHDOG=1"); std::this_thread::sleep_for(std::chrono::milliseconds(200)); }
+    sd_notify(0, "STOPPING=1");
+    server.stop();
+    if (http.joinable()) http.join();
     return 0;
 }