Server becomes self-contained: web/dist embedded via go:embed (server/internal/webui), SPA served from the binary with JSON-404 guard on /api paths, nginx web container removed from compose (31336 now maps to the server). Clean checkouts without the UI copy build API-only. Agent local API gains its first write endpoint, POST /v1/actions/trigger-scan (FEAT-002 write path): group-ACL authorized, single-flight, 202/409/503 semantics. Registered agents run the same HandleScanUpdates path as a signed scan command (empty command_id, no ack tracking); standalone agents scan through the orchestrator into the local read model only. Also repairs localapi tests left uncompilable by the desktop-provider parameter.
34 lines
979 B
Go
34 lines
979 B
Go
// Package webui embeds the production web dashboard build into the server
|
|
// binary so a native install needs no nginx and no separate web container.
|
|
//
|
|
// The build pipeline copies web/dist into this package's dist/ directory
|
|
// before `go build`. When that copy has not happened (plain `go build` from
|
|
// a clean checkout), the embed holds only the .gitkeep placeholder and the
|
|
// server runs API-only — Present() reports false and the caller logs it.
|
|
package webui
|
|
|
|
import (
|
|
"embed"
|
|
"io/fs"
|
|
)
|
|
|
|
//go:embed all:dist
|
|
var distFS embed.FS
|
|
|
|
// FS returns the embedded UI file tree rooted at the dist directory.
|
|
func FS() (fs.FS, error) {
|
|
return fs.Sub(distFS, "dist")
|
|
}
|
|
|
|
// Present reports whether a real UI build is embedded (index.html exists),
|
|
// as opposed to the empty placeholder tree from a UI-less build.
|
|
func Present() bool {
|
|
sub, err := FS()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
if _, err := fs.Stat(sub, "index.html"); err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|