@lucern/mcp 0.3.0-alpha.12 → 0.3.0-alpha.14
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/dist/cli.js +381 -53
- package/dist/cli.js.map +1 -1
- package/dist/gateway.d.ts +14 -1
- package/dist/gateway.js +1524 -275
- package/dist/gateway.js.map +1 -1
- package/dist/hosted-route.js +381 -53
- package/dist/hosted-route.js.map +1 -1
- package/dist/index.js +381 -53
- package/dist/index.js.map +1 -1
- package/dist/runtime.js +122 -4
- package/dist/runtime.js.map +1 -1
- package/package.json +7 -6
package/dist/gateway.js
CHANGED
|
@@ -4,6 +4,7 @@ import { basename, extname } from 'path';
|
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
5
5
|
import { anyApi } from 'convex/server';
|
|
6
6
|
import { ConvexHttpClient } from 'convex/browser';
|
|
7
|
+
import { Permit } from 'permitio';
|
|
7
8
|
|
|
8
9
|
// ../contracts/src/types/reasoning-method.ts
|
|
9
10
|
var REASONING_METHODS = [
|
|
@@ -1032,6 +1033,35 @@ defineTable({
|
|
|
1032
1033
|
{ kind: "index", name: "by_source", columns: ["source"] }
|
|
1033
1034
|
]
|
|
1034
1035
|
});
|
|
1036
|
+
defineTable({
|
|
1037
|
+
name: "domainEvents",
|
|
1038
|
+
component: "kernel",
|
|
1039
|
+
category: "events",
|
|
1040
|
+
shape: z.object({
|
|
1041
|
+
"eventId": z.string(),
|
|
1042
|
+
"type": z.string(),
|
|
1043
|
+
"version": z.string(),
|
|
1044
|
+
"timestamp": z.number(),
|
|
1045
|
+
"tenantId": z.string().optional(),
|
|
1046
|
+
"workspaceId": z.string().optional(),
|
|
1047
|
+
"topicId": z.string(),
|
|
1048
|
+
"resourceId": z.string(),
|
|
1049
|
+
"resourceType": z.string(),
|
|
1050
|
+
"actorId": z.string(),
|
|
1051
|
+
"actorType": z.enum(["human", "agent", "service"]),
|
|
1052
|
+
"data": z.record(z.any()),
|
|
1053
|
+
"correlationId": z.string().optional(),
|
|
1054
|
+
"expiresAt": z.number()
|
|
1055
|
+
}),
|
|
1056
|
+
indices: [
|
|
1057
|
+
{ kind: "index", name: "by_eventId", columns: ["eventId"] },
|
|
1058
|
+
{ kind: "index", name: "by_topic_timestamp", columns: ["topicId", "timestamp"] },
|
|
1059
|
+
{ kind: "index", name: "by_tenant_workspace_timestamp", columns: ["tenantId", "workspaceId", "timestamp"] },
|
|
1060
|
+
{ kind: "index", name: "by_type_timestamp", columns: ["type", "timestamp"] },
|
|
1061
|
+
{ kind: "index", name: "by_resource", columns: ["resourceType", "resourceId", "timestamp"] },
|
|
1062
|
+
{ kind: "index", name: "by_expiresAt", columns: ["expiresAt"] }
|
|
1063
|
+
]
|
|
1064
|
+
});
|
|
1035
1065
|
defineTable({
|
|
1036
1066
|
name: "beliefConfidence",
|
|
1037
1067
|
component: "kernel",
|
|
@@ -4438,7 +4468,10 @@ defineTable({
|
|
|
4438
4468
|
}),
|
|
4439
4469
|
indices: [
|
|
4440
4470
|
{ kind: "index", name: "by_principalId", columns: ["principalId"] },
|
|
4471
|
+
{ kind: "index", name: "by_provider_subject", columns: ["provider", "providerSubjectId"] },
|
|
4472
|
+
{ kind: "index", name: "by_provider_project_subject", columns: ["provider", "providerProjectId", "providerSubjectId"] },
|
|
4441
4473
|
{ kind: "index", name: "by_tenant_provider_subject", columns: ["tenantId", "provider", "providerSubjectId"] },
|
|
4474
|
+
{ kind: "index", name: "by_tenant_provider_project_subject", columns: ["tenantId", "provider", "providerProjectId", "providerSubjectId"] },
|
|
4442
4475
|
{
|
|
4443
4476
|
kind: "index",
|
|
4444
4477
|
name: "by_tenant_provider_alias",
|
|
@@ -9411,7 +9444,7 @@ var IDENTITY_WHOAMI = {
|
|
|
9411
9444
|
description: "Canonical identity summary for the current session",
|
|
9412
9445
|
fields: {
|
|
9413
9446
|
principalId: "string \u2014 canonical federated principal identifier",
|
|
9414
|
-
principalType: "string \u2014 human, service, or
|
|
9447
|
+
principalType: "string \u2014 human, service, agent, group, or external_viewer",
|
|
9415
9448
|
tenantId: "string | undefined \u2014 resolved tenant scope",
|
|
9416
9449
|
workspaceId: "string | undefined \u2014 resolved workspace scope",
|
|
9417
9450
|
scopes: "string[] | undefined \u2014 granted scopes for this session",
|
|
@@ -9422,6 +9455,49 @@ var IDENTITY_WHOAMI = {
|
|
|
9422
9455
|
ontologyPrimitive: "identity",
|
|
9423
9456
|
tier: "workhorse"
|
|
9424
9457
|
};
|
|
9458
|
+
var RESOLVE_INTERACTIVE_PRINCIPAL = {
|
|
9459
|
+
name: "resolve_interactive_principal",
|
|
9460
|
+
description: "Read the Permit-backed Lucern principal context for an authenticated Clerk user. Like `git config --get user.email` plus the repository ACL \u2014 resolves the identity alias into the canonical authorization subject.",
|
|
9461
|
+
parameters: {
|
|
9462
|
+
clerkId: {
|
|
9463
|
+
type: "string",
|
|
9464
|
+
description: "Authenticated Clerk subject (`sub`). Clerk proves identity only; it is not the authorization record."
|
|
9465
|
+
},
|
|
9466
|
+
tenantId: {
|
|
9467
|
+
type: "string",
|
|
9468
|
+
description: "Optional tenant scope. Omit only when the Clerk alias is globally unambiguous."
|
|
9469
|
+
},
|
|
9470
|
+
workspaceId: {
|
|
9471
|
+
type: "string",
|
|
9472
|
+
description: "Optional workspace scope. Required when the principal has access to multiple workspaces and no default can be inferred."
|
|
9473
|
+
},
|
|
9474
|
+
providerProjectId: {
|
|
9475
|
+
type: "string",
|
|
9476
|
+
description: "Optional Clerk project or provider instance id for tenants with multiple identity providers."
|
|
9477
|
+
}
|
|
9478
|
+
},
|
|
9479
|
+
required: ["clerkId"],
|
|
9480
|
+
response: {
|
|
9481
|
+
description: "Permit-backed Lucern principal context for tenant SDK bootstrap",
|
|
9482
|
+
fields: {
|
|
9483
|
+
principalId: "string \u2014 canonical Lucern principal identifier",
|
|
9484
|
+
principalType: "string \u2014 human, service, agent, group, or external_viewer",
|
|
9485
|
+
clerkId: "string \u2014 authenticated Clerk subject alias",
|
|
9486
|
+
tenantId: "string \u2014 resolved tenant scope",
|
|
9487
|
+
workspaceId: "string | null \u2014 resolved workspace scope",
|
|
9488
|
+
roles: "string[] \u2014 effective Permit roles",
|
|
9489
|
+
scopes: "string[] \u2014 effective scopes derived from Permit/control-plane projection",
|
|
9490
|
+
groupIds: "string[] \u2014 active Permit group memberships",
|
|
9491
|
+
principalStatus: "string \u2014 active, invited, suspended, disabled, revoked, or missing",
|
|
9492
|
+
tenantStatus: "string \u2014 projected tenant resource status",
|
|
9493
|
+
workspaceStatus: "string \u2014 projected workspace resource status",
|
|
9494
|
+
permit: "object \u2014 Permit subject, tenant, and optional workspace tuple"
|
|
9495
|
+
}
|
|
9496
|
+
},
|
|
9497
|
+
ownerModule: "control-plane",
|
|
9498
|
+
ontologyPrimitive: "identity",
|
|
9499
|
+
tier: "workhorse"
|
|
9500
|
+
};
|
|
9425
9501
|
var COMPILE_CONTEXT = {
|
|
9426
9502
|
name: "compile_context",
|
|
9427
9503
|
description: "Compile a focused reasoning context. If topicId is omitted, Lucern resolves the best topic from the query. Like `git log --graph --decorate` for the reasoning substrate \u2014 returns the canonical Pillar 3 context pack through the public API shape.",
|
|
@@ -11324,6 +11400,7 @@ var MCP_TOOL_CONTRACTS = {
|
|
|
11324
11400
|
update_worktree_targets: UPDATE_WORKTREE_TARGETS,
|
|
11325
11401
|
update_worktree_metadata: UPDATE_WORKTREE_METADATA,
|
|
11326
11402
|
identity_whoami: IDENTITY_WHOAMI,
|
|
11403
|
+
resolve_interactive_principal: RESOLVE_INTERACTIVE_PRINCIPAL,
|
|
11327
11404
|
compile_context: COMPILE_CONTEXT,
|
|
11328
11405
|
record_scope_learning: RECORD_SCOPE_LEARNING,
|
|
11329
11406
|
pipeline_snapshot: PIPELINE_SNAPSHOT,
|
|
@@ -11441,6 +11518,7 @@ function entries(names, surfaceClass, surfaceIntent, surfaces, rationale) {
|
|
|
11441
11518
|
var MCP_CORE_OPERATION_NAMES = [
|
|
11442
11519
|
"compile_context",
|
|
11443
11520
|
"identity_whoami",
|
|
11521
|
+
"resolve_interactive_principal",
|
|
11444
11522
|
"check_permission",
|
|
11445
11523
|
"filter_by_permission",
|
|
11446
11524
|
"create_belief",
|
|
@@ -11994,7 +12072,13 @@ function surfaceContract(args) {
|
|
|
11994
12072
|
scopes: args.scopes ?? [
|
|
11995
12073
|
args.kind === "query" ? `${args.domain}.read` : `${args.domain}.write`
|
|
11996
12074
|
],
|
|
11997
|
-
allowedPrincipalTypes: [
|
|
12075
|
+
allowedPrincipalTypes: [
|
|
12076
|
+
"user",
|
|
12077
|
+
"service",
|
|
12078
|
+
"agent",
|
|
12079
|
+
"group",
|
|
12080
|
+
"external_viewer"
|
|
12081
|
+
]
|
|
11998
12082
|
},
|
|
11999
12083
|
convex: args.convex,
|
|
12000
12084
|
gateway: args.gateway,
|
|
@@ -12136,8 +12220,6 @@ var contextContracts = [
|
|
|
12136
12220
|
args: observationContextArgs
|
|
12137
12221
|
})
|
|
12138
12222
|
];
|
|
12139
|
-
|
|
12140
|
-
// ../contracts/src/function-registry/identity.ts
|
|
12141
12223
|
var withPrincipal = (input, context) => ({
|
|
12142
12224
|
...input,
|
|
12143
12225
|
tenantId: input.tenantId ?? context.tenantId,
|
|
@@ -12163,6 +12245,28 @@ var identityContracts = [
|
|
|
12163
12245
|
inputProjection: withPrincipal
|
|
12164
12246
|
}
|
|
12165
12247
|
}),
|
|
12248
|
+
surfaceContract({
|
|
12249
|
+
name: "resolve_interactive_principal",
|
|
12250
|
+
kind: "query",
|
|
12251
|
+
domain: "controlPlane",
|
|
12252
|
+
surfaceClass: "platform_public",
|
|
12253
|
+
method: "POST",
|
|
12254
|
+
path: "/control-plane/identity/resolve-interactive-principal",
|
|
12255
|
+
sdkNamespace: "controlPlane.identity",
|
|
12256
|
+
sdkMethod: "resolveInteractivePrincipal",
|
|
12257
|
+
summary: "Resolve an authenticated Clerk user into a Permit-backed Lucern principal context.",
|
|
12258
|
+
args: z.object({
|
|
12259
|
+
clerkId: z.string().min(1),
|
|
12260
|
+
tenantId: z.string().min(1).optional(),
|
|
12261
|
+
workspaceId: z.string().min(1).optional(),
|
|
12262
|
+
providerProjectId: z.string().min(1).optional()
|
|
12263
|
+
}),
|
|
12264
|
+
convex: {
|
|
12265
|
+
module: "identity",
|
|
12266
|
+
functionName: "resolveInteractivePrincipal",
|
|
12267
|
+
kind: "query"
|
|
12268
|
+
}
|
|
12269
|
+
}),
|
|
12166
12270
|
surfaceContract({
|
|
12167
12271
|
name: "check_permission",
|
|
12168
12272
|
kind: "query",
|
|
@@ -16255,6 +16359,13 @@ var TENANT_BOOTSTRAP_TABLE_REQUIREMENTS = [
|
|
|
16255
16359
|
copyMode: "none",
|
|
16256
16360
|
description: "Deliberation sessions are created by tenant workflows."
|
|
16257
16361
|
},
|
|
16362
|
+
{
|
|
16363
|
+
component: "kernel",
|
|
16364
|
+
table: "domainEvents",
|
|
16365
|
+
prepopulation: "runtime_log",
|
|
16366
|
+
copyMode: "none",
|
|
16367
|
+
description: "Domain event rows are append-only runtime audit/exhaust data."
|
|
16368
|
+
},
|
|
16258
16369
|
{
|
|
16259
16370
|
component: "kernel",
|
|
16260
16371
|
table: "epistemicAudit",
|
|
@@ -23084,23 +23195,31 @@ async function resolveTaskEventTopicId(authContext, task, operation) {
|
|
|
23084
23195
|
});
|
|
23085
23196
|
}
|
|
23086
23197
|
async function emitTaskEventFromGatewayAuth(authContext, args) {
|
|
23087
|
-
return
|
|
23088
|
-
|
|
23089
|
-
|
|
23090
|
-
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
23094
|
-
|
|
23095
|
-
|
|
23096
|
-
|
|
23097
|
-
|
|
23098
|
-
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23198
|
+
return authContext.convex.mutation(api.events.recordEvent, {
|
|
23199
|
+
tenantId: authContext.tenantId,
|
|
23200
|
+
workspaceId: authContext.workspaceId,
|
|
23201
|
+
topicId: args.topicId,
|
|
23202
|
+
type: args.type,
|
|
23203
|
+
resourceId: args.resourceId,
|
|
23204
|
+
resourceType: "task",
|
|
23205
|
+
actorId: authContext.principalId ?? authContext.userId,
|
|
23206
|
+
actorType: inferActorType({
|
|
23207
|
+
authMode: authContext.authMode,
|
|
23208
|
+
principalType: authContext.principalType
|
|
23209
|
+
}),
|
|
23210
|
+
data: args.data
|
|
23211
|
+
});
|
|
23212
|
+
}
|
|
23213
|
+
async function emitTaskEventBestEffortFromGatewayAuth(authContext, args) {
|
|
23214
|
+
try {
|
|
23215
|
+
await emitTaskEventFromGatewayAuth(authContext, args);
|
|
23216
|
+
} catch (error) {
|
|
23217
|
+
console.warn("[tasks] Task write succeeded but event emission failed.", {
|
|
23218
|
+
taskId: args.resourceId,
|
|
23219
|
+
eventType: args.type,
|
|
23220
|
+
error: error instanceof Error ? error.message : String(error)
|
|
23221
|
+
});
|
|
23222
|
+
}
|
|
23104
23223
|
}
|
|
23105
23224
|
function gatewayIdempotencyArgs(authContext, options) {
|
|
23106
23225
|
{
|
|
@@ -23197,7 +23316,7 @@ async function createTaskFromGatewayAuth(authContext, input, options) {
|
|
|
23197
23316
|
...input,
|
|
23198
23317
|
topicId: resolvedTopic.topicId
|
|
23199
23318
|
});
|
|
23200
|
-
await
|
|
23319
|
+
await emitTaskEventBestEffortFromGatewayAuth(authContext, {
|
|
23201
23320
|
topicId: payload.topicId ?? resolvedTopic.topicId,
|
|
23202
23321
|
type: "task.created",
|
|
23203
23322
|
resourceId: payload.id,
|
|
@@ -23225,7 +23344,7 @@ async function updateTaskFromGatewayAuth(authContext, input, options) {
|
|
|
23225
23344
|
payload,
|
|
23226
23345
|
"update"
|
|
23227
23346
|
);
|
|
23228
|
-
await
|
|
23347
|
+
await emitTaskEventBestEffortFromGatewayAuth(authContext, {
|
|
23229
23348
|
topicId,
|
|
23230
23349
|
type: "task.updated",
|
|
23231
23350
|
resourceId: payload.id,
|
|
@@ -23252,7 +23371,7 @@ async function completeTaskFromGatewayAuth(authContext, input, options) {
|
|
|
23252
23371
|
payload,
|
|
23253
23372
|
"complete"
|
|
23254
23373
|
);
|
|
23255
|
-
await
|
|
23374
|
+
await emitTaskEventBestEffortFromGatewayAuth(authContext, {
|
|
23256
23375
|
topicId,
|
|
23257
23376
|
type: "task.completed",
|
|
23258
23377
|
resourceId: payload.id,
|
|
@@ -25732,7 +25851,7 @@ function handleEventsError(error, fallbackMessage, correlationId, policyTraceId)
|
|
|
25732
25851
|
}
|
|
25733
25852
|
async function handleEventsList(args) {
|
|
25734
25853
|
try {
|
|
25735
|
-
const payload = await args.authContext.convex.query(
|
|
25854
|
+
const payload = await args.authContext.convex.query(api.events.listEvents, {
|
|
25736
25855
|
tenantId: args.authContext.tenantId,
|
|
25737
25856
|
workspaceId: args.authContext.workspaceId,
|
|
25738
25857
|
topicId: args.query.topicId,
|
|
@@ -25758,7 +25877,7 @@ async function handleEventsList(args) {
|
|
|
25758
25877
|
async function handleEventsReplay(args) {
|
|
25759
25878
|
try {
|
|
25760
25879
|
const payload = await args.authContext.convex.mutation(
|
|
25761
|
-
|
|
25880
|
+
api.events.replayEvents,
|
|
25762
25881
|
{
|
|
25763
25882
|
tenantId: args.authContext.tenantId,
|
|
25764
25883
|
workspaceId: args.authContext.workspaceId,
|
|
@@ -27077,22 +27196,69 @@ function readTenantKeyFromValue(value) {
|
|
|
27077
27196
|
const record = asRecord25(value);
|
|
27078
27197
|
return readString27(record.key) ?? readString27(record.tenant) ?? readString27(record.tenantKey) ?? readString27(record.tenant_id);
|
|
27079
27198
|
}
|
|
27199
|
+
function hasTenantIdentifier(value) {
|
|
27200
|
+
if (typeof value === "string" && value.trim()) {
|
|
27201
|
+
return true;
|
|
27202
|
+
}
|
|
27203
|
+
const record = asRecord25(value);
|
|
27204
|
+
return Boolean(
|
|
27205
|
+
readString27(record.key) ?? readString27(record.tenant) ?? readString27(record.tenantKey) ?? readString27(record.tenant_key) ?? readString27(record.tenant_id) ?? readString27(record.id)
|
|
27206
|
+
);
|
|
27207
|
+
}
|
|
27080
27208
|
function extractPermitWebhookTenantKeys(body) {
|
|
27081
27209
|
const record = asRecord25(body);
|
|
27082
27210
|
const candidates = [
|
|
27083
27211
|
record.tenant,
|
|
27084
27212
|
record.tenantKey,
|
|
27213
|
+
record.tenant_key,
|
|
27214
|
+
asRecord25(record.data).tenant,
|
|
27215
|
+
asRecord25(record.data).tenantKey,
|
|
27216
|
+
asRecord25(record.data).tenant_key,
|
|
27217
|
+
asRecord25(record.object).tenant,
|
|
27218
|
+
asRecord25(record.object).tenantKey,
|
|
27219
|
+
asRecord25(record.object).tenant_key,
|
|
27220
|
+
asRecord25(record.resource_instance).tenant,
|
|
27221
|
+
asRecord25(record.resource_instance).tenantKey,
|
|
27222
|
+
asRecord25(record.resource_instance).tenant_key,
|
|
27223
|
+
asRecord25(record.access_request_details).tenant,
|
|
27224
|
+
asRecord25(record.access_request_details).tenantKey,
|
|
27225
|
+
asRecord25(record.access_request_details).tenant_key,
|
|
27226
|
+
asRecord25(asRecord25(record.data).access_request_details).tenant,
|
|
27227
|
+
asRecord25(asRecord25(record.data).access_request_details).tenantKey,
|
|
27228
|
+
asRecord25(asRecord25(record.data).access_request_details).tenant_key
|
|
27229
|
+
];
|
|
27230
|
+
const tenantKeys = candidates.map(readTenantKeyFromValue).filter((entry) => Boolean(entry));
|
|
27231
|
+
return [...new Set(tenantKeys)];
|
|
27232
|
+
}
|
|
27233
|
+
function hasPermitWebhookTenantScope(body) {
|
|
27234
|
+
const record = asRecord25(body);
|
|
27235
|
+
const candidates = [
|
|
27236
|
+
record.tenant,
|
|
27237
|
+
record.tenantKey,
|
|
27238
|
+
record.tenant_key,
|
|
27085
27239
|
record.tenant_id,
|
|
27086
27240
|
asRecord25(record.data).tenant,
|
|
27087
27241
|
asRecord25(record.data).tenantKey,
|
|
27242
|
+
asRecord25(record.data).tenant_key,
|
|
27088
27243
|
asRecord25(record.data).tenant_id,
|
|
27089
27244
|
asRecord25(record.object).tenant,
|
|
27090
27245
|
asRecord25(record.object).tenantKey,
|
|
27246
|
+
asRecord25(record.object).tenant_key,
|
|
27091
27247
|
asRecord25(record.object).tenant_id,
|
|
27092
|
-
asRecord25(record.resource_instance).tenant
|
|
27248
|
+
asRecord25(record.resource_instance).tenant,
|
|
27249
|
+
asRecord25(record.resource_instance).tenantKey,
|
|
27250
|
+
asRecord25(record.resource_instance).tenant_key,
|
|
27251
|
+
asRecord25(record.resource_instance).tenant_id,
|
|
27252
|
+
asRecord25(record.access_request_details).tenant,
|
|
27253
|
+
asRecord25(record.access_request_details).tenantKey,
|
|
27254
|
+
asRecord25(record.access_request_details).tenant_key,
|
|
27255
|
+
asRecord25(record.access_request_details).tenant_id,
|
|
27256
|
+
asRecord25(asRecord25(record.data).access_request_details).tenant,
|
|
27257
|
+
asRecord25(asRecord25(record.data).access_request_details).tenantKey,
|
|
27258
|
+
asRecord25(asRecord25(record.data).access_request_details).tenant_key,
|
|
27259
|
+
asRecord25(asRecord25(record.data).access_request_details).tenant_id
|
|
27093
27260
|
];
|
|
27094
|
-
|
|
27095
|
-
return [...new Set(tenantKeys)];
|
|
27261
|
+
return candidates.some(hasTenantIdentifier);
|
|
27096
27262
|
}
|
|
27097
27263
|
function summarizePermitWebhookEvent(body) {
|
|
27098
27264
|
const record = asRecord25(body);
|
|
@@ -27160,7 +27326,8 @@ async function handlePermitProjectionWebhook(args) {
|
|
|
27160
27326
|
try {
|
|
27161
27327
|
const event = summarizePermitWebhookEvent(args.body);
|
|
27162
27328
|
const tenantKeys = extractPermitWebhookTenantKeys(args.body);
|
|
27163
|
-
|
|
27329
|
+
const hasTenantScope = hasPermitWebhookTenantScope(args.body);
|
|
27330
|
+
if (tenantKeys.length === 0 && !hasTenantScope) {
|
|
27164
27331
|
return successResponse(
|
|
27165
27332
|
{
|
|
27166
27333
|
acknowledged: true,
|
|
@@ -27178,7 +27345,7 @@ async function handlePermitProjectionWebhook(args) {
|
|
|
27178
27345
|
const receipt = await client.action(mcApi.permitProjectionActions.reconcile, {
|
|
27179
27346
|
mode: "apply",
|
|
27180
27347
|
trigger: "permit_webhook",
|
|
27181
|
-
tenantKeys,
|
|
27348
|
+
tenantKeys: tenantKeys.length > 0 ? tenantKeys : void 0,
|
|
27182
27349
|
environments: ["dev", "staging", "prod"],
|
|
27183
27350
|
componentPath: "controlPlane",
|
|
27184
27351
|
webhookSecret: readSecret(),
|
|
@@ -27202,37 +27369,1119 @@ async function handlePermitProjectionWebhook(args) {
|
|
|
27202
27369
|
);
|
|
27203
27370
|
}
|
|
27204
27371
|
}
|
|
27372
|
+
var mcApi2 = anyApi;
|
|
27373
|
+
var mcClientCache2 = {
|
|
27374
|
+
value: null
|
|
27375
|
+
};
|
|
27376
|
+
var permitClientCache = {
|
|
27377
|
+
value: null
|
|
27378
|
+
};
|
|
27379
|
+
var permitClientFactory = null;
|
|
27380
|
+
var SYSTEM_ACTOR_ID = "clerk:system";
|
|
27381
|
+
var SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
27382
|
+
var USER_EVENTS = /* @__PURE__ */ new Set([
|
|
27383
|
+
"user.created",
|
|
27384
|
+
"user.updated",
|
|
27385
|
+
"user.deleted"
|
|
27386
|
+
]);
|
|
27387
|
+
var MEMBERSHIP_EVENTS = /* @__PURE__ */ new Set([
|
|
27388
|
+
"organizationMembership.created",
|
|
27389
|
+
"organizationMembership.updated",
|
|
27390
|
+
"organizationMembership.deleted"
|
|
27391
|
+
]);
|
|
27392
|
+
var INVITATION_EVENTS = /* @__PURE__ */ new Set([
|
|
27393
|
+
"organizationInvitation.created",
|
|
27394
|
+
"organizationInvitation.accepted",
|
|
27395
|
+
"organizationInvitation.revoked"
|
|
27396
|
+
]);
|
|
27397
|
+
var ORGANIZATION_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
|
|
27398
|
+
"organization.created",
|
|
27399
|
+
"organization.updated",
|
|
27400
|
+
"organization.deleted"
|
|
27401
|
+
]);
|
|
27402
|
+
var PERMIT_MEMBERSHIP_ROLES = /* @__PURE__ */ new Set([
|
|
27403
|
+
"tenant_admin",
|
|
27404
|
+
"viewer",
|
|
27405
|
+
"editor",
|
|
27406
|
+
"auditor",
|
|
27407
|
+
"service_agent",
|
|
27408
|
+
"platform_admin",
|
|
27409
|
+
"workspace_admin"
|
|
27410
|
+
]);
|
|
27411
|
+
var CLERK_WEBHOOK_SECRETS = [
|
|
27412
|
+
"LUCERN_CLERK_WEBHOOK_SECRET",
|
|
27413
|
+
"CLERK_WEBHOOK_SECRET",
|
|
27414
|
+
"CLERK_WEBHOOK_SIGNING_SECRET"
|
|
27415
|
+
];
|
|
27416
|
+
function isRecord8(value) {
|
|
27417
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
27418
|
+
}
|
|
27419
|
+
function readString28(value) {
|
|
27420
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
27421
|
+
}
|
|
27422
|
+
function readNumber18(value) {
|
|
27423
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
27424
|
+
return value;
|
|
27425
|
+
}
|
|
27426
|
+
if (typeof value === "string" && value.trim()) {
|
|
27427
|
+
const parsed = Number(value);
|
|
27428
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
27429
|
+
}
|
|
27430
|
+
return void 0;
|
|
27431
|
+
}
|
|
27432
|
+
var PERMIT_USER_KEY_PATTERN = /^[A-Za-z0-9|@+\-._]+$/;
|
|
27433
|
+
var PERMIT_USER_KEY_ESCAPE_SENTINEL = "|";
|
|
27434
|
+
function asRecord26(value) {
|
|
27435
|
+
return isRecord8(value) ? value : {};
|
|
27436
|
+
}
|
|
27437
|
+
function asArray(value) {
|
|
27438
|
+
return Array.isArray(value) ? value : [];
|
|
27439
|
+
}
|
|
27440
|
+
function encodeBase64(bytes) {
|
|
27441
|
+
const buffer = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
27442
|
+
let binary = "";
|
|
27443
|
+
for (const value of buffer) {
|
|
27444
|
+
binary += String.fromCharCode(value);
|
|
27445
|
+
}
|
|
27446
|
+
return btoa(binary);
|
|
27447
|
+
}
|
|
27448
|
+
function permitUserKeyForPrincipalId(principalId) {
|
|
27449
|
+
const trimmed = principalId.trim();
|
|
27450
|
+
if (PERMIT_USER_KEY_PATTERN.test(trimmed) && !trimmed.includes(PERMIT_USER_KEY_ESCAPE_SENTINEL)) {
|
|
27451
|
+
return trimmed;
|
|
27452
|
+
}
|
|
27453
|
+
return Array.from(trimmed).map(
|
|
27454
|
+
(character) => PERMIT_USER_KEY_PATTERN.test(character) && character !== PERMIT_USER_KEY_ESCAPE_SENTINEL ? character : `${PERMIT_USER_KEY_ESCAPE_SENTINEL}${character.codePointAt(0)?.toString(16) ?? "0"}${PERMIT_USER_KEY_ESCAPE_SENTINEL}`
|
|
27455
|
+
).join("");
|
|
27456
|
+
}
|
|
27457
|
+
function compactRecord5(value) {
|
|
27458
|
+
return Object.fromEntries(
|
|
27459
|
+
Object.entries(value).filter(([, entry]) => entry !== void 0)
|
|
27460
|
+
);
|
|
27461
|
+
}
|
|
27462
|
+
function statusCodeFromError(error) {
|
|
27463
|
+
if (!error || typeof error !== "object") {
|
|
27464
|
+
return void 0;
|
|
27465
|
+
}
|
|
27466
|
+
const record = error;
|
|
27467
|
+
return numericStatus(record.status) ?? numericStatus(record.statusCode) ?? numericStatus(record.response?.status) ?? numericStatus(record.cause?.response?.status);
|
|
27468
|
+
}
|
|
27469
|
+
function numericStatus(value) {
|
|
27470
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
27471
|
+
return value;
|
|
27472
|
+
}
|
|
27473
|
+
if (typeof value === "string") {
|
|
27474
|
+
const parsed = Number(value);
|
|
27475
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
27476
|
+
}
|
|
27477
|
+
return void 0;
|
|
27478
|
+
}
|
|
27479
|
+
function isNotFound(error) {
|
|
27480
|
+
return statusCodeFromError(error) === 404 || String(error?.message ?? "").includes("404");
|
|
27481
|
+
}
|
|
27482
|
+
function isConflict(error) {
|
|
27483
|
+
return statusCodeFromError(error) === 409 || String(error?.message ?? "").includes("409");
|
|
27484
|
+
}
|
|
27485
|
+
function readRoleAssignments(value) {
|
|
27486
|
+
if (!Array.isArray(value)) {
|
|
27487
|
+
const record = isRecord8(value) ? value : {};
|
|
27488
|
+
if (Array.isArray(record.data)) {
|
|
27489
|
+
return record.data.filter(isRecord8);
|
|
27490
|
+
}
|
|
27491
|
+
if (Array.isArray(record.results)) {
|
|
27492
|
+
return record.results.filter(isRecord8);
|
|
27493
|
+
}
|
|
27494
|
+
return [];
|
|
27495
|
+
}
|
|
27496
|
+
return value.filter(isRecord8);
|
|
27497
|
+
}
|
|
27498
|
+
function roleAssignmentResourceInstance(assignment) {
|
|
27499
|
+
return readString28(assignment.resource_instance) ?? readString28(assignment.resourceInstance) ?? readString28(assignment.resource_instance_id) ?? readString28(assignment.resourceInstanceId);
|
|
27500
|
+
}
|
|
27501
|
+
function isTenantScopedRoleAssignment(assignment) {
|
|
27502
|
+
return !roleAssignmentResourceInstance(assignment);
|
|
27503
|
+
}
|
|
27504
|
+
function createPermitClient() {
|
|
27505
|
+
const token = readString28(process.env.LUCERN_PERMIT_API_KEY) ?? readString28(process.env.PERMIT_API_KEY);
|
|
27506
|
+
const pdpUrl = readString28(process.env.LUCERN_PERMIT_PDP_URL) ?? readString28(process.env.PERMIT_PDP_URL);
|
|
27507
|
+
const apiUrl = readString28(process.env.LUCERN_PERMIT_API_URL) ?? readString28(process.env.PERMIT_API_URL);
|
|
27508
|
+
if (!token || !pdpUrl) {
|
|
27509
|
+
throw {
|
|
27510
|
+
status: 502,
|
|
27511
|
+
code: "UPSTREAM_ERROR",
|
|
27512
|
+
message: "Permit projection is not configured. Set LUCERN_PERMIT_API_KEY and LUCERN_PERMIT_PDP_URL."
|
|
27513
|
+
};
|
|
27514
|
+
}
|
|
27515
|
+
return new Permit({
|
|
27516
|
+
token,
|
|
27517
|
+
pdp: pdpUrl,
|
|
27518
|
+
...apiUrl ? { apiUrl } : {},
|
|
27519
|
+
throwOnError: true
|
|
27520
|
+
});
|
|
27521
|
+
}
|
|
27522
|
+
function getPermitClient() {
|
|
27523
|
+
if (permitClientCache.value) {
|
|
27524
|
+
return permitClientCache.value;
|
|
27525
|
+
}
|
|
27526
|
+
if (permitClientFactory) {
|
|
27527
|
+
permitClientCache.value = permitClientFactory();
|
|
27528
|
+
return permitClientCache.value;
|
|
27529
|
+
}
|
|
27530
|
+
permitClientCache.value = createPermitClient();
|
|
27531
|
+
return permitClientCache.value;
|
|
27532
|
+
}
|
|
27533
|
+
var __testOnly = {
|
|
27534
|
+
setPermitClientFactory(factory) {
|
|
27535
|
+
permitClientFactory = factory;
|
|
27536
|
+
permitClientCache.value = null;
|
|
27537
|
+
}
|
|
27538
|
+
};
|
|
27539
|
+
async function upsertPermitTenant(args) {
|
|
27540
|
+
const permit = getPermitClient();
|
|
27541
|
+
const tenantPayload = {
|
|
27542
|
+
name: args.tenantName ?? args.tenantKey,
|
|
27543
|
+
attributes: compactRecord5({
|
|
27544
|
+
clerkOrganizationId: args.clerkOrganizationId,
|
|
27545
|
+
clerkOrganizationSlug: args.clerkOrganizationSlug,
|
|
27546
|
+
mcTenantKey: args.tenantKey,
|
|
27547
|
+
sourceType: "organization",
|
|
27548
|
+
sourceEvent: args.eventType,
|
|
27549
|
+
eventAt: args.eventAt,
|
|
27550
|
+
actorId: args.actorId
|
|
27551
|
+
})
|
|
27552
|
+
};
|
|
27553
|
+
try {
|
|
27554
|
+
return await permit.api.tenants.update(args.tenantKey, tenantPayload);
|
|
27555
|
+
} catch (error) {
|
|
27556
|
+
if (!isNotFound(error)) {
|
|
27557
|
+
throw error;
|
|
27558
|
+
}
|
|
27559
|
+
}
|
|
27560
|
+
return await permit.api.tenants.create({
|
|
27561
|
+
key: args.tenantKey,
|
|
27562
|
+
...tenantPayload
|
|
27563
|
+
});
|
|
27564
|
+
}
|
|
27565
|
+
async function syncPermitUser(args) {
|
|
27566
|
+
const permit = getPermitClient();
|
|
27567
|
+
return await permit.api.users.sync({
|
|
27568
|
+
key: permitUserKeyForPrincipalId(args.userId),
|
|
27569
|
+
email: args.email,
|
|
27570
|
+
attributes: compactRecord5({
|
|
27571
|
+
sourceType: "clerk_webhook_user",
|
|
27572
|
+
sourceEvent: args.eventType,
|
|
27573
|
+
clerkStatus: args.eventType,
|
|
27574
|
+
clerkDisplayName: args.displayName,
|
|
27575
|
+
eventAt: args.eventAt,
|
|
27576
|
+
actorId: args.actorId
|
|
27577
|
+
})
|
|
27578
|
+
});
|
|
27579
|
+
}
|
|
27580
|
+
async function upsertPermitTenantMembershipRole(args) {
|
|
27581
|
+
const permit = getPermitClient();
|
|
27582
|
+
const permitUserId = permitUserKeyForPrincipalId(args.userId);
|
|
27583
|
+
const existing = readRoleAssignments(
|
|
27584
|
+
await permit.api.roleAssignments.list({
|
|
27585
|
+
user: permitUserId,
|
|
27586
|
+
tenant: args.tenantKey,
|
|
27587
|
+
perPage: 100
|
|
27588
|
+
})
|
|
27589
|
+
);
|
|
27590
|
+
await Promise.all(
|
|
27591
|
+
existing.map((assignment2) => {
|
|
27592
|
+
const role = readString28(assignment2.role);
|
|
27593
|
+
if (!role || !PERMIT_MEMBERSHIP_ROLES.has(role)) {
|
|
27594
|
+
return Promise.resolve();
|
|
27595
|
+
}
|
|
27596
|
+
if (!isTenantScopedRoleAssignment(assignment2)) {
|
|
27597
|
+
return Promise.resolve();
|
|
27598
|
+
}
|
|
27599
|
+
if (role === args.role) {
|
|
27600
|
+
return Promise.resolve();
|
|
27601
|
+
}
|
|
27602
|
+
return unassignPermitTenantMembershipRole({
|
|
27603
|
+
permit,
|
|
27604
|
+
permitUserId,
|
|
27605
|
+
tenant: args.tenantKey,
|
|
27606
|
+
role
|
|
27607
|
+
});
|
|
27608
|
+
})
|
|
27609
|
+
);
|
|
27610
|
+
const assignment = {
|
|
27611
|
+
user: permitUserId,
|
|
27612
|
+
role: args.role,
|
|
27613
|
+
tenant: args.tenantKey
|
|
27614
|
+
};
|
|
27615
|
+
try {
|
|
27616
|
+
return await permit.api.roleAssignments.assign(assignment);
|
|
27617
|
+
} catch (error) {
|
|
27618
|
+
if (isConflict(error)) {
|
|
27619
|
+
return { alreadyAssigned: true };
|
|
27620
|
+
}
|
|
27621
|
+
throw error;
|
|
27622
|
+
}
|
|
27623
|
+
}
|
|
27624
|
+
async function unassignPermitTenantMembershipRole(args) {
|
|
27625
|
+
const api2 = args.permit.api;
|
|
27626
|
+
const assignment = {
|
|
27627
|
+
user: args.permitUserId,
|
|
27628
|
+
role: args.role,
|
|
27629
|
+
tenant: args.tenant,
|
|
27630
|
+
...args.resourceInstance ? { resource_instance: args.resourceInstance } : {}
|
|
27631
|
+
};
|
|
27632
|
+
if (typeof api2.roleAssignments?.unassign === "function") {
|
|
27633
|
+
return await api2.roleAssignments.unassign(assignment);
|
|
27634
|
+
}
|
|
27635
|
+
if (typeof api2.unassignRole === "function") {
|
|
27636
|
+
return await api2.unassignRole(assignment);
|
|
27637
|
+
}
|
|
27638
|
+
if (typeof api2.users?.unassignRole === "function") {
|
|
27639
|
+
return await api2.users.unassignRole({
|
|
27640
|
+
user: args.permitUserId,
|
|
27641
|
+
role: args.role,
|
|
27642
|
+
tenant: args.tenant
|
|
27643
|
+
});
|
|
27644
|
+
}
|
|
27645
|
+
throw new Error("Permit SDK does not expose an unassignRole method");
|
|
27646
|
+
}
|
|
27647
|
+
async function revokePermitTenantMembershipRoles(args) {
|
|
27648
|
+
const permit = getPermitClient();
|
|
27649
|
+
const permitUserId = permitUserKeyForPrincipalId(args.userId);
|
|
27650
|
+
const assignments = readRoleAssignments(
|
|
27651
|
+
await permit.api.roleAssignments.list({
|
|
27652
|
+
user: permitUserId,
|
|
27653
|
+
tenant: args.tenantKey,
|
|
27654
|
+
perPage: 100
|
|
27655
|
+
})
|
|
27656
|
+
);
|
|
27657
|
+
const membershipRoles = assignments.filter(
|
|
27658
|
+
(assignment) => isTenantScopedRoleAssignment(assignment) && PERMIT_MEMBERSHIP_ROLES.has(readString28(assignment.role) ?? "")
|
|
27659
|
+
);
|
|
27660
|
+
await Promise.all(
|
|
27661
|
+
membershipRoles.map((assignment) => {
|
|
27662
|
+
const role = readString28(assignment.role);
|
|
27663
|
+
if (!role) {
|
|
27664
|
+
return Promise.resolve();
|
|
27665
|
+
}
|
|
27666
|
+
return unassignPermitTenantMembershipRole({
|
|
27667
|
+
permit,
|
|
27668
|
+
permitUserId,
|
|
27669
|
+
tenant: args.tenantKey,
|
|
27670
|
+
role
|
|
27671
|
+
});
|
|
27672
|
+
})
|
|
27673
|
+
);
|
|
27674
|
+
}
|
|
27675
|
+
function normalizeBase64(value) {
|
|
27676
|
+
return value.replace(/-/g, "+").replace(/_/g, "/");
|
|
27677
|
+
}
|
|
27678
|
+
function maybeBase64(value) {
|
|
27679
|
+
if (!value || value.length < 16) {
|
|
27680
|
+
return false;
|
|
27681
|
+
}
|
|
27682
|
+
if (value.length % 4 === 1) {
|
|
27683
|
+
return false;
|
|
27684
|
+
}
|
|
27685
|
+
return /^[A-Za-z0-9+/=_-]+$/.test(value);
|
|
27686
|
+
}
|
|
27687
|
+
function decodeBase64OrRaw(value) {
|
|
27688
|
+
if (!value) {
|
|
27689
|
+
return new Uint8Array();
|
|
27690
|
+
}
|
|
27691
|
+
const trimmed = value.trim();
|
|
27692
|
+
const secretMaterial = trimmed.startsWith("whsec_") ? trimmed.slice("whsec_".length) : trimmed;
|
|
27693
|
+
const candidate = normalizeBase64(secretMaterial);
|
|
27694
|
+
if (!maybeBase64(candidate)) {
|
|
27695
|
+
return new TextEncoder().encode(secretMaterial);
|
|
27696
|
+
}
|
|
27697
|
+
try {
|
|
27698
|
+
const binary = atob(candidate);
|
|
27699
|
+
return Uint8Array.from(binary, (entry) => entry.charCodeAt(0));
|
|
27700
|
+
} catch {
|
|
27701
|
+
return new TextEncoder().encode(secretMaterial);
|
|
27702
|
+
}
|
|
27703
|
+
}
|
|
27704
|
+
function readSigningSecret(env = process.env) {
|
|
27705
|
+
for (const key of CLERK_WEBHOOK_SECRETS) {
|
|
27706
|
+
const value = readString28(env[key]);
|
|
27707
|
+
if (value) {
|
|
27708
|
+
return value;
|
|
27709
|
+
}
|
|
27710
|
+
}
|
|
27711
|
+
return void 0;
|
|
27712
|
+
}
|
|
27713
|
+
function parseSvixSignatures(header) {
|
|
27714
|
+
return header.split(",").map((entry) => entry.trim()).filter(Boolean).flatMap((entry) => {
|
|
27715
|
+
if (entry.startsWith("v1=")) {
|
|
27716
|
+
return [entry.slice("v1=".length)];
|
|
27717
|
+
}
|
|
27718
|
+
return [];
|
|
27719
|
+
}).filter(Boolean);
|
|
27720
|
+
}
|
|
27721
|
+
function parseWebhookHeaders(headers) {
|
|
27722
|
+
const secret = readSigningSecret();
|
|
27723
|
+
const webhookId = headers.get("svix-id");
|
|
27724
|
+
const timestamp = headers.get("svix-timestamp");
|
|
27725
|
+
const signatureHeader = headers.get("svix-signature");
|
|
27726
|
+
if (!secret || !webhookId || !timestamp || !signatureHeader) {
|
|
27727
|
+
return null;
|
|
27728
|
+
}
|
|
27729
|
+
return {
|
|
27730
|
+
webhookId,
|
|
27731
|
+
timestamp,
|
|
27732
|
+
signatures: parseSvixSignatures(signatureHeader),
|
|
27733
|
+
secret
|
|
27734
|
+
};
|
|
27735
|
+
}
|
|
27736
|
+
function safeEquals(left, right) {
|
|
27737
|
+
if (left.length !== right.length) {
|
|
27738
|
+
return false;
|
|
27739
|
+
}
|
|
27740
|
+
let diff = 0;
|
|
27741
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
27742
|
+
diff |= left.charCodeAt(index) ^ right.charCodeAt(index);
|
|
27743
|
+
}
|
|
27744
|
+
return diff === 0;
|
|
27745
|
+
}
|
|
27746
|
+
async function verifyClerkSignature(args) {
|
|
27747
|
+
const parsed = parseWebhookHeaders(args.headers);
|
|
27748
|
+
if (!parsed) {
|
|
27749
|
+
return "missing_headers_or_secret";
|
|
27750
|
+
}
|
|
27751
|
+
const signatureTimestamp = readNumber18(parsed.timestamp);
|
|
27752
|
+
if (!signatureTimestamp) {
|
|
27753
|
+
return "malformed_timestamp";
|
|
27754
|
+
}
|
|
27755
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
27756
|
+
if (Math.abs(nowSeconds - signatureTimestamp) > SIGNATURE_TOLERANCE_SECONDS) {
|
|
27757
|
+
return "signature_expired";
|
|
27758
|
+
}
|
|
27759
|
+
const message = `${parsed.webhookId}.${parsed.timestamp}.${args.body}`;
|
|
27760
|
+
const keyBytes = decodeBase64OrRaw(parsed.secret);
|
|
27761
|
+
const key = await crypto.subtle.importKey(
|
|
27762
|
+
"raw",
|
|
27763
|
+
keyBytes,
|
|
27764
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
27765
|
+
false,
|
|
27766
|
+
["sign"]
|
|
27767
|
+
);
|
|
27768
|
+
const computed = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(message));
|
|
27769
|
+
const computedSignature = encodeBase64(computed);
|
|
27770
|
+
return parsed.signatures.some((candidate) => safeEquals(candidate, computedSignature)) || "signature_mismatch";
|
|
27771
|
+
}
|
|
27772
|
+
function extractClerkActorId(payload) {
|
|
27773
|
+
const event = asRecord26(payload);
|
|
27774
|
+
const data = asRecord26(event.data);
|
|
27775
|
+
return readString28(event.actor_id) || readString28(asRecord26(event.actor).id) || readString28(data.actor_id) || readString28(asRecord26(data.actor).id) || readString28(data.created_by) || readString28(asRecord26(data.public_user_data).user_id) || SYSTEM_ACTOR_ID;
|
|
27776
|
+
}
|
|
27777
|
+
function extractUserData(data) {
|
|
27778
|
+
const user = asRecord26(data.user);
|
|
27779
|
+
if (Object.keys(user).length > 0) {
|
|
27780
|
+
return user;
|
|
27781
|
+
}
|
|
27782
|
+
const publicUser = asRecord26(data.public_user_data);
|
|
27783
|
+
if (Object.keys(publicUser).length > 0) {
|
|
27784
|
+
return publicUser;
|
|
27785
|
+
}
|
|
27786
|
+
return data;
|
|
27787
|
+
}
|
|
27788
|
+
function extractOrganizationIds(data) {
|
|
27789
|
+
const organization = asRecord26(data.organization);
|
|
27790
|
+
return {
|
|
27791
|
+
organizationId: readString28(data.organization_id) || readString28(data.id) || readString28(organization.id),
|
|
27792
|
+
organizationSlug: readString28(data.organization_slug) || readString28(data.slug) || readString28(organization.slug)
|
|
27793
|
+
};
|
|
27794
|
+
}
|
|
27795
|
+
function readPrimaryEmail(userData) {
|
|
27796
|
+
const direct = readString28(userData.primary_email_address) || readString28(userData.email) || readString28(userData.emailAddress);
|
|
27797
|
+
if (direct) {
|
|
27798
|
+
return direct;
|
|
27799
|
+
}
|
|
27800
|
+
for (const entry of asArray(userData.email_addresses)) {
|
|
27801
|
+
const row = asRecord26(entry);
|
|
27802
|
+
const value = readString28(row.email_address) || readString28(row.emailAddress) || readString28(row.address);
|
|
27803
|
+
if (value) {
|
|
27804
|
+
return value;
|
|
27805
|
+
}
|
|
27806
|
+
}
|
|
27807
|
+
return void 0;
|
|
27808
|
+
}
|
|
27809
|
+
function readDisplayName(userData) {
|
|
27810
|
+
const first = readString28(userData.first_name) || readString28(userData.firstName);
|
|
27811
|
+
const last = readString28(userData.last_name) || readString28(userData.lastName);
|
|
27812
|
+
if (first || last) {
|
|
27813
|
+
return [first, last].filter(Boolean).join(" ");
|
|
27814
|
+
}
|
|
27815
|
+
return readString28(userData.username) || readString28(userData.name);
|
|
27816
|
+
}
|
|
27817
|
+
function normalizeRole(value) {
|
|
27818
|
+
const normalized = readString28(value)?.toLowerCase() ?? "viewer";
|
|
27819
|
+
if (normalized === "admin" || normalized === "owner" || normalized === "org:admin") {
|
|
27820
|
+
return "tenant_admin";
|
|
27821
|
+
}
|
|
27822
|
+
if (normalized === "editor" || normalized === "viewer" || normalized === "auditor" || normalized === "service_agent" || normalized === "platform_admin" || normalized === "tenant_admin" || normalized === "workspace_admin") {
|
|
27823
|
+
return normalized;
|
|
27824
|
+
}
|
|
27825
|
+
if (normalized === "basic_member" || normalized === "org:member") {
|
|
27826
|
+
return "viewer";
|
|
27827
|
+
}
|
|
27828
|
+
return "viewer";
|
|
27829
|
+
}
|
|
27830
|
+
function buildWebhookMetadata(args) {
|
|
27831
|
+
return {
|
|
27832
|
+
source: "clerk_webhook",
|
|
27833
|
+
eventType: args.eventType,
|
|
27834
|
+
eventId: args.eventId,
|
|
27835
|
+
eventAt: args.eventAt,
|
|
27836
|
+
actorId: args.actorId,
|
|
27837
|
+
...args.extra
|
|
27838
|
+
};
|
|
27839
|
+
}
|
|
27840
|
+
function extractOrganizationName(organization) {
|
|
27841
|
+
return readString28(organization.name) || readString28(organization.slug) || readString28(organization.title);
|
|
27842
|
+
}
|
|
27843
|
+
async function getMasterControlConvexClient2() {
|
|
27844
|
+
if (mcClientCache2.value) {
|
|
27845
|
+
return mcClientCache2.value;
|
|
27846
|
+
}
|
|
27847
|
+
const convexUrl = readString28(process.env.CONVEX_MC_URL);
|
|
27848
|
+
const deployKey = readString28(process.env.CONVEX_MC_DEPLOY_KEY);
|
|
27849
|
+
if (!convexUrl || !deployKey) {
|
|
27850
|
+
throw new Error(
|
|
27851
|
+
"Master Control is not configured. Set CONVEX_MC_URL and CONVEX_MC_DEPLOY_KEY."
|
|
27852
|
+
);
|
|
27853
|
+
}
|
|
27854
|
+
const client = new ConvexHttpClient(convexUrl);
|
|
27855
|
+
client.setAdminAuth(
|
|
27856
|
+
deployKey
|
|
27857
|
+
);
|
|
27858
|
+
mcClientCache2.value = client;
|
|
27859
|
+
return client;
|
|
27860
|
+
}
|
|
27861
|
+
async function resolveTenantByOrgSlug(args) {
|
|
27862
|
+
if (!args.organizationSlug) {
|
|
27863
|
+
return void 0;
|
|
27864
|
+
}
|
|
27865
|
+
const tenant = await args.client.query(mcApi2.tenants.getBySlug, {
|
|
27866
|
+
slug: args.organizationSlug
|
|
27867
|
+
});
|
|
27868
|
+
if (!tenant || !isRecord8(tenant)) {
|
|
27869
|
+
return void 0;
|
|
27870
|
+
}
|
|
27871
|
+
const tenantId = readString28(tenant._id);
|
|
27872
|
+
const tenantSlug = readString28(tenant.slug);
|
|
27873
|
+
if (!tenantId || !tenantSlug) {
|
|
27874
|
+
return void 0;
|
|
27875
|
+
}
|
|
27876
|
+
return { tenantId, tenantSlug };
|
|
27877
|
+
}
|
|
27878
|
+
function webhookError(code, status, message, correlationId, policyTraceId, details) {
|
|
27879
|
+
return errorResponse({
|
|
27880
|
+
code,
|
|
27881
|
+
status,
|
|
27882
|
+
message,
|
|
27883
|
+
correlationId,
|
|
27884
|
+
policyTraceId,
|
|
27885
|
+
details
|
|
27886
|
+
});
|
|
27887
|
+
}
|
|
27888
|
+
function handleClerkWebhookError(error, correlationId, policyTraceId) {
|
|
27889
|
+
const resolved = resolveServerCoreError(error, "Failed to reconcile Clerk webhook.");
|
|
27890
|
+
return errorResponse({
|
|
27891
|
+
code: resolved.code,
|
|
27892
|
+
message: resolved.message,
|
|
27893
|
+
status: resolved.status,
|
|
27894
|
+
correlationId,
|
|
27895
|
+
policyTraceId,
|
|
27896
|
+
invariant: resolved.invariant,
|
|
27897
|
+
suggestion: resolved.suggestion,
|
|
27898
|
+
details: resolved.details
|
|
27899
|
+
});
|
|
27900
|
+
}
|
|
27901
|
+
async function handleClerkWebhook(args) {
|
|
27902
|
+
try {
|
|
27903
|
+
const rawBody = await args.request.clone().text();
|
|
27904
|
+
const verification = await verifyClerkSignature({
|
|
27905
|
+
body: rawBody,
|
|
27906
|
+
headers: args.request.headers
|
|
27907
|
+
});
|
|
27908
|
+
if (verification !== true) {
|
|
27909
|
+
let message = "Clerk webhook signature verification failed.";
|
|
27910
|
+
if (verification === "signature_expired") {
|
|
27911
|
+
message = "Clerk webhook signature is too old.";
|
|
27912
|
+
}
|
|
27913
|
+
if (verification === "malformed_timestamp") {
|
|
27914
|
+
message = "Malformed Clerk webhook timestamp header.";
|
|
27915
|
+
}
|
|
27916
|
+
if (verification === "missing_headers_or_secret") {
|
|
27917
|
+
message = "Missing Clerk webhook signature headers or secret.";
|
|
27918
|
+
}
|
|
27919
|
+
return webhookError(
|
|
27920
|
+
"AUTH_REQUIRED",
|
|
27921
|
+
401,
|
|
27922
|
+
message,
|
|
27923
|
+
args.correlationId,
|
|
27924
|
+
args.policyTraceId
|
|
27925
|
+
);
|
|
27926
|
+
}
|
|
27927
|
+
let payload;
|
|
27928
|
+
try {
|
|
27929
|
+
payload = JSON.parse(rawBody);
|
|
27930
|
+
} catch {
|
|
27931
|
+
return webhookError(
|
|
27932
|
+
"INVALID_REQUEST",
|
|
27933
|
+
400,
|
|
27934
|
+
"Clerk webhook body must be valid JSON.",
|
|
27935
|
+
args.correlationId,
|
|
27936
|
+
args.policyTraceId
|
|
27937
|
+
);
|
|
27938
|
+
}
|
|
27939
|
+
const eventType = readString28(payload.type);
|
|
27940
|
+
if (!eventType) {
|
|
27941
|
+
return webhookError(
|
|
27942
|
+
"INVALID_REQUEST",
|
|
27943
|
+
400,
|
|
27944
|
+
"Clerk webhook payload must include event type.",
|
|
27945
|
+
args.correlationId,
|
|
27946
|
+
args.policyTraceId
|
|
27947
|
+
);
|
|
27948
|
+
}
|
|
27949
|
+
const data = asRecord26(payload.data);
|
|
27950
|
+
const actorId = extractClerkActorId(payload);
|
|
27951
|
+
const eventId = readString28(payload.id);
|
|
27952
|
+
const eventTimestamp = readString28(payload.created_at) || readString28(payload.timestamp);
|
|
27953
|
+
const isOrgLifecycleEvent = ORGANIZATION_LIFECYCLE_EVENTS.has(eventType);
|
|
27954
|
+
const isUserEvent = USER_EVENTS.has(eventType);
|
|
27955
|
+
const isMembershipEvent = MEMBERSHIP_EVENTS.has(eventType);
|
|
27956
|
+
const isInvitationEvent = INVITATION_EVENTS.has(eventType);
|
|
27957
|
+
const getClient = async () => args.convexClient ?? await getMasterControlConvexClient2();
|
|
27958
|
+
if (isOrgLifecycleEvent) {
|
|
27959
|
+
const nestedOrganization = asRecord26(data.organization);
|
|
27960
|
+
const organizationRecord = Object.keys(nestedOrganization).length > 0 ? nestedOrganization : data;
|
|
27961
|
+
const organizationId = readString28(data.id) || readString28(data.organization_id) || readString28(organizationRecord.id);
|
|
27962
|
+
const organizationIds = extractOrganizationIds(data);
|
|
27963
|
+
if (!organizationId) {
|
|
27964
|
+
return webhookError(
|
|
27965
|
+
"INVALID_REQUEST",
|
|
27966
|
+
400,
|
|
27967
|
+
"Clerk organization webhook payload missing organization id.",
|
|
27968
|
+
args.correlationId,
|
|
27969
|
+
args.policyTraceId
|
|
27970
|
+
);
|
|
27971
|
+
}
|
|
27972
|
+
const client = await getClient();
|
|
27973
|
+
const tenant = await resolveTenantByOrgSlug({
|
|
27974
|
+
client,
|
|
27975
|
+
organizationSlug: organizationIds.organizationSlug
|
|
27976
|
+
});
|
|
27977
|
+
if (!tenant) {
|
|
27978
|
+
return webhookError(
|
|
27979
|
+
"NOT_FOUND",
|
|
27980
|
+
404,
|
|
27981
|
+
"Could not resolve tenant for Clerk organization webhook event.",
|
|
27982
|
+
args.correlationId,
|
|
27983
|
+
args.policyTraceId,
|
|
27984
|
+
{
|
|
27985
|
+
eventType,
|
|
27986
|
+
organizationId,
|
|
27987
|
+
organizationSlug: organizationIds.organizationSlug
|
|
27988
|
+
}
|
|
27989
|
+
);
|
|
27990
|
+
}
|
|
27991
|
+
await upsertPermitTenant({
|
|
27992
|
+
clerkOrganizationId: organizationId,
|
|
27993
|
+
clerkOrganizationSlug: organizationIds.organizationSlug,
|
|
27994
|
+
tenantKey: tenant.tenantSlug,
|
|
27995
|
+
tenantName: extractOrganizationName(organizationRecord),
|
|
27996
|
+
eventType,
|
|
27997
|
+
eventAt: eventTimestamp,
|
|
27998
|
+
actorId
|
|
27999
|
+
});
|
|
28000
|
+
const principal = await client.mutation(mcApi2.identity.upsertPrincipal, {
|
|
28001
|
+
principalId: organizationId,
|
|
28002
|
+
principalType: "group",
|
|
28003
|
+
clerkId: organizationId,
|
|
28004
|
+
displayName: extractOrganizationName(organizationRecord),
|
|
28005
|
+
status: eventType === "organization.deleted" ? "disabled" : "active",
|
|
28006
|
+
actorClerkId: actorId,
|
|
28007
|
+
tenantId: tenant.tenantId,
|
|
28008
|
+
metadata: buildWebhookMetadata({
|
|
28009
|
+
eventType,
|
|
28010
|
+
eventId,
|
|
28011
|
+
actorId,
|
|
28012
|
+
eventAt: eventTimestamp,
|
|
28013
|
+
extra: {
|
|
28014
|
+
sourceType: "organization",
|
|
28015
|
+
organizationId,
|
|
28016
|
+
organizationSlug: organizationIds.organizationSlug,
|
|
28017
|
+
organizationName: extractOrganizationName(organizationRecord),
|
|
28018
|
+
organizationStatus: eventType
|
|
28019
|
+
}
|
|
28020
|
+
})
|
|
28021
|
+
});
|
|
28022
|
+
const alias = await client.mutation(mcApi2.identity.upsertPrincipalIdentityAlias, {
|
|
28023
|
+
principalId: organizationId,
|
|
28024
|
+
principalRefId: void 0,
|
|
28025
|
+
provider: "clerk",
|
|
28026
|
+
providerProjectId: void 0,
|
|
28027
|
+
externalSubjectId: organizationId,
|
|
28028
|
+
tenantId: tenant.tenantId,
|
|
28029
|
+
email: void 0,
|
|
28030
|
+
metadata: buildWebhookMetadata({
|
|
28031
|
+
eventType,
|
|
28032
|
+
eventId,
|
|
28033
|
+
actorId,
|
|
28034
|
+
eventAt: eventTimestamp,
|
|
28035
|
+
extra: {
|
|
28036
|
+
sourceType: "organization",
|
|
28037
|
+
organizationId,
|
|
28038
|
+
organizationSlug: organizationIds.organizationSlug,
|
|
28039
|
+
organizationName: extractOrganizationName(organizationRecord),
|
|
28040
|
+
organizationStatus: eventType
|
|
28041
|
+
}
|
|
28042
|
+
}),
|
|
28043
|
+
actorClerkId: actorId
|
|
28044
|
+
});
|
|
28045
|
+
return successResponse(
|
|
28046
|
+
{
|
|
28047
|
+
acknowledged: true,
|
|
28048
|
+
eventType,
|
|
28049
|
+
tenantId: tenant.tenantId,
|
|
28050
|
+
principalId: organizationId,
|
|
28051
|
+
principal,
|
|
28052
|
+
alias
|
|
28053
|
+
},
|
|
28054
|
+
{
|
|
28055
|
+
correlationId: args.correlationId,
|
|
28056
|
+
policyTraceId: args.policyTraceId
|
|
28057
|
+
}
|
|
28058
|
+
);
|
|
28059
|
+
}
|
|
28060
|
+
if (isUserEvent) {
|
|
28061
|
+
const client = await getClient();
|
|
28062
|
+
const userData = extractUserData(data);
|
|
28063
|
+
const userId = readString28(userData.id) || readString28(data.id);
|
|
28064
|
+
if (!userId) {
|
|
28065
|
+
return webhookError(
|
|
28066
|
+
"INVALID_REQUEST",
|
|
28067
|
+
400,
|
|
28068
|
+
"Clerk user webhook payload missing user id.",
|
|
28069
|
+
args.correlationId,
|
|
28070
|
+
args.policyTraceId
|
|
28071
|
+
);
|
|
28072
|
+
}
|
|
28073
|
+
await syncPermitUser({
|
|
28074
|
+
userId,
|
|
28075
|
+
email: readPrimaryEmail(userData),
|
|
28076
|
+
displayName: readDisplayName(userData),
|
|
28077
|
+
eventType,
|
|
28078
|
+
eventAt: eventTimestamp,
|
|
28079
|
+
actorId
|
|
28080
|
+
});
|
|
28081
|
+
const principal = await client.mutation(mcApi2.identity.upsertPrincipal, {
|
|
28082
|
+
principalId: userId,
|
|
28083
|
+
principalType: "user",
|
|
28084
|
+
clerkId: userId,
|
|
28085
|
+
email: readPrimaryEmail(userData),
|
|
28086
|
+
displayName: readDisplayName(userData),
|
|
28087
|
+
status: eventType === "user.deleted" ? "disabled" : "active",
|
|
28088
|
+
actorClerkId: actorId,
|
|
28089
|
+
metadata: buildWebhookMetadata({
|
|
28090
|
+
eventType,
|
|
28091
|
+
eventId,
|
|
28092
|
+
actorId,
|
|
28093
|
+
eventAt: eventTimestamp,
|
|
28094
|
+
extra: {
|
|
28095
|
+
userId,
|
|
28096
|
+
clerkStatus: eventType,
|
|
28097
|
+
user: userData
|
|
28098
|
+
}
|
|
28099
|
+
})
|
|
28100
|
+
});
|
|
28101
|
+
const alias = await client.mutation(mcApi2.identity.upsertPrincipalIdentityAlias, {
|
|
28102
|
+
principalId: userId,
|
|
28103
|
+
principalRefId: void 0,
|
|
28104
|
+
provider: "clerk",
|
|
28105
|
+
providerProjectId: void 0,
|
|
28106
|
+
externalSubjectId: userId,
|
|
28107
|
+
tenantId: void 0,
|
|
28108
|
+
email: readPrimaryEmail(userData),
|
|
28109
|
+
metadata: buildWebhookMetadata({
|
|
28110
|
+
eventType,
|
|
28111
|
+
eventId,
|
|
28112
|
+
actorId,
|
|
28113
|
+
eventAt: eventTimestamp,
|
|
28114
|
+
extra: {
|
|
28115
|
+
userId,
|
|
28116
|
+
sourceType: "user",
|
|
28117
|
+
status: eventType,
|
|
28118
|
+
email: readPrimaryEmail(userData),
|
|
28119
|
+
displayName: readDisplayName(userData)
|
|
28120
|
+
}
|
|
28121
|
+
}),
|
|
28122
|
+
actorClerkId: actorId
|
|
28123
|
+
});
|
|
28124
|
+
return successResponse(
|
|
28125
|
+
{
|
|
28126
|
+
acknowledged: true,
|
|
28127
|
+
eventType,
|
|
28128
|
+
principal,
|
|
28129
|
+
alias,
|
|
28130
|
+
source: {
|
|
28131
|
+
eventType,
|
|
28132
|
+
eventId
|
|
28133
|
+
}
|
|
28134
|
+
},
|
|
28135
|
+
{
|
|
28136
|
+
correlationId: args.correlationId,
|
|
28137
|
+
policyTraceId: args.policyTraceId
|
|
28138
|
+
}
|
|
28139
|
+
);
|
|
28140
|
+
}
|
|
28141
|
+
if (isMembershipEvent || isInvitationEvent) {
|
|
28142
|
+
const client = await getClient();
|
|
28143
|
+
const org = extractOrganizationIds(data);
|
|
28144
|
+
const tenant = await resolveTenantByOrgSlug({
|
|
28145
|
+
client,
|
|
28146
|
+
organizationSlug: org.organizationSlug
|
|
28147
|
+
});
|
|
28148
|
+
if (!tenant) {
|
|
28149
|
+
return webhookError(
|
|
28150
|
+
"NOT_FOUND",
|
|
28151
|
+
404,
|
|
28152
|
+
"Could not resolve tenant for Clerk organization webhook event.",
|
|
28153
|
+
args.correlationId,
|
|
28154
|
+
args.policyTraceId,
|
|
28155
|
+
{
|
|
28156
|
+
eventType,
|
|
28157
|
+
organizationId: org.organizationId,
|
|
28158
|
+
organizationSlug: org.organizationSlug
|
|
28159
|
+
}
|
|
28160
|
+
);
|
|
28161
|
+
}
|
|
28162
|
+
const userId = readString28(data.user_id) || readString28(asRecord26(data.public_user_data).user_id) || readString28(asRecord26(data.user).id);
|
|
28163
|
+
const rawRole = readString28(data.role);
|
|
28164
|
+
const role = normalizeRole(rawRole);
|
|
28165
|
+
const permitTenantKey = tenant.tenantSlug;
|
|
28166
|
+
if (!permitTenantKey) {
|
|
28167
|
+
return webhookError(
|
|
28168
|
+
"INVALID_REQUEST",
|
|
28169
|
+
400,
|
|
28170
|
+
"Clerk organization webhook payload missing organization tenant key.",
|
|
28171
|
+
args.correlationId,
|
|
28172
|
+
args.policyTraceId
|
|
28173
|
+
);
|
|
28174
|
+
}
|
|
28175
|
+
if (INVITATION_EVENTS.has(eventType)) {
|
|
28176
|
+
const invitationId = readString28(data.id);
|
|
28177
|
+
const invitationAccepted = eventType === "organizationInvitation.accepted";
|
|
28178
|
+
const invitationRevoked = eventType === "organizationInvitation.revoked";
|
|
28179
|
+
let fallbackInvitationStatus = "created";
|
|
28180
|
+
if (invitationAccepted) {
|
|
28181
|
+
fallbackInvitationStatus = "accepted";
|
|
28182
|
+
} else if (invitationRevoked) {
|
|
28183
|
+
fallbackInvitationStatus = "revoked";
|
|
28184
|
+
}
|
|
28185
|
+
const invitationStatus = readString28(data.status) || fallbackInvitationStatus;
|
|
28186
|
+
if (!invitationId) {
|
|
28187
|
+
return webhookError(
|
|
28188
|
+
"INVALID_REQUEST",
|
|
28189
|
+
400,
|
|
28190
|
+
"Clerk organization invitation webhook payload missing invitation id.",
|
|
28191
|
+
args.correlationId,
|
|
28192
|
+
args.policyTraceId
|
|
28193
|
+
);
|
|
28194
|
+
}
|
|
28195
|
+
if (userId) {
|
|
28196
|
+
const userEmail = readPrimaryEmail(asRecord26(data.public_user_data));
|
|
28197
|
+
await syncPermitUser({
|
|
28198
|
+
userId,
|
|
28199
|
+
email: userEmail,
|
|
28200
|
+
displayName: void 0,
|
|
28201
|
+
eventType,
|
|
28202
|
+
eventAt: eventTimestamp,
|
|
28203
|
+
actorId
|
|
28204
|
+
});
|
|
28205
|
+
const existingPrincipal = invitationAccepted ? null : await client.query(mcApi2.identity.getPrincipalByPrincipalId, {
|
|
28206
|
+
principalId: userId
|
|
28207
|
+
});
|
|
28208
|
+
const principalStatus = invitationAccepted ? "active" : readString28(asRecord26(existingPrincipal).status) ?? "invited";
|
|
28209
|
+
await client.mutation(mcApi2.identity.upsertPrincipal, {
|
|
28210
|
+
principalId: userId,
|
|
28211
|
+
principalType: "user",
|
|
28212
|
+
clerkId: userId,
|
|
28213
|
+
actorClerkId: actorId,
|
|
28214
|
+
status: principalStatus,
|
|
28215
|
+
metadata: buildWebhookMetadata({
|
|
28216
|
+
eventType,
|
|
28217
|
+
eventId,
|
|
28218
|
+
actorId,
|
|
28219
|
+
eventAt: eventTimestamp,
|
|
28220
|
+
extra: {
|
|
28221
|
+
sourceType: "organization_invitation",
|
|
28222
|
+
invitationId,
|
|
28223
|
+
organizationId: org.organizationId,
|
|
28224
|
+
organizationSlug: org.organizationSlug,
|
|
28225
|
+
membershipId: readString28(data.membership_id),
|
|
28226
|
+
role,
|
|
28227
|
+
tenantId: tenant.tenantId
|
|
28228
|
+
}
|
|
28229
|
+
})
|
|
28230
|
+
});
|
|
28231
|
+
if (invitationAccepted) {
|
|
28232
|
+
await upsertPermitTenantMembershipRole({
|
|
28233
|
+
userId,
|
|
28234
|
+
tenantKey: permitTenantKey,
|
|
28235
|
+
role
|
|
28236
|
+
});
|
|
28237
|
+
await client.mutation(mcApi2.identity.upsertMembership, {
|
|
28238
|
+
principalId: userId,
|
|
28239
|
+
principalRefId: void 0,
|
|
28240
|
+
tenantId: tenant.tenantId,
|
|
28241
|
+
role,
|
|
28242
|
+
source: "api",
|
|
28243
|
+
actorClerkId: actorId
|
|
28244
|
+
});
|
|
28245
|
+
}
|
|
28246
|
+
await client.mutation(mcApi2.identity.upsertPrincipalIdentityAlias, {
|
|
28247
|
+
principalId: userId,
|
|
28248
|
+
principalRefId: void 0,
|
|
28249
|
+
provider: "clerk",
|
|
28250
|
+
providerProjectId: void 0,
|
|
28251
|
+
externalSubjectId: userId,
|
|
28252
|
+
tenantId: tenant.tenantId,
|
|
28253
|
+
email: readPrimaryEmail(asRecord26(data.public_user_data)),
|
|
28254
|
+
metadata: buildWebhookMetadata({
|
|
28255
|
+
eventType,
|
|
28256
|
+
eventId,
|
|
28257
|
+
actorId,
|
|
28258
|
+
eventAt: eventTimestamp,
|
|
28259
|
+
extra: {
|
|
28260
|
+
sourceType: "organization_invitation",
|
|
28261
|
+
organizationId: org.organizationId,
|
|
28262
|
+
organizationSlug: org.organizationSlug,
|
|
28263
|
+
invitationId,
|
|
28264
|
+
invitationStatus,
|
|
28265
|
+
role,
|
|
28266
|
+
tenantId: tenant.tenantId,
|
|
28267
|
+
membershipId: readString28(data.membership_id)
|
|
28268
|
+
}
|
|
28269
|
+
}),
|
|
28270
|
+
actorClerkId: actorId
|
|
28271
|
+
});
|
|
28272
|
+
if (invitationRevoked) {
|
|
28273
|
+
await revokePermitTenantMembershipRoles({
|
|
28274
|
+
userId,
|
|
28275
|
+
tenantKey: permitTenantKey
|
|
28276
|
+
});
|
|
28277
|
+
const existing = await client.query(mcApi2.identity.getMembershipForPrincipal, {
|
|
28278
|
+
principalId: userId,
|
|
28279
|
+
tenantId: tenant.tenantId,
|
|
28280
|
+
workspaceId: void 0
|
|
28281
|
+
});
|
|
28282
|
+
if (existing) {
|
|
28283
|
+
await client.mutation(mcApi2.identity.revokeMembership, {
|
|
28284
|
+
membershipId: existing._id,
|
|
28285
|
+
actorClerkId: actorId
|
|
28286
|
+
});
|
|
28287
|
+
}
|
|
28288
|
+
}
|
|
28289
|
+
}
|
|
28290
|
+
return successResponse(
|
|
28291
|
+
{
|
|
28292
|
+
acknowledged: true,
|
|
28293
|
+
eventType,
|
|
28294
|
+
tenantId: tenant.tenantId,
|
|
28295
|
+
principalId: userId,
|
|
28296
|
+
invitationId,
|
|
28297
|
+
userMatched: Boolean(userId),
|
|
28298
|
+
skipped: userId ? void 0 : "no_user_reference"
|
|
28299
|
+
},
|
|
28300
|
+
{
|
|
28301
|
+
correlationId: args.correlationId,
|
|
28302
|
+
policyTraceId: args.policyTraceId
|
|
28303
|
+
}
|
|
28304
|
+
);
|
|
28305
|
+
}
|
|
28306
|
+
if (!userId) {
|
|
28307
|
+
return webhookError(
|
|
28308
|
+
"INVALID_REQUEST",
|
|
28309
|
+
400,
|
|
28310
|
+
"Clerk membership webhook payload missing user id.",
|
|
28311
|
+
args.correlationId,
|
|
28312
|
+
args.policyTraceId
|
|
28313
|
+
);
|
|
28314
|
+
}
|
|
28315
|
+
await syncPermitUser({
|
|
28316
|
+
userId,
|
|
28317
|
+
email: readPrimaryEmail(asRecord26(data.public_user_data)),
|
|
28318
|
+
displayName: void 0,
|
|
28319
|
+
eventType,
|
|
28320
|
+
eventAt: eventTimestamp,
|
|
28321
|
+
actorId
|
|
28322
|
+
});
|
|
28323
|
+
await client.mutation(mcApi2.identity.upsertPrincipal, {
|
|
28324
|
+
principalId: userId,
|
|
28325
|
+
principalType: "user",
|
|
28326
|
+
clerkId: userId,
|
|
28327
|
+
actorClerkId: actorId,
|
|
28328
|
+
status: "active",
|
|
28329
|
+
metadata: buildWebhookMetadata({
|
|
28330
|
+
eventType,
|
|
28331
|
+
eventId,
|
|
28332
|
+
actorId,
|
|
28333
|
+
eventAt: eventTimestamp,
|
|
28334
|
+
extra: {
|
|
28335
|
+
sourceType: "organization_membership",
|
|
28336
|
+
organizationId: org.organizationId,
|
|
28337
|
+
organizationSlug: org.organizationSlug,
|
|
28338
|
+
membershipId: readString28(data.id),
|
|
28339
|
+
role,
|
|
28340
|
+
tenantId: tenant.tenantId
|
|
28341
|
+
}
|
|
28342
|
+
})
|
|
28343
|
+
});
|
|
28344
|
+
await client.mutation(mcApi2.identity.upsertPrincipalIdentityAlias, {
|
|
28345
|
+
principalId: userId,
|
|
28346
|
+
principalRefId: void 0,
|
|
28347
|
+
provider: "clerk",
|
|
28348
|
+
providerProjectId: void 0,
|
|
28349
|
+
externalSubjectId: userId,
|
|
28350
|
+
tenantId: tenant.tenantId,
|
|
28351
|
+
email: readPrimaryEmail(asRecord26(data.public_user_data)),
|
|
28352
|
+
metadata: buildWebhookMetadata({
|
|
28353
|
+
eventType,
|
|
28354
|
+
eventId,
|
|
28355
|
+
actorId,
|
|
28356
|
+
eventAt: eventTimestamp,
|
|
28357
|
+
extra: {
|
|
28358
|
+
sourceType: "organization_membership",
|
|
28359
|
+
organizationId: org.organizationId,
|
|
28360
|
+
organizationSlug: org.organizationSlug,
|
|
28361
|
+
membershipId: readString28(data.id),
|
|
28362
|
+
role,
|
|
28363
|
+
tenantId: tenant.tenantId,
|
|
28364
|
+
organizationEventType: eventType
|
|
28365
|
+
}
|
|
28366
|
+
}),
|
|
28367
|
+
actorClerkId: actorId
|
|
28368
|
+
});
|
|
28369
|
+
if (eventType === "organizationMembership.deleted") {
|
|
28370
|
+
await revokePermitTenantMembershipRoles({
|
|
28371
|
+
userId,
|
|
28372
|
+
tenantKey: permitTenantKey
|
|
28373
|
+
});
|
|
28374
|
+
const existing = await client.query(mcApi2.identity.getMembershipForPrincipal, {
|
|
28375
|
+
principalId: userId,
|
|
28376
|
+
tenantId: tenant.tenantId,
|
|
28377
|
+
workspaceId: void 0
|
|
28378
|
+
});
|
|
28379
|
+
if (!existing) {
|
|
28380
|
+
return successResponse(
|
|
28381
|
+
{
|
|
28382
|
+
acknowledged: true,
|
|
28383
|
+
eventType,
|
|
28384
|
+
principalId: userId,
|
|
28385
|
+
tenantId: tenant.tenantId,
|
|
28386
|
+
skipped: "membership_not_found"
|
|
28387
|
+
},
|
|
28388
|
+
{
|
|
28389
|
+
correlationId: args.correlationId,
|
|
28390
|
+
policyTraceId: args.policyTraceId
|
|
28391
|
+
}
|
|
28392
|
+
);
|
|
28393
|
+
}
|
|
28394
|
+
const revoked = await client.mutation(mcApi2.identity.revokeMembership, {
|
|
28395
|
+
membershipId: existing._id,
|
|
28396
|
+
actorClerkId: actorId
|
|
28397
|
+
});
|
|
28398
|
+
return successResponse(
|
|
28399
|
+
{
|
|
28400
|
+
acknowledged: true,
|
|
28401
|
+
eventType,
|
|
28402
|
+
tenantId: tenant.tenantId,
|
|
28403
|
+
principalId: userId,
|
|
28404
|
+
revoked
|
|
28405
|
+
},
|
|
28406
|
+
{
|
|
28407
|
+
correlationId: args.correlationId,
|
|
28408
|
+
policyTraceId: args.policyTraceId
|
|
28409
|
+
}
|
|
28410
|
+
);
|
|
28411
|
+
}
|
|
28412
|
+
const membership = await client.mutation(mcApi2.identity.upsertMembership, {
|
|
28413
|
+
principalId: userId,
|
|
28414
|
+
principalRefId: void 0,
|
|
28415
|
+
tenantId: tenant.tenantId,
|
|
28416
|
+
role,
|
|
28417
|
+
source: "api",
|
|
28418
|
+
actorClerkId: actorId
|
|
28419
|
+
});
|
|
28420
|
+
await upsertPermitTenantMembershipRole({
|
|
28421
|
+
userId,
|
|
28422
|
+
tenantKey: permitTenantKey,
|
|
28423
|
+
role
|
|
28424
|
+
});
|
|
28425
|
+
return successResponse(
|
|
28426
|
+
{
|
|
28427
|
+
acknowledged: true,
|
|
28428
|
+
eventType,
|
|
28429
|
+
tenantId: tenant.tenantId,
|
|
28430
|
+
principalId: userId,
|
|
28431
|
+
membership
|
|
28432
|
+
},
|
|
28433
|
+
{
|
|
28434
|
+
correlationId: args.correlationId,
|
|
28435
|
+
policyTraceId: args.policyTraceId
|
|
28436
|
+
}
|
|
28437
|
+
);
|
|
28438
|
+
}
|
|
28439
|
+
return successResponse(
|
|
28440
|
+
{
|
|
28441
|
+
acknowledged: true,
|
|
28442
|
+
eventType,
|
|
28443
|
+
reason: "Unsupported Clerk event type"
|
|
28444
|
+
},
|
|
28445
|
+
{
|
|
28446
|
+
correlationId: args.correlationId,
|
|
28447
|
+
policyTraceId: args.policyTraceId
|
|
28448
|
+
}
|
|
28449
|
+
);
|
|
28450
|
+
} catch (error) {
|
|
28451
|
+
return handleClerkWebhookError(error, args.correlationId, args.policyTraceId);
|
|
28452
|
+
}
|
|
28453
|
+
}
|
|
27205
28454
|
|
|
27206
28455
|
// ../../apps/gateway/src/routes/questions.ts
|
|
27207
|
-
function
|
|
28456
|
+
function asRecord27(value) {
|
|
27208
28457
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
27209
28458
|
}
|
|
27210
|
-
function
|
|
28459
|
+
function readString29(value) {
|
|
27211
28460
|
if (typeof value !== "string") {
|
|
27212
28461
|
return void 0;
|
|
27213
28462
|
}
|
|
27214
28463
|
const normalized = value.trim();
|
|
27215
28464
|
return normalized.length > 0 ? normalized : void 0;
|
|
27216
28465
|
}
|
|
27217
|
-
function
|
|
28466
|
+
function readNumber19(value) {
|
|
27218
28467
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
27219
28468
|
}
|
|
27220
28469
|
function readStringArray14(value) {
|
|
27221
28470
|
if (!Array.isArray(value)) {
|
|
27222
28471
|
return void 0;
|
|
27223
28472
|
}
|
|
27224
|
-
const items = value.map((entry) =>
|
|
28473
|
+
const items = value.map((entry) => readString29(entry)).filter((entry) => Boolean(entry));
|
|
27225
28474
|
return items.length > 0 ? items : void 0;
|
|
27226
28475
|
}
|
|
27227
28476
|
async function handleQuestionCreate(args) {
|
|
27228
28477
|
try {
|
|
27229
|
-
const body =
|
|
28478
|
+
const body = asRecord27(args.body);
|
|
27230
28479
|
const payload = await createQuestionFromGatewayAuth(args.authContext, {
|
|
27231
|
-
topicId:
|
|
27232
|
-
text:
|
|
27233
|
-
priority:
|
|
27234
|
-
linkedBeliefId:
|
|
27235
|
-
metadata:
|
|
28480
|
+
topicId: readString29(body.topicId),
|
|
28481
|
+
text: readString29(body.text) ?? "",
|
|
28482
|
+
priority: readString29(body.priority),
|
|
28483
|
+
linkedBeliefId: readString29(body.linkedBeliefId),
|
|
28484
|
+
metadata: asRecord27(body.metadata)
|
|
27236
28485
|
});
|
|
27237
28486
|
return successResponse(payload, {
|
|
27238
28487
|
status: 201,
|
|
@@ -27279,10 +28528,10 @@ async function handleQuestionGet(args) {
|
|
|
27279
28528
|
}
|
|
27280
28529
|
async function handleQuestionArchive(args) {
|
|
27281
28530
|
try {
|
|
27282
|
-
const body =
|
|
28531
|
+
const body = asRecord27(args.body);
|
|
27283
28532
|
const payload = await archiveQuestionFromGatewayAuth(args.authContext, {
|
|
27284
28533
|
id: args.questionId,
|
|
27285
|
-
rationale:
|
|
28534
|
+
rationale: readString29(body.reason) ?? readString29(body.rationale)
|
|
27286
28535
|
});
|
|
27287
28536
|
return successResponse(payload, {
|
|
27288
28537
|
correlationId: args.correlationId,
|
|
@@ -27325,13 +28574,13 @@ async function handleQuestionList(args) {
|
|
|
27325
28574
|
}
|
|
27326
28575
|
async function handleQuestionAnswer(args) {
|
|
27327
28576
|
try {
|
|
27328
|
-
const body =
|
|
28577
|
+
const body = asRecord27(args.body);
|
|
27329
28578
|
const payload = await answerQuestionFromGatewayAuth(args.authContext, {
|
|
27330
28579
|
id: args.questionId,
|
|
27331
|
-
text:
|
|
27332
|
-
confidence:
|
|
28580
|
+
text: readString29(body.text) ?? "",
|
|
28581
|
+
confidence: readString29(body.confidence),
|
|
27333
28582
|
evidenceIds: readStringArray14(body.evidenceIds),
|
|
27334
|
-
rationale:
|
|
28583
|
+
rationale: readString29(body.rationale)
|
|
27335
28584
|
});
|
|
27336
28585
|
return successResponse(payload, {
|
|
27337
28586
|
correlationId: args.correlationId,
|
|
@@ -27377,11 +28626,11 @@ async function handleQuestionGetAnswer(args) {
|
|
|
27377
28626
|
}
|
|
27378
28627
|
async function handleQuestionRefine(args) {
|
|
27379
28628
|
try {
|
|
27380
|
-
const body =
|
|
28629
|
+
const body = asRecord27(args.body);
|
|
27381
28630
|
const payload = await refineQuestionFromGatewayAuth(args.authContext, {
|
|
27382
28631
|
id: args.questionId,
|
|
27383
|
-
text:
|
|
27384
|
-
rationale:
|
|
28632
|
+
text: readString29(body.text) ?? "",
|
|
28633
|
+
rationale: readString29(body.rationale)
|
|
27385
28634
|
});
|
|
27386
28635
|
return successResponse(payload, {
|
|
27387
28636
|
correlationId: args.correlationId,
|
|
@@ -27403,11 +28652,11 @@ async function handleQuestionRefine(args) {
|
|
|
27403
28652
|
}
|
|
27404
28653
|
async function handleQuestionUpdateStatus(args) {
|
|
27405
28654
|
try {
|
|
27406
|
-
const body =
|
|
28655
|
+
const body = asRecord27(args.body);
|
|
27407
28656
|
const payload = await updateQuestionStatusFromGatewayAuth(args.authContext, {
|
|
27408
28657
|
id: args.questionId,
|
|
27409
|
-
status:
|
|
27410
|
-
rationale:
|
|
28658
|
+
status: readString29(body.status) ?? "",
|
|
28659
|
+
rationale: readString29(body.rationale)
|
|
27411
28660
|
});
|
|
27412
28661
|
return successResponse(payload, {
|
|
27413
28662
|
correlationId: args.correlationId,
|
|
@@ -27432,19 +28681,19 @@ async function handleQuestionUpdateStatus(args) {
|
|
|
27432
28681
|
}
|
|
27433
28682
|
async function handleQuestionBatchCreate(args) {
|
|
27434
28683
|
try {
|
|
27435
|
-
const body =
|
|
27436
|
-
const questions = Array.isArray(body.questions) ? body.questions.map((entry) =>
|
|
27437
|
-
question:
|
|
27438
|
-
category:
|
|
27439
|
-
priority:
|
|
27440
|
-
linkedBeliefNodeId:
|
|
27441
|
-
linkedWorktreeId:
|
|
27442
|
-
testType:
|
|
28684
|
+
const body = asRecord27(args.body);
|
|
28685
|
+
const questions = Array.isArray(body.questions) ? body.questions.map((entry) => asRecord27(entry)).map((entry) => ({
|
|
28686
|
+
question: readString29(entry.question) ?? readString29(entry.text) ?? "",
|
|
28687
|
+
category: readString29(entry.category),
|
|
28688
|
+
priority: readString29(entry.priority),
|
|
28689
|
+
linkedBeliefNodeId: readString29(entry.linkedBeliefNodeId) ?? readString29(entry.linkedBeliefId),
|
|
28690
|
+
linkedWorktreeId: readString29(entry.linkedWorktreeId),
|
|
28691
|
+
testType: readString29(entry.testType)
|
|
27443
28692
|
})) : [];
|
|
27444
28693
|
const payload = await createQuestionsBatchFromGatewayAuth(args.authContext, {
|
|
27445
|
-
topicId:
|
|
28694
|
+
topicId: readString29(body.topicId),
|
|
27446
28695
|
questions,
|
|
27447
|
-
source:
|
|
28696
|
+
source: readString29(body.source)
|
|
27448
28697
|
});
|
|
27449
28698
|
return successResponse(payload, {
|
|
27450
28699
|
status: 201,
|
|
@@ -27470,20 +28719,20 @@ async function handleQuestionBatchCreate(args) {
|
|
|
27470
28719
|
}
|
|
27471
28720
|
async function handleQuestionAdd(args) {
|
|
27472
28721
|
try {
|
|
27473
|
-
const body =
|
|
28722
|
+
const body = asRecord27(args.body);
|
|
27474
28723
|
const payload = await addQuestionFromGatewayAuth(args.authContext, {
|
|
27475
|
-
topicId:
|
|
27476
|
-
question:
|
|
27477
|
-
category:
|
|
27478
|
-
priority:
|
|
27479
|
-
source:
|
|
27480
|
-
beliefId:
|
|
27481
|
-
linkedWorktreeId:
|
|
27482
|
-
chatId:
|
|
27483
|
-
importance:
|
|
27484
|
-
epistemicUnlock:
|
|
27485
|
-
metadata:
|
|
27486
|
-
questionType:
|
|
28724
|
+
topicId: readString29(body.topicId),
|
|
28725
|
+
question: readString29(body.question) ?? readString29(body.text),
|
|
28726
|
+
category: readString29(body.category),
|
|
28727
|
+
priority: readString29(body.priority),
|
|
28728
|
+
source: readString29(body.source),
|
|
28729
|
+
beliefId: readString29(body.beliefId) ?? readString29(body.linkedBeliefId),
|
|
28730
|
+
linkedWorktreeId: readString29(body.linkedWorktreeId),
|
|
28731
|
+
chatId: readString29(body.chatId),
|
|
28732
|
+
importance: readNumber19(body.importance),
|
|
28733
|
+
epistemicUnlock: readString29(body.epistemicUnlock),
|
|
28734
|
+
metadata: asRecord27(body.metadata),
|
|
28735
|
+
questionType: readString29(body.questionType)
|
|
27487
28736
|
});
|
|
27488
28737
|
return successResponse(payload, {
|
|
27489
28738
|
status: 201,
|
|
@@ -27506,12 +28755,12 @@ async function handleQuestionAdd(args) {
|
|
|
27506
28755
|
}
|
|
27507
28756
|
async function handleQuestionUpdatePriority(args) {
|
|
27508
28757
|
try {
|
|
27509
|
-
const body =
|
|
28758
|
+
const body = asRecord27(args.body);
|
|
27510
28759
|
const payload = await updateQuestionPriorityFromGatewayAuth(
|
|
27511
28760
|
args.authContext,
|
|
27512
28761
|
{
|
|
27513
|
-
id:
|
|
27514
|
-
priority:
|
|
28762
|
+
id: readString29(body.id) ?? readString29(body.nodeId) ?? readString29(body.questionId),
|
|
28763
|
+
priority: readString29(body.priority) ?? "medium"
|
|
27515
28764
|
}
|
|
27516
28765
|
);
|
|
27517
28766
|
return successResponse(payload, {
|
|
@@ -27537,12 +28786,12 @@ async function handleQuestionUpdatePriority(args) {
|
|
|
27537
28786
|
}
|
|
27538
28787
|
async function handleQuestionAdvanceToConviction(args) {
|
|
27539
28788
|
try {
|
|
27540
|
-
const body =
|
|
28789
|
+
const body = asRecord27(args.body);
|
|
27541
28790
|
const payload = await advanceQuestionToConvictionFromGatewayAuth(
|
|
27542
28791
|
args.authContext,
|
|
27543
28792
|
{
|
|
27544
|
-
questionId:
|
|
27545
|
-
worktreeId:
|
|
28793
|
+
questionId: readString29(body.questionId) ?? readString29(body.id) ?? readString29(body.nodeId),
|
|
28794
|
+
worktreeId: readString29(body.worktreeId)
|
|
27546
28795
|
}
|
|
27547
28796
|
);
|
|
27548
28797
|
return successResponse(payload, {
|
|
@@ -27568,14 +28817,14 @@ async function handleQuestionAdvanceToConviction(args) {
|
|
|
27568
28817
|
}
|
|
27569
28818
|
async function handleQuestionUpdateConviction(args) {
|
|
27570
28819
|
try {
|
|
27571
|
-
const body =
|
|
28820
|
+
const body = asRecord27(args.body);
|
|
27572
28821
|
const payload = await updateQuestionConvictionFromGatewayAuth(
|
|
27573
28822
|
args.authContext,
|
|
27574
28823
|
{
|
|
27575
|
-
questionId:
|
|
27576
|
-
conviction:
|
|
27577
|
-
answerCompleteness:
|
|
27578
|
-
convictionRationale:
|
|
28824
|
+
questionId: readString29(body.questionId) ?? readString29(body.id) ?? readString29(body.nodeId),
|
|
28825
|
+
conviction: readNumber19(body.conviction),
|
|
28826
|
+
answerCompleteness: readString29(body.answerCompleteness),
|
|
28827
|
+
convictionRationale: readString29(body.convictionRationale)
|
|
27579
28828
|
}
|
|
27580
28829
|
);
|
|
27581
28830
|
return successResponse(payload, {
|
|
@@ -27601,16 +28850,16 @@ async function handleQuestionUpdateConviction(args) {
|
|
|
27601
28850
|
}
|
|
27602
28851
|
async function handleQuestionFinalizeConviction(args) {
|
|
27603
28852
|
try {
|
|
27604
|
-
const body =
|
|
28853
|
+
const body = asRecord27(args.body);
|
|
27605
28854
|
const payload = await finalizeQuestionConvictionFromGatewayAuth(
|
|
27606
28855
|
args.authContext,
|
|
27607
28856
|
{
|
|
27608
|
-
questionId:
|
|
27609
|
-
conviction:
|
|
27610
|
-
answer:
|
|
27611
|
-
convictionRationale:
|
|
27612
|
-
answerCompleteness:
|
|
27613
|
-
whatWeNeed:
|
|
28857
|
+
questionId: readString29(body.questionId) ?? readString29(body.id) ?? readString29(body.nodeId),
|
|
28858
|
+
conviction: readNumber19(body.conviction) ?? Number.NaN,
|
|
28859
|
+
answer: readString29(body.answer) ?? "",
|
|
28860
|
+
convictionRationale: readString29(body.convictionRationale),
|
|
28861
|
+
answerCompleteness: readString29(body.answerCompleteness),
|
|
28862
|
+
whatWeNeed: readString29(body.whatWeNeed)
|
|
27614
28863
|
}
|
|
27615
28864
|
);
|
|
27616
28865
|
return successResponse(payload, {
|
|
@@ -27636,12 +28885,12 @@ async function handleQuestionFinalizeConviction(args) {
|
|
|
27636
28885
|
}
|
|
27637
28886
|
async function handleQuestionUpdate(args) {
|
|
27638
28887
|
try {
|
|
27639
|
-
const body =
|
|
28888
|
+
const body = asRecord27(args.body);
|
|
27640
28889
|
const payload = await updateQuestionFromGatewayAuth(args.authContext, {
|
|
27641
|
-
questionId:
|
|
27642
|
-
question:
|
|
27643
|
-
category:
|
|
27644
|
-
priority:
|
|
28890
|
+
questionId: readString29(body.questionId) ?? readString29(body.id) ?? readString29(body.nodeId),
|
|
28891
|
+
question: readString29(body.question) ?? readString29(body.text),
|
|
28892
|
+
category: readString29(body.category),
|
|
28893
|
+
priority: readString29(body.priority)
|
|
27645
28894
|
});
|
|
27646
28895
|
return successResponse(payload, {
|
|
27647
28896
|
correlationId: args.correlationId,
|
|
@@ -27663,9 +28912,9 @@ async function handleQuestionUpdate(args) {
|
|
|
27663
28912
|
}
|
|
27664
28913
|
async function handleQuestionDelete(args) {
|
|
27665
28914
|
try {
|
|
27666
|
-
const body =
|
|
28915
|
+
const body = asRecord27(args.body);
|
|
27667
28916
|
const payload = await deleteQuestionFromGatewayAuth(args.authContext, {
|
|
27668
|
-
questionId:
|
|
28917
|
+
questionId: readString29(body.questionId) ?? readString29(body.id) ?? readString29(body.nodeId)
|
|
27669
28918
|
});
|
|
27670
28919
|
return successResponse(payload, {
|
|
27671
28920
|
correlationId: args.correlationId,
|
|
@@ -27687,30 +28936,30 @@ async function handleQuestionDelete(args) {
|
|
|
27687
28936
|
}
|
|
27688
28937
|
|
|
27689
28938
|
// ../../apps/gateway/src/routes/search.ts
|
|
27690
|
-
function
|
|
28939
|
+
function asRecord28(value) {
|
|
27691
28940
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
27692
28941
|
}
|
|
27693
|
-
function
|
|
28942
|
+
function readString30(value) {
|
|
27694
28943
|
if (typeof value !== "string") {
|
|
27695
28944
|
return void 0;
|
|
27696
28945
|
}
|
|
27697
28946
|
const normalized = value.trim();
|
|
27698
28947
|
return normalized.length > 0 ? normalized : void 0;
|
|
27699
28948
|
}
|
|
27700
|
-
function
|
|
28949
|
+
function readNumber20(value) {
|
|
27701
28950
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
27702
28951
|
}
|
|
27703
28952
|
function readStringArray15(value) {
|
|
27704
28953
|
if (!Array.isArray(value)) {
|
|
27705
28954
|
return void 0;
|
|
27706
28955
|
}
|
|
27707
|
-
const items = value.map((entry) =>
|
|
28956
|
+
const items = value.map((entry) => readString30(entry)).filter((entry) => Boolean(entry));
|
|
27708
28957
|
return items.length > 0 ? items : void 0;
|
|
27709
28958
|
}
|
|
27710
28959
|
async function handleSearchResources(args) {
|
|
27711
|
-
const body =
|
|
27712
|
-
const q =
|
|
27713
|
-
const topicId =
|
|
28960
|
+
const body = asRecord28(args.body);
|
|
28961
|
+
const q = readString30(body.q) ?? readString30(body.query);
|
|
28962
|
+
const topicId = readString30(body.topicId) ?? readString30(body.projectId);
|
|
27714
28963
|
if (!q) {
|
|
27715
28964
|
return errorResponse({
|
|
27716
28965
|
code: "INVALID_REQUEST",
|
|
@@ -27734,10 +28983,10 @@ async function handleSearchResources(args) {
|
|
|
27734
28983
|
q,
|
|
27735
28984
|
topicId,
|
|
27736
28985
|
types: readStringArray15(body.types),
|
|
27737
|
-
status:
|
|
27738
|
-
minConfidence:
|
|
27739
|
-
limit:
|
|
27740
|
-
cursor:
|
|
28986
|
+
status: readString30(body.status),
|
|
28987
|
+
minConfidence: readNumber20(body.minConfidence),
|
|
28988
|
+
limit: readNumber20(body.limit),
|
|
28989
|
+
cursor: readString30(body.cursor)
|
|
27741
28990
|
});
|
|
27742
28991
|
return successResponse(payload, {
|
|
27743
28992
|
correlationId: args.correlationId,
|
|
@@ -27759,17 +29008,17 @@ async function handleSearchResources(args) {
|
|
|
27759
29008
|
}
|
|
27760
29009
|
|
|
27761
29010
|
// ../../apps/gateway/src/routes/sources.ts
|
|
27762
|
-
function
|
|
29011
|
+
function asRecord29(value) {
|
|
27763
29012
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
27764
29013
|
}
|
|
27765
|
-
function
|
|
29014
|
+
function readString31(value) {
|
|
27766
29015
|
if (typeof value !== "string") {
|
|
27767
29016
|
return void 0;
|
|
27768
29017
|
}
|
|
27769
29018
|
const normalized = value.trim();
|
|
27770
29019
|
return normalized.length > 0 ? normalized : void 0;
|
|
27771
29020
|
}
|
|
27772
|
-
function
|
|
29021
|
+
function readNumber21(value) {
|
|
27773
29022
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
27774
29023
|
}
|
|
27775
29024
|
function handleSourcesError(error, fallbackMessage, correlationId, policyTraceId) {
|
|
@@ -27787,15 +29036,15 @@ function handleSourcesError(error, fallbackMessage, correlationId, policyTraceId
|
|
|
27787
29036
|
}
|
|
27788
29037
|
async function handleSourceUpsert(args) {
|
|
27789
29038
|
try {
|
|
27790
|
-
const body =
|
|
29039
|
+
const body = asRecord29(args.body);
|
|
27791
29040
|
const payload = await upsertSourceFromGatewayAuth(args.authContext, {
|
|
27792
|
-
url:
|
|
27793
|
-
sha:
|
|
27794
|
-
kind:
|
|
27795
|
-
title:
|
|
27796
|
-
capturedAt:
|
|
27797
|
-
topicId:
|
|
27798
|
-
metadata:
|
|
29041
|
+
url: readString31(body.url),
|
|
29042
|
+
sha: readString31(body.sha),
|
|
29043
|
+
kind: readString31(body.kind) ?? "",
|
|
29044
|
+
title: readString31(body.title),
|
|
29045
|
+
capturedAt: readNumber21(body.capturedAt),
|
|
29046
|
+
topicId: readString31(body.topicId),
|
|
29047
|
+
metadata: asRecord29(body.metadata)
|
|
27799
29048
|
});
|
|
27800
29049
|
return successResponse(payload, {
|
|
27801
29050
|
status: 201,
|
|
@@ -27829,10 +29078,10 @@ async function handleSourceGet(args) {
|
|
|
27829
29078
|
}
|
|
27830
29079
|
|
|
27831
29080
|
// ../../apps/gateway/src/routes/tasks.ts
|
|
27832
|
-
function
|
|
29081
|
+
function asRecord30(value) {
|
|
27833
29082
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
27834
29083
|
}
|
|
27835
|
-
function
|
|
29084
|
+
function readString32(value) {
|
|
27836
29085
|
if (typeof value !== "string") {
|
|
27837
29086
|
return void 0;
|
|
27838
29087
|
}
|
|
@@ -27854,18 +29103,18 @@ function handleTasksError(error, fallbackMessage, correlationId, policyTraceId)
|
|
|
27854
29103
|
}
|
|
27855
29104
|
async function handleTaskCreate(args) {
|
|
27856
29105
|
try {
|
|
27857
|
-
const body =
|
|
29106
|
+
const body = asRecord30(args.body);
|
|
27858
29107
|
const payload = await createTaskFromGatewayAuth(args.authContext, {
|
|
27859
|
-
topicId:
|
|
27860
|
-
title:
|
|
27861
|
-
description:
|
|
27862
|
-
taskType:
|
|
27863
|
-
priority:
|
|
27864
|
-
status:
|
|
27865
|
-
linkedBeliefId:
|
|
27866
|
-
linkedQuestionId:
|
|
27867
|
-
linkedWorktreeId:
|
|
27868
|
-
tags: Array.isArray(body.tags) ? body.tags.map((entry) =>
|
|
29108
|
+
topicId: readString32(body.topicId),
|
|
29109
|
+
title: readString32(body.title) ?? "",
|
|
29110
|
+
description: readString32(body.description),
|
|
29111
|
+
taskType: readString32(body.taskType),
|
|
29112
|
+
priority: readString32(body.priority),
|
|
29113
|
+
status: readString32(body.status),
|
|
29114
|
+
linkedBeliefId: readString32(body.linkedBeliefId),
|
|
29115
|
+
linkedQuestionId: readString32(body.linkedQuestionId),
|
|
29116
|
+
linkedWorktreeId: readString32(body.linkedWorktreeId),
|
|
29117
|
+
tags: Array.isArray(body.tags) ? body.tags.map((entry) => readString32(entry)).filter((entry) => Boolean(entry)) : void 0,
|
|
27869
29118
|
metadata: body.metadata && typeof body.metadata === "object" && !Array.isArray(body.metadata) ? body.metadata : void 0
|
|
27870
29119
|
});
|
|
27871
29120
|
return successResponse(payload, {
|
|
@@ -27900,16 +29149,16 @@ async function handleTaskList(args) {
|
|
|
27900
29149
|
}
|
|
27901
29150
|
async function handleTaskUpdate(args) {
|
|
27902
29151
|
try {
|
|
27903
|
-
const body =
|
|
29152
|
+
const body = asRecord30(args.body);
|
|
27904
29153
|
const payload = await updateTaskFromGatewayAuth(args.authContext, {
|
|
27905
29154
|
id: args.taskId,
|
|
27906
|
-
title:
|
|
27907
|
-
description:
|
|
27908
|
-
priority:
|
|
27909
|
-
status:
|
|
27910
|
-
linkedBeliefId:
|
|
27911
|
-
linkedQuestionId:
|
|
27912
|
-
linkedWorktreeId:
|
|
29155
|
+
title: readString32(body.title),
|
|
29156
|
+
description: readString32(body.description),
|
|
29157
|
+
priority: readString32(body.priority),
|
|
29158
|
+
status: readString32(body.status),
|
|
29159
|
+
linkedBeliefId: readString32(body.linkedBeliefId),
|
|
29160
|
+
linkedQuestionId: readString32(body.linkedQuestionId),
|
|
29161
|
+
linkedWorktreeId: readString32(body.linkedWorktreeId),
|
|
27913
29162
|
metadata: body.metadata && typeof body.metadata === "object" && !Array.isArray(body.metadata) ? body.metadata : void 0
|
|
27914
29163
|
});
|
|
27915
29164
|
return successResponse(payload, {
|
|
@@ -27927,10 +29176,10 @@ async function handleTaskUpdate(args) {
|
|
|
27927
29176
|
}
|
|
27928
29177
|
async function handleTaskComplete(args) {
|
|
27929
29178
|
try {
|
|
27930
|
-
const body =
|
|
29179
|
+
const body = asRecord30(args.body);
|
|
27931
29180
|
const payload = await completeTaskFromGatewayAuth(args.authContext, {
|
|
27932
29181
|
id: args.taskId,
|
|
27933
|
-
outputSummary:
|
|
29182
|
+
outputSummary: readString32(body.outputSummary)
|
|
27934
29183
|
});
|
|
27935
29184
|
return successResponse(payload, {
|
|
27936
29185
|
correlationId: args.correlationId,
|
|
@@ -27947,10 +29196,10 @@ async function handleTaskComplete(args) {
|
|
|
27947
29196
|
}
|
|
27948
29197
|
|
|
27949
29198
|
// ../../apps/gateway/src/routes/topics.ts
|
|
27950
|
-
function
|
|
29199
|
+
function asRecord31(value) {
|
|
27951
29200
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
27952
29201
|
}
|
|
27953
|
-
function
|
|
29202
|
+
function readString33(value) {
|
|
27954
29203
|
if (typeof value !== "string") {
|
|
27955
29204
|
return void 0;
|
|
27956
29205
|
}
|
|
@@ -27960,14 +29209,14 @@ function readString32(value) {
|
|
|
27960
29209
|
function readBoolean(value) {
|
|
27961
29210
|
return typeof value === "boolean" ? value : void 0;
|
|
27962
29211
|
}
|
|
27963
|
-
function
|
|
29212
|
+
function readNumber22(value) {
|
|
27964
29213
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
27965
29214
|
}
|
|
27966
29215
|
function readStringArray16(value) {
|
|
27967
29216
|
if (!Array.isArray(value)) {
|
|
27968
29217
|
return void 0;
|
|
27969
29218
|
}
|
|
27970
|
-
const items = value.map((entry) =>
|
|
29219
|
+
const items = value.map((entry) => readString33(entry)).filter((entry) => Boolean(entry));
|
|
27971
29220
|
return items.length > 0 ? items : void 0;
|
|
27972
29221
|
}
|
|
27973
29222
|
function handleTopicsError(error, fallbackMessage, correlationId, policyTraceId) {
|
|
@@ -27985,17 +29234,17 @@ function handleTopicsError(error, fallbackMessage, correlationId, policyTraceId)
|
|
|
27985
29234
|
}
|
|
27986
29235
|
async function handleTopicCreate(args) {
|
|
27987
29236
|
try {
|
|
27988
|
-
const body =
|
|
29237
|
+
const body = asRecord31(args.body);
|
|
27989
29238
|
const payload = await createTopicFromGatewayAuth(args.authContext, {
|
|
27990
|
-
name:
|
|
27991
|
-
description:
|
|
27992
|
-
type:
|
|
27993
|
-
parentTopicId:
|
|
27994
|
-
ontologyId:
|
|
27995
|
-
tenantId:
|
|
27996
|
-
workspaceId:
|
|
27997
|
-
visibility:
|
|
27998
|
-
createdBy:
|
|
29239
|
+
name: readString33(body.name) ?? "",
|
|
29240
|
+
description: readString33(body.description),
|
|
29241
|
+
type: readString33(body.type),
|
|
29242
|
+
parentTopicId: readString33(body.parentTopicId),
|
|
29243
|
+
ontologyId: readString33(body.ontologyId),
|
|
29244
|
+
tenantId: readString33(body.tenantId),
|
|
29245
|
+
workspaceId: readString33(body.workspaceId),
|
|
29246
|
+
visibility: readString33(body.visibility),
|
|
29247
|
+
createdBy: readString33(body.createdBy)
|
|
27999
29248
|
});
|
|
28000
29249
|
return successResponse(payload, {
|
|
28001
29250
|
status: 201,
|
|
@@ -28013,16 +29262,16 @@ async function handleTopicCreate(args) {
|
|
|
28013
29262
|
}
|
|
28014
29263
|
async function handleTopicUpdate(args) {
|
|
28015
29264
|
try {
|
|
28016
|
-
const body =
|
|
29265
|
+
const body = asRecord31(args.body);
|
|
28017
29266
|
const payload = await updateTopicFromGatewayAuth(args.authContext, {
|
|
28018
29267
|
id: args.topicId,
|
|
28019
|
-
name:
|
|
28020
|
-
description:
|
|
28021
|
-
type:
|
|
28022
|
-
ontologyId:
|
|
29268
|
+
name: readString33(body.name),
|
|
29269
|
+
description: readString33(body.description),
|
|
29270
|
+
type: readString33(body.type),
|
|
29271
|
+
ontologyId: readString33(body.ontologyId),
|
|
28023
29272
|
clearOntologyId: readBoolean(body.clearOntologyId),
|
|
28024
|
-
status:
|
|
28025
|
-
visibility:
|
|
29273
|
+
status: readString33(body.status),
|
|
29274
|
+
visibility: readString33(body.visibility)
|
|
28026
29275
|
});
|
|
28027
29276
|
return successResponse(payload, {
|
|
28028
29277
|
correlationId: args.correlationId,
|
|
@@ -28073,7 +29322,7 @@ async function handleTopicTree(args) {
|
|
|
28073
29322
|
try {
|
|
28074
29323
|
const payload = await getTopicTreeFromGatewayAuth(args.authContext, {
|
|
28075
29324
|
id: args.topicId,
|
|
28076
|
-
maxDepth:
|
|
29325
|
+
maxDepth: readNumber22(args.query.maxDepth)
|
|
28077
29326
|
});
|
|
28078
29327
|
return successResponse(payload, {
|
|
28079
29328
|
correlationId: args.correlationId,
|
|
@@ -28093,7 +29342,7 @@ async function handleTopicCoverage(args) {
|
|
|
28093
29342
|
const payload = await getTopicCoverageFromGatewayAuth(args.authContext, {
|
|
28094
29343
|
id: args.topicId,
|
|
28095
29344
|
includeDescendants: typeof args.query.includeDescendants === "boolean" ? args.query.includeDescendants : void 0,
|
|
28096
|
-
maxDepth:
|
|
29345
|
+
maxDepth: readNumber22(args.query.maxDepth)
|
|
28097
29346
|
});
|
|
28098
29347
|
return successResponse(payload, {
|
|
28099
29348
|
correlationId: args.correlationId,
|
|
@@ -28110,9 +29359,9 @@ async function handleTopicCoverage(args) {
|
|
|
28110
29359
|
}
|
|
28111
29360
|
async function handleTopicRemove(args) {
|
|
28112
29361
|
try {
|
|
28113
|
-
const body =
|
|
29362
|
+
const body = asRecord31(args.body);
|
|
28114
29363
|
const payload = await removeTopicFromGatewayAuth(args.authContext, {
|
|
28115
|
-
id:
|
|
29364
|
+
id: readString33(body.id) ?? readString33(body.topicId) ?? ""
|
|
28116
29365
|
});
|
|
28117
29366
|
return successResponse(payload, {
|
|
28118
29367
|
correlationId: args.correlationId,
|
|
@@ -28129,22 +29378,22 @@ async function handleTopicRemove(args) {
|
|
|
28129
29378
|
}
|
|
28130
29379
|
async function handleTopicBulkCreate(args) {
|
|
28131
29380
|
try {
|
|
28132
|
-
const body =
|
|
28133
|
-
const topics2 = Array.isArray(body.topics) ? body.topics.map((entry) =>
|
|
28134
|
-
globalId:
|
|
28135
|
-
name:
|
|
28136
|
-
description:
|
|
28137
|
-
type:
|
|
28138
|
-
parentTopicId:
|
|
28139
|
-
depth:
|
|
29381
|
+
const body = asRecord31(args.body);
|
|
29382
|
+
const topics2 = Array.isArray(body.topics) ? body.topics.map((entry) => asRecord31(entry)).map((entry) => ({
|
|
29383
|
+
globalId: readString33(entry.globalId) ?? "",
|
|
29384
|
+
name: readString33(entry.name) ?? "",
|
|
29385
|
+
description: readString33(entry.description),
|
|
29386
|
+
type: readString33(entry.type) ?? "theme",
|
|
29387
|
+
parentTopicId: readString33(entry.parentTopicId),
|
|
29388
|
+
depth: readNumber22(entry.depth) ?? 0,
|
|
28140
29389
|
path: readStringArray16(entry.path) ?? [],
|
|
28141
|
-
tenantId:
|
|
28142
|
-
workspaceId:
|
|
28143
|
-
graphScopeProjectId:
|
|
28144
|
-
status:
|
|
28145
|
-
visibility:
|
|
28146
|
-
metadata:
|
|
28147
|
-
createdBy:
|
|
29390
|
+
tenantId: readString33(entry.tenantId),
|
|
29391
|
+
workspaceId: readString33(entry.workspaceId),
|
|
29392
|
+
graphScopeProjectId: readString33(entry.graphScopeProjectId),
|
|
29393
|
+
status: readString33(entry.status) ?? "active",
|
|
29394
|
+
visibility: readString33(entry.visibility),
|
|
29395
|
+
metadata: asRecord31(entry.metadata),
|
|
29396
|
+
createdBy: readString33(entry.createdBy)
|
|
28148
29397
|
})) : [];
|
|
28149
29398
|
const payload = await bulkCreateTopicsFromGatewayAuth(args.authContext, {
|
|
28150
29399
|
topics: topics2
|
|
@@ -28165,10 +29414,10 @@ async function handleTopicBulkCreate(args) {
|
|
|
28165
29414
|
}
|
|
28166
29415
|
|
|
28167
29416
|
// ../../apps/gateway/src/routes/webhooks.ts
|
|
28168
|
-
function
|
|
29417
|
+
function asRecord32(value) {
|
|
28169
29418
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
28170
29419
|
}
|
|
28171
|
-
function
|
|
29420
|
+
function readString34(value) {
|
|
28172
29421
|
if (typeof value !== "string") {
|
|
28173
29422
|
return void 0;
|
|
28174
29423
|
}
|
|
@@ -28182,7 +29431,7 @@ function readStringArray17(value) {
|
|
|
28182
29431
|
if (!Array.isArray(value)) {
|
|
28183
29432
|
return void 0;
|
|
28184
29433
|
}
|
|
28185
|
-
const normalized = value.map((entry) =>
|
|
29434
|
+
const normalized = value.map((entry) => readString34(entry)).filter((entry) => Boolean(entry));
|
|
28186
29435
|
return normalized.length > 0 ? normalized : void 0;
|
|
28187
29436
|
}
|
|
28188
29437
|
function handleWebhooksError(error, fallbackMessage, correlationId, policyTraceId) {
|
|
@@ -28200,16 +29449,16 @@ function handleWebhooksError(error, fallbackMessage, correlationId, policyTraceI
|
|
|
28200
29449
|
}
|
|
28201
29450
|
async function handleWebhookCreate(args) {
|
|
28202
29451
|
try {
|
|
28203
|
-
const body =
|
|
29452
|
+
const body = asRecord32(args.body);
|
|
28204
29453
|
const payload = await args.authContext.convex.mutation(
|
|
28205
29454
|
"events:createWebhook",
|
|
28206
29455
|
{
|
|
28207
29456
|
tenantId: args.authContext.tenantId,
|
|
28208
29457
|
workspaceId: args.authContext.workspaceId,
|
|
28209
|
-
topicId:
|
|
28210
|
-
url:
|
|
29458
|
+
topicId: readString34(body.topicId),
|
|
29459
|
+
url: readString34(body.url) ?? "",
|
|
28211
29460
|
events: readStringArray17(body.events) ?? [],
|
|
28212
|
-
secret:
|
|
29461
|
+
secret: readString34(body.secret) ?? "",
|
|
28213
29462
|
active: readBoolean2(body.active),
|
|
28214
29463
|
createdBy: args.authContext.principalId ?? args.authContext.userId
|
|
28215
29464
|
}
|
|
@@ -28270,17 +29519,17 @@ async function handleWebhookGet(args) {
|
|
|
28270
29519
|
}
|
|
28271
29520
|
async function handleWebhookUpdate(args) {
|
|
28272
29521
|
try {
|
|
28273
|
-
const body =
|
|
29522
|
+
const body = asRecord32(args.body);
|
|
28274
29523
|
const payload = await args.authContext.convex.mutation(
|
|
28275
29524
|
"events:updateWebhook",
|
|
28276
29525
|
{
|
|
28277
29526
|
webhookId: args.webhookId,
|
|
28278
29527
|
tenantId: args.authContext.tenantId,
|
|
28279
29528
|
workspaceId: args.authContext.workspaceId,
|
|
28280
|
-
url:
|
|
29529
|
+
url: readString34(body.url),
|
|
28281
29530
|
events: readStringArray17(body.events),
|
|
28282
|
-
secret:
|
|
28283
|
-
topicId:
|
|
29531
|
+
secret: readString34(body.secret),
|
|
29532
|
+
topicId: readString34(body.topicId),
|
|
28284
29533
|
clearTopicId: body.topicId === null ? true : readBoolean2(body.clearTopicId),
|
|
28285
29534
|
active: readBoolean2(body.active),
|
|
28286
29535
|
updatedBy: args.authContext.principalId ?? args.authContext.userId
|
|
@@ -28324,12 +29573,12 @@ async function handleWebhookDelete(args) {
|
|
|
28324
29573
|
}
|
|
28325
29574
|
async function handleWebhookTest(args) {
|
|
28326
29575
|
try {
|
|
28327
|
-
const body =
|
|
29576
|
+
const body = asRecord32(args.body);
|
|
28328
29577
|
const payload = await args.authContext.convex.action("events:testWebhook", {
|
|
28329
29578
|
webhookId: args.webhookId,
|
|
28330
29579
|
tenantId: args.authContext.tenantId,
|
|
28331
29580
|
workspaceId: args.authContext.workspaceId,
|
|
28332
|
-
topicId:
|
|
29581
|
+
topicId: readString34(body.topicId),
|
|
28333
29582
|
actorId: args.authContext.principalId ?? args.authContext.userId,
|
|
28334
29583
|
actorType: inferActorType({
|
|
28335
29584
|
authMode: args.authContext.authMode,
|
|
@@ -28399,31 +29648,31 @@ async function handleWebhookHealth(args) {
|
|
|
28399
29648
|
}
|
|
28400
29649
|
|
|
28401
29650
|
// ../../apps/gateway/src/routes/worktrees.ts
|
|
28402
|
-
function
|
|
29651
|
+
function asRecord33(value) {
|
|
28403
29652
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
28404
29653
|
}
|
|
28405
|
-
function
|
|
29654
|
+
function readString35(value) {
|
|
28406
29655
|
if (typeof value !== "string") {
|
|
28407
29656
|
return void 0;
|
|
28408
29657
|
}
|
|
28409
29658
|
const normalized = value.trim();
|
|
28410
29659
|
return normalized.length > 0 ? normalized : void 0;
|
|
28411
29660
|
}
|
|
28412
|
-
function
|
|
29661
|
+
function readNumber23(value) {
|
|
28413
29662
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
28414
29663
|
}
|
|
28415
29664
|
function readStringArray18(value) {
|
|
28416
29665
|
if (!Array.isArray(value)) {
|
|
28417
29666
|
return void 0;
|
|
28418
29667
|
}
|
|
28419
|
-
const normalized = value.map((entry) =>
|
|
29668
|
+
const normalized = value.map((entry) => readString35(entry)).filter((entry) => Boolean(entry));
|
|
28420
29669
|
return normalized.length > 0 ? normalized : void 0;
|
|
28421
29670
|
}
|
|
28422
29671
|
function readObjectArray(value) {
|
|
28423
29672
|
if (!Array.isArray(value)) {
|
|
28424
29673
|
return void 0;
|
|
28425
29674
|
}
|
|
28426
|
-
const normalized = value.map((entry) =>
|
|
29675
|
+
const normalized = value.map((entry) => asRecord33(entry)).filter((entry) => Object.keys(entry).length > 0);
|
|
28427
29676
|
return normalized.length > 0 ? normalized : void 0;
|
|
28428
29677
|
}
|
|
28429
29678
|
function readConfidenceImpact(value) {
|
|
@@ -28434,18 +29683,18 @@ function normalizeMergeOutcomes2(value) {
|
|
|
28434
29683
|
return [];
|
|
28435
29684
|
}
|
|
28436
29685
|
return value.map((entry) => {
|
|
28437
|
-
const finding =
|
|
29686
|
+
const finding = readString35(entry);
|
|
28438
29687
|
if (finding) {
|
|
28439
29688
|
return finding;
|
|
28440
29689
|
}
|
|
28441
|
-
const row =
|
|
29690
|
+
const row = asRecord33(entry);
|
|
28442
29691
|
if (!Object.keys(row).length) {
|
|
28443
29692
|
return null;
|
|
28444
29693
|
}
|
|
28445
29694
|
return {
|
|
28446
|
-
beliefId:
|
|
28447
|
-
confidence:
|
|
28448
|
-
rationale:
|
|
29695
|
+
beliefId: readString35(row.beliefId) ?? "",
|
|
29696
|
+
confidence: readNumber23(row.confidence) ?? Number.NaN,
|
|
29697
|
+
rationale: readString35(row.rationale) ?? ""
|
|
28449
29698
|
};
|
|
28450
29699
|
}).filter((entry) => entry !== null);
|
|
28451
29700
|
}
|
|
@@ -28464,22 +29713,22 @@ function handleWorktreesError(error, fallbackMessage, correlationId, policyTrace
|
|
|
28464
29713
|
}
|
|
28465
29714
|
async function handleWorktreeCreate(args) {
|
|
28466
29715
|
try {
|
|
28467
|
-
const body =
|
|
29716
|
+
const body = asRecord33(args.body);
|
|
28468
29717
|
const goCriteria = readStringArray18(body.goCriteria);
|
|
28469
29718
|
const noGoSignals = readStringArray18(body.noGoSignals);
|
|
28470
29719
|
const payload = await createWorktreeFromGatewayAuth(args.authContext, {
|
|
28471
|
-
title:
|
|
28472
|
-
topicId:
|
|
28473
|
-
topicHint:
|
|
28474
|
-
objective:
|
|
28475
|
-
hypothesis:
|
|
28476
|
-
rationale:
|
|
28477
|
-
worktreeType:
|
|
28478
|
-
startDate:
|
|
28479
|
-
endDate:
|
|
28480
|
-
durationWeeks:
|
|
29720
|
+
title: readString35(body.title) ?? readString35(body.name) ?? "",
|
|
29721
|
+
topicId: readString35(body.topicId ?? body.projectId) ?? "",
|
|
29722
|
+
topicHint: readString35(body.topicHint),
|
|
29723
|
+
objective: readString35(body.objective),
|
|
29724
|
+
hypothesis: readString35(body.hypothesis),
|
|
29725
|
+
rationale: readString35(body.rationale),
|
|
29726
|
+
worktreeType: readString35(body.worktreeType),
|
|
29727
|
+
startDate: readNumber23(body.startDate),
|
|
29728
|
+
endDate: readNumber23(body.endDate),
|
|
29729
|
+
durationWeeks: readNumber23(body.durationWeeks),
|
|
28481
29730
|
confidenceImpact: readConfidenceImpact(body.confidenceImpact),
|
|
28482
|
-
beliefFocus:
|
|
29731
|
+
beliefFocus: readString35(body.beliefFocus),
|
|
28483
29732
|
beliefIds: readStringArray18(body.targetBeliefIds) ?? readStringArray18(body.beliefIds) ?? readStringArray18(body.beliefs),
|
|
28484
29733
|
targetBeliefIds: readStringArray18(body.targetBeliefIds),
|
|
28485
29734
|
targetQuestionIds: readStringArray18(body.targetQuestionIds),
|
|
@@ -28490,23 +29739,23 @@ async function handleWorktreeCreate(args) {
|
|
|
28490
29739
|
noGoSignals: noGoSignals ?? []
|
|
28491
29740
|
} : void 0,
|
|
28492
29741
|
autoShape: typeof body.autoShape === "boolean" ? body.autoShape : void 0,
|
|
28493
|
-
domainPackId:
|
|
29742
|
+
domainPackId: readString35(body.domainPackId),
|
|
28494
29743
|
tags: readStringArray18(body.tags),
|
|
28495
29744
|
touchedPaths: readStringArray18(body.touchedPaths),
|
|
28496
|
-
sourceRef:
|
|
28497
|
-
sourceKind:
|
|
28498
|
-
campaign:
|
|
28499
|
-
lane:
|
|
28500
|
-
laneOrderInCampaign:
|
|
28501
|
-
orderInLane:
|
|
29745
|
+
sourceRef: readString35(body.sourceRef),
|
|
29746
|
+
sourceKind: readString35(body.sourceKind),
|
|
29747
|
+
campaign: readNumber23(body.campaign),
|
|
29748
|
+
lane: readString35(body.lane),
|
|
29749
|
+
laneOrderInCampaign: readNumber23(body.laneOrderInCampaign),
|
|
29750
|
+
orderInLane: readNumber23(body.orderInLane),
|
|
28502
29751
|
dependsOn: readStringArray18(body.dependsOn),
|
|
28503
29752
|
blocks: readStringArray18(body.blocks),
|
|
28504
|
-
gate:
|
|
29753
|
+
gate: readString35(body.gate),
|
|
28505
29754
|
proofArtifacts: Array.isArray(body.proofArtifacts) ? body.proofArtifacts : void 0,
|
|
28506
|
-
staffingHint:
|
|
28507
|
-
lastReconciledAt:
|
|
29755
|
+
staffingHint: readString35(body.staffingHint),
|
|
29756
|
+
lastReconciledAt: readNumber23(body.lastReconciledAt),
|
|
28508
29757
|
autoFixPolicy: body.autoFixPolicy && typeof body.autoFixPolicy === "object" && !Array.isArray(body.autoFixPolicy) ? body.autoFixPolicy : void 0,
|
|
28509
|
-
lensId:
|
|
29758
|
+
lensId: readString35(body.lensId)
|
|
28510
29759
|
});
|
|
28511
29760
|
return successResponse(payload, {
|
|
28512
29761
|
status: 201,
|
|
@@ -28525,12 +29774,12 @@ async function handleWorktreeCreate(args) {
|
|
|
28525
29774
|
async function handleWorktreeList(args) {
|
|
28526
29775
|
try {
|
|
28527
29776
|
const payload = await listWorktreesFromGatewayAuth(args.authContext, {
|
|
28528
|
-
topicId:
|
|
28529
|
-
status:
|
|
28530
|
-
groupBy:
|
|
28531
|
-
lane:
|
|
28532
|
-
campaign:
|
|
28533
|
-
limit:
|
|
29777
|
+
topicId: readString35(args.query.topicId) ?? "",
|
|
29778
|
+
status: readString35(args.query.status),
|
|
29779
|
+
groupBy: readString35(args.query.groupBy),
|
|
29780
|
+
lane: readString35(args.query.lane),
|
|
29781
|
+
campaign: readNumber23(args.query.campaign),
|
|
29782
|
+
limit: readNumber23(args.query.limit)
|
|
28534
29783
|
});
|
|
28535
29784
|
return successResponse(payload, {
|
|
28536
29785
|
correlationId: args.correlationId,
|
|
@@ -28548,11 +29797,11 @@ async function handleWorktreeList(args) {
|
|
|
28548
29797
|
async function handleWorktreeListAll(args) {
|
|
28549
29798
|
try {
|
|
28550
29799
|
const payload = await listAllWorktreesFromGatewayAuth(args.authContext, {
|
|
28551
|
-
status:
|
|
28552
|
-
lane:
|
|
28553
|
-
campaign:
|
|
28554
|
-
groupBy:
|
|
28555
|
-
limit:
|
|
29800
|
+
status: readString35(args.query.status),
|
|
29801
|
+
lane: readString35(args.query.lane),
|
|
29802
|
+
campaign: readNumber23(args.query.campaign),
|
|
29803
|
+
groupBy: readString35(args.query.groupBy),
|
|
29804
|
+
limit: readNumber23(args.query.limit)
|
|
28556
29805
|
});
|
|
28557
29806
|
return successResponse(payload, {
|
|
28558
29807
|
correlationId: args.correlationId,
|
|
@@ -28570,9 +29819,9 @@ async function handleWorktreeListAll(args) {
|
|
|
28570
29819
|
async function handleWorktreeListCampaigns(args) {
|
|
28571
29820
|
try {
|
|
28572
29821
|
const payload = await listCampaignsFromGatewayAuth(args.authContext, {
|
|
28573
|
-
topicId:
|
|
28574
|
-
status:
|
|
28575
|
-
limit:
|
|
29822
|
+
topicId: readString35(args.query.topicId),
|
|
29823
|
+
status: readString35(args.query.status),
|
|
29824
|
+
limit: readNumber23(args.query.limit)
|
|
28576
29825
|
});
|
|
28577
29826
|
return successResponse(payload, {
|
|
28578
29827
|
correlationId: args.correlationId,
|
|
@@ -28607,27 +29856,27 @@ async function handleWorktreeActivate(args) {
|
|
|
28607
29856
|
}
|
|
28608
29857
|
async function handleWorktreeUpdate(args) {
|
|
28609
29858
|
try {
|
|
28610
|
-
const body =
|
|
29859
|
+
const body = asRecord33(args.body);
|
|
28611
29860
|
const payload = await updateWorktreeFromGatewayAuth(args.authContext, {
|
|
28612
29861
|
id: args.worktreeId,
|
|
28613
|
-
objective:
|
|
28614
|
-
hypothesis:
|
|
28615
|
-
rationale:
|
|
28616
|
-
campaign:
|
|
28617
|
-
lane:
|
|
28618
|
-
laneOrderInCampaign:
|
|
28619
|
-
orderInLane:
|
|
29862
|
+
objective: readString35(body.objective),
|
|
29863
|
+
hypothesis: readString35(body.hypothesis),
|
|
29864
|
+
rationale: readString35(body.rationale),
|
|
29865
|
+
campaign: readNumber23(body.campaign),
|
|
29866
|
+
lane: readString35(body.lane),
|
|
29867
|
+
laneOrderInCampaign: readNumber23(body.laneOrderInCampaign),
|
|
29868
|
+
orderInLane: readNumber23(body.orderInLane),
|
|
28620
29869
|
dependsOn: readStringArray18(body.dependsOn),
|
|
28621
29870
|
blocks: readStringArray18(body.blocks),
|
|
28622
|
-
gate:
|
|
28623
|
-
status:
|
|
28624
|
-
topicId:
|
|
29871
|
+
gate: readString35(body.gate),
|
|
29872
|
+
status: readString35(body.status),
|
|
29873
|
+
topicId: readString35(body.topicId),
|
|
28625
29874
|
additionalTopicIds: readStringArray18(body.additionalTopicIds),
|
|
28626
29875
|
proofArtifacts: Array.isArray(body.proofArtifacts) ? body.proofArtifacts : void 0,
|
|
28627
|
-
staffingHint:
|
|
28628
|
-
lastReconciledAt:
|
|
29876
|
+
staffingHint: readString35(body.staffingHint),
|
|
29877
|
+
lastReconciledAt: readNumber23(body.lastReconciledAt),
|
|
28629
29878
|
autoFixPolicy: body.autoFixPolicy && typeof body.autoFixPolicy === "object" ? body.autoFixPolicy : void 0,
|
|
28630
|
-
lensId:
|
|
29879
|
+
lensId: readString35(body.lensId)
|
|
28631
29880
|
});
|
|
28632
29881
|
return successResponse(payload, {
|
|
28633
29882
|
correlationId: args.correlationId,
|
|
@@ -28644,11 +29893,11 @@ async function handleWorktreeUpdate(args) {
|
|
|
28644
29893
|
}
|
|
28645
29894
|
async function handleWorktreeMerge(args) {
|
|
28646
29895
|
try {
|
|
28647
|
-
const body =
|
|
29896
|
+
const body = asRecord33(args.body);
|
|
28648
29897
|
const outcomes = normalizeMergeOutcomes2(body.outcomes);
|
|
28649
29898
|
const payload = await mergeWorktreeFromGatewayAuth(args.authContext, {
|
|
28650
29899
|
id: args.worktreeId,
|
|
28651
|
-
summary:
|
|
29900
|
+
summary: readString35(body.summary),
|
|
28652
29901
|
outcomes
|
|
28653
29902
|
});
|
|
28654
29903
|
return successResponse(payload, {
|
|
@@ -28666,7 +29915,7 @@ async function handleWorktreeMerge(args) {
|
|
|
28666
29915
|
}
|
|
28667
29916
|
async function handleWorktreeUpdateTargets(args) {
|
|
28668
29917
|
try {
|
|
28669
|
-
const body =
|
|
29918
|
+
const body = asRecord33(args.body);
|
|
28670
29919
|
const payload = await updateWorktreeTargetsFromGatewayAuth(
|
|
28671
29920
|
args.authContext,
|
|
28672
29921
|
{
|
|
@@ -28692,11 +29941,11 @@ async function handleWorktreeUpdateTargets(args) {
|
|
|
28692
29941
|
}
|
|
28693
29942
|
async function handleWorktreeComplete(args) {
|
|
28694
29943
|
try {
|
|
28695
|
-
const body =
|
|
29944
|
+
const body = asRecord33(args.body);
|
|
28696
29945
|
const payload = await completeWorktreeRecordFromGatewayAuth(
|
|
28697
29946
|
args.authContext,
|
|
28698
29947
|
{
|
|
28699
|
-
worktreeId:
|
|
29948
|
+
worktreeId: readString35(body.worktreeId) ?? "",
|
|
28700
29949
|
keyFindings: readStringArray18(body.keyFindings),
|
|
28701
29950
|
decisionsReached: readStringArray18(body.decisionsReached),
|
|
28702
29951
|
nextSteps: readStringArray18(body.nextSteps)
|
|
@@ -28717,9 +29966,9 @@ async function handleWorktreeComplete(args) {
|
|
|
28717
29966
|
}
|
|
28718
29967
|
async function handleWorktreeAdvancePhase(args) {
|
|
28719
29968
|
try {
|
|
28720
|
-
const body =
|
|
29969
|
+
const body = asRecord33(args.body);
|
|
28721
29970
|
const payload = await advanceWorktreePhaseFromGatewayAuth(args.authContext, {
|
|
28722
|
-
worktreeId:
|
|
29971
|
+
worktreeId: readString35(body.worktreeId) ?? ""
|
|
28723
29972
|
});
|
|
28724
29973
|
return successResponse(payload, {
|
|
28725
29974
|
correlationId: args.correlationId,
|
|
@@ -28736,10 +29985,10 @@ async function handleWorktreeAdvancePhase(args) {
|
|
|
28736
29985
|
}
|
|
28737
29986
|
async function handleWorktreeSetPhase(args) {
|
|
28738
29987
|
try {
|
|
28739
|
-
const body =
|
|
29988
|
+
const body = asRecord33(args.body);
|
|
28740
29989
|
const payload = await setWorktreePhaseFromGatewayAuth(args.authContext, {
|
|
28741
|
-
worktreeId:
|
|
28742
|
-
phase:
|
|
29990
|
+
worktreeId: readString35(body.worktreeId) ?? "",
|
|
29991
|
+
phase: readString35(body.phase) ?? ""
|
|
28743
29992
|
});
|
|
28744
29993
|
return successResponse(payload, {
|
|
28745
29994
|
correlationId: args.correlationId,
|
|
@@ -28756,12 +30005,12 @@ async function handleWorktreeSetPhase(args) {
|
|
|
28756
30005
|
}
|
|
28757
30006
|
async function handleWorktreePatchState(args) {
|
|
28758
30007
|
try {
|
|
28759
|
-
const body =
|
|
30008
|
+
const body = asRecord33(args.body);
|
|
28760
30009
|
const payload = await patchWorktreeStateFromGatewayAuth(
|
|
28761
30010
|
args.authContext,
|
|
28762
30011
|
{
|
|
28763
|
-
worktreeId:
|
|
28764
|
-
patch:
|
|
30012
|
+
worktreeId: readString35(body.worktreeId) ?? "",
|
|
30013
|
+
patch: asRecord33(body.patch)
|
|
28765
30014
|
}
|
|
28766
30015
|
);
|
|
28767
30016
|
return successResponse(payload, {
|
|
@@ -28779,7 +30028,7 @@ async function handleWorktreePatchState(args) {
|
|
|
28779
30028
|
}
|
|
28780
30029
|
async function handleWorktreeBulkCreate(args) {
|
|
28781
30030
|
try {
|
|
28782
|
-
const body =
|
|
30031
|
+
const body = asRecord33(args.body);
|
|
28783
30032
|
const payload = await bulkCreateWorktreesFromGatewayAuth(args.authContext, {
|
|
28784
30033
|
worktrees: Array.isArray(body.worktrees) ? body.worktrees : []
|
|
28785
30034
|
});
|
|
@@ -28798,6 +30047,6 @@ async function handleWorktreeBulkCreate(args) {
|
|
|
28798
30047
|
}
|
|
28799
30048
|
}
|
|
28800
30049
|
|
|
28801
|
-
export { extractPermitWebhookTenantKeys, handleBeliefArchive, handleBeliefBatchUpdateCriticality, handleBeliefBisect, handleBeliefConfidenceHistory, handleBeliefCreate, handleBeliefCreateContract, handleBeliefFork, handleBeliefGet, handleBeliefLineage, handleBeliefLink, handleBeliefList, handleBeliefReassignTopic, handleBeliefRefine, handleBeliefRelationships, handleBeliefUnlinkEvidence, handleBeliefUpdateConfidence, handleBeliefUpdateCriticality, handleBeliefUpdateRationale, handleBeliefUpdateStatus, handleContradictionFlag, handleContradictionGet, handleContradictionList, handleEdgeBatchCreate, handleEdgeCreate, handleEdgeDelete, handleEdgeList, handleEdgeRemove, handleEdgeTraverse, handleEdgeUpdate, handleEdgesRemoveBetween, handleEventsList, handleEventsReplay, handleEvidenceClassify, handleEvidenceClassifyBatch, handleEvidenceCreate, handleEvidenceFlagIncorrect, handleEvidenceGet, handleEvidenceLink, handleEvidenceList, handleEvidenceRemove, handleEvidenceSearch, handleEvidenceUpdate, handleEvidenceUpdateStatus, handleEvidenceUpdateVerificationStatus, handleGraphAnalysisCompute, handleGraphAnalysisLatest, handleGraphAnalysisList, handleGraphAnalysisListChanges, handleGraphAnalysisListSuggestions, handleGraphAnalysisSave, handleGraphAnalysisSaveSuggestions, handleGraphAnalysisUpdateSuggestion, handleGraphAnalyze, handleGraphBias, handleGraphEdgeList, handleGraphFalsify, handleGraphGaps, handleGraphNeighborhood, handleGraphNodeList, handleGraphRecommendationGet, handleGraphRecommendationStatus, handleGraphRecommendationsList, handleGraphTraverse, handleIdentityWhoami, handleOntologyBind, handleOntologyGet, handleOntologyList, handleOntologyMatch, handleOrgGraphByProvenance, handleOrgGraphNodeGet, handleOrgGraphPublished, handleOrgGraphSearch, handlePermitProjectionWebhook, handleQuestionAdd, handleQuestionAdvanceToConviction, handleQuestionAnswer, handleQuestionArchive, handleQuestionBatchCreate, handleQuestionCreate, handleQuestionDelete, handleQuestionFinalizeConviction, handleQuestionGet, handleQuestionGetAnswer, handleQuestionList, handleQuestionRefine, handleQuestionUpdate, handleQuestionUpdateConviction, handleQuestionUpdatePriority, handleQuestionUpdateStatus, handleSearchResources, handleSourceGet, handleSourceUpsert, handleTaskComplete, handleTaskCreate, handleTaskList, handleTaskUpdate, handleTopicBulkCreate, handleTopicCoverage, handleTopicCreate, handleTopicGet, handleTopicList, handleTopicRemove, handleTopicTree, handleTopicUpdate, handleWebhookCreate, handleWebhookDelete, handleWebhookDeliveries, handleWebhookGet, handleWebhookHealth, handleWebhookList, handleWebhookTest, handleWebhookUpdate, handleWorktreeActivate, handleWorktreeAdvancePhase, handleWorktreeBulkCreate, handleWorktreeComplete, handleWorktreeCreate, handleWorktreeList, handleWorktreeListAll, handleWorktreeListCampaigns, handleWorktreeMerge, handleWorktreePatchState, handleWorktreeSetPhase, handleWorktreeUpdate, handleWorktreeUpdateTargets, isPermitWebhookAuthorized };
|
|
30050
|
+
export { __testOnly, extractPermitWebhookTenantKeys, handleBeliefArchive, handleBeliefBatchUpdateCriticality, handleBeliefBisect, handleBeliefConfidenceHistory, handleBeliefCreate, handleBeliefCreateContract, handleBeliefFork, handleBeliefGet, handleBeliefLineage, handleBeliefLink, handleBeliefList, handleBeliefReassignTopic, handleBeliefRefine, handleBeliefRelationships, handleBeliefUnlinkEvidence, handleBeliefUpdateConfidence, handleBeliefUpdateCriticality, handleBeliefUpdateRationale, handleBeliefUpdateStatus, handleClerkWebhook, handleContradictionFlag, handleContradictionGet, handleContradictionList, handleEdgeBatchCreate, handleEdgeCreate, handleEdgeDelete, handleEdgeList, handleEdgeRemove, handleEdgeTraverse, handleEdgeUpdate, handleEdgesRemoveBetween, handleEventsList, handleEventsReplay, handleEvidenceClassify, handleEvidenceClassifyBatch, handleEvidenceCreate, handleEvidenceFlagIncorrect, handleEvidenceGet, handleEvidenceLink, handleEvidenceList, handleEvidenceRemove, handleEvidenceSearch, handleEvidenceUpdate, handleEvidenceUpdateStatus, handleEvidenceUpdateVerificationStatus, handleGraphAnalysisCompute, handleGraphAnalysisLatest, handleGraphAnalysisList, handleGraphAnalysisListChanges, handleGraphAnalysisListSuggestions, handleGraphAnalysisSave, handleGraphAnalysisSaveSuggestions, handleGraphAnalysisUpdateSuggestion, handleGraphAnalyze, handleGraphBias, handleGraphEdgeList, handleGraphFalsify, handleGraphGaps, handleGraphNeighborhood, handleGraphNodeList, handleGraphRecommendationGet, handleGraphRecommendationStatus, handleGraphRecommendationsList, handleGraphTraverse, handleIdentityWhoami, handleOntologyBind, handleOntologyGet, handleOntologyList, handleOntologyMatch, handleOrgGraphByProvenance, handleOrgGraphNodeGet, handleOrgGraphPublished, handleOrgGraphSearch, handlePermitProjectionWebhook, handleQuestionAdd, handleQuestionAdvanceToConviction, handleQuestionAnswer, handleQuestionArchive, handleQuestionBatchCreate, handleQuestionCreate, handleQuestionDelete, handleQuestionFinalizeConviction, handleQuestionGet, handleQuestionGetAnswer, handleQuestionList, handleQuestionRefine, handleQuestionUpdate, handleQuestionUpdateConviction, handleQuestionUpdatePriority, handleQuestionUpdateStatus, handleSearchResources, handleSourceGet, handleSourceUpsert, handleTaskComplete, handleTaskCreate, handleTaskList, handleTaskUpdate, handleTopicBulkCreate, handleTopicCoverage, handleTopicCreate, handleTopicGet, handleTopicList, handleTopicRemove, handleTopicTree, handleTopicUpdate, handleWebhookCreate, handleWebhookDelete, handleWebhookDeliveries, handleWebhookGet, handleWebhookHealth, handleWebhookList, handleWebhookTest, handleWebhookUpdate, handleWorktreeActivate, handleWorktreeAdvancePhase, handleWorktreeBulkCreate, handleWorktreeComplete, handleWorktreeCreate, handleWorktreeList, handleWorktreeListAll, handleWorktreeListCampaigns, handleWorktreeMerge, handleWorktreePatchState, handleWorktreeSetPhase, handleWorktreeUpdate, handleWorktreeUpdateTargets, hasPermitWebhookTenantScope, isPermitWebhookAuthorized };
|
|
28802
30051
|
//# sourceMappingURL=gateway.js.map
|
|
28803
30052
|
//# sourceMappingURL=gateway.js.map
|