@teamscala/service-boot 0.23.329 → 0.23.331
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 +538 -522
- package/src/agreement-gate.d.ts +19 -0
- package/src/asset-cache-key.d.ts +11 -0
- package/src/asset-optimize.d.ts +17 -0
- package/src/asset-proxy.d.ts +11 -0
- package/src/asset-social-card.d.ts +17 -0
- package/src/attach-agreement-magic.d.ts +20 -0
- package/src/attach-portal-members.d.ts +23 -0
- package/src/attach-proposal-accept.d.ts +26 -0
- package/src/attach-proposal-magic.d.ts +18 -0
- package/src/attach-transfers-upload.d.ts +27 -0
- package/src/auth-gate.d.ts +28 -0
- package/src/auth-gate.ts +6 -68
- package/src/bind-page-handler.d.ts +18 -0
- package/src/build-client-assets/input-hashing.d.ts +25 -0
- package/src/build-client-assets/source-candidates.d.ts +27 -0
- package/src/build-client-assets.d.ts +50 -0
- package/src/build-client-assets.test.ts +1 -1
- package/src/build-client-assets.ts +1 -1
- package/src/compose-page-title.d.ts +41 -0
- package/src/content-gate/access.d.ts +15 -0
- package/src/content-gate/config-types.d.ts +99 -0
- package/src/content-gate/gate.d.ts +13 -0
- package/src/content-gate/parse-cookie.d.ts +9 -0
- package/src/content-gate/token.d.ts +48 -0
- package/src/content-page-floor.d.ts +39 -0
- package/src/discover-blocks.d.ts +28 -0
- package/src/discover-blocks.ts +1 -1
- package/src/expand-roster.d.ts +34 -0
- package/src/fn-routers/agreement-completion-email.d.ts +14 -0
- package/src/fn-routers/agreement-send-router.d.ts +82 -0
- package/src/fn-routers/ai-health-router.d.ts +35 -0
- package/src/fn-routers/auth-router.d.ts +47 -0
- package/src/fn-routers/cache-admin-router.d.ts +57 -0
- package/src/fn-routers/chat-session-router.d.ts +219 -0
- package/src/fn-routers/email-defaults.d.ts +1 -0
- package/src/fn-routers/email-link-ttl.d.ts +1 -0
- package/src/fn-routers/index.d.ts +18 -0
- package/src/fn-routers/index.ts +0 -2
- package/src/fn-routers/panel-data-router.d.ts +19 -0
- package/src/fn-routers/persist-chat-messages.d.ts +36 -0
- package/src/fn-routers/plans-router.d.ts +25 -0
- package/src/fn-routers/proposal-send-router.d.ts +58 -0
- package/src/fn-routers/public-agreement-router.d.ts +289 -0
- package/src/fn-routers/public-assessment-router.d.ts +68 -0
- package/src/fn-routers/public-gpt-session-router.d.ts +143 -0
- package/src/fn-routers/sign-in-flow-router.d.ts +107 -0
- package/src/fn-routers/task-sync-assign.d.ts +305 -0
- package/src/fn-routers/task-sync-assign.test.ts +1 -2
- package/src/fn-routers/task-sync-assign.ts +4 -4
- package/src/fn-routers/task-sync-bind.test.ts +18 -18
- package/src/fn-routers/task-sync-brief.d.ts +96 -0
- package/src/fn-routers/task-sync-brief.test.ts +17 -20
- package/src/fn-routers/task-sync-brief.ts +14 -15
- package/src/fn-routers/task-sync-close.d.ts +41 -0
- package/src/fn-routers/task-sync-dispatch.d.ts +61 -0
- package/src/fn-routers/task-sync-dispatch.test.ts +33 -51
- package/src/fn-routers/task-sync-dispatch.ts +124 -0
- package/src/fn-routers/task-sync-lane.d.ts +49 -0
- package/src/fn-routers/task-sync-lane.ts +125 -0
- package/src/fn-routers/task-sync-projection.d.ts +121 -0
- package/src/fn-routers/task-sync-projection.test.ts +0 -26
- package/src/fn-routers/task-sync-projection.ts +0 -51
- package/src/fn-routers/task-sync-rename.d.ts +91 -0
- package/src/fn-routers/task-sync-router.d.ts +444 -0
- package/src/fn-routers/task-sync-router.test.ts +2 -14
- package/src/fn-routers/task-sync-router.ts +1111 -0
- package/src/fn-routers/tasks-router.d.ts +25 -0
- package/src/fn-routers/user-preferences-router.d.ts +77 -0
- package/src/fn-routers/work-items-router.d.ts +102 -0
- package/src/gate-ttls.d.ts +6 -0
- package/src/gpt-gate.d.ts +25 -0
- package/src/handlers/bun-stable-watch.d.ts +1 -0
- package/src/handlers/pane-outbox-drain.d.ts +1 -0
- package/src/handlers/projects-digest.d.ts +26 -0
- package/src/handlers/prune-stale-data.d.ts +30 -0
- package/src/handlers/registry-stale-inactive-sweep.d.ts +1 -0
- package/src/handlers/scala-tools-currency-watch.d.ts +1 -0
- package/src/handlers/singleton-tools-currency-watch.d.ts +1 -0
- package/src/handlers/sweep-event-log.d.ts +1 -0
- package/src/handlers/sweep-host-cache.d.ts +1 -0
- package/src/handlers/sweep-host-cache.ts +26 -143
- package/src/handlers/upstream-issue-sync.d.ts +1 -0
- package/src/handlers/whatsapp-liveness-logic.d.ts +34 -0
- package/src/handlers/whatsapp-liveness.d.ts +4 -0
- package/src/hono-error-handler.d.ts +25 -0
- package/src/install-harness.d.ts +45 -0
- package/src/install-logging.d.ts +34 -0
- package/src/load-service-install-row.d.ts +24 -0
- package/src/load-service-prisma-client.d.ts +18 -0
- package/src/mount-orpc-router.d.ts +15 -0
- package/src/mount-orpc-router.ts +1 -1
- package/src/mount-server-packages.d.ts +29 -0
- package/src/mount.d.ts +9 -0
- package/src/mutable-app-ref.d.ts +44 -0
- package/src/page-route-shell-types.d.ts +12 -0
- package/src/page-server-orpc/audit-revert-router.d.ts +37 -0
- package/src/page-server-orpc/hub-mcp-client.d.ts +12 -0
- package/src/page-server-orpc/portal-diagnostics-router.d.ts +49 -0
- package/src/page-server-orpc/puck-pages-router.d.ts +58 -0
- package/src/page-server-orpc/server-client.d.ts +16 -0
- package/src/page-server-orpc/templates-router.d.ts +34 -0
- package/src/page-server-orpc/user-preferences-router.d.ts +79 -0
- package/src/pg-boss-handler-registry.d.ts +27 -0
- package/src/pg-boss-mount.d.ts +42 -0
- package/src/proposal-authorized-emails.d.ts +28 -0
- package/src/proposal-chat-inject.d.ts +17 -0
- package/src/proposal-gate.d.ts +18 -0
- package/src/read-html-template.d.ts +38 -0
- package/src/read-viewport-from-request.d.ts +18 -0
- package/src/readiness-gate.d.ts +16 -0
- package/src/register-api-routes.d.ts +18 -0
- package/src/register-crash-handlers.d.ts +15 -0
- package/src/register-page-routes.d.ts +27 -0
- package/src/register-page-routes.ts +3 -0
- package/src/register-page-server-client.d.ts +11 -0
- package/src/register-registry-page-route/ai-chat-prefetch.d.ts +13 -0
- package/src/register-registry-page-route/graph-cache.d.ts +30 -0
- package/src/register-registry-page-route/meta-title.d.ts +2 -0
- package/src/register-registry-page-route/proposal-approval-email-token.d.ts +14 -0
- package/src/register-registry-page-route/proposal-brand-stamping.d.ts +28 -0
- package/src/register-registry-page-route/resolve-page-data.d.ts +1 -0
- package/src/register-registry-page-route.d.ts +27 -0
- package/src/register-static-assets.d.ts +13 -0
- package/src/register-ws-routes.d.ts +28 -0
- package/src/resolve-app-base-url.d.ts +13 -0
- package/src/resolve-brand-favicon.d.ts +28 -0
- package/src/resolve-brand-favicon.ts +1 -1
- package/src/resolve-from-loader-config.d.ts +32 -0
- package/src/resolve-service-context.d.ts +17 -0
- package/src/resolve-service-port.d.ts +75 -0
- package/src/resolve-theme-mode.d.ts +42 -0
- package/src/resolvers/fetch-org-brand.d.ts +2 -0
- package/src/resolvers/portal-route-paths.d.ts +39 -0
- package/src/resolvers/website-by-host-map.d.ts +12 -0
- package/src/resource-chat-inject.d.ts +46 -0
- package/src/resource-not-found.d.ts +60 -0
- package/src/run-boot-hook-list.d.ts +19 -0
- package/src/run-boot-hooks.d.ts +31 -0
- package/src/scala-tools-currency-watchdog.d.ts +10 -0
- package/src/security-headers.d.ts +12 -0
- package/src/serve/serve.d.ts +46 -0
- package/src/serve/stamp-transport-identity.d.ts +32 -0
- package/src/serve/stamp-transport-identity.ts +2 -14
- package/src/server-error-page.d.ts +29 -0
- package/src/start-scheduled-jobs.d.ts +18 -0
- package/src/two-phase-boot.d.ts +136 -0
- package/src/two-phase-boot.ts +17 -85
- package/src/two-phase-health-gate.test.ts +2 -13
- package/src/types.d.ts +46 -0
- package/src/ui-service.d.ts +46 -0
- package/src/ws-boot-self-test.d.ts +19 -0
- package/src/auth-gate.test.ts +0 -70
- package/src/fn-routers/task-sync-lane.test.ts +0 -36
- package/src/handlers/sweep-host-cache.test.ts +0 -133
- package/src/serve/stamp-transport-identity.test.ts +0 -24
- package/src/two-phase-health-gate-client-only.test.ts +0 -77
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
* @indivisible-unit
|
|
6
|
+
*
|
|
7
|
+
* One-call install of the entire logging pipeline. After installLogging()
|
|
8
|
+
* runs, every error in the service — process-level, HTTP middleware, Hono
|
|
9
|
+
* handlers, Puck blocks, even third-party packages calling console.* — is
|
|
10
|
+
* captured by @teamscala/logger and flows to Sentry/GlitchTip (prod) or
|
|
11
|
+
* loga (dev) with full context. Application code never imports the logger
|
|
12
|
+
* or wraps anything in try/catch for telemetry purposes.
|
|
13
|
+
*
|
|
14
|
+
* Marked @indivisible-unit: installLogging (early bootstrap, hardcoded
|
|
15
|
+
* defaults) and applyLoggerConfig (late-stage, DB-driven) are the two
|
|
16
|
+
* phases of the same one-call install — the service boot pipeline calls
|
|
17
|
+
* them in sequence with the same serviceSlug.
|
|
18
|
+
*/
|
|
19
|
+
import { attachRequestLogger } from "@teamscala/logger/install-logging";
|
|
20
|
+
export { attachRequestLogger };
|
|
21
|
+
export interface InstallLoggingOptions {
|
|
22
|
+
serviceSlug: string;
|
|
23
|
+
}
|
|
24
|
+
/** Initial bootstrap install — runs BEFORE DB/Registry are available.
|
|
25
|
+
* Uses hardcoded defaults (INFO level, /tmp/scala-logs). */
|
|
26
|
+
export declare function installLogging(opts: InstallLoggingOptions): void;
|
|
27
|
+
/** Late-stage configuration — runs AFTER Registry is loaded.
|
|
28
|
+
* Injects DB-driven settings into the logger primitive. */
|
|
29
|
+
export declare function applyLoggerConfig(config: {
|
|
30
|
+
minLevel?: "debug" | "info" | "warn" | "error";
|
|
31
|
+
logDir?: string;
|
|
32
|
+
maxFileSize?: number;
|
|
33
|
+
maxFiles?: number;
|
|
34
|
+
}): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Loads the service_install registry row for a given service slug.
|
|
7
|
+
* Uses registry.require() per Constitution Rule 11.
|
|
8
|
+
* Schema is owned by @teamscala/db-validation (Rule 7).
|
|
9
|
+
*/
|
|
10
|
+
import type { ServiceInstallConfig } from "@teamscala/db-validation/registry-schemas/service-install";
|
|
11
|
+
export { ServiceInstallConfigSchema } from "@teamscala/db-validation/registry-schemas/service-install";
|
|
12
|
+
export type { ServiceInstallConfig };
|
|
13
|
+
export interface LoadServiceInstallRowResult {
|
|
14
|
+
success: true;
|
|
15
|
+
config: ServiceInstallConfig;
|
|
16
|
+
}
|
|
17
|
+
export interface LoadServiceInstallRowError {
|
|
18
|
+
success: false;
|
|
19
|
+
error: "row_not_found" | "validation_failed";
|
|
20
|
+
slug: string;
|
|
21
|
+
message: string;
|
|
22
|
+
}
|
|
23
|
+
export type LoadServiceInstallRowOutcome = LoadServiceInstallRowResult | LoadServiceInstallRowError;
|
|
24
|
+
export declare function loadServiceInstallRow(serviceSlug: string): Promise<LoadServiceInstallRowOutcome>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Loads the service's own generated PrismaClient from
|
|
7
|
+
* <cwd>/prisma/generated/prisma/client.ts. Each service repo generates its own
|
|
8
|
+
* client from its own schema.prisma; resolving a static import would pick up
|
|
9
|
+
* whichever @prisma/generated bun resolves first in a multi-service workspace,
|
|
10
|
+
* which is wrong.
|
|
11
|
+
*
|
|
12
|
+
* No fallback: if the generated client is missing the deploy is broken — fail
|
|
13
|
+
* loud with the remediation step.
|
|
14
|
+
*/
|
|
15
|
+
export type ServicePrismaClientConstructor = new (args: {
|
|
16
|
+
adapter: unknown;
|
|
17
|
+
}) => unknown;
|
|
18
|
+
export declare function loadServicePrismaClient(serviceSlug: string): Promise<ServicePrismaClientConstructor>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Mounts the composed ORPC app router (generated Prisma CRUD + custom fn routers)
|
|
7
|
+
* at /api/rpc/* over HTTP via @orpc/server/fetch's RPCHandler.
|
|
8
|
+
* Uses getAppRouter() from @teamscala/orpc/app-router which merges generated
|
|
9
|
+
* routers with custom routers registered via registerCustomRouter().
|
|
10
|
+
*/
|
|
11
|
+
import type { Hono } from "hono";
|
|
12
|
+
export interface OrpcMountResult {
|
|
13
|
+
routeCount: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function mountOrpcRouter(app: Hono, serviceSlug: string): Promise<OrpcMountResult | null>;
|
package/src/mount-orpc-router.ts
CHANGED
|
@@ -37,7 +37,7 @@ export async function mountOrpcRouter(
|
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
// No generated ORPC router is the EXPECTED state for daemon-only / boot-hook
|
|
40
|
-
// services (session-picker,
|
|
40
|
+
// services (session-picker, package-poller, etc.) that own no DB schema or
|
|
41
41
|
// api_routes — they serve no /api/rpc surface. Skip silently: importing a
|
|
42
42
|
// nonexistent module would throw into the catch below and surface a
|
|
43
43
|
// misleading "ORPC router not mounted" WARN on every boot. The catch is
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Walks `service_install.server_packages[]`, dynamic-imports each, and calls
|
|
7
|
+
* its `mount(ctx)` function. Server packages register handlers / boot hooks /
|
|
8
|
+
* scheduled jobs / WS routes via the MountContext exposed in ctx; the
|
|
9
|
+
* resulting MountRegistry is consumed by register-api-routes /
|
|
10
|
+
* register-ws-routes / run-boot-hook-list / start-scheduled-jobs.
|
|
11
|
+
*/
|
|
12
|
+
import type { ServiceInstallConfig } from "@teamscala/db/registry/loader/load-service-install-row";
|
|
13
|
+
import { type MountRegistry } from "@teamscala/os/runtime-contracts/mount-context";
|
|
14
|
+
import type { Hono } from "hono";
|
|
15
|
+
/**
|
|
16
|
+
* Speculatively import every server_package's mount module so Bun compiles
|
|
17
|
+
* the module graphs into its cache NOW, overlapping the (CPU-bound)
|
|
18
|
+
* compilation with whatever I/O the caller runs next. When mountServerPackages
|
|
19
|
+
* later imports the same paths they hit the cache (instant).
|
|
20
|
+
*
|
|
21
|
+
* Same pattern as create-boot-pipeline's speculative preloads — the
|
|
22
|
+
* cross-internet DB I/O in the gate chain (~3.4s) is dead time the compiler
|
|
23
|
+
* can use. Best-effort + non-fatal: a failed import here (wrong candidate
|
|
24
|
+
* path, transient resolution race) is silently swallowed because
|
|
25
|
+
* mountServerPackages will re-attempt with full error surfacing; the preload
|
|
26
|
+
* only warms the cache, never gates boot.
|
|
27
|
+
*/
|
|
28
|
+
export declare function preloadServerPackages(packages: string[]): Promise<void>;
|
|
29
|
+
export declare function mountServerPackages(app: Hono, config: ServiceInstallConfig, serviceSlug: string): Promise<MountRegistry>;
|
package/src/mount.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Server-package mount for opt-in service-boot watchdogs.
|
|
7
|
+
*/
|
|
8
|
+
import type { MountContext } from "@teamscala/os/runtime-contracts/mount-context";
|
|
9
|
+
export declare function mount(ctx: MountContext): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Mutable app reference for two-phase boot. Allows swapping the Hono app
|
|
7
|
+
* atomically after building the full app in the background. The initial app
|
|
8
|
+
* is a minimal tool-only surface (ORPC, data routes) that starts serving
|
|
9
|
+
* immediately; the full app (pages, hydration) is built off-to-the-side and
|
|
10
|
+
* swapped in once complete.
|
|
11
|
+
*
|
|
12
|
+
* Thread-safety: Bun is single-threaded, so a simple module-level variable
|
|
13
|
+
* is sufficient. Atomics are not needed.
|
|
14
|
+
*/
|
|
15
|
+
import type { Hono } from "hono";
|
|
16
|
+
/**
|
|
17
|
+
* Create a new mutable app reference initialized with the provided app.
|
|
18
|
+
* This should be called once at boot time.
|
|
19
|
+
*/
|
|
20
|
+
export declare function initMutableAppRef(initialApp: Hono, label: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get the current app. Throws if the ref hasn't been initialized.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getApp(): Hono;
|
|
25
|
+
/**
|
|
26
|
+
* Get the current app label for logging.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getAppLabel(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Atomically swap the app to a new instance. This is called after the
|
|
31
|
+
* full app is built in the background. Returns the previous label for logging.
|
|
32
|
+
*/
|
|
33
|
+
export declare function swapApp(newApp: Hono, newLabel: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Fetch handler that routes through the mutable app reference.
|
|
36
|
+
* This replaces the direct app.fetch call in the serve layer.
|
|
37
|
+
*
|
|
38
|
+
* Stamps transport-derived identity (x-caller-remote-address/-port + the
|
|
39
|
+
* loopback local-caller comm) via the SAME stampTransportIdentity helper as
|
|
40
|
+
* direct mode, so two-phase-boot (mutable-ref) UI services carry identical
|
|
41
|
+
* identity on every request — closing the gap where the mutable-ref path
|
|
42
|
+
* previously served requests with no transport headers stamped at all.
|
|
43
|
+
*/
|
|
44
|
+
export declare function fetchWithMutableApp(req: Request, server: ReturnType<typeof Bun.serve>): Promise<Response>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system ui-service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Render mode literal shared across page route registration. The old
|
|
7
|
+
* shell-variant types (LegacyShell, PageSlugShell, RegionsShell,
|
|
8
|
+
* PublicShell, ConfigPageRoute) were removed when the Phase 2 deploy-time
|
|
9
|
+
* `service_install.page_routes[]` path was eliminated — all routing is
|
|
10
|
+
* now registry-driven `page_route` rows (Phase 1).
|
|
11
|
+
*/
|
|
12
|
+
export type RenderModeLiteral = "public" | "portals" | "utility";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Audit revert procedure — re-applies an audit_trail row's changes_before to
|
|
7
|
+
* the entity via the canonical generated Prisma procedure for the entity's
|
|
8
|
+
* table: INSERT→delete the created row, UPDATE→restore the old values,
|
|
9
|
+
* DELETE→recreate from the deleted snapshot. The revert write itself fires the
|
|
10
|
+
* audit extension + DB trigger, recording a NEW forward audit_trail row —
|
|
11
|
+
* history is never edited (audit-trail-permanent; the undo is itself audited).
|
|
12
|
+
*
|
|
13
|
+
* Gated to super-admin (reverting business data is privileged). The caller
|
|
14
|
+
* must pass the audit_trail row id; the procedure resolves table + action +
|
|
15
|
+
* before-snapshot from that row.
|
|
16
|
+
*/
|
|
17
|
+
import * as v from "valibot";
|
|
18
|
+
export declare const auditRevertRouter: {
|
|
19
|
+
/**
|
|
20
|
+
* Revert a single audited change by re-applying changes_before through the
|
|
21
|
+
* generated Prisma model for the entity's table. Returns the action taken.
|
|
22
|
+
*/
|
|
23
|
+
revert: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
24
|
+
readonly auditTrailId: v.StringSchema<undefined>;
|
|
25
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
26
|
+
success: true;
|
|
27
|
+
action: string;
|
|
28
|
+
table: string;
|
|
29
|
+
entityId: string;
|
|
30
|
+
}, {
|
|
31
|
+
success: true;
|
|
32
|
+
action: string;
|
|
33
|
+
table: string;
|
|
34
|
+
entityId: string;
|
|
35
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
36
|
+
};
|
|
37
|
+
export type AuditRevertRouter = typeof auditRevertRouter;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Module-level singleton for the hub MCP client. setHubMcpClient(client)
|
|
7
|
+
* is called once at boot by the host service after creating the multi-
|
|
8
|
+
* tenant MCP client; createPageHandler's resolve-page-state reads it via
|
|
9
|
+
* getHubMcpClient to pass through to data loaders.
|
|
10
|
+
*/
|
|
11
|
+
export declare function setHubMcpClient(client: unknown): void;
|
|
12
|
+
export declare function getHubMcpClient(): unknown | undefined;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* ORPC procedures for portal diagnostics. These replace direct Prisma calls
|
|
7
|
+
* in the portal diagnostic section files with proper ORPC procedures that
|
|
8
|
+
* receive context.prisma from the router.
|
|
9
|
+
*/
|
|
10
|
+
import * as v from "valibot";
|
|
11
|
+
export declare const portalDiagRouter: {
|
|
12
|
+
findPortalWebsite: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{}, undefined>, v.NullableSchema<v.ObjectSchema<{
|
|
13
|
+
readonly id: v.StringSchema<undefined>;
|
|
14
|
+
readonly name: v.StringSchema<undefined>;
|
|
15
|
+
readonly organisation_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
16
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
17
|
+
findMember: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
18
|
+
readonly organisationId: v.StringSchema<undefined>;
|
|
19
|
+
}, undefined>, v.NullableSchema<v.ObjectSchema<{
|
|
20
|
+
readonly user_id: v.StringSchema<undefined>;
|
|
21
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
22
|
+
countPages: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
23
|
+
readonly websiteId: v.StringSchema<undefined>;
|
|
24
|
+
}, undefined>, v.NumberSchema<undefined>, Record<never, never>, Record<never, never>>;
|
|
25
|
+
findPages: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
26
|
+
readonly websiteId: v.StringSchema<undefined>;
|
|
27
|
+
readonly path: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
28
|
+
readonly take: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
29
|
+
readonly orderBy: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
30
|
+
}, undefined>, v.ArraySchema<v.ObjectSchema<{
|
|
31
|
+
readonly id: v.StringSchema<undefined>;
|
|
32
|
+
readonly path: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
33
|
+
readonly name: v.StringSchema<undefined>;
|
|
34
|
+
readonly puck_data: v.UnknownSchema;
|
|
35
|
+
readonly updated_at: v.StringSchema<undefined>;
|
|
36
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
37
|
+
findBlockSchemas: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
38
|
+
readonly slugs: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
39
|
+
}, undefined>, v.ArraySchema<v.ObjectSchema<{
|
|
40
|
+
readonly slug: v.StringSchema<undefined>;
|
|
41
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
42
|
+
findWebsites: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
43
|
+
readonly take: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
44
|
+
}, undefined>, v.ArraySchema<v.ObjectSchema<{
|
|
45
|
+
readonly id: v.StringSchema<undefined>;
|
|
46
|
+
readonly name: v.StringSchema<undefined>;
|
|
47
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
48
|
+
};
|
|
49
|
+
export type PortalDiagRouter = typeof portalDiagRouter;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* ORPC procedures for loading Puck pages. These replace the direct Prisma calls
|
|
7
|
+
* in load-puck-page-by-slug.ts with proper ORPC procedures that receive
|
|
8
|
+
* context.prisma from the router.
|
|
9
|
+
*/
|
|
10
|
+
import * as v from "valibot";
|
|
11
|
+
export declare const puckPagesRouter: {
|
|
12
|
+
loadFromWebsite: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
13
|
+
readonly websiteSlug: v.StringSchema<undefined>;
|
|
14
|
+
readonly path: v.StringSchema<undefined>;
|
|
15
|
+
}, undefined>, v.NullableSchema<v.ObjectSchema<{
|
|
16
|
+
readonly id: v.StringSchema<undefined>;
|
|
17
|
+
readonly path: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
18
|
+
readonly puckData: v.UnknownSchema;
|
|
19
|
+
readonly mode: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
20
|
+
readonly render_mode: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
21
|
+
readonly website_slug: v.StringSchema<undefined>;
|
|
22
|
+
readonly organisation_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
23
|
+
readonly meta_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
24
|
+
readonly meta_description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
25
|
+
readonly website: v.ObjectSchema<{
|
|
26
|
+
readonly slug: v.StringSchema<undefined>;
|
|
27
|
+
readonly name: v.StringSchema<undefined>;
|
|
28
|
+
readonly organisation_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
29
|
+
readonly website_type: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
30
|
+
readonly layout_settings: v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
31
|
+
readonly header_settings: v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
32
|
+
readonly footer_settings: v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
33
|
+
}, undefined>;
|
|
34
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
35
|
+
loadById: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
36
|
+
readonly pageId: v.StringSchema<undefined>;
|
|
37
|
+
}, undefined>, v.NullableSchema<v.ObjectSchema<{
|
|
38
|
+
readonly id: v.StringSchema<undefined>;
|
|
39
|
+
readonly path: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
40
|
+
readonly puckData: v.UnknownSchema;
|
|
41
|
+
readonly mode: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
42
|
+
readonly render_mode: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
43
|
+
readonly website_slug: v.StringSchema<undefined>;
|
|
44
|
+
readonly organisation_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
45
|
+
readonly meta_title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
46
|
+
readonly meta_description: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
47
|
+
readonly website: v.ObjectSchema<{
|
|
48
|
+
readonly slug: v.StringSchema<undefined>;
|
|
49
|
+
readonly name: v.StringSchema<undefined>;
|
|
50
|
+
readonly organisation_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
51
|
+
readonly website_type: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
52
|
+
readonly layout_settings: v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
53
|
+
readonly header_settings: v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
54
|
+
readonly footer_settings: v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>;
|
|
55
|
+
}, undefined>;
|
|
56
|
+
}, undefined>, undefined>, Record<never, never>, Record<never, never>>;
|
|
57
|
+
};
|
|
58
|
+
export type PuckPagesRouter = typeof puckPagesRouter;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Server-side ORPC client for in-process direct invocation, per the canonical
|
|
7
|
+
* Vite/Next/Nuxt SSR pattern documented at https://orpc.dev/docs/best-practices/optimize-ssr
|
|
8
|
+
*
|
|
9
|
+
* The host service (scala-install) must call `setServerClient(client)` once
|
|
10
|
+
* at boot, after createRouterClient(appRouter, { context: { prisma } }).
|
|
11
|
+
* Then page-server's createPageHandler reads `getServerClient()` per request
|
|
12
|
+
* — no HTTP loopback, just a typed function call.
|
|
13
|
+
*/
|
|
14
|
+
import { createRouterClient } from "@orpc/server";
|
|
15
|
+
export declare function getServerClient(): ReturnType<typeof createRouterClient>;
|
|
16
|
+
export declare function setServerClient(client: ReturnType<typeof createRouterClient>): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* ORPC procedure: templates.getSettings(slug). Reads the registry_entries row
|
|
7
|
+
* of type='template_settings' for the requested slug, validates against the
|
|
8
|
+
* matching Valibot schema from db-validation, returns typed settings.
|
|
9
|
+
*
|
|
10
|
+
* Per data-access.md: every data read goes through ORPC. The Template
|
|
11
|
+
* components do not call Prisma or registry directly — they receive the
|
|
12
|
+
* typed result of this procedure as a prop.
|
|
13
|
+
*
|
|
14
|
+
* Server-side (SSR) calls land here in-process via createRouterClient.
|
|
15
|
+
* Client-side calls would land here over HTTP via createORPCClient.
|
|
16
|
+
*/
|
|
17
|
+
import * as v from "valibot";
|
|
18
|
+
export declare const templatesRouter: {
|
|
19
|
+
getSettings: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
20
|
+
readonly slug: v.StringSchema<undefined>;
|
|
21
|
+
}, undefined>, import("@orpc/contract").Schema<unknown, unknown>, Record<never, never>, Record<never, never>>;
|
|
22
|
+
/**
|
|
23
|
+
* Patch a template's settings row. The patch is a deep partial applied
|
|
24
|
+
* over the existing config; the merged result is validated against the
|
|
25
|
+
* matching Valibot schema before write. Used by chrome layout (pane
|
|
26
|
+
* widths, toolbar height, etc.) so resizes persist server-side and the
|
|
27
|
+
* next SSR render picks them up directly — no localStorage, no flash.
|
|
28
|
+
*/
|
|
29
|
+
updateSettings: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
30
|
+
readonly slug: v.StringSchema<undefined>;
|
|
31
|
+
readonly patch: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
|
|
32
|
+
}, undefined>, import("@orpc/contract").Schema<unknown, unknown>, Record<never, never>, Record<never, never>>;
|
|
33
|
+
};
|
|
34
|
+
export type TemplatesRouter = typeof templatesRouter;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system page-server
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* ORPC procedures for per-user portal UI preferences (sidebar collapse,
|
|
7
|
+
* panel sizes, active right panel, conversation ID, brand cache).
|
|
8
|
+
* Reads and writes the `portal` key inside `user.preferences` JSONB.
|
|
9
|
+
*
|
|
10
|
+
* The SSR page loads initial state via getPortalPreferences; mutations
|
|
11
|
+
* from usePortalActionHelpers call updatePortalPreferences. This replaces
|
|
12
|
+
* the injected localStorage pattern with DB-backed persistence.
|
|
13
|
+
*/
|
|
14
|
+
import * as v from "valibot";
|
|
15
|
+
export declare const userPreferencesRouter: {
|
|
16
|
+
/**
|
|
17
|
+
* Read the current user's portal preferences from user.preferences.portal.
|
|
18
|
+
* Returns null portal if no preferences exist yet.
|
|
19
|
+
*/
|
|
20
|
+
getPortalPreferences: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, import("@orpc/contract").Schema<unknown, unknown>, import("@orpc/contract").Schema<{
|
|
21
|
+
portal: null;
|
|
22
|
+
} | {
|
|
23
|
+
portal: Record<string, unknown>;
|
|
24
|
+
}, {
|
|
25
|
+
portal: null;
|
|
26
|
+
} | {
|
|
27
|
+
portal: Record<string, unknown>;
|
|
28
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
29
|
+
/**
|
|
30
|
+
* Merge and persist a patch to the user's portal preferences.
|
|
31
|
+
* The patch is a deep partial of the portal object; missing keys
|
|
32
|
+
* are preserved from the existing value.
|
|
33
|
+
*/
|
|
34
|
+
updatePortalPreferences: import("@orpc/server").DecoratedProcedure<Record<never, never>, Record<never, never>, v.ObjectSchema<{
|
|
35
|
+
readonly patch: v.ObjectSchema<{
|
|
36
|
+
readonly theme: v.OptionalSchema<v.NullableSchema<v.PicklistSchema<["light", "dark"], undefined>, undefined>, undefined>;
|
|
37
|
+
readonly paneLeftWidth: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
38
|
+
readonly paneRightWidth: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
39
|
+
readonly sidebarCollapsed: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
40
|
+
readonly activePanel: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
41
|
+
readonly panelSizes: v.OptionalSchema<v.ObjectSchema<{
|
|
42
|
+
readonly main: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
43
|
+
readonly right: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
44
|
+
}, undefined>, undefined>;
|
|
45
|
+
readonly conversationId: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
46
|
+
readonly brandCache: v.OptionalSchema<v.NullableSchema<v.ObjectSchema<{
|
|
47
|
+
readonly logo: v.ObjectSchema<{
|
|
48
|
+
readonly light: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
49
|
+
readonly dark: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
50
|
+
readonly brand: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
51
|
+
}, undefined>;
|
|
52
|
+
readonly primaryColor: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
53
|
+
}, undefined>, undefined>, undefined>;
|
|
54
|
+
}, undefined>;
|
|
55
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
56
|
+
portal: {
|
|
57
|
+
theme?: "dark" | "light" | null | undefined;
|
|
58
|
+
paneLeftWidth?: number | undefined;
|
|
59
|
+
paneRightWidth?: number | undefined;
|
|
60
|
+
sidebarCollapsed?: boolean | undefined;
|
|
61
|
+
activePanel?: string | null | undefined;
|
|
62
|
+
conversationId?: string | null | undefined;
|
|
63
|
+
panelSizes: unknown;
|
|
64
|
+
brandCache: unknown;
|
|
65
|
+
};
|
|
66
|
+
}, {
|
|
67
|
+
portal: {
|
|
68
|
+
theme?: "dark" | "light" | null | undefined;
|
|
69
|
+
paneLeftWidth?: number | undefined;
|
|
70
|
+
paneRightWidth?: number | undefined;
|
|
71
|
+
sidebarCollapsed?: boolean | undefined;
|
|
72
|
+
activePanel?: string | null | undefined;
|
|
73
|
+
conversationId?: string | null | undefined;
|
|
74
|
+
panelSizes: unknown;
|
|
75
|
+
brandCache: unknown;
|
|
76
|
+
};
|
|
77
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
78
|
+
};
|
|
79
|
+
export type UserPreferencesRouter = typeof userPreferencesRouter;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* The pg-boss scheduled-job handler registry — `handler_slug` → handler
|
|
7
|
+
* function. Built on `@teamscala/generic-registry` `createRegistry` (the mandated
|
|
8
|
+
* primitive per `generic-registry-is-the-only-registry-pattern`); a hand-rolled
|
|
9
|
+
* Map or a hardcoded switch in service-boot is the prohibited alternative.
|
|
10
|
+
*
|
|
11
|
+
* Handlers live in packages and self-register at boot (a boot hook / package
|
|
12
|
+
* subscriber shape) by calling `registerScheduledJobHandler`. `resolveHandler`
|
|
13
|
+
* in `pg-boss-mount.ts` reads this registry to dispatch a firing `scheduled_job`
|
|
14
|
+
* row to its registered function.
|
|
15
|
+
*/
|
|
16
|
+
import type { ScheduledJobConfig } from "@teamscala/db-validation/registry-schemas/scheduled-job";
|
|
17
|
+
export type PgBossJobHandler = (ctx: {
|
|
18
|
+
config: ScheduledJobConfig;
|
|
19
|
+
/** Per-job data payload from a one-shot `boss.send()` — absent for scheduled jobs. */
|
|
20
|
+
jobData?: unknown;
|
|
21
|
+
}) => Promise<unknown> | unknown;
|
|
22
|
+
export declare const pgBossHandlerRegistry: import("@teamscala/generic-registry/create-registry").Registry<PgBossJobHandler>;
|
|
23
|
+
/**
|
|
24
|
+
* Register a handler for a `scheduled_job.handler_slug`. Idempotent on re-import
|
|
25
|
+
* (createRegistry.register overwrites silently — last registration wins).
|
|
26
|
+
*/
|
|
27
|
+
export declare function registerScheduledJobHandler(slug: string, handler: PgBossJobHandler): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system server-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Mounts pg-boss for a backend service. Reads all scheduled_job registry
|
|
7
|
+
* entries scoped to the current service from the registry cache, registers
|
|
8
|
+
* pg-boss workers per queue_name, and schedules cron/interval jobs.
|
|
9
|
+
* Per Constitution Rule 6: pg-boss is the single mechanism for all
|
|
10
|
+
* application background work.
|
|
11
|
+
*/
|
|
12
|
+
import { PgBoss } from "pg-boss";
|
|
13
|
+
import "./handlers/prune-stale-data.ts";
|
|
14
|
+
import "./handlers/projects-digest.ts";
|
|
15
|
+
import "./handlers/sweep-event-log.ts";
|
|
16
|
+
import "./handlers/sweep-host-cache.ts";
|
|
17
|
+
import "./handlers/bun-stable-watch.ts";
|
|
18
|
+
import "./handlers/whatsapp-liveness.ts";
|
|
19
|
+
import "./handlers/upstream-issue-sync.ts";
|
|
20
|
+
import "./handlers/scala-tools-currency-watch.ts";
|
|
21
|
+
import "./handlers/singleton-tools-currency-watch.ts";
|
|
22
|
+
import "./handlers/registry-stale-inactive-sweep.ts";
|
|
23
|
+
import "./handlers/pane-outbox-drain.ts";
|
|
24
|
+
/** Returns the mounted PgBoss instance, or null if pg-boss is not running on this service. */
|
|
25
|
+
export declare function getPgBoss(): PgBoss | null;
|
|
26
|
+
export interface PgBossMountContext {
|
|
27
|
+
databaseUrl: string;
|
|
28
|
+
serviceSlug: string;
|
|
29
|
+
packages: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface MountedJob {
|
|
32
|
+
queueName: string;
|
|
33
|
+
handlerSlug: string;
|
|
34
|
+
cron?: string;
|
|
35
|
+
intervalSeconds?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface PgBossMountResult {
|
|
38
|
+
boss: PgBoss | null;
|
|
39
|
+
jobs: MountedJob[];
|
|
40
|
+
}
|
|
41
|
+
export declare function intervalToCron(intervalSeconds: number): string;
|
|
42
|
+
export declare function mountPgBoss(ctx: PgBossMountContext): Promise<PgBossMountResult>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Resolves the set of emails authorized to view a proposal. A proposal is
|
|
7
|
+
* gated (proposal-access) — only these emails can unlock it:
|
|
8
|
+
*
|
|
9
|
+
* - the issuing-org team: every member of the proposal's organisation
|
|
10
|
+
* (better_auth_member → user.email). Lets the agency team open any of their
|
|
11
|
+
* own proposals AND covers existing proposals whose created_by is
|
|
12
|
+
* "system"/null.
|
|
13
|
+
* - the recipient: the proposal's CRM contact (client_database.primary_email),
|
|
14
|
+
* when contact_id is set.
|
|
15
|
+
* - the partner team: every CRM contact belonging to the proposal's partner
|
|
16
|
+
* org (client_database.company_id = proposals.partner_id → primary_email),
|
|
17
|
+
* when partner_id is set. Lets the co-delivery partner's team open a
|
|
18
|
+
* co-branded proposal. The partner is still branding-first; this is the one
|
|
19
|
+
* access edge it carries.
|
|
20
|
+
*
|
|
21
|
+
* Uses $queryRaw (raw SQL) deliberately: the per-service Prisma client is scoped
|
|
22
|
+
* to that service's own models, so the proposals service's client has no
|
|
23
|
+
* `member`/`user` model methods — but $queryRaw runs against the shared DB
|
|
24
|
+
* regardless of the client's model scope. Returns a lowercased Set, checked
|
|
25
|
+
* server-side only (emails never sent to the client). Fail-closed: any error
|
|
26
|
+
* yields an empty set (no access).
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveProposalAuthorizedEmails(proposalId: string): Promise<Set<string>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* Injects the ProposalChatLauncher block into an AUTHORISED proposal page (called
|
|
7
|
+
* from proposalGateConfig.onAuthorized — so the bubble lives strictly behind the
|
|
8
|
+
* email gate, and every proposal gets it with no per-page Puck edit). It builds
|
|
9
|
+
* the proposal's full page content into a runtime-context string and passes it to
|
|
10
|
+
* the launcher, which forwards it to the chat as <runtime_context> — so ONE shared
|
|
11
|
+
* "Proposal Assistant" agent answers about whichever proposal is being viewed.
|
|
12
|
+
*
|
|
13
|
+
* The agent id is config, not code (registries-are-source-of-truth): the
|
|
14
|
+
* `config / proposal-assistant-agent` row carries { agentId }. No row (or no
|
|
15
|
+
* agent) → no injection, the page renders exactly as before (fail-soft).
|
|
16
|
+
*/
|
|
17
|
+
export declare function injectProposalChatLauncher(resolved: Record<string, unknown>, viewerEmail: string): Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* The PROPOSAL content gate, expressed as config for the content-gate primitive
|
|
7
|
+
* (content-gate/). No bespoke gate plumbing — just the proposal-specific bits:
|
|
8
|
+
* which resource (resolved.proposal.id), who's authorized (issuing-org team +
|
|
9
|
+
* recipient), what to seed (initialVisitor for the chat), and how to withhold
|
|
10
|
+
* (replace the proposal body with an injected SignIn gate block + neutralize the
|
|
11
|
+
* meta tags). The engine handles cookie/token/verify/orchestration.
|
|
12
|
+
*
|
|
13
|
+
* Universal: every proposal route exposes resolved.proposal, so this gates every
|
|
14
|
+
* proposal (existing + new) with no per-page block or migration.
|
|
15
|
+
*/
|
|
16
|
+
import type { AccessConfig, ContentGateConfig } from "./content-gate/config-types.ts";
|
|
17
|
+
export declare const proposalGateConfig: ContentGateConfig;
|
|
18
|
+
export declare const proposalAccessConfig: AccessConfig;
|