Compare commits

...

12 Commits

Author SHA1 Message Date
d1bc29b41b Add Apple IAP product config to subscription options
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-06-16 18:31:36 -07:00
853769e183 Add Apple subscription mobile operations 2026-06-16 18:31:36 -07:00
84524d165d Merge pull request 'Add followingCount to GetVideoFeed payload' (#261) from dean/feed-following-count into master
Reviewed-on: #261
2026-06-16 23:51:38 +00:00
Dean Wenstrand
f4c5fcedd6 Add followingCount to GetVideoFeed payload
All checks were successful
Tests / Tests (pull_request) Successful in 9s
Surfaces how many leading feed videos come from followed users so the
client can place the 'Trending' section divider in the blended home feed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 16:46:21 -07:00
07ca121a3e Merge pull request 'Add spinTypeBreakdown (draw/center/follow) to PlayerSummaryFields' (#259) from dean/player-spin-types into master
Reviewed-on: #259
2026-06-16 22:24:19 +00:00
Dean Wenstrand
66fb4d3dcc Add spinTypeBreakdown (draw/center/follow) to PlayerSummaryFields
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2026-06-16 14:36:56 -07:00
5293576947 Merge pull request 'Add runLengths to PlayerSummaryFields (per-player run distribution)' (#258) from dean/player-run-lengths into master
Reviewed-on: #258
2026-06-16 20:57:00 +00:00
655209e1c6 Merge pull request 'Add Apple IAP subscription options schema' (#256) from loewy/apple-iap-product-config into master
Reviewed-on: #256
2026-06-16 18:10:00 +00:00
c9576cf405 Add Apple IAP subscription options schema
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-06-16 10:47:07 -07:00
0c0cd7a7bb Merge pull request 'dean/my-drill-runs' (#257) from dean/my-drill-runs into master
Reviewed-on: #257
2026-06-16 04:25:03 +00:00
48b647636e Merge pull request 'Add GetDrillRunLeaderboard query + generated types' (#254) from dean/drill-run-leaderboard into master
Reviewed-on: #254
2026-06-16 00:52:05 +00:00
079e4e8719 Merge pull request 'Add Apple subscription sync schema' (#253) from apple-iap-pr2-backend-schema into master
Reviewed-on: #253
2026-06-12 04:50:36 +00:00
5 changed files with 285 additions and 0 deletions

View File

@@ -2754,6 +2754,7 @@ export type PlayerSummaryGql = {
representativeFullFrameUrl?: Maybe<Scalars["String"]["output"]>;
runLengths: Array<Scalars["Int"]["output"]>;
score?: Maybe<Scalars["Int"]["output"]>;
spinTypeBreakdown: SpinTypeBreakdownGql;
totalShots: Scalars["Int"]["output"];
totalShotsMade: Scalars["Int"]["output"];
userId?: Maybe<Scalars["Int"]["output"]>;
@@ -3345,6 +3346,13 @@ export type ShotsOrderingComponent =
videoId: IntOrdering;
};
export type SpinTypeBreakdownGql = {
__typename?: "SpinTypeBreakdownGQL";
center: Scalars["Int"]["output"];
draw: Scalars["Int"]["output"];
follow: Scalars["Int"]["output"];
};
export type SpinTypeCountsGql = {
__typename?: "SpinTypeCountsGQL";
center: Scalars["Int"]["output"];
@@ -3671,6 +3679,7 @@ export type VideoGql = {
export type VideoHistoryGql = {
__typename?: "VideoHistoryGQL";
followingCount: Scalars["Int"]["output"];
hasFollowing: Scalars["Boolean"]["output"];
pageInfo: PageInfoGql;
videos: Array<VideoGql>;
@@ -4292,6 +4301,12 @@ export type GetFeedQuery = {
runLengths: Array<number>;
averageDifficulty?: number | null;
averageTimeBetweenShots?: number | null;
spinTypeBreakdown: {
__typename?: "SpinTypeBreakdownGQL";
draw: number;
center: number;
follow: number;
};
}>;
currentProcessing?: {
__typename?: "VideoProcessingGQL";
@@ -4397,6 +4412,12 @@ export type VideoCardFieldsFragment = {
runLengths: Array<number>;
averageDifficulty?: number | null;
averageTimeBetweenShots?: number | null;
spinTypeBreakdown: {
__typename?: "SpinTypeBreakdownGQL";
draw: number;
center: number;
follow: number;
};
}>;
currentProcessing?: {
__typename?: "VideoProcessingGQL";
@@ -4488,6 +4509,7 @@ export type GetVideoFeedQuery = {
getFeedVideos: {
__typename?: "VideoHistoryGQL";
hasFollowing: boolean;
followingCount: number;
videos: Array<{
__typename?: "VideoGQL";
id: number;
@@ -4534,6 +4556,12 @@ export type GetVideoFeedQuery = {
runLengths: Array<number>;
averageDifficulty?: number | null;
averageTimeBetweenShots?: number | null;
spinTypeBreakdown: {
__typename?: "SpinTypeBreakdownGQL";
draw: number;
center: number;
follow: number;
};
}>;
currentProcessing?: {
__typename?: "VideoProcessingGQL";
@@ -5012,6 +5040,11 @@ export type GetAvailableSubscriptionOptionsQuery = {
getAvailableSubscriptionOptions: {
__typename?: "StripeSubscriptionOptionsGQL";
trialPeriodDays?: number | null;
appleIap: {
__typename?: "AppleIapSubscriptionOptionsGQL";
enabled: boolean;
proMonthlyProductId?: string | null;
};
products: Array<{
__typename?: "StripeProductGQL";
id: string;
@@ -5041,6 +5074,9 @@ export type GetSubscriptionStatusQuery = {
getUserSubscriptionStatus: {
__typename?: "UserSubscriptionStatusGQL";
hasActiveSubscription: boolean;
entitlementSource?: EntitlementSourceTypeEnum | null;
entitlementStartsAt?: any | null;
entitlementEndsAt?: any | null;
subscriptionStatus?: StripeSubscriptionStatusEnum | null;
currentPeriodStart?: any | null;
currentPeriodEnd?: any | null;
@@ -5050,6 +5086,38 @@ export type GetSubscriptionStatusQuery = {
};
};
export type GetAppleAppAccountTokenQueryVariables = Exact<{
[key: string]: never;
}>;
export type GetAppleAppAccountTokenQuery = {
__typename?: "Query";
getAppleAppAccountToken: string;
};
export type SyncAppleSubscriptionMutationVariables = Exact<{
signedTransactionInfo: Scalars["String"]["input"];
}>;
export type SyncAppleSubscriptionMutation = {
__typename?: "Mutation";
syncAppleSubscription: {
__typename?: "SyncAppleSubscriptionResultGQL";
ok: boolean;
errorCode?: string | null;
errorMessage?: string | null;
hasActiveSubscription: boolean;
entitlementSource?: EntitlementSourceTypeEnum | null;
entitlementStartsAt?: any | null;
entitlementEndsAt?: any | null;
appleStatus?: number | null;
originalTransactionId?: string | null;
latestTransactionId?: string | null;
productId?: string | null;
expiresAt?: any | null;
};
};
export type CancelSubscriptionMutationVariables = Exact<{
[key: string]: never;
}>;
@@ -5059,6 +5127,9 @@ export type CancelSubscriptionMutation = {
cancelSubscription: {
__typename?: "UserSubscriptionStatusGQL";
hasActiveSubscription: boolean;
entitlementSource?: EntitlementSourceTypeEnum | null;
entitlementStartsAt?: any | null;
entitlementEndsAt?: any | null;
subscriptionStatus?: StripeSubscriptionStatusEnum | null;
currentPeriodStart?: any | null;
currentPeriodEnd?: any | null;
@@ -5178,6 +5249,12 @@ export type PlayerSummaryFieldsFragment = {
runLengths: Array<number>;
averageDifficulty?: number | null;
averageTimeBetweenShots?: number | null;
spinTypeBreakdown: {
__typename?: "SpinTypeBreakdownGQL";
draw: number;
center: number;
follow: number;
};
};
export type PlayerClusterShotFieldsFragment = {
@@ -6304,6 +6381,12 @@ export type GetVideoDetailsQuery = {
runLengths: Array<number>;
averageDifficulty?: number | null;
averageTimeBetweenShots?: number | null;
spinTypeBreakdown: {
__typename?: "SpinTypeBreakdownGQL";
draw: number;
center: number;
follow: number;
};
}>;
};
};
@@ -6424,6 +6507,12 @@ export type GetVideoCardQuery = {
runLengths: Array<number>;
averageDifficulty?: number | null;
averageTimeBetweenShots?: number | null;
spinTypeBreakdown: {
__typename?: "SpinTypeBreakdownGQL";
draw: number;
center: number;
follow: number;
};
}>;
currentProcessing?: {
__typename?: "VideoProcessingGQL";
@@ -7072,6 +7161,11 @@ export const PlayerSummaryFieldsFragmentDoc = gql`
score
longestRun
runLengths
spinTypeBreakdown {
draw
center
follow
}
averageDifficulty
averageTimeBetweenShots
}
@@ -9429,6 +9523,7 @@ export const GetVideoFeedDocument = gql`
endCursor
}
hasFollowing
followingCount
}
}
${VideoCardFieldsFragmentDoc}
@@ -10594,6 +10689,10 @@ export const GetAvailableSubscriptionOptionsDocument = gql`
query GetAvailableSubscriptionOptions {
getAvailableSubscriptionOptions {
trialPeriodDays
appleIap {
enabled
proMonthlyProductId
}
products {
id
name
@@ -10681,6 +10780,9 @@ export const GetSubscriptionStatusDocument = gql`
query GetSubscriptionStatus {
getUserSubscriptionStatus {
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
subscriptionStatus
currentPeriodStart
currentPeriodEnd
@@ -10755,10 +10857,146 @@ export type GetSubscriptionStatusQueryResult = Apollo.QueryResult<
GetSubscriptionStatusQuery,
GetSubscriptionStatusQueryVariables
>;
export const GetAppleAppAccountTokenDocument = gql`
query GetAppleAppAccountToken {
getAppleAppAccountToken
}
`;
/**
* __useGetAppleAppAccountTokenQuery__
*
* To run a query within a React component, call `useGetAppleAppAccountTokenQuery` and pass it any options that fit your needs.
* When your component renders, `useGetAppleAppAccountTokenQuery` 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 } = useGetAppleAppAccountTokenQuery({
* variables: {
* },
* });
*/
export function useGetAppleAppAccountTokenQuery(
baseOptions?: Apollo.QueryHookOptions<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>(GetAppleAppAccountTokenDocument, options);
}
export function useGetAppleAppAccountTokenLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>(GetAppleAppAccountTokenDocument, options);
}
export function useGetAppleAppAccountTokenSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>(GetAppleAppAccountTokenDocument, options);
}
export type GetAppleAppAccountTokenQueryHookResult = ReturnType<
typeof useGetAppleAppAccountTokenQuery
>;
export type GetAppleAppAccountTokenLazyQueryHookResult = ReturnType<
typeof useGetAppleAppAccountTokenLazyQuery
>;
export type GetAppleAppAccountTokenSuspenseQueryHookResult = ReturnType<
typeof useGetAppleAppAccountTokenSuspenseQuery
>;
export type GetAppleAppAccountTokenQueryResult = Apollo.QueryResult<
GetAppleAppAccountTokenQuery,
GetAppleAppAccountTokenQueryVariables
>;
export const SyncAppleSubscriptionDocument = gql`
mutation SyncAppleSubscription($signedTransactionInfo: String!) {
syncAppleSubscription(
input: { signedTransactionInfo: $signedTransactionInfo }
) {
ok
errorCode
errorMessage
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
appleStatus
originalTransactionId
latestTransactionId
productId
expiresAt
}
}
`;
export type SyncAppleSubscriptionMutationFn = Apollo.MutationFunction<
SyncAppleSubscriptionMutation,
SyncAppleSubscriptionMutationVariables
>;
/**
* __useSyncAppleSubscriptionMutation__
*
* To run a mutation, you first call `useSyncAppleSubscriptionMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useSyncAppleSubscriptionMutation` 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 [syncAppleSubscriptionMutation, { data, loading, error }] = useSyncAppleSubscriptionMutation({
* variables: {
* signedTransactionInfo: // value for 'signedTransactionInfo'
* },
* });
*/
export function useSyncAppleSubscriptionMutation(
baseOptions?: Apollo.MutationHookOptions<
SyncAppleSubscriptionMutation,
SyncAppleSubscriptionMutationVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useMutation<
SyncAppleSubscriptionMutation,
SyncAppleSubscriptionMutationVariables
>(SyncAppleSubscriptionDocument, options);
}
export type SyncAppleSubscriptionMutationHookResult = ReturnType<
typeof useSyncAppleSubscriptionMutation
>;
export type SyncAppleSubscriptionMutationResult =
Apollo.MutationResult<SyncAppleSubscriptionMutation>;
export type SyncAppleSubscriptionMutationOptions = Apollo.BaseMutationOptions<
SyncAppleSubscriptionMutation,
SyncAppleSubscriptionMutationVariables
>;
export const CancelSubscriptionDocument = gql`
mutation CancelSubscription {
cancelSubscription {
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
subscriptionStatus
currentPeriodStart
currentPeriodEnd

View File

@@ -146,5 +146,6 @@ query GetVideoFeed(
endCursor
}
hasFollowing
followingCount
}
}

View File

@@ -29,6 +29,10 @@ mutation CreateCustomerPortalSession {
query GetAvailableSubscriptionOptions {
getAvailableSubscriptionOptions {
trialPeriodDays
appleIap {
enabled
proMonthlyProductId
}
products {
id
name
@@ -50,6 +54,9 @@ query GetAvailableSubscriptionOptions {
query GetSubscriptionStatus {
getUserSubscriptionStatus {
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
subscriptionStatus
currentPeriodStart
currentPeriodEnd
@@ -59,9 +66,35 @@ query GetSubscriptionStatus {
}
}
query GetAppleAppAccountToken {
getAppleAppAccountToken
}
mutation SyncAppleSubscription($signedTransactionInfo: String!) {
syncAppleSubscription(
input: { signedTransactionInfo: $signedTransactionInfo }
) {
ok
errorCode
errorMessage
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
appleStatus
originalTransactionId
latestTransactionId
productId
expiresAt
}
}
mutation CancelSubscription {
cancelSubscription {
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
subscriptionStatus
currentPeriodStart
currentPeriodEnd

View File

@@ -10,6 +10,11 @@ fragment PlayerSummaryFields on PlayerSummaryGQL {
score
longestRun
runLengths
spinTypeBreakdown {
draw
center
follow
}
averageDifficulty
averageTimeBetweenShots
}

View File

@@ -689,10 +689,17 @@ type PlayerSummaryGQL {
score: Int
longestRun: Int!
runLengths: [Int!]!
spinTypeBreakdown: SpinTypeBreakdownGQL!
averageDifficulty: Float
averageTimeBetweenShots: Float
}
type SpinTypeBreakdownGQL {
draw: Int!
center: Int!
follow: Int!
}
type DeployedConfigGQL {
allowNewUsers: Boolean!
firebase: Boolean!
@@ -725,6 +732,7 @@ type VideoHistoryGQL {
videos: [VideoGQL!]!
pageInfo: PageInfoGQL!
hasFollowing: Boolean!
followingCount: Int!
}
type PageInfoGQL {