@cat-factory/integrations 0.101.2 → 0.102.0
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/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/environments/EnvironmentHandlerSeeder.js +0 -0
- package/dist/modules/environments/EnvironmentHandlerSeeder.js.map +1 -1
- package/dist/modules/environments/EnvironmentProvisioningService.d.ts.map +1 -1
- package/dist/modules/environments/EnvironmentProvisioningService.js +9 -1
- package/dist/modules/environments/EnvironmentProvisioningService.js.map +1 -1
- package/dist/modules/tasks/GitHubIssuesProvider.d.ts +6 -0
- package/dist/modules/tasks/GitHubIssuesProvider.d.ts.map +1 -1
- package/dist/modules/tasks/GitHubIssuesProvider.js +7 -0
- package/dist/modules/tasks/GitHubIssuesProvider.js.map +1 -1
- package/dist/modules/tasks/JiraProvider.d.ts +6 -0
- package/dist/modules/tasks/JiraProvider.d.ts.map +1 -1
- package/dist/modules/tasks/JiraProvider.js +7 -0
- package/dist/modules/tasks/JiraProvider.js.map +1 -1
- package/dist/modules/tasks/LinearTaskProvider.d.ts +6 -0
- package/dist/modules/tasks/LinearTaskProvider.d.ts.map +1 -1
- package/dist/modules/tasks/LinearTaskProvider.js +7 -0
- package/dist/modules/tasks/LinearTaskProvider.js.map +1 -1
- package/dist/modules/tasks/TaskConnectionService.d.ts +63 -1
- package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -1
- package/dist/modules/tasks/TaskConnectionService.js +156 -2
- package/dist/modules/tasks/TaskConnectionService.js.map +1 -1
- package/dist/modules/tasks/TrackerWebhookService.d.ts +102 -0
- package/dist/modules/tasks/TrackerWebhookService.d.ts.map +1 -0
- package/dist/modules/tasks/TrackerWebhookService.js +245 -0
- package/dist/modules/tasks/TrackerWebhookService.js.map +1 -0
- package/dist/modules/tasks/intakeMatch.logic.d.ts +21 -0
- package/dist/modules/tasks/intakeMatch.logic.d.ts.map +1 -0
- package/dist/modules/tasks/intakeMatch.logic.js +43 -0
- package/dist/modules/tasks/intakeMatch.logic.js.map +1 -0
- package/dist/modules/tasks/webhook/adapters.d.ts +31 -0
- package/dist/modules/tasks/webhook/adapters.d.ts.map +1 -0
- package/dist/modules/tasks/webhook/adapters.js +259 -0
- package/dist/modules/tasks/webhook/adapters.js.map +1 -0
- package/dist/modules/tasks/webhook/hmac.d.ts +34 -0
- package/dist/modules/tasks/webhook/hmac.d.ts.map +1 -0
- package/dist/modules/tasks/webhook/hmac.js +98 -0
- package/dist/modules/tasks/webhook/hmac.js.map +1 -0
- package/dist/modules/writeback/IssueWritebackService.d.ts +17 -1
- package/dist/modules/writeback/IssueWritebackService.d.ts.map +1 -1
- package/dist/modules/writeback/IssueWritebackService.js +21 -1
- package/dist/modules/writeback/IssueWritebackService.js.map +1 -1
- package/dist/modules/writeback/reviewQuestions.logic.d.ts.map +1 -1
- package/dist/modules/writeback/reviewQuestions.logic.js +6 -1
- package/dist/modules/writeback/reviewQuestions.logic.js.map +1 -1
- package/dist/modules/writeback/reviewReplies.logic.d.ts +90 -0
- package/dist/modules/writeback/reviewReplies.logic.d.ts.map +1 -0
- package/dist/modules/writeback/reviewReplies.logic.js +262 -0
- package/dist/modules/writeback/reviewReplies.logic.js.map +1 -0
- package/package.json +4 -4
|
@@ -2,7 +2,7 @@ import type { Clock } from '@cat-factory/kernel';
|
|
|
2
2
|
import type { TaskConnectionRecord, TaskConnectionRepository } from '@cat-factory/kernel';
|
|
3
3
|
import type { TaskSourceSettingsRepository } from '@cat-factory/kernel';
|
|
4
4
|
import type { GitHubInstallationRepository } from '@cat-factory/kernel';
|
|
5
|
-
import type { TaskSourceRegistry } from '@cat-factory/kernel';
|
|
5
|
+
import type { TaskSourceProvider, TaskSourceRegistry } from '@cat-factory/kernel';
|
|
6
6
|
import type { TaskConnection, TaskSourceDiagnostic, TaskSourceKind, TaskSourceState } from '@cat-factory/kernel';
|
|
7
7
|
import type { WorkspaceRepository } from '@cat-factory/kernel';
|
|
8
8
|
import type { LinearOAuthSecret } from '@cat-factory/contracts';
|
|
@@ -107,7 +107,69 @@ export declare class TaskConnectionService {
|
|
|
107
107
|
listConnections(workspaceId: string): Promise<TaskConnection[]>;
|
|
108
108
|
/** Resolve the live connection (with credentials) or throw if not connected. */
|
|
109
109
|
requireConnection(workspaceId: string, source: TaskSourceKind): Promise<TaskConnectionRecord>;
|
|
110
|
+
/**
|
|
111
|
+
* The provider serving a source on this deployment, or undefined when it isn't registered.
|
|
112
|
+
* Exposed so the shared webhook receiver can reach a source's `webhook` adapter without a second
|
|
113
|
+
* registry of its own — the connection service is already the one thing that holds both the
|
|
114
|
+
* registry and the stored credentials a delivery is verified against.
|
|
115
|
+
*/
|
|
116
|
+
providerFor(source: TaskSourceKind): TaskSourceProvider | undefined;
|
|
117
|
+
/**
|
|
118
|
+
* The workspace's stored connection RECORD (credentials included), or null when not connected.
|
|
119
|
+
*
|
|
120
|
+
* Distinct from {@link getConnection}, which deliberately projects credentials away for client
|
|
121
|
+
* responses. This is for server-internal callers that need the bag itself — today the webhook
|
|
122
|
+
* receiver, reading the inbound secret.
|
|
123
|
+
*/
|
|
124
|
+
getConnectionRecord(workspaceId: string, source: TaskSourceKind): Promise<TaskConnectionRecord | null>;
|
|
125
|
+
/** The connection's inbound-webhook state, safe to read back at any time (never the secret). */
|
|
126
|
+
getWebhookState(workspaceId: string, source: TaskSourceKind): Promise<TaskSourceWebhookState>;
|
|
127
|
+
/**
|
|
128
|
+
* Mint (or ROTATE) the connection's inbound-webhook secret, returning it exactly once.
|
|
129
|
+
*
|
|
130
|
+
* Rotation is destructive by design: the previous secret stops verifying the instant this
|
|
131
|
+
* returns, so a delivery signed with it is rejected rather than accepted during a grace window.
|
|
132
|
+
* Backwards compatibility is a non-goal here and a webhook secret with two live values is a
|
|
133
|
+
* webhook secret an attacker only has to steal once.
|
|
134
|
+
*/
|
|
135
|
+
mintWebhookSecret(workspaceId: string, source: TaskSourceKind, input?: {
|
|
136
|
+
replyAllow?: string;
|
|
137
|
+
}): Promise<TaskSourceWebhookState & {
|
|
138
|
+
secret: string;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Edit the reply allow-list, leaving the webhook secret untouched.
|
|
142
|
+
*
|
|
143
|
+
* Deliberately NOT folded into {@link mintWebhookSecret}: that call rotates, and rotation is
|
|
144
|
+
* destructive the instant it returns. Tightening the allow-list is precisely what an operator
|
|
145
|
+
* does when a tracker turns out to be more public than they thought, and answering that with a
|
|
146
|
+
* silently rotated secret would take deliveries down until they re-pasted it into the vendor —
|
|
147
|
+
* a security control that costs an outage is a security control people avoid using.
|
|
148
|
+
*/
|
|
149
|
+
updateWebhookReplyAllow(workspaceId: string, source: TaskSourceKind, replyAllow: string): Promise<TaskSourceWebhookState>;
|
|
150
|
+
/**
|
|
151
|
+
* Clear the inbound-webhook secret, so deliveries stop being accepted (they 503 at the receiver,
|
|
152
|
+
* which is the honest answer: the operator turned this off). The connection itself is untouched
|
|
153
|
+
* — polling intake and imports keep working exactly as before.
|
|
154
|
+
*/
|
|
155
|
+
clearWebhookSecret(workspaceId: string, source: TaskSourceKind): Promise<void>;
|
|
110
156
|
/** Disconnect a workspace from a source (tombstones the binding). */
|
|
111
157
|
disconnect(workspaceId: string, source: TaskSourceKind): Promise<void>;
|
|
112
158
|
}
|
|
159
|
+
/** The inbound-webhook state of one connection (the secret itself is never part of it). */
|
|
160
|
+
export interface TaskSourceWebhookState {
|
|
161
|
+
source: TaskSourceKind;
|
|
162
|
+
supported: boolean;
|
|
163
|
+
configured: boolean;
|
|
164
|
+
deliveryPath: string;
|
|
165
|
+
replyAllow: string;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Where a tracker should POST its deliveries, relative to the deployment's public base URL.
|
|
169
|
+
*
|
|
170
|
+
* Built here rather than in the controller so the string an operator PASTES and the route the
|
|
171
|
+
* receiver SERVES have one definition — a mismatch between them fails silently, as deliveries that
|
|
172
|
+
* simply never arrive.
|
|
173
|
+
*/
|
|
174
|
+
export declare function trackerWebhookPath(workspaceId: string, source: TaskSourceKind): string;
|
|
113
175
|
//# sourceMappingURL=TaskConnectionService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskConnectionService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"TaskConnectionService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConflictError, ValidationError } from '@cat-factory/kernel';
|
|
1
|
+
import { ConflictError, TRACKER_WEBHOOK_REPLY_ALLOW_KEY, TRACKER_WEBHOOK_SECRET_KEY, ValidationError, trackerWebhookSecret, } from '@cat-factory/kernel';
|
|
2
2
|
import { requireWorkspace } from '@cat-factory/kernel';
|
|
3
3
|
/**
|
|
4
4
|
* A credentialless provider carries no connection to make: there are no credential
|
|
@@ -229,7 +229,13 @@ export class TaskConnectionService {
|
|
|
229
229
|
const record = {
|
|
230
230
|
workspaceId,
|
|
231
231
|
source,
|
|
232
|
-
|
|
232
|
+
// Carry the PLATFORM-owned keys across a re-connect. The bag is replaced wholesale (a
|
|
233
|
+
// reconnect is "here are my credentials now"), and a provider's `normalizeConnection`
|
|
234
|
+
// legitimately returns only the VENDOR credentials it validated — so without this, rotating
|
|
235
|
+
// a Jira API token would silently drop the inbound webhook secret and every subsequent
|
|
236
|
+
// delivery would 503 with nothing to point at the cause. Preserved HERE rather than in each
|
|
237
|
+
// provider so no provider can forget, and so a new platform-owned key is a one-line change.
|
|
238
|
+
credentials: { ...preservedPlatformCredentials(existing?.credentials), ...credentials },
|
|
233
239
|
label,
|
|
234
240
|
createdAt: existing?.createdAt ?? this.deps.clock.now(),
|
|
235
241
|
deletedAt: null,
|
|
@@ -255,6 +261,108 @@ export class TaskConnectionService {
|
|
|
255
261
|
}
|
|
256
262
|
return record;
|
|
257
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* The provider serving a source on this deployment, or undefined when it isn't registered.
|
|
266
|
+
* Exposed so the shared webhook receiver can reach a source's `webhook` adapter without a second
|
|
267
|
+
* registry of its own — the connection service is already the one thing that holds both the
|
|
268
|
+
* registry and the stored credentials a delivery is verified against.
|
|
269
|
+
*/
|
|
270
|
+
providerFor(source) {
|
|
271
|
+
return this.deps.registry.get(source);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The workspace's stored connection RECORD (credentials included), or null when not connected.
|
|
275
|
+
*
|
|
276
|
+
* Distinct from {@link getConnection}, which deliberately projects credentials away for client
|
|
277
|
+
* responses. This is for server-internal callers that need the bag itself — today the webhook
|
|
278
|
+
* receiver, reading the inbound secret.
|
|
279
|
+
*/
|
|
280
|
+
getConnectionRecord(workspaceId, source) {
|
|
281
|
+
return this.deps.taskConnectionRepository.getByWorkspace(workspaceId, source);
|
|
282
|
+
}
|
|
283
|
+
/** The connection's inbound-webhook state, safe to read back at any time (never the secret). */
|
|
284
|
+
async getWebhookState(workspaceId, source) {
|
|
285
|
+
const record = await this.getConnectionRecord(workspaceId, source);
|
|
286
|
+
return {
|
|
287
|
+
source,
|
|
288
|
+
supported: this.deps.registry.get(source)?.webhook != null,
|
|
289
|
+
configured: trackerWebhookSecret(record?.credentials) !== '',
|
|
290
|
+
deliveryPath: trackerWebhookPath(workspaceId, source),
|
|
291
|
+
replyAllow: record?.credentials?.[TRACKER_WEBHOOK_REPLY_ALLOW_KEY] ?? '',
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Mint (or ROTATE) the connection's inbound-webhook secret, returning it exactly once.
|
|
296
|
+
*
|
|
297
|
+
* Rotation is destructive by design: the previous secret stops verifying the instant this
|
|
298
|
+
* returns, so a delivery signed with it is rejected rather than accepted during a grace window.
|
|
299
|
+
* Backwards compatibility is a non-goal here and a webhook secret with two live values is a
|
|
300
|
+
* webhook secret an attacker only has to steal once.
|
|
301
|
+
*/
|
|
302
|
+
async mintWebhookSecret(workspaceId, source, input = {}) {
|
|
303
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
304
|
+
const provider = this.deps.registry.get(source);
|
|
305
|
+
if (!provider?.webhook) {
|
|
306
|
+
throw new ValidationError(`${source} does not accept inbound webhooks on this deployment`);
|
|
307
|
+
}
|
|
308
|
+
const record = await this.requireConnection(workspaceId, source);
|
|
309
|
+
const secret = generateWebhookSecret();
|
|
310
|
+
const credentials = {
|
|
311
|
+
...record.credentials,
|
|
312
|
+
[TRACKER_WEBHOOK_SECRET_KEY]: secret,
|
|
313
|
+
...(input.replyAllow !== undefined
|
|
314
|
+
? { [TRACKER_WEBHOOK_REPLY_ALLOW_KEY]: input.replyAllow.trim() }
|
|
315
|
+
: {}),
|
|
316
|
+
};
|
|
317
|
+
await this.deps.taskConnectionRepository.upsert({ ...record, credentials });
|
|
318
|
+
return {
|
|
319
|
+
source,
|
|
320
|
+
supported: true,
|
|
321
|
+
configured: true,
|
|
322
|
+
deliveryPath: trackerWebhookPath(workspaceId, source),
|
|
323
|
+
replyAllow: credentials[TRACKER_WEBHOOK_REPLY_ALLOW_KEY] ?? '',
|
|
324
|
+
secret,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Edit the reply allow-list, leaving the webhook secret untouched.
|
|
329
|
+
*
|
|
330
|
+
* Deliberately NOT folded into {@link mintWebhookSecret}: that call rotates, and rotation is
|
|
331
|
+
* destructive the instant it returns. Tightening the allow-list is precisely what an operator
|
|
332
|
+
* does when a tracker turns out to be more public than they thought, and answering that with a
|
|
333
|
+
* silently rotated secret would take deliveries down until they re-pasted it into the vendor —
|
|
334
|
+
* a security control that costs an outage is a security control people avoid using.
|
|
335
|
+
*/
|
|
336
|
+
async updateWebhookReplyAllow(workspaceId, source, replyAllow) {
|
|
337
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
338
|
+
const record = await this.requireConnection(workspaceId, source);
|
|
339
|
+
const credentials = {
|
|
340
|
+
...record.credentials,
|
|
341
|
+
[TRACKER_WEBHOOK_REPLY_ALLOW_KEY]: replyAllow.trim(),
|
|
342
|
+
};
|
|
343
|
+
await this.deps.taskConnectionRepository.upsert({ ...record, credentials });
|
|
344
|
+
return {
|
|
345
|
+
source,
|
|
346
|
+
supported: this.deps.registry.get(source)?.webhook != null,
|
|
347
|
+
configured: trackerWebhookSecret(credentials) !== '',
|
|
348
|
+
deliveryPath: trackerWebhookPath(workspaceId, source),
|
|
349
|
+
replyAllow: credentials[TRACKER_WEBHOOK_REPLY_ALLOW_KEY] ?? '',
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Clear the inbound-webhook secret, so deliveries stop being accepted (they 503 at the receiver,
|
|
354
|
+
* which is the honest answer: the operator turned this off). The connection itself is untouched
|
|
355
|
+
* — polling intake and imports keep working exactly as before.
|
|
356
|
+
*/
|
|
357
|
+
async clearWebhookSecret(workspaceId, source) {
|
|
358
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
359
|
+
const record = await this.deps.taskConnectionRepository.getByWorkspace(workspaceId, source);
|
|
360
|
+
if (!record)
|
|
361
|
+
return;
|
|
362
|
+
const credentials = { ...record.credentials };
|
|
363
|
+
delete credentials[TRACKER_WEBHOOK_SECRET_KEY];
|
|
364
|
+
await this.deps.taskConnectionRepository.upsert({ ...record, credentials });
|
|
365
|
+
}
|
|
258
366
|
/** Disconnect a workspace from a source (tombstones the binding). */
|
|
259
367
|
async disconnect(workspaceId, source) {
|
|
260
368
|
const record = await this.deps.taskConnectionRepository.getByWorkspace(workspaceId, source);
|
|
@@ -263,4 +371,50 @@ export class TaskConnectionService {
|
|
|
263
371
|
await this.deps.taskConnectionRepository.softDelete(workspaceId, source, this.deps.clock.now());
|
|
264
372
|
}
|
|
265
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Where a tracker should POST its deliveries, relative to the deployment's public base URL.
|
|
376
|
+
*
|
|
377
|
+
* Built here rather than in the controller so the string an operator PASTES and the route the
|
|
378
|
+
* receiver SERVES have one definition — a mismatch between them fails silently, as deliveries that
|
|
379
|
+
* simply never arrive.
|
|
380
|
+
*/
|
|
381
|
+
export function trackerWebhookPath(workspaceId, source) {
|
|
382
|
+
return `/webhooks/tasks/${source}/${workspaceId}`;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* A fresh inbound-webhook secret: 32 bytes of CSPRNG entropy, hex-encoded.
|
|
386
|
+
*
|
|
387
|
+
* `crypto.getRandomValues` (not `Math.random`) because this value is the ONLY thing standing
|
|
388
|
+
* between an anonymous POST and a run-driving command; it is a global on both workerd and Node.
|
|
389
|
+
* Hex rather than base64url so it survives being pasted into every vendor's webhook form without
|
|
390
|
+
* anyone wondering whether a `-` or `_` was part of it.
|
|
391
|
+
*/
|
|
392
|
+
function generateWebhookSecret() {
|
|
393
|
+
const bytes = new Uint8Array(32);
|
|
394
|
+
crypto.getRandomValues(bytes);
|
|
395
|
+
let out = '';
|
|
396
|
+
for (const byte of bytes)
|
|
397
|
+
out += byte.toString(16).padStart(2, '0');
|
|
398
|
+
return out;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* The credential-bag keys the PLATFORM owns rather than the vendor — today the inbound-webhook
|
|
402
|
+
* secret and its reply allow-list. They are configured through their own endpoints, never sent to
|
|
403
|
+
* the vendor, and must survive a credential rotation.
|
|
404
|
+
*
|
|
405
|
+
* Note the merge order at the call site: preserved keys come FIRST, so an explicit value in the
|
|
406
|
+
* incoming bag still wins. That matters for the mint path, which writes the secret through the
|
|
407
|
+
* same store.
|
|
408
|
+
*/
|
|
409
|
+
function preservedPlatformCredentials(existing) {
|
|
410
|
+
if (!existing)
|
|
411
|
+
return {};
|
|
412
|
+
const preserved = {};
|
|
413
|
+
for (const key of [TRACKER_WEBHOOK_SECRET_KEY, TRACKER_WEBHOOK_REPLY_ALLOW_KEY]) {
|
|
414
|
+
const value = existing[key];
|
|
415
|
+
if (value !== undefined)
|
|
416
|
+
preserved[key] = value;
|
|
417
|
+
}
|
|
418
|
+
return preserved;
|
|
419
|
+
}
|
|
266
420
|
//# sourceMappingURL=TaskConnectionService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskConnectionService.js","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TaskConnectionService.js","sourceRoot":"","sources":["../../../src/modules/tasks/TaskConnectionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { type Clock, type IssueWritebackProvider, type RequirementReview, type ResolveRequirementsExceededChoice, type ReviewItemStatus, type ReviewReplyAck, type TaskConnectionRepository, type TaskRepository, type TrackerCommentIngestRepository, type TrackerIssueEvent, type TrackerWebhookEvent } from '@cat-factory/kernel';
|
|
2
|
+
/**
|
|
3
|
+
* The requirements-review surface, narrowed to what a ticket reply drives.
|
|
4
|
+
*
|
|
5
|
+
* Declared structurally rather than imported: `@cat-factory/orchestration` depends on this
|
|
6
|
+
* package, so naming its types here would invert the layering. The composition root binds these
|
|
7
|
+
* to `requirements.service` + `executionService.requirementsReview` — the very methods the SPA
|
|
8
|
+
* controller calls — which is what makes "no parallel mutation path" true by construction rather
|
|
9
|
+
* than by discipline.
|
|
10
|
+
*/
|
|
11
|
+
export interface ReviewReplyGateway {
|
|
12
|
+
/** The block's live review, or null when it has none. */
|
|
13
|
+
getForBlock(workspaceId: string, blockId: string): Promise<RequirementReview | null>;
|
|
14
|
+
/** Record a human answer against one finding. */
|
|
15
|
+
replyToItem(workspaceId: string, reviewId: string, itemId: string, reply: string): Promise<RequirementReview>;
|
|
16
|
+
/** Set a finding's status (dismiss / reopen). */
|
|
17
|
+
setItemStatus(workspaceId: string, reviewId: string, itemId: string, status: ReviewItemStatus): Promise<RequirementReview>;
|
|
18
|
+
/** Fold the recorded answers in and re-review — the async path the durable driver runs. */
|
|
19
|
+
incorporate(workspaceId: string, blockId: string, feedback?: string): Promise<RequirementReview>;
|
|
20
|
+
/** Settle the review with the last incorporated document and advance the parked run. */
|
|
21
|
+
proceed(workspaceId: string, blockId: string): Promise<RequirementReview>;
|
|
22
|
+
/** Resolve a review that hit its iteration cap. */
|
|
23
|
+
resolveExceeded(workspaceId: string, blockId: string, choice: ResolveRequirementsExceededChoice): Promise<RequirementReview>;
|
|
24
|
+
}
|
|
25
|
+
export interface TrackerWebhookServiceDependencies {
|
|
26
|
+
taskRepository: TaskRepository;
|
|
27
|
+
taskConnectionRepository: TaskConnectionRepository;
|
|
28
|
+
/**
|
|
29
|
+
* Fire every recurring schedule whose intake configuration this issue event qualifies for,
|
|
30
|
+
* returning how many fired. Bound to `RecurringPipelineService.triggerForIssueEvent`. Absent ⇒
|
|
31
|
+
* push-driven intake is off and the polling schedule alone covers it (which is the pre-existing
|
|
32
|
+
* behaviour, so an unwired facade is byte-for-byte unchanged).
|
|
33
|
+
*/
|
|
34
|
+
triggerIntake?: (workspaceId: string, event: TrackerIssueEvent) => Promise<number>;
|
|
35
|
+
/** The requirements-review surface. Absent ⇒ ticket replies are ignored. */
|
|
36
|
+
reviewGateway?: ReviewReplyGateway;
|
|
37
|
+
/**
|
|
38
|
+
* Idempotency markers. Absent ⇒ replies are ignored entirely, because applying without a claim
|
|
39
|
+
* would re-answer the same finding on every redelivery — the same "pass through rather than act
|
|
40
|
+
* unsafely" stance `postReviewQuestions` takes without its marker store.
|
|
41
|
+
*/
|
|
42
|
+
commentIngestRepository?: TrackerCommentIngestRepository;
|
|
43
|
+
/** Posts the follow-up acknowledgement. Absent ⇒ replies still apply, silently. */
|
|
44
|
+
issueWriteback?: Pick<IssueWritebackProvider, 'postReviewReplyAck'>;
|
|
45
|
+
/** Resolve the run parked on a block, so the ack can name it. Absent ⇒ the ack omits the id. */
|
|
46
|
+
resolveRunId?: (workspaceId: string, blockId: string) => Promise<string | null>;
|
|
47
|
+
clock?: Clock;
|
|
48
|
+
/** Structured log sink for the silent-drop paths (an unauthorized reply leaves no other trace). */
|
|
49
|
+
log?: (event: Record<string, unknown>) => void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* What a delivery did, for the consumer's logs. Deliberately coarse: a webhook consumer's only
|
|
53
|
+
* decisions are "ack" and "retry", and every outcome here is an ack.
|
|
54
|
+
*/
|
|
55
|
+
export type TrackerWebhookOutcome = {
|
|
56
|
+
kind: 'intake';
|
|
57
|
+
fired: number;
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'reply';
|
|
60
|
+
outcome: ReviewReplyAck['outcome'];
|
|
61
|
+
} | {
|
|
62
|
+
kind: 'ignored';
|
|
63
|
+
reason: string;
|
|
64
|
+
};
|
|
65
|
+
export declare class TrackerWebhookService {
|
|
66
|
+
private readonly deps;
|
|
67
|
+
constructor(deps: TrackerWebhookServiceDependencies);
|
|
68
|
+
/** Route one verified, parsed delivery. */
|
|
69
|
+
handle(workspaceId: string, event: TrackerWebhookEvent): Promise<TrackerWebhookOutcome>;
|
|
70
|
+
/**
|
|
71
|
+
* An issue moved on the tracker: fire any recurring intake schedule it qualifies for.
|
|
72
|
+
*
|
|
73
|
+
* Nothing is imported here. The fired run's `bug-intake` step does the searching, dedup,
|
|
74
|
+
* importing, linking and claiming through the unchanged `BugIntakeService`, so a push-driven
|
|
75
|
+
* pickup is byte-for-byte a cadence pickup that simply happened sooner.
|
|
76
|
+
*/
|
|
77
|
+
private handleIssue;
|
|
78
|
+
/**
|
|
79
|
+
* A comment landed on a tracked issue: apply any review commands it carries.
|
|
80
|
+
*
|
|
81
|
+
* The guard ORDER is load-bearing and runs cheapest-and-most-silencing first:
|
|
82
|
+
*
|
|
83
|
+
* 1. **No commands ⇒ ignore, before anything else.** Most comments on a linked issue are
|
|
84
|
+
* ordinary human discussion; reading the projection for each of them would make every
|
|
85
|
+
* conversation cost a database round trip.
|
|
86
|
+
* 2. **Bot / unauthorized author ⇒ drop SILENTLY** — no state change and, deliberately, no ack.
|
|
87
|
+
* Replying would confirm the hook exists and hand an attacker an oracle (D7). The bot half
|
|
88
|
+
* also stops the platform's own ack comment from feeding itself.
|
|
89
|
+
* 3. Only then the projection lookup, the review lookup, and the claim.
|
|
90
|
+
*/
|
|
91
|
+
private handleComment;
|
|
92
|
+
/**
|
|
93
|
+
* Apply a comment's commands to a live review, in the order written, and describe what happened.
|
|
94
|
+
*
|
|
95
|
+
* A review that has already SETTLED (`incorporated`) applies nothing — the run is no longer
|
|
96
|
+
* waiting on these questions — but still produces an ack, because a reporter who answered in
|
|
97
|
+
* good faith deserves to learn the questions moved on rather than watch their reply vanish.
|
|
98
|
+
*/
|
|
99
|
+
private applyCommands;
|
|
100
|
+
private now;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=TrackerWebhookService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrackerWebhookService.d.ts","sourceRoot":"","sources":["../../../src/modules/tasks/TrackerWebhookService.ts"],"names":[],"mappings":"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"}
|