diff --git a/client/src/hooks/queries/useGetAmbiguousResults.ts b/client/src/hooks/queries/useGetAmbiguousResults.ts index 38fd6a70..6ed9b08a 100644 --- a/client/src/hooks/queries/useGetAmbiguousResults.ts +++ b/client/src/hooks/queries/useGetAmbiguousResults.ts @@ -112,9 +112,13 @@ export function useGetMatchedResults(names: string[], type: ResultTypes) { return useQuery( key, async () => { - const res = await graphQLClient.request(requestQuery, { - searchTerms: names, - }); + const res = await graphQLClient.request( + requestQuery, + { + searchTerms: names, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: names.length > 0 } diff --git a/client/src/hooks/queries/useGetCategories.ts b/client/src/hooks/queries/useGetCategories.ts index cf034710..1341a4c2 100644 --- a/client/src/hooks/queries/useGetCategories.ts +++ b/client/src/hooks/queries/useGetCategories.ts @@ -38,9 +38,13 @@ export function useGetCategories(names: string[]) { return useQuery( 'categories' + names, async () => { - const res = await graphQLClient.request(getCategoriesQuery, { - searchTerms: names, - }); + const res = await graphQLClient.request( + getCategoriesQuery, + { + searchTerms: names, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: names.length > 0 } diff --git a/client/src/hooks/queries/useGetDrugInteractions.ts b/client/src/hooks/queries/useGetDrugInteractions.ts index b5722cd0..c21d5703 100644 --- a/client/src/hooks/queries/useGetDrugInteractions.ts +++ b/client/src/hooks/queries/useGetDrugInteractions.ts @@ -33,9 +33,13 @@ export function useGetDrugInteractions(conceptId: string) { return useQuery( 'drug-interactions' + conceptId, async () => { - const res = await graphQLClient.request(getDrugInteractionsQuery, { - conceptId, - }); + const res = await graphQLClient.request( + getDrugInteractionsQuery, + { + conceptId, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: conceptId !== '' } diff --git a/client/src/hooks/queries/useGetDrugRecord.ts b/client/src/hooks/queries/useGetDrugRecord.ts index 9085cfbb..b36a1b7d 100644 --- a/client/src/hooks/queries/useGetDrugRecord.ts +++ b/client/src/hooks/queries/useGetDrugRecord.ts @@ -31,9 +31,13 @@ export function useGetDrugRecord(conceptId: string) { return useQuery( 'drug-record' + conceptId, async () => { - const res = await graphQLClient.request(getDrugRecordQuery, { - conceptId, - }); + const res = await graphQLClient.request( + getDrugRecordQuery, + { + conceptId, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: conceptId !== '' } diff --git a/client/src/hooks/queries/useGetDruggableSources.ts b/client/src/hooks/queries/useGetDruggableSources.ts index 909cf4ee..51c53a61 100644 --- a/client/src/hooks/queries/useGetDruggableSources.ts +++ b/client/src/hooks/queries/useGetDruggableSources.ts @@ -41,9 +41,13 @@ export function useGetDruggableSources(sourceType: string) { return useQuery( 'druggable-sources' + sourceType, async () => { - const res = await graphQLClient.request(getDruggableSourcesQuery, { - sourceType, - }); + const res = await graphQLClient.request( + getDruggableSourcesQuery, + { + sourceType, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: sourceType !== '' } @@ -81,9 +85,13 @@ export function useGetGeneSources(sourceType: string) { return useQuery( 'gene-sources' + sourceType, async () => { - const res = await graphQLClient.request(getGeneSourcesQuery, { - sourceType, - }); + const res = await graphQLClient.request( + getGeneSourcesQuery, + { + sourceType, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: sourceType !== '' } @@ -121,9 +129,13 @@ export function useGetDrugSources(sourceType: string) { return useQuery( 'drug-sources' + sourceType, async () => { - const res = await graphQLClient.request(getDrugSourcesQuery, { - sourceType, - }); + const res = await graphQLClient.request( + getDrugSourcesQuery, + { + sourceType, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: sourceType !== '' } @@ -165,9 +177,13 @@ export function useGetInteractionSources(sourceType: string) { return useQuery( 'interaction-sources' + sourceType, async () => { - const res = await graphQLClient.request(getInteractionSourcesQuery, { - sourceType, - }); + const res = await graphQLClient.request( + getInteractionSourcesQuery, + { + sourceType, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: sourceType !== '' } diff --git a/client/src/hooks/queries/useGetGeneCountsForCategories.ts b/client/src/hooks/queries/useGetGeneCountsForCategories.ts index 45d3348b..5eb0a549 100644 --- a/client/src/hooks/queries/useGetGeneCountsForCategories.ts +++ b/client/src/hooks/queries/useGetGeneCountsForCategories.ts @@ -17,9 +17,13 @@ export const useGetGeneCountsForCategories = (sourceDbNames: String[]) => { return useQuery( 'gene-counts-for-categories', async () => { - const res = await graphQLClient.request(getGeneCountsForCategoriesQuery, { - sourceDbNames: sourceDbNames, - }); + const res = await graphQLClient.request( + getGeneCountsForCategoriesQuery, + { + sourceDbNames: sourceDbNames, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: true } // TODO double check diff --git a/client/src/hooks/queries/useGetGeneInteractions.ts b/client/src/hooks/queries/useGetGeneInteractions.ts index b863316b..13b109b7 100644 --- a/client/src/hooks/queries/useGetGeneInteractions.ts +++ b/client/src/hooks/queries/useGetGeneInteractions.ts @@ -33,9 +33,13 @@ export function useGetGeneInteractions(conceptId: string) { return useQuery( 'gene-interactions' + conceptId, async () => { - const res = await graphQLClient.request(getGeneInteractionsQuery, { - conceptId, - }); + const res = await graphQLClient.request( + getGeneInteractionsQuery, + { + conceptId, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: conceptId !== '' } diff --git a/client/src/hooks/queries/useGetGeneRecord.ts b/client/src/hooks/queries/useGetGeneRecord.ts index 9d3fdf74..f84980f1 100644 --- a/client/src/hooks/queries/useGetGeneRecord.ts +++ b/client/src/hooks/queries/useGetGeneRecord.ts @@ -30,9 +30,13 @@ export function useGetGeneRecord(conceptId: string) { return useQuery( 'gene-record' + conceptId, async () => { - const res = await graphQLClient.request(getGeneRecordQuery, { - conceptId, - }); + const res = await graphQLClient.request( + getGeneRecordQuery, + { + conceptId, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: conceptId !== '' } diff --git a/client/src/hooks/queries/useGetGenesForCategory.ts b/client/src/hooks/queries/useGetGenesForCategory.ts index e42a449e..af0180c7 100644 --- a/client/src/hooks/queries/useGetGenesForCategory.ts +++ b/client/src/hooks/queries/useGetGenesForCategory.ts @@ -27,10 +27,14 @@ export function useGetGenesForCategory( return useQuery( `genes-for-category-${categoryName}-db-${sourceDbNames}`, async () => { - const res = await graphQLClient.request(getGenesForCategoryQuery, { - categoryName: categoryName, - sourceDbNames: sourceDbNames, - }); + const res = await graphQLClient.request( + getGenesForCategoryQuery, + { + categoryName: categoryName, + sourceDbNames: sourceDbNames, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: categoryName !== '' } diff --git a/client/src/hooks/queries/useGetInteractionClaimTypes.ts b/client/src/hooks/queries/useGetInteractionClaimTypes.ts index 325b2e16..d7d8ecc7 100644 --- a/client/src/hooks/queries/useGetInteractionClaimTypes.ts +++ b/client/src/hooks/queries/useGetInteractionClaimTypes.ts @@ -17,7 +17,11 @@ const getInteractionClaimTypesQuery = gql` export function useGetInteractionClaimTypes() { return useQuery('interaction_claim_types', async () => { - const res = await graphQLClient.request(getInteractionClaimTypesQuery, {}); + const res = await graphQLClient.request( + getInteractionClaimTypesQuery, + {}, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }); } diff --git a/client/src/hooks/queries/useGetInteractionRecord.ts b/client/src/hooks/queries/useGetInteractionRecord.ts index e2f2e5b3..2ab629b2 100644 --- a/client/src/hooks/queries/useGetInteractionRecord.ts +++ b/client/src/hooks/queries/useGetInteractionRecord.ts @@ -38,9 +38,13 @@ export function useGetInteractionRecord(id: string) { return useQuery( id, async () => { - const res = await graphQLClient.request(getInteractionRecordQuery, { - id, - }); + const res = await graphQLClient.request( + getInteractionRecordQuery, + { + id, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: id !== '' } diff --git a/client/src/hooks/queries/useGetInteractions.ts b/client/src/hooks/queries/useGetInteractions.ts index b9c743a1..29da8d76 100644 --- a/client/src/hooks/queries/useGetInteractions.ts +++ b/client/src/hooks/queries/useGetInteractions.ts @@ -48,9 +48,13 @@ export function useGetInteractionsByGenes(names: string[]) { return useQuery( 'interactions' + names, async () => { - const res = await graphQLClient.request(getInteractionsByGenesQuery, { - names, - }); + const res = await graphQLClient.request( + getInteractionsByGenesQuery, + { + names, + }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: names.length > 0 } diff --git a/client/src/hooks/queries/useGetNameSuggestions.ts b/client/src/hooks/queries/useGetNameSuggestions.ts index fd0eeccb..68f21dda 100644 --- a/client/src/hooks/queries/useGetNameSuggestions.ts +++ b/client/src/hooks/queries/useGetNameSuggestions.ts @@ -29,7 +29,11 @@ export function useGetNameSuggestions(searchTerm: string, type: SearchTypes) { return useQuery( queryName + searchTerm, async () => { - const res = await graphQLClient.request(query, { term: searchTerm }); + const res = await graphQLClient.request( + query, + { term: searchTerm }, + { 'dgidb-client-name': 'dgidb-frontend' } + ); return res; }, { enabled: searchTerm !== '' } diff --git a/server/Gemfile b/server/Gemfile index a1773ba7..113de989 100644 --- a/server/Gemfile +++ b/server/Gemfile @@ -9,10 +9,10 @@ gem "pg", "~>1.2.3" gem "puma" gem "rufo" -gem "graphql", "~> 1.12.15" -gem "graphql-batch", "~> 0.4.3" +gem "graphql", "~> 2.3.14" +gem 'graphql-batch', '~>0.5.3' gem "graphiql-rails", "~> 1.7.0" -gem "search_object_graphql", "0.3.1" +gem "search_object_graphql", "~> 1.0.5" # Reduces boot times through caching; required in config/boot.rb gem "bootsnap", ">= 1.4.4", require: false @@ -26,7 +26,7 @@ gem "activestorage", ">= 6.1.4.7" gem "nokogiri", ">= 1.13.2" # Importer dependencies -gem "graphql-client" +gem "graphql-client", "~> 0.23.0" gem "ruby-progressbar" gem "sqlite3", require: false gem "zlib", require: false diff --git a/server/Gemfile.lock b/server/Gemfile.lock index 11beb5db..bc13f326 100644 --- a/server/Gemfile.lock +++ b/server/Gemfile.lock @@ -1,113 +1,118 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.3) - actionpack (= 6.1.7.3) - activesupport (= 6.1.7.3) + actioncable (6.1.7.9) + actionpack (= 6.1.7.9) + activesupport (= 6.1.7.9) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.3) - actionpack (= 6.1.7.3) - activejob (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionmailbox (6.1.7.9) + actionpack (= 6.1.7.9) + activejob (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) mail (>= 2.7.1) - actionmailer (6.1.7.3) - actionpack (= 6.1.7.3) - actionview (= 6.1.7.3) - activejob (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionmailer (6.1.7.9) + actionpack (= 6.1.7.9) + actionview (= 6.1.7.9) + activejob (= 6.1.7.9) + activesupport (= 6.1.7.9) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.7.3) - actionview (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionpack (6.1.7.9) + actionview (= 6.1.7.9) + activesupport (= 6.1.7.9) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.3) - actionpack (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + actiontext (6.1.7.9) + actionpack (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) nokogiri (>= 1.8.5) - actionview (6.1.7.3) - activesupport (= 6.1.7.3) + actionview (6.1.7.9) + activesupport (= 6.1.7.9) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.7.3) - activesupport (= 6.1.7.3) + activejob (6.1.7.9) + activesupport (= 6.1.7.9) globalid (>= 0.3.6) - activemodel (6.1.7.3) - activesupport (= 6.1.7.3) - activerecord (6.1.7.3) - activemodel (= 6.1.7.3) - activesupport (= 6.1.7.3) - activestorage (6.1.7.3) - actionpack (= 6.1.7.3) - activejob (= 6.1.7.3) - activerecord (= 6.1.7.3) - activesupport (= 6.1.7.3) + activemodel (6.1.7.9) + activesupport (= 6.1.7.9) + activerecord (6.1.7.9) + activemodel (= 6.1.7.9) + activesupport (= 6.1.7.9) + activestorage (6.1.7.9) + actionpack (= 6.1.7.9) + activejob (= 6.1.7.9) + activerecord (= 6.1.7.9) + activesupport (= 6.1.7.9) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.3) + activesupport (6.1.7.9) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - airbrussh (1.4.1) + airbrussh (1.5.3) sshkit (>= 1.6.1, != 1.7.0) - bcrypt_pbkdf (1.1.0) - bootsnap (1.16.0) + base64 (0.2.0) + bcrypt_pbkdf (1.1.1) + bcrypt_pbkdf (1.1.1-arm64-darwin) + bootsnap (1.18.4) msgpack (~> 1.2) - builder (3.2.4) + builder (3.3.0) byebug (11.1.3) - capistrano (3.17.3) + capistrano (3.19.1) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) sshkit (>= 1.9.0) - capistrano-bundler (2.1.0) + capistrano-bundler (2.1.1) capistrano (~> 3.1) - capistrano-rails (1.6.2) + capistrano-rails (1.6.3) capistrano (~> 3.1) capistrano-bundler (>= 1.1, < 3) capistrano-rbenv (2.2.0) capistrano (~> 3.1) sshkit (~> 1.3) - concurrent-ruby (1.2.2) + concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) - date (3.3.3) - diff-lcs (1.5.0) + date (3.3.4) + diff-lcs (1.5.1) ed25519 (1.3.0) - erubi (1.12.0) - factory_bot (6.2.1) + erubi (1.13.0) + factory_bot (6.5.0) activesupport (>= 5.0.0) - ffi (1.15.5) - globalid (1.1.0) - activesupport (>= 5.0) + ffi (1.17.0) + fiber-storage (1.0.0) + globalid (1.2.1) + activesupport (>= 6.1) graphiql-rails (1.7.0) railties sprockets-rails - graphql (1.12.24) - graphql-batch (0.4.3) - graphql (>= 1.3, < 2) + graphql (2.3.18) + base64 + fiber-storage + graphql-batch (0.5.4) + graphql (>= 1.12.18, < 3) promise.rb (~> 0.7.2) - graphql-client (0.18.0) + graphql-client (0.23.0) activesupport (>= 3.0) - graphql - i18n (1.14.1) + graphql (>= 1.13.0) + i18n (1.14.6) concurrent-ruby (~> 1.0) - listen (3.8.0) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.21.3) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -115,86 +120,89 @@ GEM net-imap net-pop net-smtp - marcel (1.0.2) - method_source (1.0.0) - mini_mime (1.1.2) - minitest (5.18.1) - msgpack (1.7.1) - net-ftp (0.2.0) + marcel (1.0.4) + method_source (1.1.0) + mini_mime (1.1.5) + mini_portile2 (2.8.7) + minitest (5.25.1) + msgpack (1.7.3) + net-ftp (0.3.8) net-protocol time - net-imap (0.3.6) + net-imap (0.5.0) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout net-scp (4.0.0) net-ssh (>= 2.6.5, < 8.0.0) - net-smtp (0.3.3) + net-sftp (4.0.0) + net-ssh (>= 5.0.0, < 8.0.0) + net-smtp (0.5.0) net-protocol - net-ssh (7.1.0) - nio4r (2.5.9) - nokogiri (1.15.2-arm64-darwin) + net-ssh (7.3.0) + nio4r (2.7.3) + nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) - nokogiri (1.15.2-x86_64-darwin) - racc (~> 1.4) - nokogiri (1.15.2-x86_64-linux) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) + ostruct (0.6.0) pg (1.2.3) promise.rb (0.7.4) - puma (6.3.0) + puma (6.4.3) nio4r (~> 2.0) - racc (1.7.1) - rack (2.2.7) - rack-cors (2.0.1) + racc (1.8.1) + rack (2.2.10) + rack-cors (2.0.2) rack (>= 2.0.0) - rack-mini-profiler (3.1.0) + rack-mini-profiler (3.3.1) rack (>= 1.2.0) rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.3) - actioncable (= 6.1.7.3) - actionmailbox (= 6.1.7.3) - actionmailer (= 6.1.7.3) - actionpack (= 6.1.7.3) - actiontext (= 6.1.7.3) - actionview (= 6.1.7.3) - activejob (= 6.1.7.3) - activemodel (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + rails (6.1.7.9) + actioncable (= 6.1.7.9) + actionmailbox (= 6.1.7.9) + actionmailer (= 6.1.7.9) + actionpack (= 6.1.7.9) + actiontext (= 6.1.7.9) + actionview (= 6.1.7.9) + activejob (= 6.1.7.9) + activemodel (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) bundler (>= 1.15.0) - railties (= 6.1.7.3) + railties (= 6.1.7.9) sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (6.1.7.3) - actionpack (= 6.1.7.3) - activesupport (= 6.1.7.3) + railties (6.1.7.9) + actionpack (= 6.1.7.9) + activesupport (= 6.1.7.9) method_source rake (>= 12.2) thor (~> 1.0) - rake (13.0.6) + rake (13.2.1) rb-fsevent (0.11.2) - rb-inotify (0.10.1) + rb-inotify (0.11.1) ffi (~> 1.0) - redis-client (0.14.1) + redis-client (0.22.2) connection_pool - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rspec-core (3.13.1) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.5) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) + rspec-support (~> 3.13.0) rspec-rails (5.1.2) actionpack (>= 5.2) activesupport (>= 5.2) @@ -203,51 +211,49 @@ GEM rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) rspec-support (~> 3.10) - rspec-support (3.12.0) + rspec-support (3.13.1) ruby-progressbar (1.13.0) rubyzip (2.3.2) - rufo (0.16.1) + rufo (0.18.0) search_object (1.2.5) - search_object_graphql (0.3.1) - graphql (~> 1.8) - search_object (~> 1.2.2) - sidekiq (7.1.2) + search_object_graphql (1.0.5) + graphql (> 1.8) + search_object (~> 1.2.5) + sidekiq (7.1.6) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) redis-client (>= 0.14.0) - spring (4.1.1) - sprockets (4.2.0) + spring (4.2.1) + sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) - sqlite3 (1.6.3-arm64-darwin) - sqlite3 (1.6.3-x86_64-darwin) - sqlite3 (1.6.3-x86_64-linux) - sshkit (1.21.4) + sqlite3 (2.1.0) + mini_portile2 (~> 2.8.0) + sshkit (1.23.2) + base64 net-scp (>= 1.1.2) + net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) - thor (1.2.2) - time (0.2.2) + ostruct + thor (1.3.2) + time (0.4.0) date - timeout (0.3.2) + timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - websocket-driver (0.7.5) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.6.8) - zlib (3.0.0) + zeitwerk (2.6.18) + zlib (3.1.1) PLATFORMS arm64-darwin-23 - x86_64-darwin-19 - x86_64-darwin-20 - x86_64-darwin-21 - x86_64-darwin-22 x86_64-linux DEPENDENCIES @@ -262,9 +268,9 @@ DEPENDENCIES ed25519 factory_bot (~> 6.2) graphiql-rails (~> 1.7.0) - graphql (~> 1.12.15) - graphql-batch (~> 0.4.3) - graphql-client + graphql (~> 2.3.14) + graphql-batch (~> 0.5.3) + graphql-client (~> 0.23.0) listen (~> 3.3) net-ftp net-imap @@ -280,7 +286,7 @@ DEPENDENCIES ruby-progressbar rubyzip rufo - search_object_graphql (= 0.3.1) + search_object_graphql (~> 1.0.5) sidekiq (~> 7.1.2) spring sqlite3 @@ -288,7 +294,7 @@ DEPENDENCIES zlib RUBY VERSION - ruby 3.1.2p20 + ruby 3.1.0p0 BUNDLED WITH - 2.2.33 + 2.3.19 diff --git a/server/app/controllers/concerns/analytics.rb b/server/app/controllers/concerns/analytics.rb new file mode 100644 index 00000000..8c46b212 --- /dev/null +++ b/server/app/controllers/concerns/analytics.rb @@ -0,0 +1,15 @@ +module Analytics + extend ActiveSupport::Concern + + def get_trace_mode(request) + return unless Rails.env.production? + + if request.headers['dgidb-client-name'] == 'dgidb-frontend' + :frontend_analytics + elsif request.headers['query'] && !requests.headers['query'].include?('IntrospectionQuery') + :api_analytics + end + end + + module_function :get_trace_mode +end diff --git a/server/app/controllers/graphql_controller.rb b/server/app/controllers/graphql_controller.rb index 148a2520..5a5539dd 100644 --- a/server/app/controllers/graphql_controller.rb +++ b/server/app/controllers/graphql_controller.rb @@ -8,11 +8,8 @@ def execute variables = prepare_variables(params[:variables]) query = params[:query] operation_name = params[:operationName] - context = { - # Query context goes here, for example: - # current_user: current_user, - } - result = DgidbSchema.execute(query, variables: variables, context: context, operation_name: operation_name) + trace_mode = Analytics.get_trace_mode(request) + result = DgidbSchema.execute(query, variables: variables, context: { trace_mode: }, operation_name: operation_name) render json: result rescue StandardError => e raise e unless Rails.env.development? diff --git a/server/app/graphql/dgidb_schema.rb b/server/app/graphql/dgidb_schema.rb index 4e08414e..b637afed 100644 --- a/server/app/graphql/dgidb_schema.rb +++ b/server/app/graphql/dgidb_schema.rb @@ -2,6 +2,9 @@ class DgidbSchema < GraphQL::Schema mutation(Types::MutationType) query(Types::QueryType) + trace_with FrontendAnalyticsTracer, mode: :frontend_analytics + trace_with ApiAnalyticsTracer, mode: :api_analytics + use GraphQL::Batch # Union and Interface Resolution diff --git a/server/app/jobs/submit_analytics_event.rb b/server/app/jobs/submit_analytics_event.rb new file mode 100644 index 00000000..0fb8d46b --- /dev/null +++ b/server/app/jobs/submit_analytics_event.rb @@ -0,0 +1,21 @@ +require 'uri' +require 'net/http' + +class SubmitAnalyticsEvent < ApplicationJob + # TODO not entirely sure what goes here + GA_MEASUREMENT_ID = 'G-Y6DR1YK7V9'.freeze + GA_API_SECRET = Rails.application.credentials[:ga_api_secret] + + ANALYTICS_URL = "https://www.google-analytics.com/mp/collect?api_secret=#{GA_API_SECRET}&measurement_id=#{GA_MEASUREMENT_ID}".freeze + HEADER = { 'Content-Type': 'application/json' }.freeze + + def perform(opts = {}) + Net::HTTP.post(URI(ANALYTICS_URL), create_body(opts)) + end + + private + + def create_body(opts) + raise NotImplementedError.new("Implement in subclass") + end +end diff --git a/server/app/jobs/submit_api_analytics.rb b/server/app/jobs/submit_api_analytics.rb new file mode 100644 index 00000000..24a7b67b --- /dev/null +++ b/server/app/jobs/submit_api_analytics.rb @@ -0,0 +1,23 @@ +require 'uri' +require 'net/http' + +class SubmitApiAnalytics < SubmitAnalyticsEvent + def create_body(opts) + { + client_id: SecureRandom.uuid, + user_id: opts[:user_ip], + timestamp_micros: DateTime.now.strftime('%s%6N'), + events: [ + { + name: 'api_request', + params: { + query_type: opts[:query_type], + query: opts[:query], + query_params: opts[:query_params], + ip: opts[:user_ip] + } + } + ] + }.to_json + end +end diff --git a/server/app/lib/api_analytics_tracer.rb b/server/app/lib/api_analytics_tracer.rb new file mode 100644 index 00000000..8e4b1b6e --- /dev/null +++ b/server/app/lib/api_analytics_tracer.rb @@ -0,0 +1,12 @@ +module ApiAnalyticsTracer + def analyze_query(query: ) + params = { + user_ip: query.context[:request_ip], + query: query.query_string, + query_variables: query.provided_variables + } + + SubmitApiAnalytics.perform_later(params) + super + end +end diff --git a/server/app/lib/frontend_analytics_tracer.rb b/server/app/lib/frontend_analytics_tracer.rb new file mode 100644 index 00000000..b86265e8 --- /dev/null +++ b/server/app/lib/frontend_analytics_tracer.rb @@ -0,0 +1,12 @@ +module FrontendAnalyticsTracer + def analyze_query(query: ) + params = { + user_ip: query.context[:request_ip], + query_type: query.selected_operation.selections&.first&.name, + query_variables: query.provided_variables + } + + SubmitApiAnalytics.perform_later(params) + super + end +end