Skip to content

Commit 2f83af2

Browse files
tonyxiaoclaude
andcommitted
Add OAS spec and Scalar docs to standalone webhook server
- webhook-app.ts: add /health, /openapi.json, and /docs routes - open-docs.sh: add `webhook` option (port 4030) - generate-openapi.sh: generate and check webhook.json alongside engine/service Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Committed-By-Agent: claude
1 parent 3fa609c commit 2f83af2

4 files changed

Lines changed: 86 additions & 10 deletions

File tree

apps/service/src/api/webhook-app.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
2+
import { apiReference } from '@scalar/hono-api-reference'
23

34
export interface WebhookAppOptions {
45
/** Called for each incoming webhook event. Fire-and-forget. */
@@ -66,6 +67,24 @@ export function createWebhookApp({ push_event }: WebhookAppOptions) {
6667
}
6768
},
6869
})
70+
app.get('/health', (c) => c.text('ok'))
71+
6972
mountWebhookRoutes(app, push_event)
73+
74+
app.get('/openapi.json', (c) =>
75+
c.json(
76+
app.getOpenAPIDocument({
77+
openapi: '3.0.0',
78+
info: {
79+
title: 'Stripe Sync Webhook Server',
80+
version: '1.0.0',
81+
description: 'Standalone webhook ingress — receives Stripe webhook events.',
82+
},
83+
})
84+
)
85+
)
86+
87+
app.get('/docs', apiReference({ url: '/openapi.json' }))
88+
7089
return app
7190
}

docs/openapi/webhook.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"openapi": "3.0.0",
3+
"info": {
4+
"title": "Stripe Sync Webhook Server",
5+
"version": "1.0.0",
6+
"description": "Standalone webhook ingress — receives Stripe webhook events."
7+
},
8+
"components": {
9+
"schemas": {},
10+
"parameters": {}
11+
},
12+
"paths": {
13+
"/webhooks/{credential_id}": {
14+
"post": {
15+
"operationId": "pushWebhook",
16+
"tags": ["Webhooks"],
17+
"summary": "Ingest a Stripe webhook event",
18+
"description": "Receives a raw Stripe webhook event, verifies its signature using the credential's webhook secret, and enqueues it for processing by the active sync.",
19+
"parameters": [
20+
{
21+
"schema": {
22+
"type": "string",
23+
"example": "cred_abc123"
24+
},
25+
"required": true,
26+
"name": "credential_id",
27+
"in": "path"
28+
}
29+
],
30+
"responses": {
31+
"200": {
32+
"description": "Event accepted",
33+
"content": {
34+
"text/plain": {
35+
"schema": {
36+
"type": "string",
37+
"enum": ["ok"]
38+
}
39+
}
40+
}
41+
}
42+
}
43+
}
44+
}
45+
}
46+
}

scripts/generate-openapi.sh

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
2-
# Generate OpenAPI specs from both engine and service apps.
3-
# Output: docs/openapi/engine.json, docs/openapi/service.json
2+
# Generate OpenAPI specs from engine, service, and webhook apps.
3+
# Output: docs/openapi/{engine,service,webhook}.json
44
set -euo pipefail
55

66
cd "$(dirname "$0")/.."
@@ -36,11 +36,20 @@ node -e "
3636
process.stdout.write(JSON.stringify(spec, null, 2) + '\n');
3737
" > "$outdir/service.json"
3838

39-
pnpm prettier --write "$outdir/engine.json" "$outdir/service.json" --log-level warn
39+
echo "Generating webhook OpenAPI spec..."
40+
node -e "
41+
import { createWebhookApp } from './apps/service/dist/api/webhook-app.js';
42+
const app = createWebhookApp({ push_event: () => {} });
43+
const res = await app.request('/openapi.json');
44+
const spec = await res.json();
45+
process.stdout.write(JSON.stringify(spec, null, 2) + '\n');
46+
" > "$outdir/webhook.json"
47+
48+
pnpm prettier --write "$outdir/engine.json" "$outdir/service.json" "$outdir/webhook.json" --log-level warn
4049

4150
if $check_mode; then
4251
drift=false
43-
for spec in engine.json service.json; do
52+
for spec in engine.json service.json webhook.json; do
4453
if ! diff -q "$outdir/$spec" "docs/openapi/$spec" > /dev/null 2>&1; then
4554
echo "DRIFT: docs/openapi/$spec is out of date"
4655
diff --unified "$outdir/$spec" "docs/openapi/$spec" || true
@@ -57,4 +66,5 @@ else
5766
echo "Done:"
5867
echo " docs/openapi/engine.json ($(wc -l < docs/openapi/engine.json) lines)"
5968
echo " docs/openapi/service.json ($(wc -l < docs/openapi/service.json) lines)"
69+
echo " docs/openapi/webhook.json ($(wc -l < docs/openapi/webhook.json) lines)"
6070
fi

scripts/open-docs.sh

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
#!/usr/bin/env bash
2-
# Start engine or service API server and open Scalar docs in the browser.
3-
# Usage: ./scripts/open-docs.sh [engine|service]
2+
# Start engine, service, or webhook server and open Scalar docs in the browser.
3+
# Usage: ./scripts/open-docs.sh [engine|service|webhook]
44
set -euo pipefail
55

66
APP="${1:-engine}"
77
RUN="$(dirname "$0")/ts-run"
88

99
case "$APP" in
10-
engine) PORT="${PORT:-3000}"; ENTRY="apps/engine/src/cli/index.ts" ;;
11-
service) PORT="${PORT:-4020}"; ENTRY="apps/service/src/bin/cli.ts" ;;
12-
*) echo "Usage: $0 [engine|service]" >&2; exit 1 ;;
10+
engine) PORT="${PORT:-3000}"; ENTRY="apps/engine/src/cli/index.ts"; CMD_ARGS="serve --port $PORT" ;;
11+
service) PORT="${PORT:-4020}"; ENTRY="apps/service/src/bin/cli.ts"; CMD_ARGS="serve --port $PORT" ;;
12+
webhook) PORT="${PORT:-4030}"; ENTRY="apps/service/src/bin/cli.ts"; CMD_ARGS="webhook --port $PORT --temporal-address localhost:7233" ;;
13+
*) echo "Usage: $0 [engine|service|webhook]" >&2; exit 1 ;;
1314
esac
1415

15-
CMD="$RUN $ENTRY serve --port $PORT"
16+
CMD="$RUN $ENTRY $CMD_ARGS"
1617

1718
cd "$(dirname "$0")/.."
1819

0 commit comments

Comments
 (0)