Files
aurorabot/shared/db/CLAUDE.md
syntaxbullet 56db5bc998 refactor(games): rework room lifecycle events and remove chess plugin
Consolidate room leave/delete event handling into RoomManager emitter,
remove redundant PLAYER_LEFT publishes from GameServer, and delete the
chess game plugin (board, types, tests) in favor of the new plugin
architecture. Add per-module CLAUDE.md files for leveling, guild-settings,
feature-flags, db, api, and panel to improve agent navigability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 15:19:51 +02:00

41 lines
2.3 KiB
Markdown

# Database Layer
## Column Types
- **Bigint** (`mode: 'bigint'`): All Discord snowflake IDs (`userId`, `guildId`, `roleId`, `channelId`), currency amounts (`balance`, `xp`, transaction `amount`, item `price`, inventory `quantity`). Use `0n` BigInt literals, never `Number()`.
- **Integer**: Small counts and internal IDs — `level`, `daily_streak`, `progress`, `reward_amount` in lootdrops, auto-increment `serial('id')` for items.
## Composite Primary Keys
- `inventory(userId, itemId)` — one stack per user per item
- `userQuests(userId, questId)` — one assignment per user per quest
- `userTimers(userId, type, key)` — one timer per user per type/key combo
## Constraints
- `inventory.quantity > 0` check constraint — never store zero-quantity rows
- `classes.name` and `items.name` are unique
- Cascade deletes on user FK; set null on `relatedUserId` (preserves transaction history)
## JSON Columns (JSONB)
- `quests.requirements`: `{ target: number }`
- `quests.rewards`: `{ xp?: number, balance?: number }`
- `gameSettings` fields: Typed via `.$type<T>()``LevelingConfig`, `EconomyConfig`, etc.
- `guildSettings.featureOverrides`: `Record<string, boolean>` (sparse)
- `guildSettings.colorRoleIds`: `string[]`
- `users.settings`, `userTimers.metadata`, `items.usageData`: Untyped JSONB, default `{}`
## Enums
Defined as TypeScript enums in `shared/lib/constants.ts`, **not** as database enums. Schema columns use `varchar` with length constraints. Key enum types:
- `TimerType`: COOLDOWN, EFFECT, ACCESS, EXAM_SYSTEM, TRIVIA_COOLDOWN
- `TransactionType`: TRANSFER_IN, DAILY_REWARD, etc. (8 values)
- `ModerationCaseType`: warn, timeout, kick, ban, note, prune
- `ItemType`: MATERIAL, CONSUMABLE, EQUIPMENT, QUEST
## Notable Indexes
- `user_timers_lookup_idx`: Composite on (userId, type, key) — fast timer checks
- `user_timers_expires_at_idx`: Expiry-based cleanup queries
- `users_balance_idx` / `users_level_xp_idx`: Leaderboard queries
## Client Setup
- `DrizzleClient` is a singleton in `shared/db/DrizzleClient.ts` (postgres-js driver, no prefetch).
- `withTransaction` utility in `bot/lib/db.ts` wraps Drizzle transactions and tracks count for graceful shutdown. Accepts optional existing `tx` for nested calls.
- No soft deletes anywhere. `moderationCases` uses `active: boolean` + `resolvedAt`/`resolvedBy` for lifecycle, but rows are never deleted.