Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# `build-routes` (campaigns)
## Purpose
`buildCampaignRoutes` is the single aggregator that materialises every
`/campaigns/*` `PluginRouteEntry` in a canonical order. The plugin's
`onInit` consumes the array verbatim — there is no per-route opt-in or
configuration knob — so the OpenAPI spec generated for the campaigns
tree is deterministic across deployments and across reloads. Tests
assert the canonical order so accidental reordering during refactors
surfaces immediately rather than as silent spec drift.
The aggregator is intentionally a flat function returning a readonly
array (rather than a class or builder). The cost of describing 12
routes inline is small, the structure is obvious, and downstream
consumers can `array.map(toPrefixed)` cheaply when they need to mount
under a non-root prefix.
## Features
- Returns 12 entries in a documented canonical order.
- Pure: no I/O, no side effects, no captured registry.
- Each entry exposes `route: RouteConfig` + `handler: RouteHandler` so
it can be mounted either via `definePluginRoutes` (production) or
directly on a bare `Hono` app (tests).
## Usage: Basic
```ts
import { buildCampaignRoutes } from "@suaveplan/api-plugin-campaigns";
const entries = buildCampaignRoutes();
for (const e of entries) {
app[e.route.method as "get" | "post" | "patch" | "delete"](
e.route.path,
(c) => e.handler(c)
);
}
```
## Usage: Advanced
```ts
import {
buildCampaignRoutes,
definePluginRoutes,
} from "@suaveplan/api-plugin-campaigns";
const prefix = "/api/v1";
const prefixed = buildCampaignRoutes().map((e) => ({
...e,
route: { ...e.route, path: `${prefix}${e.route.path}` },
}));
definePluginRoutes(prefixed, { app, registry, pluginName: "campaigns" });
```
## API Reference
- `buildCampaignRoutes(): readonly PluginRouteEntry[]` — returns the
12 canonical campaign route entries.
## Implementation Notes
The canonical order — list, create, get, update, delete, send, pause,
cancel, duplicate, test, stats, events — places the read endpoints
before write/action endpoints (so OpenAPI consumers naturally see the
read surface first) and groups the lifecycle action routes together.
The `events` route comes last because it depends on the
`deliveryEventStore` slot being populated, which is the only
non-trivial dependency in the bundle; co-locating it with `stats`
makes the dependency footprint visible at a glance.