Skip to content

feat: [SDK-5374] add sessions API backend client - #2775

Merged
fadi-george merged 5 commits into
new-session-eventsfrom
fadi/sdk-5374
Oct 9, 2026
Merged

fadi-george merged 5 commits into
new-session-eventsfrom
fadi/sdk-5374

Conversation

@fadi-george

@fadi-george fadi-george commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #2774 (SDK-5369). Merge that first; this PR's diff is only the sessions API client.

Description

One Line Summary

Add SessionsBackendService for POST /apps/{app_id}/sessions and PATCH /apps/{app_id}/sessions/{session_id}.

Details

Motivation

Typed request/response layer for the public sessions API, used by the upcoming persistent queue (SDK-5378).

Scope

  • New ISessionsBackendService / SessionsBackendService on IHttpClient, registered in SessionModule.
  • Follows the existing backend service pattern: throws BackendException (status, payload, Retry-After) on failure and leaves retry classification to the executor. createSession returns the session ID, or null if a success response has no usable data.session_id.
  • start_time / end_time are sent as ISO 8601 UTC strings and device_type as an int, per the tech spec.
  • Retry-After comes from HttpClient, which already falls back to a default on 429 without the header.
  • No callers yet, no bulk endpoint. No behavior change.

Testing

Unit testing

SessionsBackendServiceTests: request bodies (with and without optional fields), 202 parsing, malformed create responses, BackendException with status and Retry-After on failure.

Manual testing

Not tested on device; no callers yet.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

🤖 Generated with Claude Code

@fadi-george
fadi-george requested a review from a team as a code owner October 6, 2026 22:29
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

📊 Diff Coverage Report

Diff Coverage Report (Changed Lines Only)

Gate: aggregate coverage on changed executable lines must be ≥ 80% (JaCoCo line data for lines touched in the diff).

Changed Files Coverage

  • ⚠️ SessionModule.kt: Not in coverage report (may not be compiled/tested)
  • ISessionsBackendService.kt: 15/15 touched executable lines (100.0%) (48 touched lines in diff)
  • SessionsBackendService.kt: 35/35 touched executable lines (100.0%) (71 touched lines in diff)

Overall (aggregate gate)

50/50 touched executable lines covered (100.0% — requires ≥ 80%)

📥 View workflow run

@cursor cursor 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.

Multi-model review

Claude Opus 5.5, GPT 5.6 Sol, and Grok 4.7 reviewed 10a61054...9d345ceb (sessions API backend client).

Act on (3/3): classifyFailure retries only status 0. HttpClient leaves httpResponse at -1 for ConnectException, UnknownHostException, and socket timeouts, so those become Drop(-1) and offline create/update never retry. NetworkUtils.getResponseStatusType treats unknown codes including -1 as RETRYABLE. Tests only pin 0. Treat code <= 0 (or throwable != null) as Retry and add a -1 case.

Consider (2/3): safeString + Android JSONObject.getString turns "session_id": null into Success("null"), then later PATCH .../sessions/null 404s and drops. Reject isNull / non-string ids.

Consider (2/3): a 2xx with an unparseable body is Drop, so an idempotent create that already landed (or a captive-portal HTML 200, same class of bug as SDK-4478) never recovers the session id. Prefer Retry for unparseable success; keep Drop for real 4xx.

Noted: consent-not-given is HttpResponse(0) → Retry(0, null); the future caller needs its own backoff. Path segments are unencoded, matching other backend services.

Open in Web View Automation 

Sent by Cursor Automation: PR Reviews

@fadi-george
fadi-george added this pull request to stack #2776 October 6, 2026 22:45
@fadi-george

Copy link
Copy Markdown
Contributor Author

Addressed the review in 3c3de96:

  • Network errors (-1) now retry, not just 0.
  • A null or non-string session_id no longer becomes "null". It's treated as missing.
  • A create success without a usable session_id now retries instead of dropping, since the idempotency key makes that safe.
  • Consent-blocked (0) retrying is fine here. The queue will handle backoff and max attempts.

@sherwinski sherwinski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@fadi-george

Copy link
Copy Markdown
Contributor Author
  • The API requires it so the caller will skip or wait when the model's value is null, same as the operations already do with local IDs
  • The warning right before it says the session_id was missing, so I think the 202 is fine in context

@nan-li nan-li left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is the open questions in the PR description confirmed?

@fadi-george

Copy link
Copy Markdown
Contributor Author

Is the open questions in the PR description confirmed?

Ah thanks, theyre addressed. Device type is an int, and I added use of toIso8601 for start_time and end_time

@fadi-george
fadi-george requested a review from nan-li October 8, 2026 00:32

@abdulraqeeb33 abdulraqeeb33 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

RFC3339 fix confirmed. Paths, field names, device_type and the 202 handling match sessions-http/openapi.yaml.

Base automatically changed from fadi/sdk-5369 to new-session-events October 9, 2026 20:53
fadi-george and others added 5 commits October 9, 2026 13:53
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…to the caller

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@fadi-george
fadi-george merged commit 30d2896 into new-session-events Oct 9, 2026
4 checks passed
@fadi-george
fadi-george deleted the fadi/sdk-5374 branch October 9, 2026 20:53
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.

4 participants