Skip to main content

Database

Zander uses MySQL with Prisma as the ORM. This page documents the connection setup, how to apply migrations, and a full breakdown of every model in the schema so you know exactly where your data lives. The schema is defined in prisma/schema.prisma.

Connections​

Up to four separate MySQL connections can be configured. zander-web owns and migrates only the main database via Prisma; the other three are external schemas it reads/writes into without owning their migrations:

VariablePurposeOwned by zander-web?
DATABASE_URLMain Zander database (required)Yes — migrated via prisma/migrations/
LUCKPERMS_URLLuckPerms database — used for rank/permission lookups (required if using ranks)No — external schema, read for permission checks and rank management
QUICKSHOP_URLQuickShop database — used for the shop directory (required if using shop directory)No — external schema
PUNISHMENTS_URLLiteBans database — read/written for the web punishments dashboard and profile pagesNo — external schema

Connection strings use the format:

mysql://username:password@host:3306/database_name
note

Most controllers query the main database with raw SQL via a mysql2 pool rather than through Prisma Client models — Prisma is used here primarily as a migration tool, not the everyday query layer. Schema changes should still always go through a new Prisma migration.

Initial Setup​

Run the SQL initialisation script to create the base schema, then apply all numbered migrations from the migration/ directory in order:

mysql -u root -p zander < dbinit.sql
# then for each migration file in order:
mysql -u root -p zander < migration/001_name.sql

For new deployments using the Prisma build script:

npm run build

This runs prisma migrate deploy and prisma generate automatically.

Schema Overview​

The following models are defined in prisma/schema.prisma:

Users & Authentication​

ModelDescription
usersCore user accounts — UUID, username, email, password hash, profile data, social links
userEmailVerificationsEmail verification tokens
userPasswordResetsPassword reset tokens
userVerifyLinkShort-lived codes for linking Discord accounts to Minecraft UUIDs

Sessions​

ModelDescription
sessionExpress session store (Prisma-backed)

Forums​

ModelDescription
forumCategoriesForum categories with view/post permission nodes
forumDiscussionsDiscussion threads
forumPostsIndividual posts/replies
forumPostRevisionsEdit history for posts
forumPollsPolls embedded in discussions
forumPollOptionsPoll answer options
forumPollVotesUser vote records

Announcements & Servers​

ModelDescription
announcementsMulti-type announcements (web, popup, tip, motd)
serversServer registry with connection details and type
serverStatusCached live server status (player count, online state)
gameSessionsIn-game session records reported by the plugins

Applications​

ModelDescription
applicationsStaff/player application listings and submissions

Discord​

ModelDescription
discord_punishmentsPunishment records (warn, kick, ban, mute) with expiry and status
discord_punishment_appealsAppeal submissions and review outcomes
scheduledDiscordMessagesScheduled message queue for the Discord scheduler

Support​

ModelDescription
supportTicketsSupport ticket records with category and status
supportTicketMessagesMessages and internal notes within tickets
supportTicketCategoriesConfigured ticket categories
supportTicketCategoryPermissionsPer-category access permissions for staff

Reports (Web)​

ModelDescription
reportsPlayer reports submitted via web or Discord
note

There is no local punishments Prisma model for website punishments — the web punishments dashboard and profile pages read and write to the external LiteBans schema via PUNISHMENTS_URL instead (see the Connections table above), the same way LUCKPERMS_URL is used for rank data.

Badges​

ModelDescription
badgesBadge definitions (name, icon, description)
user_badgesBadge assignments to users

Webstore​

ModelDescription
webstorePurchasesRecorded Tebex/Stripe purchases
webstoreSubscriptionsRecurring subscription records
webstoreWebhookEventsRaw webhook events received from Stripe
webstoreStripeCommandsCommand mappings run for Stripe products
webstoreCommandRunsExecution log for webstore-triggered commands
webstoreTransactionsTransaction ledger for the webstore/goal tracking

Finance​

ModelDescription
financeAccountsFinance accounts (e.g. bank, PayPal)
financeCategoriesIncome/expense categories
financeTagsTags applied to finance transactions
financeVendorsVendor/payee records
financeTransactionsIndividual income/expense transactions
financeTransactionTagsJoin table linking transactions to tags
financeInvoicesInvoice records
financePaymentsPayments applied against invoices
financeAttachmentsFile attachments on finance records
financeOperationsBudgetOperating budget tracking
financeMonthlyReportsGenerated monthly finance reports

Voting​

ModelDescription
votesIndividual vote records
vote_sitesConfigured voting sites
vote_reward_templatesCommand templates for vote and monthly rewards
vote_monthly_totalsAggregated monthly vote counts per player
vote_monthly_resultsProcessed monthly reward results
player_command_queueQueue of reward commands to execute in-game

Events​

ModelDescription
eventsCommunity events with full lifecycle state
event_templatesRecurring event templates
event_template_announcementsAnnouncement config attached to event templates
event_template_hostsDefault host assignments for event templates
event_hostsHost assignments for events
event_actionsIn-game actions triggered by events
event_announcementsDiscord/web announcements tied to events
event_audit_logsChange history for events

Creator Content​

ModelDescription
creator_content_itemsCached Twitch/YouTube content items
creator_content_notificationsNotification records for new creator content
user_platform_connectionsTwitch/YouTube account links for users

Bridge & Automation​

ModelDescription
bridgeLegacy single command-bridge queue (command, target server, processed flag)
executorTasksIndividual command tasks in the newer bridge executor queue
executorRoutinesNamed multi-step routines for the bridge
executorRoutineStepsIndividual steps within an executor routine

Logs​

ModelDescription
logsSystem activity/audit log entries shown in the dashboard (Dashboard → Logs)

Notifications​

ModelDescription
userNotificationsIn-app notification records
pushSubscriptionsWeb push subscription endpoints per user

Migrations​

Migration files are located in migration/. Run them in numeric order. After applying all migrations, the Prisma client must be regenerated:

npx prisma generate