Compare commits

..

55 Commits

Author SHA1 Message Date
Dean Wenstrand
8655cb75fc Regenerate schema + client from merged backend
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 17:05:11 -07:00
Dean Wenstrand
87d40eb990 Merge pool hall camera claim schema onto gql master
Generated files (schema.gql, index.tsx) resolved arbitrarily here; the next
commit regenerates them from the merged backend via just gql.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 17:02:20 -07:00
2f9dc86ad9 Merge pull request 'Add capability enforcement config to schema' (#279) from capability-enforcement-config into master
Reviewed-on: #279
2026-07-03 21:02:11 +00:00
e2fe6cadda Add capability enforcement config to schema
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2026-07-03 12:01:58 -07:00
aafdab5d4d Merge pull request 'Add computePotAim query and shot-simulation operations' (#278) from compute-pot-aim into master 2026-07-03 17:58:48 +00:00
adf05e3c28 Add computePotAim query and shot-simulation operations
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Schema: computePotAim(simulationInput, targetBallId, pocket) ->
PotAimGQL, the spin/throw-compensated aim solver (regenerated from
backend strawberry definitions; reuses the existing PocketIdentifier
enum). Operations: GetTableState, SimulateShot, and ComputePotAim
documents so both clients get generated hooks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 01:44:02 -07:00
64bc5c723a Add pool hall camera GraphQL operations
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2026-07-02 21:52:48 -07:00
5391466e90 Merge pull request 'Add simulateShot query, cue strike and shot projection types' (#277) from shot-simulation-stubs into master
Reviewed-on: #277
2026-07-02 23:35:30 +00:00
4ff2db1ef4 Add simulateShot query, cue strike and shot projection types
All checks were successful
Tests / Tests (pull_request) Successful in 12s
Generated from backend strawberry definitions for the shot simulation
feature (image -> pooltool scenario -> projected outcome). Backend PR:
shot-simulation-stubs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 16:12:11 -07:00
257dcdc31a Merge pull request 'Add DismissVideoExport mutation (soft-hide exports)' (#276) from dean/export-dismiss-gql into master
Reviewed-on: #276
2026-07-02 22:38:02 +00:00
Dean Wenstrand
b41365e99e Add videoName + videoThumbnailUri to VideoExportJobFields
All checks were successful
Tests / Tests (pull_request) Successful in 13s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:41:59 -07:00
Dean Wenstrand
0e8233a5d5 Add DismissVideoExport mutation (soft-hide exports)
All checks were successful
Tests / Tests (pull_request) Successful in 17s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:18:55 -07:00
b6adae4949 Merge pull request 'Storage limit enforcement schema' (#275) from storage-limit-enforcement-schema into master
Reviewed-on: #275
2026-07-01 22:29:41 +00:00
459e89d8b8 Select storage limit error fields
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-07-01 14:50:45 -07:00
fa2ff19572 Add storage limit enforcement schema 2026-07-01 14:41:21 -07:00
428286fa5a Merge pull request 'dean/video-export-gql' (#273) from dean/video-export-gql into master
Reviewed-on: #273
2026-06-30 22:48:02 +00:00
Dean Wenstrand
8771350115 Echo shotIds/runId on VideoExportJobGQL for re-export
All checks were successful
Tests / Tests (pull_request) Successful in 13s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 14:00:04 -07:00
Dean Wenstrand
f1594b8492 Video export client operations + myVideoExports list query
RequestVideoExport mutation, VideoExportJob + MyVideoExports queries (with the
VideoExportJobFields fragment) for the mobile fire-and-list flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 13:54:29 -07:00
Dean Wenstrand
3ec3e3d081 Add EXPORT_READY notification type (video export Phase 1b)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 12:51:39 -07:00
Dean Wenstrand
d2c697e4cb Add video export schema: VideoExportJob + request/query + mode/status enums
Generated from the backend video export resolvers (Phase 1a).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 12:35:34 -07:00
3484af9dde Merge pull request 'Add storage usage readiness fields' (#272) from storage-usage-readiness into master
Reviewed-on: #272
2026-06-30 17:12:00 +00:00
bc62cb5e39 Add storage usage readiness fields
All checks were successful
Tests / Tests (pull_request) Successful in 27s
2026-06-29 10:56:33 -07:00
bc52145a9e Merge pull request 'Add storage status schema' (#270) from pr8-storage-status into master
Reviewed-on: #270
2026-06-26 15:33:19 +00:00
5c286f2bcf Add storage status schema
All checks were successful
Tests / Tests (pull_request) Successful in 24s
2026-06-25 17:34:19 -07:00
d636c298f8 Merge pull request 'Add resolved tier capabilities schema' (#269) from tier-capabilities-schema into master
Reviewed-on: #269
2026-06-24 03:37:17 +00:00
681320c62d Add resolved tier capabilities schema
All checks were successful
Tests / Tests (pull_request) Successful in 15s
2026-06-23 15:51:21 -07:00
49f409f60b Merge pull request 'Add resolved tier schema' (#268) from resolved-tier-contract into master
Reviewed-on: #268
2026-06-23 22:10:10 +00:00
e7fc6c147d Add resolved tier schema
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-06-23 14:01:32 -07:00
10c3f6de53 Merge pull request 'Add drill leaderboard run dates to gql' (#267) from dean/add-dates-to-leaderboards-gql into master
Reviewed-on: #267
2026-06-23 15:51:28 +00:00
Dean Wenstrand
d7b1aaee13 Add drill leaderboard run dates to gql
All checks were successful
Tests / Tests (pull_request) Successful in 25s
2026-06-23 08:47:08 -07:00
b477590137 Merge pull request 'VideoCardFields: fetch stream isCompleted + lastSegmentUploadedAt' (#266) from dean/feed-upload-status-fields into master
Reviewed-on: #266
2026-06-20 22:45:07 +00:00
Dean Wenstrand
d428a8caa2 VideoCardFields: fetch stream isCompleted + lastSegmentUploadedAt
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Lets the feed derive upload state (uploading vs paused vs processing) per card.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 15:16:11 -07:00
48207e12ee Merge pull request 'Add lastSegmentUploadedAt to UploadStreamGQL' (#265) from dean/last-uploaded-chunk into master
Reviewed-on: #265
2026-06-20 21:45:32 +00:00
Dean Wenstrand
1d403f8155 Add lastSegmentUploadedAt to UploadStreamGQL
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Surfaces the timestamp of the most recently uploaded chunk so clients can tell
an actively-uploading stream from a partially-uploaded, stalled/paused one
(combined with isCompleted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 14:40:40 -07:00
6758f3e77a Merge pull request 'Add bio field to user (UserFragment + editUser)' (#264) from dean/profile-bio into master
Reviewed-on: #264
2026-06-19 21:27:52 +00:00
Dean Wenstrand
79979b001a Add bio field to user (UserFragment + editUser)
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Expose UserGQL.bio in UserFragment and let editUser set it; regenerated
codegen. Rebased onto current master.
2026-06-19 14:14:24 -07:00
49fbebd0c2 Merge pull request 'Fix duplicate Apple IAP selection' (#263) from loewy/fix-duplicate-apple-iap-selection into master
Reviewed-on: #263
2026-06-18 21:39:20 +00:00
9219451c8d Fix duplicate Apple IAP selection
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-06-18 14:32:37 -07:00
42601f9587 Merge pull request 'Add Apple subscription mobile operations' (#255) from apple-iap-pr4-mobile-ops into master
Reviewed-on: #255
2026-06-18 20:03:10 +00:00
acfb750265 Merge pull request 'Add Apple IAP product IDs to subscription options' (#262) from loewy/apple-iap-product-options into master
Reviewed-on: #262
2026-06-18 01:59:53 +00:00
ffa96a24c3 Add Apple subscription mobile operations
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2026-06-17 18:39:36 -07:00
5b73dd3a83 Add Apple IAP product IDs to subscription options
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2026-06-17 18:22:47 -07:00
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
8111042936 Add pool hall camera claim schema
All checks were successful
Tests / Tests (pull_request) Successful in 9s
2026-06-16 15:41:16 -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
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
d6fd68c1f6 add quotaEnforcementEnabled to deployed config
All checks were successful
Tests / Tests (pull_request) Successful in 10s
2026-05-28 14:40:31 -07:00
10 changed files with 3341 additions and 4 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,8 @@ fragment VideoCardFields on VideoGQL {
id
lastIntendedSegmentBound
streamSegmentType
isCompleted
lastSegmentUploadedAt
}
tableSize
pocketSize
@@ -146,5 +148,6 @@ query GetVideoFeed(
endCursor
}
hasFollowing
followingCount
}
}

View File

@@ -56,6 +56,7 @@ query GetDrillRunLeaderboard(
video {
tableSize
pocketSize
createdAt
}
user {
id

View File

@@ -44,12 +44,20 @@ query GetAvailableSubscriptionOptions {
active
}
}
appleIap {
enabled
proMonthlyProductId
productIds
}
}
}
query GetSubscriptionStatus {
getUserSubscriptionStatus {
hasActiveSubscription
entitlementSource
entitlementStartsAt
entitlementEndsAt
subscriptionStatus
currentPeriodStart
currentPeriodEnd
@@ -59,9 +67,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

@@ -0,0 +1,152 @@
fragment PoolHallFields on PoolHall {
id
name
address
latitude
longitude
timezone
status
createdAt
updatedAt
}
fragment PoolHallCameraFields on PoolHallCamera {
id
poolHallId
name
tableLabel
streamPath
status
lastPublishedAt
lastUnpublishedAt
createdAt
updatedAt
}
fragment PoolHallCameraWithHallFields on PoolHallCamera {
...PoolHallCameraFields
poolHall {
...PoolHallFields
}
}
fragment PoolHallCameraStreamCredentialsFields on PoolHallCameraStreamCredentials {
streamKey
rtmpPath
camera {
...PoolHallCameraWithHallFields
}
}
fragment CameraClaimSessionFields on CameraClaimSession {
id
cameraId
userId
challengeCode
status
expiresAt
detectedAt
failedAt
failureReason
createdAt
updatedAt
camera {
...PoolHallCameraWithHallFields
}
}
fragment CameraLeaseFields on CameraLease {
id
cameraId
claimSessionId
userId
videoId
status
startedAt
endedAt
expiresAt
endReason
createdAt
updatedAt
camera {
...PoolHallCameraWithHallFields
}
}
query GetPoolHalls {
poolHalls {
...PoolHallFields
}
}
query GetClaimablePoolHalls {
claimablePoolHalls {
...PoolHallFields
}
}
query GetPoolHallCameras($poolHallId: ID!) {
poolHallCameras(poolHallId: $poolHallId) {
...PoolHallCameraWithHallFields
}
}
query GetClaimableCameras($poolHallId: ID!) {
claimableCameras(poolHallId: $poolHallId) {
...PoolHallCameraWithHallFields
}
}
query GetCameraClaimSession($id: ID!) {
cameraClaimSession(id: $id) {
...CameraClaimSessionFields
}
}
query GetActiveCameraLease {
activeCameraLease {
...CameraLeaseFields
}
}
mutation CreatePoolHall($input: CreatePoolHallInput!) {
createPoolHall(input: $input) {
...PoolHallFields
}
}
mutation UpdatePoolHall($input: UpdatePoolHallInput!) {
updatePoolHall(input: $input) {
...PoolHallFields
}
}
mutation CreatePoolHallCamera($input: CreatePoolHallCameraInput!) {
createPoolHallCamera(input: $input) {
...PoolHallCameraStreamCredentialsFields
}
}
mutation UpdatePoolHallCamera($input: UpdatePoolHallCameraInput!) {
updatePoolHallCamera(input: $input) {
...PoolHallCameraWithHallFields
}
}
mutation RotatePoolHallCameraStreamKey($cameraId: ID!) {
rotatePoolHallCameraStreamKey(cameraId: $cameraId) {
...PoolHallCameraStreamCredentialsFields
}
}
mutation CreateCameraClaimSession($cameraId: ID!) {
createCameraClaimSession(cameraId: $cameraId) {
...CameraClaimSessionFields
}
}
mutation CancelCameraClaimSession($claimSessionId: ID!) {
cancelCameraClaimSession(claimSessionId: $claimSessionId) {
...CameraClaimSessionFields
}
}

View File

@@ -0,0 +1,57 @@
query GetTableState(
$b64Image: String!
$tableSize: Float
$useHomography: HomographyInputGQL
) {
getTableState(
b64Image: $b64Image
tableSize: $tableSize
useHomography: $useHomography
) {
identifierToPosition
}
}
query SimulateShot($simulationInput: SimulateShotInputGQL!) {
simulateShot(simulationInput: $simulationInput) {
trajectories {
ballId
points {
time
position
}
}
events {
eventType
time
ballIds
position
}
finalState {
ballId
position
}
pottedBallIds
}
}
query ComputePotAim(
$simulationInput: SimulateShotInputGQL!
$targetBallId: Int!
$pocket: PocketIdentifier!
) {
computePotAim(
simulationInput: $simulationInput
targetBallId: $targetBallId
pocket: $pocket
) {
phi
geometricPhi
cutAngle
requiredPrecision
feasible
potted
converged
occludingBallIds
}
}

View File

@@ -177,6 +177,7 @@ mutation editUser(
$fargoRating: Int
$videosPrivateByDefault: Boolean
$agreesToMarketing: Boolean
$bio: String
) {
editUser(
input: {
@@ -184,6 +185,7 @@ mutation editUser(
fargoRating: $fargoRating
videosPrivateByDefault: $videosPrivateByDefault
agreesToMarketing: $agreesToMarketing
bio: $bio
}
) {
id
@@ -193,6 +195,7 @@ mutation editUser(
updatedAt
videosPrivateByDefault
agreesToMarketing
bio
}
}
@@ -206,6 +209,7 @@ fragment UserFragment on UserGQL {
username
isAdmin
profileImageUri
bio
fargoRating
activeVideoId
createdAt

View File

@@ -0,0 +1,36 @@
fragment VideoExportJobFields on VideoExportJobGQL {
id
videoId
mode
status
videoName
videoThumbnailUri
shotIds
runId
downloadUrl
fileSizeBytes
expiresAt
createdAt
}
mutation RequestVideoExport($input: RequestVideoExportInput!) {
requestVideoExport(input: $input) {
...VideoExportJobFields
}
}
mutation DismissVideoExport($jobId: Int!) {
dismissVideoExport(jobId: $jobId)
}
query VideoExportJob($jobId: Int!) {
videoExportJob(jobId: $jobId) {
...VideoExportJobFields
}
}
query MyVideoExports($limit: Int = 30, $offset: Int = 0) {
myVideoExports(limit: $limit, offset: $offset) {
...VideoExportJobFields
}
}

View File

@@ -67,6 +67,13 @@ mutation GetHlsInitUploadLink($videoId: Int!) {
... on TooManyInitUploadsErr {
linksRequested
}
... on StorageLimitExceededErr {
reason
tierName
retainedStorageUsedBytes
retainedStorageLimitBytes
remainingStorageBytes
}
}
}
}

View File

@@ -52,6 +52,12 @@ type Query {
filters: NotificationFilters = null
): NotificationConnection!
unreadNotificationCount: Int!
poolHalls: [PoolHall!]!
claimablePoolHalls: [PoolHall!]!
poolHallCameras(poolHallId: ID!): [PoolHallCamera!]!
claimableCameras(poolHallId: ID!): [PoolHallCamera!]!
cameraClaimSession(id: ID!): CameraClaimSession
activeCameraLease: CameraLease
getRuns(
filterInput: RunFilterInput!
runIds: [Int!] = null
@@ -66,6 +72,12 @@ type Query {
tableSize: Float = 100
useHomography: HomographyInputGQL = null
): TableStateGQL!
simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL!
computePotAim(
simulationInput: SimulateShotInputGQL!
targetBallId: Int!
pocket: PocketIdentifier!
): PotAimGQL!
getOrderedShots(
filterInput: FilterInput!
ids: [Int!] = null
@@ -108,8 +120,10 @@ type Query {
): UserRelationshipsResult!
getAvailableSubscriptionOptions: StripeSubscriptionOptionsGQL!
getUserSubscriptionStatus: UserSubscriptionStatusGQL!
getResolvedTier: ResolvedTierGQL!
getAppleAppAccountToken: String!
getQuotaStatus: QuotaStatusGQL!
getStorageStatus: StorageStatusGQL
getPlayTime(userId: Int!, filters: VideoFilterInput = null): UserPlayTimeGQL!
getUserVideos(
userId: Int = null
@@ -119,6 +133,8 @@ type Query {
): VideoHistoryGQL!
getUserTags(includeRetiredTags: Boolean = false): [TagGQL!]!
getGameTypeTagMetrics(input: GameTypeTagMetricsInput!): [GameTypeTagMetric!]!
videoExportJob(jobId: Int!): VideoExportJobGQL
myVideoExports(limit: Int! = 30, offset: Int! = 0): [VideoExportJobGQL!]!
getVideo(videoId: Int!, debuggingJson: JSON = null): VideoGQL!
getVideos(videoIds: [Int!]!): [VideoGQL!]!
}
@@ -356,6 +372,7 @@ type UserGQL {
activeVideoId: Int
stripeCustomerId: String
profileImageUri: String
bio: String
createdAt: DateTime
updatedAt: DateTime
videosPrivateByDefault: Boolean
@@ -529,6 +546,7 @@ type UploadStreamGQL {
initPlaylistUploadStatus: InitPlaylistUploadStatusEnum
lowestUnuploadedSegmentIndex: Int!
uploadCompletionCursor: Int!
lastSegmentUploadedAt: DateTime
errors: [StreamErrorGQL!]!
createdAt: DateTime!
updatedAt: DateTime!
@@ -708,6 +726,8 @@ type DeployedConfigGQL {
minimumAllowedAppVersion: String!
subscriptionGatingEnabled: Boolean!
quotaEnforcementEnabled: Boolean!
storageLimitEnforcementEnabled: Boolean!
capabilityEnforcementEnabled: Boolean!
bannerMessages: [BannerGQL!]!
defaultAndroidRecordingFormat: StreamSegmentTypeEnum!
bucketUrl: String!
@@ -732,6 +752,7 @@ type VideoHistoryGQL {
videos: [VideoGQL!]!
pageInfo: PageInfoGQL!
hasFollowing: Boolean!
followingCount: Int!
}
type PageInfoGQL {
@@ -859,6 +880,7 @@ enum NotificationTypeEnum {
REACTION
FOLLOW
CHALLENGE_INVITE
EXPORT_READY
}
input NotificationFilters {
@@ -866,6 +888,63 @@ input NotificationFilters {
notificationTypes: [NotificationTypeEnum!] = null
}
type PoolHall {
id: ID!
name: String!
address: String
latitude: Float
longitude: Float
timezone: String
status: String!
createdAt: DateTime!
updatedAt: DateTime!
}
type PoolHallCamera {
id: ID!
poolHallId: ID!
name: String!
tableLabel: String
streamPath: String!
status: String!
lastPublishedAt: DateTime
lastUnpublishedAt: DateTime
createdAt: DateTime!
updatedAt: DateTime!
poolHall: PoolHall!
}
type CameraClaimSession {
id: ID!
cameraId: ID!
userId: ID!
challengeCode: String!
status: String!
expiresAt: DateTime!
detectedAt: DateTime
failedAt: DateTime
failureReason: String
createdAt: DateTime!
updatedAt: DateTime!
camera: PoolHallCamera!
}
type CameraLease {
id: ID!
cameraId: ID!
claimSessionId: ID
userId: ID!
videoId: ID
status: String!
startedAt: DateTime!
endedAt: DateTime
expiresAt: DateTime
endReason: String
createdAt: DateTime!
updatedAt: DateTime!
camera: PoolHallCamera!
}
type GetRunsResult {
runs: [RunGQL!]!
count: Int
@@ -961,6 +1040,76 @@ input IntPoint2DInput {
y: Int!
}
type ShotProjectionGQL {
trajectories: [BallTrajectoryGQL!]!
events: [SimulationEventGQL!]!
finalState: [SimulationBallStateGQL!]!
pottedBallIds: [Int!]!
}
type BallTrajectoryGQL {
ballId: Int!
points: [TrajectoryPointGQL!]!
}
type TrajectoryPointGQL {
time: Float!
position: [Float!]!
}
type SimulationEventGQL {
eventType: SimulationEventType!
time: Float!
ballIds: [Int!]!
position: [Float!]
}
enum SimulationEventType {
STICK_BALL
BALL_BALL
BALL_CUSHION
BALL_POCKET
BALL_STOP
}
type SimulationBallStateGQL {
ballId: Int!
position: [Float!]!
}
input SimulateShotInputGQL {
cueBallId: Int!
strike: CueStrikeInputGQL!
balls: [SimulationBallStateInputGQL!] = null
b64Image: String = null
useHomography: HomographyInputGQL = null
tableSize: Float = null
}
input CueStrikeInputGQL {
v0: Float!
phi: Float!
theta: Float! = 0
a: Float! = 0
b: Float! = 0
}
input SimulationBallStateInputGQL {
ballId: Int!
position: [Float!]!
}
type PotAimGQL {
phi: Float!
geometricPhi: Float!
cutAngle: Float!
requiredPrecision: Float!
feasible: Boolean!
potted: Boolean!
converged: Boolean!
occludingBallIds: [Int!]!
}
type GetShotsResult {
shots: [ShotGQL!]!
count: Int
@@ -1033,6 +1182,7 @@ type StripePriceGQL {
type AppleIapSubscriptionOptionsGQL {
enabled: Boolean!
proMonthlyProductId: String
productIds: [String!]!
}
type UserSubscriptionStatusGQL {
@@ -1067,6 +1217,17 @@ enum StripeSubscriptionStatusEnum {
PAUSED
}
type ResolvedTierGQL {
tierName: String!
tierDisplayName: String!
hasActiveSubscription: Boolean!
entitlementSource: EntitlementSourceTypeEnum
entitlementStatus: String
entitlementStartsAt: DateTime
entitlementEndsAt: DateTime
capabilities: [String!]!
}
type QuotaStatusGQL {
tierName: String!
periodStart: DateTime!
@@ -1091,6 +1252,27 @@ type QuotaBucketStatusGQL {
canUpload: Boolean!
}
type StorageStatusGQL {
userId: Int!
tierName: String!
retainedStorageUsedBytes: BigInt!
retainedStorageLimitBytes: BigInt
isUnlimited: Boolean!
policyConfigured: Boolean!
remainingStorageBytes: BigInt
storageUsageRatio: Float
isNearLimit: Boolean!
isOverLimit: Boolean!
usageCalculated: Boolean!
usageSource: String
lastCalculatedAt: DateTime
}
"""
Integer value that can exceed GraphQL Int's 32-bit range.
"""
scalar BigInt
type UserPlayTimeGQL {
totalSeconds: Float!
}
@@ -1126,6 +1308,36 @@ input GameTypeTagMetricsInput {
includePrivate: IncludePrivateEnum! = MINE
}
type VideoExportJobGQL {
id: Int!
videoId: Int!
mode: VideoExportModeEnum!
status: VideoExportStatusEnum!
videoName: String
videoThumbnailUri: String
shotIds: [Int!]
runId: Int
downloadUrl: String
fileSizeBytes: Int
expiresAt: DateTime
createdAt: DateTime
}
enum VideoExportModeEnum {
FULL_SESSION
SHOTS
RUN
}
enum VideoExportStatusEnum {
CREATED
QUEUED
RUNNING
SUCCEEDED
FAILED
EXPIRED
}
"""
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).
"""
@@ -1182,6 +1394,15 @@ type Mutation {
markAllNotificationsAsRead: Boolean!
markNotificationsAsRead(notificationIds: [Int!]!): Boolean!
deleteNotification(notificationId: Int!): Boolean!
createPoolHall(input: CreatePoolHallInput!): PoolHall!
updatePoolHall(input: UpdatePoolHallInput!): PoolHall!
createPoolHallCamera(
input: CreatePoolHallCameraInput!
): PoolHallCameraStreamCredentials!
updatePoolHallCamera(input: UpdatePoolHallCameraInput!): PoolHallCamera!
rotatePoolHallCameraStreamKey(cameraId: ID!): PoolHallCameraStreamCredentials!
createCameraClaimSession(cameraId: ID!): CameraClaimSession!
cancelCameraClaimSession(claimSessionId: ID!): CameraClaimSession!
finalizePlayerAssignments(
input: FinalizePlayerAssignmentsInput!
): [PlayerClusterGQL!]!
@@ -1227,6 +1448,8 @@ type Mutation {
feedback: String = null
metadata: CancellationFeedbackMetadataInput = null
): Boolean!
requestVideoExport(input: RequestVideoExportInput!): VideoExportJobGQL!
dismissVideoExport(jobId: Int!): Boolean!
findPrerecordTableLayout(b64Image: String!, videoId: Int!): HomographyInfoGQL
createUploadStream(
videoMetadata: VideoMetadataInput!
@@ -1259,6 +1482,44 @@ enum ReportReasonEnum {
OTHER
}
input CreatePoolHallInput {
name: String!
address: String = null
latitude: Float = null
longitude: Float = null
timezone: String = null
}
input UpdatePoolHallInput {
id: ID!
name: String = null
address: String = null
latitude: Float = null
longitude: Float = null
timezone: String = null
status: String = null
}
type PoolHallCameraStreamCredentials {
camera: PoolHallCamera!
streamKey: String!
rtmpPath: String!
}
input CreatePoolHallCameraInput {
poolHallId: ID!
name: String!
tableLabel: String = null
streamPath: String = null
}
input UpdatePoolHallCameraInput {
id: ID!
name: String = null
tableLabel: String = null
status: String = null
}
input FinalizePlayerAssignmentsInput {
videoId: Int!
clusterAssignments: [ClusterAssignmentInput!]! = []
@@ -1362,6 +1623,7 @@ input EditUserInputGQL {
fargoRating: Int = null
videosPrivateByDefault: Boolean = null
agreesToMarketing: Boolean = null
bio: String = null
}
type SyncAppleSubscriptionResultGQL {
@@ -1408,6 +1670,13 @@ input CancellationFeedbackMetadataInput {
platform: String = null
}
input RequestVideoExportInput {
videoId: Int!
mode: VideoExportModeEnum!
shotIds: [Int!] = null
runId: Int = null
}
type CreateUploadStreamReturn {
videoId: Int!
}
@@ -1447,10 +1716,10 @@ type GetUploadLinkReturn {
union UploadLinkGetUploadLinkErrors = UploadLink | GetUploadLinkErrors
type GetUploadLinkErrors {
error: MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErr!
error: MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErrStorageLimitExceededErr!
}
union MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErr =
union MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoInitForChunkedUploadErrTooManyProfileImageUploadsErrInitUploadAlreadyCompletedErrTooManyInitUploadsErrStorageLimitExceededErr =
MustHaveSetForUploadLinkErr
| SegmentAlreadyUploadedErr
| ProcessingFailedErr
@@ -1458,6 +1727,7 @@ union MustHaveSetForUploadLinkErrSegmentAlreadyUploadedErrProcessingFailedErrNoI
| TooManyProfileImageUploadsErr
| InitUploadAlreadyCompletedErr
| TooManyInitUploadsErr
| StorageLimitExceededErr
type MustHaveSetForUploadLinkErr {
resolution: Boolean
@@ -1483,3 +1753,11 @@ type InitUploadAlreadyCompletedErr {
type TooManyInitUploadsErr {
linksRequested: Int!
}
type StorageLimitExceededErr {
reason: String!
tierName: String!
retainedStorageUsedBytes: BigInt!
retainedStorageLimitBytes: BigInt
remainingStorageBytes: BigInt
}