Skip to content

MT-22401: Add email campaigns tools - #128

Draft
Rabsztok wants to merge 4 commits into
mainfrom
MT-22401-mcp-email-campaigns
Draft

MT-22401: Add email campaigns tools#128
Rabsztok wants to merge 4 commits into
mainfrom
MT-22401-mcp-email-campaigns

Conversation

@Rabsztok

@Rabsztok Rabsztok commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Draft until the server-side Email Campaigns API changes are released.

Motivation

MT-22401

Port the Email Campaigns public API (MT-21113) to the MCP server.

Do not merge until mailtrap-nodejs#148 is released to npm and the mailtrap dep is bumped here — handlers call client.emailCampaigns.*, which doesn't exist in 4.8.0. Types compile today via a local EmailCampaignsClient interface cast (marked with a TODO(MT-22401) to drop after the bump).

Changes

  • Add 11 tools: list-email-campaigns, get-email-campaign, create-email-campaign, update-email-campaign, delete-email-campaign, start-email-campaign, schedule-email-campaign, cancel-email-campaign, terminate-email-campaign, reset-email-campaign, get-email-campaign-stats
  • Hand-written JSON Schemas from the OpenAPI spec (snake_case, closed objects) with a zod .strict() validation layer on list/create/update/schedule; lifecycle preconditions (draft-only, scheduled-only, sending-states) called out in tool descriptions
  • Responses unwrap the data envelope; list keeps {data, pagination} so page tokens stay usable; delete returns {email_campaign_id, deleted: true}
  • README "Available Tools" sections + CLAUDE.md tool list updated; manifest/version files untouched (release workflow owns them)

How to test

  • With the bumped mailtrap dep and real env vars, ask the MCP client to create a draft campaign, update its design, schedule and cancel it, fetch stats, then delete it
  • Verify a lifecycle 422 (e.g. cancelling a draft) comes back as a readable Failed to cancel email campaign: ... message

Summary by CodeRabbit

  • New Features
    • Added comprehensive email campaign management tools.
    • Campaigns can be listed, viewed, created, updated, deleted, started, scheduled, canceled, terminated, and reset.
    • Added campaign statistics retrieval with optional date filters.
    • Added validation for campaign details, audience settings, delivery options, pagination, and scheduling inputs.
  • Documentation
    • Documented campaign capabilities, parameters, state restrictions, scheduling rules, and statistics filters.
  • Tests
    • Added coverage for successful operations, validation, response handling, and API errors.

