Urgent.News

What's breaking now, across thousands of outlets.

Tech

Every table in our database is inserted with the word "placeholder" in a NOT NULL column, because the QR code contains the row's own id

In PubTrivia a pub puts a printed code on each table. A team scans it, the phone opens a page, and they are in that night's quiz as that table. No app install, no account, which is the entire reason the product works in a room full of strangers. The feature page walks through what the player actually does , and the short version is that the code encodes a URL and nothing else:…

PubTrivia inserts the word "placeholder" into a NOT NULL column in each table of the database. This is because the QR code contains the row's own unique identifier. A team scans the code, and the phone opens a page, allowing them to participate in that night's quiz as that table. No app installation or account is required, which is the core reason the product functions in a room full of strangers.

The feature page explains how players actually engage with the product, and the brief version is that the code encodes a URL, with both the venue ID and table ID being UUIDs. The primary key for tableId is generated using Postgres' defaultRandom(). This creates a small and unintended ordering issue, as the image cannot be generated until the row exists, and the column holding the image is NOT NULL.

The solution is to insert a known-wrong value and immediately correct it after generating the QR code. The insert is performed for all tables simultaneously, generating IDs and returning them. Then, the codes are rendered and written in parallel. However, the insert and updates are not in one transaction, leading to rows with a literal "placeholder" value in the QR code URL.

If the process fails between these two statements, the issue arises, and the UI tries to render the image, which is not a valid PNG. The PNG size comparison shows that a real table URL is 101 characters, while the rendered data URL is 5,934 characters, about 4.3 KB of PNG once the base64 is undone. For a 50-table venue, this results in roughly 300 KB of base64 text in Postgres.

Although this is not free, the alternative is object storage, which would add more complexity, such as a bucket, public URL policy, cleanup job for orphaned objects, and a second thing that could fail while venues print their codes an hour before the quiz. Embedding the data URL offers the benefit of trivial consumption by all three consumers, including the dashboard card, download button, and print-everything button.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Contentful to Sanity Migration: How I Move Content, Assets and Locales

A contentful to sanity migration is mostly a data-mapping exercise with a few sharp edges: rich text, assets, and locales. Done as a script you can re-run, it is low drama.

  • Data exported and audited using Contentful CLI, generating JSON file
  • Content model mapped from Contentful to Sanity schemas with differences
  • Deterministic IDs generated for idempotent import process

Kubernetes Controllers: The Cache-Staleness Bug at Scale

Key takeaways Structure reconcilers as ordered, independently testable steps, each reporting its own status condition, over one monolithic Reconcile function.

  • Kubernetes controller pattern divides reconcile loop into ordered steps
  • Informer caches may lag by tens of milliseconds, causing stale reads
  • Shared status-patching helper centralizes conflict-safe read-then-patch

Two phones at the same table pressed Join in the same moment, and the loser was told the quiz did not exist

Nobody who plays a quiz on PubTrivia has an account. They scan the code on their table, type a name, and they are in. That is deliberate, because the alternative is asking six people in a pub to…

  • Two phones attempted to join the same PubTrivia session simultaneously.
  • Race condition caused both phones to be denied entry to the quiz.
  • Advisory lock could prevent concurrent inserts in future quizzes.

More from Wednesday 14 October →