Make the Windows build produce a truly standalone .exe with no runtime
DLL prerequisites, and stop tracking a placeholder index.html that the
build pipeline rewrites on every run.
webui package
- Move the placeholder HTML out of a tracked file on disk and into a
placeholderHTML const in webui.go. serveIndex falls back to that
const when the embed does not contain index.html, so dev builds that
skip the frontend still get a sensible landing page.
- IsBuilt now checks for index.html instead of _next/ so the helper
stays accurate when only the placeholder is embedded.
Embed directory hygiene
- dist/.gitignore now ignores everything except itself; the directory
still exists for //go:embed but never shows dirty after a build.
- Stop tracking the old placeholder at dist/index.html.
scripts/build.ps1
- Staging step clears everything in dist/ except .gitignore (was also
preserving the old index.html).
- Windows amd64 builds now static-link the mingw-w64 C runtime via
-ldflags '-linkmode external -extldflags "-static"' so the final
orchestrad.exe depends only on standard Windows system DLLs and the
Universal CRT (part of Windows 10+). Verified: no libgcc_s_seh-1,
libstdc++-6, libwinpthread-1, msvcr*, or vcruntime140 imports.
- Auto-discover gcc from C:\ProgramData\mingw64, Chocolatey's mingw,
MSYS2 (ucrt64/mingw64), and TDM-GCC install locations so fresh
checkouts build without manual PATH edits after 'choco install mingw'.
- Windows arm64 is now skipped with a clear message when a matching
aarch64-w64-mingw32-gcc cross-compiler is not available, instead of
failing the whole run.
Binary impact (windows/amd64, CGO on, static): 24.06 MB.
Prune the Spike NextJS PRO demo content that was still shipping inside
the embedded UI and rename the route group to match the app, so every
page we compile is one we actually use. Separately the full Spike main
is preserved at Grace-Solutions/Spike-NextJS-PRO-Template on a parallel
branch for future template pulls.
Route group
- Rename src/app/(DashboardLayout) -> src/app/(app); update all
imports, lazy chunk references, and layout boundary names.
Remove demo routes
- src/app/(app)/{apps,charts,muicharts,forms,icons,mui-trees,
react-tables,tables,theme-pages,ui-components,widgets,sample-page,
dashboards} and the remaining (app)/apps/{blog,ecommerce,invoice}
detail/edit subtrees.
- src/app/{frontend-pages,landingpage} and the blog [slug] route.
- src/app/auth/{auth2,error,maintenance} and the auth1 forgot/register
variants; keep the primary login flow only.
- src/app/api/* demo fetchers (blog, chat, contacts, dashboard,
eCommerce, email, invoice, kanban, notes, ticket, userprofile,
globalFetcher); real calls go through @/lib/api.
Remove demo components and contexts
- src/app/components/{apps,dashboards,forms/form-*,pages,widgets,...}.
- src/app/context/{BlogContext,ChatContext,Ecommercecontext,...};
keep AuthContext, CustomizerContext, Config only.
- src/app/types/{apps,auth}; AuthLogin now uses a local props type.
Layout cleanup
- (app)/layout/vertical/header/Header.tsx and horizontal/header
drop ProductProvider / Ecommerce wrappers so the build succeeds.
- (app)/layout/horizontal/navbar/Menudata.ts mirrors the OrchestrAD
sidebar MenuItems so both layouts expose the same routes.
Build artifacts
- Re-stage frontend/out into backend/internal/webui/dist after the
flatten; index.html now references the (app) chunk graph.
Binary impact (windows/amd64, CGO off): ~37.5 MB -> 26.27 MB.
Embedded dist: 298 files / 14.46 MB.
Switch Next.js to static export (output: 'export', trailingSlash: true) and add a new backend/internal/webui package that embeds frontend/out/ via //go:embed. The backend now serves the UI from its own HTTP server with SPA fallback, long-lived cache headers on _next/static/*, and no dependency on a separate Node.js runtime or static host.
- frontend/next.config.mjs: output='export', trailingSlash=true, images.unoptimized.
- backend/internal/webui: Handler() with SPA fallback, resolve() mirroring Next trailing-slash behavior, IsBuilt() helper, and a placeholder dist/index.html so go build works without a prior frontend build. Top-level .gitignore tracks only the placeholder and its own .gitignore; the copied static export is ignored.
- backend/internal/server/server.go: mount webui.Handler() as the chi NotFound handler so /api/v1/* and /health continue to be served by their handlers while all other routes resolve through the embedded UI with SPA deep-link support.
- scripts/build.ps1: build the frontend (npm install if needed, then npm run build) before any Go build, stage frontend/out into backend/internal/webui/dist, and fail loudly if the UI output is missing or empty. Adds -SkipFrontend for developer iteration.
- Remove Spike demo content that prevented static export: api/* route handlers (dynamic POST/PUT/DELETE), apps/{blog,ecommerce,invoice} dynamic [slug]/[id] detail/edit pages, and frontend-pages/blog/[slug].
- Fix TypeScript errors surfaced by enabling the production build: ApiMeta.totalCount (not total) in audit and rule-runs pages; MUI v7 Grid uses size={{...}} instead of item+xs+md in config page.
Binary size grows from ~8 MB to ~37 MB, reflecting the embedded UI. The produced single binary is now sufficient to run the full product; no separate web server is required.