# `build-routes.ts` — webhook plugin route entries _(no submodules)_ ## Purpose Builds the six CRUD + test route entries the webhook plugin mounts on the host's Hono app. Each entry pairs a Zod-typed `RouteConfig` (constructed via `@suaveplan/api-openapi`'s `RouteBuilder`) with a thin handler that delegates to the supplied `WebhookService`. The plugin's `onInit` installs `requireAuth()` upstream so anonymous requests hit 401 before any handler runs; the handlers themselves enforce tenant scoping when the request principal carries a `tenantId`. Re-exports `requireAuth` from `@suaveplan/api-plugin-auth` for callers that mount the routes manually. ## Features - Six routes — `GET /`, `POST /`, `GET /{id}`, `PATCH /{id}`, `DELETE /{id}`, `POST /{id}/test`. - Tenant scoping — every handler that reads / writes an endpoint enforces that the principal's `tenantId` matches the endpoint's; cross-tenant access returns 404 (the endpoint is hidden from the calling tenant). - Validation — request bodies are Zod-parsed at the handler entry so malformed JSON returns a structured error. - The test route returns the `DeliveryResult` shape (status + finalStatusCode + attempts) so operators can confirm the receiver is healthy without firing real business data. ## Usage: Basic ```ts import { buildWebhookRoutes } from "@suaveplan/api-plugin-webhook/routes/routes"; import { definePluginRoutes } from "@suaveplan/api-openapi"; const entries = buildWebhookRoutes(service); definePluginRoutes(entries, { app, registry: openAPIRegistry, pluginName: "webhook" }); ``` ## Usage: Advanced ```ts // Mount on a sub-router gated by requireAuth() before delegation import { Hono } from "hono"; import { buildWebhookRoutes, requireAuth } from "@suaveplan/api-plugin-webhook/routes/routes"; const sub = new Hono(); sub.use("*", requireAuth()); for (const entry of buildWebhookRoutes(service)) { const method = entry.route.method.toLowerCase() as "get" | "post" | "patch" | "delete"; sub[method](entry.route.path.replace(/{(\w+)}/g, ":$1"), entry.handler as never); } app.route("/webhooks", sub); ``` ## API Reference - `buildWebhookRoutes(service)` — returns `PluginRouteEntry[]`. Six entries in this order: list, create, read, update, delete, test. - `requireAuth` — re-export of `@suaveplan/api-plugin-auth`'s `requireAuth()`. Apply BEFORE mounting these routes. ## Implementation Notes The handlers do not call `requireAuth` directly because Hono's middleware chain composes more naturally when authentication is installed at the router level. Mounting `requireAuth` per-handler would require every handler to re-narrow `c.get("user")`; installing it at the router level lets the handlers consume `Principal` via the augmented `ContextVariableMap` from `@suaveplan/api-plugin-auth` with no extra ceremony. The "load-then-check-tenant" pattern (rather than "list filtered by tenant then index") is deliberate — it produces consistent 404 responses regardless of whether the endpoint exists in another tenant.