{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreih2ey33wwje4wb2cunut2g2e7rbns6smoosa3nbj5itmabg3vxbii",
    "uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3moiakkuhrqi2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreigobb3xcfdlljycd32664c4xsq57ghyxwjb7lohpkmm7vrujmkl64"
    },
    "mimeType": "image/webp",
    "size": 99948
  },
  "path": "/ekpenyong_mfon_504ac7ca05/how-i-built-a-restaurant-waitlist-app-on-amazon-aurora-dsql-that-cannot-double-book-a-table-i22",
  "publishedAt": "2026-06-17T11:19:38.000Z",
  "site": "https://dev.to",
  "tags": [
    "aws",
    "database",
    "devchallenge",
    "showdev",
    "https://tableturn-steel.vercel.app",
    "https://github.com/ekpenyongasuquo/tableturn"
  ],
  "textContent": "I built TableTurn for the H0: Hack the Zero Stack hackathon — a restaurant waitlist and table management app on Amazon Aurora DSQL and Vercel. I created this post as part of my entry for the hackathon. #H0Hackathon\nRestaurants that cannot afford OpenTable or Yelp Guest Manager manage waitlists on paper or WhatsApp. TableTurn gives them a working alternative at $29/month.\nThe hardest technical requirement was preventing double-booking. Two hosts seating two different parties at the same table at the same time must be impossible, not just unlikely. I used Aurora DSQL's serializable transactions to enforce this at the database level:\n\nawait sql.begin(async (tx) => {\nconst table = await tx`SELECT id, status FROM tables WHERE id = ${table_id} FOR UPDATE`;\nif (table[0].status !== \"available\") {\nthrow new Error(\"Table just taken by another host\");\n}\nawait tx`UPDATE tables SET status = 'occupied' WHERE id = ${table_id}`;\nawait tx`UPDATE parties SET status = 'seated', table_id = ${table_id} WHERE id = ${id}`;\n});\n\nI tested this directly with two curl requests targeting the same table. The first returned success. The second returned \"Table just taken by another host.\" That is Aurora DSQL's serializable isolation working, not application-level checking that could race.\nThree things I had to learn the hard way: CREATE INDEX fails unless you use CREATE INDEX ASYNC, which returns a job_id and builds in the background. IAM auth tokens expire every 15 minutes, so token refresh logic is required in production. Aurora DSQL has no foreign keys, so I used TEXT for IDs and enforced relationships in the application layer.\nLive app: https://tableturn-steel.vercel.app\n\nGitHub: https://github.com/ekpenyongasuquo/tableturn",
  "title": "How I Built a Restaurant Waitlist App on Amazon Aurora DSQL That Cannot Double-Book a Table"
}