Selaa lähdekoodia

feat(docs): serve offline rendered API docs at /docs + web UI link

Vendor RapiDoc 9.3.8 (863 kB, single-file) into api/docs/; serve it publicly
at /docs via a static mount + explicit GET handler in meta.cpp; ship docs
assets in the server .deb; add "API Docs" sidebar link in the web UI.
Fszontagh 1 kuukausi sitten
vanhempi
sitoutus
26af36abad

+ 9 - 0
api/docs/index.html

@@ -0,0 +1,9 @@
+<!doctype html>
+<html lang="en"><head><meta charset="utf-8"><title>smartbotic-vectorapi API</title>
+<meta name="viewport" content="width=device-width,initial-scale=1"></head>
+<body style="margin:0">
+  <rapi-doc spec-url="/openapi.json" theme="dark" bg-color="#0b0f17" text-color="#e5e7eb"
+            render-style="read" show-header="false" allow-try="true"
+            regular-font="system-ui, sans-serif"></rapi-doc>
+  <script type="module" src="/docs/rapidoc-min.js"></script>
+</body></html>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
api/docs/rapidoc-min.js


+ 2 - 0
packaging/deb/create-debs.sh

@@ -58,6 +58,8 @@ chmod 0755 "$PKG1/usr/bin/smartbotic-vectorapi"
 cp "$CONFIG_DIR/config.json" "$PKG1/etc/smartbotic-vectorapi/config.json"
 cp "$SYSTEMD_DIR/smartbotic-vectorapi.service" "$PKG1/lib/systemd/system/"
 cp "$API_DIR/openapi.json" "$API_DIR/llms.txt" "$PKG1/usr/share/smartbotic-vectorapi/"
+mkdir -p "$PKG1/usr/share/smartbotic-vectorapi/docs"
+cp -a "$API_DIR/docs/." "$PKG1/usr/share/smartbotic-vectorapi/docs/"
 cp "$TEMPLATE_DIR/control.server" "$PKG1/DEBIAN/control"
 cp "$SCRIPTS_DIR/server.postinst" "$PKG1/DEBIAN/postinst"
 cp "$SCRIPTS_DIR/server.prerm"    "$PKG1/DEBIAN/prerm"

+ 10 - 0
src/handlers/meta.cpp

@@ -36,6 +36,16 @@ void registerMetaRoutes(ApiServer& s) {
         res.set_content(ss.str(), "text/plain");
         res.status = 200;
     });
+
+    // Serve /docs (no trailing slash) -> docs/index.html so the page loads without a redirect.
+    svr.Get("/docs", [share](const httplib::Request&, httplib::Response& res) {
+        if (share.empty()) { sendJson(res, 404, {{"error", "not configured"}}); return; }
+        std::ifstream f(share + "/docs/index.html");
+        if (!f) { sendJson(res, 404, {{"error", "not found"}}); return; }
+        std::ostringstream ss; ss << f.rdbuf();
+        res.set_content(ss.str(), "text/html");
+        res.status = 200;
+    });
 }
 
 } // namespace svapi

+ 1 - 0
src/server.cpp

@@ -74,6 +74,7 @@ void ApiServer::registerRoutes() {
     registerStatsRoutes(*this);
     registerSettingsRoutes(*this);
 
+    if (!d_.shareDir.empty()) svr_.set_mount_point("/docs", d_.shareDir + "/docs");
     if (!d_.webuiDir.empty()) svr_.set_mount_point("/", d_.webuiDir);
 }
 

+ 11 - 0
webui/src/components/AppShell.tsx

@@ -8,6 +8,7 @@ import {
   FolderKanban,
   KeyRound,
   LogOut,
+  BookOpen,
 } from 'lucide-react'
 import { useAuthStore } from '@/stores/authStore'
 import { ProjectSelector } from './ProjectSelector'
@@ -78,6 +79,16 @@ export function AppShell() {
             <SidebarLink key={item.to} item={item} />
           ))}
 
+          <a
+            href="/docs"
+            target="_blank"
+            rel="noreferrer"
+            className="flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition text-slate-400 hover:text-slate-200 hover:bg-slate-700/50"
+          >
+            <BookOpen size={18} />
+            API Docs
+          </a>
+
           {admin && (
             <>
               <div className="mt-4 mb-1 px-3">

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä