Surface third party links on TrackerPattern in GraphQL

Each tracker pattern carries either a direct org-scoped third_party_id
or an indirect link via common_tracker_pattern_id, but the console API
never surfaced either. Expose two optional resolver-driven fields on
the GraphQL TrackerPattern node:

  thirdParty: ThirdParty
  commonThirdParty: CommonThirdParty

The org-scoped ThirdParty takes priority. When ThirdPartyID is set the
commonThirdParty resolver short-circuits to nil, so the chained
common_tracker_pattern -> common_third_party lookup is only paid for
when a pattern has not been promoted to a tenant-managed third party.

To make the resolver pattern viable across paginated banner trackers
listings, the model now uses @goModel and a custom struct that carries
the foreign-key handles (ThirdPartyID, CommonTrackerPatternID) without
exposing them in the schema. NewTrackerPatternNode populates them from
coredata.

Two new request-scoped dataloaders (CommonTrackerPattern,
CommonThirdParty) batch the chained lookup, mirroring the existing
ThirdParty / CookieCategory loaders. The console mux now wires the
third-party service through dataloader.NewMiddleware so the second
loader has its backing service.

Authorization follows existing precedent: ActionThirdPartyGet for the
org-scoped lookup, ActionCommonThirdPartyGet (granted by the
identity-scoped CommonThirdPartyCatalogPolicy) for the catalog lookup.
ErrResourceNotFound and dataloadgen.ErrNotFound are mapped to a null
field rather than an error.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-05-27 21:02:53 +02:00
parent cdd7eb1171
commit d93ff7ba25
5 changed files with 213 additions and 42 deletions

View File

@@ -263,7 +263,10 @@ enum TrackerPatternOrderField
)
}
type TrackerPattern implements Node {
type TrackerPattern implements Node
@goModel(
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.TrackerPattern"
) {
id: ID!
cookieCategory: CookieCategory @goField(forceResolver: true)
trackerType: TrackerType!
@@ -279,6 +282,22 @@ type TrackerPattern implements Node {
createdAt: Datetime!
updatedAt: Datetime!
"""
The org-scoped third party this pattern is mapped to, if any. Set
when the mapping worker promoted the pattern to a tenant-managed
ThirdParty record. When this field is non-null, commonThirdParty is
always null.
"""
thirdParty: ThirdParty @goField(forceResolver: true)
"""
The global third party this pattern is mapped to via the common
tracker-pattern catalog. Null when the pattern has its own
org-scoped thirdParty, when it has not been mapped, or when the
matched common pattern has no common third party.
"""
commonThirdParty: CommonThirdParty @goField(forceResolver: true)
detectedTrackers(
first: Int
after: CursorKey