initial NextChair Manager.
CI / ci (push) Canceled after 0s

Key additions:
* Separate platform Manager stack: [stacks/manager/compose.yaml]
* Dedicated manager authentication with signed sessions.
* Business overview dashboard.
* Add Business workflow with slug suggestions and deployment progress.
* Business detail page with start, stop, restart, update, logs, Dockge, and conservative removal actions.
* Explicit management API endpoints under [src/app/api/manager]
* Shared provisioning service layer in [provisioning.service.ts]
* CLI and UI now use the same [create-business.sh] provisioning logic.
* Registry metadata, database status, container health, and media usage reporting.
* Manager-only entrypoint mode that does not require a business database.
* Updated deployment documentation with Manager setup and Caddy routing.
Validation passed:
* Infra, Caddy, Manager, and generated business Compose configurations.
* Shell syntax checks.
* Registry generation with registry image tags.
* git diff --check.
This commit is contained in:
Stefan Lazic committed 2026-09-04 20:54:58 +01:00
1 parent 764d087eac
commit b219fb4519
24 files changed
+596 -11

No files matched your search

+5 -1
View File
@@ -21,6 +21,7 @@ const PROTECTED_PREFIXES = ["/staff", "/owner"];
// business data guard themselves (see /api/health and
// /api/cron/process-notifications).
const INSTALL_EXEMPT_PREFIXES = [
"/manager",
"/install",
"/offline",
"/manifest.webmanifest",
@@ -90,7 +91,10 @@ export default auth(async (req) => {
const isInstallExempt = INSTALL_EXEMPT_PREFIXES.some(
(prefix) => pathname === prefix || pathname.startsWith(prefix.endsWith("/") ? prefix : `${prefix}/`),
);
const installed = await isInstalledForRequest();
// The platform Manager is a separate deployment and deliberately has no
// business database. Its own session guard runs inside /manager pages/API.
const isManagerPath = pathname === "/manager" || pathname.startsWith("/manager/");
const installed = isManagerPath ? true : await isInstalledForRequest();
if (!installed && !isInstallExempt) {
const response = NextResponse.redirect(new URL("/install", req.nextUrl.origin));