Skip to content

refactor partnerCode handling#6520

Merged
mononaut merged 1 commit into
masterfrom
mononaut/partner-codes
Jun 14, 2026
Merged

refactor partnerCode handling#6520
mononaut merged 1 commit into
masterfrom
mononaut/partner-codes

Conversation

@mononaut

Copy link
Copy Markdown
Contributor

This PR extracts partnerCode handling into a small self-contained service so that we have a single source-of-truth and more consistent/predictable behavior across the various components that rely on this state.

also resolves https://github.com/mempool/mempool.space/issues/2228 and supersedes #6459

Copilot AI review requested due to automatic review settings May 21, 2026 08:11
@cla-bot cla-bot Bot added the cla-signed label May 21, 2026

Copilot AI 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.

Pull request overview

This PR centralizes “partnerCode” resolution and persistence into a dedicated Angular service, replacing duplicated ad-hoc fragment/localStorage handling in the transaction/tracker flows. This aligns partnerCode behavior across components and supports consistent precedence between Enterprise-derived codes and one-off fragment codes.

Changes:

  • Added PartnerCodeService as a single source of truth for partnerCode (Enterprise code takes precedence over stored one-off code).
  • Updated TransactionComponent and TrackerComponent to consume partnerCode from the service and to strip partnerCode from the URL fragment via Angular Router navigation.
  • Updated AccelerateCheckout to consume (clear) one-off codes via the service after successful acceleration/payment flows.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
frontend/src/app/services/partner-code.service.ts Introduces centralized partnerCode state, combining Enterprise info and persisted one-off codes.
frontend/src/app/components/transaction/transaction.component.ts Removes inline fragment/localStorage partnerCode handling; subscribes to service and cleans URL fragment.
frontend/src/app/components/tracker/tracker.component.ts Removes inline fragment/localStorage partnerCode handling; subscribes to service, consumes fragment partnerCode, and cleans URL fragment.
frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts Clears one-off partnerCode through the service after successful payment/acceleration completion paths.

@mononaut mononaut requested a review from nymkappa May 21, 2026 08:17
Comment on lines +893 to +899
fragmentParams.delete('partnerCode');
this.router.navigate([], {
relativeTo: this.route,
fragment: fragmentParams.toString() || null,
queryParamsHandling: 'merge',
replaceUrl: true,
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can also wrap this in the partner code service?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All components which needs to read the partner code follow the same logic right.

  1. Get partner code (from subdomain || from url || from local storage)
  2. Clean up the url

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So I would go as far as saying that consumers of the partner-code service should only have one call it to it getPartnerCode() and the partner-code service would just take care of everything maybe.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ideally yes, but the awkward part is how that interacts with the other pages' fragment handling and navigation.

it's nice for e.g. the transaction page component to fully "own" the url and internal navigation for its own route, then you can consider that logic in isolation without worrying about side-effects leaking in from elsewhere.

Copilot AI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment on lines +24 to +38
const enterprisePartnerCode$ = this.enterpriseService.info$.pipe(
filter((info: object | null) => !isEnterprise || info !== null),
map((info: object | null) => (info as { name?: string } | null)?.name || undefined),
);

// enterprise partner code takes precedence, and remains applicable for all requests on this instance
// one-off code applies to the first successful request after being set, iff no enterprise code is present
this.partnerCode$ = combineLatest([
enterprisePartnerCode$,
this.storedPartnerCode$,
]).pipe(
map(([enterpriseCode, storedCode]) => enterpriseCode || storedCode),
distinctUntilChanged(),
shareReplay(1),
);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is fine because if the $info call fails, the user will probably be redirected to the main website anyway so all this does not matter anymore?

Comment on lines +1 to +4
import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { distinctUntilChanged, filter, map, shareReplay } from 'rxjs/operators';
import { EnterpriseService } from '@app/services/enterprise.service';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See my comment above

@nymkappa

nymkappa commented Jun 5, 2026

Copy link
Copy Markdown
Member

@nymkappa nymkappa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Otherwise my local tests looks good to me 👍🏻

@mononaut mononaut force-pushed the mononaut/partner-codes branch from 0093469 to 361fbbe Compare June 14, 2026 04:30
@nymkappa nymkappa self-requested a review June 14, 2026 07:22

@nymkappa nymkappa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-tested ACK @ 361fbbe. Thanks for simplifying the string manipulation.

The extra = does not seem to be a an issue anymore, and the subdomain code still properly replaces the one passed in the url (if any).

I see some doc updated sneaked in but that's cool haha.

@mononaut

Copy link
Copy Markdown
Contributor Author

thanks!

I just rebased on master and fixed the trailing '=' issue - the doc change you saw was probably just the diff between the original branch and the rebased one with recent commits included, not actually part of this PR.

@mononaut mononaut merged commit ffb913d into master Jun 14, 2026
19 of 20 checks passed
@mononaut mononaut deleted the mononaut/partner-codes branch June 14, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants