Skip to content

[codex] add economy system#10

Merged
danjdewhurst merged 2 commits into
mainfrom
codex/economy-system
Jun 14, 2026
Merged

[codex] add economy system#10
danjdewhurst merged 2 commits into
mainfrom
codex/economy-system

Conversation

@danjdewhurst

Copy link
Copy Markdown
Contributor

Summary

Adds a server-authoritative economy system for Tilezo: starting balances, room creation costs, catalogue purchases, persistent inventory, and inventory-aware furniture placement/pickup.

What changed

  • Added shared economy/user protocol types, furniture prices, and balance/inventory server messages.
  • Added users.dollars, user_inventory, migration metadata, and DrizzleEconomyStore.
  • Charged room creation through POST /rooms, added inventory list/purchase HTTP endpoints, and broadcasted balance/inventory updates.
  • Wired WebSocket furniture placement to reserve inventory and pickup/failure paths to refund inventory.
  • Updated the client top bar, room creation dialog, furniture panel, inventory client, and game message handling.
  • Added tests for economy store integration, HTTP inventory routes, WebSocket inventory behavior, client purchase/balance UI, and protocol updates.

Validation

  • bun run typecheck
  • bun run lint
  • bun test
  • bun run test:integration
  • bun run test:coverage
  • bun run coverage:check
  • git diff --check

Notes

Browser automation was not run because the repository instructions require explicit approval before automated browser testing.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6930898e-ce4d-4465-81ca-095abeaf6822

📥 Commits

Reviewing files that changed from the base of the PR and between f745d9e and 5e5bb39.

📒 Files selected for processing (39)
  • apps/client/src/app/createApp.test.ts
  • apps/client/src/app/createApp.ts
  • apps/client/src/auth/AuthClient.test.ts
  • apps/client/src/auth/AuthClient.ts
  • apps/client/src/game/Game.test.ts
  • apps/client/src/game/Game.ts
  • apps/client/src/game/NetClient.test.ts
  • apps/client/src/inventory/InventoryClient.test.ts
  • apps/client/src/inventory/InventoryClient.ts
  • apps/client/src/rooms/RoomClient.ts
  • apps/client/src/styles.css
  • apps/client/src/ui/CreateRoomDialog.test.ts
  • apps/client/src/ui/CreateRoomDialog.ts
  • apps/client/src/ui/FurniturePanel.test.ts
  • apps/client/src/ui/FurniturePanel.ts
  • apps/server/src/auth/auth.test.ts
  • apps/server/src/auth/auth.ts
  • apps/server/src/db/integration.test.ts
  • apps/server/src/db/migrations/0014_medical_supreme_intelligence.sql
  • apps/server/src/db/migrations/meta/0014_snapshot.json
  • apps/server/src/db/migrations/meta/_journal.json
  • apps/server/src/db/schema.ts
  • apps/server/src/economy/economy.ts
  • apps/server/src/http/router.test.ts
  • apps/server/src/http/router.ts
  • apps/server/src/net/handleMessage.test.ts
  • apps/server/src/net/handleMessage.ts
  • apps/server/src/net/socketTypes.ts
  • apps/server/src/serverRuntime.test.ts
  • apps/server/src/serverRuntime.ts
  • docs/overview.md
  • docs/persistence.md
  • packages/protocol/src/economy.ts
  • packages/protocol/src/furniture.ts
  • packages/protocol/src/index.ts
  • packages/protocol/src/messages.ts
  • packages/protocol/src/protocol.test.ts
  • packages/protocol/src/schemas.ts
  • packages/protocol/src/user.ts

📝 Walkthrough

Summary by CodeRabbit

Release Notes

New Features

  • Added in-game economy system with persistent user balances and starting funds.
  • Implemented furniture purchasing functionality with real-time inventory updates.
  • Balance display now visible in the UI with live updates.
  • Room creation now requires spending balance; creation disabled when funds insufficient.

Bug Fixes & Improvements

  • Added server-authoritative validation for inventory and spending operations.
  • Improved UI feedback with error messages for failed purchases.

Walkthrough

Adds a full server-authoritative economy system. Users start with a dollar balance (DEFAULT_STARTING_DOLLARS = 500), spend ROOM_CREATION_COST = 100 to create rooms, and purchase priced furniture items into a persistent user_inventory table. Inventory gates WebSocket furniture placement via reserve/refund semantics, with live balance.updated and inventory.updated pushes to clients.

Changes

Economy Feature

