import { draftLoop } from './draft-loop.ts'
import { pickActiveAnomaly, unwrapWebhookPayload } from './loop-helpers.ts'
import { readLoopConfig } from './loop-storage.ts'
import { listAnomalies } from './list-anomalies.ts'
import runLoop from './run-loop.ts'
/**
* Handle a PlanetScale `branch.anomaly` webhook. Drafts the loop by default.
* Live issue/PR creation only happens when configure-loop saved loopEnabled.
* @example
* import handleWebhook from 'kody:@kody/planetscale/handle-webhook'
* await handleWebhook(payload)
*/
export default async function handleWebhook(input: unknown = {}) {
const payload = unwrapWebhookPayload(input)
const stored = await readLoopConfig()
const organization = payload.organization ?? stored.organization
const database = payload.database ?? stored.database
const branch = payload.resource?.name ?? stored.branch ?? 'main'
if (!organization || !database) {
return {
ok: false,
message: 'Webhook is missing organization/database and none are saved in configure-loop.',
}
}
if (payload.event && payload.event !== 'branch.anomaly') {
return {
ok: true,
ignored: true,
event: payload.event,
message: 'Only branch.anomaly starts the Insights loop. Other events are ignored.',
}
}
const anomalies = await listAnomalies({
organization,
database,
branch,
account: stored.account,
})
const anomaly = pickActiveAnomaly(anomalies.items)
if (!anomaly) {
return {
ok: true,
organization,
database,
branch,
message: 'branch.anomaly received, but Insights currently lists no anomalies.',
}
}
const draft = await draftLoop({
organization,
database,
branch,
anomaly,
githubOwner: stored.githubOwner,
githubRepo: stored.githubRepo,
repositoryUrl: stored.repositoryUrl,
labels: stored.labels,
account: stored.account,
})
if (!stored.loopEnabled) {
return {
ok: true,
dryRun: true,
event: payload.event ?? 'branch.anomaly',
draft,
next: 'Set loopEnabled: true with configure-loop (confirm: true) if you want webhooks to open the issue and launch the implementer.',
}
}
return runLoop({
organization,
database,
branch,
anomalyId: anomaly.id,
confirm: true,
})
}