FluffBoost

Database & schema

The Drizzle schema, the tables, and how migrations work.

FluffBoost uses PostgreSQL through Drizzle ORM. The schema in apps/discord/src/database/schema.ts is the single source of truth — Drizzle reads it at runtime, so there's no code-generation step.

Tables

TablePurpose
guildsPer-server config: channel, schedule (frequency/time/timezone/day), premium status, lastMotivationSentAt
motivationQuotesThe approved quote library
suggestionQuotesUser-submitted quotes pending admin review
discordActivitiesBot status entries, with a type enum

Two enums back these: motivationFrequencyEnum (Daily / Weekly / Monthly) and discordActivityTypeEnum (Custom / Listening / Streaming / Playing).

Working with the schema

After editing schema.ts:

bun run db:push

Pushes the schema straight to your dev database. Fast, no migration files.

bun run db:generate   # create a migration from the schema diff
bun run db:migrate    # apply pending migrations

Open a visual browser with bun run db:studio.

How scheduling reads the data

The send-motivation worker job runs every minute and asks isGuildDueForMotivation() (in apps/discord/src/utils/scheduleEvaluator.ts, powered by dayjs with timezone support) which guilds are due right now. After a successful send it updates lastMotivationSentAt so a quote is never delivered twice.

Migrations run at deploy time. The container entrypoint runs apps/discord/src/database/migrate.ts before starting the bot, so a fresh database is created and kept up to date automatically. The repository ships both the migration SQL and drizzle/meta/_journal.json, which is what the script looks for — if that journal ever goes missing, the script silently skips and the schema stops being applied. Set SKIP_MIGRATIONS=true to opt out for a single deploy.

Don't mix db:push with migrations in production. db:push reshapes the database directly without recording anything in the migration history, so a later db:migrate can find the schema already changed and fail or drift. Use db:push for local development only; let production go through generated migrations.

On this page