# Trade Module

- Trade sessions are stored **in-memory only** (a `Map` keyed by thread ID). Sessions are lost on restart. There is no persistence or recovery mechanism.
- The trade uses a **two-phase lock** pattern: both users must `toggleLock` (accept) before `executeTrade` can proceed. Any offer modification (add/remove item, change money) automatically **unlocks both users**, forcing re-confirmation. This prevents bait-and-switch.
- `executeTrade` wraps both directions of transfer in a single DB transaction. If any part fails (e.g., insufficient funds, inventory full), the entire trade rolls back.
- Money and item transfers go through `economyService.modifyUserBalance` and `inventoryService.addItem`/`removeItem`, which means all their validation (balance checks, stack limits, slot limits) and side effects (transaction logging, quest events) apply.
- Item transactions are logged separately in the `itemTransactions` table (distinct from currency `transactions`), with `TRADE_IN`/`TRADE_OUT` types.
- The trade types are defined in `bot/modules/trade/trade.types.ts` but the service lives in `shared/modules/trade/`. The import uses `@/modules/trade/trade.types` (bot alias). This cross-boundary import works because both run in the same process.
- `_sessions` is exposed on the service object for testing purposes only.
