Files
suaveplan/openspec/changes/enterprise-react-campaigns/proposal.md
2026-05-27 23:29:53 +01:00

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

  1. CampaignUiError — codes: CAMPAIGN_ENGINE_MISSING, CAMPAIGN_UPDATE_FAILED, CAMPAIGN_SEND_FAILED.
  2. CampaignEngineProvider — React context replacing module-scoped defaultEngine; every hook resolves engine via context or throws CampaignUiError(CAMPAIGN_ENGINE_MISSING) in dev.
  3. useCampaign.update fix — calls real engine update path (main branch re-fetched instead of updating).
  4. CampaignBuilder split — per-step subcomponents in steps/ keeping top-level file under 250 lines.
  5. CampaignsErrorBoundary — exported wrapper via @suaveplan/react-error-boundary.
  6. Missing tests — campaign-builder, campaign-detail, use-campaign-stats all fully covered.
  7. OTel counters — campaign.created, campaign.sent, campaign.cancelled, campaign.duplicated.
  8. Draft auto-save — debounced save in CampaignBuilder with local restore on mount.
  9. 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