Skip to content

Carry main into redesign/main: 3D Secure checkout and the challenge and accountability removal (#746) - #785

Merged
thomasluizon merged 2 commits into
redesign/mainfrom
thomasluizon/ticket-746-carry-oct19c
Oct 19, 2026
Merged

thomasluizon merged 2 commits into
redesign/mainfrom
thomasluizon/ticket-746-carry-oct19c

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

Carries the two requested main commits onto redesign/main, preserving the redesign API behavior and retaining the challenge and accountability tables for the later contraction.

Refs thomasluizon/orbit-tickets#746
Refs thomasluizon/orbit-tickets#208
Refs thomasluizon/orbit-tickets#218

Carries and resolution

  • 46e3aac4cec26b1368c4df054cd89f691980143f (ORB-202: request 3D Secure for subscription checkout #780): checkout requests card 3D Secure with any; the idempotency key includes the authentication policy. Source and regression tests carried together in 60e0a55a, without conflicts.
  • c75ab1bd10044e020295df012022596d3c60091f (Remove challenge and accountability endpoints (ORB-212) #779), carried as 749e56bb: removes challenge and accountability controllers, handlers, validators, DI, rate policies, catalog actions, and feature tests; filters removed achievement unlocks from returned badges and totals while retaining stored XP and unlocks. Retains entities, tables, DbSets, mappings, account-reset cleanup, and friend-profile reads for thomasluizon/orbit-tickets#1555.

Both carried commits retain the same stable patch IDs as their main originals: 46e3aac4 and 60e0a55a both produce cb84a51ddbc4e0757b29a9b36a8721b3fee7dd8d; c75ab1bd and 749e56bb both produce 23855fe527f21555cd77efa57fd4c636b0519cb4 (git show <commit> | git patch-id --stable).

Neither commit was skipped. Before each carry, redesign/main had no corresponding cherry-pick trailer and still contained the pre-change implementation. The Stripe checkout lacked PaymentMethodOptions and its policy key; both feature controllers, catalog actions, and feature handlers remained present.

Conflicted paths by redesign commit

All C# merges were automatic and reviewed against both branches. The Astra block error mapping, ask and block stores, pending-write service wiring, proactive catalog entries, Notion catalog entries, and account-reset dependencies retain their redesign additions. No additional redesign-only consumer served the removed features. No migrations or snapshot edits are required, and there is no migration ordering question.

External interface evidence

Source PR #780 records the installed Stripe.net 52.4.2 manifest/source evidence for SessionCreateOptions.PaymentMethodOptions, SessionPaymentMethodOptionsOptions.Card, and SessionPaymentMethodOptionsCardOptions.RequestThreeDSecure, the serialized field names, supported any value, and the supplied test-mode acceptance probe. This carry introduces exactly those same SDK option reads and assertions. Re-derive from the package manifest's source commit f4f1c8ce704825d7d7f00b4c9d848a2d028757eb and its three linked Checkout option source files.

Test evidence

Before the checkout implementation changed, env -u LANG dotnet test tests/Orbit.Infrastructure.Tests --filter FullyQualifiedName~StripeBillingServiceTests exited 0 with 38 existing tests passing while the 3D Secure option was absent.

With the carried tests present and the original checkout implementation restored, forced a rebuild with dotnet build src/Orbit.Infrastructure --no-incremental (exit 0), then ran:

env -u LANG dotnet test tests/Orbit.Infrastructure.Tests --filter 'FullyQualifiedName~Checkout_RequestsThreeDSecureWithoutChangingSubscriptionOptions|FullyQualifiedName~Checkout_ThreeDSecurePolicy_DoesNotReuseThePrePolicyKey'

Exit 1: all five cases failed for the missing options and unchanged pre-policy key. After restoring the carried implementation, the original checkout-suite command exited 0 with all 43 tests passing.

Before the removal, the unchanged existing tests passed 186 cases (exit 0):

env -u LANG dotnet test tests/Orbit.Application.Tests --filter 'FullyQualifiedName~LogHabit|FullyQualifiedName~GetAchievementsQueryHandlerTests|FullyQualifiedName~AchievementDefinitionsTests|FullyQualifiedName~GetGamificationProfileQueryHandlerTests'

With the removed definitions and the original unfiltered query implementations, the carried Handle_RemovedAchievementEarned_OmitsBadgeAndPreservesXpAndLevel regressions failed all four cases (exit 1), exposing the orphaned unlock in counts and returned profile IDs:

env -u LANG dotnet test tests/Orbit.Application.Tests --filter FullyQualifiedName~Handle_RemovedAchievementEarned_OmitsBadgeAndPreservesXpAndLevel

After restoring both carried query implementations, focused application coverage passed 732 tests and focused infrastructure coverage passed 280 tests, each exit 0. These include habit logging, gamification and historical badges, public profiles, Astra asks and block answers, held writes, the proactive engine, removed routes and policies, content moderation registration, agent catalog and step-up, account reset, retained accountability deletion, idempotency, and snapshot consistency.

Semantic comparison of both regenerated contracts against the branch base confirms exactly ten removed challenge/accountability paths and nine unused schemas per document, zero changed surviving paths or schemas, and the unchanged Notion CallbackRequest schema. The retained domain entities, DbSets, model configuration, and migration snapshot have no diff.

Final verification after both commits, all exit codes read directly:

Command Result Exit
env -u LANG dotnet build Orbit.slnx zero errors 0
LC_ALL=en_US.UTF-8 dotnet build Orbit.slnx zero errors 0
env -u LANG dotnet test tests/Orbit.Domain.Tests 778 passed 0
env -u LANG dotnet test tests/Orbit.Application.Tests 5,570 passed 0
env -u LANG dotnet test tests/Orbit.Infrastructure.Tests 3,928 passed 0
env -u LANG dotnet test 10,308 passed, zero failed or skipped 0
LC_ALL=en_US.UTF-8 dotnet test 10,308 passed, zero failed or skipped 0

From src/Orbit.Infrastructure, env -u LANG dotnet ef migrations has-pending-model-changes --project . --startup-project ../Orbit.Api --no-build exited 0 and reported: "No changes have been made to the model since the last migration." It used the design-time factory without opening a database connection. The full runs include all 32 analyzer tests.

Builds retain warnings from existing dependencies and obsolete APIs. EF reports tool 10.0.12 versus runtime 10.0.13. No suppressions were added. Both commit hooks, generated-contract regeneration, whitespace checks, and the PR prose dash check passed. The working tree is clean. No browser, server, release, database change, or other repository was used.

Manual steps

The following steps are copied unchanged from the source PRs. They remain release prerequisites; this carry performs no release or floor change.

Source #780

  1. Release the API to staging through GitHub Actions > Release API (.github/workflows/release.yml), dispatched from main, with environment=staging and branch=thomasluizon/ticket-208-stripe-3ds. Use the staging web checkout with Stripe test credentials and the published 3DS-required card 4000000000003220. Observe the hosted challenge, complete it, inspect the resulting Stripe test subscription for active status, and read GET /api/subscriptions/status for the same Orbit user to confirm the paid plan and interval. Repeat with a fresh checkout and fail or abandon authentication: verify no paid Orbit subscription and no successful charge, and a usable return path. These browser checks were not run by this worker, as prohibited by the work order.
  2. Also test supported optional-3DS card 4000000000003055 to confirm the explicit request applies beyond cards already requiring 3DS. Do not expect 4242424242424242 to display a challenge: Stripe documents it as unenrolled. With any, frictionless authentication is allowed.
  3. Production effect starts only after a production API release, with the owner's explicit approval. After staging verification and merge, use GitHub Actions > Release API with environment=production and branch=main. Verify the release commit, observe the next real checkouts, and read the existing subscriber's next recurring invoice/subscription state to confirm renewal succeeds. No live release, renewal or payment was performed here. A report that a customer cannot pay is a rollback trigger.
  4. Reversal: remove PaymentMethodOptions.Card.RequestThreeDSecure or set it to automatic in StripeBillingService.CreateCheckoutSessionAsync, then release the API through the same workflow. Confirm newly created sessions use the default or automatic policy. No Dashboard rule needs changing.

Source #779

  • Before merging or running the production API release that carries this removal through GitHub Actions release.yml, confirm in Google Play Console that an Android build without challenge and accountability screens is live in the fleet. Complete the owner-approved MinSupportedVersion gate in thomasluizon/orbit-tickets#1531, including the exact MinSupportedVersion row in production Supabase AppConfigs, the Render APP_VERSION preconditions, readback, and cache activation evidence described in AGENTS.md. This PR does not raise the floor. Merging to main itself deploys nothing.
  • The orchestrator files the separate table-drop ticket. Build its migration only after the compatible removal is released through release.yml and production drain evidence exists. AccountResetRepository cleanup and GetFriendProfileQuery remain table consumers in this PR; remove or retire those consumers in a compatible production release before recording a contract barrier. Record Render service/deploy/commit identifiers and web, hosted-service, Hangfire, retry, queued-job, and in-flight-work drain evidence as required by tests/Orbit.Infrastructure.Tests/Persistence/RollingMigrations.md, then contract in a later PR and release with .github/migration-contracts.json evidence. No table drop is authorized by this PR alone.
  • Rollback of this code-only PR is a revert; it needs no schema restoration and deletes no stored feature data. The later contraction must state its safe rollback floor and that recreating dropped tables restores schema rather than historical data.

thomasluizon and others added 2 commits October 19, 2026 10:12
* fix(billing): request 3D Secure for subscription checkout

* fix(billing): key checkout retries by the 3D Secure policy

A checkout request with the new card authentication option must not reuse
an idempotency key that a request without it created, because Stripe
rejects changed parameters for a retained key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 46e3aac)
* feat: remove challenge and accountability endpoints (ORB-212)

* fix: exclude removed achievements from earned totals (ORB-212)

(cherry picked from commit c75ab1b)
@sonarqubecloud

Copy link
Copy Markdown

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

No new issues found.

Reviewed changes Reviewed both carried commits against redesign/main, including the full diff, surviving backend consumers, and the sibling client's removal of these features.

  • Checkout authentication: Requests card 3D Secure with any and distinguishes the new policy in checkout idempotency keys without changing subscription, coupon, or return-URL options.
  • Feature retirement: Removes challenge/accountability endpoints, application logic, registrations, rate policies, and agent catalog actions while retaining friends and unrelated authentication challenges.
  • Historical data: Filters removed achievement definitions from returned badges and totals without deleting stored unlocks or XP; retains feature tables, account-reset cleanup, and friend-profile compatibility fields for later contraction.
  • Verification: All 428 tests in three focused local runs passed, covering checkout, habit logging, gamification, profile reads, selected redesign agent flows, and retained persistence behavior. CI Build and the OpenAPI Breaking-Change Gate also passed; the full CI test run was still in progress when checked.

The Android release/version-floor gate and hosted 3DS acceptance checks remain the documented release prerequisites. This review did not verify production fleet state or perform browser payment checks.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

@thomasluizon
thomasluizon merged commit b5ed1d0 into redesign/main Oct 19, 2026
24 checks passed
@thomasluizon
thomasluizon deleted the thomasluizon/ticket-746-carry-oct19c branch October 19, 2026 14:24
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