Compare commits

...

11 Commits

Author SHA1 Message Date
8f663b766e add initPlaylistUploadStatus to UploadStreamWithDetails fragment
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2026-04-14 13:12:17 -07:00
ad9cab4543 Merge pull request 'Get Game Type Tag Operations' (#234) from loewy/get-game-type-tag-metrics-operation into master
Reviewed-on: #234
2026-04-14 20:11:43 +00:00
cd3ecdfba4 Merge pull request 'Add schema getGameTypeTagMetrics' (#232) from loewy/add-get-game-type-tag-metrics into master
Reviewed-on: #232
2026-04-01 23:23:16 +00:00
28ba01c07f operation
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-03-30 15:31:24 -07:00
27a0c08cd5 add schema getGameTypeTagMetrics
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2026-03-30 13:09:18 -07:00
99f0913fd8 Merge pull request 'Add manual entitlement GraphQL schema fields' (#231) from ivan/manual-entitlement-abstraction-gql into master
Reviewed-on: #231
2026-03-22 18:32:22 +00:00
dfb0e02630 Add manual entitlement GraphQL schema fields
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-03-22 11:23:11 -07:00
c4a2e184fb Merge pull request 'Add lowestUnuploadedSegmentIndex to operation' (#230) from loewy/add-lowest-unuploaded-segment-index-to-stream-monitoring-details into master
Reviewed-on: #230
2026-03-20 23:39:50 +00:00
f14cf3b255 add lowestUnuploadedSegmentIndex to operation
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-03-18 16:43:31 -07:00
c46776d417 Merge pull request 'Upload Quota GQL' (#227) from loewy/upload-quota-limit-gql into master
Reviewed-on: #227
2026-03-18 21:33:26 +00:00
6ab5286a49 add expected durations to operation
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-03-17 17:22:19 -07:00
5 changed files with 218 additions and 4 deletions

View File

@@ -316,6 +316,13 @@ export type EditableShotFieldInputGql = {
targetPocketAngleDirection?: InputMaybe<ShotDirectionEnum>; targetPocketAngleDirection?: InputMaybe<ShotDirectionEnum>;
}; };
export enum EntitlementSourceTypeEnum {
Admin = "ADMIN",
AlphaLegacy = "ALPHA_LEGACY",
Manual = "MANUAL",
Stripe = "STRIPE",
}
export type EnumAggregation = { export type EnumAggregation = {
feature: Scalars["String"]["input"]; feature: Scalars["String"]["input"];
}; };
@@ -2184,6 +2191,26 @@ export type FloatRangeFilter = {
lessThanInclusive?: Scalars["Boolean"]["input"]; lessThanInclusive?: Scalars["Boolean"]["input"];
}; };
export type GameTypeTagMetric = {
__typename?: "GameTypeTagMetric";
madeShots: Scalars["Int"]["output"];
makeRate: Scalars["Float"]["output"];
shotCount: Scalars["Int"]["output"];
tableSize?: Maybe<Scalars["Float"]["output"]>;
tagLabel: Scalars["String"]["output"];
tagName: Scalars["String"]["output"];
};
export type GameTypeTagMetricsInput = {
createdAt?: InputMaybe<DateRangeFilter>;
groupByTableSize?: Scalars["Boolean"]["input"];
includePrivate?: IncludePrivateEnum;
includeUnknown?: Scalars["Boolean"]["input"];
maxTags?: InputMaybe<Scalars["Int"]["input"]>;
tagClass?: InputMaybe<Scalars["String"]["input"]>;
userId: Scalars["Int"]["input"];
};
export type GetProfileUploadLinkErrors = { export type GetProfileUploadLinkErrors = {
__typename?: "GetProfileUploadLinkErrors"; __typename?: "GetProfileUploadLinkErrors";
error: TooManyProfileImageUploadsErr; error: TooManyProfileImageUploadsErr;
@@ -2366,6 +2393,7 @@ export type Mutation = {
getHlsInitUploadLink: GetUploadLinkReturn; getHlsInitUploadLink: GetUploadLinkReturn;
getProfileImageUploadLink: GetProfileUploadLinkReturn; getProfileImageUploadLink: GetProfileUploadLinkReturn;
getUploadLink: GetUploadLinkReturn; getUploadLink: GetUploadLinkReturn;
grantManualEntitlement: UserSubscriptionStatusGql;
inviteUsersToChallenge: Array<ChallengeInvitation>; inviteUsersToChallenge: Array<ChallengeInvitation>;
markAllNotificationsAsRead: Scalars["Boolean"]["output"]; markAllNotificationsAsRead: Scalars["Boolean"]["output"];
markNotificationAsRead: Scalars["Boolean"]["output"]; markNotificationAsRead: Scalars["Boolean"]["output"];
@@ -2375,6 +2403,7 @@ export type Mutation = {
reportContent: Scalars["Boolean"]["output"]; reportContent: Scalars["Boolean"]["output"];
respondToChallengeInvitation: ChallengeInvitation; respondToChallengeInvitation: ChallengeInvitation;
retireTags: Scalars["Boolean"]["output"]; retireTags: Scalars["Boolean"]["output"];
revokeManualEntitlement: UserSubscriptionStatusGql;
setLoggerLevel: Scalars["Boolean"]["output"]; setLoggerLevel: Scalars["Boolean"]["output"];
setSegmentDuration: Scalars["Boolean"]["output"]; setSegmentDuration: Scalars["Boolean"]["output"];
startChallenge: ChallengeEntry; startChallenge: ChallengeEntry;
@@ -2504,6 +2533,14 @@ export type MutationGetUploadLinkArgs = {
videoId: Scalars["Int"]["input"]; videoId: Scalars["Int"]["input"];
}; };
export type MutationGrantManualEntitlementArgs = {
endsAt?: InputMaybe<Scalars["DateTime"]["input"]>;
reason?: InputMaybe<Scalars["String"]["input"]>;
startsAt?: InputMaybe<Scalars["DateTime"]["input"]>;
tierName?: Scalars["String"]["input"];
userId: Scalars["Int"]["input"];
};
export type MutationInviteUsersToChallengeArgs = { export type MutationInviteUsersToChallengeArgs = {
challengeId: Scalars["ID"]["input"]; challengeId: Scalars["ID"]["input"];
userIds: Array<Scalars["ID"]["input"]>; userIds: Array<Scalars["ID"]["input"]>;
@@ -2541,6 +2578,10 @@ export type MutationRetireTagsArgs = {
tagIds: Array<Scalars["Int"]["input"]>; tagIds: Array<Scalars["Int"]["input"]>;
}; };
export type MutationRevokeManualEntitlementArgs = {
userId: Scalars["Int"]["input"];
};
export type MutationSetLoggerLevelArgs = { export type MutationSetLoggerLevelArgs = {
level: Scalars["String"]["input"]; level: Scalars["String"]["input"];
path: Scalars["String"]["input"]; path: Scalars["String"]["input"];
@@ -2711,6 +2752,7 @@ export type Query = {
getBucketSet?: Maybe<BucketSetGql>; getBucketSet?: Maybe<BucketSetGql>;
getDeployedConfig: DeployedConfigGql; getDeployedConfig: DeployedConfigGql;
getFeedVideos: VideoHistoryGql; getFeedVideos: VideoHistoryGql;
getGameTypeTagMetrics: Array<GameTypeTagMetric>;
getLoggedInUser?: Maybe<UserGql>; getLoggedInUser?: Maybe<UserGql>;
getLongestRunsLeaderboard: RunLeaderboardGql; getLongestRunsLeaderboard: RunLeaderboardGql;
getMakesLeaderboard: CountLeaderboardGql; getMakesLeaderboard: CountLeaderboardGql;
@@ -2778,6 +2820,10 @@ export type QueryGetFeedVideosArgs = {
limit?: Scalars["Int"]["input"]; limit?: Scalars["Int"]["input"];
}; };
export type QueryGetGameTypeTagMetricsArgs = {
input: GameTypeTagMetricsInput;
};
export type QueryGetLongestRunsLeaderboardArgs = { export type QueryGetLongestRunsLeaderboardArgs = {
interval?: InputMaybe<TimeInterval>; interval?: InputMaybe<TimeInterval>;
limit?: Scalars["Int"]["input"]; limit?: Scalars["Int"]["input"];
@@ -3395,6 +3441,9 @@ export type UserSubscriptionStatusGql = {
__typename?: "UserSubscriptionStatusGQL"; __typename?: "UserSubscriptionStatusGQL";
currentPeriodEnd?: Maybe<Scalars["DateTime"]["output"]>; currentPeriodEnd?: Maybe<Scalars["DateTime"]["output"]>;
currentPeriodStart?: Maybe<Scalars["DateTime"]["output"]>; currentPeriodStart?: Maybe<Scalars["DateTime"]["output"]>;
entitlementEndsAt?: Maybe<Scalars["DateTime"]["output"]>;
entitlementSource?: Maybe<EntitlementSourceTypeEnum>;
entitlementStartsAt?: Maybe<Scalars["DateTime"]["output"]>;
hasActiveSubscription: Scalars["Boolean"]["output"]; hasActiveSubscription: Scalars["Boolean"]["output"];
stripePriceId?: Maybe<Scalars["String"]["output"]>; stripePriceId?: Maybe<Scalars["String"]["output"]>;
stripeSubscriptionId?: Maybe<Scalars["String"]["output"]>; stripeSubscriptionId?: Maybe<Scalars["String"]["output"]>;
@@ -5522,6 +5571,23 @@ export type GetUserTagsQuery = {
}>; }>;
}; };
export type GetGameTypeTagMetricsQueryVariables = Exact<{
input: GameTypeTagMetricsInput;
}>;
export type GetGameTypeTagMetricsQuery = {
__typename?: "Query";
getGameTypeTagMetrics: Array<{
__typename?: "GameTypeTagMetric";
tagName: string;
tagLabel: string;
tableSize?: number | null;
shotCount: number;
madeShots: number;
makeRate: number;
}>;
};
export type FollowUserMutationVariables = Exact<{ export type FollowUserMutationVariables = Exact<{
followedUserId: Scalars["Int"]["input"]; followedUserId: Scalars["Int"]["input"];
}>; }>;
@@ -5687,6 +5753,7 @@ export type GetStreamMonitoringDetailsQuery = {
__typename?: "UploadStreamGQL"; __typename?: "UploadStreamGQL";
id: string; id: string;
linksRequested: number; linksRequested: number;
lowestUnuploadedSegmentIndex: number;
uploadsCompleted: number; uploadsCompleted: number;
segmentProcessingCursor: number; segmentProcessingCursor: number;
isCompleted: boolean; isCompleted: boolean;
@@ -6249,6 +6316,7 @@ export type HomographyInfoFragment = {
export type CreateUploadStreamMutationVariables = Exact<{ export type CreateUploadStreamMutationVariables = Exact<{
videoMetadataInput: VideoMetadataInput; videoMetadataInput: VideoMetadataInput;
expectedDurationSeconds?: InputMaybe<Scalars["Float"]["input"]>;
}>; }>;
export type CreateUploadStreamMutation = { export type CreateUploadStreamMutation = {
@@ -6399,6 +6467,7 @@ export type UploadStreamWithDetailsFragment = {
lastIntendedSegmentBound?: number | null; lastIntendedSegmentBound?: number | null;
uploadCompletionCursor: number; uploadCompletionCursor: number;
uploadsCompleted: number; uploadsCompleted: number;
initPlaylistUploadStatus?: InitPlaylistUploadStatusEnum | null;
} | null; } | null;
}; };
@@ -6423,6 +6492,7 @@ export type GetUploadStreamsWithDetailsQuery = {
lastIntendedSegmentBound?: number | null; lastIntendedSegmentBound?: number | null;
uploadCompletionCursor: number; uploadCompletionCursor: number;
uploadsCompleted: number; uploadsCompleted: number;
initPlaylistUploadStatus?: InitPlaylistUploadStatusEnum | null;
} | null; } | null;
}>; }>;
pageInfo: { pageInfo: {
@@ -6765,6 +6835,7 @@ export const UploadStreamWithDetailsFragmentDoc = gql`
lastIntendedSegmentBound lastIntendedSegmentBound
uploadCompletionCursor uploadCompletionCursor
uploadsCompleted uploadsCompleted
initPlaylistUploadStatus
} }
} }
`; `;
@@ -11503,6 +11574,84 @@ export type GetUserTagsQueryResult = Apollo.QueryResult<
GetUserTagsQuery, GetUserTagsQuery,
GetUserTagsQueryVariables GetUserTagsQueryVariables
>; >;
export const GetGameTypeTagMetricsDocument = gql`
query GetGameTypeTagMetrics($input: GameTypeTagMetricsInput!) {
getGameTypeTagMetrics(input: $input) {
tagName
tagLabel
tableSize
shotCount
madeShots
makeRate
}
}
`;
/**
* __useGetGameTypeTagMetricsQuery__
*
* To run a query within a React component, call `useGetGameTypeTagMetricsQuery` and pass it any options that fit your needs.
* When your component renders, `useGetGameTypeTagMetricsQuery` 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 } = useGetGameTypeTagMetricsQuery({
* variables: {
* input: // value for 'input'
* },
* });
*/
export function useGetGameTypeTagMetricsQuery(
baseOptions: Apollo.QueryHookOptions<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useQuery<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>(GetGameTypeTagMetricsDocument, options);
}
export function useGetGameTypeTagMetricsLazyQuery(
baseOptions?: Apollo.LazyQueryHookOptions<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useLazyQuery<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>(GetGameTypeTagMetricsDocument, options);
}
export function useGetGameTypeTagMetricsSuspenseQuery(
baseOptions?: Apollo.SuspenseQueryHookOptions<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>,
) {
const options = { ...defaultOptions, ...baseOptions };
return Apollo.useSuspenseQuery<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>(GetGameTypeTagMetricsDocument, options);
}
export type GetGameTypeTagMetricsQueryHookResult = ReturnType<
typeof useGetGameTypeTagMetricsQuery
>;
export type GetGameTypeTagMetricsLazyQueryHookResult = ReturnType<
typeof useGetGameTypeTagMetricsLazyQuery
>;
export type GetGameTypeTagMetricsSuspenseQueryHookResult = ReturnType<
typeof useGetGameTypeTagMetricsSuspenseQuery
>;
export type GetGameTypeTagMetricsQueryResult = Apollo.QueryResult<
GetGameTypeTagMetricsQuery,
GetGameTypeTagMetricsQueryVariables
>;
export const FollowUserDocument = gql` export const FollowUserDocument = gql`
mutation followUser($followedUserId: Int!) { mutation followUser($followedUserId: Int!) {
followUser(followedUserId: $followedUserId) { followUser(followedUserId: $followedUserId) {
@@ -11968,6 +12117,7 @@ export const GetStreamMonitoringDetailsDocument = gql`
stream { stream {
id id
linksRequested linksRequested
lowestUnuploadedSegmentIndex
uploadsCompleted uploadsCompleted
segmentProcessingCursor segmentProcessingCursor
isCompleted isCompleted
@@ -13215,8 +13365,14 @@ export type FindPrerecordTableLayoutMutationOptions =
FindPrerecordTableLayoutMutationVariables FindPrerecordTableLayoutMutationVariables
>; >;
export const CreateUploadStreamDocument = gql` export const CreateUploadStreamDocument = gql`
mutation CreateUploadStream($videoMetadataInput: VideoMetadataInput!) { mutation CreateUploadStream(
createUploadStream(videoMetadata: $videoMetadataInput) { $videoMetadataInput: VideoMetadataInput!
$expectedDurationSeconds: Float = null
) {
createUploadStream(
videoMetadata: $videoMetadataInput
expectedDurationSeconds: $expectedDurationSeconds
) {
videoId videoId
} }
} }
@@ -13240,6 +13396,7 @@ export type CreateUploadStreamMutationFn = Apollo.MutationFunction<
* const [createUploadStreamMutation, { data, loading, error }] = useCreateUploadStreamMutation({ * const [createUploadStreamMutation, { data, loading, error }] = useCreateUploadStreamMutation({
* variables: { * variables: {
* videoMetadataInput: // value for 'videoMetadataInput' * videoMetadataInput: // value for 'videoMetadataInput'
* expectedDurationSeconds: // value for 'expectedDurationSeconds'
* }, * },
* }); * });
*/ */

View File

@@ -92,6 +92,17 @@ query GetUserTags {
} }
} }
query GetGameTypeTagMetrics($input: GameTypeTagMetricsInput!) {
getGameTypeTagMetrics(input: $input) {
tagName
tagLabel
tableSize
shotCount
madeShots
makeRate
}
}
mutation followUser($followedUserId: Int!) { mutation followUser($followedUserId: Int!) {
followUser(followedUserId: $followedUserId) { followUser(followedUserId: $followedUserId) {
id id

View File

@@ -10,6 +10,7 @@ query GetStreamMonitoringDetails($videoId: Int!, $debuggingJson: JSON) {
stream { stream {
id id
linksRequested linksRequested
lowestUnuploadedSegmentIndex
uploadsCompleted uploadsCompleted
segmentProcessingCursor segmentProcessingCursor
isCompleted isCompleted

View File

@@ -1,5 +1,11 @@
mutation CreateUploadStream($videoMetadataInput: VideoMetadataInput!) { mutation CreateUploadStream(
createUploadStream(videoMetadata: $videoMetadataInput) { $videoMetadataInput: VideoMetadataInput!
$expectedDurationSeconds: Float = null
) {
createUploadStream(
videoMetadata: $videoMetadataInput
expectedDurationSeconds: $expectedDurationSeconds
) {
videoId videoId
} }
} }
@@ -111,6 +117,7 @@ fragment UploadStreamWithDetails on VideoGQL {
lastIntendedSegmentBound lastIntendedSegmentBound
uploadCompletionCursor uploadCompletionCursor
uploadsCompleted uploadsCompleted
initPlaylistUploadStatus
} }
} }

View File

@@ -106,6 +106,7 @@ type Query {
filters: VideoFilterInput = null filters: VideoFilterInput = null
): VideoHistoryGQL! ): VideoHistoryGQL!
getUserTags(includeRetiredTags: Boolean = false): [TagGQL!]! getUserTags(includeRetiredTags: Boolean = false): [TagGQL!]!
getGameTypeTagMetrics(input: GameTypeTagMetricsInput!): [GameTypeTagMetric!]!
getVideo(videoId: Int!, debuggingJson: JSON = null): VideoGQL! getVideo(videoId: Int!, debuggingJson: JSON = null): VideoGQL!
getVideos(videoIds: [Int!]!): [VideoGQL!]! getVideos(videoIds: [Int!]!): [VideoGQL!]!
} }
@@ -961,6 +962,9 @@ type StripePriceGQL {
type UserSubscriptionStatusGQL { type UserSubscriptionStatusGQL {
hasActiveSubscription: Boolean! hasActiveSubscription: Boolean!
entitlementSource: EntitlementSourceTypeEnum
entitlementStartsAt: DateTime
entitlementEndsAt: DateTime
subscriptionStatus: StripeSubscriptionStatusEnum subscriptionStatus: StripeSubscriptionStatusEnum
currentPeriodStart: DateTime currentPeriodStart: DateTime
currentPeriodEnd: DateTime currentPeriodEnd: DateTime
@@ -969,6 +973,13 @@ type UserSubscriptionStatusGQL {
stripeSubscriptionId: String stripeSubscriptionId: String
} }
enum EntitlementSourceTypeEnum {
ADMIN
MANUAL
STRIPE
ALPHA_LEGACY
}
enum StripeSubscriptionStatusEnum { enum StripeSubscriptionStatusEnum {
INCOMPLETE INCOMPLETE
INCOMPLETE_EXPIRED INCOMPLETE_EXPIRED
@@ -1007,6 +1018,25 @@ type TagClassGQL {
name: String! name: String!
} }
type GameTypeTagMetric {
tagName: String!
tagLabel: String!
tableSize: Float
shotCount: Int!
madeShots: Int!
makeRate: Float!
}
input GameTypeTagMetricsInput {
userId: Int!
createdAt: DateRangeFilter = null
maxTags: Int = null
groupByTableSize: Boolean! = true
includeUnknown: Boolean! = true
tagClass: String = "game_type"
includePrivate: IncludePrivateEnum! = MINE
}
""" """
The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf). The `JSON` scalar type represents JSON values as specified by [ECMA-404](https://ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf).
""" """
@@ -1088,6 +1118,14 @@ type Mutation {
deleteUser: Boolean! deleteUser: Boolean!
createSubscription(priceId: String!): CreateSubscriptionResultGQL! createSubscription(priceId: String!): CreateSubscriptionResultGQL!
cancelSubscription: UserSubscriptionStatusGQL! cancelSubscription: UserSubscriptionStatusGQL!
grantManualEntitlement(
userId: Int!
tierName: String! = "pro"
startsAt: DateTime = null
endsAt: DateTime = null
reason: String = null
): UserSubscriptionStatusGQL!
revokeManualEntitlement(userId: Int!): UserSubscriptionStatusGQL!
submitCancellationFeedback( submitCancellationFeedback(
reasons: [CancellationReasonEnum!] = null reasons: [CancellationReasonEnum!] = null
feedback: String = null feedback: String = null