# Database layer Aurora uses Drizzle ORM with PostgreSQL. Docker Compose currently runs PostgreSQL 17. ## Schema modules - `users.ts` - `inventory.ts` - `economy.ts` - `quests.ts` - `moderation.ts` - `feature-flags.ts` - `guild-settings.ts` - `game-settings.ts` `shared/db/schema/index.ts` re-exports the full schema surface. ## Numeric conventions - Discord IDs, balances, XP, quantities, and transaction amounts are stored as `bigint` - many API responses serialize those `bigint` values to strings - JSON config blobs inside `game_settings` use strings for values that become `bigint` at runtime, for example: - `economy.daily.amount` - `economy.daily.streakBonus` - `economy.daily.weeklyBonus` - `economy.transfers.minAmount` - `inventory.maxStackSize` - `trivia.entryFee` ## Important tables - `users` - `classes` - `transactions` - `item_transactions` - `items` - `inventory` - `quests` - `user_quests` - `user_timers` - `moderation_cases` - `lootdrops` - `feature_flags` - `feature_flag_access` - `guild_settings` - `game_settings` ## Composite keys and constraints - `inventory(userId, itemId)` - `userQuests(userId, questId)` - `userTimers(userId, type, key)` - `inventory.quantity > 0` - `items.name` is unique - `feature_flags.name` is unique ## JSON columns - `items.usageData` - `users.settings` - `userTimers.metadata` - `quests.requirements` - `quests.rewards` - `guildSettings.colorRoleIds` - `guildSettings.featureOverrides` - every main section in `gameSettings` ## Relations and deletion behavior - inventory rows cascade on user/item deletion - `transactions.relatedUserId` and `item_transactions.relatedUserId` use `set null` - feature flag access rows cascade when a feature flag is deleted - moderation cases are not soft-deleted; lifecycle is represented by `active`, `resolvedAt`, and `resolvedBy` ## Client setup - `shared/db/DrizzleClient.ts` exports the singleton DB client - `bot/lib/db.ts` exports `withTransaction()` - shared services normally accept an optional existing transaction so nested operations stay atomic