Before merge

  • Bump mailtrap to the release that ships emailCampaigns (mailtrap-nodejs PR #148) and remove the temporary EmailCampaignsClient interface and per-handler casts

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 855f1934-5001-4b29-8587-f9c8fb5c82db

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added email campaign tools for CRUD operations, lifecycle management, scheduling, cancellation, termination, reset, listing, retrieval, and statistics. Added typed contracts, validation schemas, server registration, tests, and documentation.

Changes

Email Campaigns

Layer / File(s) Summary
Campaign contracts and validation
src/types/mailtrap.ts, src/tools/emailCampaigns/schemas/*
Added campaign models, client methods, request types, JSON schemas, and strict Zod validation.
Campaign operation handlers
src/tools/emailCampaigns/*.ts, src/tools/emailCampaigns/__tests__/*
Added handlers for campaign CRUD, lifecycle operations, scheduling, and statistics. Added success, validation, response, and API error tests.
Server wiring and documentation
src/server.ts, README.md, CLAUDE.md, src/tools/emailCampaigns/index.ts
Registered the campaign tools and documented their parameters, state restrictions, scheduling rules, and statistics filters.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant Server
  participant EmailCampaignsClient
  MCPClient->>Server: Invoke an email campaign tool
  Server->>EmailCampaignsClient: Execute the campaign operation
  EmailCampaignsClient-->>Server: Return campaign or statistics data
  Server-->>MCPClient: Return formatted tool response
Loading

Possibly related PRs

  • mailtrap/mailtrap-mcp#96: Adds another Mailtrap MCP tool suite with handlers, schemas, registration, documentation, tests, and types.

Suggested reviewers: vladimirtaytor, leonid-shevtsov, piobeny

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description includes motivation, detailed changes, testing steps, and before-merge requirements, with the dependency caveat clearly documented.
Title check ✅ Passed The title clearly identifies the primary change: adding email campaign tools.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Rabsztok

Copy link
Copy Markdown
Contributor Author

Aligned with the account-id fix from the Python/Node.js PRs: all 11 campaign handlers now call requireClient("email campaigns", { requireAccountId: false }) — the endpoints are token-scoped, so the tools no longer demand MAILTRAP_ACCOUNT_ID. 32 campaign tests + lint green.

@Rabsztok
Rabsztok force-pushed the MT-22401-mcp-email-campaigns branch from a2d725e to 44d7081 Compare August 6, 2026 12:06
@Rabsztok
Rabsztok marked this pull request as ready for review August 7, 2026 07:24
@Rabsztok
Rabsztok requested review from IgorDobryn and piobeny August 7, 2026 07:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (3)
src/tools/emailCampaigns/listEmailCampaigns.ts (1)

13-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Use the required per-tool directory layout.

Move this tool to src/tools/emailCampaigns/listEmailCampaigns/. Add index.ts, schema.ts, implementation.ts, and __tests__/.

Apply the same layout to the other campaign tools. The current shared schemas/ and __tests__/ directories do not meet the configured tool structure.

As per coding guidelines, “each tool has subdirectory with index.ts, schema.ts, implementation.ts, and tests/.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tools/emailCampaigns/listEmailCampaigns.ts` around lines 13 - 50,
Restructure the email campaign tools to use per-tool directories: move each tool
into its own directory under emailCampaigns, including listEmailCampaigns, with
index.ts, schema.ts, implementation.ts, and __tests__/; update imports and
exports to preserve existing behavior, and remove reliance on the shared
schemas/ and __tests__/ directories.

Source: Coding guidelines

src/tools/emailCampaigns/getEmailCampaign.ts (1)

12-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use camelCase for campaign request local variables.

The JSON wire fields must remain snake_case. Alias them at destructuring boundaries, then use camelCase variables in each handler.

  • src/tools/emailCampaigns/getEmailCampaign.ts#L12-L20: Alias email_campaign_id to emailCampaignId.
  • src/tools/emailCampaigns/deleteEmailCampaign.ts#L12-L23: Alias email_campaign_id to emailCampaignId.
  • src/tools/emailCampaigns/startEmailCampaign.ts#L12-L20: Alias email_campaign_id to emailCampaignId.
  • src/tools/emailCampaigns/terminateEmailCampaign.ts#L12-L20: Alias email_campaign_id to emailCampaignId.
  • src/tools/emailCampaigns/getEmailCampaignStats.ts#L12-L29: Alias email_campaign_id, start_date, and end_date to camelCase variables.

As per coding guidelines: “Use camelCase for functions and variables.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tools/emailCampaigns/getEmailCampaign.ts` around lines 12 - 20, Alias the
snake_case request fields at destructuring boundaries and use camelCase locals
throughout each handler: in src/tools/emailCampaigns/getEmailCampaign.ts lines
12-20, deleteEmailCampaign.ts lines 12-23, startEmailCampaign.ts lines 12-20,
and terminateEmailCampaign.ts lines 12-20, rename email_campaign_id to
emailCampaignId; in src/tools/emailCampaigns/getEmailCampaignStats.ts lines
12-29, also rename start_date to startDate and end_date to endDate. Preserve the
original snake_case JSON wire fields.

Source: Coding guidelines

src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts (1)

1-23: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Place each campaign tool in its required tool directory.

The reviewed files use shared schemas/ and __tests__/ directories. This does not provide the required per-tool index.ts, schema.ts, implementation.ts, and __tests__/ structure.

  • src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts#L1-L23: move to getEmailCampaignStats/schema.ts.
  • src/tools/emailCampaigns/schemas/resetEmailCampaign.ts#L1-L13: move to resetEmailCampaign/schema.ts.
  • src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts#L1-L27: move to scheduleEmailCampaign/schema.ts.
  • src/tools/emailCampaigns/schemas/startEmailCampaign.ts#L1-L13: move to startEmailCampaign/schema.ts.
  • src/tools/emailCampaigns/schemas/terminateEmailCampaign.ts#L1-L13: move to terminateEmailCampaign/schema.ts.
  • src/tools/emailCampaigns/scheduleEmailCampaign.ts#L1-L39: move to scheduleEmailCampaign/implementation.ts and add its index.ts.
  • src/tools/emailCampaigns/__tests__/scheduleEmailCampaign.test.ts#L1-L71: move under scheduleEmailCampaign/__tests__/.
  • src/tools/emailCampaigns/__tests__/cancelEmailCampaign.test.ts#L1-L48: move under cancelEmailCampaign/__tests__/.
  • src/tools/emailCampaigns/__tests__/terminateEmailCampaign.test.ts#L1-L48: move under terminateEmailCampaign/__tests__/.

As per coding guidelines, src/tools/**/*.ts tools must use a subdirectory with index.ts, schema.ts, implementation.ts, and __tests__/.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts` around lines 1 -
23, Reorganize the email campaign tools into per-tool directories with index.ts,
schema.ts, implementation.ts, and __tests__/ structures. Move the schemas from
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts,
resetEmailCampaign.ts, scheduleEmailCampaign.ts, startEmailCampaign.ts, and
terminateEmailCampaign.ts to their corresponding tool directories as schema.ts;
move src/tools/emailCampaigns/scheduleEmailCampaign.ts to
scheduleEmailCampaign/implementation.ts and add its index.ts; move the schedule,
cancel, and terminate test files from src/tools/emailCampaigns/__tests__/ into
their corresponding tool __tests__/ directories. Update imports and exports to
preserve existing tool behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLAUDE.md`:
- Around line 182-195: Update the environment-variable documentation to include
all email campaign tools in the exception for MAILTRAP_ACCOUNT_ID, alongside
send-email and send-sandbox-email, reflecting the requireClient("email
campaigns", { requireAccountId: false }) behavior.

In `@src/tools/emailCampaigns/createEmailCampaign.ts`:
- Around line 23-27: Upgrade the Mailtrap SDK dependency to a release that
implements the emailCampaigns API, then update the client setup in the
createEmailCampaign flow to use the SDK-provided EmailCampaignsClient type and
remove the temporary unknown cast before calling mailtrap.emailCampaigns.create.

In `@src/tools/emailCampaigns/getEmailCampaign.ts`:
- Around line 16-20: Upgrade the mailtrap dependency in package.json and
package-lock.json to the future SDK release that provides EmailCampaignsClient
and emailCampaigns before exposing these handlers. Apply the dependency
alignment for getEmailCampaign.ts, deleteEmailCampaign.ts,
startEmailCampaign.ts, terminateEmailCampaign.ts, and getEmailCampaignStats.ts;
no direct handler logic change is required.

In `@src/tools/emailCampaigns/index.ts`:
- Around line 1-22: Reorganize the eleven campaign tools imported by
emailCampaigns/index.ts so each tool has its own directory containing index.ts,
schema.ts, implementation.ts, and __tests__/. Move the corresponding schema and
implementation files together for listEmailCampaigns, getEmailCampaign,
createEmailCampaign, updateEmailCampaign, deleteEmailCampaign,
startEmailCampaign, scheduleEmailCampaign, cancelEmailCampaign,
terminateEmailCampaign, resetEmailCampaign, and getEmailCampaignStats, and leave
emailCampaigns/index.ts only for group-level exports.

In `@src/tools/emailCampaigns/schemas/cancelEmailCampaign.ts`:
- Around line 4-5: Update the email_campaign_id schema property in
cancelEmailCampaign.ts (lines 4-5), deleteEmailCampaign.ts (lines 4-5), and
getEmailCampaign.ts (lines 4-5) to use type "integer" with minimum 1, ensuring
all campaign-ID schemas accept only positive integers.

In `@src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts`:
- Around line 4-7: Constrain the email_campaign_id property in every exposed
schema to positive integers by using type "integer" and minimum 1, matching the
existing Zod identifier constraint. Apply this in
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts (lines 4-7),
resetEmailCampaign.ts (lines 4-7), scheduleEmailCampaign.ts (lines 6-9),
startEmailCampaign.ts (lines 4-7), and terminateEmailCampaign.ts (lines 4-7).
- Around line 8-17: Update the start_date and end_date properties in the email
campaign stats schema to validate the documented YYYY-MM-DD format, using a
pattern or equivalent date constraint that rejects invalid strings while
preserving their existing optional defaults and descriptions.

In `@src/tools/emailCampaigns/schemas/listEmailCampaigns.ts`:
- Around line 6-14: Align both email campaign JSON Schemas with their Zod
validators: in src/tools/emailCampaigns/schemas/listEmailCampaigns.ts lines
6-14, make token and per_page positive integers and set per_page.maximum to 100;
in src/tools/emailCampaigns/schemas/updateEmailCampaign.ts lines 6-107, make
campaign, list, and segment IDs plus emails_per_hour integers and add every
minimum constraint enforced by the corresponding Zod validator.

In `@src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts`:
- Around line 20-25: The scheduleEmailCampaignZod schema must validate datetime
invariants before scheduling: use offset-aware datetime parsing, require a
future timestamp, and reject values more than one month ahead. In
src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts at lines 20-25, update
the datetime validation and refinements; in
src/tools/emailCampaigns/__tests__/scheduleEmailCampaign.test.ts at lines 20-54,
change the success fixture to a future timestamp and add rejection coverage for
non-ISO, past, and over-one-month values.

In `@src/tools/emailCampaigns/schemas/updateEmailCampaign.ts`:
- Around line 61-64: Update the body_text field in the UpdateEmailCampaignParams
schema to accept optional null values by using the nullable optional Zod type,
and update its JSON Schema representation to allow both string and null while
preserving the existing description and optional behavior.
- Around line 110-144: Update updateEmailCampaignZod and its corresponding JSON
Schema so requests must include at least one mutable field in addition to
email_campaign_id. Apply the non-empty update constraint to the existing
optional fields without making the required identifier optional, and ensure both
validation definitions reject identifier-only payloads.

In `@src/types/mailtrap.ts`:
- Around line 803-832: Upgrade the mailtrap dependency to a release that
provides the runtime emailCampaigns resource, then remove the temporary
EmailCampaignsClient interface and all per-handler casts relying on it. Update
campaign handlers to use the typed SDK client directly while preserving the
existing campaign operations.

---

Nitpick comments:
In `@src/tools/emailCampaigns/getEmailCampaign.ts`:
- Around line 12-20: Alias the snake_case request fields at destructuring
boundaries and use camelCase locals throughout each handler: in
src/tools/emailCampaigns/getEmailCampaign.ts lines 12-20, deleteEmailCampaign.ts
lines 12-23, startEmailCampaign.ts lines 12-20, and terminateEmailCampaign.ts
lines 12-20, rename email_campaign_id to emailCampaignId; in
src/tools/emailCampaigns/getEmailCampaignStats.ts lines 12-29, also rename
start_date to startDate and end_date to endDate. Preserve the original
snake_case JSON wire fields.

In `@src/tools/emailCampaigns/listEmailCampaigns.ts`:
- Around line 13-50: Restructure the email campaign tools to use per-tool
directories: move each tool into its own directory under emailCampaigns,
including listEmailCampaigns, with index.ts, schema.ts, implementation.ts, and
__tests__/; update imports and exports to preserve existing behavior, and remove
reliance on the shared schemas/ and __tests__/ directories.

In `@src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts`:
- Around line 1-23: Reorganize the email campaign tools into per-tool
directories with index.ts, schema.ts, implementation.ts, and __tests__/
structures. Move the schemas from
src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts,
resetEmailCampaign.ts, scheduleEmailCampaign.ts, startEmailCampaign.ts, and
terminateEmailCampaign.ts to their corresponding tool directories as schema.ts;
move src/tools/emailCampaigns/scheduleEmailCampaign.ts to
scheduleEmailCampaign/implementation.ts and add its index.ts; move the schedule,
cancel, and terminate test files from src/tools/emailCampaigns/__tests__/ into
their corresponding tool __tests__/ directories. Update imports and exports to
preserve existing tool behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d43326b4-34a7-48df-b3cb-dcc2541858d5

📥 Commits

Reviewing files that changed from the base of the PR and between 574eb72 and 44d7081.

📒 Files selected for processing (38)
  • CLAUDE.md
  • README.md
  • src/server.ts
  • src/tools/emailCampaigns/__tests__/cancelEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/createEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/deleteEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/getEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/getEmailCampaignStats.test.ts
  • src/tools/emailCampaigns/__tests__/listEmailCampaigns.test.ts
  • src/tools/emailCampaigns/__tests__/resetEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/scheduleEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/startEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/terminateEmailCampaign.test.ts
  • src/tools/emailCampaigns/__tests__/updateEmailCampaign.test.ts
  • src/tools/emailCampaigns/cancelEmailCampaign.ts
  • src/tools/emailCampaigns/createEmailCampaign.ts
  • src/tools/emailCampaigns/deleteEmailCampaign.ts
  • src/tools/emailCampaigns/getEmailCampaign.ts
  • src/tools/emailCampaigns/getEmailCampaignStats.ts
  • src/tools/emailCampaigns/index.ts
  • src/tools/emailCampaigns/listEmailCampaigns.ts
  • src/tools/emailCampaigns/resetEmailCampaign.ts
  • src/tools/emailCampaigns/scheduleEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/cancelEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/createEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/deleteEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/getEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/getEmailCampaignStats.ts
  • src/tools/emailCampaigns/schemas/listEmailCampaigns.ts
  • src/tools/emailCampaigns/schemas/resetEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/startEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/terminateEmailCampaign.ts
  • src/tools/emailCampaigns/schemas/updateEmailCampaign.ts
  • src/tools/emailCampaigns/startEmailCampaign.ts
  • src/tools/emailCampaigns/terminateEmailCampaign.ts
  • src/tools/emailCampaigns/updateEmailCampaign.ts
  • src/types/mailtrap.ts

Comment thread CLAUDE.md
Comment thread src/tools/emailCampaigns/createEmailCampaign.ts
Comment thread src/tools/emailCampaigns/getEmailCampaign.ts
Comment thread src/tools/emailCampaigns/index.ts
Comment thread src/tools/emailCampaigns/schemas/cancelEmailCampaign.ts Outdated
Comment thread src/tools/emailCampaigns/schemas/listEmailCampaigns.ts
Comment thread src/tools/emailCampaigns/schemas/scheduleEmailCampaign.ts
Comment thread src/tools/emailCampaigns/schemas/updateEmailCampaign.ts Outdated
Comment thread src/tools/emailCampaigns/schemas/updateEmailCampaign.ts Outdated
Comment thread src/types/mailtrap.ts
@Rabsztok
Rabsztok marked this pull request as draft August 7, 2026 09:51
Decisions:
- 11 tools mirror src/tools/contactLists/ layout (one file per tool, schemas/, __tests__, barrel index.ts), registered after the contacts group in src/server.ts
- Handlers target the future mailtrap npm emailCampaigns surface via a local EmailCampaignsClient interface in src/types/mailtrap.ts with a single TODO(MT-22401) to drop the casts after the SDK release
- Single-object and stats responses unwrap the {data} envelope; list keeps {data, pagination} so page tokens stay visible; delete returns a {email_campaign_id, deleted: true} confirmation
- Zod validation layer added for list/create/update/schedule per repo CLAUDE.md recommendation
- readOnlyHint for list/get/stats; destructiveHint: true for create/update/delete and all five lifecycle tools per the MT-22401 plan
Decisions:
- The email campaigns endpoints are token-scoped, so the handlers now
  pass requireAccountId: false (listAccounts precedent), matching the
  same fix in the Python and Node.js SDK PRs
@Rabsztok
Rabsztok force-pushed the MT-22401-mcp-email-campaigns branch from 44d7081 to fdcd44b Compare August 7, 2026 11:31
Decisions:
- Rename EmailCampaignPagination to Pagination; nothing in it is campaign-specific
- Move it to a Common types section so the next paginated tool reuses it
Decisions:
- The backend allows deleting only a campaign in the draft state
  (EmailCampaign#validate_soft_delete), not merely a non-sending one
- Examples deleted a campaign after start/terminate, which would 422; a started
  campaign can never return to draft, so they now delete a fresh draft
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant