Gemini coding
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 a ready‑to‑use prompt you can give to an LLM (or any code‑generation model) to create a clean, well‑structured RESTful API for a Texas Hold’em poker game.
Feel free to adjust the wording, technology stack, or level of detail to match the exact environment you’re targeting.
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
- Data Models (Prisma schema)
User–id,username,email,createdAt.Game–id,status(enum:waiting,in_progress,finished),maxPlayers,createdAt,updatedAt.Seat–id,gameId,userId,position(1‑10),stack,isDealer,isSmallBlind,isBigBlind.Hand–id,gameId,handNumber,communityCards(JSON array),pot,status(enum:preflop,flop,turn,river,showdown).Bet–id,handId,seatId,type(enum:fold,call,raise,check,bet),amount,timestamp.
- Authentication
- Middleware that validates a JWT (
Authorization: Bearer <token>). - Attach
req.userIdfor downstream handlers.
- Middleware that validates a JWT (
- Core Endpoints
POST /api/v1/games– Create a new game (specifymaxPlayers). 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 (requiresuserId). Assign seat position automatically.POST /api/v1/games/:gameId/start– Transition game status toin_progress; deal hole cards, set blinds.POST /api/v1/games/:gameId/hands/:handId/action– Submit a player action (fold,call,raise,check,bet) with optionalamount. 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).
- Error Handling
- Return standard HTTP status codes (
400for validation errors,401for auth failures,403for forbidden actions,404for missing resources,409for state conflicts,500for unexpected errors). - Include a consistent JSON error shape:
{ "error": { "code": "<CODE>", "message": "<human readable>" } }.
- Return standard HTTP status codes (
- Real‑Time Layer (outline)
- Describe a WebSocket namespace
/ws/games/:gameIdthat broadcasts:playerJoined,playerLefthandStarted,cardDealt,actionTaken,handEnded
- Mention that the HTTP
actionendpoint should also push the same event to connected sockets.
- Describe a WebSocket namespace
- Testing
- Scaffold a Jest test suite with at least one integration test per endpoint (using Supertest).
- Mock the JWT middleware for simplicity.
- 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.
- Additional Quality Concerns
- Use async/await everywhere, proper try/catch blocks, and close DB connections on shutdown.
- Ensure all public functions/types are exported from an
index.tsbarrel file. - Follow the Airbnb TypeScript style guide (or similar) for linting.
Expected Output
When the model receives the prompt, it should produce:
package.jsonwith necessary dependencies (express,typescript,prisma,jsonwebtoken,ws,jest, etc.).tsconfig.jsonconfigured for Node 18+.- Prisma schema (
schema.prisma) containing the models listed above. - Express server (
src/server.ts) with middleware, routes, and error handling. - Controllers/services for each endpoint, encapsulating game logic.
- WebSocket server stub (
src/ws.ts) with event emission hooks. - Example Jest test files (
tests/*.test.ts). - Swagger/OpenAPI generation code (
src/swagger.ts). - A concise
README.mdcovering installation, database setup, running, and testing.
How to Use This Prompt
- Copy the entire block (starting from “Goal – …” down to the last bullet).
- Paste it into the prompt field of your chosen code‑generation model (e.g., Claude, GPT‑4, or a self‑hosted LLM).
- Run the model. It should output a full project skeleton matching the specifications.
- Review the generated code, adjust any business‑rule specifics (e.g., blind amounts, max players), and run the provided tests.
Quick Variant (if you prefer Python/FastAPI)
If you’d rather use Python, replace the tech stack line with:
“Use Python 3.11, FastAPI, SQLModel (or SQLAlchemy), and Pydantic for schemas.”
Everything else (models, endpoints, authentication, real‑time via WebSockets with Starlette) stays the same; just ask the model to emit Python code instead of TypeScript.
Let me know if you’d like a more focused version (e.g., only the Prisma schema, or just the WebSocket layer) or if you have a different language/framework in mind!
Not too bad! So lets give it a test by creating a blank directory and firing up gemini-cli and pasting the prompt and let it do it's thing. It broke down the tasks and perked along for about 5-8 minutes when it ran into a loop detection error and stopped. Specifically, A potential loop was detected. This can happen due to repetitive tool calls or other model behavior. The request has been halted. After looking up what to do at this point the recommendation was resubmit the prompt. So I submitted the remaining tasks and it quickly finished.
Todo 10/10 completed (ctrl+t to toggle)
✓ 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
There were really only 2 issues that were related. When defining Prisima connection it didn't define the adapter.
So changed this
import { PrismaClient, GameStatus, HandStatus } from '@prisma/client';
import { createDeck, shuffleDeck } from '../utils/cards';
import * as notificationService from './notificationService';
const prisma = new PrismaClient();To -
import { PrismaClient, GameStatus, HandStatus } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import { createDeck, shuffleDeck } from '../utils/cards';
import * as notificationService from './notificationService';
const connectionString = `${process.env.DATABASE_URL}`;
const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });For both src/services/gameService.ts and tests/api.test.ts
Also I might have had to add additional dependencies to package.json and do an npm install Locally I install Postgresql, create a database, user w/password and updated the .env file. However to run Jest tests you have to define the DATABASE_URL from .env to execute tests. For some reason Jest isn't loading the .env file.
$ DATABASE_URL="postgresql://myuser:mypass99@localhost:5432/mydbname?schema=public" npm test
> poker-api@1.0.0 test
> jest
console.log
[dotenv@17.2.3] injecting env (0) from .env -- tip: ⚙️ override existing env vars with { override: true }
at _log (node_modules/dotenv/lib/main.js:142:11)
console.log
WebSocket server initialized.
at initWebSocketServer (src/ws.ts:44:11)
console.log
Server is running at http://localhost:3000
at Server.<anonymous> (src/server.ts:33:11)
PASS tests/api.test.ts
Games API
POST /api/v1/games
✓ should create a new game (18 ms)
GET /api/v1/games/:gameId
✓ should get game details (11 ms)
POST /api/v1/games/:gameId/join
✓ should join a waiting game (6 ms)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 0.918 s, estimated 2 s
Ran all test suites.You can find the generated code at https://gitlab.com/geoffcorey/poker-api
Total cost to generate?
