Add player cluster + labeling mutation types
All checks were successful
Tests / Tests (pull_request) Successful in 10s
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Schema additions for the per-video player labeling UI:
* `PlayerClusterGQL` / `PlayerClusterShotGQL` — read shape.
* `FinalizePlayerAssignmentsInput` + `ClusterAssignmentInput` +
`ShotMoveInput` — write shape.
* Query: `videoPlayerClusters(videoId)`.
* Mutation: `finalizePlayerAssignments(input)`.
Generated by `just gql` from the backend type definitions in
`railbird/datatypes/gql/shooter.py` and resolvers in
`railbird/server/resolvers/shooter.py`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -205,6 +205,11 @@ export enum ClientUploadStatusEnum {
|
|||||||
UploadEnabled = "UPLOAD_ENABLED",
|
UploadEnabled = "UPLOAD_ENABLED",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ClusterAssignmentInput = {
|
||||||
|
clusterId: Scalars["Int"]["input"];
|
||||||
|
userId?: InputMaybe<Scalars["Int"]["input"]>;
|
||||||
|
};
|
||||||
|
|
||||||
export type CommentGql = {
|
export type CommentGql = {
|
||||||
__typename?: "CommentGQL";
|
__typename?: "CommentGQL";
|
||||||
id: Scalars["Int"]["output"];
|
id: Scalars["Int"]["output"];
|
||||||
@@ -224,6 +229,11 @@ export type CreateBucketSetInput = {
|
|||||||
keyName: Scalars["String"]["input"];
|
keyName: Scalars["String"]["input"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CreateCustomerPortalSessionResultGql = {
|
||||||
|
__typename?: "CreateCustomerPortalSessionResultGQL";
|
||||||
|
portalUrl: Scalars["String"]["output"];
|
||||||
|
};
|
||||||
|
|
||||||
export type CreateSubscriptionResultGql = {
|
export type CreateSubscriptionResultGql = {
|
||||||
__typename?: "CreateSubscriptionResultGQL";
|
__typename?: "CreateSubscriptionResultGQL";
|
||||||
checkoutUrl: Scalars["String"]["output"];
|
checkoutUrl: Scalars["String"]["output"];
|
||||||
@@ -2177,6 +2187,12 @@ export type FilterInput =
|
|||||||
videoId: Array<Scalars["Int"]["input"]>;
|
videoId: Array<Scalars["Int"]["input"]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FinalizePlayerAssignmentsInput = {
|
||||||
|
clusterAssignments?: Array<ClusterAssignmentInput>;
|
||||||
|
shotMoves?: Array<ShotMoveInput>;
|
||||||
|
videoId: Scalars["Int"]["input"];
|
||||||
|
};
|
||||||
|
|
||||||
export type FloatOrdering = {
|
export type FloatOrdering = {
|
||||||
descending?: Scalars["Boolean"]["input"];
|
descending?: Scalars["Boolean"]["input"];
|
||||||
startingAt?: InputMaybe<Scalars["Float"]["input"]>;
|
startingAt?: InputMaybe<Scalars["Float"]["input"]>;
|
||||||
@@ -2373,6 +2389,7 @@ export type Mutation = {
|
|||||||
commentOnVideo: Scalars["Boolean"]["output"];
|
commentOnVideo: Scalars["Boolean"]["output"];
|
||||||
createBucketSet: BucketSetGql;
|
createBucketSet: BucketSetGql;
|
||||||
createChallenge: Challenge;
|
createChallenge: Challenge;
|
||||||
|
createCustomerPortalSession: CreateCustomerPortalSessionResultGql;
|
||||||
createRuleSet: RuleSet;
|
createRuleSet: RuleSet;
|
||||||
createSubscription: CreateSubscriptionResultGql;
|
createSubscription: CreateSubscriptionResultGql;
|
||||||
createUploadStream: CreateUploadStreamReturn;
|
createUploadStream: CreateUploadStreamReturn;
|
||||||
@@ -2388,6 +2405,7 @@ export type Mutation = {
|
|||||||
editUploadStream: Scalars["Boolean"]["output"];
|
editUploadStream: Scalars["Boolean"]["output"];
|
||||||
editUser: UserGql;
|
editUser: UserGql;
|
||||||
ensureStripeCustomerExists: UserGql;
|
ensureStripeCustomerExists: UserGql;
|
||||||
|
finalizePlayerAssignments: Array<PlayerClusterGql>;
|
||||||
findPrerecordTableLayout?: Maybe<HomographyInfoGql>;
|
findPrerecordTableLayout?: Maybe<HomographyInfoGql>;
|
||||||
followUser: UserGql;
|
followUser: UserGql;
|
||||||
getHlsInitUploadLink: GetUploadLinkReturn;
|
getHlsInitUploadLink: GetUploadLinkReturn;
|
||||||
@@ -2511,6 +2529,10 @@ export type MutationEditUserArgs = {
|
|||||||
input: EditUserInputGql;
|
input: EditUserInputGql;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MutationFinalizePlayerAssignmentsArgs = {
|
||||||
|
input: FinalizePlayerAssignmentsInput;
|
||||||
|
};
|
||||||
|
|
||||||
export type MutationFindPrerecordTableLayoutArgs = {
|
export type MutationFindPrerecordTableLayoutArgs = {
|
||||||
b64Image: Scalars["String"]["input"];
|
b64Image: Scalars["String"]["input"];
|
||||||
videoId: Scalars["Int"]["input"];
|
videoId: Scalars["Int"]["input"];
|
||||||
@@ -2673,6 +2695,29 @@ export type PageInfoGql = {
|
|||||||
hasNextPage: Scalars["Boolean"]["output"];
|
hasNextPage: Scalars["Boolean"]["output"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PlayerClusterGql = {
|
||||||
|
__typename?: "PlayerClusterGQL";
|
||||||
|
clusterId: Scalars["Int"]["output"];
|
||||||
|
confirmed: Scalars["Boolean"]["output"];
|
||||||
|
nShots: Scalars["Int"]["output"];
|
||||||
|
shots: Array<PlayerClusterShotGql>;
|
||||||
|
userId?: Maybe<Scalars["Int"]["output"]>;
|
||||||
|
videoId: Scalars["Int"]["output"];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PlayerClusterShotGql = {
|
||||||
|
__typename?: "PlayerClusterShotGQL";
|
||||||
|
bboxX1: Scalars["Int"]["output"];
|
||||||
|
bboxX2: Scalars["Int"]["output"];
|
||||||
|
bboxY1: Scalars["Int"]["output"];
|
||||||
|
bboxY2: Scalars["Int"]["output"];
|
||||||
|
confidence: Scalars["Float"]["output"];
|
||||||
|
cropUrl?: Maybe<Scalars["String"]["output"]>;
|
||||||
|
fullFrameUrl?: Maybe<Scalars["String"]["output"]>;
|
||||||
|
isConfirmed: Scalars["Boolean"]["output"];
|
||||||
|
shotId: Scalars["Int"]["output"];
|
||||||
|
};
|
||||||
|
|
||||||
export enum PocketEnum {
|
export enum PocketEnum {
|
||||||
Corner = "CORNER",
|
Corner = "CORNER",
|
||||||
Side = "SIDE",
|
Side = "SIDE",
|
||||||
@@ -2783,6 +2828,7 @@ export type Query = {
|
|||||||
notifications: NotificationConnection;
|
notifications: NotificationConnection;
|
||||||
ruleSets: Array<RuleSet>;
|
ruleSets: Array<RuleSet>;
|
||||||
unreadNotificationCount: Scalars["Int"]["output"];
|
unreadNotificationCount: Scalars["Int"]["output"];
|
||||||
|
videoPlayerClusters: Array<PlayerClusterGql>;
|
||||||
waitFor: Scalars["Float"]["output"];
|
waitFor: Scalars["Float"]["output"];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2949,6 +2995,10 @@ export type QueryNotificationsArgs = {
|
|||||||
offset?: Scalars["Int"]["input"];
|
offset?: Scalars["Int"]["input"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type QueryVideoPlayerClustersArgs = {
|
||||||
|
videoId: Scalars["Int"]["input"];
|
||||||
|
};
|
||||||
|
|
||||||
export type QueryWaitForArgs = {
|
export type QueryWaitForArgs = {
|
||||||
duration: Scalars["Float"]["input"];
|
duration: Scalars["Float"]["input"];
|
||||||
};
|
};
|
||||||
@@ -3166,6 +3216,11 @@ export type ShotGql = {
|
|||||||
videoId: Scalars["Int"]["output"];
|
videoId: Scalars["Int"]["output"];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ShotMoveInput = {
|
||||||
|
newClusterId: Scalars["Int"]["input"];
|
||||||
|
shotId: Scalars["Int"]["input"];
|
||||||
|
};
|
||||||
|
|
||||||
export type ShotsOrderingComponent =
|
export type ShotsOrderingComponent =
|
||||||
| {
|
| {
|
||||||
difficulty: FloatOrdering;
|
difficulty: FloatOrdering;
|
||||||
@@ -3264,6 +3319,7 @@ export type StripeProductGql = {
|
|||||||
export type StripeSubscriptionOptionsGql = {
|
export type StripeSubscriptionOptionsGql = {
|
||||||
__typename?: "StripeSubscriptionOptionsGQL";
|
__typename?: "StripeSubscriptionOptionsGQL";
|
||||||
products: Array<StripeProductGql>;
|
products: Array<StripeProductGql>;
|
||||||
|
trialPeriodDays?: Maybe<Scalars["Int"]["output"]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum StripeSubscriptionStatusEnum {
|
export enum StripeSubscriptionStatusEnum {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type Query {
|
|||||||
limit: Int! = 500
|
limit: Int! = 500
|
||||||
countRespectsLimit: Boolean! = false
|
countRespectsLimit: Boolean! = false
|
||||||
): GetRunsResult!
|
): GetRunsResult!
|
||||||
|
videoPlayerClusters(videoId: Int!): [PlayerClusterGQL!]!
|
||||||
getShotAnnotationTypes(errorTypes: Boolean = false): [ShotAnnotationTypeGQL!]!
|
getShotAnnotationTypes(errorTypes: Boolean = false): [ShotAnnotationTypeGQL!]!
|
||||||
getTableState(
|
getTableState(
|
||||||
b64Image: String!
|
b64Image: String!
|
||||||
@@ -860,6 +861,27 @@ input DatetimeOrdering {
|
|||||||
startingAt: DateTime = null
|
startingAt: DateTime = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlayerClusterGQL {
|
||||||
|
videoId: Int!
|
||||||
|
clusterId: Int!
|
||||||
|
nShots: Int!
|
||||||
|
userId: Int
|
||||||
|
confirmed: Boolean!
|
||||||
|
shots: [PlayerClusterShotGQL!]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlayerClusterShotGQL {
|
||||||
|
shotId: Int!
|
||||||
|
bboxX1: Int!
|
||||||
|
bboxY1: Int!
|
||||||
|
bboxX2: Int!
|
||||||
|
bboxY2: Int!
|
||||||
|
confidence: Float!
|
||||||
|
isConfirmed: Boolean!
|
||||||
|
cropUrl: String
|
||||||
|
fullFrameUrl: String
|
||||||
|
}
|
||||||
|
|
||||||
type TableStateGQL {
|
type TableStateGQL {
|
||||||
identifierToPosition: [[Float!]!]!
|
identifierToPosition: [[Float!]!]!
|
||||||
homography: HomographyInfoGQL
|
homography: HomographyInfoGQL
|
||||||
@@ -940,6 +962,7 @@ type UserRelationship {
|
|||||||
|
|
||||||
type StripeSubscriptionOptionsGQL {
|
type StripeSubscriptionOptionsGQL {
|
||||||
products: [StripeProductGQL!]!
|
products: [StripeProductGQL!]!
|
||||||
|
trialPeriodDays: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type StripeProductGQL {
|
type StripeProductGQL {
|
||||||
@@ -1093,6 +1116,9 @@ type Mutation {
|
|||||||
markAllNotificationsAsRead: Boolean!
|
markAllNotificationsAsRead: Boolean!
|
||||||
markNotificationsAsRead(notificationIds: [Int!]!): Boolean!
|
markNotificationsAsRead(notificationIds: [Int!]!): Boolean!
|
||||||
deleteNotification(notificationId: Int!): Boolean!
|
deleteNotification(notificationId: Int!): Boolean!
|
||||||
|
finalizePlayerAssignments(
|
||||||
|
input: FinalizePlayerAssignmentsInput!
|
||||||
|
): [PlayerClusterGQL!]!
|
||||||
addAnnotationToShot(
|
addAnnotationToShot(
|
||||||
shotId: Int!
|
shotId: Int!
|
||||||
annotationName: String!
|
annotationName: String!
|
||||||
@@ -1117,6 +1143,7 @@ type Mutation {
|
|||||||
ensureStripeCustomerExists: UserGQL!
|
ensureStripeCustomerExists: UserGQL!
|
||||||
deleteUser: Boolean!
|
deleteUser: Boolean!
|
||||||
createSubscription(priceId: String!): CreateSubscriptionResultGQL!
|
createSubscription(priceId: String!): CreateSubscriptionResultGQL!
|
||||||
|
createCustomerPortalSession: CreateCustomerPortalSessionResultGQL!
|
||||||
cancelSubscription: UserSubscriptionStatusGQL!
|
cancelSubscription: UserSubscriptionStatusGQL!
|
||||||
grantManualEntitlement(
|
grantManualEntitlement(
|
||||||
userId: Int!
|
userId: Int!
|
||||||
@@ -1163,6 +1190,22 @@ enum ReportReasonEnum {
|
|||||||
OTHER
|
OTHER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input FinalizePlayerAssignmentsInput {
|
||||||
|
videoId: Int!
|
||||||
|
clusterAssignments: [ClusterAssignmentInput!]! = []
|
||||||
|
shotMoves: [ShotMoveInput!]! = []
|
||||||
|
}
|
||||||
|
|
||||||
|
input ClusterAssignmentInput {
|
||||||
|
clusterId: Int!
|
||||||
|
userId: Int = null
|
||||||
|
}
|
||||||
|
|
||||||
|
input ShotMoveInput {
|
||||||
|
shotId: Int!
|
||||||
|
newClusterId: Int!
|
||||||
|
}
|
||||||
|
|
||||||
type AddShotAnnotationReturn {
|
type AddShotAnnotationReturn {
|
||||||
value: SuccessfulAddAddShotAnnotationErrors!
|
value: SuccessfulAddAddShotAnnotationErrors!
|
||||||
}
|
}
|
||||||
@@ -1256,6 +1299,10 @@ type CreateSubscriptionResultGQL {
|
|||||||
sessionId: String!
|
sessionId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreateCustomerPortalSessionResultGQL {
|
||||||
|
portalUrl: String!
|
||||||
|
}
|
||||||
|
|
||||||
enum CancellationReasonEnum {
|
enum CancellationReasonEnum {
|
||||||
DONT_PLAY_ENOUGH
|
DONT_PLAY_ENOUGH
|
||||||
TOO_EXPENSIVE
|
TOO_EXPENSIVE
|
||||||
|
|||||||
Reference in New Issue
Block a user