feat: proxy signal/event/segment queries to dq#289
Draft
elffjs wants to merge 5 commits into
Draft
Conversation
Adds an optional dq proxy mode. When DQ_ENDPOINT is set, the seven main query resolvers (signals, signalsLatest, availableSignals, dataSummary, events, segments, dailyActivity) forward to dq instead of querying ClickHouse directly. Key transforms applied per request: - tokenId → ERC721 DID subject string - DetectionMechanism camelCase → UPPER_SNAKE_CASE - JWT Authorization header forwarded as-is (same token issuer) - Per-signal filters use named GraphQL variables (not inline JSON) vinVCLatest, attestations, and signalsSnapshot retain their existing ClickHouse-backed implementations for now. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dq's EventFilter has the same tags field as telemetry-api's, so the wrapper type stripping it was unnecessary and wrong. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
transform_test.go covers: - ToSubject, ToDQMechanism (all 6 values + invalid) - BuildSignalsQuery: no filters, alias preserved, float filter with named variables, approximate-coordinates alias mapping, required vars - UnmarshalSignalsResponse: basic, alias→map key, null skipped, multi-row - BuildSignalsLatestQuery: field inclusion, lastSeen toggle - UnmarshalSignalsLatestResponse: happy path, null body client_test.go covers: - Execute: auth header forwarding, no-auth, variable serialization, GraphQL error propagation, data JSON passthrough - ProxySignals round-trip: correct subject/interval/query sent, response unmarshaled with alias preserved - ProxySegments: DetectionMechanism mapped to UPPER_SNAKE_CASE Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
internal/proxypackage with a thin GraphQL HTTP client and all query builders/response mappers needed to forward requests todqsignals,signalsLatest,availableSignals,dataSummary,events,segments,dailyActivity) check forProxyClientat the top of each handler and delegate todqwhen it's configuredvinVCLatest,attestations, andsignalsSnapshotkeep their existing ClickHouse-backed implementations (phase 2)Activation: set
DQ_ENDPOINT=http://<dq-host>:3000/queryin settings. Unset = existing ClickHouse behavior unchanged.Key transforms applied per request:
tokenId(int) → ERC721 DID subject string via existing chain/contract configDetectionMechanismcamelCase → UPPER_SNAKE_CASE (dq schema)Authorizationheader forwarded as-is (same token-exchange issuer)SignalFloatFilter/SignalLocationFiltervalues are passed as named GraphQL variables (not inlined), producing valid GraphQLEventFilter.tagsfield stripped before forwarding (dq'sEventFilterdoesn't include it)Alias handling for
signals:aggregationArgsFromContextalready captures both the schema field name and the client alias intoFloatSignalArgs.Alias. The proxy emitsalias: fieldName(agg: AGG)in the dq query, dq returns{"alias": value}, and we keyValueNumbers[alias]— matching how the generated field resolvers look up values.Test plan
go test ./...)DQ_ENDPOINT, querysignalsvia telemetry-api — verify tokenId→subject conversion and data flows through dqsegmentswithignitionDetection— verify dq receivesIGNITION_DETECTIONsignalswith a field alias — verify alias is preserved in responseDQ_ENDPOINT— verify fallback to ClickHouse still works🤖 Generated with Claude Code