Skip to content

Add campaign contact frequency caps to TypeScript SDK - #351

Merged
purpshell merged 2 commits into
mainfrom
feat/campaign-frequency-cap
Oct 17, 2026
Merged

purpshell merged 2 commits into
mainfrom
feat/campaign-frequency-cap

Conversation

@purpshell

@purpshell purpshell commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Summary

Add TypeScript support for campaign contact frequency caps from merged API dev e404a727dd. Team settings preserve revisions and 409 conflicts; campaign requests, recipient reason filters and skip analytics match the merged contract. Existing feature_unavailable errors remain typed.

Companion PRs: SDK #351, CLI #80, docs #619. Native-client additions on active SDK #348.

Impact

Impact table

Area Updated / blocked Change or named blocker Evidence
SDKs Updated TypeScript; native additions handed to active draft #348 Team revision-guarded GET/PUT, campaign fields, reason filter, analytics and beta errors #348 and frequency-cap contract tests
CLI Updated; publication blocked Settings get/set/remove, campaign cap flags, skips; unchanged SDK pin until matching SDK prerelease CLI companion PR
Documentation Updated SDK/CLI examples and release availability boundary Monorepo docs companion PR
Feature release / rollout Blocked SDK prerelease secrets and matching staging acceptance remain prerequisites; no availability advanced API source e404a727dd, backend #601, Console #609
Roadmap and session checkpoint Blocked Parent orchestrator owns existing Linear/Notion reconciliation and sanitized transcript checkpoint; no links fabricated Parent thread 646a0c0a-e900-4d0f-9a25-0b8834d7d4e6

No impact table

Area Why there is no impact Evidence
API and Admin controls/MCP Consume merged contracts; no server route, scope or staff capability changes Backend #601 and merged OpenAPI
Libraries, runners/Bartender, Temporal and Inspector Client wrappers and documentation only; dispatch and native transport untouched Changed files confined to SDK/CLI/docs
Console and Admin UI No UI code changed; Console work already merged separately Console #609
Onboarding and consent / user analysis Existing API-key resolution retained; no telemetry or collection added Existing client transport and CLI BaseCommand
Billing/upgrade, PAYG and Usage No price, entitlement, funding or meter changes Only cap request fields and output projections
Logs and audit logs No storage or event producer changes API retains existing request/error behavior
Customer Analytics Server calculation unchanged; clients expose existing skippedRecipientCount Merged Platform/Messaging schemas
Help Center and marketing No audience or availability widened; no launch copy changed Existing campaign safety guide remains authoritative

Verification

Node 24 typecheck, lint, format, all workspace builds, coverage ledger and function checks pass. Full suite: 1,521 tests pass before the final added projection test; all six frequency-cap HTTP/contract tests pass at head 5583e43. CI tests both Node 20 and 22. Synthetic HTTP covers settings GET/PUT/null, 409/403 codes without write retries, campaign fields on both APIs, read projections, skip analytics and reason filters. No deployed API or native send exercised.

Session provenance and UI evidence

Parent T3 thread: 646a0c0a-e900-4d0f-9a25-0b8834d7d4e6. Implementation agent: OpenAI gpt-6.1-sol, T3 Code Codex harness. Shared brief and repository guides read; implementation sequential, no delegated agents or requested automated reviews. The parent orchestrator owns publication of the sanitized transcript checkpoint and registration link; those links remain pending. No graphical UI changed. CLI output and SDK transport use synthetic loopback HTTP fixtures, not customer data.

Rollout and rollback

Do not merge or publish as part of this task. Merge SDK source before updating the CLI to a matching accepted SDK prerelease; then release CLI and publish aligned documentation only after acceptance. Existing API contract date is unchanged. Beta enrollment remains server enforced; reads and cap removal remain available without beta access. Revert these additive client/doc changes if necessary; no migration or data rollback is required. No deployed API, native send or hosted beta acceptance was exercised.

Open questions: publication secrets and staging acceptance are owned by release coordination. No product decision remains open.

Summary by CodeRabbit

  • New Features
    • Added beta support for team- and campaign-level contact frequency caps, including reading, updating, and clearing limits.
    • Campaign recipient lists can be filtered by failure reason and include failure details; analytics report recipients skipped by frequency caps.
    • Updates detect stale revisions and may require beta access. Raising limits does not retry recipients already skipped.
  • Documentation
    • Added guidance on frequency caps and their beta access and release requirements.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T06:42:35.584877Z 83eb304 PR opened
