@teamscala/service-boot 0.23.284 → 0.23.286
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 +1006 -1014
- 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/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/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/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/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 +281 -0
- package/src/fn-routers/public-assessment-router.d.ts +68 -0
- package/src/fn-routers/public-gpt-session-router.d.ts +125 -0
- package/src/fn-routers/sign-in-flow-router.d.ts +75 -0
- package/src/fn-routers/task-sync-dispatch.d.ts +61 -0
- package/src/fn-routers/task-sync-router.d.ts +376 -0
- package/src/fn-routers/task-sync-router.test.ts +32 -0
- package/src/fn-routers/task-sync-router.ts +27 -1
- 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/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/scheduled-browser-tests.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/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-server-packages.d.ts +29 -0
- package/src/mount.d.ts +9 -0
- package/src/mutable-app-ref.d.ts +38 -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 +25 -0
- package/src/pg-boss-mount.d.ts +39 -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-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-from-loader-config.d.ts +32 -0
- package/src/resolve-service-context.d.ts +17 -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/server-error-page.d.ts +29 -0
- package/src/start-scheduled-jobs.d.ts +18 -0
- package/src/two-phase-boot.d.ts +93 -0
- package/src/two-phase-boot.ts +3 -0
- package/src/types.d.ts +46 -0
- package/src/ui-service.d.ts +46 -0
- package/src/ui-service.ts +10 -1
- package/src/ws-boot-self-test.d.ts +19 -0
|
@@ -0,0 +1,58 @@
|
|
|
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: any;
|
|
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: any;
|
|
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 {};
|
|
@@ -0,0 +1,281 @@
|
|
|
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: any;
|
|
118
|
+
signerName: any;
|
|
119
|
+
partySignedAt: any;
|
|
120
|
+
allSigned: any;
|
|
121
|
+
parties: any;
|
|
122
|
+
accessToken: any;
|
|
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: any;
|
|
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: any;
|
|
151
|
+
signerName: any;
|
|
152
|
+
partySignedAt: any;
|
|
153
|
+
allSigned: any;
|
|
154
|
+
parties: any;
|
|
155
|
+
accessToken: any;
|
|
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: any;
|
|
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: any;
|
|
186
|
+
signedAt: any;
|
|
187
|
+
allSigned: any;
|
|
188
|
+
parties: any;
|
|
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: any;
|
|
214
|
+
signedAt: any;
|
|
215
|
+
allSigned: any;
|
|
216
|
+
parties: any;
|
|
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: any;
|
|
252
|
+
documentName: any;
|
|
253
|
+
complete: any;
|
|
254
|
+
signedAt: any;
|
|
255
|
+
sealedHash: string | null;
|
|
256
|
+
recomputedHash: string | null;
|
|
257
|
+
valid: boolean;
|
|
258
|
+
parties: any;
|
|
259
|
+
}, {
|
|
260
|
+
parties?: undefined;
|
|
261
|
+
signedAt?: undefined;
|
|
262
|
+
ok: false;
|
|
263
|
+
envelopeId?: undefined;
|
|
264
|
+
documentName?: undefined;
|
|
265
|
+
complete?: undefined;
|
|
266
|
+
sealedHash?: undefined;
|
|
267
|
+
recomputedHash?: undefined;
|
|
268
|
+
valid?: undefined;
|
|
269
|
+
} | {
|
|
270
|
+
ok: true;
|
|
271
|
+
envelopeId: any;
|
|
272
|
+
documentName: any;
|
|
273
|
+
complete: any;
|
|
274
|
+
signedAt: any;
|
|
275
|
+
sealedHash: string | null;
|
|
276
|
+
recomputedHash: string | null;
|
|
277
|
+
valid: boolean;
|
|
278
|
+
parties: any;
|
|
279
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
280
|
+
};
|
|
281
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
readonly 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
|
+
readonly 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 {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* ORPC procedures for public GPT session management.
|
|
7
|
+
* Creates/restores conversations and messages for public-facing GPT pages.
|
|
8
|
+
*/
|
|
9
|
+
import * as v from "valibot";
|
|
10
|
+
interface Context {
|
|
11
|
+
prisma: any;
|
|
12
|
+
headers: Headers;
|
|
13
|
+
resolveUser?: (headers: Headers, prisma: any) => Promise<any>;
|
|
14
|
+
}
|
|
15
|
+
export declare const publicGptSessionRouter: {
|
|
16
|
+
createOrRestore: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
17
|
+
readonly contactName: v.StringSchema<undefined>;
|
|
18
|
+
readonly email: v.StringSchema<undefined>;
|
|
19
|
+
readonly phone: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
20
|
+
readonly gptId: v.StringSchema<undefined>;
|
|
21
|
+
readonly orgId: v.StringSchema<undefined>;
|
|
22
|
+
readonly sourceUrl: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
23
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
24
|
+
conversationId: any;
|
|
25
|
+
contactName: any;
|
|
26
|
+
contactPhone: any;
|
|
27
|
+
messages: any;
|
|
28
|
+
tokenTotals: {
|
|
29
|
+
inputTokens: number;
|
|
30
|
+
outputTokens: number;
|
|
31
|
+
};
|
|
32
|
+
}, {
|
|
33
|
+
conversationId: any;
|
|
34
|
+
contactName: any;
|
|
35
|
+
contactPhone: any;
|
|
36
|
+
messages: any;
|
|
37
|
+
tokenTotals: {
|
|
38
|
+
inputTokens: number;
|
|
39
|
+
outputTokens: number;
|
|
40
|
+
};
|
|
41
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
42
|
+
load: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
43
|
+
readonly conversationId: v.StringSchema<undefined>;
|
|
44
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
45
|
+
conversationId: any;
|
|
46
|
+
contactName: string;
|
|
47
|
+
contactEmail: string;
|
|
48
|
+
messages: any;
|
|
49
|
+
tokenTotals: {
|
|
50
|
+
inputTokens: number;
|
|
51
|
+
outputTokens: number;
|
|
52
|
+
};
|
|
53
|
+
} | null, {
|
|
54
|
+
conversationId: any;
|
|
55
|
+
contactName: string;
|
|
56
|
+
contactEmail: string;
|
|
57
|
+
messages: any;
|
|
58
|
+
tokenTotals: {
|
|
59
|
+
inputTokens: number;
|
|
60
|
+
outputTokens: number;
|
|
61
|
+
};
|
|
62
|
+
} | null>, Record<never, never>, Record<never, never>>;
|
|
63
|
+
saveMessages: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
64
|
+
readonly conversationId: v.StringSchema<undefined>;
|
|
65
|
+
readonly messages: v.ArraySchema<v.ObjectSchema<{
|
|
66
|
+
readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
67
|
+
readonly role: v.StringSchema<undefined>;
|
|
68
|
+
readonly content: v.StringSchema<undefined>;
|
|
69
|
+
readonly parts: v.OptionalSchema<v.ArraySchema<v.AnySchema, undefined>, undefined>;
|
|
70
|
+
readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>, undefined>;
|
|
71
|
+
}, undefined>, undefined>;
|
|
72
|
+
}, undefined>, import("@orpc/contract").Schema<void, void>, Record<never, never>, Record<never, never>>;
|
|
73
|
+
clear: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
74
|
+
readonly conversationId: v.StringSchema<undefined>;
|
|
75
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
76
|
+
conversationId: any;
|
|
77
|
+
contactName: string;
|
|
78
|
+
contactPhone: string | undefined;
|
|
79
|
+
messages: Array<{
|
|
80
|
+
role: string;
|
|
81
|
+
content: string;
|
|
82
|
+
parts?: unknown[];
|
|
83
|
+
}>;
|
|
84
|
+
tokenTotals: {
|
|
85
|
+
inputTokens: number;
|
|
86
|
+
outputTokens: number;
|
|
87
|
+
};
|
|
88
|
+
}, {
|
|
89
|
+
conversationId: any;
|
|
90
|
+
contactName: string;
|
|
91
|
+
contactPhone: string | undefined;
|
|
92
|
+
messages: Array<{
|
|
93
|
+
role: string;
|
|
94
|
+
content: string;
|
|
95
|
+
parts?: unknown[];
|
|
96
|
+
}>;
|
|
97
|
+
tokenTotals: {
|
|
98
|
+
inputTokens: number;
|
|
99
|
+
outputTokens: number;
|
|
100
|
+
};
|
|
101
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
102
|
+
checkIdentity: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
103
|
+
readonly email: v.StringSchema<undefined>;
|
|
104
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
105
|
+
isPlatformUser: boolean;
|
|
106
|
+
}, {
|
|
107
|
+
isPlatformUser: boolean;
|
|
108
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
109
|
+
upload: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, v.ObjectSchema<{
|
|
110
|
+
readonly conversationId: v.StringSchema<undefined>;
|
|
111
|
+
readonly fileData: v.StringSchema<undefined>;
|
|
112
|
+
readonly fileName: v.StringSchema<undefined>;
|
|
113
|
+
readonly fileType: v.StringSchema<undefined>;
|
|
114
|
+
readonly fileSize: v.NumberSchema<undefined>;
|
|
115
|
+
}, undefined>, import("@orpc/contract").Schema<{
|
|
116
|
+
success: true;
|
|
117
|
+
url: string;
|
|
118
|
+
type: string;
|
|
119
|
+
}, {
|
|
120
|
+
success: true;
|
|
121
|
+
url: string;
|
|
122
|
+
type: string;
|
|
123
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
124
|
+
};
|
|
125
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* `fn.signInFlow` — typed ORPC procedures for the sign-in flow's client-facing
|
|
7
|
+
* reads (flow config, session check, portal list). Replaces the former
|
|
8
|
+
* `/api/data/{sign-in-flow-config,check-session,portals}` HANDLER_MAP entries
|
|
9
|
+
* from the deleted register-data-routes.ts (orpc-is-the-only-api: every API surface is a
|
|
10
|
+
* typed ORPC procedure, never a hand-written Hono route). Logic ported
|
|
11
|
+
* verbatim from those handlers — these are anonymous-allowed reads (they
|
|
12
|
+
* return an empty result for an unauthenticated caller, never throw), so they
|
|
13
|
+
* use a public base procedure reading `context.headers` for the session, NOT
|
|
14
|
+
* the `authed` middleware (which throws UNAUTHORIZED).
|
|
15
|
+
*
|
|
16
|
+
* EXPAND phase: this router is ADDITIVE — registered into the `fn` namespace
|
|
17
|
+
* but not yet retargeted by @teamscala/auth's use-sign-in-flow client (which
|
|
18
|
+
* still hits the /api/data/* routes). The HANDLER_MAP entries stay until the
|
|
19
|
+
* client retarget + round-trip verify land (post-incident, when the auth-flow
|
|
20
|
+
* test harness can run), then are removed (CONTRACT).
|
|
21
|
+
*/
|
|
22
|
+
import type { Context } from "./auth-router.ts";
|
|
23
|
+
export declare const signInFlowRouter: {
|
|
24
|
+
getSignInFlowConfig: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, import("@orpc/contract").Schema<unknown, unknown>, import("@orpc/contract").Schema<any, any>, Record<never, never>, Record<never, never>>;
|
|
25
|
+
checkSession: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, import("@orpc/contract").Schema<unknown, unknown>, import("@orpc/contract").Schema<{
|
|
26
|
+
user?: undefined;
|
|
27
|
+
redirectUrl?: undefined;
|
|
28
|
+
portalCount?: undefined;
|
|
29
|
+
} | {
|
|
30
|
+
user: any;
|
|
31
|
+
redirectUrl: any;
|
|
32
|
+
portalCount: number;
|
|
33
|
+
}, {
|
|
34
|
+
user?: undefined;
|
|
35
|
+
redirectUrl?: undefined;
|
|
36
|
+
portalCount?: undefined;
|
|
37
|
+
} | {
|
|
38
|
+
user: any;
|
|
39
|
+
redirectUrl: any;
|
|
40
|
+
portalCount: number;
|
|
41
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
42
|
+
listPortals: import("@orpc/server").DecoratedProcedure<Context & Record<never, never>, Context, import("@orpc/contract").Schema<unknown, unknown>, import("@orpc/contract").Schema<{
|
|
43
|
+
portals: never[];
|
|
44
|
+
userOrgId: null;
|
|
45
|
+
userName: any;
|
|
46
|
+
} | {
|
|
47
|
+
portals: {
|
|
48
|
+
id: unknown;
|
|
49
|
+
name: {};
|
|
50
|
+
slug: {} | null;
|
|
51
|
+
status: {} | null;
|
|
52
|
+
website_type: {} | null;
|
|
53
|
+
organisation_id: {} | null;
|
|
54
|
+
portal_type: {} | null;
|
|
55
|
+
}[];
|
|
56
|
+
userOrgId: string;
|
|
57
|
+
userName: any;
|
|
58
|
+
}, {
|
|
59
|
+
portals: never[];
|
|
60
|
+
userOrgId: null;
|
|
61
|
+
userName: any;
|
|
62
|
+
} | {
|
|
63
|
+
portals: {
|
|
64
|
+
id: unknown;
|
|
65
|
+
name: {};
|
|
66
|
+
slug: {} | null;
|
|
67
|
+
status: {} | null;
|
|
68
|
+
website_type: {} | null;
|
|
69
|
+
organisation_id: {} | null;
|
|
70
|
+
portal_type: {} | null;
|
|
71
|
+
}[];
|
|
72
|
+
userOrgId: string;
|
|
73
|
+
userName: any;
|
|
74
|
+
}>, Record<never, never>, Record<never, never>>;
|
|
75
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @system service-boot
|
|
3
|
+
* @status handwritten
|
|
4
|
+
* @edit edit directly
|
|
5
|
+
*
|
|
6
|
+
* DB→AGENT dispatch for task-sync — notifies a lane's live pane that its
|
|
7
|
+
* work_items task list changed out-of-band (operator toggled a subtask in the
|
|
8
|
+
* projects UI, another lane edited a shared task). The pane's adapter then
|
|
9
|
+
* re-reads (fn.taskSync.readTaskList) and updates its native list.
|
|
10
|
+
*
|
|
11
|
+
* MECHANISM — reuses the existing CLI-agnostic channel delivery, no new
|
|
12
|
+
* transport: a POST to scala-channel's fleet-events publish entry
|
|
13
|
+
* (POST /api/fleet/events — @teamscala/channel/fleet-events-publish) carrying an
|
|
14
|
+
* `orchestrator.message` FleetEvent with slotName "cross-pane". That slot is
|
|
15
|
+
* the watchEvents bypass for events NOT tied to a fleet_agent_runs row
|
|
16
|
+
* (FleetEventOrchestratorMessageSchema comment) — exactly the system-originated
|
|
17
|
+
* case. scala-channel re-emits onto its eventBus and streamFleetEvents delivers
|
|
18
|
+
* to the subscriber filtered by orchestratorSessionId (the target lane pane).
|
|
19
|
+
* Both the Claude Code relay and the OpenCode scala-hooks plugin subscribe to
|
|
20
|
+
* that SSE stream for their own pane identity and inject each event natively —
|
|
21
|
+
* so ONE publish reaches every CLI that has a live projection, no per-CLI
|
|
22
|
+
* dispatch code here.
|
|
23
|
+
*
|
|
24
|
+
* NOT the dispatch entry (POST /api/channel/send): that path requires a real
|
|
25
|
+
* sender pane identity (channel-sender-identity-validated anti-spoof) and so
|
|
26
|
+
* cannot carry a system-originated notification. The publish path is
|
|
27
|
+
* internal-trusted (localhost super-admin) and accepts a synthetic
|
|
28
|
+
* fromOrchestratorId — the correct path for a system→pane message.
|
|
29
|
+
*
|
|
30
|
+
* scala-channel's address is resolved from its service_routing row (local_port)
|
|
31
|
+
* — never hardcoded (service-ports-from-registry). Fire-and-forget: a dispatch
|
|
32
|
+
* failure (scala-channel down, port unresolvable) is logged and swallowed; it
|
|
33
|
+
* must never block the work_items write that triggered it, and the lane's
|
|
34
|
+
* SessionStart/UserPromptSubmit backstop picks up the change on its next turn
|
|
35
|
+
* regardless.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* The `orchestrator.message` FleetEvent payload that notifies a lane its task
|
|
39
|
+
* list changed. Pure (no I/O) so it is unit-testable; notifyLaneOfTaskChange
|
|
40
|
+
* posts it. slotName "cross-pane" is REQUIRED — it is the watchEvents bypass for
|
|
41
|
+
* events not tied to a fleet_agent_runs row. orchestratorSessionId is the TARGET
|
|
42
|
+
* lane pane (the SSE subscriber filter). The message is single-line (the
|
|
43
|
+
* <channel> tag renders it inline).
|
|
44
|
+
*/
|
|
45
|
+
export interface TaskChangedEvent {
|
|
46
|
+
type: "orchestrator.message";
|
|
47
|
+
message: string;
|
|
48
|
+
fromOrchestratorId: string;
|
|
49
|
+
runId: string;
|
|
50
|
+
slotName: "cross-pane";
|
|
51
|
+
ts: number;
|
|
52
|
+
orchestratorSessionId: string;
|
|
53
|
+
}
|
|
54
|
+
export declare function buildTaskChangedEvent(lanePane: string, taskId: string, now?: number): TaskChangedEvent;
|
|
55
|
+
/**
|
|
56
|
+
* Publish a "your task list changed" notification to the owning lane's pane.
|
|
57
|
+
* The pane identity is the stable tmux id ("tmux:%42") every CLI relay/plugin
|
|
58
|
+
* receives for. `taskId` is carried in the message so the recipient can re-read
|
|
59
|
+
* just that task. Fire-and-forget.
|
|
60
|
+
*/
|
|
61
|
+
export declare function notifyLaneOfTaskChange(lanePane: string, taskId: string): Promise<void>;
|