4.2 KiB
OpenSpec Change: enterprise-react-campaigns
- Change ID: enterprise-react-campaigns
- Package:
@suaveplan/react-campaigns - Category: react
- Target path:
react/platform/react-campaigns - Status: PROPOSED
- Date: 2026-04-24
- Reference spec:
/mnt/s/web/suaveplan/enterprise/react-campaigns.md
Summary
Deliver @suaveplan/react-campaigns on genesis from scratch at enterprise quality. React UI layer on top of @suaveplan/campaigns: five-step CampaignBuilder wizard (basics → audience → template → schedule → review), CampaignList, CampaignDetail, CampaignAnalytics, CampaignStatusBadge, AudienceSelector, and three hooks (useCampaign, useCampaignList, useCampaignStats). Genesis fixes the useCampaign.update contract (main branch re-fetched instead of calling engine update), removes the module-scoped default engine in favour of CampaignEngineProvider, splits campaign-builder.tsx past the 300-line limit into per-step subcomponents, and adds missing tests for campaign-builder, campaign-detail, and use-campaign-stats.
Current-state audit (genesis)
Package does not exist on genesis — fresh build.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/error (workspace:^) |
CampaignUiError |
@suaveplan/campaigns (workspace:^) |
Campaign engine, schemas, store |
@suaveplan/react-translate (workspace:^) |
i18n for all UI strings |
@suaveplan/react-error-boundary (workspace:^) |
CampaignsErrorBoundary |
@opentelemetry/api (catalog:observability) |
campaign.* counters + spans |
zod (catalog:forms) |
Boundary validation |
tslib (catalog:build) |
TS helpers |
External: React 18 peer.
Preserved public API surface
// Provider
CampaignEngineProvider, useCampaignEngine
// Components
CampaignBuilder, CampaignList, CampaignDetail,
CampaignAnalytics, CampaignStatusBadge, AudienceSelector,
CampaignsErrorBoundary
// Hooks
useCampaign, useCampaignList, useCampaignStats
// Types
AudienceGroup, CampaignBuilderProps, CampaignListProps,
CampaignDetailProps, CampaignAnalyticsProps, CampaignStatusBadgeProps,
AudienceSelectorProps, UseCampaignOptions, UseCampaignReturn,
UseCampaignListOptions, UseCampaignListReturn,
UseCampaignStatsOptions, UseCampaignStatsReturn
New additions for genesis
CampaignUiError— codes:CAMPAIGN_ENGINE_MISSING,CAMPAIGN_UPDATE_FAILED,CAMPAIGN_SEND_FAILED.CampaignEngineProvider— React context replacing module-scopeddefaultEngine; every hook resolves engine via context or throwsCampaignUiError(CAMPAIGN_ENGINE_MISSING)in dev.useCampaign.updatefix — calls real engine update path (main branch re-fetched instead of updating).CampaignBuildersplit — per-step subcomponents insteps/keeping top-level file under 250 lines.CampaignsErrorBoundary— exported wrapper via@suaveplan/react-error-boundary.- Missing tests —
campaign-builder,campaign-detail,use-campaign-statsall fully covered. - OTel counters —
campaign.created,campaign.sent,campaign.cancelled,campaign.duplicated. - Draft auto-save — debounced save in
CampaignBuilderwith local restore on mount. - Playwright E2E — wizard happy path, list filter + pagination, keyboard-only, mobile viewport.
File layout
react/platform/react-campaigns/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
types/
provider/
campaign-engine-provider/ (tsx + md + test + index)
components/
campaign-builder/
campaign-builder.tsx + types + md + test + stories + index
steps/
basics.tsx audience.tsx template.tsx schedule.tsx review.tsx
campaign-list/ (tsx + types + md + test + stories + index)
campaign-detail/ (tsx + types + md + test + stories + index)
campaign-analytics/ (tsx + types + md + test + stories + index)
campaign-status-badge/ (tsx + types + md + test + stories + index)
audience-selector/ (tsx + types + md + test + stories + index)
hooks/
use-campaign/ use-campaign-list/ use-campaign-stats/
e2e/
campaigns.spec.ts