@teamscala/service-boot 0.23.345 → 0.23.346
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 +1064 -1093
- package/src/two-phase-boot.ts +2 -1
- package/src/agreement-gate.d.ts +0 -19
- package/src/asset-cache-key.d.ts +0 -11
- package/src/asset-optimize.d.ts +0 -17
- package/src/asset-proxy.d.ts +0 -11
- package/src/asset-social-card.d.ts +0 -17
- package/src/attach-agreement-magic.d.ts +0 -20
- package/src/attach-portal-members.d.ts +0 -23
- package/src/attach-proposal-accept.d.ts +0 -26
- package/src/attach-proposal-magic.d.ts +0 -18
- package/src/attach-transfers-upload.d.ts +0 -27
- package/src/auth-gate.d.ts +0 -29
- package/src/bind-page-handler.d.ts +0 -18
- package/src/build-client-assets/input-hashing.d.ts +0 -25
- package/src/build-client-assets/source-candidates.d.ts +0 -27
- package/src/build-client-assets.d.ts +0 -50
- package/src/compose-page-title.d.ts +0 -41
- package/src/content-gate/access.d.ts +0 -15
- package/src/content-gate/config-types.d.ts +0 -99
- package/src/content-gate/gate.d.ts +0 -13
- package/src/content-gate/parse-cookie.d.ts +0 -9
- package/src/content-gate/token.d.ts +0 -48
- package/src/content-page-floor.d.ts +0 -39
- package/src/discover-blocks.d.ts +0 -28
- package/src/expand-roster.d.ts +0 -34
- package/src/fn-routers/agreement-completion-email.d.ts +0 -14
- package/src/fn-routers/agreement-send-router.d.ts +0 -82
- package/src/fn-routers/ai-health-router.d.ts +0 -35
- package/src/fn-routers/auth-router.d.ts +0 -47
- package/src/fn-routers/cache-admin-router.d.ts +0 -57
- package/src/fn-routers/chat-session-router.d.ts +0 -219
- package/src/fn-routers/email-defaults.d.ts +0 -1
- package/src/fn-routers/email-link-ttl.d.ts +0 -1
- package/src/fn-routers/index.d.ts +0 -18
- package/src/fn-routers/orchestrator-registration-router.d.ts +0 -60
- package/src/fn-routers/orchestrator-registration-router.ts +0 -77
- package/src/fn-routers/orchestrator-registration.live.test.ts +0 -70
- package/src/fn-routers/orchestrator-registration.test.ts +0 -23
- package/src/fn-routers/panel-data-router.d.ts +0 -19
- package/src/fn-routers/persist-chat-messages.d.ts +0 -36
- package/src/fn-routers/plans-router.d.ts +0 -25
- package/src/fn-routers/proposal-send-router.d.ts +0 -58
- package/src/fn-routers/public-agreement-router.d.ts +0 -289
- package/src/fn-routers/public-assessment-router.d.ts +0 -68
- package/src/fn-routers/public-gpt-session-router.d.ts +0 -143
- package/src/fn-routers/sign-in-flow-router.d.ts +0 -107
- package/src/fn-routers/task-sync-assign.d.ts +0 -307
- package/src/fn-routers/task-sync-brief.d.ts +0 -98
- package/src/fn-routers/task-sync-close.d.ts +0 -41
- package/src/fn-routers/task-sync-dispatch.d.ts +0 -47
- package/src/fn-routers/task-sync-dispatch.ts +0 -81
- package/src/fn-routers/task-sync-lane.d.ts +0 -49
- package/src/fn-routers/task-sync-lane.ts +0 -114
- package/src/fn-routers/task-sync-projection.d.ts +0 -144
- package/src/fn-routers/task-sync-rename.d.ts +0 -91
- package/src/fn-routers/task-sync-router.d.ts +0 -455
- package/src/fn-routers/task-sync-router.ts +0 -1075
- package/src/fn-routers/tasks-router.d.ts +0 -25
- package/src/fn-routers/user-preferences-router.d.ts +0 -77
- package/src/fn-routers/work-items-router.d.ts +0 -102
- package/src/gate-ttls.d.ts +0 -6
- package/src/gpt-gate.d.ts +0 -25
- package/src/handlers/bun-stable-watch.d.ts +0 -1
- package/src/handlers/pane-outbox-drain.d.ts +0 -1
- package/src/handlers/projects-digest.d.ts +0 -26
- package/src/handlers/prune-stale-data.d.ts +0 -30
- package/src/handlers/registry-stale-inactive-sweep.d.ts +0 -1
- package/src/handlers/scala-tools-currency-watch.d.ts +0 -1
- package/src/handlers/singleton-tools-currency-watch.d.ts +0 -1
- package/src/handlers/sweep-event-log.d.ts +0 -1
- package/src/handlers/sweep-host-cache.d.ts +0 -24
- package/src/handlers/upstream-issue-sync.d.ts +0 -1
- package/src/handlers/whatsapp-liveness-logic.d.ts +0 -34
- package/src/handlers/whatsapp-liveness.d.ts +0 -4
- package/src/hono-error-handler.d.ts +0 -25
- package/src/install-harness.d.ts +0 -45
- package/src/install-logging.d.ts +0 -34
- package/src/load-service-install-row.d.ts +0 -24
- package/src/load-service-prisma-client.d.ts +0 -18
- package/src/mount-orpc-router.d.ts +0 -15
- package/src/mount-server-packages.d.ts +0 -29
- package/src/mount.d.ts +0 -9
- package/src/mutable-app-ref.d.ts +0 -44
- package/src/page-route-shell-types.d.ts +0 -12
- package/src/page-server-orpc/audit-revert-router.d.ts +0 -37
- package/src/page-server-orpc/hub-mcp-client.d.ts +0 -12
- package/src/page-server-orpc/portal-diagnostics-router.d.ts +0 -49
- package/src/page-server-orpc/puck-pages-router.d.ts +0 -58
- package/src/page-server-orpc/server-client.d.ts +0 -16
- package/src/page-server-orpc/templates-router.d.ts +0 -34
- package/src/page-server-orpc/user-preferences-router.d.ts +0 -79
- package/src/pg-boss-handler-registry.d.ts +0 -27
- package/src/pg-boss-mount.d.ts +0 -42
- package/src/proposal-authorized-emails.d.ts +0 -28
- package/src/proposal-chat-inject.d.ts +0 -17
- package/src/proposal-gate.d.ts +0 -18
- package/src/read-html-template.d.ts +0 -38
- package/src/read-viewport-from-request.d.ts +0 -18
- package/src/readiness-gate.d.ts +0 -16
- package/src/register-api-routes.d.ts +0 -18
- package/src/register-crash-handlers.d.ts +0 -15
- package/src/register-page-routes.d.ts +0 -27
- package/src/register-page-server-client.d.ts +0 -11
- package/src/register-registry-page-route/ai-chat-prefetch.d.ts +0 -13
- package/src/register-registry-page-route/graph-cache.d.ts +0 -30
- package/src/register-registry-page-route/meta-title.d.ts +0 -2
- package/src/register-registry-page-route/proposal-approval-email-token.d.ts +0 -14
- package/src/register-registry-page-route/proposal-brand-stamping.d.ts +0 -28
- package/src/register-registry-page-route/resolve-page-data.d.ts +0 -1
- package/src/register-registry-page-route.d.ts +0 -27
- package/src/register-static-assets.d.ts +0 -13
- package/src/register-ws-routes.d.ts +0 -28
- package/src/resolve-app-base-url.d.ts +0 -13
- package/src/resolve-brand-favicon.d.ts +0 -28
- package/src/resolve-from-loader-config.d.ts +0 -32
- package/src/resolve-service-context.d.ts +0 -17
- package/src/resolve-service-port.d.ts +0 -75
- package/src/resolve-theme-mode.d.ts +0 -42
- package/src/resolvers/fetch-org-brand.d.ts +0 -2
- package/src/resolvers/portal-route-paths.d.ts +0 -39
- package/src/resolvers/website-by-host-map.d.ts +0 -12
- package/src/resource-chat-inject.d.ts +0 -46
- package/src/resource-not-found.d.ts +0 -60
- package/src/run-boot-hook-list.d.ts +0 -19
- package/src/run-boot-hooks.d.ts +0 -31
- package/src/scala-tools-currency-watchdog.d.ts +0 -10
- package/src/security-headers.d.ts +0 -12
- package/src/serve/serve.d.ts +0 -46
- package/src/serve/stamp-transport-identity.d.ts +0 -39
- package/src/server-error-page.d.ts +0 -29
- package/src/start-scheduled-jobs.d.ts +0 -18
- package/src/two-phase-boot.d.ts +0 -176
- package/src/types.d.ts +0 -46
- package/src/ui-service.d.ts +0 -46
- package/src/ws-boot-self-test.d.ts +0 -19
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* One transaction for the permanent Orchestrator registration. Database
|
|
7
|
-
* uniqueness is the correctness boundary; every identity row is upserted
|
|
8
|
-
* inside one transaction and callers cannot supply a project/session id.
|
|
9
|
-
*/
|
|
10
|
-
import { authed, type Context } from "./auth-router.ts";
|
|
11
|
-
import { loadRegistryConfig } from "@teamscala/db/registry/load-config";
|
|
12
|
-
import type { PrismaClient } from "@teamscala/db/client";
|
|
13
|
-
import * as v from "valibot";
|
|
14
|
-
|
|
15
|
-
const input = v.object({ runtime_slug: v.string() });
|
|
16
|
-
const registryConfig = v.looseObject({
|
|
17
|
-
enabled: v.optional(v.boolean()), model: v.optional(v.string()), reasoning_effort: v.optional(v.string()), picker_option_slug: v.optional(v.string()),
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export type OrchestratorRegistrationRequest = v.InferOutput<typeof input>;
|
|
21
|
-
|
|
22
|
-
export function buildOrchestratorSpawnPayload(input: {
|
|
23
|
-
workItemId: string;
|
|
24
|
-
launchCommentId: string;
|
|
25
|
-
cliSessionId: string;
|
|
26
|
-
slug: string;
|
|
27
|
-
}) {
|
|
28
|
-
return {
|
|
29
|
-
workItemId: input.workItemId,
|
|
30
|
-
launchCommentId: input.launchCommentId,
|
|
31
|
-
cliSessionId: input.cliSessionId,
|
|
32
|
-
slug: input.slug,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export async function ensureOrchestratorRegistration(
|
|
37
|
-
request: OrchestratorRegistrationRequest,
|
|
38
|
-
context: Context,
|
|
39
|
-
) {
|
|
40
|
-
const runtime = await loadRegistryConfig("agent_runtime", request.runtime_slug, registryConfig);
|
|
41
|
-
if (runtime.enabled === false || runtime.model !== "gpt-5.6-sol" || runtime.reasoning_effort !== "high" || !runtime.picker_option_slug) throw new Error("requested runtime is not the registry-backed Sol High Orchestrator runtime");
|
|
42
|
-
const user = context.user as { id: string; name?: string | null; displayName?: string | null; organisationId?: string | null };
|
|
43
|
-
const organisationId = context.orgId || user.organisationId;
|
|
44
|
-
if (!organisationId) throw new Error("Orchestrator registration requires an organisation");
|
|
45
|
-
return await (context.prisma as PrismaClient).$transaction(async (tx) => {
|
|
46
|
-
const initiative = await tx.work_items.findFirst({ where: { organisation_id: organisationId, kind: "initiative", kind_data: { path: ["tree"], equals: "agent_work" } } });
|
|
47
|
-
if (!initiative) throw new Error("agent-work initiative is not registered");
|
|
48
|
-
const developerName = user.displayName?.trim() || user.name?.trim() || "Developer";
|
|
49
|
-
const project = await tx.work_items.upsert({
|
|
50
|
-
where: { organisation_id_parent_id_assignee_id: { organisation_id: organisationId, parent_id: initiative.id, assignee_id: user.id } },
|
|
51
|
-
create: { kind: "project", parent_id: initiative.id, organisation_id: organisationId, title: `Developer session — ${developerName}`, owner_id: user.id, assignee_id: user.id, created_by: user.id, kind_data: { project_type: "developer_session" } },
|
|
52
|
-
update: { title: `Developer session — ${developerName}`, owner_id: user.id, assignee_id: user.id },
|
|
53
|
-
});
|
|
54
|
-
await tx.work_item_roles.upsert({ where: { work_item_id_user_id_role: { work_item_id: project.id, user_id: user.id, role: "assignee" } }, create: { work_item_id: project.id, user_id: user.id, role: "assignee", organisation_id: organisationId, created_by: user.id }, update: {} });
|
|
55
|
-
const task = await tx.work_items.upsert({
|
|
56
|
-
where: { parent_id_title: { parent_id: project.id, title: "Orchestrator" } },
|
|
57
|
-
create: { kind: "task", parent_id: project.id, organisation_id: organisationId, title: "Orchestrator", owner_id: user.id, assignee_id: user.id, created_by: user.id },
|
|
58
|
-
update: { owner_id: user.id, assignee_id: user.id },
|
|
59
|
-
});
|
|
60
|
-
const session = await tx.cli_sessions.upsert({
|
|
61
|
-
where: { work_item_id: task.id },
|
|
62
|
-
create: { authority: "operator", role: "orchestrator", cli_kind: "codex", picker_option_slug: runtime.picker_option_slug, runtime_slug: request.runtime_slug, provider: "codex", model: runtime.model, source_adapter: "orchestrator", label: "Orchestrator", lifecycle_state: "registering", host_route: {}, restore_metadata: {}, adapter_metadata: { project_id: project.id, work_item_id: task.id }, work_item_id: task.id },
|
|
63
|
-
update: { picker_option_slug: runtime.picker_option_slug, runtime_slug: request.runtime_slug, model: runtime.model, closed_at: null, lifecycle_state: "registering" },
|
|
64
|
-
});
|
|
65
|
-
const startupBrief = `You are the permanent Orchestrator for developer project “${project.title}” (${project.id}). Coordinate all work through the canonical work_items and comments surfaces. Every tab is a child task, every prompt and reply is a comment, and cli_sessions is runtime identity only. Dispatch implementation through the fleet and reconcile durable outcomes; never create a parallel task, message, or session source.`;
|
|
66
|
-
const launchComment = await tx.comments.upsert({ where: { work_item_id_system_key: { work_item_id: task.id, system_key: "orchestrator-startup" } }, update: { source_cli_session_id: session.id, sender_role: "orchestrator", sender_name: "Orchestrator" }, create: { work_item_id: task.id, content: startupBrief, system_key: "orchestrator-startup", source_cli_session_id: session.id, sender_role: "orchestrator", sender_name: "Orchestrator" } });
|
|
67
|
-
await tx.cli_session_transitions.upsert({ where: { session_id_idempotency_key: { session_id: session.id, idempotency_key: `register:${project.id}` } }, create: { session_id: session.id, idempotency_key: `register:${project.id}`, from_state: null, to_state: "registering", trigger_event: "atomic-registration", metadata_json: { work_item_id: task.id } }, update: {} });
|
|
68
|
-
await tx.host_commands.upsert({ where: { command_idempotency_key: { command: "picker_spawn_tab", idempotency_key: `orchestrator-visible:${project.id}` } }, update: {}, create: { command: "picker_spawn_tab", idempotency_key: `orchestrator-visible:${project.id}`, payload: buildOrchestratorSpawnPayload({ workItemId: task.id, launchCommentId: launchComment.id, cliSessionId: session.id, slug: runtime.picker_option_slug }), originator: { role: "orchestrator", session_id: session.id } } });
|
|
69
|
-
return { projectId: project.id, taskId: task.id, sessionId: session.id, launchCommentId: launchComment.id, runtime: request.runtime_slug, slug: runtime.picker_option_slug };
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const orchestratorRegistrationRouter = {
|
|
74
|
-
ensure: authed.input(input).handler(async ({ input: request, context }) => {
|
|
75
|
-
return ensureOrchestratorRegistration(request, context);
|
|
76
|
-
}),
|
|
77
|
-
};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* Real database concurrency acceptance for the canonical developer-session
|
|
7
|
-
* registration. Run with PM_FLEET_LIVE_TEST=1 and a PM_FLEET_TEST_USER_ID
|
|
8
|
-
* (plus PM_FLEET_TEST_ORG_ID when the user has more than one membership).
|
|
9
|
-
*/
|
|
10
|
-
import { describe, expect, it } from "bun:test";
|
|
11
|
-
import { createDbClient } from "@teamscala/db/create-db-client";
|
|
12
|
-
import { registerPrismaClient } from "@teamscala/db/prisma-registry";
|
|
13
|
-
import { ensureOrchestratorRegistration } from "./orchestrator-registration-router.ts";
|
|
14
|
-
import type { Context } from "./auth-router.ts";
|
|
15
|
-
|
|
16
|
-
const live = process.env.PM_FLEET_LIVE_TEST === "1";
|
|
17
|
-
|
|
18
|
-
describe.skipIf(!live)("canonical Orchestrator registration — live database", () => {
|
|
19
|
-
it("concurrent callers converge on one project, task, comment, runtime, transition, and spawn intent", async () => {
|
|
20
|
-
const userId = process.env.PM_FLEET_TEST_USER_ID;
|
|
21
|
-
if (!userId) throw new Error("PM_FLEET_TEST_USER_ID is required for the live concurrency acceptance");
|
|
22
|
-
const db = await createDbClient({ serviceName: "service-boot-pm-fleet-live", maxConnections: 10 });
|
|
23
|
-
try {
|
|
24
|
-
registerPrismaClient(db.prisma as never);
|
|
25
|
-
const user = await db.prisma.user.findUniqueOrThrow({ where: { id: userId }, select: { id: true, name: true } });
|
|
26
|
-
const organisationId = process.env.PM_FLEET_TEST_ORG_ID;
|
|
27
|
-
if (!organisationId) throw new Error("PM_FLEET_TEST_ORG_ID is required for the live concurrency acceptance");
|
|
28
|
-
const context: Context = { user: { id: user.id, name: user.name, organisationId }, orgId: organisationId, prisma: db.prisma, headers: new Headers() };
|
|
29
|
-
const results = await Promise.all(Array.from({ length: 8 }, () => ensureOrchestratorRegistration({ runtime_slug: "codex-acp" }, context)));
|
|
30
|
-
const projectIds = new Set(results.map((result) => result.projectId));
|
|
31
|
-
const taskIds = new Set(results.map((result) => result.taskId));
|
|
32
|
-
const sessionIds = new Set(results.map((result) => result.sessionId));
|
|
33
|
-
expect(projectIds.size).toBe(1);
|
|
34
|
-
expect(taskIds.size).toBe(1);
|
|
35
|
-
expect(sessionIds.size).toBe(1);
|
|
36
|
-
const projectId = results[0]?.projectId;
|
|
37
|
-
const taskId = results[0]?.taskId;
|
|
38
|
-
const sessionId = results[0]?.sessionId;
|
|
39
|
-
expect(await db.prisma.work_items.count({ where: { id: projectId, parent: { kind: "initiative", kind_data: { path: ["tree"], equals: "agent_work" } } } })).toBe(1);
|
|
40
|
-
expect(await db.prisma.work_items.count({ where: { id: taskId, parent_id: projectId, kind: "task", title: "Orchestrator" } })).toBe(1);
|
|
41
|
-
const startupComments = await db.prisma.comments.findMany({
|
|
42
|
-
where: { work_item_id: taskId, system_key: "orchestrator-startup" },
|
|
43
|
-
select: { id: true, source_cli_session_id: true, sender_role: true, sender_name: true },
|
|
44
|
-
});
|
|
45
|
-
expect(startupComments).toHaveLength(1);
|
|
46
|
-
expect(startupComments[0]).toMatchObject({
|
|
47
|
-
id: results[0]?.launchCommentId,
|
|
48
|
-
source_cli_session_id: sessionId,
|
|
49
|
-
sender_role: "orchestrator",
|
|
50
|
-
sender_name: "Orchestrator",
|
|
51
|
-
});
|
|
52
|
-
expect(await db.prisma.cli_sessions.count({ where: { id: sessionId, work_item_id: taskId, role: "orchestrator", closed_at: null } })).toBe(1);
|
|
53
|
-
expect(await db.prisma.cli_session_transitions.count({ where: { session_id: sessionId, idempotency_key: `register:${projectId}` } })).toBe(1);
|
|
54
|
-
const spawnIntents = await db.prisma.host_commands.findMany({
|
|
55
|
-
where: { command: "picker_spawn_tab", idempotency_key: `orchestrator-visible:${projectId}` },
|
|
56
|
-
select: { payload: true },
|
|
57
|
-
});
|
|
58
|
-
expect(spawnIntents).toHaveLength(1);
|
|
59
|
-
expect(spawnIntents[0]?.payload).toMatchObject({
|
|
60
|
-
workItemId: taskId,
|
|
61
|
-
launchCommentId: results[0]?.launchCommentId,
|
|
62
|
-
cliSessionId: sessionId,
|
|
63
|
-
slug: results[0]?.slug,
|
|
64
|
-
});
|
|
65
|
-
expect(Object.keys(spawnIntents[0]?.payload as Record<string, unknown>).sort()).toEqual(["cliSessionId", "launchCommentId", "slug", "workItemId"]);
|
|
66
|
-
} finally {
|
|
67
|
-
await db.disconnect();
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { buildOrchestratorSpawnPayload } from "./orchestrator-registration-router.ts";
|
|
3
|
-
|
|
4
|
-
describe("orchestrator spawn intent", () => {
|
|
5
|
-
it("uses the generated Rust slug contract and carries no alternate launch input", () => {
|
|
6
|
-
const payload = buildOrchestratorSpawnPayload({
|
|
7
|
-
workItemId: "task-1",
|
|
8
|
-
launchCommentId: "comment-1",
|
|
9
|
-
cliSessionId: "session-1",
|
|
10
|
-
slug: "codex-sol-acp-client",
|
|
11
|
-
});
|
|
12
|
-
expect(payload).toEqual({
|
|
13
|
-
workItemId: "task-1",
|
|
14
|
-
launchCommentId: "comment-1",
|
|
15
|
-
cliSessionId: "session-1",
|
|
16
|
-
slug: "codex-sol-acp-client",
|
|
17
|
-
});
|
|
18
|
-
expect(payload).not.toHaveProperty("pickerOptionSlug");
|
|
19
|
-
expect(payload).not.toHaveProperty("initialPrompt");
|
|
20
|
-
expect(payload).not.toHaveProperty("windowName");
|
|
21
|
-
expect(Object.keys(payload).sort()).toEqual(["cliSessionId", "launchCommentId", "slug", "workItemId"]);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as v from "valibot";
|
|
2
|
-
interface Context {
|
|
3
|
-
prisma: {
|
|
4
|
-
builda_websites: {
|
|
5
|
-
findFirst: (args: unknown) => Promise<{
|
|
6
|
-
organisation_id?: string | null;
|
|
7
|
-
} | null>;
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
export declare const resolvePanelDataHandler: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
12
|
-
readonly panelSlug: v.StringSchema<undefined>;
|
|
13
|
-
readonly websiteSlug: v.StringSchema<undefined>;
|
|
14
|
-
/** Tenant orgId (preferred over the website's organisation_id, which is
|
|
15
|
-
* the platform org on a multi-tenant portal — not the tenant). The
|
|
16
|
-
* caller (RegionPageSwap) threads this from __PAGE_DATA__.orgId. */
|
|
17
|
-
readonly orgId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
18
|
-
}, undefined>, import("@orpc/contract").Schema<Record<string, unknown> | null, Record<string, unknown> | null>, Record<never, never>, Record<never, never>>;
|
|
19
|
-
export {};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* The ONE chat-message write surface for the session routers. Both the authed
|
|
7
|
-
* (chatSession) and public (publicGptSession) saveMessages procedures persist
|
|
8
|
-
* turns through here — they differ only in IDENTITY/ownership (user_id vs
|
|
9
|
-
* contact_email, resolved in the router before calling this), never in the
|
|
10
|
-
* write itself. Keeping the write in two routers was literal duplication
|
|
11
|
-
* (no-duplicate-canonical-units) and is why the stable-id fix had to be applied
|
|
12
|
-
* twice.
|
|
13
|
-
*
|
|
14
|
-
* Upserts each message on its SDK UIMessage id so a re-save of a turn (a retry,
|
|
15
|
-
* a reconnect after a network drop, or a stray dual-write) updates the one row
|
|
16
|
-
* in place instead of inserting a duplicate (chat-message-ids-server-stable);
|
|
17
|
-
* falls back to create only for legacy id-less callers. occurred_at is stamped
|
|
18
|
-
* with a 1ms step preserving array order so same-second saves restore in order.
|
|
19
|
-
*/
|
|
20
|
-
export interface ChatMessageInput {
|
|
21
|
-
id?: string;
|
|
22
|
-
role: string;
|
|
23
|
-
content: string;
|
|
24
|
-
parts?: unknown[];
|
|
25
|
-
/** The SDK UIMessage `metadata` — carries per-message token usage
|
|
26
|
-
* (`inputTokens`/`outputTokens`/`contextWindow`/`model`) the stream attaches
|
|
27
|
-
* via `messageMetadata`. Persisted so the context-usage gauge can rehydrate
|
|
28
|
-
* on reload and budget-enforcement can read per-message token counts; without
|
|
29
|
-
* it the save dropped the usage and the gauge came back blank on refresh. */
|
|
30
|
-
metadata?: Record<string, unknown> | null;
|
|
31
|
-
}
|
|
32
|
-
export declare function persistChatMessages(prisma: any, opts: {
|
|
33
|
-
conversationId: string;
|
|
34
|
-
organisationId: string | null;
|
|
35
|
-
messages: ChatMessageInput[];
|
|
36
|
-
}): Promise<void>;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* ORPC procedures for plan creation with tasks and subtasks.
|
|
7
|
-
* Extracted from @teamscala/orpc/fn-router — primitives tier must not
|
|
8
|
-
* contain application-specific work_items logic.
|
|
9
|
-
*/
|
|
10
|
-
import { type Context } from "./auth-router.ts";
|
|
11
|
-
export declare const plansRouter: {
|
|
12
|
-
save: import("@orpc/server").DecoratedProcedure<import("@orpc/server").MergedInitialContext<Context & Record<never, never>, Context, Context>, import("@orpc/server").MergedCurrentContext<Context, {
|
|
13
|
-
headers: Headers;
|
|
14
|
-
resolveUser?: (headers: Headers, prisma: any) => Promise<import("./auth-router.ts").User | null>;
|
|
15
|
-
prisma: any;
|
|
16
|
-
user: import("./auth-router.ts").User;
|
|
17
|
-
orgId: string | null | undefined;
|
|
18
|
-
}>, import("@orpc/contract").Schema<unknown, unknown>, import("@orpc/contract").Schema<{
|
|
19
|
-
success: boolean;
|
|
20
|
-
data: any;
|
|
21
|
-
}, {
|
|
22
|
-
success: boolean;
|
|
23
|
-
data: any;
|
|
24
|
-
}>, Record<never, never>, Record<never, never>>;
|
|
25
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* The proposal SEND router — the proposal twin of agreement-send-router. An
|
|
7
|
-
* authed portal caller POSTs {proposalId, baseUrl} to email the proposal's CRM
|
|
8
|
-
* contact a per-recipient magic-link (no email gate, no OTP — see
|
|
9
|
-
* attach-proposal-magic.ts) to view their proposal. Resend-backed.
|
|
10
|
-
*/
|
|
11
|
-
import * as v from "valibot";
|
|
12
|
-
interface User {
|
|
13
|
-
id: string;
|
|
14
|
-
organisationId: string | null;
|
|
15
|
-
}
|
|
16
|
-
interface Context {
|
|
17
|
-
user: User | null | undefined;
|
|
18
|
-
headers: Headers;
|
|
19
|
-
resolveUser?: (headers: Headers, prisma: any) => Promise<User | null>;
|
|
20
|
-
prisma: any;
|
|
21
|
-
}
|
|
22
|
-
export declare const proposalSendRouter: {
|
|
23
|
-
send: import("@orpc/server").DecoratedProcedure<import("@orpc/server").MergedInitialContext<Context & Record<never, never>, Context, Context>, import("@orpc/server").MergedCurrentContext<Context, {
|
|
24
|
-
headers: Headers;
|
|
25
|
-
resolveUser?: (headers: Headers, prisma: any) => Promise<User | null>;
|
|
26
|
-
prisma: any;
|
|
27
|
-
user: User;
|
|
28
|
-
}>, v.ObjectSchema<{
|
|
29
|
-
readonly proposalId: v.StringSchema<undefined>;
|
|
30
|
-
/** Public base URL of the proposals site, e.g. https://proposals-dev.scala.business (no trailing slash). */
|
|
31
|
-
readonly baseUrl: v.StringSchema<undefined>;
|
|
32
|
-
}, undefined>, import("@orpc/contract").Schema<{
|
|
33
|
-
ok: false;
|
|
34
|
-
error: string;
|
|
35
|
-
sentAt?: undefined;
|
|
36
|
-
url?: undefined;
|
|
37
|
-
email?: undefined;
|
|
38
|
-
} | {
|
|
39
|
-
error?: undefined;
|
|
40
|
-
ok: true;
|
|
41
|
-
sentAt: string;
|
|
42
|
-
url: string;
|
|
43
|
-
email: string;
|
|
44
|
-
}, {
|
|
45
|
-
ok: false;
|
|
46
|
-
error: string;
|
|
47
|
-
sentAt?: undefined;
|
|
48
|
-
url?: undefined;
|
|
49
|
-
email?: undefined;
|
|
50
|
-
} | {
|
|
51
|
-
error?: undefined;
|
|
52
|
-
ok: true;
|
|
53
|
-
sentAt: string;
|
|
54
|
-
url: string;
|
|
55
|
-
email: string;
|
|
56
|
-
}>, Record<never, never>, Record<never, never>>;
|
|
57
|
-
};
|
|
58
|
-
export {};
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* Public ORPC procedures for DocuSign-style agreement signing, reached by the
|
|
7
|
-
* sign-in block's in-document signing blocks over the public HTTP transport
|
|
8
|
-
* (getOrpcClient().fn.publicAgreement.*). The unguessable agreement id plus an
|
|
9
|
-
* email that matches one of the agreement's parties IS the gate (no password).
|
|
10
|
-
*
|
|
11
|
-
* This is the off-the-shelf path per building-applications: server logic beyond
|
|
12
|
-
* CRUD is a typed ORPC procedure (the publicAssessment/publicGptSession shape),
|
|
13
|
-
* NOT a hand-written /api/data/* Hono handler and NOT a loopback fetch to the
|
|
14
|
-
* service's own ORPC. Writes go through context.prisma inside the handler — the
|
|
15
|
-
* sanctioned in-handler DB access (orpc-is-the-only-api) — so the audit trigger
|
|
16
|
-
* sees the ORPC caller context, the same proven path publicGptSession uses.
|
|
17
|
-
*
|
|
18
|
-
* Multi-party model: signature_data holds a parties roster (JSON) so one
|
|
19
|
-
* agreement can require signatures from several parties (e.g. Provider + Client)
|
|
20
|
-
* with no schema change. Each party is gated by its own email; the agreement
|
|
21
|
-
* completes (signed_at set) only when every party has signed. A single-signer
|
|
22
|
-
* agreement falls back to the original signer_email/signer_name columns.
|
|
23
|
-
*/
|
|
24
|
-
import * as v from "valibot";
|
|
25
|
-
/** The Certificate of Completion display copy. DB-driven via the
|
|
26
|
-
* `config/certificate-of-completion` registry row — mirrors the agreement gate's
|
|
27
|
-
* `config/content-gate-agreement` pattern (same signing surface), so an operator
|
|
28
|
-
* can rebrand/reword the certificate via `registry_edit` with no deploy; the
|
|
29
|
-
* hardcoded defaults are the fallback. Generic structural data-column labels
|
|
30
|
-
* (Signer/Role/Envelope ID/…) stay in the component, exactly as the gate keeps
|
|
31
|
-
* its structural markup in code. */
|
|
32
|
-
export interface CertificateCopy {
|
|
33
|
-
title: string;
|
|
34
|
-
signersHeading: string;
|
|
35
|
-
sealHeading: string;
|
|
36
|
-
sealNote: string;
|
|
37
|
-
footer: string;
|
|
38
|
-
badgeCompleted: string;
|
|
39
|
-
badgeInProgress: string;
|
|
40
|
-
/** Audit-table column labels — DB-driven so rewording is a registry_edit.
|
|
41
|
-
* Each labels BOTH the <th> header AND the stacked-row data-label on mobile
|
|
42
|
-
* (one source, kept in sync), never a second hardcoded copy. */
|
|
43
|
-
colSigner: string;
|
|
44
|
-
colRole: string;
|
|
45
|
-
colSigned: string;
|
|
46
|
-
colIp: string;
|
|
47
|
-
colAuth: string;
|
|
48
|
-
}
|
|
49
|
-
/** The Certificate of Completion data shape — the court-style audit certificate.
|
|
50
|
-
* One home: {@link buildCertificateData} is consumed by both the
|
|
51
|
-
* `publicAgreement.certificate` ORPC and the SSR agreement gate, so the signing
|
|
52
|
-
* block receives identical data whether it reads the ORPC response or the
|
|
53
|
-
* server-seeded prop. */
|
|
54
|
-
export interface CertificateData {
|
|
55
|
-
ok: boolean;
|
|
56
|
-
envelopeId?: string;
|
|
57
|
-
documentName?: string | null;
|
|
58
|
-
issuedAt?: string;
|
|
59
|
-
complete?: boolean;
|
|
60
|
-
createdAt?: string | null;
|
|
61
|
-
sentAt?: string | null;
|
|
62
|
-
viewedAt?: string | null;
|
|
63
|
-
signedAt?: string | null;
|
|
64
|
-
documentHash?: string | null;
|
|
65
|
-
hashAlgo?: string | null;
|
|
66
|
-
hashedAt?: string | null;
|
|
67
|
-
parties?: {
|
|
68
|
-
role: string;
|
|
69
|
-
name: string | null;
|
|
70
|
-
email: string | null;
|
|
71
|
-
title: string | null;
|
|
72
|
-
company: string | null;
|
|
73
|
-
signedAt: string | null;
|
|
74
|
-
ip: string | null;
|
|
75
|
-
userAgent: string | null;
|
|
76
|
-
authMethod: string | null;
|
|
77
|
-
}[];
|
|
78
|
-
/** DB-driven display copy (config/certificate-of-completion); null when the
|
|
79
|
-
* config row is missing/broken — the component falls back to FALLBACK_COPY. */
|
|
80
|
-
copy?: CertificateCopy | null;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Build the Certificate of Completion data for an agreement, gated to a party
|
|
84
|
-
* email — signer evidence (IP/device) is never exposed to a non-party. One data
|
|
85
|
-
* home: the `publicAgreement.certificate` ORPC and the SSR agreement gate
|
|
86
|
-
* (`buildSigningSession` in agreement-gate.ts) both call this. The read is
|
|
87
|
-
* intentionally RLS-unscoped via the raw registry prisma — the certificate is
|
|
88
|
-
* reached without a session (AG cookie only), which context.prisma's RLS would
|
|
89
|
-
* otherwise treat as no-org and hide. Accepts either the agreement record id or
|
|
90
|
-
* its page id (the UUID the signer sees in the URL is the page id).
|
|
91
|
-
*/
|
|
92
|
-
export declare function buildCertificateData(agreementId: string, email: string): Promise<CertificateData>;
|
|
93
|
-
interface Context {
|
|
94
|
-
prisma: any;
|
|
95
|
-
headers: Headers;
|
|
96
|
-
resolveUser?: (headers: Headers, prisma: any) => Promise<any>;
|
|
97
|
-
}
|
|
98
|
-
export declare const publicAgreementRouter: {
|
|
99
|
-
verify: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
100
|
-
readonly agreementId: v.StringSchema<undefined>;
|
|
101
|
-
readonly email: v.StringSchema<undefined>;
|
|
102
|
-
}, undefined>, import("@orpc/contract").Schema<{
|
|
103
|
-
matched: false;
|
|
104
|
-
multiParty?: undefined;
|
|
105
|
-
role?: undefined;
|
|
106
|
-
partySignedAt?: undefined;
|
|
107
|
-
allSigned?: undefined;
|
|
108
|
-
parties?: undefined;
|
|
109
|
-
name?: undefined;
|
|
110
|
-
signerName?: undefined;
|
|
111
|
-
signedAt?: undefined;
|
|
112
|
-
accessToken?: undefined;
|
|
113
|
-
} | {
|
|
114
|
-
matched: boolean;
|
|
115
|
-
multiParty: boolean;
|
|
116
|
-
name: any;
|
|
117
|
-
role: string;
|
|
118
|
-
signerName: string;
|
|
119
|
-
partySignedAt: string | null;
|
|
120
|
-
allSigned: boolean;
|
|
121
|
-
parties: import("@teamscala/document-signing/agreement-parties").PublicAgreementParty[];
|
|
122
|
-
accessToken: string | null;
|
|
123
|
-
signedAt?: undefined;
|
|
124
|
-
} | {
|
|
125
|
-
multiParty?: undefined;
|
|
126
|
-
role?: undefined;
|
|
127
|
-
partySignedAt?: undefined;
|
|
128
|
-
allSigned?: undefined;
|
|
129
|
-
parties?: undefined;
|
|
130
|
-
matched: boolean;
|
|
131
|
-
name: any;
|
|
132
|
-
signerName: any;
|
|
133
|
-
signedAt: any;
|
|
134
|
-
accessToken: string | null;
|
|
135
|
-
}, {
|
|
136
|
-
matched: false;
|
|
137
|
-
multiParty?: undefined;
|
|
138
|
-
role?: undefined;
|
|
139
|
-
partySignedAt?: undefined;
|
|
140
|
-
allSigned?: undefined;
|
|
141
|
-
parties?: undefined;
|
|
142
|
-
name?: undefined;
|
|
143
|
-
signerName?: undefined;
|
|
144
|
-
signedAt?: undefined;
|
|
145
|
-
accessToken?: undefined;
|
|
146
|
-
} | {
|
|
147
|
-
matched: boolean;
|
|
148
|
-
multiParty: boolean;
|
|
149
|
-
name: any;
|
|
150
|
-
role: string;
|
|
151
|
-
signerName: string;
|
|
152
|
-
partySignedAt: string | null;
|
|
153
|
-
allSigned: boolean;
|
|
154
|
-
parties: import("@teamscala/document-signing/agreement-parties").PublicAgreementParty[];
|
|
155
|
-
accessToken: string | null;
|
|
156
|
-
signedAt?: undefined;
|
|
157
|
-
} | {
|
|
158
|
-
multiParty?: undefined;
|
|
159
|
-
role?: undefined;
|
|
160
|
-
partySignedAt?: undefined;
|
|
161
|
-
allSigned?: undefined;
|
|
162
|
-
parties?: undefined;
|
|
163
|
-
matched: boolean;
|
|
164
|
-
name: any;
|
|
165
|
-
signerName: any;
|
|
166
|
-
signedAt: any;
|
|
167
|
-
accessToken: string | null;
|
|
168
|
-
}>, Record<never, never>, Record<never, never>>;
|
|
169
|
-
sign: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
170
|
-
readonly agreementId: v.StringSchema<undefined>;
|
|
171
|
-
readonly email: v.StringSchema<undefined>;
|
|
172
|
-
readonly signatureData: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
173
|
-
readonly signerName: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
174
|
-
readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
175
|
-
readonly company: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
176
|
-
}, undefined>, import("@orpc/contract").Schema<{
|
|
177
|
-
signerName?: undefined;
|
|
178
|
-
signedAt?: undefined;
|
|
179
|
-
ok: false;
|
|
180
|
-
error: string;
|
|
181
|
-
alreadySigned?: undefined;
|
|
182
|
-
payUrl?: undefined;
|
|
183
|
-
} | {
|
|
184
|
-
ok: true;
|
|
185
|
-
role: string;
|
|
186
|
-
signedAt: string;
|
|
187
|
-
allSigned: boolean;
|
|
188
|
-
parties: import("@teamscala/document-signing/agreement-parties").PublicAgreementParty[];
|
|
189
|
-
payUrl: string | null;
|
|
190
|
-
} | {
|
|
191
|
-
error?: undefined;
|
|
192
|
-
ok: true;
|
|
193
|
-
alreadySigned: boolean;
|
|
194
|
-
signedAt: any;
|
|
195
|
-
signerName: any;
|
|
196
|
-
payUrl?: undefined;
|
|
197
|
-
} | {
|
|
198
|
-
error?: undefined;
|
|
199
|
-
alreadySigned?: undefined;
|
|
200
|
-
ok: true;
|
|
201
|
-
signedAt: any;
|
|
202
|
-
signerName: any;
|
|
203
|
-
payUrl: string | null;
|
|
204
|
-
}, {
|
|
205
|
-
signerName?: undefined;
|
|
206
|
-
signedAt?: undefined;
|
|
207
|
-
ok: false;
|
|
208
|
-
error: string;
|
|
209
|
-
alreadySigned?: undefined;
|
|
210
|
-
payUrl?: undefined;
|
|
211
|
-
} | {
|
|
212
|
-
ok: true;
|
|
213
|
-
role: string;
|
|
214
|
-
signedAt: string;
|
|
215
|
-
allSigned: boolean;
|
|
216
|
-
parties: import("@teamscala/document-signing/agreement-parties").PublicAgreementParty[];
|
|
217
|
-
payUrl: string | null;
|
|
218
|
-
} | {
|
|
219
|
-
error?: undefined;
|
|
220
|
-
ok: true;
|
|
221
|
-
alreadySigned: boolean;
|
|
222
|
-
signedAt: any;
|
|
223
|
-
signerName: any;
|
|
224
|
-
payUrl?: undefined;
|
|
225
|
-
} | {
|
|
226
|
-
error?: undefined;
|
|
227
|
-
alreadySigned?: undefined;
|
|
228
|
-
ok: true;
|
|
229
|
-
signedAt: any;
|
|
230
|
-
signerName: any;
|
|
231
|
-
payUrl: string | null;
|
|
232
|
-
}>, Record<never, never>, Record<never, never>>;
|
|
233
|
-
certificate: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
234
|
-
readonly agreementId: v.StringSchema<undefined>;
|
|
235
|
-
readonly email: v.StringSchema<undefined>;
|
|
236
|
-
}, undefined>, import("@orpc/contract").Schema<CertificateData, CertificateData>, Record<never, never>, Record<never, never>>;
|
|
237
|
-
verifyDocument: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
238
|
-
readonly agreementId: v.StringSchema<undefined>;
|
|
239
|
-
}, undefined>, import("@orpc/contract").Schema<{
|
|
240
|
-
parties?: undefined;
|
|
241
|
-
signedAt?: undefined;
|
|
242
|
-
ok: false;
|
|
243
|
-
envelopeId?: undefined;
|
|
244
|
-
documentName?: undefined;
|
|
245
|
-
complete?: undefined;
|
|
246
|
-
sealedHash?: undefined;
|
|
247
|
-
recomputedHash?: undefined;
|
|
248
|
-
valid?: undefined;
|
|
249
|
-
} | {
|
|
250
|
-
ok: true;
|
|
251
|
-
envelopeId: string;
|
|
252
|
-
documentName: string;
|
|
253
|
-
complete: boolean;
|
|
254
|
-
signedAt: string | null;
|
|
255
|
-
sealedHash: string | null;
|
|
256
|
-
recomputedHash: string | null;
|
|
257
|
-
valid: boolean;
|
|
258
|
-
parties: {
|
|
259
|
-
role: string;
|
|
260
|
-
name: string;
|
|
261
|
-
signedAt: string | null;
|
|
262
|
-
}[];
|
|
263
|
-
}, {
|
|
264
|
-
parties?: undefined;
|
|
265
|
-
signedAt?: undefined;
|
|
266
|
-
ok: false;
|
|
267
|
-
envelopeId?: undefined;
|
|
268
|
-
documentName?: undefined;
|
|
269
|
-
complete?: undefined;
|
|
270
|
-
sealedHash?: undefined;
|
|
271
|
-
recomputedHash?: undefined;
|
|
272
|
-
valid?: undefined;
|
|
273
|
-
} | {
|
|
274
|
-
ok: true;
|
|
275
|
-
envelopeId: string;
|
|
276
|
-
documentName: string;
|
|
277
|
-
complete: boolean;
|
|
278
|
-
signedAt: string | null;
|
|
279
|
-
sealedHash: string | null;
|
|
280
|
-
recomputedHash: string | null;
|
|
281
|
-
valid: boolean;
|
|
282
|
-
parties: {
|
|
283
|
-
role: string;
|
|
284
|
-
name: string;
|
|
285
|
-
signedAt: string | null;
|
|
286
|
-
}[];
|
|
287
|
-
}>, Record<never, never>, Record<never, never>>;
|
|
288
|
-
};
|
|
289
|
-
export {};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @system service-boot
|
|
3
|
-
* @status handwritten
|
|
4
|
-
* @edit edit directly
|
|
5
|
-
*
|
|
6
|
-
* Public ORPC procedure for submitting a public assessment (quiz) response.
|
|
7
|
-
* Mirrors public-gpt-session-router: a public, system-trusted write path for an
|
|
8
|
-
* anonymous/guest visitor — find-or-create the contact in client_database, score
|
|
9
|
-
* the answers, and persist an assessment_responses row. This is the submit path
|
|
10
|
-
* the deleted public-assessment wrapper used to provide via an injected onSubmit;
|
|
11
|
-
* recovering it here brings the quiz in line with the shared machinery (the GPT's
|
|
12
|
-
* publicGptSession is the sibling pattern) instead of a per-page bespoke handler.
|
|
13
|
-
*
|
|
14
|
-
* Scoring (recovered from live data, 2026-06-13): each scale answer contributes
|
|
15
|
-
* (scaleValue - 1) earned out of 4 max (1–5 scale → 0–4); choice answers
|
|
16
|
-
* contribute the selected option's points out of the question's max option
|
|
17
|
-
* points. A category's score is round(100 * earned / max) over that category's
|
|
18
|
-
* questions; the overall total is the same over all questions. Unanswered
|
|
19
|
-
* questions count toward the denominator (contribute 0) — matches the historical
|
|
20
|
-
* rows (e.g. Σ(v-1)=78 over 36 questions → 78/144 = 54).
|
|
21
|
-
*/
|
|
22
|
-
import * as v from "valibot";
|
|
23
|
-
interface Context {
|
|
24
|
-
prisma: any;
|
|
25
|
-
headers: Headers;
|
|
26
|
-
resolveUser?: (headers: Headers, prisma: any) => Promise<any>;
|
|
27
|
-
}
|
|
28
|
-
export declare const publicAssessmentRouter: {
|
|
29
|
-
submit: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
30
|
-
readonly assessmentId: v.StringSchema<undefined>;
|
|
31
|
-
readonly firstName: v.StringSchema<undefined>;
|
|
32
|
-
readonly email: v.StringSchema<undefined>;
|
|
33
|
-
readonly company: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
34
|
-
readonly phone: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
35
|
-
readonly website: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
36
|
-
readonly industry: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
37
|
-
readonly teamSize: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
38
|
-
readonly revenueRange: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
39
|
-
readonly answers: v.ArraySchema<v.ObjectSchema<{
|
|
40
|
-
readonly questionId: v.StringSchema<undefined>;
|
|
41
|
-
readonly scaleValue: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
42
|
-
readonly textValue: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
43
|
-
readonly choiceValue: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
44
|
-
readonly choiceValues: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
45
|
-
}, undefined>, undefined>;
|
|
46
|
-
}, undefined>, import("@orpc/contract").Schema<{
|
|
47
|
-
readonly error: "Assessment not found";
|
|
48
|
-
} | {
|
|
49
|
-
error?: undefined;
|
|
50
|
-
success: true;
|
|
51
|
-
responseId: any;
|
|
52
|
-
reportUrl: string;
|
|
53
|
-
totalScore: number;
|
|
54
|
-
categoryScores: Record<string, number>;
|
|
55
|
-
band?: string | undefined;
|
|
56
|
-
}, {
|
|
57
|
-
readonly error: "Assessment not found";
|
|
58
|
-
} | {
|
|
59
|
-
error?: undefined;
|
|
60
|
-
success: true;
|
|
61
|
-
responseId: any;
|
|
62
|
-
reportUrl: string;
|
|
63
|
-
totalScore: number;
|
|
64
|
-
categoryScores: Record<string, number>;
|
|
65
|
-
band?: string | undefined;
|
|
66
|
-
}>, Record<never, never>, Record<never, never>>;
|
|
67
|
-
};
|
|
68
|
-
export {};
|