feat(marketer): campaign/content draft-approve-schedule-publish loop (#3148/#3149) - #4016
Open
kevinthelago wants to merge 2 commits into
Open
feat(marketer): campaign/content draft-approve-schedule-publish loop (#3148/#3149)#4016kevinthelago wants to merge 2 commits into
kevinthelago wants to merge 2 commits into
Conversation
…3148/#3149) Adds the Marketer feature's frontend: a pure domain model + state machine for campaigns/content items (draft -> approved -> scheduled -> published, #3148), compliance guardrails that block approval on noncompliant content (missing unsubscribe/sender identity, PII, over-length social posts, #3150), a channel-status view over the mcp feature's server catalog (#3146), an analytics read-back with graceful degrade when the backend isn't wired yet (#3149), and the workspace UI tying it together. Not yet mounted to a rail Workspace/Settings page or folded into the composed app store -- both are narrow follow-up integration steps outside this feature's write scope. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WDc7B2fkQxzAjhZPRfTRQ7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The frontend slice of the Marketer epic's remaining phases (#3145 P3/P4), scoped to
src/features/marketer/**per the marketer stream's fleet assignment.lib/campaign.ts) —Campaign/ContentItem, thedraft → approved → {scheduled, published}transitions (Marketer P3 — campaign/content store + draft→approve→publish loop #3148: publish is never reachable directly from draft),dueForDispatchfor scheduled items whose fire time has passed.lib/compliance.ts, Marketer P5 — persona rewrite + skills + docs + compliance guardrails #3150) — email requires an unsubscribe link + sender identity (CAN-SPAM/GDPR); social enforces a channel length limit; all content is checked for PII-shaped strings. A content item with any violation cannot reachapproved(enforced instore.ts'sapproveContentItem).lib/channels.ts, Marketer P1 — first channel MCP server + keychain-backed secret env #3146) — derives a channel list from themcpfeature's installed-server catalog (consumed only via its public barrel,@/features/mcp), tagging installed/assigned state.lib/metrics.ts, Marketer P4 — analytics read-back + iterate #3149) — rollup + per-channel readout formatting, mirroringcrates/channel'sget_metricsshape ({ total, by_tool }).lib/api.ts) —marketing_*Tauri command calls with graceful degrade (the same patternsourceConnection.tsuses fordata_platform_scan): the UI works standalone today and will pick up the real backend the momentcrates/marketing+ its Tauri commands land, with no code change.store.ts) — a standalone Zustand store (persisted via the samepersistStorageadapter the composed app store uses, under its own"bsc-marketer"key). Not folded intouseAppStore— that needs a two-line edit tosrc/store/index.ts+src/store/types.ts, both outside this feature's write scope. Noted as a follow-up integration step.MarketerWorkspace.tsx,ContentDrawer.tsx,MarketerStatus.tsx) — Campaigns/Channels/Analytics tabs, the compose→approve→schedule→publish drawer, and a compact status widget. Not yet mounted to a rail Workspace or Settings page (a director-owned integration step); exported from the feature'sindex.tsbarrel, ready for it.Notes on scope
#3146's remaining acceptance criteria (keychain-backed secretenv, the Settings "connect a channel" UI) are deliberately deferred per the issue's own comment thread — the owner noted both land when the real beautiful-emails channel needs credentials, not for the mock channel.#3147(outbound confirm gate + role tier) and the rest of#3150(persona/skills/docs) touchsrc/shared/lib/session/**andsrc-tauri/data/personas/**— outside this feature's write scope; left to whichever stream owns those paths.#3800(Glance marketing tab + standing maintainer session) is explicitly filed-not-scheduled in the epic.Test plan
npm run typecheck— cleannpm run lint— 0 errors insrc/features/marketer/**(0 new warnings)npx vitest run src/features/marketer— 48/48 passing (pure lib tests, store tests, component tests)npm test(full suite) — 6076/6078 passing; the 2 failures are pre-existing, unrelatedsrc/features/designs/lib/reactUiKit.gen.test.tsCRLF hash-sidecar failures (untouched by this PR)Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01WDc7B2fkQxzAjhZPRfTRQ7