Files
aurorabot/shared/db/AGENTS.md
syntaxbullet 2b89fb7ede
Some checks failed
Deploy to Production / test (push) Failing after 34s
docs: rename CLAUDE.md to AGENTS.md across the project
2026-04-06 14:18:56 +02:00

2.3 KiB

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.