(params: {
userId: string
accessTier?: FreebuffAccessTier
userEmail?: string | null | undefined
userBanned?: boolean
claimedInstanceId?: string | null | undefined
deps?: SessionDeps
})
| 557 | * - `queued` / `active` / `ended` otherwise (see `toSessionStateResponse`) |
| 558 | */ |
| 559 | export async function getSessionState(params: { |
| 560 | userId: string |
| 561 | accessTier?: FreebuffAccessTier |
| 562 | userEmail?: string | null | undefined |
| 563 | userBanned?: boolean |
| 564 | claimedInstanceId?: string | null | undefined |
| 565 | deps?: SessionDeps |
| 566 | }): Promise<FreebuffSessionServerResponse> { |
| 567 | const deps = params.deps ?? defaultDeps |
| 568 | const accessTier = params.accessTier ?? 'full' |
| 569 | if (params.userBanned) { |
| 570 | return { status: 'banned' } |
| 571 | } |
| 572 | if ( |
| 573 | !deps.isWaitingRoomEnabled() || |
| 574 | isWaitingRoomBypassedForEmail(params.userEmail) |
| 575 | ) { |
| 576 | return { status: 'disabled' } |
| 577 | } |
| 578 | const row = await deps.getSessionRow(params.userId) |
| 579 | |
| 580 | // Build a `none` response with live queue depths so the CLI's pre-join |
| 581 | // picker can show "N ahead" hints without first committing the user to a |
| 582 | // queue, plus per-user quota snapshots so exhausted models are visible |
| 583 | // before POST. |
| 584 | const noneResponse = async (): Promise<FreebuffSessionServerResponse> => { |
| 585 | const [queueDepthByModel, rateLimitsByModel] = await Promise.all([ |
| 586 | deps.queueDepthsByModel(), |
| 587 | fetchRateLimitsByModel(params.userId, accessTier, deps), |
| 588 | ]) |
| 589 | return { |
| 590 | status: 'none', |
| 591 | accessTier, |
| 592 | queueDepthByModel, |
| 593 | ...nonEmptyRateLimitsByModel( |
| 594 | onlyUsedRateLimitsByModel(rateLimitsByModel), |
| 595 | ), |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | if (!row) return noneResponse() |
| 600 | |
| 601 | if (!isSessionRowCompatibleWithAccessTier(row, accessTier)) { |
| 602 | await deps.endSession({ |
| 603 | userId: params.userId, |
| 604 | now: nowOf(deps), |
| 605 | sessionLengthMs: deps.sessionLengthMs, |
| 606 | }) |
| 607 | return noneResponse() |
| 608 | } |
| 609 | |
| 610 | if ( |
| 611 | row.status === 'active' && |
| 612 | params.claimedInstanceId && |
| 613 | params.claimedInstanceId !== row.active_instance_id |
| 614 | ) { |
| 615 | return { status: 'superseded' } |
| 616 | } |
no test coverage detected