Files
suaveplan/openspec/archive/2026-05-24-api-plugin-campaigns/proposal.md
2026-05-27 23:29:53 +01:00

53 lines
2.6 KiB
Markdown

# Migrate `@suaveplan/api-plugin-campaigns` (chunked: A → B → C)
## Why
`@suaveplan/api-plugin-campaigns` mounts the campaigns / suppression / webhooks
HTTP surface (consumed by `@suaveplan/campaigns`, `@suaveplan/delivery-tracking`,
and a per-tenant `CampaignSuppressionStore`) onto the genesis API host. Two
prior single-agent migration attempts halted at the size of the full port, so
this change ships the package in three sequential, independently-greenable
chunks. Each chunk passes lint/typecheck/test/coverage on its own subset.
## What changes
Add the package `@suaveplan/api-plugin-campaigns@0.1.0` under
`packages/api-stack/api/api-plugin-campaigns/`, server-tier, sharing the shape
of the genesis-already-shipped `@suaveplan/api-plugin-contacts`.
- **Chunk A (this change body)** — foundation: package shell + vite/vitest/ts
configs, error-code namespace + `CampaignsApiError`, OTel instrument bundle,
Zod options schema, shared option/config types, plugin scaffold via
`definePlugin` from `@suaveplan/api-plugin` with a no-op `onInit` (B/C wire
the real lifecycle), package barrel.
- **Chunk B (follow-up)** — repositories: `SurrealCampaignRepository`,
`CampaignSuppressionStore` interface + `SurrealCampaignSuppressionStore`,
consumption of `@suaveplan/delivery-tracking`'s
`SurrealDeliveryEventStore`, schema DDL bundle, repository registration
inside `onInit`.
- **Chunk C (follow-up)** — routes: `/campaigns` CRUD + lifecycle endpoints,
`/suppression` list/add/remove, `/webhooks/:provider` ingestion, full Hono
route wiring with OpenAPI registry, integration tests against the SurrealDB
testcontainer.
## Impact
- **Affected specs**: new capability `api-plugin-campaigns`.
- **Affected code**: new package only.
- **Dependencies pulled**: `@suaveplan/api-plugin`, `@suaveplan/api-openapi`,
`@suaveplan/api-plugin-auth`, `@suaveplan/api-plugin-database`,
`@suaveplan/api-plugin-contacts`, `@suaveplan/campaigns`,
`@suaveplan/contacts`, `@suaveplan/delivery-tracking`,
`@suaveplan/surrealdb`, `@suaveplan/events`, `@suaveplan/error`,
`@suaveplan/types`, `@suaveplan/logger`, `@opentelemetry/api`, `hono`,
`@hono/zod-openapi`, `tslib`, `zod`.
- **Quality gates per chunk**: `bunx turbo lint typecheck test --filter` green
and `bunx turbo test:coverage --filter` 100/100/100/100 on the modules
shipped in that chunk.
## Why chunked
Two prior single-agent attempts halted at the full-package size. Splitting at
the dependency boundaries (foundation ↔ data ↔ routes) keeps each chunk under
the limit while leaving every intermediate state green.