Skip to main content

Database Seeding Plan

Last Updated: 2026-01-21
Purpose: Define what data should be seeded in production vs. development/test environments


Overview​

Database seeding ensures that essential global data is available to all users. This document defines what should and should not be seeded, and how seeding should be implemented.


What to Seed (Production)​

These items should be seeded in all environments (production, staging, development):

Global Content (userId = null)​

  1. Global Achievements ✅

    • Achievement definitions available to all users
    • Seeded via: seed-gamification.ts
    • Idempotent: Uses upsert by key
  2. Global Shop Items ✅

    • Items available in the shop for all users
    • Seeded via: seed-gamification.ts
    • Idempotent: Uses upsert by key
  3. Global Challenges ✅

    • Challenge templates available to all users
    • Seeded via: seed-gamification.ts
    • Idempotent: Uses upsert by key
  4. Global Bounties ✅

    • Bounty templates available to all users
    • Seeded via: seed-gamification.ts
    • Idempotent: Uses upsert by key
  5. Global Opponents (for battles) ✅

    • Opponent templates for gamification battles
    • Seeded via: seed-gamification.ts
    • Idempotent: Uses upsert by key
  6. Global Journal Questions ✅

    • Default journal questions available to all users
    • Seeded via: seed.ts (main seed function)
    • Idempotent: Checks for existing questions before creating
  7. Exercise Catalog (Global Exercises) ✅

    • Common exercises available to all users (userId = null)
    • Seeded via: seed-exercises.ts or seed.ts
    • Idempotent: Checks for existing exercises by name and userId = null
  8. Seasonal Event Templates ✅

    • Template seasonal events for holidays and seasonal celebrations
    • Status: Complete
    • Seeded via: seed-seasonal-events.ts
    • Idempotent: Uses upsert by key
    • Includes: Christmas, New Year, Valentine's Day, Easter, Summer, Halloween, Thanksgiving
  9. One-time Event Templates ✅

    • Template one-time events for milestones and special celebrations
    • Status: Complete
    • Seeded via: seed-one-time-events.ts
    • Idempotent: Uses upsert by key
    • Includes: Launch event, user count milestones, XP milestones, beta celebration
  10. Default Week Settings Templates ⚠️

    • Default week settings that new users can copy
    • Status: Deferred - WeekSettings is user-specific (userId unique), not suitable for global templates
    • Alternative: Consider creating example week settings documentation or admin interface for copying settings

What NOT to Seed (Production)​

These items should never be seeded in production:

  1. Users ❌

    • Production databases should start clean
    • Users register through the normal registration flow
    • Exception: Development/test environments may seed demo users
  2. User-Specific Data ❌

    • Tasks, training sessions, journal entries
    • Perimeter tasks, projects, deadlines
    • People, relationships, interactions
    • All data tied to a specific userId
  3. User Gamification Data ❌

    • User XP, coins, level, achievements earned
    • User-owned items, collections, gear
    • All gamification data tied to a specific userId

Seeding Implementation​

Seed Script Structure​

server/prisma/
├── seed.ts # Main seed script (production seeds only)
├── seed-dev.ts # Development/test seeds (demo user, test data)
├── seed-exercises.ts # Exercise catalog seeding
├── seed-gamification.ts # Gamification data seeding
├── seed-seasonal-events.ts # Seasonal event templates seeding
└── seed-one-time-events.ts # One-time event templates seeding

Seed Commands​

{
"scripts": {
"prisma:seed": "tsx prisma/seed.ts", // Production seeds only (includes all seed scripts)
"prisma:seed:dev": "tsx prisma/seed-dev.ts", // Dev/test seeds
"prisma:seed:exercises": "tsx prisma/seed-exercises.ts", // Exercises only
"prisma:seed:gamification": "tsx prisma/seed-gamification.ts", // Gamification only
"prisma:seed:seasonal-events": "tsx prisma/seed-seasonal-events.ts", // Seasonal events only
"prisma:seed:one-time-events": "tsx prisma/seed-one-time-events.ts", // One-time events only
"prisma:seed:all": "tsx prisma/seed.ts && tsx prisma/seed-gamification.ts" // All production seeds
}
}

Idempotency Requirements​

All seed scripts must be idempotent - safe to run multiple times:

  • Use upsert operations where possible
  • Check for existing records before creating
  • Use unique keys/identifiers (e.g., achievement key, exercise name + userId)
  • Never delete existing data (only create/update)

Seed Script Pattern​

async function seedGlobalData() {
console.log('Seeding global data...');

// Check if already seeded
const existing = await prisma.achievement.findFirst({
where: { key: 'FIRST_LOGIN', userId: null }
});

if (existing) {
console.log(' ✓ Global data already seeded, skipping...');
return;
}

// Seed data using upsert
await prisma.achievement.upsert({
where: { key: 'FIRST_LOGIN' },
update: {},
create: { /* ... */ }
});

console.log(' ✓ Global data seeded successfully');
}

Development/Test Seeding​

For development and testing, additional seed scripts can create:

  1. Demo User (development only)

    • Email: demo@arcos.local
    • Password: demo123
    • Pre-populated with sample data for testing
  2. Test Users (testing only)

    • Created via separate test utilities
    • Clearly marked for easy cleanup
    • Pattern: test-*@example.com

Creating Test Users​

Test users should be created via test utilities, not seed scripts:

// server/src/utils/test-helpers.ts
export async function createTestUser(email: string): Promise<User> {
// Creates test user with pattern: test-*@example.com
// Automatically cleaned up in test teardown
}

Deployment Seeding​

Production Deployment​

# Run production seeds only (no users, no demo data)
pnpm prisma db seed

Development Setup​

# Run production seeds
pnpm prisma db seed

# Run development seeds (demo user, test data)
# Note: Development seeds should be separate from production seeds
# See seed.ts for current implementation

Docker Deployment​

# In docker-compose.yml or deployment script
docker compose exec server pnpm prisma db seed

Seed Script Checklist​

When creating or updating seed scripts:

  • Script is idempotent (safe to run multiple times)
  • Uses upsert or checks for existing records
  • Only seeds global data (userId = null where applicable)
  • Does not seed users or user-specific data
  • Includes clear console logging
  • Handles errors gracefully
  • Documented in this file

Current Seed Status​

CategoryStatusScriptIdempotent
Global Achievements✅ Completeseed-gamification.ts✅ Yes
Global Shop Items✅ Completeseed-gamification.ts✅ Yes
Global Challenges✅ Completeseed-gamification.ts✅ Yes
Global Bounties✅ Completeseed-gamification.ts✅ Yes
Global Opponents✅ Completeseed-gamification.ts✅ Yes
Global Journal Questions✅ Completeseed.ts✅ Yes
Exercise Catalog✅ Completeseed-exercises.ts✅ Yes
Seasonal Event Templates✅ Completeseed-seasonal-events.ts✅ Yes
One-time Event Templates✅ Completeseed-one-time-events.ts✅ Yes
Default Week Settings⚠️ Deferred--

Future Enhancements​

  1. Separate seed modules for each category
  2. Seed validation to ensure data integrity
  3. Seed rollback capability (if needed)
  4. Seed versioning to track changes
  5. Admin interface for managing seed data

Notes​

  • The current seed.ts mixes production seeds with demo user creation
  • This should be refactored to separate production seeds from dev/test seeds
  • Demo user creation should be moved to seed-dev.ts
  • All production seeds should be idempotent and safe to run in production