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