Skip to content

Direct join on an uncontested empty seat #27

Description

@DLSS5ONECLICK

Problem

Split out of #23 after real-device testing: with a seat visibly open and nobody queued, the app still required Request the mic → type a "why should you get the mic?" message → submit → Claim your seat — high-friction for a literally uncontested seat. #23's own body already treats this as separable (its dependency on #22 is explicitly soft: "direct-join doesn't need it"). This issue is that separable, independent piece, pulled forward because it's cheap and the friction is real today — not a bureaucratic split.

Design

Direct join on a truly uncontested seat: if a seat is open and no pending speaker_requests exist for it, the empty tile itself reads "Join the conversation" instead of "Seat open," and tapping it attempts to occupy that seat directly:

  • No request message.
  • No separate "Claim your seat" button/step.
  • One tap, one server round-trip.

If a legitimate queue exists, the tile falls back to today's existing request flow unchanged — a bystander tapping the empty tile must never let them cut ahead of a real pending request.

Server-authoritative, race-safe: a new, thin server action — verify no pending request exists for the seat, then call the existing claim_speaker_seat (issue #13, already concurrency-safe: two simultaneous taps on a genuinely empty seat still resolve to exactly one winner, the same DB-level atomicity every other seat-claim path already relies on). No new database-level primitive needed — this is a new entry point onto an existing, already-safe one, not new concurrency logic.

Explicit non-goal

No ranking, no eligibility/readiness signal, no time-graduated fallback — those only matter once a queue exists, which by definition this issue's path doesn't have. That's #23's job.

Depends on

Nothing — no dependency on #22 (candidate readiness) or #23 (automatic promotion for contested seats). Depends only on what already exists (claim_speaker_seat, speaker_requests).

Blocks

Nothing new. Removes one class of friction #23 would otherwise have left in place until it landed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions