Compare commits

...

7 Commits

Author SHA1 Message Date
4ffd9f972d Add explicit auth client operations 2026-08-14 18:19:47 -07:00
33707523f0 Add social SSO auth contract 2026-08-14 17:18:07 -07:00
308c60c93b Merge pull request 'Rename Session Coach feedback enums' (#323) from loewy/session-coach-feedback-enums into master
Reviewed-on: #323
2026-08-10 19:56:23 +00:00
19ba43ad6d Rename Session Coach feedback enums
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2026-08-10 12:26:43 -07:00
03b565dc7d Merge pull request 'Let shot filters select a single player within a video' (#322) from dean/filter-by-player-index into master
Reviewed-on: #322
2026-08-06 20:21:37 +00:00
Dean Wenstrand
901f4222a4 Let shot filters select a single player within a video
All checks were successful
Tests / Tests (pull_request) Successful in 11s
Adds playerIndex to FilterInput, backing ShooterIdentity.player_index --
the cluster-assigned shooter, 0-based and stable only within one video.

Deliberately separate from userId, which is populated only once a cluster
has been confirmed against a registered account. Multiplayer sessions are
usually played against someone without a Railbird login, so filtering by
userId cannot express "the other player" in the common case; the cluster
index always can.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 13:14:00 -07:00
0f6e7b28d4 Merge pull request 'Return the shot's start frame image from getShotTableState' (#321) from ivan/shot-table-state-frame-image into master 2026-08-06 19:11:59 +00:00
4 changed files with 397 additions and 4 deletions

View File

@@ -88,6 +88,26 @@ export type AppleIapSubscriptionOptionsGql = {
productIds: Array<Scalars["String"]["output"]>;
};
export type AuthBootstrapGql = {
__typename?: "AuthBootstrapGQL";
status: AuthBootstrapStatusEnum;
user?: Maybe<UserGql>;
};
export enum AuthBootstrapStatusEnum {
NeedsProfile = "NEEDS_PROFILE",
Registered = "REGISTERED",
RegistrationDisabled = "REGISTRATION_DISABLED",
}
export enum AuthRegistrationErrorEnum {
InvalidUsername = "INVALID_USERNAME",
RegistrationDisabled = "REGISTRATION_DISABLED",
UnsupportedProvider = "UNSUPPORTED_PROVIDER",
UsernameUnavailable = "USERNAME_UNAVAILABLE",
VerifiedEmailRequired = "VERIFIED_EMAIL_REQUIRED",
}
export type BallTrajectoryGql = {
__typename?: "BallTrajectoryGQL";
ballId: Scalars["Int"]["output"];
@@ -279,6 +299,12 @@ export type CommentGql = {
user: UserGql;
};
export type CompleteAuthRegistrationGql = {
__typename?: "CompleteAuthRegistrationGQL";
errorCode?: Maybe<AuthRegistrationErrorEnum>;
user?: Maybe<UserGql>;
};
export type CountLeaderboardGql = {
__typename?: "CountLeaderboardGQL";
entries: Array<UserShotCountEntry>;
@@ -386,6 +412,7 @@ export type DeployedConfigGql = {
firebase: Scalars["Boolean"]["output"];
minimumAllowedAppVersion: Scalars["String"]["output"];
quotaEnforcementEnabled: Scalars["Boolean"]["output"];
socialAuthProviderAvailability: Array<SocialAuthProviderAvailabilityGql>;
storageLimitEnforcementEnabled: Scalars["Boolean"]["output"];
subscriptionGatingEnabled: Scalars["Boolean"]["output"];
};
@@ -476,6 +503,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -520,6 +548,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -564,6 +593,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -608,6 +638,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -652,6 +683,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -696,6 +728,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -740,6 +773,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -784,6 +818,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -828,6 +863,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -872,6 +908,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -916,6 +953,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -960,6 +998,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1004,6 +1043,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1048,6 +1088,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1092,6 +1133,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1136,6 +1178,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1180,6 +1223,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1224,6 +1268,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1268,6 +1313,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1312,6 +1358,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1356,6 +1403,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1400,6 +1448,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1444,6 +1493,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1488,6 +1538,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1532,6 +1583,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1576,6 +1628,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1620,6 +1673,7 @@ export type FilterInput =
missAngleInDegrees: FloatRangeFilter;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1664,6 +1718,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter: FilterInput;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1708,6 +1763,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters: Array<FilterInput>;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1752,6 +1808,52 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex: Array<Scalars["Int"]["input"]>;
runId?: never;
runLength?: never;
shotDirection?: never;
spinType?: never;
tableSize?: never;
tags?: never;
targetPocketAngle?: never;
targetPocketAngleDirection?: never;
targetPocketDistance?: never;
totalDistance?: never;
userId?: never;
username?: never;
videoId?: never;
}
| {
andFilters?: never;
annotations?: never;
backcut?: never;
bankAngle?: never;
bankDistance?: never;
createdAt?: never;
cueAngleAfterObject?: never;
cueBallSpeed?: never;
cueObjectAngle?: never;
cueObjectDistance?: never;
cueSpeedAfterObject?: never;
difficulty?: never;
falsePositiveScore?: never;
fargoRating?: never;
intendedPocketType?: never;
isBreakHeuristic?: never;
isDirect?: never;
isLeft?: never;
isLeftMiss?: never;
isRight?: never;
isRightMiss?: never;
isStraight?: never;
kickAngle?: never;
kickDistance?: never;
make?: never;
marginOfErrorInDegrees?: never;
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId: Array<Scalars["Int"]["input"]>;
runLength?: never;
shotDirection?: never;
@@ -1796,6 +1898,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength: FloatRangeFilter;
shotDirection?: never;
@@ -1840,6 +1943,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection: Array<ShotDirectionEnum>;
@@ -1884,6 +1988,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1928,6 +2033,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -1972,6 +2078,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2016,6 +2123,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2060,6 +2168,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2104,6 +2213,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2148,6 +2258,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2192,6 +2303,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2236,6 +2348,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2280,6 +2393,7 @@ export type FilterInput =
missAngleInDegrees?: never;
notFilter?: never;
orFilters?: never;
playerIndex?: never;
runId?: never;
runLength?: never;
shotDirection?: never;
@@ -2531,6 +2645,7 @@ export type Mutation = {
cancelCameraClaimSession: CameraClaimSession;
cancelSubscription: UserSubscriptionStatusGql;
commentOnVideo: Scalars["Boolean"]["output"];
completeAuthRegistration: CompleteAuthRegistrationGql;
createBucketSet: BucketSetGql;
createCameraClaimSession: CameraClaimSession;
createChallenge: Challenge;
@@ -2615,6 +2730,11 @@ export type MutationCommentOnVideoArgs = {
videoId: Scalars["Int"]["input"];
};
export type MutationCompleteAuthRegistrationArgs = {
agreesToMarketing: Scalars["Boolean"]["input"];
username: Scalars["String"]["input"];
};
export type MutationCreateBucketSetArgs = {
params: CreateBucketSetInput;
};
@@ -3114,6 +3234,7 @@ export type Query = {
doesUsernameExist: Scalars["Boolean"]["output"];
getAggregatedShotMetrics: Array<AggregateResultGql>;
getAppleAppAccountToken: Scalars["String"]["output"];
getAuthBootstrap: AuthBootstrapGql;
getAvailableSubscriptionOptions: StripeSubscriptionOptionsGql;
getBucketSet?: Maybe<BucketSetGql>;
getDeployedConfig: DeployedConfigGql;
@@ -3708,10 +3829,10 @@ export type SessionCoachFeedbackGql = {
};
export enum SessionCoachFeedbackResponseEnum {
AlreadyWorkingOnThis = "ALREADY_WORKING_ON_THIS",
Helpful = "HELPFUL",
NotEnoughEvidence = "NOT_ENOUGH_EVIDENCE",
WrongFocus = "WRONG_FOCUS",
NotInsightful = "NOT_INSIGHTFUL",
NotRelevant = "NOT_RELEVANT",
}
export type SessionCoachGql = {
@@ -3975,6 +4096,25 @@ export enum SimulationEventType {
StickBall = "STICK_BALL",
}
export enum SocialAuthPlatformEnum {
Android = "ANDROID",
Ios = "IOS",
Web = "WEB",
}
export type SocialAuthProviderAvailabilityGql = {
__typename?: "SocialAuthProviderAvailabilityGQL";
enabled: Scalars["Boolean"]["output"];
platform: SocialAuthPlatformEnum;
provider: SocialAuthProviderEnum;
};
export enum SocialAuthProviderEnum {
Apple = "APPLE",
Facebook = "FACEBOOK",
Google = "GOOGLE",
}
export type SpinTypeBreakdownGql = {
__typename?: "SpinTypeBreakdownGQL";
center: Scalars["Int"]["output"];
@@ -4569,6 +4709,31 @@ export type GetAggregatedShotMetricsQuery = {
}>;
};
export type GetAuthBootstrapQueryVariables = Exact<{ [key: string]: never }>;
export type GetAuthBootstrapQuery = {
__typename?: "Query";
getAuthBootstrap: {
__typename?: "AuthBootstrapGQL";
status: AuthBootstrapStatusEnum;
user?: { __typename?: "UserGQL"; id: number; username: string } | null;
};
};
export type CompleteAuthRegistrationMutationVariables = Exact<{
username: Scalars["String"]["input"];
agreesToMarketing: Scalars["Boolean"]["input"];
}>;
export type CompleteAuthRegistrationMutation = {
__typename?: "Mutation";
completeAuthRegistration: {
__typename?: "CompleteAuthRegistrationGQL";
errorCode?: AuthRegistrationErrorEnum | null;
user?: { __typename?: "UserGQL"; id: number; username: string } | null;
};
};
export type GetChallengesQueryVariables = Exact<{ [key: string]: never }>;
export type GetChallengesQuery = {
@@ -4996,6 +5161,12 @@ export type GetDeployedConfigQuery = {
message: string;
priority: number;
}>;
socialAuthProviderAvailability: Array<{
__typename?: "SocialAuthProviderAvailabilityGQL";
provider: SocialAuthProviderEnum;
platform: SocialAuthPlatformEnum;
enabled: boolean;
}>;
};
};
@@ -10580,6 +10751,144 @@ export type GetAggregatedShotMetricsQueryResult = Apollo.QueryResult<
GetAggregatedShotMetricsQuery,
GetAggregatedShotMetricsQueryVariables
>;
export const GetAuthBootstrapDocument = gql`
query getAuthBootstrap {
getAuthBootstrap {
status
user {
id
username
}
}
}
`;
/**
* __useGetAuthBootstrapQuery__
*
* To run a query within a React component, call `useGetAuthBootstrapQuery` and pass it any options that fit your needs.
* When your component renders, `useGetAuthBootstrapQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetAuthBootstrapQuery({
* variables: {
* },
* });
*/
export function useGetAuthBootstrapQuery(
baseOptions?: Apollo.QueryHookOptions<
GetAuthBootstrapQuery,
GetAuthBootstrapQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<GetAuthBootstrapQuery, GetAuthBootstrapQueryVariables>(
GetAuthBootstrapDocument,
options,
);
}
export function useGetAuthBootstrapLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetAuthBootstrapQuery,
GetAuthBootstrapQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
GetAuthBootstrapQuery,
GetAuthBootstrapQueryVariables
>(GetAuthBootstrapDocument, options);
}
export function useGetAuthBootstrapSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetAuthBootstrapQuery,
GetAuthBootstrapQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetAuthBootstrapQuery,
GetAuthBootstrapQueryVariables
>(GetAuthBootstrapDocument, options);
}
export type GetAuthBootstrapQueryHookResult = ReturnType<
typeof useGetAuthBootstrapQuery
>;
export type GetAuthBootstrapLazyQueryHookResult = ReturnType<
typeof useGetAuthBootstrapLazyQuery
>;
export type GetAuthBootstrapSuspenseQueryHookResult = ReturnType<
typeof useGetAuthBootstrapSuspenseQuery
>;
export type GetAuthBootstrapQueryResult = Apollo.QueryResult<
GetAuthBootstrapQuery,
GetAuthBootstrapQueryVariables
>;
export const CompleteAuthRegistrationDocument = gql`
mutation completeAuthRegistration(
$username: String!
$agreesToMarketing: Boolean!
) {
completeAuthRegistration(
username: $username
agreesToMarketing: $agreesToMarketing
) {
errorCode
user {
id
username
}
}
}
`;
export type CompleteAuthRegistrationMutationFn = Apollo.MutationFunction<
CompleteAuthRegistrationMutation,
CompleteAuthRegistrationMutationVariables
>;
/**
* __useCompleteAuthRegistrationMutation__
*
* To run a mutation, you first call `useCompleteAuthRegistrationMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useCompleteAuthRegistrationMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [completeAuthRegistrationMutation, { data, loading, error }] = useCompleteAuthRegistrationMutation({
* variables: {
* username: // value for 'username'
* agreesToMarketing: // value for 'agreesToMarketing'
* },
* });
*/
export function useCompleteAuthRegistrationMutation(
baseOptions?: Apollo.MutationHookOptions<
CompleteAuthRegistrationMutation,
CompleteAuthRegistrationMutationVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useMutation<
CompleteAuthRegistrationMutation,
CompleteAuthRegistrationMutationVariables
>(CompleteAuthRegistrationDocument, options);
}
export type CompleteAuthRegistrationMutationHookResult = ReturnType<
typeof useCompleteAuthRegistrationMutation
>;
export type CompleteAuthRegistrationMutationResult =
Apollo.MutationResult<CompleteAuthRegistrationMutation>;
export type CompleteAuthRegistrationMutationOptions =
Apollo.BaseMutationOptions<
CompleteAuthRegistrationMutation,
CompleteAuthRegistrationMutationVariables
>;
export const GetChallengesDocument = gql`
query GetChallenges {
challenges {
@@ -11987,6 +12296,11 @@ export const GetDeployedConfigDocument = gql`
}
defaultAndroidRecordingFormat
bucketUrl
socialAuthProviderAvailability {
provider
platform
enabled
}
}
}
`;

25
src/operations/auth.gql Normal file
View File

@@ -0,0 +1,25 @@
query getAuthBootstrap {
getAuthBootstrap {
status
user {
id
username
}
}
}
mutation completeAuthRegistration(
$username: String!
$agreesToMarketing: Boolean!
) {
completeAuthRegistration(
username: $username
agreesToMarketing: $agreesToMarketing
) {
errorCode
user {
id
username
}
}
}

View File

@@ -19,5 +19,10 @@ query getDeployedConfig {
}
defaultAndroidRecordingFormat
bucketUrl
socialAuthProviderAvailability {
provider
platform
enabled
}
}
}

View File

@@ -42,6 +42,25 @@ type AppleIapSubscriptionOptionsGQL {
productIds: [String!]!
}
type AuthBootstrapGQL {
status: AuthBootstrapStatusEnum!
user: UserGQL
}
enum AuthBootstrapStatusEnum {
REGISTERED
NEEDS_PROFILE
REGISTRATION_DISABLED
}
enum AuthRegistrationErrorEnum {
USERNAME_UNAVAILABLE
REGISTRATION_DISABLED
VERIFIED_EMAIL_REQUIRED
INVALID_USERNAME
UNSUPPORTED_PROVIDER
}
type BallTrajectoryGQL {
ballId: Int!
points: [TrajectoryPointGQL!]!
@@ -225,6 +244,11 @@ type CommentGQL {
replyToCommentId: Int
}
type CompleteAuthRegistrationGQL {
user: UserGQL
errorCode: AuthRegistrationErrorEnum
}
type CountLeaderboardGQL {
entries: [UserShotCountEntry!]!
}
@@ -337,6 +361,7 @@ type DeployedConfigGQL {
storageLimitEnforcementEnabled: Boolean!
capabilityEnforcementEnabled: Boolean!
bannerMessages: [BannerGQL!]!
socialAuthProviderAvailability: [SocialAuthProviderAvailabilityGQL!]!
defaultAndroidRecordingFormat: StreamSegmentTypeEnum!
bucketUrl: String!
}
@@ -408,6 +433,7 @@ input FilterInput @oneOf {
userId: [Int!]
runId: [Int!]
username: [String!]
playerIndex: [Int!]
fargoRating: FloatRangeFilter
make: [Boolean!]
tags: [VideoTagInput!]
@@ -737,6 +763,10 @@ type Mutation {
response: SessionCoachFeedbackResponseEnum!
): SessionCoachFeedbackGQL!
requestSessionCoachGeneration(videoId: Int!): SessionCoachGQL!
completeAuthRegistration(
username: String!
agreesToMarketing: Boolean!
): CompleteAuthRegistrationGQL!
getProfileImageUploadLink(
fileExt: String = ".png"
): GetProfileUploadLinkReturn!
@@ -1118,6 +1148,7 @@ type Query {
): [ShotGQL!]!
getShotsByIds(ids: [Int!]!): [ShotGQL!]!
getUsageStats(days: Int! = 30): UsageStatsGQL!
getAuthBootstrap: AuthBootstrapGQL!
getUser(userId: Int!): UserGQL
doesUsernameExist(candidateUsername: String!): Boolean!
getLoggedInUser: UserGQL
@@ -1406,8 +1437,8 @@ type SessionCoachFeedbackGQL {
enum SessionCoachFeedbackResponseEnum {
HELPFUL
WRONG_FOCUS
ALREADY_WORKING_ON_THIS
NOT_RELEVANT
NOT_INSIGHTFUL
NOT_ENOUGH_EVIDENCE
}
@@ -1614,6 +1645,24 @@ enum SimulationEventType {
BALL_STOP
}
enum SocialAuthPlatformEnum {
WEB
IOS
ANDROID
}
type SocialAuthProviderAvailabilityGQL {
provider: SocialAuthProviderEnum!
platform: SocialAuthPlatformEnum!
enabled: Boolean!
}
enum SocialAuthProviderEnum {
GOOGLE
APPLE
FACEBOOK
}
type SpinTypeBreakdownGQL {
draw: Int!
center: Int!