🔒 Security Review ✅ Completed 2026-10-17T06:41:08.117876Z 83eb304 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Team
  • Run ID: d95d523b-7795-47c0-9292-b8373d00888e
📥 Commits

Reviewing files that changed from the base of the PR and between daac84b and 5583e43.

📒 Files selected for processing: 10
  • CHANGELOG.md
  • contracts/README.md
  • contracts/campaign-frequency-cap.json
  • packages/typescript/README.md
  • packages/typescript/src/index.ts
  • packages/typescript/src/messaging/campaigns.ts
  • packages/typescript/src/messaging/types.ts
  • packages/typescript/src/platform/campaigns.ts
  • packages/typescript/src/platform/types.ts
  • packages/typescript/test/campaign-frequency-cap.test.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour.

📝 Walkthrough

The TypeScript SDK adds team and campaign frequency-cap types and operations. It supports revision-checked team limit updates, campaign cap fields, recipient failure-reason filters, and analytics data. The change also adds a pinned API contract snapshot, tests, and beta documentation.

Changes: Campaign frequency caps

Layer / File(s) Summary
Contracts and TypeScript shapes
contracts/campaign-frequency-cap.json, contracts/README.md, packages/typescript/src/messaging/types.ts, packages/typescript/src/platform/types.ts, packages/typescript/src/index.ts, packages/typescript/test/campaign-frequency-cap.test.ts
The API snapshot documents cap limits, revision-based updates, campaign restrictions, and recipient failure reasons. TypeScript types expose these settings, campaign fields, analytics counts, and recipient filters. Contract and type tests check the documented shapes and limits.
SDK operations and validation
packages/typescript/src/platform/campaigns.ts, packages/typescript/src/messaging/campaigns.ts, packages/typescript/test/campaign-frequency-cap.test.ts, packages/typescript/README.md, CHANGELOG.md
The SDK adds team cap retrieval and updates, disables automatic retries for cap updates, and forwards recipient-reason filters. Tests cover update requests, error responses, campaign data, analytics, and recipient failures. Documentation describes beta access and release gates.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant CampaignsResource
  participant PlatformAPI
  Caller->>CampaignsResource: getFrequencyCap()
  CampaignsResource->>PlatformAPI: GET team frequency-cap settings
  PlatformAPI-->>CampaignsResource: settings and revision
  Caller->>CampaignsResource: updateFrequencyCap(limits, revision)
  CampaignsResource->>PlatformAPI: PUT limits and revision, no automatic retries
  PlatformAPI-->>CampaignsResource: updated settings or error
Loading
Merge Risk: ⚪ Minimal · up to 5583e

No actionable issue remains from this review. Normal release checks and the stated staging acceptance prerequisites still apply.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding campaign contact frequency cap support to the TypeScript SDK.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 6…
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.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 6 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83eb304784

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"messaging": {
"sourcePath": "apps/api/docs/openapi.json",
"sourceSha256": "9d8faf13be970bee800ad15e308c130bc4ae8703865ae99278b9ae315cc27638",
"schemas": {},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include the Messaging frequency-cap schemas

When this supplement is combined with the pinned openapi.messaging.json, its new CampaignFrequencyCap and CampaignFrequencyCapAnalytics references cannot be resolved because schemas is empty and the pinned snapshot predates both definitions. This also leaves the Messaging limits and analytics shape unrecorded and untested, so add both new schema definitions here rather than relying on the Platform copy.

Useful? React with 👍 / 👎.

readonly maxPer7Days: number | null;
}

export type CampaignRecipientFailureReason =

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep recipient failure reasons forward-compatible

When the API adds a new failure code—as the accompanying contract explicitly says it may—this closed union makes CampaignRecipient.failureReason unsound and can lead consumers to treat exhaustive switches as complete even though an unknown string arrives at runtime. Keep the query filter restricted to the accepted known values, but model the response reason as the known union plus string & {}, following the SDK's existing forward-compatible enum pattern.

Useful? React with 👍 / 👎.

@purpshell
purpshell merged commit 55f75dc into main Oct 17, 2026
3 checks passed
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