Continue to play with various AI’s and how to use them in code generation. Next up is Gemini. I installed gemini-cli and setup an API key on Google along with a billing account and limit. See https://aistudio.google.com

Next I decided to try something that isn’t common (to-do, note taking, etc) and build a Texas Holdem Poker API server. I wasn’t sure the best way to write prompts and have been reading some books on the matter. I decided to ask Proton’s Lumo AI with the prompt, “help me write a prompt to build the API for a texas holdem poker game”

The result was impressive — below is the prompt it generated:

Prompt

Goal – Generate a complete, production-ready backend API for a multiplayer Texas Hold’em poker game. Scope – Define data models, request/response schemas, core game-logic endpoints, authentication, error handling, and basic real-time notifications. Constraints – Use Node.js with Express, TypeScript, and PostgreSQL (via Prisma ORM). All game actions must be idempotent where possible, and the API should be versioned (/api/v1). Include inline comments and brief documentation for each endpoint. Assumptions – Players are already registered and authenticated via JWT; the API will be consumed by a separate front-end client (web or mobile). Real-time updates can be delivered through WebSocket (or Server-Sent Events) but the prompt only needs to scaffold the HTTP endpoints and outline the real-time layer.

Detailed Requirements

  1. Data Models (Prisma schema)

    • Userid, username, email, createdAt.
    • Gameid, status (enum: waiting, in_progress, finished), maxPlayers, createdAt, updatedAt.
    • Seatid, gameId, userId, position (1-10), stack, isDealer, isSmallBlind, isBigBlind.
    • Handid, gameId, handNumber, communityCards (JSON array), pot, status (enum: preflop, flop, turn, river, showdown).
    • Betid, handId, seatId, type (enum: fold, call, raise, check, bet), amount, timestamp.
  2. Authentication

    • Middleware that validates a JWT (Authorization: Bearer <token>).
    • Attach req.userId for downstream handlers.
  3. Core Endpoints

    • POST /api/v1/games – Create a new game (specify maxPlayers). Returns game ID and initial state.
    • GET /api/v1/games/:gameId – Retrieve game details, seats, and current hand status.
    • POST /api/v1/games/:gameId/join – Join a waiting game (requires userId). Assign seat position automatically.
    • POST /api/v1/games/:gameId/start – Transition game status to in_progress; deal hole cards, set blinds.
    • POST /api/v1/games/:gameId/hands/:handId/action – Submit a player action (fold, call, raise, check, bet) with optional amount. Validate turn order and bet sizing.
    • GET /api/v1/games/:gameId/hands/:handId/state – Get the current hand state (community cards, pot, active players, whose turn it is).
    • POST /api/v1/games/:gameId/hands/:handId/end – Resolve the hand, distribute pots, update stacks, and advance to next street or start a new hand.
    • DELETE /api/v1/games/:gameId – Cancel a waiting game (admin only).
  4. Error Handling

    • Return standard HTTP status codes (400 for validation errors, 401 for auth failures, 403 for forbidden actions, 404 for missing resources, 409 for state conflicts, 500 for unexpected errors).
    • Include a consistent JSON error shape: { "error": { "code": "<CODE>", "message": "<human readable>" } }.
  5. Real-Time Layer (outline)

    • Describe a WebSocket namespace /ws/games/:gameId that broadcasts:
      • playerJoined, playerLeft
      • handStarted, cardDealt, actionTaken, handEnded
    • Mention that the HTTP action endpoint should also push the same event to connected sockets.
  6. Testing

    • Scaffold a Jest test suite with at least one integration test per endpoint (using Supertest).
    • Mock the JWT middleware for simplicity.
  7. Documentation

    • Generate an OpenAPI (Swagger) spec automatically from route annotations/comments.
    • Provide a short README explaining setup, migration (prisma migrate), and how to run the server.

Implementation Results

When submitting the prompt to Gemini CLI, the model encountered a loop detection error after 5-8 minutes. Resubmitting remaining tasks allowed completion of all 10 tasks successfully.

Build progress:

✓ Initialize Node.js project and install dependencies
✓ Configure TypeScript (tsconfig.json)
✓ Set up Prisma and create the database schema
✓ Create the Express server and middleware
✓ Implement API routes and controllers
✓ Implement core game logic
✓ Set up WebSocket server for real-time updates
✓ Write integration tests with Jest and Supertest
✓ Generate OpenAPI documentation
✓ Write README.md

Issues encountered:

  1. Prisma adapter configuration required manual addition of @prisma/adapter-pg. Changed:
const prisma = new PrismaClient();

To:

import { PrismaPg } from '@prisma/adapter-pg';

const connectionString = `${process.env.DATABASE_URL}`;
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });
  1. Jest tests needed explicit DATABASE_URL environment variable (dotenv not auto-loading):
$ DATABASE_URL="postgresql://myuser:mypass99@localhost:5432/mydbname?schema=public" npm test

Testing output:

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Time:        0.918 s, estimated 2 s

Complete generated code available at: https://gitlab.com/geoffcorey/poker-api

Total Cost to Generate?

Gemini API cost breakdown