Skip to content

Calls: number_restricted, session.restriction_updated and typed logout reasons - #282

Merged
purpshell merged 11 commits into
devfrom
t3code/calls-bansafe
Sep 23, 2026
Merged

purpshell merged 11 commits into
devfrom
t3code/calls-bansafe

Conversation

@purpshell

@purpshell purpshell commented Sep 20, 2026 •

Copy link
Copy Markdown
Member

Calls restrictions now retain their typed error and lifecycle values across the server SDK and Calls client. This consumes merged monorepo PRs #231 and #233. Contract files are byte-identical to monorepo dev commit 63111fec728ac3ebc9a825ea57ebc4c592abdafc; there is no pending overlay.

  • Recognizes number_restricted, session.restriction_updated, structured logout reasons and WhatsApp codes.
  • Preserves call_restricted in Call.endReason and both ended events, including the runtime parser.
  • Types previousBand as BanSafeHealthBandName | null and keeps one copy of each BanSafe payload definition.
  • Recognizes the contract's addon_required code after the retirement of premium_required.

Verification

Full suites pass on Node 20 and 22: 1,076 tests each. Formatting, lint, typecheck, workspace and root builds, coverage, retired-name checks, nine package checks and production audit pass. The ledger records 433 operations: 317 covered, 5 missing (retention in #278 and analytics in #281), 111 excluded, zero changed or removed fingerprints. No whole-contract parity is claimed.

Contract and release assessment

Part Status and evidence
API Unaffected runtime; consumes merged #231/#233 and exact source snapshots above.
SDKs Updated server and Calls packages, browser-facing shared exports, webhook/test-event types and errors. The repository's nine JavaScript/TypeScript workspace packages pass checks; no other-language artifact or parity is claimed.
CLI Downstream polymorfa/cli#27 must pin the exact prerelease after this merges and publishes.
Docs Updated SDK changelog, Calls README, root source reference and contract ledger. Public behavior is documented in monorepo #231/#233; no public Calls release entry is added.
Feature releases No flag, entitlement or audience change. Unified Calls remains unreleased to customers. Package publication and a successful live call are separate from these checks.
Admin Unaffected: no staff control or database contract changes.

Not exercised: npm publication from this head, a live WhatsApp call or a real PBX call. Merge is gated on current-head CI and clean Codex. The owner approved merging this PR without a clean CodeRabbit review because its bot is rate-limited and its CLI cannot connect; record that exception at merge.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • New Features

    • Added call-retention settings for platform and console, including policy options and protection against updates based on stale settings.
    • Added session restriction webhook events and typed payloads, plus a number_restricted error code.
    • Added support for reporting restricted calls with the call_restricted end reason.
    • Added clearer BanSafe health-band and risk-factor types, and expanded webhook details.
  • Updates

    • Updated billing and QuickLink requirements, production enrollment guidance, and time-zone documentation.
    • Updated logout event details to include a typed reason and numeric code.

… number_restricted

Repins the contract snapshots to polymorfa/polymorfa t3code/calls-bansafe
(dca98a44) and adds the BanSafe risk and health webhook payload types that
landed on monorepo dev after the previous pin.
@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

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: f5e7361e-bf74-4e76-86e4-5e629cbffc6e

📥 Commits

Reviewing files that changed from the base of the PR and between 2b69396 and 21ae48b.

📒 Files selected for processing (22)
  • CHANGELOG.md
  • README.md
  • contracts/README.md
  • contracts/coverage.json
  • contracts/openapi.messaging.json
  • contracts/openapi.platform.json
  • contracts/source.json
  • packages/calls/README.md
  • packages/calls/src/call.ts
  • packages/calls/src/client.ts
  • packages/calls/test/client.test.ts
  • packages/typescript/README.md
  • packages/typescript/src/errors.ts
  • packages/typescript/src/index.ts
  • packages/typescript/src/messaging/testing-configuration.ts
  • packages/typescript/src/webhooks/events.ts
  • packages/typescript/src/webhooks/index.ts
  • packages/typescript/test/coverage-reconciliation.test.ts
  • packages/typescript/test/coverage.test.ts
  • packages/typescript/test/error-body.test.ts
  • packages/typescript/test/webhook-contract.test.ts
  • packages/typescript/test/webhook-event-types.test.ts

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

The pull request updates Messaging and Platform API contracts and TypeScript SDK types. It adds call-retention operations, revises SIP endpoint coverage, and adds session restriction event and call-restriction types. It also updates BanSafe webhook types and contract snapshot records.

Changes

Messaging restrictions and events

Layer / File(s) Summary
Messaging event and restriction contracts
contracts/openapi.messaging.json
The schemas add typed logout reasons and codes, a session restriction event, restricted-call reasons, and number_restricted responses.
SDK event and call mappings
packages/typescript/src/webhooks/*, packages/typescript/src/errors.ts, packages/typescript/src/index.ts, packages/calls/src/*, packages/calls/test/client.test.ts, packages/typescript/test/*, packages/calls/README.md, packages/typescript/src/messaging/testing-configuration.ts, CHANGELOG.md
The SDK adds webhook payload types and exports, recognizes call_restricted, and tests call lifecycle mapping and webhook payload types.

Platform API contracts

Layer / File(s) Summary
Call-retention and SIP endpoint operations
contracts/openapi.platform.json
The contract adds public and Console call-retention operations and schemas, and documents public and Console SIP endpoint operations and schemas.
Platform endpoint details and snapshot records
contracts/openapi.platform.json, contracts/README.md, contracts/source.json, README.md, packages/typescript/test/coverage*
The contract updates add-on, enrollment, billing, and time-zone descriptions. Snapshot records and coverage expectations use the updated source revision and operation counts.

BanSafe webhook types

Layer / File(s) Summary
BanSafe payload types and exports
contracts/openapi.messaging.json, packages/typescript/src/webhooks/events.ts, packages/typescript/src/webhooks/index.ts, packages/typescript/src/index.ts, packages/typescript/README.md, packages/typescript/test/webhook-contract.test.ts, CHANGELOG.md
BanSafe health and risk payloads use named types for health bands and risk-factor groups. The types are exported, documented, and checked by type tests.

Priority: ⬇️ Low

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

Change: Feature

Merge Risk: ⚪ Minimal · up to 21ae4

This change teaches the SDK and Calls client about restriction-related values: the number_restricted and addon_required error codes, the session.restriction_updated webhook, typed logout reasons, and call_restricted call endings. It also adds named BanSafe types and refreshes the contract snapshots. The type and documentation changes match the updated contracts. Unknown call-end reasons still fall back to unknown. No blocking issue was found, so the change appears ready to merge.

🚥 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%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 13 files. (8 skipped: 8… 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 Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main restriction-related Calls and webhook changes, including number_restricted, session.restriction_updated, and typed logout reasons.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 13 files. (8 skipped: 8 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

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

@purpshell

Copy link
Copy Markdown
Member Author

Pin note: contracts/ is pinned to dca98a44 on the monorepo branch, which is the revision that contains every API change this PR consumes. The monorepo branch has since merged dev (bringing the calls-analytics routes from polymorfa/polymorfa#234, which this PR does not cover) and taken review fixes that do not touch the contract. Re-sync the snapshots to dev after polymorfa/polymorfa#231 merges, before publishing.

@purpshell

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@purpshell

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 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-09-23T10:10:41.835908Z 21ae48b Manual request
ℹ️ 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.

@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: 182fca1edd

ℹ️ 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".

export interface BanSafeRiskFactor {
/** A feature key, or `group:<groupId>`. */
readonly key: string;
readonly group: string;

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 Narrow risk-factor groups to the contract enum

The pinned BanSafeRiskFactor.group schema permits only 16 named values (volume, cold_outreach, …, reputation), but the exported SDK type widens this field to arbitrary string. Consequently, consumers cannot exhaustively handle the documented groups and invalid values or typos are accepted in typed fixtures and application models. Represent this field with the corresponding string-literal union, as is already done for direction and strength.

Useful? React with 👍 / 👎.

- BanSafeRiskFactor.group is the BanSafeRiskFactorGroup union (Codex review)
- keep dev's BanSafe risk and health payload types; export them and the
  new group and band names from the package root
- repin contracts to polymorfa/polymorfa t3code/calls-bansafe c8798f09, which
  contains dev's previous pin; record the SIP address routes it brings
- drop premium_required, which the API no longer returns
@purpshell

Copy link
Copy Markdown
Member Author

Codex follow-up: BanSafeRiskFactor.group is now the BanSafeRiskFactorGroup union of the sixteen documented groups (b212d83). Merging dev brought dev's own bansafe.risk_changed / bansafe.health_changed types, so this PR now keeps dev's definitions and only exports them (plus the new group and band names) from the package root. previousBand stays string | null as the pinned contract still declares it. The contracts are repinned to polymorfa/polymorfa c8798f09 (contains dev's previous pin 576176a6); that re-sync also brings the SIP address routes, recorded as excluded (Console) and missing (covered by #277), and premium_required, which the API no longer returns, is dropped from the known codes.

@purpshell

Copy link
Copy Markdown
Member Author

@codex review

@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: b212d83ba8

ℹ️ 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".

| "timeout"
| "lost_connection"
| "rejected"
| "call_restricted";

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 Preserve the new call-restricted end reason

When a call.ended lifecycle event carries this newly accepted value, packages/calls/src/client.ts's endReasonFrom() has no matching case and falls through to "unknown"; the exported CallEndReason union in packages/calls/src/call.ts also omits it. Consequently, @polymorfa/calls consumers cannot distinguish a WhatsApp restriction from an unrecognized termination, despite the updated contract exposing this reason. Add call_restricted to that package's reason type and parser.

Useful? React with 👍 / 👎.

…epo dev 9fe6c235 (#231 merge)

Keeps one BanSafe risk/health type block (the named BanSafeHealthBandName and
BanSafeRiskFactorGroup unions) and one export of each type.
@purpshell

Copy link
Copy Markdown
Member Author

@codex review

@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: 4af86787fa

ℹ️ 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".

readonly health: number | null;
readonly band: "good" | "fair" | "poor" | "failing" | "unknown";
/** `null` for the first evaluation of the number. */
readonly band: BanSafeHealthBandName;

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 Type previousBand with the health-band union

The updated BanSafeHealthChangedPayload contract now restricts previousBand to the same five values as band (plus null), but the exported interface still declares it as string | null. Consumers therefore cannot exhaustively handle the newly documented enum, and invalid previous-band values continue to type-check; reuse BanSafeHealthBandName | null for previousBand as well.

Useful? React with 👍 / 👎.

"call_not_ringing",
"call_permission_required",
"calls_disabled",
"number_restricted",

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 Add the replacement addon_required error code

When hideWatermark: true is requested without the Branded QuickLink add-on, the newly pinned Platform contract now documents addon_required as the returned code, replacing premium_required. This update removes the old code but never adds the replacement, so isKnownPolymorfaErrorCode("addon_required") returns false and KnownPolymorfaErrorCode omits an error produced by the covered QuickLink settings API.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

@codex review

Current head: 02d2461. This merges dev, narrows previousBand, preserves call_restricted through the Calls lifecycle parser, and adds addon_required to known errors. Both contracts are byte-identical to merged monorepo commit 63111fec728ac3ebc9a825ea57ebc4c592abdafc, with no overlay. Full local checks passed: tests on Node 20 and 22, typecheck, lint/format, workspace builds, coverage/names, package checks, and production audit. Retention and analytics methods remain explicitly tracked in #278 and #281.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 02d2461809

ℹ️ 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".

Copy link
Copy Markdown
Member Author

@codex review

Current head: e8d2a18. The only change since the clean review of 02d2461 is the root README's source SHA, now matching contracts/source.json and the byte-identical monorepo dev snapshot 63111fec728ac3ebc9a825ea57ebc4c592abdafc. README formatting passes. The PR description now reflects the verified 1,066-test suites and remaining CLI publication dependency.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: e8d2a18176

ℹ️ 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".

@purpshell

Copy link
Copy Markdown
Member Author

@codex review

@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: 21ae48b261

ℹ️ 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".

Comment thread CHANGELOG.md
Comment on lines +11 to +12
WhatsApp restricts the Number to existing contacts; `Retry-After` carries the
seconds until the restriction ends when WhatsApp reports one. A call WhatsApp

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 Preserve Retry-After in Calls API errors

When CallsClient.place() or Call.addParticipant() receives the new 403 number_restricted response, HttpCallsApi.#request constructs a CallsApiError using only the status, code, and message, discarding the response headers. As a result, Calls package consumers cannot read the documented Retry-After value to determine when the restriction ends; retain this header on CallsApiError (or expose response metadata) in this path.

Useful? React with 👍 / 👎.

@purpshell

Copy link
Copy Markdown
Member Author

@codex review

Please review current head 21ae48b. It merges current SDK dev 2b69396 without changing the BanSafe contract; Node 20 and 22 CI are green.

@purpshell

Copy link
Copy Markdown
Member Author

Merge gate at head 21ae48b: Node 20 and Node 22 current-head CI are green. Local codex review --base origin/dev on this clean, exact head reported "No actionable regression was identified in the changes relative to the specified merge base." The GitHub Codex bot has not answered the two current-head mentions; its earlier clean review covered e8d2a18. The owner authorized merging SDK #282 with CI + Codex while recording that a clean CodeRabbit review is unavailable because the bot is rate-limited and the CodeRabbit CLI cannot connect. This records that exception; no CodeRabbit clearance is claimed.

@purpshell
purpshell merged commit 228fa7b into dev Sep 23, 2026
4 checks passed
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 21ae48b261

ℹ️ 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".

purpshell added a commit that referenced this pull request Sep 23, 2026
Preserve strict dates and repeated-cursor safeguards. BanSafe typed alignment remains dependent on SDK #282; its error-body and webhook catalog tests remain failing until integration.
purpshell added a commit that referenced this pull request Sep 23, 2026
Resolve duplicate BanSafe exports and fixtures while retaining the closed usage webhook enums. Refresh both contract snapshots to pending API PR #228 commit 651c137, with an explicit final dev repin requirement and SDK #282 dependency.

Node 20 and 22 typechecks pass; all workspace builds, format, lint, coverage, package checks and production audit pass. Full suites have 1068 passing tests and the two known SDK #282 contract failures, which remain unchanged until that dependency merges.
purpshell added a commit that referenced this pull request Sep 23, 2026
Record all 13 existing voice methods and Console exclusions against exact pending API b361dab snapshots. Replace fake pending error/event additions with real schema parity, including required and nullable voice fields.

Narrow request enums to accepted API values while preserving documented response handling. Reject unsupported Blob MIME types before creating assets and type preview audio as Ogg. Preserve the bounded polling and exact upload-size fixes.

Node 20 and 22 typechecks and builds pass. Final full suites each pass 1112 tests with only the two known SDK #282 contract failures; final source repin after API #227 merge remains required before publication.
purpshell added a commit that referenced this pull request Sep 23, 2026
Preserve the existing consent resources and one set of BanSafe types while resolving the normal dev merge. Add the browser permission content and kind, with real HTTP serialization and error-path tests.

Pin both snapshots exactly to pending API PR #226 c9be7bd, with explicit final dev repin and SDK #282 requirements. Node 20 and 22 typechecks pass; final full suites each have 1099 passing tests and only the two known SDK #282 failures. Builds, coverage, package consumers and production audit pass.
@purpshell
purpshell deleted the t3code/calls-bansafe branch October 26, 2026 15:51
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