# OpenSpec Change: enterprise-gaming-economy - **Change ID**: enterprise-gaming-economy - **Package**: `@suaveplan/economy` - **Category**: gaming/narrative - **Target path**: `gaming/narrative/economy` - **Status**: PROPOSED - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/economy.md` --- ## Summary Deliver `@suaveplan/economy` on the genesis branch from scratch at enterprise quality. The package provides an in-game economy with player wallets, peer-to-peer trading, a marketplace (fixed-price listings), and an auction system with bidding and expiry. `Wallet` tracks multi-currency balances with transactional add/subtract; `Marketplace` holds `Listing` objects with configurable stock and price; `AuctionHouse` manages `Auction` objects with bidding history, reserve price, and expiry timers. Genesis adds Zod schemas, structured errors, OTel transaction counters, injectable clock, and 100% coverage with concurrency invariant tests. --- ## Current-state audit (genesis) Package does not exist on genesis yet — fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | `EconomyError`; `ECONOMY.*` codes | | `@suaveplan/types` (`workspace:^`) | `Clock`, `IdGenerator` | | `@suaveplan/events` (`workspace:^`) | `economy:purchase`, `economy:bid`, `economy:auction_end` events | | `zod` (`catalog:forms`) | `Listing`, `Auction`, `WalletConfig` schemas | | `@opentelemetry/api` (`catalog:observability`) | Transaction counter, active listings gauge | --- ## Public API surface ```ts function createWallet(playerId: string, options?: WalletOptions): Wallet interface WalletOptions { currencies?: string[] // registered currency codes, default ['GOLD'] initialBalances?: Record } interface Wallet { getBalance(currency?: string): number add(amount: number, currency?: string, reason?: string): void subtract(amount: number, currency?: string, reason?: string): void canAfford(amount: number, currency?: string): boolean getHistory(): Transaction[] } interface Transaction { id: string type: 'credit' | 'debit' amount: number currency: string reason?: string timestamp: number } // Marketplace function createMarketplace(options?: MarketplaceOptions): Marketplace interface Marketplace { createListing(seller: string, itemId: string, price: number, stock: number, currency?: string): Listing getListing(listingId: string): Listing | undefined listAll(filter?: ListingFilter): Listing[] purchase(listingId: string, buyerWallet: Wallet, quantity?: number): PurchaseResult removeListing(listingId: string): void } interface Listing { id: string seller: string itemId: string price: number currency: string stock: number createdAt: number } interface PurchaseResult { itemId: string quantity: number totalCost: number } // Auction house function createAuctionHouse(options?: AuctionHouseOptions): AuctionHouse interface AuctionHouse { createAuction(options: AuctionOptions): Auction bid(auctionId: string, bidderId: string, bidderWallet: Wallet, amount: number): BidResult tick(dt: number): ExpiredAuction[] getAuction(id: string): Auction | undefined listActive(): Auction[] } interface Auction { id: string seller: string itemId: string startingPrice: number reservePrice?: number currentBid: number currentBidder: string | null endsAt: number } ``` ### Error codes ```ts type EconomyErrorCode = | 'ECONOMY_INSUFFICIENT_FUNDS' | 'ECONOMY_LISTING_NOT_FOUND' | 'ECONOMY_OUT_OF_STOCK' | 'ECONOMY_BID_TOO_LOW' | 'ECONOMY_AUCTION_ENDED' | 'ECONOMY_SELF_BID' ``` --- ## File layout ```text gaming/narrative/economy/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/index.ts types/common.ts types/common.md core/ wallet/ wallet.ts wallet.md wallet.types.ts wallet.test.ts index.ts marketplace/ marketplace.ts marketplace.md marketplace.types.ts marketplace.test.ts index.ts auction-house/ auction-house.ts auction-house.md auction-house.types.ts auction-house.test.ts index.ts tests/ integration.test.ts ``` --- ## Impact **Downstream**: `@suaveplan/react-bank` displays wallet state; `@suaveplan/api-plugin-virtual-currency` provides HTTP surface. Prerequisites: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`.