@teamscala/service-boot 0.23.394 → 0.23.395

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "name": "@teamscala/service-boot",
8
8
  "type": "module",
9
- "version": "0.23.394",
9
+ "version": "0.23.395",
10
10
  "sideEffects": false,
11
11
  "imports": {
12
12
  "#service-boot/*": "./src/*",
@@ -44,6 +44,8 @@ export async function registerPageRoutes(
44
44
  const authMode = (config as { auth?: string }).auth ?? "none";
45
45
  const providers = ((config as { providers?: string[] }).providers ??
46
46
  []) as string[];
47
+ const portalScoped =
48
+ (config as { portal_scoped?: boolean }).portal_scoped === true;
47
49
 
48
50
  const registryPatterns = await registerRegistryPageRoute({
49
51
  app,
@@ -53,6 +55,7 @@ export async function registerPageRoutes(
53
55
  authMode,
54
56
  renderMode,
55
57
  providers,
58
+ portalScoped,
56
59
  });
57
60
 
58
61
  return registryPatterns;
@@ -79,6 +79,12 @@ interface RegistryRouteArgs {
79
79
  authMode: string;
80
80
  renderMode: RenderModeLiteral;
81
81
  providers: string[];
82
+ /** Declared service_install fact: this service's page URL space is
83
+ * org-scoped portal-shaped (/<websiteId>/<orgId>/<path>). Gates the SSR
84
+ * portal home redirect — NOT derivable from catchall presence: a flat-path
85
+ * catchall service (scala-agents-ui) serves its real page at "/" and must
86
+ * not be redirected to an org-scoped path that has no page there. */
87
+ portalScoped: boolean;
82
88
  }
83
89
 
84
90
  function extractUrlParams(
@@ -111,6 +117,7 @@ export async function registerRegistryPageRoute(
111
117
  authMode,
112
118
  renderMode,
113
119
  providers: baseProviders,
120
+ portalScoped,
114
121
  } = args;
115
122
  const log = getAppLogger();
116
123
 
@@ -123,16 +130,6 @@ export async function registerRegistryPageRoute(
123
130
  );
124
131
  if (serviceRoutes.length === 0) return [];
125
132
 
126
- // Only a service serving arbitrary portal paths (a `/*` catchall route —
127
- // the portal) redirects signed-in users from `/` into
128
- // /<website>/<org>/dashboard. Single-site portal-mode services (the
129
- // fleet dashboard) serve their real page AT `/` — the unconditional
130
- // redirect 404-looped them (2026-06-06; service-runtime@1.15.82 made
131
- // the redirect opt-in via this flag).
132
- const servesPortalCatchall = serviceRoutes.some(
133
- (r) => r.config.pattern === "/*",
134
- );
135
-
136
133
  // Sort routes so more specific patterns register before wildcard/param routes.
137
134
  // Hono matches by registration order, so `/*` (the portal catchall) registered
138
135
  // before `/sign-in` would swallow the sign-in page and render it inside the
@@ -834,7 +831,11 @@ export async function registerRegistryPageRoute(
834
831
  providers: routeProviders,
835
832
  renderMode: routeRenderMode,
836
833
  loadData: loadData as never,
837
- portalHomeRedirect: servesPortalCatchall,
834
+ // The portal home redirect follows the DECLARED portal_scoped service
835
+ // fact (see RegistryRouteArgs.portalScoped) — a signed-in user at "/" of
836
+ // an org-scoped portal belongs at /<websiteId>/<orgId>/dashboard; a
837
+ // flat-path service (the fleet dashboard) serves its real page at "/".
838
+ portalHomeRedirect: portalScoped,
838
839
  serviceSlug,
839
840
  });
840
841