Layer / File(s) Summary
Protocol contracts
packages/protocol/src/user.ts, packages/protocol/src/economy.ts, packages/protocol/src/furniture.ts, packages/protocol/src/messages.ts, packages/protocol/src/schemas.ts, packages/protocol/src/index.ts, packages/protocol/src/protocol.test.ts
AuthUser type centralised with dollars field; ROOM_CREATION_COST = 100 and furniture price fields added; ConnectedMessage extended with dollars; new BalanceUpdatedMessage, InventoryItem, InventoryUpdatedMessage types and corresponding Zod schemas introduced; both modules re-exported from the barrel.
Database schema and migration
apps/server/src/db/schema.ts, apps/server/src/db/migrations/0014_medical_supreme_intelligence.sql, apps/server/src/db/migrations/meta/0014_snapshot.json, apps/server/src/db/migrations/meta/_journal.json
users.dollars integer column (default 500) added; new user_inventory table with composite PK (user_id, item_type), non-negative quantity, cascade FK, and user index; Drizzle ORM schema, migration SQL, snapshot, and journal updated together.
Server economy store
apps/server/src/economy/economy.ts, apps/server/src/db/integration.test.ts
New EconomyStore interface, EconomyError class, and DrizzleEconomyStore implementing atomic purchase (transactional funds decrement + inventory upsert), spend, reserveItem, refundItem, getBalance, and getInventory. Integration tests cover the full lifecycle including error paths.
Server auth: dollars field
apps/server/src/auth/auth.ts, apps/server/src/auth/auth.test.ts
AuthUser sourced from @tilezo/protocol; DEFAULT_STARTING_DOLLARS = 500 exported; STORED_USER_COLUMNS selects dollars; createUser sets it; toAuthUser maps it. Auth tests include fixture updates and dollar assertions.
Server HTTP inventory and room creation
apps/server/src/http/router.ts, apps/server/src/http/router.test.ts
RouterDeps gains optional economy and publishUserMessage. New GET /inventory and POST /inventory/purchase handlers with auth guards and EconomyError→HTTP status mapping. Room creation requires economy, deducts ROOM_CREATION_COST, and returns updated balance. Tests cover all new routes and error cases.
Server WebSocket economy integration and runtime wiring
apps/server/src/net/handleMessage.ts, apps/server/src/net/handleMessage.test.ts, apps/server/src/net/socketTypes.ts, apps/server/src/serverRuntime.ts, apps/server/src/serverRuntime.test.ts
connected WS message includes dollars; furniture placement reserves inventory and returns INSUFFICIENT_INVENTORY on failure, refunds on error; pickup refunds and publishes inventory.updated. userTopic exported; sendInventoryUpdate helper added. Runtime instantiates DrizzleEconomyStore and threads it through all handlers; WebSocket upgrade carries dollars.
Client inventory HTTP client and AuthUser re-export
apps/client/src/inventory/InventoryClient.ts, apps/client/src/inventory/InventoryClient.test.ts, apps/client/src/rooms/RoomClient.ts, apps/client/src/auth/AuthClient.ts, apps/client/src/auth/AuthClient.test.ts
New InventoryClient with getInventory() and purchaseItem() using fetch with credentials. CreatedRoom gains optional balance. AuthClient re-exports AuthUser from @tilezo/protocol. Unit tests cover success, empty-payload, HTTP-error, and JSON-parse-failure paths.
Client UI: FurniturePanel, CreateRoomDialog, and balance CSS
apps/client/src/ui/FurniturePanel.ts, apps/client/src/ui/FurniturePanel.test.ts, apps/client/src/ui/CreateRoomDialog.ts, apps/client/src/ui/CreateRoomDialog.test.ts, apps/client/src/styles.css
FurniturePanel adds onBuy/inventory options, a Buy button, owned-count labels, setInventory(), async buySelected() with inline error display, and ownership-gated placement mode. CreateRoomDialog.show() accepts balance, renders cost, and disables submit when funds are insufficient. Balance element CSS with balance-cue animation added.
Client app wiring, game events, and tests
apps/client/src/app/createApp.ts, apps/client/src/app/createApp.test.ts, apps/client/src/game/Game.ts, apps/client/src/game/Game.test.ts, apps/client/src/game/NetClient.test.ts, docs/overview.md, docs/persistence.md
createApp adds balance display, syncCreateRoomButton, onBuy handler, refreshInventory(), and Game callbacks onBalanceUpdated/onInventoryUpdated. Balance updated on auth, session restore, and room creation. Game.ts routes balance.updated/inventory.updated WS messages. Harness fakes extended; docs updated to reflect implemented economy.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser (createApp)
  participant InventoryClient
  participant GameWS as Game WebSocket
  participant HTTPRouter as HTTP Router
  participant DrizzleEconomyStore
  participant Database

  rect rgba(100, 150, 200, 0.5)
    note over Browser, Database: Furniture purchase via HTTP
    Browser->>InventoryClient: purchaseItem(itemType)
    InventoryClient->>HTTPRouter: POST /inventory/purchase
    HTTPRouter->>DrizzleEconomyStore: purchase(userId, itemType)
    DrizzleEconomyStore->>Database: transaction: decrement dollars, upsert inventory
    Database-->>DrizzleEconomyStore: updated balance + items
    DrizzleEconomyStore-->>HTTPRouter: PurchaseResult
    HTTPRouter->>GameWS: publishUserMessage balance.updated
    HTTPRouter->>GameWS: publishUserMessage inventory.updated
    HTTPRouter-->>InventoryClient: 200 { balance, items }
    InventoryClient-->>Browser: PurchaseResult
    Browser->>Browser: updateBalanceDisplay, furniturePanel.setInventory
  end

  rect rgba(100, 200, 150, 0.5)
    note over Browser, Database: Furniture placement via WebSocket
    Browser->>GameWS: place furniture
    GameWS->>DrizzleEconomyStore: reserveItem(userId, itemType)
    DrizzleEconomyStore-->>GameWS: reserved: true
    GameWS->>Database: persist room item
    GameWS->>Browser: room.item.placed
    GameWS->>DrizzleEconomyStore: getInventory(userId)
    GameWS->>Browser: inventory.updated (userTopic)
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@danjdewhurst danjdewhurst marked this pull request as ready for review June 14, 2026 21:06
@danjdewhurst danjdewhurst merged commit e37c604 into main Jun 14, 2026
1 of 2 checks passed
@danjdewhurst danjdewhurst deleted the codex/economy-system branch June 14, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant