Skip to content

Database & Prisma

The backend uses Prisma ORM to interact with a PostgreSQL database. The schema contains two distinct model layers: legacy models mapped from the original production database, and modern models designed for the new application features.

STATUS: PARTIAL

Legacy models (40+) provide read-only access to production data. Modern models (90+) support full CRUD across auth, challenges, track records, gamification, communities, schools, vendors, orders, and more. Some domain services still use in-memory storage and will migrate to Prisma models as development continues.

Overview

  • Schema file: server/prisma/schema.prisma
  • Database: PostgreSQL 17 (docurious_prod)
  • Prisma client: Singleton in server/src/lib/prisma.ts (survives hot-reload in dev)

Legacy Models

These models were introspected from the original MySQL database (converted to PostgreSQL). They map 1:1 to the production SQL tables using @@map() directives.

Characteristics:

  • BigInt primary keys (auto-increment)
  • snake_case column names
  • UPPER_CASE status enums (ACTIVE, INACTIVE, PENDING)
  • uuid field as a secondary identifier (not the primary key)
  • Soft deletes via deleted_at timestamp

Key legacy models:

Prisma ModelSQL TableDescription
UserusersUser accounts (email, password, role, balance)
ChallengechallengesChallenge templates (title, vendor, pricing)
VendorvendorsVendor organizations (Stripe, commission)
OrderordersPurchase transactions
CouponcouponsDiscount codes
categoriescategoriesChallenge categories
seriesseriesChallenge series/bundles
walletswalletsUser wallet transactions
payoutspayoutsVendor payout records
gift_challengesgift_challengesGift challenge records
challenge_instanceschallenge_instancesSpecific challenge sessions (location, schedule)
challenge_submissionschallenge_submissionsUser submissions
childrenchildrenParent-child relationships
coppa_verificationscoppa_verificationsCOPPA consent records

Used by: prodData.service.ts -- serves read-only production data through the root-level API routes (/challenges, /vendors, /users, /series, /wallet).

Modern Models

These models use UUID string primary keys, camelCase conventions, and @default(now())/@updatedAt timestamps. They power the modern application features.

Characteristics:

  • UUID string primary keys (@id @default(uuid()))
  • camelCase field names
  • lowercase status enums (active, draft, pending_review)
  • Cascade deletes via onDelete: Cascade

Entity Relationship Diagram

Key modern models

ModelTableDescription
AppUserapp_usersUser accounts (email, role, tier, COPPA status)
AppUserProfileapp_user_profilesProfile details (name, phone, bio)
AppUserSettingsapp_user_settingsNotification preferences
RefreshTokenrefresh_tokensJWT refresh token storage + revocation
AppChallengeapp_challengesChallenge definitions (difficulty, XP, cost, media)
AppCategoryapp_categoriesChallenge categories with slugs
ChallengeMilestonechallenge_milestonesOrdered steps within a challenge
ChallengeVerificationReqchallenge_verification_reqsProof requirements
ChallengeDiscussionchallenge_discussionsThreaded discussion posts
UserChallengeuser_challengesUser's challenge progress (status, attempts)
TrackRecordtrack_recordsTrack record with verification status
TrackRecordEntrytrack_record_entriesIndividual entries with text + media
TrackRecordEntryMediatrack_record_entry_mediaAttached photos/videos
TrackRecordEntryVotetrack_record_entry_votesThumbs-up votes
TrackRecordCommenttrack_record_commentsThreaded comments on entries
XPEventxp_eventsXP earning events with metadata
BadgebadgesBadge definitions (category, rarity, criteria)
UserBadgeuser_badgesBadges earned by users

Dual Model Data Flow

Legacy and modern models coexist in the same database and Prisma client. The data flows differently depending on which path is used:

Legacy path: Legacy tables → prodData.service.ts transforms bigint IDs to strings, snake_case to camelCase, and UPPER_CASE enums to lowercase → Frontend adapters apply final mapping.

Modern path: Modern tables → Domain services query with Prisma → Response is already in the shape the frontend expects → No adapter transformation needed.

Prisma CLI Commands

Run these from the server/ directory:

CommandDescription
npx prisma generateRegenerate the Prisma client after schema changes
npx prisma db pushPush schema to database (no migration history)
npx prisma migrate devCreate a migration and apply it
npx prisma studioOpen browser-based database GUI
npx prisma db seedRun the seed script (prisma/seed.ts)
npx prisma formatAuto-format the schema file

INFO

During active development, db push is faster for iterating. Switch to migrate dev when you need migration history for production deployments.

See Also

DoCurious Platform Documentation