@teamscala/service-boot 0.23.432 → 0.23.433
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 +1 -1
- package/src/auth-gate.ts +0 -9
- package/src/bind-page-handler.ts +0 -3
- package/src/build-client-assets/hydrate-bundle.ts +0 -9
- package/src/build-client-assets/input-fingerprint.ts +0 -9
- package/src/build-client-assets/sourcemaps-upload.ts +0 -3
- package/src/build-client-assets/styles-build.ts +5 -2
- package/src/build-client-assets.ts +0 -3
- package/src/content-gate/catalog.ts +0 -6
- package/src/content-gate/gate.ts +0 -3
- package/src/fn-routers/agreement-sign-side-effects.ts +0 -3
- package/src/fn-routers/work-items-router.ts +0 -3
- package/src/handlers/platform-fault-escalation/orpc-client.ts +0 -3
- package/src/handlers/scala-tools-currency-watch.ts +0 -3
- package/src/handlers/singleton-tools-currency-watch.ts +0 -6
- package/src/mount-server-packages.ts +0 -3
- package/src/register-page-server-client.ts +0 -3
- package/src/register-registry-page-route/ai-chat-prefetch.ts +0 -3
- package/src/register-registry-page-route/apply-page-branding.ts +0 -9
- package/src/register-registry-page-route/graph-cache.ts +0 -3
- package/src/register-registry-page-route/meta-title.ts +0 -3
- package/src/register-registry-page-route/prefetch-org-id.ts +0 -3
- package/src/register-registry-page-route/proposal-approval-email-token.ts +0 -3
- package/src/resolvers/portal-route-paths.ts +0 -3
- package/src/resource-chat-inject.ts +0 -9
- package/src/resource-not-found.ts +0 -3
- package/src/two-phase-full-app.ts +0 -9
- package/src/two-phase-minimal-app.ts +0 -6
- package/src/two-phase-readiness.ts +0 -9
- package/src/ui-service.ts +0 -9
package/package.json
CHANGED
package/src/auth-gate.ts
CHANGED
|
@@ -44,9 +44,6 @@
|
|
|
44
44
|
* registry refused a path exemption for it, correctly — `guard-exemptions-to-zero`.
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
|
-
// Why: Point the event-log primitive at the process's Prisma single…
|
|
48
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
49
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
50
47
|
// Eager-warm the local BetterAuth runtime at boot whenever a request path
|
|
51
48
|
// will build it: the session-READ path (getSession, better-auth-cookie mode)
|
|
52
49
|
// always uses the local instance — even when /api/auth/* forwards to
|
|
@@ -61,9 +58,6 @@
|
|
|
61
58
|
// (e.g. mid-install) the first successful request rebuilds and caches — the
|
|
62
59
|
// service is never left wedged, and never boot-loops on a transient.
|
|
63
60
|
|
|
64
|
-
// Why: Eager-warm the local BetterAuth runtime at boot whenever a r…
|
|
65
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
66
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
67
61
|
// NO localhost bypass: a 127.0.0.1 page request is gated EXACTLY like a
|
|
68
62
|
// tunnel request (no session → redirect to /sign-in). The old
|
|
69
63
|
// `if (isLocalhost) return next()` let any tool — and the agent's own
|
|
@@ -76,9 +70,6 @@
|
|
|
76
70
|
// service-to-service auth still flows through the cookie/secret on the
|
|
77
71
|
// request, never the source IP.
|
|
78
72
|
|
|
79
|
-
// Why: NO localhost bypass: a 127.0.0.1 page request is gated EXACT…
|
|
80
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
81
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
82
73
|
import type { ServiceInstallConfig } from "@teamscala/db/registry/loader/load-service-install-row";
|
|
83
74
|
import { getPrisma } from "@teamscala/db/prisma-registry";
|
|
84
75
|
import { loadRegistryConfig } from "@teamscala/db/registry/load-config";
|
package/src/bind-page-handler.ts
CHANGED
|
@@ -21,9 +21,6 @@
|
|
|
21
21
|
// and was REMOVED by operator ruling the same day ("the origin should be so fast we don't care") — the origin-speed work (SWR caches,
|
|
22
22
|
// wave-parallel loader, brotli) is the sanctioned path; re-adding shared-cache headers needs a fresh operator ruling.
|
|
23
23
|
|
|
24
|
-
// Why: Per-page root.props.maxWidth (the canonical mechanism) cente…
|
|
25
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
26
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
27
24
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
28
25
|
import type { Context } from "hono";
|
|
29
26
|
import { readHtmlTemplate } from "./read-html-template.ts";
|
|
@@ -27,9 +27,6 @@
|
|
|
27
27
|
// tombstone (no-dead-block-imports-in-manifest) — never silent. Entry-point imports are excluded — those must fail loudly (silently
|
|
28
28
|
// externalizing a core import turns a build error into a mystery runtime crash; containment must not become a swallow).
|
|
29
29
|
|
|
30
|
-
// Why: Externalize an unresolvable @teamscala/* block import (a dea…
|
|
31
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
32
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
33
30
|
// minifyIdentifiers is DISABLED (whitespace + syntax/dead-code minify
|
|
34
31
|
// kept): under code-splitting, identifier mangling interacting with a
|
|
35
32
|
// shared sideEffects:false package (@tanstack/react-query) trips Bun's
|
|
@@ -42,9 +39,6 @@
|
|
|
42
39
|
// gate below fails the build LOUD if this or any future regression slips
|
|
43
40
|
// a fatal facade through on any UI service.
|
|
44
41
|
|
|
45
|
-
// Why: minifyIdentifiers is DISABLED (whitespace + syntax/dead-code…
|
|
46
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
47
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
48
42
|
// dead-facade prevention gate (agents.scala.business 2026-07-22): a Bun
|
|
49
43
|
// splitter+tree-shake bug (stable 1.3.14 + canary 1.4.0) can emit a "dead
|
|
50
44
|
// facade" chunk — `export { ... }` with NO `from` clause and NO local binding
|
|
@@ -61,9 +55,6 @@
|
|
|
61
55
|
// be silently bypassed; a valid local-export chunk carries a
|
|
62
56
|
// class/function/const/var/let/import, a valid re-export carries `from`).
|
|
63
57
|
|
|
64
|
-
// Why: dead-facade prevention gate (agents.scala.business 2026-07-2…
|
|
65
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
66
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
67
58
|
import { mkdir, readdir, rename, rm } from "node:fs/promises";
|
|
68
59
|
import { join } from "node:path";
|
|
69
60
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
@@ -31,9 +31,6 @@
|
|
|
31
31
|
// @teamscala/* version (backend packages included), so it invalidates on every publish — the false-invalidation source that made every UI service rebuild
|
|
32
32
|
// on a backend publish. The closure inputs above are a strict improvement: they catch every change that affects THIS bundle AND nothing that doesn't.
|
|
33
33
|
|
|
34
|
-
// Why: Content fingerprint of the client-bundle dependency CLOSURE …
|
|
35
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
36
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
37
34
|
// Keyed on each input's RELATIVE label + CONTENT only — never the absolute
|
|
38
35
|
// path (that would make the fingerprint cwd-dependent and defeat the skip
|
|
39
36
|
// across two checkouts of the same service). bun.lock is DELIBERATELY
|
|
@@ -46,9 +43,6 @@
|
|
|
46
43
|
// so a non-closure publish changes nothing here → zero rebuild. Rebuild
|
|
47
44
|
// iff this fingerprint differs from the one stored in the manifest.
|
|
48
45
|
|
|
49
|
-
// Why: Keyed on each input's RELATIVE label + CONTENT only — never …
|
|
50
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
51
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
52
46
|
// Fold in the resolved CONTENT of every @teamscala/* JS/TS module reachable
|
|
53
47
|
// from the client entrypoints (hashTeamgbgJsGraph). bun.lock pins versions;
|
|
54
48
|
// the build reads BYTES — and a boot can build MID-INSTALL (the package-
|
|
@@ -64,9 +58,6 @@
|
|
|
64
58
|
// which already closes this exact race for CSS). A stale bake then hashes
|
|
65
59
|
// differently from the freshly-installed bytes → rebuild → self-heals.
|
|
66
60
|
|
|
67
|
-
// Why: Fold in the resolved CONTENT of every @teamscala/* JS/TS mod…
|
|
68
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
69
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
70
61
|
import { join } from "node:path";
|
|
71
62
|
import {
|
|
72
63
|
hashResolvedPackageStylesheets,
|
|
@@ -23,9 +23,6 @@
|
|
|
23
23
|
* ships publicly; the debug IDs in the served bundles are all the SDK needs.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
// Why: Upload source maps to GlitchTip via the official `glitchtip-…
|
|
27
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
28
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
29
26
|
import { readdir, rm } from "node:fs/promises";
|
|
30
27
|
import { join } from "node:path";
|
|
31
28
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
@@ -35,7 +35,7 @@ async function resolveStylesheetRaw(
|
|
|
35
35
|
const r = await Bun.resolve(id, base);
|
|
36
36
|
return { path: r, base: dirname(r), content: await Bun.file(r).text() };
|
|
37
37
|
} catch (error) {
|
|
38
|
-
|
|
38
|
+
getAppLogger().warn("style import resolve failed — trying package fallback", error);
|
|
39
39
|
}
|
|
40
40
|
if (!id.startsWith(".")) {
|
|
41
41
|
try {
|
|
@@ -48,7 +48,10 @@ async function resolveStylesheetRaw(
|
|
|
48
48
|
return { path: r, base: dirname(r), content: await Bun.file(r).text() };
|
|
49
49
|
}
|
|
50
50
|
} catch (error) {
|
|
51
|
-
|
|
51
|
+
getAppLogger().warn(
|
|
52
|
+
"package style entry resolve failed — falling back to bare resolve",
|
|
53
|
+
error,
|
|
54
|
+
);
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
const r = resolve(base, id);
|
|
@@ -52,9 +52,6 @@
|
|
|
52
52
|
// kept serving the old bytes across restarts while node_modules was mid-install — invisible until the operator hit the white-on-white
|
|
53
53
|
// toolbar regression the fix was supposed to close).
|
|
54
54
|
|
|
55
|
-
// Why: Each build is wrapped in its own catch so a JS bundle failur…
|
|
56
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
57
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
58
55
|
import { mkdir } from "node:fs/promises";
|
|
59
56
|
import { join } from "node:path";
|
|
60
57
|
import { withFileLock } from "@teamscala/file-lock/with-lock";
|
|
@@ -39,9 +39,6 @@
|
|
|
39
39
|
* govern.
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
|
-
// Why: Registered gates, in evaluation order.
|
|
43
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
44
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
45
42
|
/**
|
|
46
43
|
* Does this gate WITHHOLD content, or only identify the visitor?
|
|
47
44
|
*
|
|
@@ -57,9 +54,6 @@
|
|
|
57
54
|
* read as an unauthorized viewer and lose an assistant they are entitled to.
|
|
58
55
|
*/
|
|
59
56
|
|
|
60
|
-
// Why: Does this gate WITHHOLD content, or only identify the visito…
|
|
61
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
62
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
63
57
|
import type { AccessConfig, ContentGateConfig } from "./config-types.ts";
|
|
64
58
|
import { agreementAccessConfig, agreementGateConfig } from "../agreement-gate.ts";
|
|
65
59
|
import { gptAccessConfig, gptGateConfig } from "../gpt-gate.ts";
|
package/src/content-gate/gate.ts
CHANGED
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
* confused with one.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
// Why: What a gate decided, so a caller can act on it without re-de…
|
|
29
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
30
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
31
28
|
import type { ContentGateConfig } from "./config-types.ts";
|
|
32
29
|
import { parseCookie } from "./parse-cookie.ts";
|
|
33
30
|
|
|
@@ -32,9 +32,6 @@
|
|
|
32
32
|
* payUrl) before this runs; only the stored record is reset.
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
-
// Why: Self-resetting demo harness. If the signed agreement's `prop…
|
|
36
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
37
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
38
35
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
39
36
|
import { queryRows } from "@teamscala/db/query-rows";
|
|
40
37
|
import type { PrismaClient } from "@teamscala/db/client";
|
|
@@ -33,9 +33,6 @@
|
|
|
33
33
|
* dependent client-side round-trip chain).
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
-
// Why: Org-scoped member list for the task-comments panel — @mentio…
|
|
37
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
38
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
39
36
|
import { createEmailClient } from "@teamscala/email-client/client";
|
|
40
37
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
41
38
|
import { authed, type Context } from "./auth-router.ts";
|
|
@@ -27,9 +27,6 @@
|
|
|
27
27
|
* never Date instances (the generated valibot schemas require it).
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
// Why: The system-authed in-process ORPC client, built LAZILY on fi…
|
|
31
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
32
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
33
30
|
import { loadRegistryConfig } from "@teamscala/db/registry/load-config";
|
|
34
31
|
import * as v from "valibot";
|
|
35
32
|
import { createCache } from "@teamscala/cache/create-cache";
|
|
@@ -45,9 +45,6 @@
|
|
|
45
45
|
// If a future package genuinely needs a restart to take effect, it does not belong here: add it to dep-sync's PM2_CACHED map, which already owns
|
|
46
46
|
// install-plus-restart and coalesces them.
|
|
47
47
|
|
|
48
|
-
// Why: NO RESTART. The reinstall alone is sufficient, and restartin…
|
|
49
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
50
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
51
48
|
import type { ScheduledJobConfig } from "@teamscala/db-validation/registry-schemas/scheduled-job";
|
|
52
49
|
import { recordEvent } from "@teamscala/event-log/record-event";
|
|
53
50
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
@@ -40,9 +40,6 @@
|
|
|
40
40
|
* tracking, never placement.
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
|
-
// Why: Where a tool's "latest" comes from.
|
|
44
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
45
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
46
43
|
// A GitHub-released binary is NOT installed by a package manager, so there
|
|
47
44
|
// is no "reinstall" verb to call — it would have to be downloaded, verified,
|
|
48
45
|
// made executable and swapped atomically over a file that may be RUNNING.
|
|
@@ -55,9 +52,6 @@
|
|
|
55
52
|
// watcher cannot actually install is honest — silently claiming currency
|
|
56
53
|
// would not be.
|
|
57
54
|
|
|
58
|
-
// Why: A GitHub-released binary is NOT installed by a package manag…
|
|
59
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
60
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
61
55
|
import type { ScheduledJobConfig } from "@teamscala/db-validation/registry-schemas/scheduled-job";
|
|
62
56
|
import { loadRegistryConfig } from "@teamscala/db/registry/load-config";
|
|
63
57
|
import { recordEvent } from "@teamscala/event-log/record-event";
|
|
@@ -24,9 +24,6 @@
|
|
|
24
24
|
* only warms the cache, never gates boot.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
// Why: Speculatively import every server_package's mount module so …
|
|
28
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
29
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
30
27
|
import type { ServiceInstallConfig } from "@teamscala/db/registry/loader/load-service-install-row";
|
|
31
28
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
32
29
|
import { BootFatalError } from "@teamscala/os/errors/boot-error";
|
|
@@ -21,9 +21,6 @@
|
|
|
21
21
|
// rather than reporting a state it has not verified (`a-component-may-not-report-a-state-it-has-not-verified`). A service
|
|
22
22
|
// that declares no models (daemon/portal shells owning no DB schema) still passes through cleanly.
|
|
23
23
|
|
|
24
|
-
// Why: REFUSE, DO NOT SKIP. `existsSync(routerPath)` being false us…
|
|
25
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
26
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
27
24
|
import { join } from "node:path";
|
|
28
25
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
29
26
|
|
|
@@ -20,9 +20,6 @@
|
|
|
20
20
|
* createOrRestore fallback, never an error page.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
// Why: SSR-prefetch the signed-in user's AI-chat conversation so a …
|
|
24
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
25
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
26
23
|
import { getServerClient } from "../page-server-orpc/server-client.ts";
|
|
27
24
|
|
|
28
25
|
/**
|
|
@@ -28,9 +28,6 @@
|
|
|
28
28
|
* Shared helper so this and bind-page-handler cannot drift on the answer.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
// Why: /sign-in brand override: a shared org-scoped link 302→/sign-…
|
|
32
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
33
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
34
31
|
/**
|
|
35
32
|
* brand-is-org-owned-full-scheme, reconciled with page-org-first
|
|
36
33
|
* (portal-branding-resolves-page-org-first): the session override now
|
|
@@ -53,9 +50,6 @@
|
|
|
53
50
|
* got the wrong page.
|
|
54
51
|
*/
|
|
55
52
|
|
|
56
|
-
// Why: brand-is-org-owned-full-scheme, reconciled with page-org-fir…
|
|
57
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
58
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
59
53
|
/**
|
|
60
54
|
* BRAND FROM THE ORG THAT OWNS THE RESOURCE, not the website's owner.
|
|
61
55
|
* A public resource page (an assessment report, a shared document) is
|
|
@@ -77,9 +71,6 @@
|
|
|
77
71
|
* more specific owner, never blank it.
|
|
78
72
|
*/
|
|
79
73
|
|
|
80
|
-
// Why: BRAND FROM THE ORG THAT OWNS THE RESOURCE, not the website's…
|
|
81
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
82
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
83
74
|
import { fetchOrganisationPageBranding } from "@teamscala/db/fetch-organisation-page-branding";
|
|
84
75
|
import { getPlatformOrgId } from "@teamscala/db/registry/platform";
|
|
85
76
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
@@ -40,9 +40,6 @@
|
|
|
40
40
|
* (an observable dead-link signal, not a hard error).
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
|
-
// Why: Stale-while-revalidate read of a cached loader graph.
|
|
44
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
45
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
46
43
|
import { createCache } from "@teamscala/cache/create-cache";
|
|
47
44
|
|
|
48
45
|
// The structural surface readCachedGraph touches (getWithMeta + refreshInBackground).
|
|
@@ -33,9 +33,6 @@
|
|
|
33
33
|
* edit here rather than a fourth branch in three files.
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
-
// Why: THE ONE SUBJECT DERIVATION. What a page is ABOUT — the entit…
|
|
37
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
38
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
39
36
|
import { interpolateMeta } from "../resolve-from-loader-config.ts";
|
|
40
37
|
|
|
41
38
|
export function buildMetaFromContext(
|
|
@@ -27,9 +27,6 @@
|
|
|
27
27
|
* (found 2026-07-21).
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
// Why: Prefer segment 1; fall back to segment 0 only when segment 1…
|
|
31
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
32
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
33
30
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
34
31
|
|
|
35
32
|
export function resolveAiOrgId(pathname: string): string | undefined {
|
|
@@ -24,9 +24,6 @@
|
|
|
24
24
|
* pages; other registry pages are untouched.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
// Why: Resolve the `{{approvalEmail}}` placeholder in a proposal pa…
|
|
28
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
29
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
30
27
|
import { getServerClient } from "../page-server-orpc/server-client.ts";
|
|
31
28
|
|
|
32
29
|
export async function applyApprovalEmailToken(
|
|
@@ -31,9 +31,6 @@
|
|
|
31
31
|
* neither leading segment is a UUID.
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
// Why: Extract the organisation id from a portal-shaped callback/pa…
|
|
35
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
36
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
37
34
|
export interface ResolverArgs {
|
|
38
35
|
input: Record<string, unknown>;
|
|
39
36
|
client: unknown;
|
|
@@ -36,9 +36,6 @@
|
|
|
36
36
|
* column holds them yet.
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
// Why: THE ASSISTANT'S WORDS BELONG TO THE AGENT ROW, NOT TO THIS F…
|
|
40
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
41
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
42
39
|
/**
|
|
43
40
|
* The rendered content tree to append the launcher to.
|
|
44
41
|
*
|
|
@@ -67,9 +64,6 @@
|
|
|
67
64
|
* caller. One shared convention, not a per-resource list.
|
|
68
65
|
*/
|
|
69
66
|
|
|
70
|
-
// Why: The rendered content tree to append the launcher to.
|
|
71
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
72
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
73
67
|
/**
|
|
74
68
|
* Serialise EVERYTHING THIS VIEWER MAY SEE as text for the assistant.
|
|
75
69
|
*
|
|
@@ -101,9 +95,6 @@
|
|
|
101
95
|
* safe rather than reckless.
|
|
102
96
|
*/
|
|
103
97
|
|
|
104
|
-
// Why: Serialise EVERYTHING THIS VIEWER MAY SEE as text for the ass…
|
|
105
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
106
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
107
98
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
108
99
|
import { loadRegistryConfig } from "@teamscala/db/registry/load-config";
|
|
109
100
|
import { getServerClient } from "./page-server-orpc/server-client.ts";
|
|
@@ -47,9 +47,6 @@
|
|
|
47
47
|
* HTML; the page renders logo-less, never broken.
|
|
48
48
|
*/
|
|
49
49
|
|
|
50
|
-
// Why: The host org's LOGO (wordmark) for the dark error page — the…
|
|
51
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
52
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
53
50
|
import { getClient } from "@teamscala/object-storage/create/client/get-client";
|
|
54
51
|
import { createCache } from "@teamscala/cache/create-cache";
|
|
55
52
|
import { registerCacheInvalidation } from "@teamscala/db/notify-listener/index";
|
|
@@ -22,9 +22,6 @@
|
|
|
22
22
|
* so we don't need to modify the app here. The app reference stays the same.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
// Why: Build the full app with hydration. This adds the expensive o…
|
|
26
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
27
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
28
25
|
// Client asset building (expensive: Vite build).
|
|
29
26
|
//
|
|
30
27
|
// ISOLATED, because a PRESENTATION failure must not take out BACKGROUND WORK.
|
|
@@ -45,9 +42,6 @@
|
|
|
45
42
|
// registry and the DB, not a bundle. Ordering it behind a Vite build was
|
|
46
43
|
// incidental, so the coupling was never intended.
|
|
47
44
|
|
|
48
|
-
// Why: Client asset building (expensive: Vite build).
|
|
49
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
50
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
51
45
|
// pg-boss (mount for UI services - wasn't mounted in minimal app)
|
|
52
46
|
//
|
|
53
47
|
// Wrapped for the SAME reason buildClientAssets above is, in the other
|
|
@@ -62,9 +56,6 @@
|
|
|
62
56
|
// migration threw, and an outage of every page followed from a scheduled-job
|
|
63
57
|
// dependency. Jobs are the degradable half; pages are not.
|
|
64
58
|
|
|
65
|
-
// Why: pg-boss (mount for UI services - wasn't mounted in minimal a…
|
|
66
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
67
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
68
59
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
69
60
|
import type { Hono } from "hono";
|
|
70
61
|
import { buildClientAssets } from "./build-client-assets.ts";
|
|
@@ -29,9 +29,6 @@
|
|
|
29
29
|
* - ORPC router, API routes, WS routes, data routes, page routes
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
// Why: Build the minimal tool-only app. This excludes the expensive…
|
|
33
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
34
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
35
32
|
// Fire independent I/O + compilation NOW, overlapping with the gate chain
|
|
36
33
|
// below. These three touch NO app route and have no ordering dependency on
|
|
37
34
|
// the gate/mount sequence, so they run concurrently with it:
|
|
@@ -45,9 +42,6 @@
|
|
|
45
42
|
// - discoverBlocks: loads the page-manifest (no app mutation, no gate
|
|
46
43
|
// dependency). Its result is consumed by registerPageRoutes much later.
|
|
47
44
|
|
|
48
|
-
// Why: Fire independent I/O + compilation NOW, overlapping with the…
|
|
49
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
50
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
51
45
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
52
46
|
import { BootFatalError } from "@teamscala/os/errors/boot-error";
|
|
53
47
|
import { createTimer } from "@teamscala/timing/create-timer";
|
|
@@ -30,9 +30,6 @@
|
|
|
30
30
|
* still reported starting — while three untouched UI services reported ok.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
// Why: Flip readiness once phase 2 has built the full app.
|
|
34
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
35
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
36
33
|
/**
|
|
37
34
|
* Reset both phase-2 flags. TEST-ONLY.
|
|
38
35
|
*
|
|
@@ -48,9 +45,6 @@
|
|
|
48
45
|
* the only writers on the boot path.
|
|
49
46
|
*/
|
|
50
47
|
|
|
51
|
-
// Why: Reset both phase-2 flags. TEST-ONLY.
|
|
52
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
53
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
54
48
|
/**
|
|
55
49
|
* `/health` for a UI service — 200 ONLY once the full app can actually render
|
|
56
50
|
* a page, 503 before that.
|
|
@@ -94,9 +88,6 @@
|
|
|
94
88
|
* one consumer contract is "can you serve me a page", is moved to phase 2.
|
|
95
89
|
*/
|
|
96
90
|
|
|
97
|
-
// Why: `/health` for a UI service — 200 ONLY once the full app can …
|
|
98
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
99
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
100
91
|
import { buildWakingPageHtml } from "@teamscala/os/brand/waking-page-html";
|
|
101
92
|
import { WAKING_RETRY_SECONDS } from "@teamscala/os/brand/waking-page-budget.generated";
|
|
102
93
|
import type { Context } from "hono";
|
package/src/ui-service.ts
CHANGED
|
@@ -22,9 +22,6 @@
|
|
|
22
22
|
* place and is NOT undone.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
// Why: Boots a UI service using two-phase boot for fast availabilit…
|
|
26
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
27
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
28
25
|
// Resolve the listen port through the SHARED resolver (`resolveServicePort`),
|
|
29
26
|
// the same one the backend branch uses. The registry wins wherever it has an
|
|
30
27
|
// opinion and a contradicting PORT env is reported, never silently obeyed —
|
|
@@ -39,9 +36,6 @@
|
|
|
39
36
|
// makes the healthcheck probe a dead port and the deploy fails (`isRailway`
|
|
40
37
|
// path in the resolver).
|
|
41
38
|
|
|
42
|
-
// Why: Resolve the listen port through the SHARED resolver (`resolv…
|
|
43
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
44
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
45
39
|
// NO-SILENT-REVERTS — surface the failed client build to OBSERVABILITY
|
|
46
40
|
// (event-log → GlitchTip, per event-log-is-the-only-durable-event-log).
|
|
47
41
|
// The minimal-app fallback keeps serving SSR from the LAST-successful
|
|
@@ -55,9 +49,6 @@
|
|
|
55
49
|
// event-log's 7-day retention → surfaces in GlitchTip as an incident
|
|
56
50
|
// trail the operator actually watches.
|
|
57
51
|
|
|
58
|
-
// Why: NO-SILENT-REVERTS — surface the failed client build to OBSER…
|
|
59
|
-
// (full note hoisted to this file's leading header — kept out of the body per
|
|
60
|
-
// no-inline-prose-blocks / prose-stays-in-docs)
|
|
61
52
|
import { recordEvent } from "@teamscala/event-log/record-event";
|
|
62
53
|
import { getAppLogger } from "@teamscala/logger/app-loggers";
|
|
63
54
|
import { BootFatalError } from "@teamscala/os/errors/boot-error";
|